libwinpr-sspi: add proper detection of MIC in server-side NLA
This commit is contained in:
parent
63a3fe70cb
commit
bf559e37eb
@ -86,9 +86,9 @@ NTLM_CONTEXT* ntlm_ContextNew()
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
context->ntlm_v2 = FALSE;
|
||||
context->ntlm_v2 = TRUE;
|
||||
context->NegotiateFlags = 0;
|
||||
context->SendVersionInfo = 0;
|
||||
context->SendVersionInfo = TRUE;
|
||||
context->LmCompatibilityLevel = 3;
|
||||
context->state = NTLM_STATE_INITIAL;
|
||||
context->SuppressExtendedProtection = 1;
|
||||
|
@ -126,6 +126,10 @@ enum _AV_ID
|
||||
};
|
||||
typedef enum _AV_ID AV_ID;
|
||||
|
||||
#define MSV_AV_FLAGS_AUTHENTICATION_CONSTRAINED 0x00000001
|
||||
#define MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK 0x00000002
|
||||
#define MSV_AV_FLAGS_TARGET_SPN_UNTRUSTED_SOURCE 0x00000004
|
||||
|
||||
#define WINDOWS_MAJOR_VERSION_5 0x05
|
||||
#define WINDOWS_MAJOR_VERSION_6 0x06
|
||||
#define WINDOWS_MINOR_VERSION_0 0x00
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include "ntlm_av_pairs.h"
|
||||
|
||||
const char* const AV_PAIRS_STRINGS[] =
|
||||
const char* const AV_PAIR_STRINGS[] =
|
||||
{
|
||||
"MsvAvEOL",
|
||||
"MsvAvNbComputerName",
|
||||
@ -51,6 +51,47 @@ void ntlm_av_pair_list_init(NTLM_AV_PAIR* pAvPairList)
|
||||
pAvPair->AvLen = 0;
|
||||
}
|
||||
|
||||
ULONG ntlm_av_pair_list_length(NTLM_AV_PAIR* pAvPairList)
|
||||
{
|
||||
ULONG length;
|
||||
NTLM_AV_PAIR* pAvPair = pAvPairList;
|
||||
|
||||
if (!pAvPair)
|
||||
return 0;
|
||||
|
||||
while (pAvPair->AvId != MsvAvEOL)
|
||||
{
|
||||
pAvPair = ntlm_av_pair_get_next_pointer(pAvPair);
|
||||
}
|
||||
|
||||
length = (pAvPair - pAvPairList) + sizeof(NTLM_AV_PAIR);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void ntlm_print_av_pair_list(NTLM_AV_PAIR* pAvPairList)
|
||||
{
|
||||
NTLM_AV_PAIR* pAvPair = pAvPairList;
|
||||
|
||||
if (!pAvPair)
|
||||
return;
|
||||
|
||||
printf("AV_PAIRs =\n{\n");
|
||||
|
||||
while (pAvPair->AvId != MsvAvEOL)
|
||||
{
|
||||
printf("\t%s AvId: %d AvLen: %d\n",
|
||||
AV_PAIR_STRINGS[pAvPair->AvId],
|
||||
pAvPair->AvId, pAvPair->AvLen);
|
||||
|
||||
winpr_HexDump(ntlm_av_pair_get_value_pointer(pAvPair), pAvPair->AvLen);
|
||||
|
||||
pAvPair = ntlm_av_pair_get_next_pointer(pAvPair);
|
||||
}
|
||||
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
ULONG ntlm_av_pair_list_size(ULONG AvPairsCount, ULONG AvPairsValueLength)
|
||||
{
|
||||
/* size of headers + value lengths + terminating MsvAvEOL AV_PAIR */
|
||||
@ -72,7 +113,7 @@ NTLM_AV_PAIR* ntlm_av_pair_get_next_pointer(NTLM_AV_PAIR* pAvPair)
|
||||
return (NTLM_AV_PAIR*) ((PBYTE) pAvPair + ntlm_av_pair_get_next_offset(pAvPair));
|
||||
}
|
||||
|
||||
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, LONG AvPairListSize)
|
||||
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, AV_ID AvId)
|
||||
{
|
||||
NTLM_AV_PAIR* pAvPair = pAvPairList;
|
||||
|
||||
@ -87,11 +128,6 @@ NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, LONG AvPai
|
||||
if (pAvPair->AvId == MsvAvEOL)
|
||||
return NULL;
|
||||
|
||||
AvPairListSize -= ntlm_av_pair_get_next_offset(pAvPair);
|
||||
|
||||
if (AvPairListSize <= 0)
|
||||
return NULL;
|
||||
|
||||
pAvPair = ntlm_av_pair_get_next_pointer(pAvPair);
|
||||
}
|
||||
|
||||
@ -102,7 +138,7 @@ NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, PUNICODE_S
|
||||
{
|
||||
NTLM_AV_PAIR* pAvPair;
|
||||
|
||||
pAvPair = ntlm_av_pair_get(pAvPairList, MsvAvEOL, AvPairListSize);
|
||||
pAvPair = ntlm_av_pair_get(pAvPairList, MsvAvEOL);
|
||||
|
||||
if (!pAvPair)
|
||||
return NULL;
|
||||
@ -207,7 +243,7 @@ void ntlm_input_av_pairs(NTLM_CONTEXT* context, PStream s)
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
if (AvId < 10)
|
||||
printf("\tAvId: %s, AvLen: %d\n", AV_PAIRS_STRINGS[AvId], AvLen);
|
||||
printf("\tAvId: %s, AvLen: %d\n", AV_PAIR_STRINGS[AvId], AvLen);
|
||||
else
|
||||
printf("\tAvId: %s, AvLen: %d\n", "Unknown", AvLen);
|
||||
|
||||
|
@ -25,11 +25,13 @@
|
||||
#include <winpr/stream.h>
|
||||
|
||||
void ntlm_av_pair_list_init(NTLM_AV_PAIR* pAvPairList);
|
||||
ULONG ntlm_av_pair_list_length(NTLM_AV_PAIR* pAvPairList);
|
||||
void ntlm_print_av_pair_list(NTLM_AV_PAIR* pAvPairList);
|
||||
ULONG ntlm_av_pair_list_size(ULONG AvPairsCount, ULONG AvPairsValueLength);
|
||||
PBYTE ntlm_av_pair_get_value_pointer(NTLM_AV_PAIR* pAvPair);
|
||||
int ntlm_av_pair_get_next_offset(NTLM_AV_PAIR* pAvPair);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_get_next_pointer(NTLM_AV_PAIR* pAvPair);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, LONG AvPairListSize);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, AV_ID AvId);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, PUNICODE_STRING pValue, LONG AvPairListSize);
|
||||
|
||||
void ntlm_construct_server_target_info(NTLM_CONTEXT* context);
|
||||
|
@ -103,6 +103,51 @@ void ntlm_print_version_info(NTLM_VERSION_INFO* versionInfo)
|
||||
printf("\tNTLMRevisionCurrent: 0x%02X\n", versionInfo->NTLMRevisionCurrent);
|
||||
}
|
||||
|
||||
void ntlm_read_ntlm_v2_client_challenge(PStream s, NTLMv2_CLIENT_CHALLENGE* challenge)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
StreamRead_UINT8(s, challenge->RespType);
|
||||
StreamRead_UINT8(s, challenge->HiRespType);
|
||||
StreamRead_UINT16(s, challenge->Reserved1);
|
||||
StreamRead_UINT32(s, challenge->Reserved2);
|
||||
StreamRead(s, challenge->Timestamp, 8);
|
||||
StreamRead(s, challenge->ClientChallenge, 8);
|
||||
StreamRead_UINT32(s, challenge->Reserved3);
|
||||
|
||||
size = StreamRemainingSize(s);
|
||||
challenge->AvPairs = (NTLM_AV_PAIR*) malloc(size);
|
||||
StreamRead(s, challenge->AvPairs, size);
|
||||
}
|
||||
|
||||
void ntlm_write_ntlm_v2_client_challenge(PStream s, NTLMv2_CLIENT_CHALLENGE* challenge)
|
||||
{
|
||||
ULONG length;
|
||||
|
||||
StreamWrite_UINT8(s, challenge->RespType);
|
||||
StreamWrite_UINT8(s, challenge->HiRespType);
|
||||
StreamWrite_UINT16(s, challenge->Reserved1);
|
||||
StreamWrite_UINT32(s, challenge->Reserved2);
|
||||
StreamWrite(s, challenge->Timestamp, 8);
|
||||
StreamWrite(s, challenge->ClientChallenge, 8);
|
||||
StreamWrite_UINT32(s, challenge->Reserved3);
|
||||
|
||||
length = ntlm_av_pair_list_length(challenge->AvPairs);
|
||||
StreamWrite(s, challenge->AvPairs, length);
|
||||
}
|
||||
|
||||
void ntlm_read_ntlm_v2_response(PStream s, NTLMv2_RESPONSE* response)
|
||||
{
|
||||
StreamRead(s, response->Response, 16);
|
||||
ntlm_read_ntlm_v2_client_challenge(s, &(response->Challenge));
|
||||
}
|
||||
|
||||
void ntlm_write_ntlm_v2_response(PStream s, NTLMv2_RESPONSE* response)
|
||||
{
|
||||
StreamWrite(s, response->Response, 16);
|
||||
ntlm_write_ntlm_v2_client_challenge(s, &(response->Challenge));
|
||||
}
|
||||
|
||||
/**
|
||||
* Output Restriction_Encoding.\n
|
||||
* Restriction_Encoding @msdn{cc236647}
|
||||
|
@ -29,6 +29,9 @@ void ntlm_read_version_info(PStream s, NTLM_VERSION_INFO* versionInfo);
|
||||
void ntlm_write_version_info(PStream s, NTLM_VERSION_INFO* versionInfo);
|
||||
void ntlm_print_version_info(NTLM_VERSION_INFO* versionInfo);
|
||||
|
||||
void ntlm_read_ntlm_v2_response(PStream s, NTLMv2_RESPONSE* response);
|
||||
void ntlm_write_ntlm_v2_response(PStream s, NTLMv2_RESPONSE* response);
|
||||
|
||||
void ntlm_output_restriction_encoding(NTLM_CONTEXT* context);
|
||||
void ntlm_output_target_name(NTLM_CONTEXT* context);
|
||||
void ntlm_output_channel_bindings(NTLM_CONTEXT* context);
|
||||
|
@ -209,10 +209,7 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
||||
ntlm_read_message_fields(s, &(message.Workstation));
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
{
|
||||
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
||||
ntlm_read_version_info(s, &(message.Version)); /* Version (8 bytes) */
|
||||
}
|
||||
|
||||
length = StreamSize(s);
|
||||
buffer->cbBuffer = length;
|
||||
@ -225,6 +222,11 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
||||
printf("NEGOTIATE_MESSAGE (length = %d)\n", length);
|
||||
winpr_HexDump(s->data, length);
|
||||
printf("\n");
|
||||
|
||||
ntlm_print_negotiate_flags(message.NegotiateFlags);
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_print_version_info(&(message.Version));
|
||||
#endif
|
||||
|
||||
context->state = NTLM_STATE_CHALLENGE;
|
||||
@ -245,9 +247,6 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
|
||||
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_NEGOTIATE);
|
||||
|
||||
/* Message Header (12 bytes) */
|
||||
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||
|
||||
if (context->ntlm_v2)
|
||||
{
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_56;
|
||||
@ -275,6 +274,9 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||
}
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_get_version_info(&(message.Version));
|
||||
|
||||
if (context->confidentiality)
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
|
||||
|
||||
@ -283,6 +285,9 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
|
||||
context->NegotiateFlags = message.NegotiateFlags;
|
||||
|
||||
/* Message Header (12 bytes) */
|
||||
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||
|
||||
StreamWrite_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
|
||||
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
||||
@ -296,19 +301,8 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
ntlm_write_message_fields(s, &(message.Workstation));
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
{
|
||||
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
||||
|
||||
ntlm_get_version_info(&(message.Version));
|
||||
ntlm_write_version_info(s, &(message.Version));
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("Version (length = 8)\n");
|
||||
winpr_HexDump((s->p - 8), 8);
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
length = StreamSize(s);
|
||||
buffer->cbBuffer = length;
|
||||
|
||||
@ -320,6 +314,9 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
printf("NEGOTIATE_MESSAGE (length = %d)\n", length);
|
||||
winpr_HexDump(s->data, length);
|
||||
printf("\n");
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_print_version_info(&(message.Version));
|
||||
#endif
|
||||
|
||||
context->state = NTLM_STATE_CHALLENGE;
|
||||
@ -523,20 +520,22 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
/* ServerChallenge */
|
||||
CopyMemory(message.ServerChallenge, context->ServerChallenge, 8);
|
||||
|
||||
message.NegotiateFlags = context->NegotiateFlags;
|
||||
|
||||
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_CHALLENGE);
|
||||
|
||||
/* Message Header (12 bytes) */
|
||||
ntlm_write_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_REQUEST_TARGET)
|
||||
if (message.NegotiateFlags & NTLMSSP_REQUEST_TARGET)
|
||||
{
|
||||
message.TargetName.Len = (UINT16) context->TargetName.cbBuffer;
|
||||
message.TargetName.Buffer = context->TargetName.pvBuffer;
|
||||
}
|
||||
|
||||
context->NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO)
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO)
|
||||
{
|
||||
message.TargetInfo.Len = (UINT16) context->TargetInfo.cbBuffer;
|
||||
message.TargetInfo.Buffer = context->TargetInfo.pvBuffer;
|
||||
@ -544,7 +543,7 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
|
||||
PayloadOffset = 48;
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
PayloadOffset += 8;
|
||||
|
||||
message.TargetName.BufferOffset = PayloadOffset;
|
||||
@ -553,7 +552,7 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
/* TargetNameFields (8 bytes) */
|
||||
ntlm_write_message_fields(s, &(message.TargetName));
|
||||
|
||||
StreamWrite_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
StreamWrite_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
|
||||
StreamWrite(s, message.ServerChallenge, 8); /* ServerChallenge (8 bytes) */
|
||||
StreamWrite(s, message.Reserved, 8); /* Reserved (8 bytes), should be ignored */
|
||||
@ -561,15 +560,15 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
/* TargetInfoFields (8 bytes) */
|
||||
ntlm_write_message_fields(s, &(message.TargetInfo));
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_write_version_info(s, &(message.Version)); /* Version (8 bytes) */
|
||||
|
||||
/* Payload (variable) */
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_REQUEST_TARGET)
|
||||
if (message.NegotiateFlags & NTLMSSP_REQUEST_TARGET)
|
||||
ntlm_write_message_fields_buffer(s, &(message.TargetName));
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO)
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO)
|
||||
ntlm_write_message_fields_buffer(s, &(message.TargetInfo));
|
||||
|
||||
length = StreamSize(s);
|
||||
@ -583,7 +582,9 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
winpr_HexDump(context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
||||
printf("\n");
|
||||
|
||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_print_negotiate_flags(message.NegotiateFlags);
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_print_version_info(&(message.Version));
|
||||
|
||||
ntlm_print_message_fields(&(message.TargetName), "TargetName");
|
||||
@ -601,6 +602,9 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
{
|
||||
PStream s;
|
||||
int length;
|
||||
UINT32 flags = 0;
|
||||
NTLMv2_RESPONSE response;
|
||||
UINT32 PayloadBufferOffset;
|
||||
NTLM_AUTHENTICATE_MESSAGE message;
|
||||
|
||||
ZeroMemory(&message, sizeof(message));
|
||||
@ -641,10 +645,7 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_read_version_info(s, &(message.Version)); /* Version (8 bytes) */
|
||||
|
||||
length = StreamSize(s);
|
||||
sspi_SecBufferAlloc(&context->AuthenticateMessage, length);
|
||||
CopyMemory(context->AuthenticateMessage.pvBuffer, s->data, length);
|
||||
buffer->cbBuffer = length;
|
||||
PayloadBufferOffset = StreamGetOffset(s);
|
||||
|
||||
/* DomainName */
|
||||
ntlm_read_message_fields_buffer(s, &(message.DomainName));
|
||||
@ -663,15 +664,40 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
|
||||
if (message.NtChallengeResponse.Len > 0)
|
||||
{
|
||||
BYTE* ClientChallengeBuffer;
|
||||
ClientChallengeBuffer = message.NtChallengeResponse.Buffer + 32;
|
||||
CopyMemory(context->ClientChallenge, ClientChallengeBuffer, 8);
|
||||
NTLM_AV_PAIR* AvFlags;
|
||||
|
||||
PStream s = PStreamAllocAttach(message.NtChallengeResponse.Buffer, message.NtChallengeResponse.Len);
|
||||
ntlm_read_ntlm_v2_response(s, &response);
|
||||
PStreamFreeDetach(s);
|
||||
|
||||
CopyMemory(context->ClientChallenge, response.Challenge.ClientChallenge, 8);
|
||||
|
||||
AvFlags = ntlm_av_pair_get(response.Challenge.AvPairs, MsvAvFlags);
|
||||
|
||||
if (AvFlags != NULL)
|
||||
flags = *((UINT32*) ntlm_av_pair_get_value_pointer(AvFlags));
|
||||
}
|
||||
|
||||
/* EncryptedRandomSessionKey */
|
||||
ntlm_read_message_fields_buffer(s, &(message.EncryptedRandomSessionKey));
|
||||
CopyMemory(context->EncryptedRandomSessionKey, message.EncryptedRandomSessionKey.Buffer, 16);
|
||||
|
||||
StreamSetOffset(s, PayloadBufferOffset);
|
||||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
StreamRead(s, message.MessageIntegrityCheck, 16);
|
||||
PayloadBufferOffset += 16;
|
||||
}
|
||||
|
||||
/* move to end of stream, incorrectly assumes the EncryptedRandomSessionKey buffer is last */
|
||||
StreamSetOffset(s, message.EncryptedRandomSessionKey.BufferOffset + message.EncryptedRandomSessionKey.Len);
|
||||
|
||||
length = StreamSize(s);
|
||||
sspi_SecBufferAlloc(&context->AuthenticateMessage, length);
|
||||
CopyMemory(context->AuthenticateMessage.pvBuffer, s->data, length);
|
||||
buffer->cbBuffer = length;
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
|
||||
winpr_HexDump(s->data, length);
|
||||
@ -686,6 +712,14 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
ntlm_print_message_fields(&(message.LmChallengeResponse), "LmChallengeResponse");
|
||||
ntlm_print_message_fields(&(message.NtChallengeResponse), "NtChallengeResponse");
|
||||
ntlm_print_message_fields(&(message.EncryptedRandomSessionKey), "EncryptedRandomSessionKey");
|
||||
|
||||
ntlm_print_av_pair_list(response.Challenge.AvPairs);
|
||||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
printf("MessageIntegrityCheck:\n");
|
||||
winpr_HexDump(message.MessageIntegrityCheck, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (message.UserName.Len > 0)
|
||||
@ -835,9 +869,15 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
if (context->ntlm_v2 < 1)
|
||||
message.Workstation.Len = 0;
|
||||
|
||||
if (message.Workstation.Len > 0)
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED;
|
||||
|
||||
message.DomainName.Len = (UINT16) context->identity.DomainLength * 2;
|
||||
message.DomainName.Buffer = (BYTE*) context->identity.Domain;
|
||||
|
||||
if (message.DomainName.Len > 0)
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
|
||||
|
||||
message.UserName.Len = (UINT16) context->identity.UserLength * 2;
|
||||
message.UserName.Buffer = (BYTE*) context->identity.User;
|
||||
|
||||
@ -853,10 +893,10 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
if (context->confidentiality)
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
|
||||
|
||||
PayloadBufferOffset = 64;
|
||||
|
||||
if (context->ntlm_v2)
|
||||
PayloadBufferOffset = 80; /* starting buffer offset */
|
||||
else
|
||||
PayloadBufferOffset = 64; /* starting buffer offset */
|
||||
PayloadBufferOffset += 16; /* Message Integrity Check */
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
PayloadBufferOffset += 8;
|
||||
|
Loading…
Reference in New Issue
Block a user