libwinpr-sspi: improve NTLM message debugging
This commit is contained in:
parent
aff78da527
commit
63a3fe70cb
@ -65,6 +65,7 @@ void ntlm_SetContextTargetName(NTLM_CONTEXT* context, char* TargetName)
|
|||||||
GetComputerNameExA(ComputerNameDnsHostname, NULL, &nSize);
|
GetComputerNameExA(ComputerNameDnsHostname, NULL, &nSize);
|
||||||
TargetName = malloc(nSize);
|
TargetName = malloc(nSize);
|
||||||
GetComputerNameExA(ComputerNameDnsHostname, TargetName, &nSize);
|
GetComputerNameExA(ComputerNameDnsHostname, TargetName, &nSize);
|
||||||
|
CharUpperA(TargetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
context->TargetName.cbBuffer = strlen(TargetName) * 2;
|
context->TargetName.cbBuffer = strlen(TargetName) * 2;
|
||||||
|
@ -81,6 +81,13 @@ enum _NTLM_STATE
|
|||||||
};
|
};
|
||||||
typedef enum _NTLM_STATE NTLM_STATE;
|
typedef enum _NTLM_STATE NTLM_STATE;
|
||||||
|
|
||||||
|
struct _NTLM_AV_PAIR
|
||||||
|
{
|
||||||
|
UINT16 AvId;
|
||||||
|
UINT16 AvLen;
|
||||||
|
};
|
||||||
|
typedef struct _NTLM_AV_PAIR NTLM_AV_PAIR;
|
||||||
|
|
||||||
struct _AV_PAIR
|
struct _AV_PAIR
|
||||||
{
|
{
|
||||||
UINT16 length;
|
UINT16 length;
|
||||||
@ -136,6 +143,32 @@ struct _NTLM_VERSION_INFO
|
|||||||
};
|
};
|
||||||
typedef struct _NTLM_VERSION_INFO NTLM_VERSION_INFO;
|
typedef struct _NTLM_VERSION_INFO NTLM_VERSION_INFO;
|
||||||
|
|
||||||
|
struct _NTLM_RESPONSE
|
||||||
|
{
|
||||||
|
BYTE Response[24];
|
||||||
|
};
|
||||||
|
typedef struct _NTLM_RESPONSE NTLM_RESPONSE;
|
||||||
|
|
||||||
|
struct _NTLMv2_CLIENT_CHALLENGE
|
||||||
|
{
|
||||||
|
UINT8 RespType;
|
||||||
|
UINT8 HiRespType;
|
||||||
|
UINT16 Reserved1;
|
||||||
|
UINT32 Reserved2;
|
||||||
|
BYTE Timestamp[8];
|
||||||
|
BYTE ClientChallenge[8];
|
||||||
|
UINT32 Reserved3;
|
||||||
|
NTLM_AV_PAIR* AvPairs;
|
||||||
|
};
|
||||||
|
typedef struct _NTLMv2_CLIENT_CHALLENGE NTLMv2_CLIENT_CHALLENGE;
|
||||||
|
|
||||||
|
struct _NTLMv2_RESPONSE
|
||||||
|
{
|
||||||
|
BYTE Response[16];
|
||||||
|
NTLMv2_CLIENT_CHALLENGE Challenge;
|
||||||
|
};
|
||||||
|
typedef struct _NTLMv2_RESPONSE NTLMv2_RESPONSE;
|
||||||
|
|
||||||
struct _NTLM_MESSAGE_FIELDS
|
struct _NTLM_MESSAGE_FIELDS
|
||||||
{
|
{
|
||||||
UINT16 Len;
|
UINT16 Len;
|
||||||
@ -169,6 +202,7 @@ struct _NTLM_CHALLENGE_MESSAGE
|
|||||||
UINT32 MessageType;
|
UINT32 MessageType;
|
||||||
UINT32 NegotiateFlags;
|
UINT32 NegotiateFlags;
|
||||||
BYTE ServerChallenge[8];
|
BYTE ServerChallenge[8];
|
||||||
|
BYTE Reserved[8];
|
||||||
NTLM_VERSION_INFO Version;
|
NTLM_VERSION_INFO Version;
|
||||||
NTLM_MESSAGE_FIELDS TargetName;
|
NTLM_MESSAGE_FIELDS TargetName;
|
||||||
NTLM_MESSAGE_FIELDS TargetInfo;
|
NTLM_MESSAGE_FIELDS TargetInfo;
|
||||||
|
@ -43,6 +43,78 @@ const char* const AV_PAIRS_STRINGS[] =
|
|||||||
"MsvChannelBindings"
|
"MsvChannelBindings"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void ntlm_av_pair_list_init(NTLM_AV_PAIR* pAvPairList)
|
||||||
|
{
|
||||||
|
NTLM_AV_PAIR* pAvPair = pAvPairList;
|
||||||
|
|
||||||
|
pAvPair->AvId = MsvAvEOL;
|
||||||
|
pAvPair->AvLen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG ntlm_av_pair_list_size(ULONG AvPairsCount, ULONG AvPairsValueLength)
|
||||||
|
{
|
||||||
|
/* size of headers + value lengths + terminating MsvAvEOL AV_PAIR */
|
||||||
|
return (AvPairsCount + 1) * sizeof(NTLM_AV_PAIR) + AvPairsValueLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
PBYTE ntlm_av_pair_get_value_pointer(NTLM_AV_PAIR* pAvPair)
|
||||||
|
{
|
||||||
|
return &((PBYTE) pAvPair)[sizeof(NTLM_AV_PAIR)];
|
||||||
|
}
|
||||||
|
|
||||||
|
int ntlm_av_pair_get_next_offset(NTLM_AV_PAIR* pAvPair)
|
||||||
|
{
|
||||||
|
return pAvPair->AvLen + sizeof(NTLM_AV_PAIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
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* pAvPair = pAvPairList;
|
||||||
|
|
||||||
|
if (!pAvPair)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (pAvPair->AvId == AvId)
|
||||||
|
return pAvPair;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, PUNICODE_STRING pValue, LONG AvPairListSize)
|
||||||
|
{
|
||||||
|
NTLM_AV_PAIR* pAvPair;
|
||||||
|
|
||||||
|
pAvPair = ntlm_av_pair_get(pAvPairList, MsvAvEOL, AvPairListSize);
|
||||||
|
|
||||||
|
if (!pAvPair)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
pAvPair->AvId = AvId;
|
||||||
|
pAvPair->AvLen = pValue->Length;
|
||||||
|
|
||||||
|
CopyMemory(ntlm_av_pair_get_value_pointer(pAvPair), pValue->Buffer, pValue->Length);
|
||||||
|
|
||||||
|
return pAvPair;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Input array of AV_PAIRs.\n
|
* Input array of AV_PAIRs.\n
|
||||||
* AV_PAIR @msdn{cc236646}
|
* AV_PAIR @msdn{cc236646}
|
||||||
@ -322,74 +394,65 @@ void ntlm_populate_av_pairs(NTLM_CONTEXT* context)
|
|||||||
ntlm_output_av_pairs(context, &context->TargetInfo);
|
ntlm_output_av_pairs(context, &context->TargetInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void ntlm_get_target_computer_name(PUNICODE_STRING pName, COMPUTER_NAME_FORMAT type)
|
||||||
* Populate array of AV_PAIRs (server).\n
|
{
|
||||||
* AV_PAIR @msdn{cc236646}
|
char* name;
|
||||||
* @param NTLM context
|
DWORD nSize = 0;
|
||||||
*/
|
|
||||||
|
|
||||||
void ntlm_populate_server_av_pairs(NTLM_CONTEXT* context)
|
GetComputerNameExA(type, NULL, &nSize);
|
||||||
|
name = malloc(nSize);
|
||||||
|
GetComputerNameExA(type, name, &nSize);
|
||||||
|
|
||||||
|
if (type == ComputerNameNetBIOS)
|
||||||
|
CharUpperA(name);
|
||||||
|
|
||||||
|
pName->Length = strlen(name) * 2;
|
||||||
|
pName->Buffer = (PWSTR) malloc(pName->Length);
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, name, strlen(name),
|
||||||
|
(LPWSTR) pName->Buffer, pName->Length / 2);
|
||||||
|
|
||||||
|
pName->MaximumLength = pName->Length;
|
||||||
|
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ntlm_construct_server_target_info(NTLM_CONTEXT* context)
|
||||||
{
|
{
|
||||||
int length;
|
int length;
|
||||||
DWORD nSize;
|
ULONG AvPairsCount;
|
||||||
AV_PAIRS* av_pairs;
|
ULONG AvPairsLength;
|
||||||
char* NbDomainName;
|
LONG AvPairListSize;
|
||||||
char* NbComputerName;
|
NTLM_AV_PAIR* pAvPairList;
|
||||||
char* DnsDomainName;
|
UNICODE_STRING NbDomainName;
|
||||||
char* DnsComputerName;
|
UNICODE_STRING NbComputerName;
|
||||||
|
UNICODE_STRING DnsDomainName;
|
||||||
|
UNICODE_STRING DnsComputerName;
|
||||||
|
UNICODE_STRING Timestamp;
|
||||||
|
|
||||||
av_pairs = context->av_pairs;
|
ntlm_get_target_computer_name(&NbDomainName, ComputerNameNetBIOS);
|
||||||
|
ntlm_get_target_computer_name(&NbComputerName, ComputerNameNetBIOS);
|
||||||
|
ntlm_get_target_computer_name(&DnsDomainName, ComputerNameDnsDomain);
|
||||||
|
ntlm_get_target_computer_name(&DnsComputerName, ComputerNameDnsHostname);
|
||||||
|
|
||||||
nSize = 0;
|
Timestamp.Buffer = (PWSTR) context->Timestamp;
|
||||||
GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize);
|
Timestamp.Length = sizeof(context->Timestamp);
|
||||||
NbDomainName = malloc(nSize);
|
|
||||||
GetComputerNameExA(ComputerNameNetBIOS, NbDomainName, &nSize);
|
|
||||||
CharUpperA(NbDomainName);
|
|
||||||
|
|
||||||
nSize = 0;
|
AvPairsCount = 5;
|
||||||
GetComputerNameExA(ComputerNameNetBIOS, NULL, &nSize);
|
AvPairsLength = NbDomainName.Length + NbComputerName.Length +
|
||||||
NbComputerName = malloc(nSize);
|
DnsDomainName.Length + DnsComputerName.Length + 8;
|
||||||
GetComputerNameExA(ComputerNameNetBIOS, NbComputerName, &nSize);
|
|
||||||
CharUpperA(NbComputerName);
|
|
||||||
|
|
||||||
nSize = 0;
|
length = ntlm_av_pair_list_size(AvPairsCount, AvPairsLength);
|
||||||
GetComputerNameExA(ComputerNameDnsDomain, NULL, &nSize);
|
|
||||||
DnsDomainName = malloc(nSize);
|
|
||||||
GetComputerNameExA(ComputerNameDnsDomain, DnsDomainName, &nSize);
|
|
||||||
|
|
||||||
nSize = 0;
|
|
||||||
GetComputerNameExA(ComputerNameDnsHostname, NULL, &nSize);
|
|
||||||
DnsComputerName = malloc(nSize);
|
|
||||||
GetComputerNameExA(ComputerNameDnsHostname, DnsComputerName, &nSize);
|
|
||||||
|
|
||||||
av_pairs->NbDomainName.length = strlen(NbDomainName) * 2;
|
|
||||||
av_pairs->NbDomainName.value = (BYTE*) malloc(av_pairs->NbDomainName.length);
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, NbDomainName, strlen(NbDomainName),
|
|
||||||
(LPWSTR) av_pairs->NbDomainName.value, av_pairs->NbDomainName.length / 2);
|
|
||||||
|
|
||||||
av_pairs->NbComputerName.length = strlen(NbDomainName) * 2;
|
|
||||||
av_pairs->NbComputerName.value = (BYTE*) malloc(av_pairs->NbComputerName.length);
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, NbComputerName, strlen(NbComputerName),
|
|
||||||
(LPWSTR) av_pairs->NbComputerName.value, av_pairs->NbComputerName.length / 2);
|
|
||||||
|
|
||||||
av_pairs->DnsDomainName.length = strlen(DnsDomainName) * 2;
|
|
||||||
av_pairs->DnsDomainName.value = (BYTE*) malloc(av_pairs->DnsDomainName.length);
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, DnsDomainName, strlen(DnsDomainName),
|
|
||||||
(LPWSTR) av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length / 2);
|
|
||||||
|
|
||||||
av_pairs->DnsComputerName.length = strlen(DnsComputerName) * 2;
|
|
||||||
av_pairs->DnsComputerName.value = (BYTE*) malloc(av_pairs->DnsComputerName.length);
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, DnsComputerName, strlen(DnsComputerName),
|
|
||||||
(LPWSTR) av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length / 2);
|
|
||||||
|
|
||||||
length = ntlm_compute_av_pairs_length(context) + 4;
|
|
||||||
sspi_SecBufferAlloc(&context->TargetInfo, length);
|
sspi_SecBufferAlloc(&context->TargetInfo, length);
|
||||||
ntlm_output_av_pairs(context, &context->TargetInfo);
|
|
||||||
|
|
||||||
free(NbDomainName);
|
pAvPairList = (NTLM_AV_PAIR*) context->TargetInfo.pvBuffer;
|
||||||
free(NbComputerName);
|
AvPairListSize = (ULONG) context->TargetInfo.cbBuffer;
|
||||||
free(DnsDomainName);
|
|
||||||
free(DnsComputerName);
|
ntlm_av_pair_list_init(pAvPairList);
|
||||||
|
ntlm_av_pair_add(pAvPairList, MsvAvNbDomainName, &NbDomainName, AvPairListSize);
|
||||||
|
ntlm_av_pair_add(pAvPairList, MsvAvNbComputerName, &NbComputerName, AvPairListSize);
|
||||||
|
ntlm_av_pair_add(pAvPairList, MsvAvDnsDomainName, &DnsDomainName, AvPairListSize);
|
||||||
|
ntlm_av_pair_add(pAvPairList, MsvAvDnsComputerName, &DnsComputerName, AvPairListSize);
|
||||||
|
ntlm_av_pair_add(pAvPairList, MsvAvTimestamp, &Timestamp, AvPairListSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,6 +24,16 @@
|
|||||||
|
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
|
|
||||||
|
void ntlm_av_pair_list_init(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_add(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, PUNICODE_STRING pValue, LONG AvPairListSize);
|
||||||
|
|
||||||
|
void ntlm_construct_server_target_info(NTLM_CONTEXT* context);
|
||||||
|
|
||||||
void ntlm_input_av_pairs(NTLM_CONTEXT* context, PStream s);
|
void ntlm_input_av_pairs(NTLM_CONTEXT* context, PStream s);
|
||||||
void ntlm_output_av_pairs(NTLM_CONTEXT* context, PSecBuffer buffer);
|
void ntlm_output_av_pairs(NTLM_CONTEXT* context, PSecBuffer buffer);
|
||||||
void ntlm_populate_av_pairs(NTLM_CONTEXT* context);
|
void ntlm_populate_av_pairs(NTLM_CONTEXT* context);
|
||||||
|
@ -56,6 +56,21 @@ void ntlm_get_version_info(NTLM_VERSION_INFO* versionInfo)
|
|||||||
versionInfo->NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
|
versionInfo->NTLMRevisionCurrent = NTLMSSP_REVISION_W2K3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read VERSION structure.\n
|
||||||
|
* VERSION @msdn{cc236654}
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ntlm_read_version_info(PStream s, NTLM_VERSION_INFO* versionInfo)
|
||||||
|
{
|
||||||
|
StreamRead_UINT8(s, versionInfo->ProductMajorVersion); /* ProductMajorVersion (1 byte) */
|
||||||
|
StreamRead_UINT8(s, versionInfo->ProductMinorVersion); /* ProductMinorVersion (1 byte) */
|
||||||
|
StreamRead_UINT16(s, versionInfo->ProductBuild); /* ProductBuild (2 bytes) */
|
||||||
|
StreamRead(s, versionInfo->Reserved, sizeof(versionInfo->Reserved)); /* Reserved (3 bytes) */
|
||||||
|
StreamRead_UINT8(s, versionInfo->NTLMRevisionCurrent); /* NTLMRevisionCurrent (1 byte) */
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write VERSION structure.\n
|
* Write VERSION structure.\n
|
||||||
* VERSION @msdn{cc236654}
|
* VERSION @msdn{cc236654}
|
||||||
@ -64,17 +79,28 @@ void ntlm_get_version_info(NTLM_VERSION_INFO* versionInfo)
|
|||||||
|
|
||||||
void ntlm_write_version_info(PStream s, NTLM_VERSION_INFO* versionInfo)
|
void ntlm_write_version_info(PStream s, NTLM_VERSION_INFO* versionInfo)
|
||||||
{
|
{
|
||||||
OSVERSIONINFOA osVersionInfo;
|
StreamWrite_UINT8(s, versionInfo->ProductMajorVersion); /* ProductMajorVersion (1 byte) */
|
||||||
|
StreamWrite_UINT8(s, versionInfo->ProductMinorVersion); /* ProductMinorVersion (1 byte) */
|
||||||
|
StreamWrite_UINT16(s, versionInfo->ProductBuild); /* ProductBuild (2 bytes) */
|
||||||
|
StreamWrite(s, versionInfo->Reserved, sizeof(versionInfo->Reserved)); /* Reserved (3 bytes) */
|
||||||
|
StreamWrite_UINT8(s, versionInfo->NTLMRevisionCurrent); /* NTLMRevisionCurrent (1 byte) */
|
||||||
|
}
|
||||||
|
|
||||||
osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
/**
|
||||||
|
* Print VERSION structure.\n
|
||||||
|
* VERSION @msdn{cc236654}
|
||||||
|
* @param s
|
||||||
|
*/
|
||||||
|
|
||||||
GetVersionExA(&osVersionInfo);
|
void ntlm_print_version_info(NTLM_VERSION_INFO* versionInfo)
|
||||||
|
{
|
||||||
StreamWrite_UINT8(s, osVersionInfo.dwMajorVersion); /* ProductMajorVersion (1 byte) */
|
printf("VERSION =\n{\n");
|
||||||
StreamWrite_UINT8(s, osVersionInfo.dwMinorVersion); /* ProductMinorVersion (1 byte) */
|
printf("\tProductMajorVersion: %d\n", versionInfo->ProductMajorVersion);
|
||||||
StreamWrite_UINT16(s, osVersionInfo.dwBuildNumber); /* ProductBuild (2 bytes) */
|
printf("\tProductMinorVersion: %d\n", versionInfo->ProductMinorVersion);
|
||||||
StreamZero(s, 3); /* Reserved (3 bytes) */
|
printf("\tProductBuild: %d\n", versionInfo->ProductBuild);
|
||||||
StreamWrite_UINT8(s, NTLMSSP_REVISION_W2K3); /* NTLMRevisionCurrent (1 byte) */
|
printf("\tReserved: 0x%02X%02X%02X\n", versionInfo->Reserved[0],
|
||||||
|
versionInfo->Reserved[1], versionInfo->Reserved[2]);
|
||||||
|
printf("\tNTLMRevisionCurrent: 0x%02X\n", versionInfo->NTLMRevisionCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
#include "ntlm_av_pairs.h"
|
#include "ntlm_av_pairs.h"
|
||||||
|
|
||||||
void ntlm_get_version_info(NTLM_VERSION_INFO* versionInfo);
|
void ntlm_get_version_info(NTLM_VERSION_INFO* versionInfo);
|
||||||
|
void ntlm_read_version_info(PStream s, NTLM_VERSION_INFO* versionInfo);
|
||||||
void ntlm_write_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_output_restriction_encoding(NTLM_CONTEXT* context);
|
void ntlm_output_restriction_encoding(NTLM_CONTEXT* context);
|
||||||
void ntlm_output_target_name(NTLM_CONTEXT* context);
|
void ntlm_output_target_name(NTLM_CONTEXT* context);
|
||||||
|
@ -187,6 +187,15 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
|
|
||||||
StreamRead_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamRead_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
|
if (!((message.NegotiateFlags & NTLMSSP_REQUEST_TARGET) &&
|
||||||
|
(message.NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM) &&
|
||||||
|
(message.NegotiateFlags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) &&
|
||||||
|
(message.NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE)))
|
||||||
|
{
|
||||||
|
PStreamFreeDetach(s);
|
||||||
|
return SEC_E_INVALID_TOKEN;
|
||||||
|
}
|
||||||
|
|
||||||
context->NegotiateFlags = message.NegotiateFlags;
|
context->NegotiateFlags = message.NegotiateFlags;
|
||||||
|
|
||||||
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
/* only set if NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED is set */
|
||||||
@ -202,7 +211,7 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
{
|
{
|
||||||
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
||||||
StreamSeek(s, 8); /* Version (8 bytes) */
|
ntlm_read_version_info(s, &(message.Version)); /* Version (8 bytes) */
|
||||||
}
|
}
|
||||||
|
|
||||||
length = StreamSize(s);
|
length = StreamSize(s);
|
||||||
@ -322,7 +331,7 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
|
|
||||||
SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buffer)
|
SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buffer)
|
||||||
{
|
{
|
||||||
BYTE* p;
|
PBYTE p;
|
||||||
PStream s;
|
PStream s;
|
||||||
int length;
|
int length;
|
||||||
PBYTE StartOffset;
|
PBYTE StartOffset;
|
||||||
@ -334,6 +343,8 @@ 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);
|
||||||
|
|
||||||
|
StartOffset = StreamGetPointer(s);
|
||||||
|
|
||||||
ntlm_read_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
ntlm_read_message_header(s, (NTLM_MESSAGE_HEADER*) &message);
|
||||||
|
|
||||||
if (!ntlm_validate_message_header(s, (NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_CHALLENGE))
|
if (!ntlm_validate_message_header(s, (NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_CHALLENGE))
|
||||||
@ -342,60 +353,38 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
return SEC_E_INVALID_TOKEN;
|
return SEC_E_INVALID_TOKEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
StartOffset = StreamGetPointer(s) - 12;
|
|
||||||
|
|
||||||
/* TargetNameFields (8 bytes) */
|
/* TargetNameFields (8 bytes) */
|
||||||
ntlm_read_message_fields(s, &(message.TargetName));
|
ntlm_read_message_fields(s, &(message.TargetName));
|
||||||
|
|
||||||
StreamRead_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamRead_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
StreamRead(s, message.ServerChallenge, 8); /* ServerChallenge (8 bytes) */
|
||||||
ntlm_print_negotiate_flags(context->NegotiateFlags);
|
CopyMemory(context->ServerChallenge, message.ServerChallenge, 8);
|
||||||
#endif
|
|
||||||
|
|
||||||
StreamRead(s, context->ServerChallenge, 8); /* ServerChallenge (8 bytes) */
|
StreamRead(s, message.Reserved, 8); /* Reserved (8 bytes), should be ignored */
|
||||||
StreamSeek(s, 8); /* Reserved (8 bytes), should be ignored */
|
|
||||||
|
|
||||||
/* TargetInfoFields (8 bytes) */
|
/* TargetInfoFields (8 bytes) */
|
||||||
ntlm_read_message_fields(s, &(message.TargetInfo));
|
ntlm_read_message_fields(s, &(message.TargetInfo));
|
||||||
|
|
||||||
/* only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
|
||||||
|
|
||||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
{
|
ntlm_read_version_info(s, &(message.Version)); /* Version (8 bytes) */
|
||||||
StreamSeek(s, 8); /* Version (8 bytes), can be ignored */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Payload (variable) */
|
/* Payload (variable) */
|
||||||
PayloadOffset = StreamGetPointer(s);
|
PayloadOffset = StreamGetPointer(s);
|
||||||
|
|
||||||
if (message.TargetName.Len > 0)
|
if (message.TargetName.Len > 0)
|
||||||
{
|
ntlm_read_message_fields_buffer(s, &(message.TargetName));
|
||||||
p = StartOffset + message.TargetName.BufferOffset;
|
|
||||||
sspi_SecBufferAlloc(&context->TargetName, message.TargetName.Len);
|
|
||||||
CopyMemory(context->TargetName.pvBuffer, p, message.TargetName.Len);
|
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
printf("TargetName (length = %d, offset = %d)\n", message.TargetName.Len, message.TargetName.BufferOffset);
|
|
||||||
winpr_HexDump(context->TargetName.pvBuffer, context->TargetName.cbBuffer);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.TargetInfo.Len > 0)
|
if (message.TargetInfo.Len > 0)
|
||||||
{
|
{
|
||||||
p = StartOffset + message.TargetInfo.BufferOffset;
|
ntlm_read_message_fields_buffer(s, &(message.TargetInfo));
|
||||||
sspi_SecBufferAlloc(&context->TargetInfo, message.TargetInfo.Len);
|
|
||||||
CopyMemory(context->TargetInfo.pvBuffer, p, message.TargetInfo.Len);
|
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
context->TargetInfo.pvBuffer = message.TargetInfo.Buffer;
|
||||||
printf("TargetInfo (length = %d, offset = %d)\n", message.TargetInfo.Len, message.TargetInfo.BufferOffset);
|
context->TargetInfo.cbBuffer = message.TargetInfo.Len;
|
||||||
winpr_HexDump(context->TargetInfo.pvBuffer, context->TargetInfo.cbBuffer);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (context->ntlm_v2)
|
if (context->ntlm_v2)
|
||||||
{
|
{
|
||||||
|
p = StartOffset + message.TargetInfo.BufferOffset;
|
||||||
StreamSetPointer(s, p);
|
StreamSetPointer(s, p);
|
||||||
ntlm_input_av_pairs(context, s);
|
ntlm_input_av_pairs(context, s);
|
||||||
}
|
}
|
||||||
@ -410,6 +399,14 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
|||||||
printf("CHALLENGE_MESSAGE (length = %d)\n", length);
|
printf("CHALLENGE_MESSAGE (length = %d)\n", length);
|
||||||
winpr_HexDump(context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
winpr_HexDump(context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
ntlm_print_negotiate_flags(context->NegotiateFlags);
|
||||||
|
|
||||||
|
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
|
ntlm_print_version_info(&(message.Version));
|
||||||
|
|
||||||
|
ntlm_print_message_fields(&(message.TargetName), "TargetName");
|
||||||
|
ntlm_print_message_fields(&(message.TargetInfo), "TargetInfo");
|
||||||
#endif
|
#endif
|
||||||
/* AV_PAIRs */
|
/* AV_PAIRs */
|
||||||
|
|
||||||
@ -508,6 +505,12 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
UINT32 PayloadOffset;
|
UINT32 PayloadOffset;
|
||||||
NTLM_CHALLENGE_MESSAGE message;
|
NTLM_CHALLENGE_MESSAGE message;
|
||||||
|
|
||||||
|
ZeroMemory(&message, sizeof(message));
|
||||||
|
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||||
|
|
||||||
|
/* Version */
|
||||||
|
ntlm_get_version_info(&(message.Version));
|
||||||
|
|
||||||
/* Server Challenge */
|
/* Server Challenge */
|
||||||
ntlm_generate_server_challenge(context);
|
ntlm_generate_server_challenge(context);
|
||||||
|
|
||||||
@ -515,10 +518,10 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
ntlm_generate_timestamp(context);
|
ntlm_generate_timestamp(context);
|
||||||
|
|
||||||
/* TargetInfo */
|
/* TargetInfo */
|
||||||
ntlm_populate_server_av_pairs(context);
|
ntlm_construct_server_target_info(context);
|
||||||
|
|
||||||
ZeroMemory(&message, sizeof(message));
|
/* ServerChallenge */
|
||||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
CopyMemory(message.ServerChallenge, context->ServerChallenge, 8);
|
||||||
|
|
||||||
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_CHALLENGE);
|
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_CHALLENGE);
|
||||||
|
|
||||||
@ -530,11 +533,6 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
message.TargetName.Len = (UINT16) context->TargetName.cbBuffer;
|
message.TargetName.Len = (UINT16) context->TargetName.cbBuffer;
|
||||||
message.TargetName.Buffer = context->TargetName.pvBuffer;
|
message.TargetName.Buffer = context->TargetName.pvBuffer;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
message.TargetName.Len = 0;
|
|
||||||
message.TargetName.Buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
context->NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
|
context->NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
|
||||||
|
|
||||||
@ -543,11 +541,6 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
message.TargetInfo.Len = (UINT16) context->TargetInfo.cbBuffer;
|
message.TargetInfo.Len = (UINT16) context->TargetInfo.cbBuffer;
|
||||||
message.TargetInfo.Buffer = context->TargetInfo.pvBuffer;
|
message.TargetInfo.Buffer = context->TargetInfo.pvBuffer;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
message.TargetInfo.Len = 0;
|
|
||||||
message.TargetInfo.Buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
PayloadOffset = 48;
|
PayloadOffset = 48;
|
||||||
|
|
||||||
@ -562,41 +555,22 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
|
|
||||||
StreamWrite_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamWrite_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
StreamWrite(s, context->ServerChallenge, 8); /* ServerChallenge (8 bytes) */
|
StreamWrite(s, message.ServerChallenge, 8); /* ServerChallenge (8 bytes) */
|
||||||
StreamZero(s, 8); /* Reserved (8 bytes), should be ignored */
|
StreamWrite(s, message.Reserved, 8); /* Reserved (8 bytes), should be ignored */
|
||||||
|
|
||||||
/* TargetInfoFields (8 bytes) */
|
/* TargetInfoFields (8 bytes) */
|
||||||
ntlm_write_message_fields(s, &(message.TargetInfo));
|
ntlm_write_message_fields(s, &(message.TargetInfo));
|
||||||
|
|
||||||
/* only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
|
||||||
|
|
||||||
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
{
|
ntlm_write_version_info(s, &(message.Version)); /* Version (8 bytes) */
|
||||||
ntlm_get_version_info(&(message.Version));
|
|
||||||
ntlm_write_version_info(s, &(message.Version)); /* Version (8 bytes), can be ignored */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Payload (variable) */
|
/* Payload (variable) */
|
||||||
|
|
||||||
if (message.TargetName.Len > 0)
|
if (context->NegotiateFlags & NTLMSSP_REQUEST_TARGET)
|
||||||
{
|
ntlm_write_message_fields_buffer(s, &(message.TargetName));
|
||||||
StreamWrite(s, message.TargetName.Buffer, message.TargetName.Len);
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
printf("TargetName (length = %d, offset = %d)\n", message.TargetName.Len, message.TargetName.BufferOffset);
|
|
||||||
winpr_HexDump(message.TargetName.Buffer, message.TargetName.Len);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.TargetInfo.Len > 0)
|
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO)
|
||||||
{
|
ntlm_write_message_fields_buffer(s, &(message.TargetInfo));
|
||||||
StreamWrite(s, message.TargetInfo.Buffer, message.TargetInfo.Len);
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
printf("TargetInfo (length = %d, offset = %d)\n", message.TargetInfo.Len, message.TargetInfo.BufferOffset);
|
|
||||||
winpr_HexDump(message.TargetInfo.Buffer, message.TargetInfo.Len);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
length = StreamSize(s);
|
length = StreamSize(s);
|
||||||
buffer->cbBuffer = length;
|
buffer->cbBuffer = length;
|
||||||
@ -608,6 +582,12 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
|||||||
printf("CHALLENGE_MESSAGE (length = %d)\n", length);
|
printf("CHALLENGE_MESSAGE (length = %d)\n", length);
|
||||||
winpr_HexDump(context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
winpr_HexDump(context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
|
ntlm_print_version_info(&(message.Version));
|
||||||
|
|
||||||
|
ntlm_print_message_fields(&(message.TargetName), "TargetName");
|
||||||
|
ntlm_print_message_fields(&(message.TargetInfo), "TargetInfo");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
context->state = NTLM_STATE_AUTHENTICATE;
|
context->state = NTLM_STATE_AUTHENTICATE;
|
||||||
@ -659,57 +639,25 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||||||
StreamRead_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamRead_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
{
|
ntlm_read_version_info(s, &(message.Version)); /* Version (8 bytes) */
|
||||||
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
|
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
printf("Version (length = 8)\n");
|
|
||||||
winpr_HexDump(s->p, 8);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
StreamSeek(s, 8); /* Version (8 bytes) */
|
|
||||||
}
|
|
||||||
|
|
||||||
length = StreamSize(s);
|
length = StreamSize(s);
|
||||||
sspi_SecBufferAlloc(&context->AuthenticateMessage, length);
|
sspi_SecBufferAlloc(&context->AuthenticateMessage, length);
|
||||||
CopyMemory(context->AuthenticateMessage.pvBuffer, s->data, length);
|
CopyMemory(context->AuthenticateMessage.pvBuffer, s->data, length);
|
||||||
buffer->cbBuffer = length;
|
buffer->cbBuffer = length;
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
|
|
||||||
winpr_HexDump(s->data, length);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* DomainName */
|
/* DomainName */
|
||||||
ntlm_read_message_fields_buffer(s, &(message.DomainName));
|
ntlm_read_message_fields_buffer(s, &(message.DomainName));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.DomainName), "DomainName");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* UserName */
|
/* UserName */
|
||||||
ntlm_read_message_fields_buffer(s, &(message.UserName));
|
ntlm_read_message_fields_buffer(s, &(message.UserName));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.UserName), "UserName");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Workstation */
|
/* Workstation */
|
||||||
ntlm_read_message_fields_buffer(s, &(message.Workstation));
|
ntlm_read_message_fields_buffer(s, &(message.Workstation));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.Workstation), "Workstation");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* LmChallengeResponse */
|
/* LmChallengeResponse */
|
||||||
ntlm_read_message_fields_buffer(s, &(message.LmChallengeResponse));
|
ntlm_read_message_fields_buffer(s, &(message.LmChallengeResponse));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.LmChallengeResponse), "LmChallengeResponse");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* NtChallengeResponse */
|
/* NtChallengeResponse */
|
||||||
ntlm_read_message_fields_buffer(s, &(message.NtChallengeResponse));
|
ntlm_read_message_fields_buffer(s, &(message.NtChallengeResponse));
|
||||||
|
|
||||||
@ -720,15 +668,23 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||||||
CopyMemory(context->ClientChallenge, ClientChallengeBuffer, 8);
|
CopyMemory(context->ClientChallenge, ClientChallengeBuffer, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.NtChallengeResponse), "NtChallengeResponse");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EncryptedRandomSessionKey */
|
/* EncryptedRandomSessionKey */
|
||||||
ntlm_read_message_fields_buffer(s, &(message.EncryptedRandomSessionKey));
|
ntlm_read_message_fields_buffer(s, &(message.EncryptedRandomSessionKey));
|
||||||
CopyMemory(context->EncryptedRandomSessionKey, message.EncryptedRandomSessionKey.Buffer, 16);
|
CopyMemory(context->EncryptedRandomSessionKey, message.EncryptedRandomSessionKey.Buffer, 16);
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
#ifdef WITH_DEBUG_NTLM
|
||||||
|
printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
|
||||||
|
winpr_HexDump(s->data, length);
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
|
ntlm_print_version_info(&(message.Version));
|
||||||
|
|
||||||
|
ntlm_print_message_fields(&(message.DomainName), "DomainName");
|
||||||
|
ntlm_print_message_fields(&(message.UserName), "UserName");
|
||||||
|
ntlm_print_message_fields(&(message.Workstation), "Workstation");
|
||||||
|
ntlm_print_message_fields(&(message.LmChallengeResponse), "LmChallengeResponse");
|
||||||
|
ntlm_print_message_fields(&(message.NtChallengeResponse), "NtChallengeResponse");
|
||||||
ntlm_print_message_fields(&(message.EncryptedRandomSessionKey), "EncryptedRandomSessionKey");
|
ntlm_print_message_fields(&(message.EncryptedRandomSessionKey), "EncryptedRandomSessionKey");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -941,21 +897,9 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||||||
|
|
||||||
StreamWrite_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
StreamWrite_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_negotiate_flags(message.NegotiateFlags);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
{
|
|
||||||
ntlm_write_version_info(s, &(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
|
|
||||||
}
|
|
||||||
|
|
||||||
if (context->ntlm_v2)
|
if (context->ntlm_v2)
|
||||||
{
|
{
|
||||||
/* Message Integrity Check */
|
/* Message Integrity Check */
|
||||||
@ -966,56 +910,21 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||||||
/* DomainName */
|
/* DomainName */
|
||||||
ntlm_write_message_fields_buffer(s, &(message.DomainName));
|
ntlm_write_message_fields_buffer(s, &(message.DomainName));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.DomainName), "DomainName");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* UserName */
|
/* UserName */
|
||||||
ntlm_write_message_fields_buffer(s, &(message.UserName));
|
ntlm_write_message_fields_buffer(s, &(message.UserName));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.UserName), "UserName");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Workstation */
|
/* Workstation */
|
||||||
ntlm_write_message_fields_buffer(s, &(message.Workstation));
|
ntlm_write_message_fields_buffer(s, &(message.Workstation));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.Workstation), "Workstation");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* LmChallengeResponse */
|
/* LmChallengeResponse */
|
||||||
ntlm_write_message_fields_buffer(s, &(message.LmChallengeResponse));
|
ntlm_write_message_fields_buffer(s, &(message.LmChallengeResponse));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.LmChallengeResponse), "LmChallengeResponse");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* NtChallengeResponse */
|
/* NtChallengeResponse */
|
||||||
ntlm_write_message_fields_buffer(s, &(message.NtChallengeResponse));
|
ntlm_write_message_fields_buffer(s, &(message.NtChallengeResponse));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
if (context->ntlm_v2)
|
|
||||||
{
|
|
||||||
ntlm_print_av_pairs(context);
|
|
||||||
|
|
||||||
printf("targetInfo (length = %d)\n", (int) context->TargetInfo.cbBuffer);
|
|
||||||
winpr_HexDump(context->TargetInfo.pvBuffer, context->TargetInfo.cbBuffer);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.NtChallengeResponse), "NtChallengeResponse");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* EncryptedRandomSessionKey */
|
/* EncryptedRandomSessionKey */
|
||||||
ntlm_write_message_fields_buffer(s, &(message.EncryptedRandomSessionKey));
|
ntlm_write_message_fields_buffer(s, &(message.EncryptedRandomSessionKey));
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
ntlm_print_message_fields(&(message.EncryptedRandomSessionKey), "EncryptedRandomSessionKey");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
length = StreamSize(s);
|
length = StreamSize(s);
|
||||||
sspi_SecBufferAlloc(&context->AuthenticateMessage, length);
|
sspi_SecBufferAlloc(&context->AuthenticateMessage, length);
|
||||||
CopyMemory(context->AuthenticateMessage.pvBuffer, s->data, length);
|
CopyMemory(context->AuthenticateMessage.pvBuffer, s->data, length);
|
||||||
@ -1029,18 +938,40 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
|||||||
s->p = MicOffset;
|
s->p = MicOffset;
|
||||||
StreamWrite(s, context->MessageIntegrityCheck, 16);
|
StreamWrite(s, context->MessageIntegrityCheck, 16);
|
||||||
s->p = s->data + length;
|
s->p = s->data + length;
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
|
||||||
printf("MessageIntegrityCheck (length = 16)\n");
|
|
||||||
winpr_HexDump(MicOffset, 16);
|
|
||||||
printf("\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_DEBUG_NTLM
|
#ifdef WITH_DEBUG_NTLM
|
||||||
printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
|
printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
|
||||||
winpr_HexDump(s->data, length);
|
winpr_HexDump(s->data, length);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
ntlm_print_negotiate_flags(message.NegotiateFlags);
|
||||||
|
|
||||||
|
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||||
|
ntlm_print_version_info(&(message.Version));
|
||||||
|
|
||||||
|
ntlm_print_message_fields(&(message.DomainName), "DomainName");
|
||||||
|
ntlm_print_message_fields(&(message.UserName), "UserName");
|
||||||
|
ntlm_print_message_fields(&(message.Workstation), "Workstation");
|
||||||
|
ntlm_print_message_fields(&(message.LmChallengeResponse), "LmChallengeResponse");
|
||||||
|
ntlm_print_message_fields(&(message.NtChallengeResponse), "NtChallengeResponse");
|
||||||
|
ntlm_print_message_fields(&(message.EncryptedRandomSessionKey), "EncryptedRandomSessionKey");
|
||||||
|
|
||||||
|
if (context->ntlm_v2)
|
||||||
|
{
|
||||||
|
ntlm_print_av_pairs(context);
|
||||||
|
|
||||||
|
printf("targetInfo (length = %d)\n", (int) context->TargetInfo.cbBuffer);
|
||||||
|
winpr_HexDump(context->TargetInfo.pvBuffer, context->TargetInfo.cbBuffer);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (context->ntlm_v2)
|
||||||
|
{
|
||||||
|
printf("MessageIntegrityCheck (length = 16)\n");
|
||||||
|
winpr_HexDump(MicOffset, 16);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
context->state = NTLM_STATE_FINAL;
|
context->state = NTLM_STATE_FINAL;
|
||||||
|
Loading…
Reference in New Issue
Block a user