1313 lines
38 KiB
C++
1313 lines
38 KiB
C++
|
// Test.cpp : Defines the entry point for the console application. This code uses SASL calling convention
|
|||
|
//
|
|||
|
|
|||
|
#include "testglobal.h"
|
|||
|
|
|||
|
#include <stdio.h> // printf
|
|||
|
|
|||
|
#include <security.h> // General definition of a Security Support Provider
|
|||
|
|
|||
|
|
|||
|
#define AUTH_USERNAME "test1"
|
|||
|
#define AUTH_USERNAME_W L"test1"
|
|||
|
|
|||
|
#define AUTH_NONCE "9b38dce631309cc25a653ebaad5b18ee01c8bf385260b26db0574a302be4c11367"
|
|||
|
#define AUTH_URI_W L"imap/elwood.innosoft.com"
|
|||
|
#define AUTH_NC "0000000b"
|
|||
|
#define AUTH_NC1 "00000001"
|
|||
|
#define AUTH_NC2 "00000002"
|
|||
|
#define AUTH_NC3 "00000003"
|
|||
|
#define AUTH_NC4 "00000004"
|
|||
|
|
|||
|
#define AUTHDATA_USERNAME L"test1"
|
|||
|
// #define AUTHDATA_DOMAIN L"kdamour2w.damourlan.nttest.microsoft.com"
|
|||
|
// #define AUTHDATA_DOMAIN L"damourlan"
|
|||
|
#define AUTHDATA_DOMAIN L"damourlan"
|
|||
|
#define AUTHDATA_PASSWORD L"test1"
|
|||
|
|
|||
|
|
|||
|
#define STR_BUF_SIZE 4000
|
|||
|
|
|||
|
char g_czTestPasswd[257];
|
|||
|
|
|||
|
|
|||
|
BOOLEAN QuietMode = FALSE; // Don't be verbose
|
|||
|
|
|||
|
|
|||
|
// Prototypes
|
|||
|
void PrintStatus(SECURITY_STATUS NetStatus);
|
|||
|
void PrintTime(LPSTR Comment,TimeStamp ConvertTime);
|
|||
|
|
|||
|
void ISCRETFlags(ULONG ulFlags);
|
|||
|
void ASCRETFlags(ULONG ulFlags);
|
|||
|
|
|||
|
VOID BinToHex(
|
|||
|
LPBYTE pSrc,
|
|||
|
UINT cSrc,
|
|||
|
LPSTR pDst
|
|||
|
);
|
|||
|
|
|||
|
int __cdecl
|
|||
|
main(int argc, char* argv[])
|
|||
|
{
|
|||
|
BOOL bPass = TRUE;
|
|||
|
SECURITY_STATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
char cTemp[STR_BUF_SIZE]; // temp buffer for scratch data
|
|||
|
char cTemp2[STR_BUF_SIZE]; // temp buffer for scratch data
|
|||
|
char cOutputTemp[STR_BUF_SIZE];
|
|||
|
char szOutSecBuf[STR_BUF_SIZE];
|
|||
|
char szChallenge[STR_BUF_SIZE];
|
|||
|
char szISCChallengeResponse[STR_BUF_SIZE]; // Output buffer from ISC
|
|||
|
char szASCChallengeResponse[STR_BUF_SIZE]; // Output buffer from ASC
|
|||
|
char szASCResponseAuth[STR_BUF_SIZE]; // Output buffer from ASC
|
|||
|
|
|||
|
// SSPI Interface tests
|
|||
|
|
|||
|
ULONG PackageCount = 0;
|
|||
|
int i = 0;
|
|||
|
PSecPkgInfo pPackageInfo = NULL;
|
|||
|
PSecPkgInfo pPackageTmp = NULL;
|
|||
|
SECURITY_STATUS TmpStatus = STATUS_SUCCESS;
|
|||
|
CredHandle ServerCred;
|
|||
|
CredHandle ClientCred;
|
|||
|
TimeStamp Lifetime;
|
|||
|
BOOL bServerCred = FALSE;
|
|||
|
BOOL bClientCred = FALSE;
|
|||
|
|
|||
|
SecPkgContext_StreamSizes StreamSizes;
|
|||
|
|
|||
|
ULONG ClientContextReqFlags = ISC_REQ_INTEGRITY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION;
|
|||
|
ULONG ServerContextReqFlags = ASC_REQ_INTEGRITY | ASC_REQ_CONFIDENTIALITY;
|
|||
|
ULONG ClientContextRetFlags = 0;
|
|||
|
ULONG ServerContextRetFlags = 0;
|
|||
|
ULONG TargetDataRep = 0;
|
|||
|
|
|||
|
|
|||
|
CtxtHandle OldContextHandle;
|
|||
|
CtxtHandle ServerCtxtHandle;
|
|||
|
CtxtHandle ClientCtxtHandle;
|
|||
|
|
|||
|
SecBufferDesc InputBuffers;
|
|||
|
SecBufferDesc OutputBuffers;
|
|||
|
SecBuffer TempTokensIn[6];
|
|||
|
SecBuffer TempTokensOut[6];
|
|||
|
|
|||
|
PCHAR pcPtr = NULL;
|
|||
|
int iLen = 0;
|
|||
|
|
|||
|
UNICODE_STRING ustrUsername;
|
|||
|
UNICODE_STRING ustrPassword;
|
|||
|
UNICODE_STRING ustrDomain;
|
|||
|
STRING strTemp;
|
|||
|
|
|||
|
STRING strChallenge;
|
|||
|
STRING strMethod;
|
|||
|
STRING strHEntity;
|
|||
|
STRING strOutBuffer;
|
|||
|
|
|||
|
ULONG ulMessSeqNo = 0;
|
|||
|
ULONG ulQOP = 0;
|
|||
|
|
|||
|
SEC_WINNT_AUTH_IDENTITY_W AuthData;
|
|||
|
|
|||
|
printf("Begining TESTC...\n");
|
|||
|
|
|||
|
|
|||
|
ZeroMemory(&ClientCred, sizeof(CredHandle));
|
|||
|
ZeroMemory(&ServerCred, sizeof(CredHandle));
|
|||
|
ZeroMemory(&OldContextHandle, sizeof(CtxtHandle));
|
|||
|
ZeroMemory(&ServerCtxtHandle, sizeof(CtxtHandle));
|
|||
|
ZeroMemory(&ClientCtxtHandle, sizeof(CtxtHandle));
|
|||
|
|
|||
|
ZeroMemory(&ustrUsername, sizeof(ustrUsername));
|
|||
|
ZeroMemory(&ustrPassword, sizeof(ustrPassword));
|
|||
|
ZeroMemory(&ustrDomain, sizeof(ustrDomain));
|
|||
|
ZeroMemory(&strTemp, sizeof(strTemp));
|
|||
|
ZeroMemory(&StreamSizes, sizeof(StreamSizes));
|
|||
|
|
|||
|
// Pull out any command line args
|
|||
|
if (argc > 1)
|
|||
|
{
|
|||
|
for (i = 1; i < argc; i++)
|
|||
|
{
|
|||
|
pcPtr = argv[i];
|
|||
|
if (*pcPtr == '-')
|
|||
|
{
|
|||
|
iLen = strlen(pcPtr);
|
|||
|
if (iLen >= 2)
|
|||
|
{
|
|||
|
switch (*(pcPtr + 1))
|
|||
|
{
|
|||
|
case 'u':
|
|||
|
Status = RtlCreateUnicodeStringFromAsciiz(&ustrUsername, (pcPtr + 2));
|
|||
|
break;
|
|||
|
case 'd':
|
|||
|
Status = RtlCreateUnicodeStringFromAsciiz(&ustrDomain, (pcPtr + 2));
|
|||
|
break;
|
|||
|
case 'p':
|
|||
|
Status = RtlCreateUnicodeStringFromAsciiz(&ustrPassword, (pcPtr + 2));
|
|||
|
break;
|
|||
|
case '?':
|
|||
|
default:
|
|||
|
printf("Usage: %s -uUsername -pPassword -ddomain\n", argv[0]);
|
|||
|
return(-1);
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get info about the security packages.
|
|||
|
//
|
|||
|
|
|||
|
Status = EnumerateSecurityPackages( &PackageCount, &pPackageInfo );
|
|||
|
TmpStatus = GetLastError();
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
printf( "EnumerateSecurityPackages failed: 0x%x", Status);
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
if ( !QuietMode ) {
|
|||
|
printf( "PackageCount: %ld\n", PackageCount );
|
|||
|
for ( i= 0; i< (int)PackageCount; i++)
|
|||
|
{
|
|||
|
pPackageTmp = (pPackageInfo + i);
|
|||
|
printf( "Name: %ws Comment: %ws\n", pPackageTmp->Name, pPackageTmp->Comment );
|
|||
|
printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
|
|||
|
pPackageTmp->fCapabilities,
|
|||
|
pPackageTmp->wVersion,
|
|||
|
pPackageTmp->wRPCID,
|
|||
|
pPackageTmp->cbMaxToken );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get info about the security packages.
|
|||
|
//
|
|||
|
|
|||
|
Status = QuerySecurityPackageInfo( WDIGEST_SP_NAME, &pPackageInfo );
|
|||
|
TmpStatus = GetLastError();
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
printf( "QuerySecurityPackageInfo failed: " );
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
if ( !QuietMode ) {
|
|||
|
printf( "Name: %ws Comment: %ws\n", pPackageInfo->Name, pPackageInfo->Comment );
|
|||
|
printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
|
|||
|
pPackageInfo->fCapabilities,
|
|||
|
pPackageInfo->wVersion,
|
|||
|
pPackageInfo->wRPCID,
|
|||
|
pPackageInfo->cbMaxToken );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Acquire a credential handle for the server side
|
|||
|
//
|
|||
|
|
|||
|
printf("Server AcquireCredentialHandle\n");
|
|||
|
Status = AcquireCredentialsHandle(
|
|||
|
NULL, // New principal
|
|||
|
WDIGEST_SP_NAME, // Package Name
|
|||
|
SECPKG_CRED_INBOUND,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
&ServerCred,
|
|||
|
&Lifetime );
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
printf( "AcquireCredentialsHandle failed: ");
|
|||
|
printf( "FAILED: AcquireCredentialsHandle failed: status 0x%x\n", Status);
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
ZeroMemory(&ServerCred, sizeof(CredHandle));
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
bServerCred = TRUE;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Acquire a credential handle for the client side
|
|||
|
//
|
|||
|
printf("Client AcquireCredentialHandle\n");
|
|||
|
|
|||
|
if (ustrUsername.Length || ustrPassword.Length || ustrDomain.Length)
|
|||
|
{
|
|||
|
printf("ACH Using supplied credentials\n");
|
|||
|
printf(" Username %wZ Domain %wZ Password %wZ\n",
|
|||
|
&ustrUsername, &ustrDomain, &ustrPassword);
|
|||
|
|
|||
|
ZeroMemory(&AuthData, sizeof(SEC_WINNT_AUTH_IDENTITY_W));
|
|||
|
AuthData.Domain = ustrDomain.Buffer;
|
|||
|
AuthData.DomainLength = ustrDomain.Length / sizeof(WCHAR);
|
|||
|
AuthData.Password = ustrPassword.Buffer;
|
|||
|
AuthData.PasswordLength = ustrPassword.Length / sizeof(WCHAR);
|
|||
|
AuthData.User = ustrUsername.Buffer;
|
|||
|
AuthData.UserLength = ustrUsername.Length / sizeof(WCHAR);
|
|||
|
AuthData.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
|||
|
|
|||
|
Status = AcquireCredentialsHandle(
|
|||
|
NULL, // AUTH_USERNAME_W, // get the creds for user digest
|
|||
|
WDIGEST_SP_NAME, // Package Name
|
|||
|
SECPKG_CRED_OUTBOUND,
|
|||
|
NULL,
|
|||
|
&AuthData, // Make NULL not to use any AuthData for cred
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
&ClientCred,
|
|||
|
&Lifetime );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("ACH Using default credentials\n");
|
|||
|
Status = AcquireCredentialsHandle(
|
|||
|
NULL, // AUTH_USERNAME_W, // get the creds for user digest
|
|||
|
WDIGEST_SP_NAME, // Package Name
|
|||
|
SECPKG_CRED_OUTBOUND,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
&ClientCred,
|
|||
|
&Lifetime );
|
|||
|
}
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status)) {
|
|||
|
printf( "AcquireCredentialsHandle failed: for user %s: ", AUTH_USERNAME);
|
|||
|
PrintStatus( Status );
|
|||
|
// bPass = FALSE;
|
|||
|
// ZeroMemory(&ClientCred, sizeof(CredHandle));
|
|||
|
// goto CleanUp;
|
|||
|
}
|
|||
|
else
|
|||
|
bClientCred = TRUE;
|
|||
|
|
|||
|
|
|||
|
if ( !QuietMode ) {
|
|||
|
printf( "ClientCred: 0x%lx 0x%lx ",
|
|||
|
ClientCred.dwLower, ClientCred.dwUpper );
|
|||
|
printf( "ServerCred: 0x%lx 0x%lx ",
|
|||
|
ServerCred.dwLower, ServerCred.dwUpper );
|
|||
|
PrintTime( "Lifetime: ", Lifetime );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// Big time - call Accept with no parameters to get a challenge
|
|||
|
|
|||
|
|
|||
|
StringAllocate(&strChallenge, 0);
|
|||
|
|
|||
|
StringCharDuplicate(&strMethod, "GET");
|
|||
|
StringAllocate(&strHEntity, 0);
|
|||
|
|
|||
|
StringAllocate(&strOutBuffer, 4000);
|
|||
|
|
|||
|
|
|||
|
ZeroMemory(TempTokensIn, sizeof(TempTokensIn));
|
|||
|
ZeroMemory(TempTokensOut, sizeof(TempTokensOut));
|
|||
|
ZeroMemory(&InputBuffers, sizeof(SecBufferDesc));
|
|||
|
ZeroMemory(&OutputBuffers, sizeof(SecBufferDesc));
|
|||
|
|
|||
|
|
|||
|
// SASL first calls ISC with no-input
|
|||
|
InputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
InputBuffers.cBuffers = 1;
|
|||
|
InputBuffers.pBuffers = TempTokensIn;
|
|||
|
|
|||
|
TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensIn[0].cbBuffer = 1; // no data passed in
|
|||
|
TempTokensIn[0].pvBuffer = cTemp;
|
|||
|
|
|||
|
OutputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
OutputBuffers.cBuffers = 1;
|
|||
|
OutputBuffers.pBuffers = TempTokensOut;
|
|||
|
|
|||
|
TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
|
|||
|
TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
|
|||
|
|
|||
|
Status = InitializeSecurityContext(&ClientCred,
|
|||
|
NULL,
|
|||
|
AUTH_URI_W,
|
|||
|
ClientContextReqFlags,
|
|||
|
NULL,
|
|||
|
SECURITY_NATIVE_DREP,
|
|||
|
NULL, // &InputBuffers, MSDN allows NULL for 1st call
|
|||
|
NULL,
|
|||
|
&ClientCtxtHandle,
|
|||
|
&OutputBuffers,
|
|||
|
&ClientContextRetFlags,
|
|||
|
&Lifetime);
|
|||
|
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("InitializeSecurityContext SASL 1st call returned: ");
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
printf("ISC Context Flags Req 0x%lx Ret 0x%lx\n", ClientContextReqFlags, ClientContextRetFlags);
|
|||
|
ISCRETFlags(ClientContextRetFlags);
|
|||
|
|
|||
|
printf("InitializeSecurityContext SASL 1st call Output buffer size %d\n",
|
|||
|
TempTokensOut[0].cbBuffer );
|
|||
|
|
|||
|
|
|||
|
InputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
InputBuffers.cBuffers = 1;
|
|||
|
InputBuffers.pBuffers = TempTokensIn;
|
|||
|
|
|||
|
TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensIn[0].cbBuffer = strChallenge.Length + 1; // for NULL
|
|||
|
TempTokensIn[0].pvBuffer = strChallenge.Buffer;
|
|||
|
|
|||
|
OutputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
OutputBuffers.cBuffers = 1;
|
|||
|
OutputBuffers.pBuffers = TempTokensOut;
|
|||
|
|
|||
|
TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
|
|||
|
TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
|
|||
|
|
|||
|
Status = AcceptSecurityContext(
|
|||
|
&ServerCred,
|
|||
|
NULL,
|
|||
|
&InputBuffers,
|
|||
|
ServerContextReqFlags,
|
|||
|
TargetDataRep,
|
|||
|
&ServerCtxtHandle,
|
|||
|
&OutputBuffers,
|
|||
|
&ServerContextRetFlags,
|
|||
|
&Lifetime);
|
|||
|
|
|||
|
if (Status != SEC_I_CONTINUE_NEEDED) // Indicates that this is the challenge
|
|||
|
{
|
|||
|
printf("SpAcceptLsaModeContext FAILED 0x%x\n", Status);
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
|
|||
|
ZeroMemory(szChallenge, STR_BUF_SIZE); // contains the output buffer
|
|||
|
strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
|
|||
|
cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
|
|||
|
strncpy(szChallenge, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
|
|||
|
szChallenge[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
|
|||
|
|
|||
|
printf("ASC Context Flags Req 0x%lx Ret 0x%lx\n", ServerContextReqFlags, ServerContextRetFlags);
|
|||
|
ASCRETFlags(ServerContextRetFlags);
|
|||
|
|
|||
|
printf("Challenge Output Buffer is:\n%s\n\n", cOutputTemp);
|
|||
|
|
|||
|
printf("Now call the SSPI InitializeSecCtxt to generate the ChallengeResponse\n");
|
|||
|
|
|||
|
|
|||
|
sprintf(cTemp, "username=\"%s\",%s,uri=\"%S\",nc=%0.8x",
|
|||
|
AUTH_USERNAME,
|
|||
|
szChallenge,
|
|||
|
AUTH_URI_W,
|
|||
|
1);
|
|||
|
|
|||
|
|
|||
|
InputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
InputBuffers.cBuffers = 1;
|
|||
|
InputBuffers.pBuffers = TempTokensIn;
|
|||
|
|
|||
|
TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensIn[0].cbBuffer = strlen(cTemp) + 1; // for NULL
|
|||
|
TempTokensIn[0].pvBuffer = cTemp;
|
|||
|
|
|||
|
OutputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
OutputBuffers.cBuffers = 1;
|
|||
|
OutputBuffers.pBuffers = TempTokensOut;
|
|||
|
|
|||
|
TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
|
|||
|
TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
|
|||
|
|
|||
|
Status = InitializeSecurityContext(&ClientCred,
|
|||
|
&ClientCtxtHandle,
|
|||
|
AUTH_URI_W,
|
|||
|
ClientContextReqFlags,
|
|||
|
NULL,
|
|||
|
SECURITY_NATIVE_DREP,
|
|||
|
&InputBuffers,
|
|||
|
NULL,
|
|||
|
&ClientCtxtHandle,
|
|||
|
&OutputBuffers,
|
|||
|
&ClientContextRetFlags,
|
|||
|
&Lifetime);
|
|||
|
|
|||
|
|
|||
|
if (Status != SEC_I_CONTINUE_NEEDED) // Indicates that this is the challengeresponse - wait for mutual auth
|
|||
|
{
|
|||
|
printf("SpAcceptLsaModeContext FAILED 0x%x\n", Status);
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
printf("InitializeSecurityContext SUCCEEDED with Context Handle (0x%x,0x%x)\n",
|
|||
|
ClientCtxtHandle.dwLower, ClientCtxtHandle.dwUpper );
|
|||
|
|
|||
|
|
|||
|
printf("ISC Context Flags Req 0x%lx Ret 0x%lx\n", ClientContextReqFlags, ClientContextRetFlags);
|
|||
|
ISCRETFlags(ClientContextRetFlags);
|
|||
|
|
|||
|
|
|||
|
ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
|
|||
|
ZeroMemory(szChallenge, STR_BUF_SIZE); // contains the output buffer
|
|||
|
strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
|
|||
|
cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
|
|||
|
strncpy(szISCChallengeResponse, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
|
|||
|
szISCChallengeResponse[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
|
|||
|
|
|||
|
printf("ISC: Challenge Response Output Buffer is\n%s\n\n", szISCChallengeResponse);
|
|||
|
|
|||
|
InputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
InputBuffers.cBuffers = 1;
|
|||
|
InputBuffers.pBuffers = TempTokensIn;
|
|||
|
|
|||
|
TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensIn[0].cbBuffer = strlen(cOutputTemp) + 1; // for NULL
|
|||
|
TempTokensIn[0].pvBuffer = cOutputTemp;
|
|||
|
|
|||
|
OutputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
OutputBuffers.cBuffers = 1;
|
|||
|
OutputBuffers.pBuffers = TempTokensOut;
|
|||
|
|
|||
|
TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
|
|||
|
TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
|
|||
|
|
|||
|
printf("Calling the AcceptSC with a ChallengeResponse (should talk to the DC)!\n");
|
|||
|
Status = AcceptSecurityContext(
|
|||
|
&ServerCred,
|
|||
|
&ServerCtxtHandle,
|
|||
|
&InputBuffers,
|
|||
|
ServerContextReqFlags,
|
|||
|
TargetDataRep,
|
|||
|
&ServerCtxtHandle,
|
|||
|
&OutputBuffers,
|
|||
|
&ServerContextRetFlags,
|
|||
|
&Lifetime);
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("AcceptSecurityContext 2nd Call: ");
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
strcpy(szASCChallengeResponse, (char *)InputBuffers.pBuffers[0].pvBuffer);
|
|||
|
|
|||
|
|
|||
|
ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
|
|||
|
ZeroMemory(szASCResponseAuth, STR_BUF_SIZE); // contains the output buffer
|
|||
|
strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
|
|||
|
cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
|
|||
|
strncpy(szASCResponseAuth, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
|
|||
|
szASCResponseAuth[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
|
|||
|
|
|||
|
printf("ASC has accepted the Challenge Resposne and generated rspauth for mutual auth back to client\n");
|
|||
|
|
|||
|
printf("ASC Context Flags Req 0x%lx Ret 0x%lx\n", ServerContextReqFlags, ServerContextRetFlags);
|
|||
|
ASCRETFlags(ServerContextRetFlags);
|
|||
|
|
|||
|
printf("ASC: Response Auth Output Buffer is\n%s\n\n", szASCResponseAuth);
|
|||
|
|
|||
|
|
|||
|
printf("Now have a valid Security Context handle from ASC\n\n");
|
|||
|
|
|||
|
InputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
InputBuffers.cBuffers = 1;
|
|||
|
InputBuffers.pBuffers = TempTokensIn;
|
|||
|
|
|||
|
TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensIn[0].cbBuffer = strlen(cOutputTemp) + 1; // for NULL
|
|||
|
TempTokensIn[0].pvBuffer = cOutputTemp;
|
|||
|
|
|||
|
OutputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
OutputBuffers.cBuffers = 1;
|
|||
|
OutputBuffers.pBuffers = TempTokensOut;
|
|||
|
|
|||
|
TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
|
|||
|
TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
|
|||
|
|
|||
|
Status = InitializeSecurityContext(&ClientCred,
|
|||
|
&ClientCtxtHandle,
|
|||
|
AUTH_URI_W,
|
|||
|
ClientContextReqFlags,
|
|||
|
NULL,
|
|||
|
SECURITY_NATIVE_DREP,
|
|||
|
&InputBuffers,
|
|||
|
NULL,
|
|||
|
&ClientCtxtHandle,
|
|||
|
&OutputBuffers,
|
|||
|
&ClientContextRetFlags,
|
|||
|
&Lifetime);
|
|||
|
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("InitializeSecurityContext on Response Auth FAILED: ");
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
printf("InitializeSecurityContext SUCCEEDED with Context Handle (0x%x,0x%x)\n",
|
|||
|
ClientCtxtHandle.dwLower, ClientCtxtHandle.dwUpper );
|
|||
|
|
|||
|
|
|||
|
printf("ISC Context Flags Req 0x%lx Ret 0x%lx\n", ClientContextReqFlags, ClientContextRetFlags);
|
|||
|
ISCRETFlags(ClientContextRetFlags);
|
|||
|
|
|||
|
ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
|
|||
|
strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
|
|||
|
cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
|
|||
|
|
|||
|
printf("\nISC: Mutual auth Output Buffer is\n%s\n\n", cOutputTemp);
|
|||
|
|
|||
|
printf("Now have a valid Security Context handle from ISC and ASC\n\n");
|
|||
|
|
|||
|
|
|||
|
// Now get some info on the securitycontexts
|
|||
|
|
|||
|
Status = QueryContextAttributes(&ServerCtxtHandle, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("FAILED: QueryContextAttributes SECPKG_ATTR_STREAM_SIZES error: status 0x%x\n", Status);
|
|||
|
PrintStatus( Status );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("Server Context Stream Sizes: MaxBuf %lu Blocksize %lu Trailer %lu\n",
|
|||
|
StreamSizes.cbMaximumMessage, StreamSizes.cbBlockSize,
|
|||
|
StreamSizes.cbTrailer);
|
|||
|
}
|
|||
|
|
|||
|
Status = QueryContextAttributes(&ClientCtxtHandle, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("FAILED: QueryContextAttributes SECPKG_ATTR_STREAM_SIZES error: status 0x%x\n", Status);
|
|||
|
PrintStatus( Status );
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printf("Client Context Stream Sizes: MaxBuf %lu Blocksize %lu Trailer %lu\n",
|
|||
|
StreamSizes.cbMaximumMessage, StreamSizes.cbBlockSize,
|
|||
|
StreamSizes.cbTrailer);
|
|||
|
}
|
|||
|
|
|||
|
// Now have authenticated connection
|
|||
|
// Try MakeSignature and VerifySignature
|
|||
|
|
|||
|
for (i = 0; i < 9; i++)
|
|||
|
{
|
|||
|
printf("Loop %d\n", i);
|
|||
|
ZeroMemory(cTemp, sizeof(cTemp));
|
|||
|
strcpy(cTemp, AUTH_NONCE); // Create message to sign
|
|||
|
|
|||
|
InputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
InputBuffers.cBuffers = 3;
|
|||
|
InputBuffers.pBuffers = TempTokensIn;
|
|||
|
|
|||
|
TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
|
|||
|
TempTokensIn[0].cbBuffer = 0;
|
|||
|
TempTokensIn[0].pvBuffer = NULL;
|
|||
|
TempTokensIn[1].BufferType = SECBUFFER_DATA; // select some data to sign
|
|||
|
TempTokensIn[1].cbBuffer = strlen(AUTH_NONCE) + 1 - i; // for NULL use i to test non-blocksize buffers
|
|||
|
TempTokensIn[1].pvBuffer = cTemp;
|
|||
|
TempTokensIn[2].BufferType = SECBUFFER_PADDING;
|
|||
|
TempTokensIn[2].cbBuffer = STR_BUF_SIZE - TempTokensIn[1].cbBuffer; // for NULL
|
|||
|
TempTokensIn[2].pvBuffer = cTemp + TempTokensIn[1].cbBuffer;
|
|||
|
|
|||
|
if (TempTokensIn[1].cbBuffer)
|
|||
|
{
|
|||
|
printf("Input Message to process is %d bytes\n", TempTokensIn[1].cbBuffer);
|
|||
|
BinToHex((PBYTE)TempTokensIn[1].pvBuffer, TempTokensIn[1].cbBuffer, cTemp2);
|
|||
|
printf("Mesage: %s\n", cTemp2);
|
|||
|
}
|
|||
|
|
|||
|
Status = EncryptMessage(&ClientCtxtHandle,
|
|||
|
ulQOP,
|
|||
|
&InputBuffers,
|
|||
|
0);
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("TestCredAPI: EncryptMessage FAILED: ");
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
printf("Processed (sign/seal) Output Buffer for message length is %d\n",
|
|||
|
TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer);
|
|||
|
if (TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer)
|
|||
|
{
|
|||
|
printf("Message is %d bytes\n", TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer);
|
|||
|
BinToHex((PBYTE)TempTokensIn[1].pvBuffer, TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer, cTemp2);
|
|||
|
printf("Mesage: %s\n", cTemp2);
|
|||
|
}
|
|||
|
|
|||
|
// You now send Output buffer to Server - in this case the buffer is szOutSecBuf
|
|||
|
|
|||
|
printf("Now verify that the 1st message is Authenticate\n");
|
|||
|
InputBuffers.ulVersion = SECBUFFER_VERSION;
|
|||
|
InputBuffers.cBuffers = 2;
|
|||
|
InputBuffers.pBuffers = TempTokensIn;
|
|||
|
|
|||
|
|
|||
|
TempTokensIn[0].BufferType = SECBUFFER_STREAM;
|
|||
|
TempTokensIn[0].cbBuffer = TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer;
|
|||
|
TempTokensIn[0].pvBuffer = TempTokensIn[1].pvBuffer;
|
|||
|
TempTokensIn[1].BufferType = SECBUFFER_DATA; // select some data to sign
|
|||
|
TempTokensIn[1].cbBuffer = 0;
|
|||
|
TempTokensIn[1].pvBuffer = NULL;
|
|||
|
|
|||
|
|
|||
|
Status = DecryptMessage(&ServerCtxtHandle,
|
|||
|
&InputBuffers,
|
|||
|
ulMessSeqNo,
|
|||
|
&ulQOP);
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("TestCredAPI: DecryptMessage 1st Call FAILED :");
|
|||
|
PrintStatus( Status );
|
|||
|
bPass = FALSE;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
printf("Now have a authenticated 1st message under context 0x%x\n", ServerCtxtHandle);
|
|||
|
|
|||
|
|
|||
|
printf("Processed (verify/unseal) is %d bytes\n", TempTokensIn[1].cbBuffer);
|
|||
|
if (TempTokensIn[1].cbBuffer)
|
|||
|
{
|
|||
|
BinToHex((PBYTE)TempTokensIn[1].pvBuffer, TempTokensIn[1].cbBuffer, cTemp2);
|
|||
|
printf("Mesage: %s\n", cTemp2);
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
CleanUp:
|
|||
|
|
|||
|
printf("Leaving test program\n");
|
|||
|
|
|||
|
if (pPackageInfo)
|
|||
|
{
|
|||
|
FreeContextBuffer(pPackageInfo);
|
|||
|
}
|
|||
|
|
|||
|
printf("About to call deletesecuritycontext\n");
|
|||
|
|
|||
|
//
|
|||
|
// Free the security context handle
|
|||
|
//
|
|||
|
if (ServerCtxtHandle.dwLower || ServerCtxtHandle.dwUpper)
|
|||
|
{
|
|||
|
Status = DeleteSecurityContext(&ServerCtxtHandle);
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("ERROR: DeleteSecurityContext ServerCtxtHandle failed: ");
|
|||
|
PrintStatus(Status);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (ClientCtxtHandle.dwLower || ClientCtxtHandle.dwUpper)
|
|||
|
{
|
|||
|
Status = DeleteSecurityContext(&ClientCtxtHandle);
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf("ERROR: DeleteSecurityContext ClientCtxtHandle failed: ");
|
|||
|
PrintStatus(Status);
|
|||
|
}
|
|||
|
}
|
|||
|
//
|
|||
|
// Free the credential handles
|
|||
|
//
|
|||
|
|
|||
|
printf("Now calling to Free the ServerCred\n");
|
|||
|
if (bServerCred)
|
|||
|
{
|
|||
|
Status = FreeCredentialsHandle( &ServerCred );
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf( "FreeCredentialsHandle failed for ServerCred: " );
|
|||
|
PrintStatus(Status);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
printf("Now calling to Free the ServerCred\n");
|
|||
|
if (bClientCred)
|
|||
|
{
|
|||
|
Status = FreeCredentialsHandle(&ClientCred);
|
|||
|
|
|||
|
if (!NT_SUCCESS(Status))
|
|||
|
{
|
|||
|
printf( "FreeCredentialsHandle failed for ClientCred: " );
|
|||
|
PrintStatus( Status );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
StringFree(&strChallenge);
|
|||
|
StringFree(&strMethod);
|
|||
|
StringFree(&strHEntity);
|
|||
|
StringFree(&strOutBuffer);
|
|||
|
|
|||
|
|
|||
|
if (bPass != TRUE)
|
|||
|
printf("FAILED test run with one or more tests failing.\n");
|
|||
|
else
|
|||
|
printf("All tests passed.\n");
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
PrintStatus(
|
|||
|
SECURITY_STATUS NetStatus
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Print a net status code.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
NetStatus - The net status code to print.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
printf( "Status = 0x%lx",NetStatus );
|
|||
|
|
|||
|
switch (NetStatus) {
|
|||
|
|
|||
|
case ERROR_LOGON_FAILURE:
|
|||
|
printf( " ERROR_LOGON_FAILURE" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_ACCESS_DENIED:
|
|||
|
printf( " ERROR_ACCESS_DENIED" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_NOT_SUPPORTED:
|
|||
|
printf( " ERROR_NOT_SUPPORTED" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_NO_LOGON_SERVERS:
|
|||
|
printf( " ERROR_NO_LOGON_SERVERS" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_NO_SUCH_DOMAIN:
|
|||
|
printf( " ERROR_NO_SUCH_DOMAIN" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_NO_TRUST_LSA_SECRET:
|
|||
|
printf( " ERROR_NO_TRUST_LSA_SECRET" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_NO_TRUST_SAM_ACCOUNT:
|
|||
|
printf( " ERROR_NO_TRUST_SAM_ACCOUNT" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_DOMAIN_TRUST_INCONSISTENT:
|
|||
|
printf( " ERROR_DOMAIN_TRUST_INCONSISTENT" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_BAD_NETPATH:
|
|||
|
printf( " ERROR_BAD_NETPATH" );
|
|||
|
break;
|
|||
|
|
|||
|
case ERROR_FILE_NOT_FOUND:
|
|||
|
printf( " ERROR_FILE_NOT_FOUND" );
|
|||
|
break;
|
|||
|
case SEC_E_NO_SPM:
|
|||
|
printf( " SEC_E_NO_SPM" );
|
|||
|
break;
|
|||
|
case SEC_E_BAD_PKGID:
|
|||
|
printf( " SEC_E_BAD_PKGID" ); break;
|
|||
|
case SEC_E_NOT_OWNER:
|
|||
|
printf( " SEC_E_NOT_OWNER" ); break;
|
|||
|
case SEC_E_CANNOT_INSTALL:
|
|||
|
printf( " SEC_E_CANNOT_INSTALL" ); break;
|
|||
|
case SEC_E_INVALID_TOKEN:
|
|||
|
printf( " SEC_E_INVALID_TOKEN" ); break;
|
|||
|
case SEC_E_CANNOT_PACK:
|
|||
|
printf( " SEC_E_CANNOT_PACK" ); break;
|
|||
|
case SEC_E_QOP_NOT_SUPPORTED:
|
|||
|
printf( " SEC_E_QOP_NOT_SUPPORTED" ); break;
|
|||
|
case SEC_E_NO_IMPERSONATION:
|
|||
|
printf( " SEC_E_NO_IMPERSONATION" ); break;
|
|||
|
case SEC_E_LOGON_DENIED:
|
|||
|
printf( " SEC_E_LOGON_DENIED" ); break;
|
|||
|
case SEC_E_UNKNOWN_CREDENTIALS:
|
|||
|
printf( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
|
|||
|
case SEC_E_NO_CREDENTIALS:
|
|||
|
printf( " SEC_E_NO_CREDENTIALS" ); break;
|
|||
|
case SEC_E_MESSAGE_ALTERED:
|
|||
|
printf( " SEC_E_MESSAGE_ALTERED" ); break;
|
|||
|
case SEC_E_OUT_OF_SEQUENCE:
|
|||
|
printf( " SEC_E_OUT_OF_SEQUENCE" ); break;
|
|||
|
case SEC_E_INSUFFICIENT_MEMORY:
|
|||
|
printf( " SEC_E_INSUFFICIENT_MEMORY" ); break;
|
|||
|
case SEC_E_INVALID_HANDLE:
|
|||
|
printf( " SEC_E_INVALID_HANDLE" ); break;
|
|||
|
case SEC_E_NOT_SUPPORTED:
|
|||
|
printf( " SEC_E_NOT_SUPPORTED" ); break;
|
|||
|
|
|||
|
case SEC_I_CONTINUE_NEEDED:
|
|||
|
printf( " SEC_I_CONTINUE_NEEDED" ); break;
|
|||
|
}
|
|||
|
|
|||
|
printf( "\n" );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
void
|
|||
|
PrintTime(
|
|||
|
LPSTR Comment,
|
|||
|
TimeStamp ConvertTime
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Print the specified time
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
Comment - Comment to print in front of the time
|
|||
|
|
|||
|
Time - Local time to print
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
LARGE_INTEGER LocalTime;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
LocalTime.HighPart = ConvertTime.HighPart;
|
|||
|
LocalTime.LowPart = ConvertTime.LowPart;
|
|||
|
|
|||
|
Status = RtlSystemTimeToLocalTime( &ConvertTime, &LocalTime );
|
|||
|
if (!NT_SUCCESS( Status )) {
|
|||
|
printf( "Can't convert time from GMT to Local time\n" );
|
|||
|
LocalTime = ConvertTime;
|
|||
|
}
|
|||
|
|
|||
|
printf( "%s", Comment );
|
|||
|
|
|||
|
//
|
|||
|
// If the time is infinite,
|
|||
|
// just say so.
|
|||
|
//
|
|||
|
|
|||
|
if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
|
|||
|
printf( "Infinite\n" );
|
|||
|
|
|||
|
//
|
|||
|
// Otherwise print it more clearly
|
|||
|
//
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
TIME_FIELDS TimeFields;
|
|||
|
|
|||
|
RtlTimeToTimeFields( &LocalTime, &TimeFields );
|
|||
|
|
|||
|
printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
|
|||
|
TimeFields.Month,
|
|||
|
TimeFields.Day,
|
|||
|
TimeFields.Year,
|
|||
|
TimeFields.Hour,
|
|||
|
TimeFields.Minute,
|
|||
|
TimeFields.Second );
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// Support Routines
|
|||
|
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: StringAllocate
|
|||
|
//
|
|||
|
// Synopsis: Allocates cb chars to STRING Buffer
|
|||
|
//
|
|||
|
// Arguments: pString - pointer to String to allocate memory to
|
|||
|
//
|
|||
|
// Returns: STATUS_SUCCESS - Normal completion
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Effects: allocates memory and sets STRING sizes
|
|||
|
//
|
|||
|
// Notes: Must call StringFree() to release memory
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
NTSTATUS
|
|||
|
StringAllocate(
|
|||
|
IN PSTRING pString,
|
|||
|
IN USHORT cb
|
|||
|
)
|
|||
|
{
|
|||
|
// DebugLog((DEB_TRACE, "NTDigest:Entering StringAllocate\n"));
|
|||
|
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
cb = cb + 1; // Add in extra room for the terminating NULL
|
|||
|
|
|||
|
if (ARGUMENT_PRESENT(pString))
|
|||
|
{
|
|||
|
pString->Length = 0;
|
|||
|
|
|||
|
pString->Buffer = (char *)DigestAllocateMemory((ULONG)(cb * sizeof(CHAR)));
|
|||
|
if (pString->Buffer)
|
|||
|
{
|
|||
|
pString->MaximumLength = cb;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pString->MaximumLength = 0;
|
|||
|
Status = STATUS_NO_MEMORY;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Status = STATUS_INVALID_PARAMETER;
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
|
|||
|
CleanUp:
|
|||
|
// DebugLog((DEB_TRACE, "NTDigest: Leaving StringAllocate\n"));
|
|||
|
return(Status);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: StringFree
|
|||
|
//
|
|||
|
// Synopsis: Clears a String and releases the memory
|
|||
|
//
|
|||
|
// Arguments: pString - pointer to String to clear
|
|||
|
//
|
|||
|
// Returns: SEC_E_OK - released memory succeeded
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Effects: de-allocates memory with LsaFunctions.AllocateLsaHeap
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
NTSTATUS
|
|||
|
StringFree(
|
|||
|
IN PSTRING pString
|
|||
|
)
|
|||
|
{
|
|||
|
// DebugLog((DEB_TRACE, "NTDigest:Entering StringFree\n"));
|
|||
|
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
|
|||
|
if (ARGUMENT_PRESENT(pString) &&
|
|||
|
(pString->Buffer != NULL))
|
|||
|
{
|
|||
|
DigestFreeMemory(pString->Buffer);
|
|||
|
pString->Length = 0;
|
|||
|
pString->MaximumLength = 0;
|
|||
|
pString->Buffer = NULL;
|
|||
|
}
|
|||
|
|
|||
|
// DebugLog((DEB_TRACE, "NTDigest: Leaving StringFree\n"));
|
|||
|
return(Status);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: StringCharDuplicate
|
|||
|
//
|
|||
|
// Synopsis: Duplicates a NULL terminated char. If the source string buffer is
|
|||
|
// NULL the destionation will be too.
|
|||
|
//
|
|||
|
// Arguments: Destination - Receives a copy of the source NULL Term char *
|
|||
|
// czSource - String to copy
|
|||
|
//
|
|||
|
// Returns: SEC_E_OK - the copy succeeded
|
|||
|
// SEC_E_INSUFFICIENT_MEMORY - the call to allocate
|
|||
|
// memory failed.
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Effects: allocates memory with LsaFunctions.AllocateLsaHeap
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
//
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
NTSTATUS
|
|||
|
StringCharDuplicate(
|
|||
|
OUT PSTRING DestinationString,
|
|||
|
IN OPTIONAL char *czSource
|
|||
|
)
|
|||
|
{
|
|||
|
// DebugLog((DEB_TRACE, "NTDigest: Entering StringCharDuplicate\n"));
|
|||
|
|
|||
|
NTSTATUS Status = STATUS_SUCCESS;
|
|||
|
USHORT cbSourceCz = 0;
|
|||
|
|
|||
|
DestinationString->Buffer = NULL;
|
|||
|
DestinationString->Length = 0;
|
|||
|
DestinationString->MaximumLength = 0;
|
|||
|
|
|||
|
if ((ARGUMENT_PRESENT(czSource)) &&
|
|||
|
((cbSourceCz = strlen(czSource)) != 0))
|
|||
|
{
|
|||
|
|
|||
|
DestinationString->Buffer = (LPSTR) DigestAllocateMemory(cbSourceCz + sizeof(CHAR));
|
|||
|
if (DestinationString->Buffer != NULL)
|
|||
|
{
|
|||
|
|
|||
|
DestinationString->Length = cbSourceCz;
|
|||
|
DestinationString->MaximumLength = cbSourceCz + sizeof(CHAR);
|
|||
|
RtlCopyMemory(
|
|||
|
DestinationString->Buffer,
|
|||
|
czSource,
|
|||
|
cbSourceCz
|
|||
|
);
|
|||
|
|
|||
|
DestinationString->Buffer[cbSourceCz/sizeof(CHAR)] = '\0';
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Status = STATUS_NO_MEMORY;
|
|||
|
// DebugLog((DEB_ERROR, "NTDigest: StringCharDuplicate, DigestAllocateMemory returns NULL\n"));
|
|||
|
goto CleanUp;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
CleanUp:
|
|||
|
|
|||
|
// DebugLog((DEB_TRACE, "NTDigest: Leaving StringCharDuplicate\n"));
|
|||
|
return(Status);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: DigestAllocateMemory
|
|||
|
//
|
|||
|
// Synopsis: Allocate memory in either lsa mode or user mode
|
|||
|
//
|
|||
|
// Effects: Allocated chunk is zeroed out
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
//
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
PVOID
|
|||
|
DigestAllocateMemory(
|
|||
|
IN ULONG BufferSize
|
|||
|
)
|
|||
|
{
|
|||
|
PVOID Buffer = NULL;
|
|||
|
// DebugLog((DEB_TRACE, "Entering DigestAllocateMemory\n"));
|
|||
|
|
|||
|
Buffer = LocalAlloc(LPTR, BufferSize);
|
|||
|
|
|||
|
// DebugLog((DEB_TRACE, "Leaving DigestAllocateMemory\n"));
|
|||
|
return Buffer;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//+-------------------------------------------------------------------------
|
|||
|
//
|
|||
|
// Function: NtLmFree
|
|||
|
//
|
|||
|
// Synopsis: Free memory in either lsa mode or user mode
|
|||
|
//
|
|||
|
// Effects:
|
|||
|
//
|
|||
|
// Arguments:
|
|||
|
//
|
|||
|
// Requires:
|
|||
|
//
|
|||
|
// Returns:
|
|||
|
//
|
|||
|
// Notes:
|
|||
|
//
|
|||
|
//
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
VOID
|
|||
|
DigestFreeMemory(
|
|||
|
IN PVOID Buffer
|
|||
|
)
|
|||
|
{
|
|||
|
// DebugLog((DEB_TRACE, "Entering DigestFreeMemory\n"));
|
|||
|
|
|||
|
LocalFree(Buffer);
|
|||
|
|
|||
|
// DebugLog((DEB_TRACE, "Leaving DigestFreeMemory\n"));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
BinToHex(
|
|||
|
LPBYTE pSrc,
|
|||
|
UINT cSrc,
|
|||
|
LPSTR pDst
|
|||
|
)
|
|||
|
{
|
|||
|
#define TOHEX(a) ((a)>=10 ? 'a'+(a)-10 : '0'+(a))
|
|||
|
|
|||
|
for ( UINT x = 0, y = 0 ; x < cSrc ; ++x )
|
|||
|
{
|
|||
|
UINT v;
|
|||
|
v = pSrc[x]>>4;
|
|||
|
pDst[y++] = TOHEX( v );
|
|||
|
v = pSrc[x]&0x0f;
|
|||
|
pDst[y++] = TOHEX( v );
|
|||
|
}
|
|||
|
pDst[y] = '\0';
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
ISCRETFlags( ULONG ulFlags)
|
|||
|
{
|
|||
|
printf("ISC Ret Flag (0x%x):", ulFlags);
|
|||
|
|
|||
|
if (ulFlags & ISC_RET_DELEGATE)
|
|||
|
{
|
|||
|
printf(" Delegate");
|
|||
|
}
|
|||
|
if (ulFlags & ISC_RET_MUTUAL_AUTH)
|
|||
|
{
|
|||
|
printf(" Mutual_Auth");
|
|||
|
}
|
|||
|
if (ulFlags & ISC_RET_REPLAY_DETECT)
|
|||
|
{
|
|||
|
printf(" Replay_Detect");
|
|||
|
}
|
|||
|
if (ulFlags & ISC_RET_SEQUENCE_DETECT)
|
|||
|
{
|
|||
|
printf(" Seq_Detect");
|
|||
|
}
|
|||
|
if (ulFlags & ISC_RET_CONFIDENTIALITY)
|
|||
|
{
|
|||
|
printf(" Confident");
|
|||
|
}
|
|||
|
if (ulFlags & ISC_RET_ALLOCATED_MEMORY)
|
|||
|
{
|
|||
|
printf(" Alloc_Mem");
|
|||
|
}
|
|||
|
if (ulFlags & ISC_RET_CONNECTION)
|
|||
|
{
|
|||
|
printf(" Connection");
|
|||
|
}
|
|||
|
if (ulFlags & ISC_RET_INTEGRITY)
|
|||
|
{
|
|||
|
printf(" Integrity");
|
|||
|
}
|
|||
|
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
ASCRETFlags( ULONG ulFlags)
|
|||
|
{
|
|||
|
printf("ASC Ret Flag (0x%x):", ulFlags);
|
|||
|
|
|||
|
if (ulFlags & ASC_RET_DELEGATE)
|
|||
|
{
|
|||
|
printf(" Delegate");
|
|||
|
}
|
|||
|
if (ulFlags & ASC_RET_MUTUAL_AUTH)
|
|||
|
{
|
|||
|
printf(" Mutual_Auth");
|
|||
|
}
|
|||
|
if (ulFlags & ASC_RET_REPLAY_DETECT)
|
|||
|
{
|
|||
|
printf(" Replay_Detect");
|
|||
|
}
|
|||
|
if (ulFlags & ASC_RET_SEQUENCE_DETECT)
|
|||
|
{
|
|||
|
printf(" Seq_Detect");
|
|||
|
}
|
|||
|
if (ulFlags & ASC_RET_CONFIDENTIALITY)
|
|||
|
{
|
|||
|
printf(" Confident");
|
|||
|
}
|
|||
|
if (ulFlags & ASC_RET_ALLOCATED_MEMORY)
|
|||
|
{
|
|||
|
printf(" Alloc_Mem");
|
|||
|
}
|
|||
|
if (ulFlags & ASC_RET_CONNECTION)
|
|||
|
{
|
|||
|
printf(" Connection");
|
|||
|
}
|
|||
|
if (ulFlags & ASC_RET_INTEGRITY)
|
|||
|
{
|
|||
|
printf(" Integrity");
|
|||
|
}
|
|||
|
|
|||
|
printf("\n");
|
|||
|
}
|
|||
|
|