libwinpr-sspi: simplify NTLM header and fields read/write
This commit is contained in:
parent
3ff86d0501
commit
633e0f90bf
@ -54,6 +54,14 @@ typedef float FLOAT;
|
|||||||
typedef unsigned char UCHAR, *PUCHAR;
|
typedef unsigned char UCHAR, *PUCHAR;
|
||||||
typedef short SHORT;
|
typedef short SHORT;
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef void* HANDLE, *LPHANDLE;
|
typedef void* HANDLE, *LPHANDLE;
|
||||||
typedef DWORD HCALL;
|
typedef DWORD HCALL;
|
||||||
typedef int INT, *LPINT;
|
typedef int INT, *LPINT;
|
||||||
|
@ -136,14 +136,21 @@ struct _NTLM_VERSION_INFO
|
|||||||
};
|
};
|
||||||
typedef struct _NTLM_VERSION_INFO NTLM_VERSION_INFO;
|
typedef struct _NTLM_VERSION_INFO NTLM_VERSION_INFO;
|
||||||
|
|
||||||
struct _NTLM_MESSAGE_FIELD
|
struct _NTLM_MESSAGE_FIELDS
|
||||||
{
|
{
|
||||||
UINT16 Len;
|
UINT16 Len;
|
||||||
UINT16 MaxLen;
|
UINT16 MaxLen;
|
||||||
PBYTE Buffer;
|
PBYTE Buffer;
|
||||||
UINT32 BufferOffset;
|
UINT32 BufferOffset;
|
||||||
};
|
};
|
||||||
typedef struct _NTLM_MESSAGE_FIELD NTLM_MESSAGE_FIELD;
|
typedef struct _NTLM_MESSAGE_FIELDS NTLM_MESSAGE_FIELDS;
|
||||||
|
|
||||||
|
struct _NTLM_MESSAGE_HEADER
|
||||||
|
{
|
||||||
|
BYTE Signature[8];
|
||||||
|
UINT32 MessageType;
|
||||||
|
};
|
||||||
|
typedef struct _NTLM_MESSAGE_HEADER NTLM_MESSAGE_HEADER;
|
||||||
|
|
||||||
struct _NTLM_NEGOTIATE_MESSAGE
|
struct _NTLM_NEGOTIATE_MESSAGE
|
||||||
{
|
{
|
||||||
@ -151,8 +158,8 @@ struct _NTLM_NEGOTIATE_MESSAGE
|
|||||||
UINT32 MessageType;
|
UINT32 MessageType;
|
||||||
UINT32 NegotiateFlags;
|
UINT32 NegotiateFlags;
|
||||||
NTLM_VERSION_INFO Version;
|
NTLM_VERSION_INFO Version;
|
||||||
NTLM_MESSAGE_FIELD DomainName;
|
NTLM_MESSAGE_FIELDS DomainName;
|
||||||
NTLM_MESSAGE_FIELD Workstation;
|
NTLM_MESSAGE_FIELDS Workstation;
|
||||||
};
|
};
|
||||||
typedef struct _NTLM_NEGOTIATE_MESSAGE NTLM_NEGOTIATE_MESSAGE;
|
typedef struct _NTLM_NEGOTIATE_MESSAGE NTLM_NEGOTIATE_MESSAGE;
|
||||||
|
|
||||||
@ -163,8 +170,8 @@ struct _NTLM_CHALLENGE_MESSAGE
|
|||||||
UINT32 NegotiateFlags;
|
UINT32 NegotiateFlags;
|
||||||
BYTE ServerChallenge[8];
|
BYTE ServerChallenge[8];
|
||||||
NTLM_VERSION_INFO Version;
|
NTLM_VERSION_INFO Version;
|
||||||
NTLM_MESSAGE_FIELD TargetName;
|
NTLM_MESSAGE_FIELDS TargetName;
|
||||||
NTLM_MESSAGE_FIELD TargetInfo;
|
NTLM_MESSAGE_FIELDS TargetInfo;
|
||||||
};
|
};
|
||||||
typedef struct _NTLM_CHALLENGE_MESSAGE NTLM_CHALLENGE_MESSAGE;
|
typedef struct _NTLM_CHALLENGE_MESSAGE NTLM_CHALLENGE_MESSAGE;
|
||||||
|
|
||||||
@ -174,12 +181,12 @@ struct _NTLM_AUTHENTICATE_MESSAGE
|
|||||||
UINT32 MessageType;
|
UINT32 MessageType;
|
||||||
UINT32 NegotiateFlags;
|
UINT32 NegotiateFlags;
|
||||||
NTLM_VERSION_INFO Version;
|
NTLM_VERSION_INFO Version;
|
||||||
NTLM_MESSAGE_FIELD DomainName;
|
NTLM_MESSAGE_FIELDS DomainName;
|
||||||
NTLM_MESSAGE_FIELD UserName;
|
NTLM_MESSAGE_FIELDS UserName;
|
||||||
NTLM_MESSAGE_FIELD Workstation;
|
NTLM_MESSAGE_FIELDS Workstation;
|
||||||
NTLM_MESSAGE_FIELD LmChallengeResponse;
|
NTLM_MESSAGE_FIELDS LmChallengeResponse;
|
||||||
NTLM_MESSAGE_FIELD NtChallengeResponse;
|
NTLM_MESSAGE_FIELDS NtChallengeResponse;
|
||||||
NTLM_MESSAGE_FIELD EncryptedRandomSessionKey;
|
NTLM_MESSAGE_FIELDS EncryptedRandomSessionKey;
|
||||||
BYTE MessageIntegrityCheck[16];
|
BYTE MessageIntegrityCheck[16];
|
||||||
};
|
};
|
||||||
typedef struct _NTLM_AUTHENTICATE_MESSAGE NTLM_AUTHENTICATE_MESSAGE;
|
typedef struct _NTLM_AUTHENTICATE_MESSAGE NTLM_AUTHENTICATE_MESSAGE;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
#include "ntlm_message.h"
|
#include "ntlm_message.h"
|
||||||
|
|
||||||
static const char NTLM_SIGNATURE[] = "NTLMSSP";
|
static const char NTLM_SIGNATURE[8] = "NTLMSSP\0";
|
||||||
|
|
||||||
static const char* const NTLM_NEGOTIATE_STRINGS[] =
|
static const char* const NTLM_NEGOTIATE_STRINGS[] =
|
||||||
{
|
{
|
||||||
@ -86,6 +86,58 @@ void ntlm_print_negotiate_flags(UINT32 flags)
|
|||||||
printf("}\n");
|
printf("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ntlm_read_message_header(PStream s, NTLM_MESSAGE_HEADER* header)
|
||||||
|
{
|
||||||
|
StreamRead(s, header->Signature, sizeof(NTLM_SIGNATURE));
|
||||||
|
StreamRead_UINT32(s, header->MessageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ntlm_write_message_header(PStream s, NTLM_MESSAGE_HEADER* header)
|
||||||
|
{
|
||||||
|
StreamWrite(s, header->Signature, sizeof(NTLM_SIGNATURE));
|
||||||
|
StreamWrite_UINT32(s, header->MessageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ntlm_populate_message_header(NTLM_MESSAGE_HEADER* header, UINT32 MessageType)
|
||||||
|
{
|
||||||
|
CopyMemory(header->Signature, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE));
|
||||||
|
header->MessageType = MessageType;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL ntlm_validate_message_header(PStream s, NTLM_MESSAGE_HEADER* header, UINT32 MessageType)
|
||||||
|
{
|
||||||
|
if (memcmp(header->Signature, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0)
|
||||||
|
{
|
||||||
|
printf("Unexpected NTLM signature: %s, expected:%s\n", header->Signature, NTLM_SIGNATURE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header->MessageType != MessageType)
|
||||||
|
{
|
||||||
|
printf("Unexpected NTLM message type: %d, expected: %d\n", header->MessageType, MessageType);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ntlm_read_message_fields(PStream s, NTLM_MESSAGE_FIELDS* fields)
|
||||||
|
{
|
||||||
|
StreamRead_UINT16(s, fields->Len); /* Len (2 bytes) */
|
||||||
|
StreamRead_UINT16(s, fields->MaxLen); /* MaxLen (2 bytes) */
|
||||||
|
StreamRead_UINT32(s, fields->BufferOffset); /* BufferOffset (4 bytes) */
|
||||||
|
}
|
||||||
|
|
||||||
|
void ntlm_write_message_fields(PStream s, NTLM_MESSAGE_FIELDS* fields)
|
||||||
|
{
|
||||||
|
if (fields->MaxLen < 1)
|
||||||
|
fields->MaxLen = fields->Len;
|
||||||
|
|
||||||
|
StreamWrite_UINT16(s, fields->Len); /* Len (2 bytes) */
|
||||||
|
StreamWrite_UINT16(s, fields->MaxLen); /* MaxLen (2 bytes) */
|
||||||
|
StreamWrite_UINT32(s, fields->BufferOffset); /* BufferOffset (4 bytes) */
|
||||||
|
}
|
||||||
|
|
||||||
SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buffer)
|
SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buffer)
|
||||||
{
|
{
|
||||||
PStream s;
|
PStream s;
|
||||||
@ -95,17 +147,9 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
ZeroMemory(&message, sizeof(message));
|
ZeroMemory(&message, sizeof(message));
|
||||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||||
|
|
||||||
StreamRead(s, message.Signature, 8);
|
ntlm_read_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||||
StreamRead_UINT32(s, message.MessageType);
|
|
||||||
|
|
||||||
if (memcmp(message.Signature, NTLM_SIGNATURE, 8) != 0)
|
if (!ntlm_validate_message_header(s, (NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_NEGOTIATE))
|
||||||
{
|
|
||||||
printf("Unexpected NTLM signature: %s, expected:%s\n", message.Signature, NTLM_SIGNATURE);
|
|
||||||
PStreamFreeDetach(s);
|
|
||||||
return SEC_E_INVALID_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.MessageType != MESSAGE_TYPE_NEGOTIATE)
|
|
||||||
{
|
{
|
||||||
PStreamFreeDetach(s);
|
PStreamFreeDetach(s);
|
||||||
return SEC_E_INVALID_TOKEN;
|
return SEC_E_INVALID_TOKEN;
|
||||||
@ -118,16 +162,12 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
||||||
|
|
||||||
/* DomainNameFields (8 bytes) */
|
/* DomainNameFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.DomainName.Len); /* DomainNameLen */
|
ntlm_read_message_fields(s, &(message.DomainName));
|
||||||
StreamRead_UINT16(s, message.DomainName.MaxLen); /* DomainNameMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.DomainName.BufferOffset); /* DomainNameBufferOffset */
|
|
||||||
|
|
||||||
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
||||||
|
|
||||||
/* WorkstationFields (8 bytes) */
|
/* WorkstationFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.Workstation.Len); /* WorkstationLen */
|
ntlm_read_message_fields(s, &(message.Workstation));
|
||||||
StreamRead_UINT16(s, message.Workstation.MaxLen); /* WorkstationMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.Workstation.BufferOffset); /* WorkstationBufferOffset */
|
|
||||||
|
|
||||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
{
|
{
|
||||||
@ -164,8 +204,10 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
ZeroMemory(&message, sizeof(message));
|
ZeroMemory(&message, sizeof(message));
|
||||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||||
|
|
||||||
StreamWrite(s, NTLM_SIGNATURE, 8); /* Signature (8 bytes) */
|
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_NEGOTIATE);
|
||||||
StreamWrite_UINT32(s, MESSAGE_TYPE_NEGOTIATE); /* MessageType */
|
|
||||||
|
/* Message Header (12 bytes) */
|
||||||
|
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||||
|
|
||||||
if (context->ntlm_v2)
|
if (context->ntlm_v2)
|
||||||
{
|
{
|
||||||
@ -207,16 +249,12 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
||||||
|
|
||||||
/* DomainNameFields (8 bytes) */
|
/* DomainNameFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, 0); /* DomainNameLen */
|
ntlm_write_message_fields(s, &(message.DomainName));
|
||||||
StreamWrite_UINT16(s, 0); /* DomainNameMaxLen */
|
|
||||||
StreamWrite_UINT32(s, 0); /* DomainNameBufferOffset */
|
|
||||||
|
|
||||||
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
||||||
|
|
||||||
/* WorkstationFields (8 bytes) */
|
/* WorkstationFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, 0); /* WorkstationLen */
|
ntlm_write_message_fields(s, &(message.Workstation));
|
||||||
StreamWrite_UINT16(s, 0); /* WorkstationMaxLen */
|
|
||||||
StreamWrite_UINT32(s, 0); /* WorkstationBufferOffset */
|
|
||||||
|
|
||||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
{
|
{
|
||||||
@ -266,17 +304,9 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
ZeroMemory(&message, sizeof(message));
|
ZeroMemory(&message, sizeof(message));
|
||||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||||
|
|
||||||
StreamRead(s, message.Signature, 8);
|
ntlm_read_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||||
StreamRead_UINT32(s, message.MessageType);
|
|
||||||
|
|
||||||
if (memcmp(message.Signature, NTLM_SIGNATURE, 8) != 0)
|
if (!ntlm_validate_message_header(s, (NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_CHALLENGE))
|
||||||
{
|
|
||||||
printf("Unexpected NTLM signature: %s, expected:%s\n", message.Signature, NTLM_SIGNATURE);
|
|
||||||
PStreamFreeDetach(s);
|
|
||||||
return SEC_E_INVALID_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.MessageType != MESSAGE_TYPE_CHALLENGE)
|
|
||||||
{
|
{
|
||||||
PStreamFreeDetach(s);
|
PStreamFreeDetach(s);
|
||||||
return SEC_E_INVALID_TOKEN;
|
return SEC_E_INVALID_TOKEN;
|
||||||
@ -285,9 +315,7 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
StartOffset = StreamGetPointer(s) - 12;
|
StartOffset = StreamGetPointer(s) - 12;
|
||||||
|
|
||||||
/* TargetNameFields (8 bytes) */
|
/* TargetNameFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.TargetName.Len); /* TargetNameLen (2 bytes) */
|
ntlm_read_message_fields(s, &(message.TargetName));
|
||||||
StreamRead_UINT16(s, message.TargetName.MaxLen); /* TargetNameMaxLen (2 bytes) */
|
|
||||||
StreamRead_UINT32(s, message.TargetName.BufferOffset); /* TargetNameBufferOffset (4 bytes) */
|
|
||||||
|
|
||||||
StreamRead_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamRead_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
@ -299,9 +327,7 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
StreamSeek(s, 8); /* Reserved (8 bytes), should be ignored */
|
StreamSeek(s, 8); /* Reserved (8 bytes), should be ignored */
|
||||||
|
|
||||||
/* TargetInfoFields (8 bytes) */
|
/* TargetInfoFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.TargetInfo.Len); /* TargetInfoLen (2 bytes) */
|
ntlm_read_message_fields(s, &(message.TargetInfo));
|
||||||
StreamRead_UINT16(s, message.TargetInfo.MaxLen); /* TargetInfoMaxLen (2 bytes) */
|
|
||||||
StreamRead_UINT32(s, message.TargetInfo.BufferOffset); /* TargetInfoBufferOffset (4 bytes) */
|
|
||||||
|
|
||||||
/* only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
/* only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
||||||
|
|
||||||
@ -466,8 +492,10 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
ZeroMemory(&message, sizeof(message));
|
ZeroMemory(&message, sizeof(message));
|
||||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||||
|
|
||||||
StreamWrite(s, NTLM_SIGNATURE, 8); /* Signature (8 bytes) */
|
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_CHALLENGE);
|
||||||
StreamWrite_UINT32(s, MESSAGE_TYPE_CHALLENGE); /* MessageType */
|
|
||||||
|
/* Message Header (12 bytes) */
|
||||||
|
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||||
|
|
||||||
if (context->NegotiateFlags & NTLMSSP_REQUEST_TARGET)
|
if (context->NegotiateFlags & NTLMSSP_REQUEST_TARGET)
|
||||||
{
|
{
|
||||||
@ -502,9 +530,7 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
message.TargetInfo.BufferOffset = message.TargetName.BufferOffset + message.TargetName.Len;
|
message.TargetInfo.BufferOffset = message.TargetName.BufferOffset + message.TargetName.Len;
|
||||||
|
|
||||||
/* TargetNameFields (8 bytes) */
|
/* TargetNameFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.TargetName.Len); /* TargetNameLen (2 bytes) */
|
ntlm_write_message_fields(s, &(message.TargetName));
|
||||||
StreamWrite_UINT16(s, message.TargetName.Len); /* TargetNameMaxLen (2 bytes) */
|
|
||||||
StreamWrite_UINT32(s, message.TargetName.BufferOffset); /* TargetNameBufferOffset (4 bytes) */
|
|
||||||
|
|
||||||
StreamWrite_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamWrite_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
@ -512,9 +538,7 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
StreamZero(s, 8); /* Reserved (8 bytes), should be ignored */
|
StreamZero(s, 8); /* Reserved (8 bytes), should be ignored */
|
||||||
|
|
||||||
/* TargetInfoFields (8 bytes) */
|
/* TargetInfoFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.TargetInfo.Len); /* TargetInfoLen (2 bytes) */
|
ntlm_write_message_fields(s, &(message.TargetInfo));
|
||||||
StreamWrite_UINT16(s, message.TargetInfo.Len); /* TargetInfoMaxLen (2 bytes) */
|
|
||||||
StreamWrite_UINT32(s, message.TargetInfo.BufferOffset); /* TargetInfoBufferOffset (4 bytes) */
|
|
||||||
|
|
||||||
/* only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
/* only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
||||||
|
|
||||||
@ -574,55 +598,35 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||||||
ZeroMemory(&message, sizeof(message));
|
ZeroMemory(&message, sizeof(message));
|
||||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||||
|
|
||||||
StreamRead(s, message.Signature, 8);
|
ntlm_read_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||||
StreamRead_UINT32(s, message.MessageType);
|
|
||||||
|
|
||||||
if (memcmp(message.Signature, NTLM_SIGNATURE, 8) != 0)
|
if (!ntlm_validate_message_header(s, (NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_AUTHENTICATE))
|
||||||
{
|
|
||||||
printf("Unexpected NTLM signature: %s, expected:%s\n", message.Signature, NTLM_SIGNATURE);
|
|
||||||
PStreamFreeDetach(s);
|
|
||||||
return SEC_E_INVALID_TOKEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.MessageType != MESSAGE_TYPE_AUTHENTICATE)
|
|
||||||
{
|
{
|
||||||
PStreamFreeDetach(s);
|
PStreamFreeDetach(s);
|
||||||
return SEC_E_INVALID_TOKEN;
|
return SEC_E_INVALID_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LmChallengeResponseFields (8 bytes) */
|
/* LmChallengeResponseFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.LmChallengeResponse.Len); /* LmChallengeResponseLen */
|
ntlm_read_message_fields(s, &(message.LmChallengeResponse));
|
||||||
StreamRead_UINT16(s, message.LmChallengeResponse.MaxLen); /* LmChallengeResponseMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.LmChallengeResponse.BufferOffset); /* LmChallengeResponseBufferOffset */
|
|
||||||
|
|
||||||
/* NtChallengeResponseFields (8 bytes) */
|
/* NtChallengeResponseFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.NtChallengeResponse.Len); /* NtChallengeResponseLen */
|
ntlm_read_message_fields(s, &(message.NtChallengeResponse));
|
||||||
StreamRead_UINT16(s, message.NtChallengeResponse.MaxLen); /* NtChallengeResponseMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.NtChallengeResponse.BufferOffset); /* NtChallengeResponseBufferOffset */
|
|
||||||
|
|
||||||
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
||||||
|
|
||||||
/* DomainNameFields (8 bytes) */
|
/* DomainNameFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.DomainName.Len); /* DomainNameLen */
|
ntlm_read_message_fields(s, &(message.DomainName));
|
||||||
StreamRead_UINT16(s, message.DomainName.MaxLen); /* DomainNameMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.DomainName.BufferOffset); /* DomainNameBufferOffset */
|
|
||||||
|
|
||||||
/* UserNameFields (8 bytes) */
|
/* UserNameFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.UserName.Len); /* UserNameLen */
|
ntlm_read_message_fields(s, &(message.UserName));
|
||||||
StreamRead_UINT16(s, message.UserName.MaxLen); /* UserNameMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.UserName.BufferOffset); /* UserNameBufferOffset */
|
|
||||||
|
|
||||||
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
||||||
|
|
||||||
/* WorkstationFields (8 bytes) */
|
/* WorkstationFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.Workstation.Len); /* WorkstationLen */
|
ntlm_read_message_fields(s, &(message.Workstation));
|
||||||
StreamRead_UINT16(s, message.Workstation.MaxLen); /* WorkstationMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.Workstation.BufferOffset); /* WorkstationBufferOffset */
|
|
||||||
|
|
||||||
/* EncryptedRandomSessionKeyFields (8 bytes) */
|
/* EncryptedRandomSessionKeyFields (8 bytes) */
|
||||||
StreamRead_UINT16(s, message.EncryptedRandomSessionKey.Len); /* EncryptedRandomSessionKeyLen */
|
ntlm_read_message_fields(s, &(message.EncryptedRandomSessionKey));
|
||||||
StreamRead_UINT16(s, message.EncryptedRandomSessionKey.MaxLen); /* EncryptedRandomSessionKeyMaxLen */
|
|
||||||
StreamRead_UINT32(s, message.EncryptedRandomSessionKey.BufferOffset); /* EncryptedRandomSessionKeyBufferOffset */
|
|
||||||
|
|
||||||
StreamRead_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamRead_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
@ -900,42 +904,32 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||||||
message.NtChallengeResponse.BufferOffset = message.LmChallengeResponse.BufferOffset + message.LmChallengeResponse.Len;
|
message.NtChallengeResponse.BufferOffset = message.LmChallengeResponse.BufferOffset + message.LmChallengeResponse.Len;
|
||||||
message.EncryptedRandomSessionKey.BufferOffset = message.NtChallengeResponse.BufferOffset + message.NtChallengeResponse.Len;
|
message.EncryptedRandomSessionKey.BufferOffset = message.NtChallengeResponse.BufferOffset + message.NtChallengeResponse.Len;
|
||||||
|
|
||||||
StreamWrite(s, NTLM_SIGNATURE, 8); /* Signature (8 bytes) */
|
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_AUTHENTICATE);
|
||||||
StreamWrite_UINT32(s, MESSAGE_TYPE_AUTHENTICATE); /* MessageType */
|
|
||||||
|
/* Message Header (12 bytes) */
|
||||||
|
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||||
|
|
||||||
/* LmChallengeResponseFields (8 bytes) */
|
/* LmChallengeResponseFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.LmChallengeResponse.Len); /* LmChallengeResponseLen */
|
ntlm_write_message_fields(s, &(message.LmChallengeResponse));
|
||||||
StreamWrite_UINT16(s, message.LmChallengeResponse.Len); /* LmChallengeResponseMaxLen */
|
|
||||||
StreamWrite_UINT32(s, message.LmChallengeResponse.BufferOffset); /* LmChallengeResponseBufferOffset */
|
|
||||||
|
|
||||||
/* NtChallengeResponseFields (8 bytes) */
|
/* NtChallengeResponseFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.NtChallengeResponse.Len); /* NtChallengeResponseLen */
|
ntlm_write_message_fields(s, &(message.NtChallengeResponse));
|
||||||
StreamWrite_UINT16(s, message.NtChallengeResponse.Len); /* NtChallengeResponseMaxLen */
|
|
||||||
StreamWrite_UINT32(s, message.NtChallengeResponse.BufferOffset); /* NtChallengeResponseBufferOffset */
|
|
||||||
|
|
||||||
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
||||||
|
|
||||||
/* DomainNameFields (8 bytes) */
|
/* DomainNameFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.DomainName.Len); /* DomainNameLen */
|
ntlm_write_message_fields(s, &(message.DomainName));
|
||||||
StreamWrite_UINT16(s, message.DomainName.Len); /* DomainNameMaxLen */
|
|
||||||
StreamWrite_UINT32(s, message.DomainName.BufferOffset); /* DomainNameBufferOffset */
|
|
||||||
|
|
||||||
/* UserNameFields (8 bytes) */
|
/* UserNameFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.UserName.Len); /* UserNameLen */
|
ntlm_write_message_fields(s, &(message.UserName));
|
||||||
StreamWrite_UINT16(s, message.UserName.Len); /* UserNameMaxLen */
|
|
||||||
StreamWrite_UINT32(s, message.UserName.BufferOffset); /* UserNameBufferOffset */
|
|
||||||
|
|
||||||
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED is set */
|
||||||
|
|
||||||
/* WorkstationFields (8 bytes) */
|
/* WorkstationFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.Workstation.Len); /* WorkstationLen */
|
ntlm_write_message_fields(s, &(message.Workstation));
|
||||||
StreamWrite_UINT16(s, message.Workstation.Len); /* WorkstationMaxLen */
|
|
||||||
StreamWrite_UINT32(s, message.Workstation.BufferOffset); /* WorkstationBufferOffset */
|
|
||||||
|
|
||||||
/* EncryptedRandomSessionKeyFields (8 bytes) */
|
/* EncryptedRandomSessionKeyFields (8 bytes) */
|
||||||
StreamWrite_UINT16(s, message.EncryptedRandomSessionKey.Len); /* EncryptedRandomSessionKeyLen */
|
ntlm_write_message_fields(s, &(message.EncryptedRandomSessionKey));
|
||||||
StreamWrite_UINT16(s, message.EncryptedRandomSessionKey.Len); /* EncryptedRandomSessionKeyMaxLen */
|
|
||||||
StreamWrite_UINT32(s, message.EncryptedRandomSessionKey.BufferOffset); /* EncryptedRandomSessionKeyBufferOffset */
|
|
||||||
|
|
||||||
StreamWrite_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamWrite_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user