1047 lines
25 KiB
C
1047 lines
25 KiB
C
/*--
|
||
|
||
Copyright (c) 1987-1993 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ssptest.c
|
||
|
||
Abstract:
|
||
|
||
Test program for the NtLmSsp service.
|
||
|
||
Author:
|
||
|
||
28-Jun-1993 (cliffv)
|
||
|
||
Environment:
|
||
|
||
User mode only.
|
||
Contains NT-specific code.
|
||
Requires ANSI C extensions: slash-slash comments, long external names.
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#ifndef UNICODE
|
||
#define UNICODE
|
||
#endif // UNICODE
|
||
|
||
#include <ntos.h>
|
||
#include <ntlsa.h>
|
||
#include <ntsam.h>
|
||
#ifndef SECURITY_WIN32
|
||
#define SECURITY_WIN32
|
||
#endif // SECURITY_WIN32
|
||
#define SECURITY_KERNEL
|
||
#define SECURITY_PACKAGE
|
||
#define SECURITY_KERBEROS
|
||
#include <security.h>
|
||
#include <zwapi.h>
|
||
|
||
BOOLEAN QuietMode = FALSE;
|
||
ULONG DoTests = FALSE;
|
||
|
||
|
||
VOID
|
||
DumpBuffer(
|
||
PVOID Buffer,
|
||
DWORD BufferSize
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Dumps the buffer content on to the debugger output.
|
||
|
||
Arguments:
|
||
|
||
Buffer: buffer pointer.
|
||
|
||
BufferSize: size of the buffer.
|
||
|
||
Return Value:
|
||
|
||
none
|
||
|
||
--*/
|
||
{
|
||
#define NUM_CHARS 16
|
||
|
||
DWORD i, limit;
|
||
CHAR TextBuffer[NUM_CHARS + 1];
|
||
PUCHAR BufferPtr = Buffer;
|
||
|
||
|
||
DbgPrint("------------------------------------\n");
|
||
|
||
//
|
||
// Hex dump of the bytes
|
||
//
|
||
limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
|
||
|
||
for (i = 0; i < limit; i++) {
|
||
|
||
if (i < BufferSize) {
|
||
|
||
DbgPrint("%02x ", BufferPtr[i]);
|
||
|
||
if (BufferPtr[i] < 31 ) {
|
||
TextBuffer[i % NUM_CHARS] = '.';
|
||
} else if (BufferPtr[i] == '\0') {
|
||
TextBuffer[i % NUM_CHARS] = ' ';
|
||
} else {
|
||
TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i];
|
||
}
|
||
|
||
} else {
|
||
|
||
DbgPrint(" ");
|
||
TextBuffer[i % NUM_CHARS] = ' ';
|
||
|
||
}
|
||
|
||
if ((i + 1) % NUM_CHARS == 0) {
|
||
TextBuffer[NUM_CHARS] = 0;
|
||
DbgPrint(" %s\n", TextBuffer);
|
||
}
|
||
|
||
}
|
||
|
||
DbgPrint("------------------------------------\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;
|
||
|
||
LocalTime.HighPart = ConvertTime.HighPart;
|
||
LocalTime.LowPart = ConvertTime.LowPart;
|
||
|
||
DbgPrint( "%s", Comment );
|
||
|
||
//
|
||
// If the time is infinite,
|
||
// just say so.
|
||
//
|
||
|
||
if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
|
||
DbgPrint( "Infinite\n" );
|
||
|
||
//
|
||
// Otherwise print it more clearly
|
||
//
|
||
|
||
} else {
|
||
|
||
TIME_FIELDS TimeFields;
|
||
|
||
RtlTimeToTimeFields( &LocalTime, &TimeFields );
|
||
|
||
DbgPrint( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
|
||
TimeFields.Month,
|
||
TimeFields.Day,
|
||
TimeFields.Year,
|
||
TimeFields.Hour,
|
||
TimeFields.Minute,
|
||
TimeFields.Second );
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
PrintStatus(
|
||
ULONG NetStatus
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Print a net status code.
|
||
|
||
Arguments:
|
||
|
||
NetStatus - The net status code to print.
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
DbgPrint( "Status = %lu 0x%lx", NetStatus, NetStatus );
|
||
|
||
switch (NetStatus) {
|
||
|
||
case SEC_E_NO_SPM:
|
||
DbgPrint( " SEC_E_NO_SPM" );
|
||
break;
|
||
case SEC_E_BAD_PKGID:
|
||
DbgPrint( " SEC_E_BAD_PKGID" ); break;
|
||
case SEC_E_NOT_OWNER:
|
||
DbgPrint( " SEC_E_NOT_OWNER" ); break;
|
||
case SEC_E_CANNOT_INSTALL:
|
||
DbgPrint( " SEC_E_CANNOT_INSTALL" ); break;
|
||
case SEC_E_INVALID_TOKEN:
|
||
DbgPrint( " SEC_E_INVALID_TOKEN" ); break;
|
||
case SEC_E_CANNOT_PACK:
|
||
DbgPrint( " SEC_E_CANNOT_PACK" ); break;
|
||
case SEC_E_QOP_NOT_SUPPORTED:
|
||
DbgPrint( " SEC_E_QOP_NOT_SUPPORTED" ); break;
|
||
case SEC_E_NO_IMPERSONATION:
|
||
DbgPrint( " SEC_E_NO_IMPERSONATION" ); break;
|
||
case SEC_E_LOGON_DENIED:
|
||
DbgPrint( " SEC_E_LOGON_DENIED" ); break;
|
||
case SEC_E_UNKNOWN_CREDENTIALS:
|
||
DbgPrint( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
|
||
case SEC_E_NO_CREDENTIALS:
|
||
DbgPrint( " SEC_E_NO_CREDENTIALS" ); break;
|
||
case SEC_E_MESSAGE_ALTERED:
|
||
DbgPrint( " SEC_E_MESSAGE_ALTERED" ); break;
|
||
case SEC_E_OUT_OF_SEQUENCE:
|
||
DbgPrint( " SEC_E_OUT_OF_SEQUENCE" ); break;
|
||
case SEC_E_INSUFFICIENT_MEMORY:
|
||
DbgPrint( " SEC_E_INSUFFICIENT_MEMORY" ); break;
|
||
case SEC_E_INVALID_HANDLE:
|
||
DbgPrint( " SEC_E_INVALID_HANDLE" ); break;
|
||
case SEC_E_NOT_SUPPORTED:
|
||
DbgPrint( " SEC_E_NOT_SUPPORTED" ); break;
|
||
|
||
|
||
}
|
||
|
||
DbgPrint( "\n" );
|
||
}
|
||
|
||
//+-------------------------------------------------------------------------
|
||
//
|
||
// Function: SecAllocate
|
||
//
|
||
// Synopsis:
|
||
//
|
||
// Effects:
|
||
//
|
||
// Arguments:
|
||
//
|
||
// Requires:
|
||
//
|
||
// Returns:
|
||
//
|
||
// Notes:
|
||
//
|
||
//
|
||
//--------------------------------------------------------------------------
|
||
|
||
|
||
VOID * SEC_ENTRY
|
||
SspAlloc(ULONG Flags, ULONG cbMemory)
|
||
{
|
||
NTSTATUS scRet;
|
||
PVOID Buffer = NULL;
|
||
scRet = ZwAllocateVirtualMemory(
|
||
NtCurrentProcess(),
|
||
&Buffer,
|
||
0L,
|
||
&cbMemory,
|
||
MEM_COMMIT,
|
||
PAGE_READWRITE
|
||
);
|
||
if (!NT_SUCCESS(scRet))
|
||
{
|
||
return(NULL);
|
||
}
|
||
return(Buffer);
|
||
UNREFERENCED_PARAMETER(Flags);
|
||
}
|
||
|
||
|
||
|
||
//+-------------------------------------------------------------------------
|
||
//
|
||
// Function: SecFree
|
||
//
|
||
// Synopsis:
|
||
//
|
||
// Effects:
|
||
//
|
||
// Arguments:
|
||
//
|
||
// Requires:
|
||
//
|
||
// Returns:
|
||
//
|
||
// Notes:
|
||
//
|
||
//
|
||
//--------------------------------------------------------------------------
|
||
|
||
|
||
void SEC_ENTRY
|
||
SspFree(PVOID pvMemory)
|
||
{
|
||
ULONG Length = 0;
|
||
|
||
(VOID) ZwFreeVirtualMemory(
|
||
NtCurrentProcess(),
|
||
&pvMemory,
|
||
&Length,
|
||
MEM_RELEASE
|
||
);
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
TestSspRoutine(
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Test base SSP functionality
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
--*/
|
||
{
|
||
SECURITY_STATUS SecStatus;
|
||
SECURITY_STATUS AcceptStatus;
|
||
SECURITY_STATUS InitStatus;
|
||
CredHandle ServerCredHandle;
|
||
CredHandle ClientCredentialHandle;
|
||
CtxtHandle ClientContextHandle;
|
||
CtxtHandle ServerContextHandle;
|
||
TimeStamp Lifetime;
|
||
ULONG ContextAttributes;
|
||
ULONG PackageCount, Index;
|
||
PSecPkgInfo PackageInfo = NULL;
|
||
HANDLE Token = NULL;
|
||
static int Calls;
|
||
ULONG ClientFlags;
|
||
ULONG ServerFlags;
|
||
LPWSTR DomainName = NULL;
|
||
LPWSTR UserName = NULL;
|
||
LPWSTR TargetName = NULL;
|
||
UNICODE_STRING TargetString;
|
||
UNICODE_STRING PackageName;
|
||
|
||
|
||
SecBufferDesc NegotiateDesc;
|
||
SecBuffer NegotiateBuffer;
|
||
|
||
SecBufferDesc ChallengeDesc;
|
||
SecBuffer ChallengeBuffer;
|
||
|
||
SecBufferDesc AuthenticateDesc;
|
||
SecBuffer AuthenticateBuffer;
|
||
|
||
SecPkgContext_Sizes ContextSizes;
|
||
SecPkgContext_Names ContextNames;
|
||
SecPkgContext_Lifespan ContextLifespan;
|
||
PSecPkgCredentials_Names CredNames;
|
||
|
||
SecBufferDesc SignMessage;
|
||
SecBuffer SigBuffers[2];
|
||
UCHAR bDataBuffer[20];
|
||
UCHAR bSigBuffer[100];
|
||
|
||
//
|
||
// Allow tests to be disabled
|
||
//
|
||
|
||
|
||
if (!DoTests)
|
||
{
|
||
return;
|
||
}
|
||
|
||
NegotiateBuffer.pvBuffer = NULL;
|
||
ChallengeBuffer.pvBuffer = NULL;
|
||
AuthenticateBuffer.pvBuffer = NULL;
|
||
|
||
SigBuffers[1].pvBuffer = bSigBuffer;
|
||
SigBuffers[1].cbBuffer = sizeof(bSigBuffer);
|
||
SigBuffers[1].BufferType = SECBUFFER_TOKEN;
|
||
|
||
SigBuffers[0].pvBuffer = bDataBuffer;
|
||
SigBuffers[0].cbBuffer = sizeof(bDataBuffer);
|
||
SigBuffers[0].BufferType = SECBUFFER_DATA;
|
||
memset(bDataBuffer,0xeb,sizeof(bDataBuffer));
|
||
|
||
SignMessage.pBuffers = SigBuffers;
|
||
SignMessage.cBuffers = 2;
|
||
SignMessage.ulVersion = 0;
|
||
|
||
DomainName = L"makalu";
|
||
UserName = L"mikesw";
|
||
|
||
|
||
PackageName.Buffer = (LPWSTR) SspAlloc(0,100);
|
||
if (PackageName.Buffer == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
wcscpy(
|
||
PackageName.Buffer,
|
||
L"Kerberos"
|
||
);
|
||
RtlInitUnicodeString(
|
||
&PackageName,
|
||
PackageName.Buffer
|
||
);
|
||
//
|
||
// Get info about the security packages.
|
||
//
|
||
|
||
SecStatus = EnumerateSecurityPackages( &PackageCount, &PackageInfo );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "EnumerateSecurityPackages failed:" );
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
DbgPrint( "PackageCount: %ld\n", PackageCount );
|
||
for (Index = 0; Index < PackageCount ; Index++ )
|
||
{
|
||
DbgPrint( "Package %d:\n",Index);
|
||
DbgPrint( "Name: %ws Comment: %ws\n", PackageInfo[Index].Name, PackageInfo[Index].Comment );
|
||
DbgPrint( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
|
||
PackageInfo[Index].fCapabilities,
|
||
PackageInfo[Index].wVersion,
|
||
PackageInfo[Index].wRPCID,
|
||
PackageInfo[Index].cbMaxToken );
|
||
|
||
|
||
}
|
||
|
||
|
||
#ifdef notdef
|
||
//
|
||
// Get info about the security packages.
|
||
//
|
||
|
||
SecStatus = QuerySecurityPackageInfo( &PackageName, &PackageInfo );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "QuerySecurityPackageInfo failed:" );
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
DbgPrint( "Name: %ws Comment: %ws\n", PackageInfo->Name, PackageInfo->Comment );
|
||
DbgPrint( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
|
||
PackageInfo->fCapabilities,
|
||
PackageInfo->wVersion,
|
||
PackageInfo->wRPCID,
|
||
PackageInfo->cbMaxToken );
|
||
}
|
||
|
||
FreeContextBuffer(PackageInfo);
|
||
#endif
|
||
|
||
//
|
||
// Acquire a credential handle for the server side
|
||
//
|
||
|
||
SecStatus = AcquireCredentialsHandle(
|
||
NULL, // New principal
|
||
&PackageName, // Package Name
|
||
SECPKG_CRED_INBOUND,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&ServerCredHandle,
|
||
&Lifetime );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "AcquireCredentialsHandle failed: ");
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
DbgPrint( "ServerCredHandle: 0x%lx 0x%lx ",
|
||
ServerCredHandle.dwLower, ServerCredHandle.dwUpper );
|
||
PrintTime( "Lifetime: ", Lifetime );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Acquire a credential handle for the client side
|
||
//
|
||
|
||
|
||
|
||
SecStatus = AcquireCredentialsHandle(
|
||
NULL, // New principal
|
||
&PackageName, // Package Name
|
||
SECPKG_CRED_OUTBOUND,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&ClientCredentialHandle,
|
||
&Lifetime );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "AcquireCredentialsHandle failed: " );
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
|
||
if ( !QuietMode ) {
|
||
DbgPrint( "ClientCredentialHandle: 0x%lx 0x%lx ",
|
||
ClientCredentialHandle.dwLower, ClientCredentialHandle.dwUpper );
|
||
PrintTime( "Lifetime: ", Lifetime );
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Query some cred attributes
|
||
//
|
||
|
||
CredNames = SspAlloc(0, sizeof(*CredNames));
|
||
if (CredNames == NULL)
|
||
{
|
||
DbgPrint("Failed to allocate CredNames\n");
|
||
return;
|
||
}
|
||
|
||
SecStatus = QueryCredentialsAttributes(
|
||
&ClientCredentialHandle,
|
||
SECPKG_CRED_ATTR_NAMES,
|
||
CredNames );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "QueryCredentialsAttributes (Client) (names): " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
DbgPrint("Client credential names: %ws\n",CredNames->sUserName);
|
||
FreeContextBuffer(CredNames->sUserName);
|
||
|
||
//
|
||
// Do the same for the client
|
||
//
|
||
|
||
SecStatus = QueryCredentialsAttributes(
|
||
&ServerCredHandle,
|
||
SECPKG_CRED_ATTR_NAMES,
|
||
CredNames );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "QueryCredentialsAttributes (Server) (names): " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
DbgPrint("Server credential names: %ws\n",CredNames->sUserName);
|
||
FreeContextBuffer(CredNames->sUserName);
|
||
|
||
SspFree(CredNames);
|
||
|
||
//
|
||
// Get the NegotiateMessage (ClientSide)
|
||
//
|
||
|
||
NegotiateDesc.ulVersion = 0;
|
||
NegotiateDesc.cBuffers = 1;
|
||
NegotiateDesc.pBuffers = &NegotiateBuffer;
|
||
|
||
NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
|
||
NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
|
||
NegotiateBuffer.pvBuffer = SspAlloc( 0, NegotiateBuffer.cbBuffer );
|
||
if ( NegotiateBuffer.pvBuffer == NULL ) {
|
||
DbgPrint( "Allocate NegotiateMessage failed\n" );
|
||
return;
|
||
}
|
||
|
||
ClientFlags = ISC_REQ_SEQUENCE_DETECT | ISC_REQ_MUTUAL_AUTH; // | ISC_REQ_USE_DCE_STYLE | ISC_REQ_DATAGRAM; // | ISC_REQ_DELEGATE;
|
||
|
||
TargetName = (LPWSTR) SspAlloc(0,100);
|
||
if (TargetName == NULL)
|
||
{
|
||
return;
|
||
}
|
||
|
||
wcscpy(
|
||
TargetName,
|
||
DomainName
|
||
);
|
||
wcscat(
|
||
TargetName,
|
||
L"\\"
|
||
);
|
||
wcscat(
|
||
TargetName,
|
||
UserName
|
||
);
|
||
|
||
RtlInitUnicodeString(
|
||
&TargetString,
|
||
TargetName
|
||
);
|
||
|
||
InitStatus = InitializeSecurityContext(
|
||
&ClientCredentialHandle,
|
||
NULL, // No Client context yet
|
||
&TargetString, // Faked target name
|
||
ClientFlags,
|
||
0, // Reserved 1
|
||
SECURITY_NATIVE_DREP,
|
||
NULL, // No initial input token
|
||
0, // Reserved 2
|
||
&ClientContextHandle,
|
||
&NegotiateDesc,
|
||
&ContextAttributes,
|
||
&Lifetime );
|
||
|
||
if ( InitStatus != STATUS_SUCCESS ) {
|
||
if ( !QuietMode || !NT_SUCCESS(InitStatus) ) {
|
||
DbgPrint( "InitializeSecurityContext (negotiate): " );
|
||
PrintStatus( InitStatus );
|
||
}
|
||
if ( !NT_SUCCESS(InitStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
DbgPrint( "\n\nNegotiate Message:\n" );
|
||
|
||
DbgPrint( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
|
||
ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
|
||
ContextAttributes );
|
||
PrintTime( "Lifetime: ", Lifetime );
|
||
|
||
// DumpBuffer( NegotiateBuffer.pvBuffer, NegotiateBuffer.cbBuffer );
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
//
|
||
// Get the ChallengeMessage (ServerSide)
|
||
//
|
||
|
||
NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
|
||
ChallengeDesc.ulVersion = 0;
|
||
ChallengeDesc.cBuffers = 1;
|
||
ChallengeDesc.pBuffers = &ChallengeBuffer;
|
||
|
||
ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
|
||
ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
|
||
ChallengeBuffer.pvBuffer = SspAlloc( 0, ChallengeBuffer.cbBuffer );
|
||
if ( ChallengeBuffer.pvBuffer == NULL ) {
|
||
DbgPrint( "Allocate ChallengeMessage failed\n");
|
||
return;
|
||
}
|
||
ServerFlags = 0;
|
||
|
||
AcceptStatus = AcceptSecurityContext(
|
||
&ServerCredHandle,
|
||
NULL, // No Server context yet
|
||
&NegotiateDesc,
|
||
ServerFlags,
|
||
SECURITY_NATIVE_DREP,
|
||
&ServerContextHandle,
|
||
&ChallengeDesc,
|
||
&ContextAttributes,
|
||
&Lifetime );
|
||
|
||
if ( AcceptStatus != STATUS_SUCCESS ) {
|
||
if ( !QuietMode || !NT_SUCCESS(AcceptStatus) ) {
|
||
DbgPrint( "AcceptSecurityContext (Challenge): " );
|
||
PrintStatus( AcceptStatus );
|
||
}
|
||
if ( !NT_SUCCESS(AcceptStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
DbgPrint( "\n\nChallenge Message:\n" );
|
||
|
||
DbgPrint( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
|
||
ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
|
||
ContextAttributes );
|
||
PrintTime( "Lifetime: ", Lifetime );
|
||
|
||
// DumpBuffer( ChallengeBuffer.pvBuffer, ChallengeBuffer.cbBuffer );
|
||
}
|
||
|
||
|
||
|
||
|
||
if (InitStatus != STATUS_SUCCESS)
|
||
{
|
||
|
||
//
|
||
// Get the AuthenticateMessage (ClientSide)
|
||
//
|
||
|
||
ChallengeBuffer.BufferType |= SECBUFFER_READONLY;
|
||
AuthenticateDesc.ulVersion = 0;
|
||
AuthenticateDesc.cBuffers = 1;
|
||
AuthenticateDesc.pBuffers = &AuthenticateBuffer;
|
||
|
||
AuthenticateBuffer.cbBuffer = PackageInfo->cbMaxToken;
|
||
AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
|
||
AuthenticateBuffer.pvBuffer = SspAlloc( 0, AuthenticateBuffer.cbBuffer );
|
||
if ( AuthenticateBuffer.pvBuffer == NULL ) {
|
||
DbgPrint( "Allocate AuthenticateMessage failed: \n" );
|
||
return;
|
||
}
|
||
|
||
SecStatus = InitializeSecurityContext(
|
||
NULL,
|
||
&ClientContextHandle,
|
||
NULL,
|
||
0,
|
||
0, // Reserved 1
|
||
SECURITY_NATIVE_DREP,
|
||
&ChallengeDesc,
|
||
0, // Reserved 2
|
||
&ClientContextHandle,
|
||
&AuthenticateDesc,
|
||
&ContextAttributes,
|
||
&Lifetime );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "InitializeSecurityContext (Authenticate): " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
DbgPrint( "\n\nAuthenticate Message:\n" );
|
||
|
||
DbgPrint( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
|
||
ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
|
||
ContextAttributes );
|
||
PrintTime( "Lifetime: ", Lifetime );
|
||
|
||
// DumpBuffer( AuthenticateBuffer.pvBuffer, AuthenticateBuffer.cbBuffer );
|
||
}
|
||
|
||
if (AcceptStatus != STATUS_SUCCESS)
|
||
{
|
||
|
||
//
|
||
// Finally authenticate the user (ServerSide)
|
||
//
|
||
|
||
AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
|
||
|
||
SecStatus = AcceptSecurityContext(
|
||
NULL,
|
||
&ServerContextHandle,
|
||
&AuthenticateDesc,
|
||
0,
|
||
SECURITY_NATIVE_DREP,
|
||
&ServerContextHandle,
|
||
NULL,
|
||
&ContextAttributes,
|
||
&Lifetime );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "AcceptSecurityContext (Challenge): " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
DbgPrint( "\n\nFinal Authentication:\n" );
|
||
|
||
DbgPrint( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
|
||
ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
|
||
ContextAttributes );
|
||
PrintTime( "Lifetime: ", Lifetime );
|
||
DbgPrint(" \n" );
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
SecStatus = QueryContextAttributes(
|
||
&ServerContextHandle,
|
||
SECPKG_ATTR_NAMES,
|
||
&ContextNames );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "QueryContextAttributes (Server) (names): " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
DbgPrint("Server Context names: %ws\n",ContextNames.sUserName);
|
||
FreeContextBuffer(ContextNames.sUserName);
|
||
|
||
|
||
//
|
||
// Impersonate the client (ServerSide)
|
||
//
|
||
|
||
SecStatus = ImpersonateSecurityContext( &ServerContextHandle );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "ImpersonateSecurityContext: " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
SecStatus = RevertSecurityContext( &ServerContextHandle );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "RevertSecurityContext: " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
#ifdef notdef
|
||
//
|
||
// Impersonate the client manually
|
||
//
|
||
|
||
SecStatus = QuerySecurityContextToken( &ServerContextHandle,&Token );
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "ImpersonateSecurityContext: " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
NtClose(Token);
|
||
|
||
#endif
|
||
#ifdef notdef
|
||
//
|
||
// Sign a message
|
||
//
|
||
|
||
SecStatus = MakeSignature(
|
||
&ClientContextHandle,
|
||
0,
|
||
&SignMessage,
|
||
0 );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "MakeSignature: " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
|
||
DbgPrint("\n Signature: \n");
|
||
// DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
|
||
|
||
}
|
||
|
||
|
||
//
|
||
// Verify the signature
|
||
//
|
||
|
||
SecStatus = VerifySignature(
|
||
&ServerContextHandle,
|
||
&SignMessage,
|
||
0,
|
||
0 );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "VerifySignature: " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Sign a message, this time to check if it can detect a change in the
|
||
// message
|
||
//
|
||
|
||
SecStatus = MakeSignature(
|
||
&ClientContextHandle,
|
||
0,
|
||
&SignMessage,
|
||
0 );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "MakeSignature: " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
if ( !QuietMode ) {
|
||
|
||
DbgPrint("\n Signature: \n");
|
||
// DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
|
||
|
||
}
|
||
|
||
//
|
||
// Mess up the message to see if VerifySignature works
|
||
//
|
||
|
||
bDataBuffer[10] = 0xec;
|
||
|
||
//
|
||
// Verify the signature
|
||
//
|
||
|
||
SecStatus = VerifySignature(
|
||
&ServerContextHandle,
|
||
&SignMessage,
|
||
0,
|
||
0 );
|
||
|
||
if ( SecStatus != SEC_E_MESSAGE_ALTERED ) {
|
||
DbgPrint( "VerifySignature: " );
|
||
PrintStatus( SecStatus );
|
||
if ( !NT_SUCCESS(SecStatus) ) {
|
||
return;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
//
|
||
// Delete both contexts.
|
||
//
|
||
|
||
|
||
SecStatus = DeleteSecurityContext( &ClientContextHandle );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "DeleteSecurityContext failed: " );
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
SecStatus = DeleteSecurityContext( &ServerContextHandle );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "DeleteSecurityContext failed: " );
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// Free both credential handles
|
||
//
|
||
|
||
SecStatus = FreeCredentialsHandle( &ServerCredHandle );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "FreeCredentialsHandle failed: " );
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
SecStatus = FreeCredentialsHandle( &ClientCredentialHandle );
|
||
|
||
if ( SecStatus != STATUS_SUCCESS ) {
|
||
DbgPrint( "FreeCredentialsHandle failed: " );
|
||
PrintStatus( SecStatus );
|
||
return;
|
||
}
|
||
|
||
|
||
//
|
||
// Final Cleanup
|
||
//
|
||
|
||
if (PackageInfo != NULL)
|
||
{
|
||
FreeContextBuffer(PackageInfo);
|
||
}
|
||
|
||
if (PackageName.Buffer != NULL)
|
||
{
|
||
SspFree(PackageName.Buffer);
|
||
}
|
||
if ( NegotiateBuffer.pvBuffer != NULL ) {
|
||
(VOID) SspFree( NegotiateBuffer.pvBuffer );
|
||
}
|
||
|
||
if ( ChallengeBuffer.pvBuffer != NULL ) {
|
||
(VOID) SspFree( ChallengeBuffer.pvBuffer );
|
||
}
|
||
|
||
if ( AuthenticateBuffer.pvBuffer != NULL ) {
|
||
(VOID) SspFree( AuthenticateBuffer.pvBuffer );
|
||
}
|
||
|
||
if (TargetName != NULL)
|
||
{
|
||
SspFree(TargetName);
|
||
}
|
||
}
|
||
|
||
|