📄 securityutils.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "securityutils.h"
#include "Cred.h"
#include "commonmacros.h"
#define MAX_USERNAME 15
#define MAX_DOMAIN 12
/*------------------------------------------------------------------------------
GetPlaintextCredentials
Get the credentials from CredMan
------------------------------------------------------------------------------*/
HRESULT GetPlaintextCredentials(
WCHAR *wszDomainBuffer,
UINT cchDomainBuffer,
WCHAR *wszUserBuffer,
UINT cchUserBuffer,
WCHAR *wszPasswordBuffer,
UINT cchPasswordBuffer
)
{
CRED *pCredPassword = NULL;
HRESULT hr = S_OK;
WCHAR *pwchDomainUserNameSeparator = NULL;
if (
wszDomainBuffer == NULL ||
wszUserBuffer == NULL ||
wszPasswordBuffer == NULL
)
{
return E_POINTER;
}
if (
cchDomainBuffer == 0 ||
cchUserBuffer == 0 ||
cchPasswordBuffer == 0
)
{
return E_INVALIDARG;
}
//Read the credentials
DWORD dwRes = CredRead(
L"",
1,
CRED_TYPE_PLAINTEXT_PASSWORD,
CRED_FLAG_NO_DEFAULT | CRED_FLAG_NO_IMPLICIT_DEFAULT,
&pCredPassword
);
if (dwRes != ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
PREFAST_ASSERT(pCredPassword != NULL);
//Fill the password buffer
if (pCredPassword->pBlob != NULL)
{
StringCchCopy(wszPasswordBuffer, cchPasswordBuffer, (WCHAR*)pCredPassword->pBlob);
}
else
{
//if NULL password we fail
hr = E_FAIL;
goto exit;
}
//Parse the domainusername
PREFAST_ASSERT(pCredPassword->wszUser);
pwchDomainUserNameSeparator = wcschr(pCredPassword->wszUser, L'\\');
if (pwchDomainUserNameSeparator != NULL)
{
*pwchDomainUserNameSeparator = 0;
pwchDomainUserNameSeparator++;
StringCchCopy(wszUserBuffer, cchUserBuffer, pwchDomainUserNameSeparator);
}
StringCchCopy(wszDomainBuffer, cchDomainBuffer, pCredPassword->wszUser);
exit:
if (pCredPassword != NULL)
{
CredFree((BYTE*)pCredPassword);
}
return hr;
}
/*------------------------------------------------------------------------------
WriteCredentials
Writes the credentials to CredMan
------------------------------------------------------------------------------*/
HRESULT WriteCredentials(
const WCHAR *c_wszDomain,
const WCHAR *c_wszUsername,
const WCHAR *c_wszPassword
)
{
HRESULT hr = S_OK;
CRED credPassword = {0};
INT cchDomain = 0,
cchUser = 0,
cchPass = 0;
if (
c_wszDomain == NULL ||
c_wszUsername == NULL ||
c_wszPassword == NULL
)
{
hr = E_POINTER;
goto exit;
}
cchDomain = wcslen(c_wszDomain);
cchUser = wcslen(c_wszUsername);
cchPass = wcslen(c_wszPassword);
DWORD dwResult = S_OK;
WCHAR wszDomainUsername[MAX_PATH] = L"";
if ((cchDomain + cchUser) >= (ARRAYSIZE(wszDomainUsername)-1))
{
hr = E_INVALIDARG;
goto exit;
}
StringCchCopy (wszDomainUsername, _countof(wszDomainUsername), c_wszDomain);
wszDomainUsername[cchDomain] = L'\\';
StringCchCopy(wszDomainUsername + cchDomain + 1, _countof(wszDomainUsername) - cchDomain - 1, c_wszUsername);
//first write the credential as a domain password that is keyed off domain name
credPassword.dwVersion = CRED_VER_1;
credPassword.dwType = CRED_TYPE_PLAINTEXT_PASSWORD; //we'll update the domain password later
credPassword.wszUser = wszDomainUsername;
credPassword.dwUserLen = cchDomain + cchUser + 1 + 1;
credPassword.wszTarget = L"";
credPassword.dwTargetLen = 1;
credPassword.pBlob = (BYTE*)c_wszPassword;
credPassword.dwBlobSize = (cchPass + 1) * sizeof(WCHAR);
credPassword.dwFlags = CRED_FLAG_PERSIST | CRED_FLAG_TRUSTED;
dwResult = CredWrite(
&credPassword,
0
);
if (dwResult != ERROR_SUCCESS)
{
ASSERT(FALSE);
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
//now write the credential as a domain password (Kerb and NTLM)
credPassword.dwType = CRED_TYPE_DOMAIN_PASSWORD;
credPassword.dwFlags &= ~CRED_FLAG_TRUSTED; //allow untrusted apps to use cached creds
dwResult = CredWrite(
&credPassword,
0
);
if (dwResult != ERROR_SUCCESS)
{
ASSERT(FALSE);
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
exit:
return hr;
}
//Helper function
HRESULT GetLoggedInUserInformation(
WCHAR *wszOutBuf,
UINT cchBuf,
UINT fItemToGet
)
{
CRED *pCredDomain = NULL;
HRESULT hr = S_OK;
DWORD dwRes = 0;
WCHAR *pwchDomain = NULL,
*pwchCopy = NULL;
UINT cchCopy = 0;
if (! wszOutBuf)
{
ASSERT(FALSE);
return E_POINTER;
}
dwRes = CredRead(
L"",
1,
CRED_TYPE_DOMAIN_PASSWORD,
CRED_FLAG_NO_DEFAULT | CRED_FLAG_NO_IMPLICIT_DEFAULT,
&pCredDomain
);
if (dwRes != ERROR_SUCCESS)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto exit;
}
if (! pCredDomain || !pCredDomain->wszUser)
{
ASSERT(FALSE);
hr = E_FAIL;
goto exit;
}
pwchDomain = wcschr(pCredDomain->wszUser, L'\\');
if (! pwchDomain)
{
DEBUGMSG(1, (L"We found default domain cred's but NO domain"));
ASSERT(FALSE);
hr = E_FAIL;
}
switch (fItemToGet)
{
case CRED_ITEM_DOMAINUSERNAME:
pwchCopy = pCredDomain->wszUser;
cchCopy = cchBuf;
break;
case CRED_ITEM_DOMAIN:
pwchCopy = pCredDomain->wszUser;
cchCopy = pwchDomain - pCredDomain->wszUser;
break;
case CRED_ITEM_USERNAME:
pwchCopy = pwchDomain + 1;
cchCopy = cchBuf;
break;
default:
ASSERT(FALSE);
hr = E_INVALIDARG;
goto exit;
}
StringCchCopy(wszOutBuf, min(cchBuf, cchCopy), pwchCopy);
exit:
if (pCredDomain)
{
CredFree((BYTE*)pCredDomain);
}
return hr;
}
BOOL PhoneHasCredentials()
{
WCHAR wszBuf[3] = L"";
HRESULT hr = S_OK;
hr = GetLoggedInUserInformation(
wszBuf,
ARRAYSIZE(wszBuf),
CRED_ITEM_DOMAINUSERNAME
);
return (SUCCEEDED(hr) && wszBuf[0]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -