You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
882 lines
24 KiB
882 lines
24 KiB
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
exchcli2.cxx
|
|
|
|
Abstract:
|
|
|
|
IIS Crypto client-side key exchange test with security impersonation.
|
|
|
|
Author:
|
|
|
|
Keith Moore (keithmo) 14-Oct-1997
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "precomp.hxx"
|
|
#pragma hdrstop
|
|
|
|
|
|
//
|
|
// Private constants.
|
|
//
|
|
|
|
#define TEST_HRESULT(api) \
|
|
if( FAILED(result) ) { \
|
|
\
|
|
printf( \
|
|
"%s:%lu failed, error %08lx\n", \
|
|
api, \
|
|
__LINE__, \
|
|
result \
|
|
); \
|
|
\
|
|
goto cleanup; \
|
|
\
|
|
} else
|
|
|
|
#define TEST_SOCKERR(api) \
|
|
if( sockerr != NO_ERROR ) { \
|
|
\
|
|
printf( \
|
|
"%s:%lu failed, error %d\n", \
|
|
api, \
|
|
__LINE__, \
|
|
sockerr \
|
|
); \
|
|
\
|
|
goto cleanup; \
|
|
\
|
|
} else
|
|
|
|
#define FREE_BLOB(b) \
|
|
if( b != NULL ) { \
|
|
\
|
|
HRESULT _result; \
|
|
\
|
|
_result = IISCryptoFreeBlob( b ); \
|
|
\
|
|
if( FAILED(_result) ) { \
|
|
\
|
|
printf( \
|
|
"IISCryptoFreeBlob( %08lx ):%lu failed, error %08lx\n", \
|
|
b, \
|
|
__LINE__, \
|
|
_result \
|
|
); \
|
|
\
|
|
} \
|
|
\
|
|
(b) = NULL; \
|
|
\
|
|
}
|
|
|
|
#define PACKAGE_NAME L"NTLM"
|
|
|
|
#define KEY_CTRL_C '\x03'
|
|
#define KEY_BACKSPACE '\x08'
|
|
#define KEY_ENTER '\x0d'
|
|
#define KEY_EOF '\x1a'
|
|
#define KEY_ESCAPE '\x1b'
|
|
|
|
#define STR_BEEP "\x07"
|
|
#define STR_HIDDEN "*"
|
|
#define STR_BACKSPACE "\x08 \x08"
|
|
|
|
#define ALLOC_MEM(cb) (PVOID)LocalAlloc( LPTR, (cb) )
|
|
#define FREE_MEM(p) (VOID)LocalFree( (HLOCAL)(p) )
|
|
|
|
#define DIM(x) (sizeof(x) / sizeof(x[0]))
|
|
|
|
|
|
//
|
|
// Private types.
|
|
//
|
|
|
|
|
|
//
|
|
// Private globals.
|
|
//
|
|
|
|
DECLARE_DEBUG_PRINTS_OBJECT()
|
|
#include <initguid.h>
|
|
DEFINE_GUID(IisCrypt2Guid,
|
|
0x784d8928, 0xaa8c, 0x11d2, 0x92, 0x5e, 0x00, 0xc0, 0x4f, 0x72, 0xd9, 0x0e);
|
|
|
|
CHAR ClientPlainText[] = "Client Client Client Client Client Client";
|
|
|
|
|
|
//
|
|
// Private prototypes.
|
|
//
|
|
|
|
SECURITY_STATUS
|
|
MyLogonUser(
|
|
IN LPWSTR UserName,
|
|
IN LPWSTR UserDomain,
|
|
IN LPWSTR UserPassword,
|
|
OUT PCtxtHandle ServerContext,
|
|
OUT PCredHandle ServerCredential
|
|
);
|
|
|
|
BOOL
|
|
GetStringFromUser(
|
|
LPSTR Prompt,
|
|
LPWSTR String,
|
|
ULONG MaxLength,
|
|
BOOL Echo
|
|
);
|
|
|
|
|
|
//
|
|
// Public functions.
|
|
//
|
|
|
|
|
|
INT
|
|
__cdecl
|
|
main(
|
|
INT argc,
|
|
CHAR * argv[]
|
|
)
|
|
{
|
|
|
|
INT sockerr;
|
|
HRESULT result;
|
|
IIS_CRYPTO_EXCHANGE_CLIENT * pclient;
|
|
BUFFERED_SOCKET * psocket;
|
|
PIIS_CRYPTO_BLOB clientKeyExchangeKeyBlob;
|
|
PIIS_CRYPTO_BLOB clientSignatureKeyBlob;
|
|
PIIS_CRYPTO_BLOB serverKeyExchangeKeyBlob;
|
|
PIIS_CRYPTO_BLOB serverSignatureKeyBlob;
|
|
PIIS_CRYPTO_BLOB serverSessionKeyBlob;
|
|
PIIS_CRYPTO_BLOB clientSessionKeyBlob;
|
|
PIIS_CRYPTO_BLOB clientHashBlob;
|
|
PIIS_CRYPTO_BLOB serverHashBlob;
|
|
PIIS_CRYPTO_BLOB dataBlob;
|
|
IIS_CRYPTO_STORAGE * clientStorage;
|
|
IIS_CRYPTO_STORAGE * serverStorage;
|
|
PVOID buffer;
|
|
DWORD bufferLength;
|
|
DWORD bufferType;
|
|
PSecurityFunctionTable ftab;
|
|
CtxtHandle serverContext;
|
|
CredHandle serverCredential;
|
|
WCHAR name[128];
|
|
WCHAR domain[128];
|
|
WCHAR password[128];
|
|
|
|
if( argc != 2 ) {
|
|
|
|
printf(
|
|
"use: exchcli2 target_server\n"
|
|
);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//
|
|
// Initialize debug stuff.
|
|
//
|
|
|
|
#ifndef _NO_TRACING_
|
|
CREATE_DEBUG_PRINT_OBJECT( "iiscrypt", IisCrypt2Guid );
|
|
CREATE_INITIALIZE_DEBUG();
|
|
#else
|
|
CREATE_DEBUG_PRINT_OBJECT( "iiscrypt" );
|
|
#endif
|
|
|
|
//
|
|
// Setup our locals so we know how to cleanup on exit.
|
|
//
|
|
|
|
pclient = NULL;
|
|
psocket = NULL;
|
|
clientKeyExchangeKeyBlob = NULL;
|
|
clientSignatureKeyBlob = NULL;
|
|
serverKeyExchangeKeyBlob = NULL;
|
|
serverSignatureKeyBlob = NULL;
|
|
serverSessionKeyBlob = NULL;
|
|
clientSessionKeyBlob = NULL;
|
|
clientHashBlob = NULL;
|
|
serverHashBlob = NULL;
|
|
dataBlob = NULL;
|
|
clientStorage = NULL;
|
|
serverStorage = NULL;
|
|
|
|
//
|
|
// Initialize SSPI.
|
|
//
|
|
|
|
ftab = InitSecurityInterface();
|
|
|
|
if( ftab == NULL ) {
|
|
sockerr = GetLastError();
|
|
TEST_SOCKERR( "InitSecurityInterface()" );
|
|
}
|
|
|
|
//
|
|
// Prompt for the user name, domain, and password.
|
|
//
|
|
|
|
if( !GetStringFromUser( "name: ", name, DIM(name), TRUE ) ||
|
|
!GetStringFromUser( "domain: ", domain, DIM(domain), TRUE ) ||
|
|
!GetStringFromUser( "password: ", password, DIM(password), FALSE ) ) {
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Logon.
|
|
//
|
|
|
|
result = MyLogonUser(
|
|
name,
|
|
domain,
|
|
password,
|
|
&serverContext,
|
|
&serverCredential
|
|
);
|
|
|
|
RtlZeroMemory(
|
|
password,
|
|
sizeof(password)
|
|
);
|
|
|
|
TEST_HRESULT( "MyLogonUser" );
|
|
|
|
result = ImpersonateSecurityContext( &serverContext );
|
|
TEST_HRESULT( "ImpersonateSecurityContext" );
|
|
|
|
//
|
|
// Initialize the crypto package.
|
|
//
|
|
|
|
printf( "exchcli2: Initializing...\n" );
|
|
|
|
result = IISCryptoInitialize();
|
|
|
|
TEST_HRESULT( "IISCryptoInitialize()" );
|
|
|
|
//
|
|
// Create & initialize the client-side key exchange object.
|
|
//
|
|
|
|
pclient = new IIS_CRYPTO_EXCHANGE_CLIENT;
|
|
|
|
if( pclient == NULL ) {
|
|
|
|
printf( "out of memory\n" );
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
result = pclient->Initialize(
|
|
CRYPT_NULL,
|
|
CRYPT_NULL,
|
|
CRYPT_NULL,
|
|
TRUE
|
|
);
|
|
|
|
TEST_HRESULT( "pclient->Initialize()" );
|
|
|
|
//
|
|
// Create & initialize the buffered socket object.
|
|
//
|
|
|
|
psocket = new BUFFERED_SOCKET;
|
|
|
|
if( psocket == NULL ) {
|
|
|
|
printf( "out of memory\n" );
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
result = psocket->InitializeClient( argv[1], SERVER_PORT );
|
|
|
|
TEST_HRESULT( "psocket->Initialize()" );
|
|
|
|
//
|
|
// 1. CLIENT(1)
|
|
//
|
|
|
|
printf( "exchcli2: Phase 1...\n" );
|
|
|
|
result = pclient->ClientPhase1(
|
|
&clientKeyExchangeKeyBlob,
|
|
&clientSignatureKeyBlob
|
|
);
|
|
TEST_HRESULT( "pclient->ClientPhase1()" );
|
|
|
|
sockerr = psocket->SendBlob( clientKeyExchangeKeyBlob );
|
|
TEST_SOCKERR( "psocket->SendBlob()" );
|
|
|
|
sockerr = psocket->SendBlob( clientSignatureKeyBlob );
|
|
TEST_SOCKERR( "psocket->SendBlob()" );
|
|
|
|
//
|
|
// 3. CLIENT(2)
|
|
//
|
|
|
|
printf( "exchcli2: Phase 2...\n" );
|
|
|
|
sockerr = psocket->RecvBlob( &serverKeyExchangeKeyBlob );
|
|
TEST_SOCKERR( "psocket->RecvBlob()" );
|
|
|
|
sockerr = psocket->RecvBlob( &serverSignatureKeyBlob );
|
|
TEST_SOCKERR( "psocket->RecvBlob()" );
|
|
|
|
sockerr = psocket->RecvBlob( &serverSessionKeyBlob );
|
|
TEST_SOCKERR( "psocket->RecvBlob()" );
|
|
|
|
result = pclient->ClientPhase2(
|
|
serverKeyExchangeKeyBlob,
|
|
serverSignatureKeyBlob,
|
|
serverSessionKeyBlob,
|
|
&clientSessionKeyBlob,
|
|
&clientHashBlob
|
|
);
|
|
TEST_HRESULT( "pclient->ClientPhase2()" );
|
|
|
|
sockerr = psocket->SendBlob( clientSessionKeyBlob );
|
|
TEST_SOCKERR( "psocket->SendBlob()" );
|
|
|
|
sockerr = psocket->SendBlob( clientHashBlob );
|
|
TEST_SOCKERR( "psocket->SendBlob()" );
|
|
|
|
//
|
|
// 5. CLIENT(3)
|
|
//
|
|
|
|
printf( "exchcli2: Phase 3...\n" );
|
|
|
|
sockerr = psocket->RecvBlob( &serverHashBlob );
|
|
TEST_SOCKERR( "psocket->RecvBlob()" );
|
|
|
|
result = pclient->ClientPhase3(
|
|
serverHashBlob
|
|
);
|
|
TEST_HRESULT( "pclient->ClientPhase3()" );
|
|
|
|
//
|
|
// Create the storage objects.
|
|
//
|
|
|
|
printf( "exchcli2: Creating storage objects...\n" );
|
|
|
|
clientStorage = new IIS_CRYPTO_STORAGE;
|
|
|
|
if( clientStorage == NULL ) {
|
|
|
|
printf( "out of memory\n" );
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
result = clientStorage->Initialize(
|
|
pclient->QueryProviderHandle(),
|
|
pclient->AssumeClientSessionKey(),
|
|
CRYPT_NULL,
|
|
CRYPT_NULL,
|
|
TRUE
|
|
);
|
|
TEST_HRESULT( "clientStorage->Initialize()" );
|
|
|
|
serverStorage = new IIS_CRYPTO_STORAGE;
|
|
|
|
if( serverStorage == NULL ) {
|
|
|
|
printf( "out of memory\n" );
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
result = serverStorage->Initialize(
|
|
pclient->QueryProviderHandle(),
|
|
pclient->AssumeServerSessionKey(),
|
|
CRYPT_NULL,
|
|
pclient->AssumeServerSignatureKey(),
|
|
TRUE
|
|
);
|
|
TEST_HRESULT( "serverStorage->Initialize()" );
|
|
|
|
//
|
|
// Send some encrypted data.
|
|
//
|
|
|
|
printf(
|
|
"exchcli2: Encrypting '%s'...\n",
|
|
ClientPlainText
|
|
);
|
|
|
|
result = clientStorage->EncryptData(
|
|
&dataBlob,
|
|
ClientPlainText,
|
|
sizeof(ClientPlainText),
|
|
REG_SZ
|
|
);
|
|
TEST_HRESULT( "clientStorage->EncryptData()" );
|
|
|
|
printf( "exchcli2: Sending encrypted data...\n" );
|
|
|
|
sockerr = psocket->SendBlob( dataBlob );
|
|
TEST_SOCKERR( "psocket->SendBlob()" );
|
|
|
|
FREE_BLOB( dataBlob );
|
|
|
|
//
|
|
// Receive some encrypted data.
|
|
//
|
|
|
|
printf( "exchcli2: Receiving encrypted data...\n" );
|
|
|
|
sockerr = psocket->RecvBlob( &dataBlob );
|
|
TEST_SOCKERR( "psocket->RecvBlob()" );
|
|
|
|
result = serverStorage->DecryptData(
|
|
&buffer,
|
|
&bufferLength,
|
|
&bufferType,
|
|
dataBlob
|
|
);
|
|
TEST_HRESULT( "serverStorage->DecryptData()" );
|
|
|
|
printf(
|
|
"exchcli2: Received data[%lu] = '%s'\n",
|
|
bufferLength,
|
|
buffer
|
|
);
|
|
|
|
//
|
|
// Tests complete.
|
|
//
|
|
|
|
printf( "exchcli2: Done!\n" );
|
|
|
|
cleanup:
|
|
|
|
FREE_BLOB( dataBlob );
|
|
FREE_BLOB( serverHashBlob );
|
|
FREE_BLOB( clientHashBlob );
|
|
FREE_BLOB( clientSessionKeyBlob );
|
|
FREE_BLOB( serverSessionKeyBlob );
|
|
FREE_BLOB( serverSignatureKeyBlob );
|
|
FREE_BLOB( serverKeyExchangeKeyBlob );
|
|
FREE_BLOB( clientSignatureKeyBlob );
|
|
FREE_BLOB( clientKeyExchangeKeyBlob );
|
|
|
|
delete psocket;
|
|
delete clientStorage;
|
|
delete serverStorage;
|
|
delete pclient;
|
|
|
|
(VOID)IISCryptoTerminate();
|
|
|
|
DELETE_DEBUG_PRINT_OBJECT();
|
|
|
|
return 0;
|
|
|
|
} // main
|
|
|
|
|
|
//
|
|
// Private functions.
|
|
//
|
|
|
|
SECURITY_STATUS
|
|
MyLogonUser(
|
|
IN LPWSTR UserName,
|
|
IN LPWSTR UserDomain,
|
|
IN LPWSTR UserPassword,
|
|
OUT PCtxtHandle ServerContext,
|
|
OUT PCredHandle ServerCredential
|
|
)
|
|
{
|
|
|
|
SECURITY_STATUS status;
|
|
PSecPkgInfoW packageInfo;
|
|
PSEC_WINNT_AUTH_IDENTITY_W additionalCredentials;
|
|
ULONG additionalCredentialsLength;
|
|
LPWSTR next;
|
|
CredHandle clientCredential;
|
|
TimeStamp expiration;
|
|
SecBufferDesc tokenBuffer1Desc;
|
|
SecBuffer tokenBuffer1;
|
|
SecBufferDesc tokenBuffer2Desc;
|
|
SecBuffer tokenBuffer2;
|
|
ULONG contextAttributes;
|
|
CtxtHandle clientContext;
|
|
PVOID rawTokenBuffer1;
|
|
PVOID rawTokenBuffer2;
|
|
BOOL haveClientCredential;
|
|
|
|
//
|
|
// Setup locals so we know how to cleanup on exit.
|
|
//
|
|
|
|
packageInfo = NULL;
|
|
additionalCredentials = NULL;
|
|
rawTokenBuffer1 = NULL;
|
|
rawTokenBuffer2 = NULL;
|
|
haveClientCredential = FALSE;
|
|
|
|
//
|
|
// Get the package info. We must do this to get the maximum
|
|
// token length.
|
|
//
|
|
|
|
status = QuerySecurityPackageInfoW(
|
|
PACKAGE_NAME, // pszPackageName
|
|
&packageInfo // ppPackageInfo
|
|
);
|
|
|
|
if( FAILED(status) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Allocate the token buffers.
|
|
//
|
|
|
|
rawTokenBuffer1 = ALLOC_MEM( packageInfo->cbMaxToken );
|
|
rawTokenBuffer2 = ALLOC_MEM( packageInfo->cbMaxToken );
|
|
|
|
if( rawTokenBuffer1 == NULL ||
|
|
rawTokenBuffer2 == NULL ) {
|
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Build the credential info containing the cleartext user name,
|
|
// domain name, and password.
|
|
//
|
|
|
|
additionalCredentialsLength = sizeof(*additionalCredentials);
|
|
|
|
if( UserName != NULL ) {
|
|
additionalCredentialsLength += ( wcslen( UserName ) + 1 ) * sizeof(WCHAR);
|
|
}
|
|
|
|
if( UserDomain != NULL ) {
|
|
additionalCredentialsLength += ( wcslen( UserDomain ) + 1 ) * sizeof(WCHAR);
|
|
}
|
|
|
|
if( UserPassword != NULL ) {
|
|
additionalCredentialsLength += ( wcslen( UserPassword ) + 1 ) * sizeof(WCHAR);
|
|
}
|
|
|
|
additionalCredentials = (PSEC_WINNT_AUTH_IDENTITY_W)ALLOC_MEM( additionalCredentialsLength );
|
|
|
|
if( additionalCredentials == NULL ) {
|
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
additionalCredentials,
|
|
additionalCredentialsLength
|
|
);
|
|
|
|
next = (LPWSTR)( additionalCredentials + 1 );
|
|
|
|
additionalCredentials->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
|
|
|
if( UserName != NULL ) {
|
|
additionalCredentials->User = (unsigned short *)next;
|
|
additionalCredentials->UserLength = wcslen( UserName );
|
|
wcscpy( next, UserName );
|
|
next += additionalCredentials->UserLength + 1;
|
|
}
|
|
|
|
if( UserDomain != NULL ) {
|
|
additionalCredentials->Domain = (unsigned short *)next;
|
|
additionalCredentials->DomainLength = wcslen( UserDomain );
|
|
wcscpy( next, UserDomain );
|
|
next += additionalCredentials->DomainLength + 1;
|
|
}
|
|
|
|
if( UserPassword != NULL ) {
|
|
additionalCredentials->Password = (unsigned short *)next;
|
|
additionalCredentials->PasswordLength = wcslen( UserPassword );
|
|
wcscpy( next, UserPassword );
|
|
next += additionalCredentials->PasswordLength + 1;
|
|
}
|
|
|
|
//
|
|
// Get the client-side credentials.
|
|
//
|
|
|
|
status = AcquireCredentialsHandleW(
|
|
NULL, // pszPrincipal
|
|
PACKAGE_NAME, // pszPackage
|
|
SECPKG_CRED_OUTBOUND, // fCredentialUse
|
|
NULL, // pvLogonID
|
|
additionalCredentials, // pAuthData
|
|
NULL, // pGetKeyFn
|
|
NULL, // pvGetKeyArgument
|
|
&clientCredential, // phCredential
|
|
&expiration // ptsExpiry
|
|
);
|
|
|
|
RtlZeroMemory(
|
|
additionalCredentials->Password,
|
|
additionalCredentials->PasswordLength
|
|
);
|
|
|
|
if( FAILED(status) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
haveClientCredential = TRUE;
|
|
|
|
//
|
|
// Get the server-side credentials.
|
|
//
|
|
|
|
status = AcquireCredentialsHandleW(
|
|
NULL, // pszPrincipal
|
|
PACKAGE_NAME, // pszPackage
|
|
SECPKG_CRED_INBOUND, // fCredentialUse
|
|
NULL, // pvLogonID
|
|
NULL, // pAuthData
|
|
NULL, // pGetKeyFn
|
|
NULL, // pvGetKeyArgument
|
|
ServerCredential, // phCredential
|
|
&expiration // ptsExpiry
|
|
);
|
|
|
|
if( FAILED(status) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Initialize the client-side security context.
|
|
//
|
|
|
|
tokenBuffer1Desc.cBuffers = 1;
|
|
tokenBuffer1Desc.pBuffers = &tokenBuffer1;
|
|
tokenBuffer1Desc.ulVersion = SECBUFFER_VERSION;
|
|
|
|
tokenBuffer1.BufferType = SECBUFFER_TOKEN;
|
|
tokenBuffer1.cbBuffer = packageInfo->cbMaxToken;
|
|
tokenBuffer1.pvBuffer = rawTokenBuffer1;
|
|
|
|
status = InitializeSecurityContext(
|
|
&clientCredential, // phCredential
|
|
NULL, // phContext
|
|
NULL, // pszTargetName
|
|
ISC_REQ_REPLAY_DETECT, // fContextReq
|
|
0, // Reserved1
|
|
SECURITY_NATIVE_DREP, // TargetDataRep,
|
|
NULL, // pInput
|
|
0, // Reserved2
|
|
&clientContext, // phNewContext
|
|
&tokenBuffer1Desc, // pOutput,
|
|
&contextAttributes, // pfContextAttr,
|
|
&expiration // ptsExpiry
|
|
);
|
|
|
|
if( FAILED(status) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Import the client-side context into the server side.
|
|
//
|
|
|
|
tokenBuffer2Desc.cBuffers = 1;
|
|
tokenBuffer2Desc.pBuffers = &tokenBuffer2;
|
|
tokenBuffer2Desc.ulVersion = SECBUFFER_VERSION;
|
|
|
|
tokenBuffer2.BufferType = SECBUFFER_TOKEN;
|
|
tokenBuffer2.cbBuffer = packageInfo->cbMaxToken;
|
|
tokenBuffer2.pvBuffer = rawTokenBuffer2;
|
|
|
|
status = AcceptSecurityContext(
|
|
ServerCredential, // phCredential
|
|
NULL, // phContext
|
|
&tokenBuffer1Desc, // pInput
|
|
0, // fContextReq
|
|
SECURITY_NATIVE_DREP, // TargetDataRep
|
|
ServerContext, // phNewContext
|
|
&tokenBuffer2Desc, // pOutput
|
|
&contextAttributes, // pfContextAttr
|
|
&expiration // ptsExpiry
|
|
);
|
|
|
|
if( FAILED(status) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Pass it back into the client.
|
|
//
|
|
|
|
tokenBuffer1Desc.cBuffers = 1;
|
|
tokenBuffer1Desc.pBuffers = &tokenBuffer1;
|
|
tokenBuffer1Desc.ulVersion = SECBUFFER_VERSION;
|
|
|
|
tokenBuffer1.BufferType = SECBUFFER_TOKEN;
|
|
tokenBuffer1.cbBuffer = packageInfo->cbMaxToken;
|
|
tokenBuffer1.pvBuffer = rawTokenBuffer1;
|
|
|
|
status = InitializeSecurityContext(
|
|
&clientCredential, // phCredential
|
|
&clientContext, // phContext
|
|
NULL, // pszTargetName
|
|
0, // fContextReq
|
|
0, // Reserved1
|
|
SECURITY_NATIVE_DREP, // TargetDataRep,
|
|
&tokenBuffer2Desc, // pInput
|
|
0, // Reserved2
|
|
&clientContext, // phNewContext
|
|
&tokenBuffer1Desc, // pOutput,
|
|
&contextAttributes, // pfContextAttr,
|
|
&expiration // ptsExpiry
|
|
);
|
|
|
|
if( FAILED(status) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// And one last time back into the server.
|
|
//
|
|
|
|
tokenBuffer2Desc.cBuffers = 1;
|
|
tokenBuffer2Desc.pBuffers = &tokenBuffer2;
|
|
tokenBuffer2Desc.ulVersion = SECBUFFER_VERSION;
|
|
|
|
tokenBuffer2.BufferType = SECBUFFER_TOKEN;
|
|
tokenBuffer2.cbBuffer = packageInfo->cbMaxToken;
|
|
tokenBuffer2.pvBuffer = rawTokenBuffer2;
|
|
|
|
status = AcceptSecurityContext(
|
|
ServerCredential, // phCredential
|
|
ServerContext, // phContext
|
|
&tokenBuffer1Desc, // pInput
|
|
0, // fContextReq
|
|
SECURITY_NATIVE_DREP, // TargetDataRep
|
|
ServerContext, // phNewContext
|
|
NULL, // pOutput
|
|
&contextAttributes, // pfContextAttr
|
|
&expiration // ptsExpiry
|
|
);
|
|
|
|
if( FAILED(status) ) {
|
|
goto Cleanup;
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
if( haveClientCredential ) {
|
|
FreeCredentialsHandle( &clientCredential );
|
|
}
|
|
|
|
if( rawTokenBuffer2 != NULL ) {
|
|
FREE_MEM( rawTokenBuffer2 );
|
|
}
|
|
|
|
if( rawTokenBuffer1 != NULL ) {
|
|
FREE_MEM( rawTokenBuffer1 );
|
|
}
|
|
|
|
if( additionalCredentials != NULL ) {
|
|
FREE_MEM( additionalCredentials );
|
|
}
|
|
|
|
if( packageInfo != NULL ) {
|
|
FreeContextBuffer( packageInfo );
|
|
}
|
|
|
|
return status;
|
|
|
|
} // MyLogonUser
|
|
|
|
BOOL
|
|
GetStringFromUser(
|
|
LPSTR Prompt,
|
|
LPWSTR String,
|
|
ULONG MaxLength,
|
|
BOOL Echo
|
|
)
|
|
{
|
|
|
|
ULONG length;
|
|
INT ch;
|
|
|
|
printf( "%s", Prompt );
|
|
|
|
length = 0;
|
|
|
|
for( ; ; ) {
|
|
|
|
ch = _getch();
|
|
|
|
switch( ch ) {
|
|
|
|
case KEY_CTRL_C :
|
|
return FALSE;
|
|
|
|
case KEY_BACKSPACE :
|
|
if( length == 0 ) {
|
|
|
|
printf( STR_BEEP );
|
|
|
|
} else {
|
|
|
|
length--;
|
|
printf( STR_BACKSPACE );
|
|
|
|
}
|
|
break;
|
|
|
|
case KEY_ENTER :
|
|
case KEY_EOF :
|
|
String[length] = L'\0';
|
|
printf( "\n" );
|
|
return TRUE;
|
|
|
|
case KEY_ESCAPE :
|
|
while( length > 0 ) {
|
|
|
|
length--;
|
|
printf( STR_BACKSPACE );
|
|
|
|
}
|
|
break;
|
|
|
|
default :
|
|
if( length < MaxLength ) {
|
|
|
|
String[length++] = (WCHAR)ch;
|
|
|
|
if( Echo ) {
|
|
printf( "%c", ch );
|
|
} else {
|
|
printf( STR_HIDDEN );
|
|
}
|
|
|
|
} else {
|
|
|
|
printf( STR_BEEP );
|
|
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
} // GetStringFromUser
|
|
|