|
|
//
//
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#ifdef KERNEL_MODE
#include <ntos.h>
#endif
#include <security.h>
#include <cryptdll.h>
#include <crypt.h>
#include <kerbcon.h>
#include <lmcons.h>
#ifdef WIN32_CHICAGO
NTSTATUS MyRtlUpcaseUnicodeStringToOemString( OUT POEM_STRING DestinationString, IN PUNICODE_STRING SourceString, IN BOOLEAN AllocateDestinationString ); #define RtlUpcaseUnicodeStringToOemString(x, y, z) MyRtlUpcaseUnicodeStringToOemString(x, y, z)
#endif // WIN32_CHICAGO
typedef struct _LM_STATE_BUFFER { LM_OWF_PASSWORD Password; } LM_STATE_BUFFER, *PLM_STATE_BUFFER;
NTSTATUS LmWrapInitialize(ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer);
NTSTATUS LmWrapSum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData );
NTSTATUS LmWrapFinalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum);
NTSTATUS LmWrapFinish(PCHECKSUM_BUFFER * ppcsBuffer);
CHECKSUM_FUNCTION csfLM = { KERB_CHECKSUM_LM, LM_OWF_PASSWORD_LENGTH, CKSUM_COLLISION, LmWrapInitialize, LmWrapSum, LmWrapFinalize, LmWrapFinish // Note : missing last function
};
#ifdef KERNEL_MODE
#pragma alloc_text( PAGEMSG, LmWrapInitialize )
#pragma alloc_text( PAGEMSG, LmWrapSum )
#pragma alloc_text( PAGEMSG, LmWrapFinalize )
#pragma alloc_text( PAGEMSG, LmWrapFinish );
#endif
NTSTATUS LmWrapInitialize( ULONG dwSeed, PCHECKSUM_BUFFER * ppcsBuffer) { PLM_STATE_BUFFER pContext;
#ifdef KERNEL_MODE
pContext = ExAllocatePool( NonPagedPool, sizeof( LM_STATE_BUFFER ) ); #else
pContext = LocalAlloc( LMEM_ZEROINIT, sizeof( LM_STATE_BUFFER ) ); #endif
if ( pContext != NULL ) { *ppcsBuffer = pContext;
return( SEC_E_OK ); }
return( STATUS_INSUFFICIENT_RESOURCES ); }
NTSTATUS LmCalculateLmPassword( IN PUNICODE_STRING NtPassword, OUT PCHAR *LmPasswordBuffer )
/*++
Routine Description:
This service converts an NT password into a LM password.
Parameters:
NtPassword - The Nt password to be converted.
LmPasswordBuffer - On successful return, points at the LM password The buffer should be freed using MIDL_user_free
Return Values:
STATUS_SUCCESS - LMPassword contains the LM version of the password.
STATUS_NULL_LM_PASSWORD - The password is too complex to be represented by a LM password. The LM password returned is a NULL string.
--*/ {
#define LM_BUFFER_LENGTH (LM20_PWLEN + 1)
NTSTATUS NtStatus; ANSI_STRING LmPassword;
//
// Prepare for failure
//
*LmPasswordBuffer = NULL;
//
// Compute the Ansi version to the Unicode password.
//
// The Ansi version of the Cleartext password is at most 14 bytes long,
// exists in a trailing zero filled 15 byte buffer,
// is uppercased.
//
#ifdef KERNEL_MODE
LmPassword.Buffer = ExAllocatePool(NonPagedPool,LM_BUFFER_LENGTH); #else
LmPassword.Buffer = LocalAlloc(0,LM_BUFFER_LENGTH); #endif
if (LmPassword.Buffer == NULL) { return(STATUS_INSUFFICIENT_RESOURCES); }
LmPassword.MaximumLength = LmPassword.Length = LM_BUFFER_LENGTH; RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH );
NtStatus = RtlUpcaseUnicodeStringToOemString( &LmPassword, NtPassword, FALSE );
if ( !NT_SUCCESS(NtStatus) ) {
//
// The password is longer than the max LM password length
//
NtStatus = STATUS_NULL_LM_PASSWORD; // Informational return code
RtlZeroMemory( LmPassword.Buffer, LM_BUFFER_LENGTH );
}
//
// Return a pointer to the allocated LM password
//
if (NT_SUCCESS(NtStatus)) {
*LmPasswordBuffer = LmPassword.Buffer;
} else {
#ifdef KERNEL_MODE
ExFreePool(LmPassword.Buffer); #else
LocalFree(LmPassword.Buffer); #endif
}
return(NtStatus); }
NTSTATUS LmWrapSum( PCHECKSUM_BUFFER pcsBuffer, ULONG cbData, PUCHAR pbData ) { PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer; UNICODE_STRING TempString; PUCHAR LmPassword; NTSTATUS Status;
TempString.Length = TempString.MaximumLength = (USHORT) cbData; TempString.Buffer = (LPWSTR) pbData;
Status = LmCalculateLmPassword( &TempString, &LmPassword ); if (!NT_SUCCESS(Status)) { return(Status); }
Status = RtlCalculateLmOwfPassword( LmPassword, &pContext->Password ); #ifdef KERNEL_MODE
ExFreePool(LmPassword); #else
LocalFree(LmPassword); #endif
return( Status );
}
NTSTATUS LmWrapFinalize( PCHECKSUM_BUFFER pcsBuffer, PUCHAR pbSum) { PLM_STATE_BUFFER pContext = (PLM_STATE_BUFFER) pcsBuffer;
RtlCopyMemory( pbSum, &pContext->Password, LM_OWF_PASSWORD_LENGTH );
return( STATUS_SUCCESS );
}
NTSTATUS LmWrapFinish( PCHECKSUM_BUFFER * ppcsBuffer) {
RtlZeroMemory( *ppcsBuffer, sizeof( PLM_STATE_BUFFER ) );
#ifdef KERNEL_MODE
ExFreePool( *ppcsBuffer ); #else
LocalFree( *ppcsBuffer ); #endif
*ppcsBuffer = NULL ;
return( STATUS_SUCCESS );
}
|