📄 contman.c
字号:
pUuidCreate(&Uuid);
if (RPC_S_OK != pUuidToStringA(&Uuid, &pszUuid))
{
dwErr = (DWORD)NTE_FAIL;
}
if (ERROR_SUCCESS != RegSetValueEx(hRegKey, SZCRYPTOMACHINEGUID,
0, REG_SZ, (BYTE*)pszUuid,
strlen(pszUuid) + 1))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
Ret:
if (pRpcStringFreeA && pszUuid)
pRpcStringFreeA(&pszUuid);
if (hRPCRT4Dll)
FreeLibrary(hRPCRT4Dll);
if (pwszOldUuid)
ContInfoFree(pwszOldUuid);
if (hRegKey)
RegCloseKey(hRegKey);
return dwErr;
}
DWORD AddMachineGuidToContainerName(
LPSTR pszContainer,
LPWSTR pwszNewContainer
)
{
WCHAR rgwszHash[33];
LPWSTR pwszUuid = NULL;
DWORD dwErr = 0;
memset(rgwszHash, 0, sizeof(rgwszHash));
// get the stringized hash of the container name
if (0 != (dwErr = GetHashOfContainer(pszContainer, rgwszHash)))
goto Ret;
// get the GUID of the machine
if (0 != (dwErr = GetMachineGUID(&pwszUuid)))
goto Ret;
wcscpy(pwszNewContainer, rgwszHash);
wcscat(pwszNewContainer, L"_");
wcscat(pwszNewContainer, pwszUuid);
Ret:
if (pwszUuid)
ContInfoFree(pwszUuid);
return dwErr;
}
//
// Just tries to use DPAPI to make sure it works before creating a key
// container.
//
DWORD TryDPAPI()
{
CRYPTPROTECT_PROMPTSTRUCT PromptStruct;
CRYPT_DATA_BLOB DataIn;
CRYPT_DATA_BLOB DataOut;
CRYPT_DATA_BLOB ExtraEntropy;
DWORD dwJunk = 0;
DWORD dwErr = 0;
memset(&PromptStruct, 0, sizeof(PromptStruct));
memset(&DataIn, 0, sizeof(DataIn));
memset(&DataOut, 0, sizeof(DataOut));
PromptStruct.cbSize = sizeof(PromptStruct);
DataIn.cbData = sizeof(DWORD);
DataIn.pbData = (BYTE*)&dwJunk;
ExtraEntropy.cbData = sizeof(STUFF_TO_GO_INTO_MIX);
ExtraEntropy.pbData = STUFF_TO_GO_INTO_MIX;
if (!MyCryptProtectData(&DataIn, L"Export Flag", &ExtraEntropy, NULL,
&PromptStruct, 0, &DataOut))
{
dwErr = (DWORD)NTE_BAD_KEYSET;
goto Ret;
}
Ret:
if (DataOut.pbData)
LocalFree(DataOut.pbData);
return dwErr;
}
DWORD ProtectExportabilityFlag(
IN BOOL fExportable,
IN BOOL fMachineKeyset,
OUT BYTE **ppbProtectedExportability,
OUT DWORD *pcbProtectedExportability
)
{
CRYPTPROTECT_PROMPTSTRUCT PromptStruct;
CRYPT_DATA_BLOB DataIn;
CRYPT_DATA_BLOB DataOut;
CRYPT_DATA_BLOB ExtraEntropy;
DWORD dwProtectFlags = 0;
DWORD dwErr = 0;
memset(&PromptStruct, 0, sizeof(PromptStruct));
memset(&DataIn, 0, sizeof(DataIn));
memset(&DataOut, 0, sizeof(DataOut));
if (fMachineKeyset)
dwProtectFlags = CRYPTPROTECT_LOCAL_MACHINE;
PromptStruct.cbSize = sizeof(PromptStruct);
DataIn.cbData = sizeof(BOOL);
DataIn.pbData = (BYTE*)&fExportable;
ExtraEntropy.cbData = sizeof(STUFF_TO_GO_INTO_MIX);
ExtraEntropy.pbData = STUFF_TO_GO_INTO_MIX;
if (!MyCryptProtectData(&DataIn, L"Export Flag", &ExtraEntropy, NULL,
&PromptStruct, dwProtectFlags, &DataOut))
{
dwErr = (DWORD)NTE_FAIL;
goto Ret;
}
if (NULL == (*ppbProtectedExportability = ContInfoAlloc(DataOut.cbData)))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
*pcbProtectedExportability = DataOut.cbData;
memcpy(*ppbProtectedExportability, DataOut.pbData, DataOut.cbData);
Ret:
if (DataOut.pbData)
LocalFree(DataOut.pbData);
return dwErr;
}
DWORD UnprotectExportabilityFlag(
IN BOOL fMachineKeyset,
IN BYTE *pbProtectedExportability,
IN DWORD cbProtectedExportability,
IN BOOL *pfExportable
)
{
CRYPTPROTECT_PROMPTSTRUCT PromptStruct;
CRYPT_DATA_BLOB DataIn;
CRYPT_DATA_BLOB DataOut;
CRYPT_DATA_BLOB ExtraEntropy;
DWORD dwProtectFlags = 0;
DWORD dwErr = 0;
memset(&PromptStruct, 0, sizeof(PromptStruct));
memset(&DataIn, 0, sizeof(DataIn));
memset(&DataOut, 0, sizeof(DataOut));
memset(&ExtraEntropy, 0, sizeof(ExtraEntropy));
if (fMachineKeyset)
dwProtectFlags = CRYPTPROTECT_LOCAL_MACHINE;
PromptStruct.cbSize = sizeof(PromptStruct);
DataIn.cbData = cbProtectedExportability;
DataIn.pbData = pbProtectedExportability;
ExtraEntropy.cbData = sizeof(STUFF_TO_GO_INTO_MIX);
ExtraEntropy.pbData = STUFF_TO_GO_INTO_MIX;
if (!MyCryptUnprotectData(&DataIn, NULL, &ExtraEntropy, NULL,
&PromptStruct, dwProtectFlags, &DataOut))
{
dwErr = (DWORD)NTE_BAD_KEYSET;
goto Ret;
}
if (sizeof(BOOL) != DataOut.cbData)
{
dwErr = (DWORD)NTE_BAD_KEYSET;
goto Ret;
}
*pfExportable = *((BOOL*)DataOut.pbData);
Ret:
// free the DataOut struct if necessary
if (DataOut.pbData)
LocalFree(DataOut.pbData);
return dwErr;
}
DWORD GetMachineKeysetDirDACL(
IN OUT PACL *ppDacl
)
/*++
Creates a DACL for the MachineKeys directory for
machine keysets so that Everyone may create machine keys.
--*/
{
SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
SID_IDENTIFIER_AUTHORITY siaNTAuth = SECURITY_NT_AUTHORITY;
PSID pEveryoneSid = NULL;
PSID pAdminsSid = NULL;
DWORD dwAclSize;
DWORD dwErr = 0;
//
// prepare Sids representing the world and admins
//
if(!AllocateAndInitializeSid(&siaWorld,
1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSid))
{
dwErr = GetLastError();
goto Ret;
}
if(!AllocateAndInitializeSid(&siaNTAuth,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdminsSid))
{
dwErr = GetLastError();
goto Ret;
}
//
// compute size of new acl
//
dwAclSize = sizeof(ACL) +
2 * ( sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) ) +
GetLengthSid(pEveryoneSid) + GetLengthSid(pAdminsSid);
//
// allocate storage for Acl
//
if (NULL == (*ppDacl = (PACL)ContInfoAlloc(dwAclSize)))
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto Ret;
}
if(!InitializeAcl(*ppDacl, dwAclSize, ACL_REVISION))
{
dwErr = GetLastError();
goto Ret;
}
if(!AddAccessAllowedAce(*ppDacl,
ACL_REVISION,
(FILE_GENERIC_WRITE | FILE_GENERIC_READ) & (~WRITE_DAC),
pEveryoneSid))
{
dwErr = GetLastError();
goto Ret;
}
if(!AddAccessAllowedAce(*ppDacl,
ACL_REVISION,
FILE_ALL_ACCESS,
pAdminsSid))
{
dwErr = GetLastError();
goto Ret;
}
Ret:
if(NULL != pEveryoneSid)
FreeSid(pEveryoneSid);
if(NULL != pAdminsSid)
FreeSid(pAdminsSid);
return dwErr;
}
DWORD
CreateNestedDirectories(
IN LPWSTR wszFullPath,
IN LPWSTR wszCreationStartPoint, // must point in null-terminated range of szFullPath
IN BOOL fMachineKeyset
)
/*++
Create all subdirectories if they do not exists starting at
szCreationStartPoint.
szCreationStartPoint must point to a character within the null terminated
buffer specified by the szFullPath parameter.
Note that szCreationStartPoint should not point at the first character
of a drive root, eg:
d:\foo\bar\bilge\water
\\server\share\foo\bar
\\?\d:\big\path\bilge\water
Instead, szCreationStartPoint should point beyond these components, eg:
bar\bilge\water
foo\bar
big\path\bilge\water
This function does not implement logic for adjusting to compensate for these
inputs because the environment it was design to be used in causes the input
szCreationStartPoint to point well into the szFullPath input buffer.
--*/
{
DWORD i;
DWORD dwPrevious = 0;
DWORD cchRemaining;
SECURITY_ATTRIBUTES SecAttrib;
SECURITY_ATTRIBUTES *pSecAttrib;
SECURITY_DESCRIPTOR sd;
PACL pDacl = NULL;
DWORD dwLastError = ERROR_SUCCESS;
if( wszCreationStartPoint < wszFullPath ||
wszCreationStartPoint > (wcslen(wszFullPath) + wszFullPath)
)
{
dwLastError = ERROR_INVALID_PARAMETER;
goto Ret;
}
cchRemaining = wcslen( wszCreationStartPoint );
//
// scan from left to right in the szCreationStartPoint string
// looking for directory delimiter.
//
for ( i = 0 ; i < cchRemaining ; i++ ) {
WCHAR charReplaced = wszCreationStartPoint[ i ];
if( charReplaced == '\\' || charReplaced == '/' ) {
BOOL fSuccess;
wszCreationStartPoint[ i ] = '\0';
pSecAttrib = NULL;
if (fMachineKeyset)
{
memset(&SecAttrib, 0, sizeof(SecAttrib));
SecAttrib.nLength = sizeof(SecAttrib);
if (0 == wcscmp(MACHINE_KEYS_DIR,
&(wszCreationStartPoint[ dwPrevious ])))
{
if (0 != (dwLastError = GetMachineKeysetDirDACL(&pDacl)))
{
goto Ret;
}
if(!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
{
dwLastError = GetLastError();
goto Ret;
}
if(!SetSecurityDescriptorDacl(&sd, TRUE, pDacl, FALSE))
{
dwLastError = GetLastError();
goto Ret;
}
SecAttrib.lpSecurityDescriptor = &sd;
pSecAttrib = &SecAttrib;
}
}
fSuccess = CreateDirectoryW( wszFullPath, pSecAttrib );
if (fSuccess && (i == (cchRemaining - 1))) {
SetFileAttributesW(wszFullPath, FILE_ATTRIBUTE_SYSTEM);
}
dwPrevious = i + 1;
wszCreationStartPoint[ i ] = charReplaced;
if( !fSuccess ) {
dwLastError = GetLastError();
if( dwLastError != ERROR_ALREADY_EXISTS ) {
//
// continue onwards, trying to create specified subdirectories.
// this is done to address the obscure scenario where
// the Bypass Traverse Checking Privilege allows the caller
// to create directories below an existing path where one
// component denies the user access.
// we just keep trying and the last CreateDirectory()
// result is returned to the caller.
//
continue;
}
}
dwLastError = ERROR_SUCCESS;
}
}
Ret:
if (pDacl)
ContInfoFree(pDacl);
return dwLastError;
}
#ifdef _M_IX86
BOOL WINAPI FIsWinNT(void) {
static BOOL fIKnow = FALSE;
static BOOL fIsWinNT = FALSE;
OSVERSIONINFO osVer;
if(fIKnow)
return(fIsWinNT);
memset(&osVer, 0, sizeof(OSVERSIONINFO));
osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if( GetVersionEx(&osVer) )
fIsWinNT = (osVer.dwPlatformId == VER_PLATFORM_WIN32_NT);
// even on an error, this is as good as it gets
fIKnow = TRUE;
return(fIsWinNT);
}
#else // other than _M_IX86
BOOL WINAPI FIsWinNT(void) {
return(TRUE);
}
#endif // _M_IX86
BOOL
IsLocalSystem(
BOOL *pfIsLocalSystem
)
/*++
This function determines if the user associated with the
specified token is the Local System account.
--*/
{
HANDLE hToken = 0;
HANDLE hThreadToken = NULL;
UCHAR InfoBuffer[1024];
DWORD dwInfoBufferSize = sizeof(InfoBuffer);
PTOKEN_USER SlowBuffer = NULL;
PTOKEN_USER pTokenUser = (PTOKEN_USER)InfoBuffer;
PSID psidLocalSystem = NULL;
SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -