libwinpr-sspi: get rid of old AV_PAIR code for NTLM
This commit is contained in:
parent
6d7f1e427c
commit
693b1787b7
@ -47,10 +47,10 @@ void ntlm_SetContextWorkstation(NTLM_CONTEXT* context, char* Workstation)
|
||||
GetComputerNameExA(ComputerNameNetBIOS, Workstation, &nSize);
|
||||
}
|
||||
|
||||
context->WorkstationLength = strlen(Workstation) * 2;
|
||||
context->Workstation = (UINT16*) malloc(context->WorkstationLength);
|
||||
context->Workstation.Length = strlen(Workstation) * 2;
|
||||
context->Workstation.Buffer = (PWSTR) malloc(context->Workstation.Length);
|
||||
MultiByteToWideChar(CP_ACP, 0, Workstation, strlen(Workstation),
|
||||
(LPWSTR) context->Workstation, context->WorkstationLength / 2);
|
||||
context->Workstation.Buffer, context->Workstation.Length / 2);
|
||||
|
||||
if (nSize > 0)
|
||||
free(Workstation);
|
||||
@ -86,14 +86,16 @@ NTLM_CONTEXT* ntlm_ContextNew()
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
context->ntlm_v2 = FALSE;
|
||||
context->NTLMv2 = TRUE;
|
||||
context->UseMIC = FALSE;
|
||||
context->NegotiateFlags = 0;
|
||||
context->SendVersionInfo = TRUE;
|
||||
context->LmCompatibilityLevel = 3;
|
||||
context->state = NTLM_STATE_INITIAL;
|
||||
context->SuppressExtendedProtection = TRUE;
|
||||
context->av_pairs = (AV_PAIRS*) malloc(sizeof(AV_PAIRS));
|
||||
ZeroMemory(context->av_pairs, sizeof(AV_PAIRS));
|
||||
|
||||
if (context->NTLMv2)
|
||||
context->UseMIC = TRUE;
|
||||
}
|
||||
|
||||
return context;
|
||||
@ -107,7 +109,7 @@ void ntlm_ContextFree(NTLM_CONTEXT* context)
|
||||
sspi_SecBufferFree(&context->NegotiateMessage);
|
||||
sspi_SecBufferFree(&context->ChallengeMessage);
|
||||
sspi_SecBufferFree(&context->AuthenticateMessage);
|
||||
sspi_SecBufferFree(&context->TargetInfo);
|
||||
sspi_SecBufferFree(&context->ChallengeTargetInfo);
|
||||
sspi_SecBufferFree(&context->TargetName);
|
||||
sspi_SecBufferFree(&context->NtChallengeResponse);
|
||||
sspi_SecBufferFree(&context->LmChallengeResponse);
|
||||
@ -115,9 +117,7 @@ void ntlm_ContextFree(NTLM_CONTEXT* context)
|
||||
free(context->identity.User);
|
||||
free(context->identity.Password);
|
||||
free(context->identity.Domain);
|
||||
free(context->Workstation);
|
||||
free(context->av_pairs->Timestamp.value);
|
||||
free(context->av_pairs);
|
||||
free(context->Workstation.Buffer);
|
||||
free(context);
|
||||
}
|
||||
|
||||
|
@ -81,36 +81,7 @@ enum _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
|
||||
{
|
||||
UINT16 length;
|
||||
BYTE* value;
|
||||
};
|
||||
typedef struct _AV_PAIR AV_PAIR;
|
||||
|
||||
struct _AV_PAIRS
|
||||
{
|
||||
AV_PAIR NbComputerName;
|
||||
AV_PAIR NbDomainName;
|
||||
AV_PAIR DnsComputerName;
|
||||
AV_PAIR DnsDomainName;
|
||||
AV_PAIR DnsTreeName;
|
||||
AV_PAIR Timestamp;
|
||||
AV_PAIR Restrictions;
|
||||
AV_PAIR TargetName;
|
||||
AV_PAIR ChannelBindings;
|
||||
UINT32 Flags;
|
||||
};
|
||||
typedef struct _AV_PAIRS AV_PAIRS;
|
||||
|
||||
enum _AV_ID
|
||||
enum _NTLM_AV_ID
|
||||
{
|
||||
MsvAvEOL,
|
||||
MsvAvNbComputerName,
|
||||
@ -124,7 +95,14 @@ enum _AV_ID
|
||||
MsvAvTargetName,
|
||||
MsvChannelBindings
|
||||
};
|
||||
typedef enum _AV_ID AV_ID;
|
||||
typedef enum _NTLM_AV_ID NTLM_AV_ID;
|
||||
|
||||
struct _NTLM_AV_PAIR
|
||||
{
|
||||
UINT16 AvId;
|
||||
UINT16 AvLen;
|
||||
};
|
||||
typedef struct _NTLM_AV_PAIR NTLM_AV_PAIR;
|
||||
|
||||
#define MSV_AV_FLAGS_AUTHENTICATION_CONSTRAINED 0x00000001
|
||||
#define MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK 0x00000002
|
||||
@ -242,7 +220,8 @@ typedef struct _NTLM_AUTHENTICATE_MESSAGE NTLM_AUTHENTICATE_MESSAGE;
|
||||
struct _NTLM_CONTEXT
|
||||
{
|
||||
BOOL server;
|
||||
BOOL ntlm_v2;
|
||||
BOOL NTLMv2;
|
||||
BOOL UseMIC;
|
||||
NTLM_STATE state;
|
||||
int SendSeqNum;
|
||||
int RecvSeqNum;
|
||||
@ -254,21 +233,21 @@ struct _NTLM_CONTEXT
|
||||
BYTE* RecvSigningKey;
|
||||
BYTE* SendSealingKey;
|
||||
BYTE* RecvSealingKey;
|
||||
AV_PAIRS* av_pairs;
|
||||
UINT32 NegotiateFlags;
|
||||
UINT16* Workstation;
|
||||
UINT32 WorkstationLength;
|
||||
int LmCompatibilityLevel;
|
||||
int SuppressExtendedProtection;
|
||||
UNICODE_STRING Workstation;
|
||||
SEC_WINNT_AUTH_IDENTITY identity;
|
||||
SecBuffer NegotiateMessage;
|
||||
SecBuffer ChallengeMessage;
|
||||
SecBuffer AuthenticateMessage;
|
||||
SecBuffer TargetInfo;
|
||||
SecBuffer ChallengeTargetInfo;
|
||||
SecBuffer AuthenticateTargetInfo;
|
||||
SecBuffer TargetName;
|
||||
SecBuffer NtChallengeResponse;
|
||||
SecBuffer LmChallengeResponse;
|
||||
BYTE Timestamp[8];
|
||||
BYTE ChallengeTimestamp[8];
|
||||
BYTE ServerChallenge[8];
|
||||
BYTE ClientChallenge[8];
|
||||
BYTE SessionBaseKey[16];
|
||||
|
@ -113,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)
|
||||
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId)
|
||||
{
|
||||
NTLM_AV_PAIR* pAvPair = pAvPairList;
|
||||
|
||||
@ -134,7 +134,7 @@ NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, AV_ID AvId)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, PUNICODE_STRING pValue, LONG AvPairListSize)
|
||||
NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId, PBYTE Value, UINT16 AvLen)
|
||||
{
|
||||
NTLM_AV_PAIR* pAvPair;
|
||||
|
||||
@ -144,290 +144,29 @@ NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, PUNICODE_S
|
||||
return NULL;
|
||||
|
||||
pAvPair->AvId = AvId;
|
||||
pAvPair->AvLen = pValue->Length;
|
||||
pAvPair->AvLen = AvLen;
|
||||
|
||||
CopyMemory(ntlm_av_pair_get_value_pointer(pAvPair), pValue->Buffer, pValue->Length);
|
||||
CopyMemory(ntlm_av_pair_get_value_pointer(pAvPair), Value, AvLen);
|
||||
|
||||
return pAvPair;
|
||||
}
|
||||
|
||||
/**
|
||||
* Input array of AV_PAIRs.\n
|
||||
* AV_PAIR @msdn{cc236646}
|
||||
* @param NTLM context
|
||||
* @param s
|
||||
*/
|
||||
|
||||
void ntlm_input_av_pairs(NTLM_CONTEXT* context, PStream s)
|
||||
NTLM_AV_PAIR* ntlm_av_pair_add_copy(NTLM_AV_PAIR* pAvPairList, NTLM_AV_PAIR* pAvPair)
|
||||
{
|
||||
AV_ID AvId;
|
||||
UINT16 AvLen;
|
||||
BYTE* value;
|
||||
AV_PAIRS* av_pairs = context->av_pairs;
|
||||
NTLM_AV_PAIR* pAvPairCopy;
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("AV_PAIRS = {\n");
|
||||
#endif
|
||||
pAvPairCopy = ntlm_av_pair_get(pAvPairList, MsvAvEOL);
|
||||
|
||||
do
|
||||
{
|
||||
value = NULL;
|
||||
StreamRead_UINT16(s, AvId);
|
||||
StreamRead_UINT16(s, AvLen);
|
||||
if (!pAvPairCopy)
|
||||
return NULL;
|
||||
|
||||
if (AvLen > 0)
|
||||
{
|
||||
if (AvId != MsvAvFlags)
|
||||
{
|
||||
value = malloc(AvLen);
|
||||
StreamRead(s, value, AvLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
StreamRead_UINT32(s, av_pairs->Flags);
|
||||
}
|
||||
}
|
||||
pAvPairCopy->AvId = pAvPair->AvId;
|
||||
pAvPairCopy->AvLen = pAvPair->AvLen;
|
||||
|
||||
switch (AvId)
|
||||
{
|
||||
case MsvAvNbComputerName:
|
||||
av_pairs->NbComputerName.length = AvLen;
|
||||
av_pairs->NbComputerName.value = value;
|
||||
break;
|
||||
CopyMemory(ntlm_av_pair_get_value_pointer(pAvPairCopy),
|
||||
ntlm_av_pair_get_value_pointer(pAvPair), pAvPair->AvLen);
|
||||
|
||||
case MsvAvNbDomainName:
|
||||
av_pairs->NbDomainName.length = AvLen;
|
||||
av_pairs->NbDomainName.value = value;
|
||||
break;
|
||||
|
||||
case MsvAvDnsComputerName:
|
||||
av_pairs->DnsComputerName.length = AvLen;
|
||||
av_pairs->DnsComputerName.value = value;
|
||||
break;
|
||||
|
||||
case MsvAvDnsDomainName:
|
||||
av_pairs->DnsDomainName.length = AvLen;
|
||||
av_pairs->DnsDomainName.value = value;
|
||||
break;
|
||||
|
||||
case MsvAvDnsTreeName:
|
||||
av_pairs->DnsTreeName.length = AvLen;
|
||||
av_pairs->DnsTreeName.value = value;
|
||||
break;
|
||||
|
||||
case MsvAvTimestamp:
|
||||
av_pairs->Timestamp.length = AvLen;
|
||||
av_pairs->Timestamp.value = value;
|
||||
break;
|
||||
|
||||
case MsvAvRestrictions:
|
||||
av_pairs->Restrictions.length = AvLen;
|
||||
av_pairs->Restrictions.value = value;
|
||||
break;
|
||||
|
||||
case MsvAvTargetName:
|
||||
av_pairs->TargetName.length = AvLen;
|
||||
av_pairs->TargetName.value = value;
|
||||
break;
|
||||
|
||||
case MsvChannelBindings:
|
||||
av_pairs->ChannelBindings.length = AvLen;
|
||||
av_pairs->ChannelBindings.value = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
if (AvId < 10)
|
||||
printf("\tAvId: %s, AvLen: %d\n", AV_PAIR_STRINGS[AvId], AvLen);
|
||||
else
|
||||
printf("\tAvId: %s, AvLen: %d\n", "Unknown", AvLen);
|
||||
|
||||
winpr_HexDump(value, AvLen);
|
||||
#endif
|
||||
}
|
||||
while (AvId != MsvAvEOL);
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("}\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Output array of AV_PAIRs.\n
|
||||
* AV_PAIR @msdn{cc236646}
|
||||
* @param NTLM context
|
||||
* @param s
|
||||
*/
|
||||
|
||||
void ntlm_output_av_pairs(NTLM_CONTEXT* context, PSecBuffer buffer)
|
||||
{
|
||||
PStream s;
|
||||
AV_PAIRS* av_pairs = context->av_pairs;
|
||||
|
||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||
|
||||
if (av_pairs->NbDomainName.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvNbDomainName); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->NbDomainName.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->NbDomainName.value, av_pairs->NbDomainName.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->NbComputerName.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvNbComputerName); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->NbComputerName.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->NbComputerName.value, av_pairs->NbComputerName.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->DnsDomainName.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvDnsDomainName); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->DnsDomainName.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->DnsComputerName.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvDnsComputerName); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->DnsComputerName.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->DnsTreeName.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvDnsTreeName); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->DnsTreeName.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->Timestamp.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvTimestamp); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->Timestamp.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->Timestamp.value, av_pairs->Timestamp.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->Flags > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvFlags); /* AvId */
|
||||
StreamWrite_UINT16(s, 4); /* AvLen */
|
||||
StreamWrite_UINT32(s, av_pairs->Flags); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->Restrictions.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvRestrictions); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->Restrictions.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->Restrictions.value, av_pairs->Restrictions.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->ChannelBindings.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvChannelBindings); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->ChannelBindings.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length); /* Value */
|
||||
}
|
||||
|
||||
if (av_pairs->TargetName.length > 0)
|
||||
{
|
||||
StreamWrite_UINT16(s, MsvAvTargetName); /* AvId */
|
||||
StreamWrite_UINT16(s, av_pairs->TargetName.length); /* AvLen */
|
||||
StreamWrite(s, av_pairs->TargetName.value, av_pairs->TargetName.length); /* Value */
|
||||
}
|
||||
|
||||
/* This indicates the end of the AV_PAIR array */
|
||||
StreamWrite_UINT16(s, MsvAvEOL); /* AvId */
|
||||
StreamWrite_UINT16(s, 0); /* AvLen */
|
||||
|
||||
if (context->ntlm_v2)
|
||||
{
|
||||
StreamZero(s, 8);
|
||||
}
|
||||
|
||||
free(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute AV_PAIRs length.\n
|
||||
* AV_PAIR @msdn{cc236646}
|
||||
* @param NTLM context
|
||||
*/
|
||||
|
||||
int ntlm_compute_av_pairs_length(NTLM_CONTEXT* context)
|
||||
{
|
||||
int length = 0;
|
||||
AV_PAIRS* av_pairs = context->av_pairs;
|
||||
|
||||
if (av_pairs->NbDomainName.length > 0)
|
||||
length += av_pairs->NbDomainName.length + 4;
|
||||
|
||||
if (av_pairs->NbComputerName.length > 0)
|
||||
length += av_pairs->NbComputerName.length + 4;
|
||||
|
||||
if (av_pairs->DnsDomainName.length > 0)
|
||||
length += av_pairs->DnsDomainName.length + 4;
|
||||
|
||||
if (av_pairs->DnsComputerName.length > 0)
|
||||
length += av_pairs->DnsComputerName.length + 4;
|
||||
|
||||
if (av_pairs->DnsTreeName.length > 0)
|
||||
length += av_pairs->DnsTreeName.length + 4;
|
||||
|
||||
if (av_pairs->Timestamp.length > 0)
|
||||
length += av_pairs->Timestamp.length;
|
||||
|
||||
if (av_pairs->Flags > 0)
|
||||
length += 4 + 4;
|
||||
|
||||
if (av_pairs->Restrictions.length > 0)
|
||||
length += av_pairs->Restrictions.length + 4;
|
||||
|
||||
if (av_pairs->ChannelBindings.length > 0)
|
||||
length += av_pairs->ChannelBindings.length + 4;
|
||||
|
||||
if (av_pairs->TargetName.length > 0)
|
||||
length += av_pairs->TargetName.length + 4;
|
||||
|
||||
length += 4;
|
||||
|
||||
if (context->ntlm_v2)
|
||||
length += 8;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate array of AV_PAIRs.\n
|
||||
* AV_PAIR @msdn{cc236646}
|
||||
* @param NTLM context
|
||||
*/
|
||||
|
||||
void ntlm_populate_av_pairs(NTLM_CONTEXT* context)
|
||||
{
|
||||
int length;
|
||||
AV_PAIRS* av_pairs = context->av_pairs;
|
||||
|
||||
/* MsvAvFlags */
|
||||
av_pairs->Flags = 0x00000002; /* Indicates the present of a Message Integrity Check (MIC) */
|
||||
|
||||
/* Restriction_Encoding */
|
||||
ntlm_output_restriction_encoding(context);
|
||||
|
||||
/* TargetName */
|
||||
ntlm_output_target_name(context);
|
||||
|
||||
/* ChannelBindings */
|
||||
ntlm_output_channel_bindings(context);
|
||||
|
||||
length = ntlm_compute_av_pairs_length(context);
|
||||
sspi_SecBufferAlloc(&context->TargetInfo, length);
|
||||
ntlm_output_av_pairs(context, &context->TargetInfo);
|
||||
return pAvPairCopy;
|
||||
}
|
||||
|
||||
void ntlm_get_target_computer_name(PUNICODE_STRING pName, COMPUTER_NAME_FORMAT type)
|
||||
@ -452,7 +191,7 @@ void ntlm_get_target_computer_name(PUNICODE_STRING pName, COMPUTER_NAME_FORMAT t
|
||||
free(name);
|
||||
}
|
||||
|
||||
void ntlm_construct_server_target_info(NTLM_CONTEXT* context)
|
||||
void ntlm_construct_challenge_target_info(NTLM_CONTEXT* context)
|
||||
{
|
||||
int length;
|
||||
ULONG AvPairsCount;
|
||||
@ -463,142 +202,132 @@ void ntlm_construct_server_target_info(NTLM_CONTEXT* context)
|
||||
UNICODE_STRING NbComputerName;
|
||||
UNICODE_STRING DnsDomainName;
|
||||
UNICODE_STRING DnsComputerName;
|
||||
UNICODE_STRING Timestamp;
|
||||
|
||||
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);
|
||||
|
||||
Timestamp.Buffer = (PWSTR) context->Timestamp;
|
||||
Timestamp.Length = sizeof(context->Timestamp);
|
||||
|
||||
AvPairsCount = 5;
|
||||
AvPairsLength = NbDomainName.Length + NbComputerName.Length +
|
||||
DnsDomainName.Length + DnsComputerName.Length + 8;
|
||||
|
||||
length = ntlm_av_pair_list_size(AvPairsCount, AvPairsLength);
|
||||
sspi_SecBufferAlloc(&context->TargetInfo, length);
|
||||
sspi_SecBufferAlloc(&context->ChallengeTargetInfo, length);
|
||||
|
||||
pAvPairList = (NTLM_AV_PAIR*) context->TargetInfo.pvBuffer;
|
||||
AvPairListSize = (ULONG) context->TargetInfo.cbBuffer;
|
||||
pAvPairList = (NTLM_AV_PAIR*) context->ChallengeTargetInfo.pvBuffer;
|
||||
AvPairListSize = (ULONG) context->ChallengeTargetInfo.cbBuffer;
|
||||
|
||||
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);
|
||||
ntlm_av_pair_add(pAvPairList, MsvAvNbDomainName, (PBYTE) NbDomainName.Buffer, NbDomainName.Length);
|
||||
ntlm_av_pair_add(pAvPairList, MsvAvNbComputerName, (PBYTE) NbComputerName.Buffer, NbComputerName.Length);
|
||||
ntlm_av_pair_add(pAvPairList, MsvAvDnsDomainName, (PBYTE) DnsDomainName.Buffer, DnsDomainName.Length);
|
||||
ntlm_av_pair_add(pAvPairList, MsvAvDnsComputerName, (PBYTE) DnsComputerName.Buffer, DnsComputerName.Length);
|
||||
ntlm_av_pair_add(pAvPairList, MsvAvTimestamp, context->Timestamp, sizeof(context->Timestamp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Print array of AV_PAIRs.\n
|
||||
* AV_PAIR @msdn{cc236646}
|
||||
* @param NTLM context
|
||||
*/
|
||||
|
||||
void ntlm_print_av_pairs(NTLM_CONTEXT* context)
|
||||
void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context)
|
||||
{
|
||||
AV_PAIRS* av_pairs = context->av_pairs;
|
||||
ULONG size;
|
||||
ULONG AvPairsCount;
|
||||
ULONG AvPairsValueLength;
|
||||
NTLM_AV_PAIR* AvTimestamp;
|
||||
NTLM_AV_PAIR* AvNbDomainName;
|
||||
NTLM_AV_PAIR* AvNbComputerName;
|
||||
NTLM_AV_PAIR* AvDnsDomainName;
|
||||
NTLM_AV_PAIR* AvDnsComputerName;
|
||||
NTLM_AV_PAIR* AvDnsTreeName;
|
||||
NTLM_AV_PAIR* ChallengeTargetInfo;
|
||||
NTLM_AV_PAIR* AuthenticateTargetInfo;
|
||||
|
||||
printf("AV_PAIRS = {\n");
|
||||
AvPairsCount = AvPairsValueLength = 0;
|
||||
ChallengeTargetInfo = (NTLM_AV_PAIR*) context->ChallengeTargetInfo.pvBuffer;
|
||||
|
||||
if (av_pairs->NbDomainName.length > 0)
|
||||
AvNbDomainName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvNbDomainName);
|
||||
AvNbComputerName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvNbComputerName);
|
||||
AvDnsDomainName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvDnsDomainName);
|
||||
AvDnsComputerName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvDnsComputerName);
|
||||
AvDnsTreeName = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvDnsTreeName);
|
||||
AvTimestamp = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvTimestamp);
|
||||
|
||||
if (AvNbDomainName != NULL)
|
||||
{
|
||||
printf("\tAvId: MsvAvNbDomainName AvLen: %d\n", av_pairs->NbDomainName.length);
|
||||
winpr_HexDump(av_pairs->NbDomainName.value, av_pairs->NbDomainName.length);
|
||||
AvPairsCount++; /* MsvAvNbDomainName */
|
||||
AvPairsValueLength += AvNbDomainName->AvLen;
|
||||
}
|
||||
|
||||
if (av_pairs->NbComputerName.length > 0)
|
||||
if (AvNbComputerName != NULL)
|
||||
{
|
||||
printf("\tAvId: MsvAvNbComputerName AvLen: %d\n", av_pairs->NbComputerName.length);
|
||||
winpr_HexDump(av_pairs->NbComputerName.value, av_pairs->NbComputerName.length);
|
||||
AvPairsCount++; /* MsvAvNbComputerName */
|
||||
AvPairsValueLength += AvNbComputerName->AvLen;
|
||||
}
|
||||
|
||||
if (av_pairs->DnsDomainName.length > 0)
|
||||
if (AvDnsDomainName != NULL)
|
||||
{
|
||||
printf("\tAvId: MsvAvDnsDomainName AvLen: %d\n", av_pairs->DnsDomainName.length);
|
||||
winpr_HexDump(av_pairs->DnsDomainName.value, av_pairs->DnsDomainName.length);
|
||||
AvPairsCount++; /* MsvAvDnsDomainName */
|
||||
AvPairsValueLength += AvDnsDomainName->AvLen;
|
||||
}
|
||||
|
||||
if (av_pairs->DnsComputerName.length > 0)
|
||||
if (AvDnsComputerName != NULL)
|
||||
{
|
||||
printf("\tAvId: MsvAvDnsComputerName AvLen: %d\n", av_pairs->DnsComputerName.length);
|
||||
winpr_HexDump(av_pairs->DnsComputerName.value, av_pairs->DnsComputerName.length);
|
||||
AvPairsCount++; /* MsvAvDnsComputerName */
|
||||
AvPairsValueLength += AvDnsComputerName->AvLen;
|
||||
}
|
||||
|
||||
if (av_pairs->DnsTreeName.length > 0)
|
||||
if (AvDnsTreeName != NULL)
|
||||
{
|
||||
printf("\tAvId: MsvAvDnsTreeName AvLen: %d\n", av_pairs->DnsTreeName.length);
|
||||
winpr_HexDump(av_pairs->DnsTreeName.value, av_pairs->DnsTreeName.length);
|
||||
AvPairsCount++; /* MsvAvDnsTreeName */
|
||||
AvPairsValueLength += AvDnsTreeName->AvLen;
|
||||
}
|
||||
|
||||
if (av_pairs->Timestamp.length > 0)
|
||||
AvPairsCount++; /* MsvAvTimestamp */
|
||||
AvPairsValueLength += 8;
|
||||
|
||||
if (context->UseMIC)
|
||||
{
|
||||
printf("\tAvId: MsvAvTimestamp AvLen: %d\n", av_pairs->Timestamp.length);
|
||||
winpr_HexDump(av_pairs->Timestamp.value, av_pairs->Timestamp.length);
|
||||
AvPairsCount++; /* MsvAvFlags */
|
||||
AvPairsValueLength += 4;
|
||||
}
|
||||
|
||||
if (av_pairs->Flags > 0)
|
||||
size = ntlm_av_pair_list_size(AvPairsCount, AvPairsValueLength);
|
||||
|
||||
if (context->NTLMv2)
|
||||
size += 8; /* unknown 8-byte padding */
|
||||
|
||||
sspi_SecBufferAlloc(&context->AuthenticateTargetInfo, size);
|
||||
AuthenticateTargetInfo = (NTLM_AV_PAIR*) context->AuthenticateTargetInfo.pvBuffer;
|
||||
|
||||
ntlm_av_pair_list_init(AuthenticateTargetInfo);
|
||||
|
||||
if (AvNbDomainName != NULL)
|
||||
ntlm_av_pair_add_copy(AuthenticateTargetInfo, AvNbDomainName);
|
||||
|
||||
if (AvNbComputerName != NULL)
|
||||
ntlm_av_pair_add_copy(AuthenticateTargetInfo, AvNbComputerName);
|
||||
|
||||
if (AvDnsDomainName != NULL)
|
||||
ntlm_av_pair_add_copy(AuthenticateTargetInfo, AvDnsDomainName);
|
||||
|
||||
if (AvDnsComputerName != NULL)
|
||||
ntlm_av_pair_add_copy(AuthenticateTargetInfo, AvDnsComputerName);
|
||||
|
||||
if (AvDnsTreeName != NULL)
|
||||
ntlm_av_pair_add_copy(AuthenticateTargetInfo, AvDnsTreeName);
|
||||
|
||||
if (AvTimestamp != NULL)
|
||||
ntlm_av_pair_add_copy(AuthenticateTargetInfo, AvTimestamp);
|
||||
|
||||
if (context->UseMIC)
|
||||
{
|
||||
printf("\tAvId: MsvAvFlags AvLen: %d\n", 4);
|
||||
printf("0x%08X\n", av_pairs->Flags);
|
||||
UINT32 flags = MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK;
|
||||
ntlm_av_pair_add(AuthenticateTargetInfo, MsvAvFlags, (PBYTE) &flags, 4);
|
||||
}
|
||||
|
||||
if (av_pairs->Restrictions.length > 0)
|
||||
if (context->NTLMv2)
|
||||
{
|
||||
printf("\tAvId: MsvAvRestrictions AvLen: %d\n", av_pairs->Restrictions.length);
|
||||
winpr_HexDump(av_pairs->Restrictions.value, av_pairs->Restrictions.length);
|
||||
}
|
||||
NTLM_AV_PAIR* AvEOL;
|
||||
|
||||
if (av_pairs->ChannelBindings.length > 0)
|
||||
{
|
||||
printf("\tAvId: MsvChannelBindings AvLen: %d\n", av_pairs->ChannelBindings.length);
|
||||
winpr_HexDump(av_pairs->ChannelBindings.value, av_pairs->ChannelBindings.length);
|
||||
AvEOL = ntlm_av_pair_get(ChallengeTargetInfo, MsvAvEOL);
|
||||
ZeroMemory((void*) AvEOL, 12);
|
||||
}
|
||||
|
||||
if (av_pairs->TargetName.length > 0)
|
||||
{
|
||||
printf("\tAvId: MsvAvTargetName AvLen: %d\n", av_pairs->TargetName.length);
|
||||
winpr_HexDump(av_pairs->TargetName.value, av_pairs->TargetName.length);
|
||||
}
|
||||
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Free array of AV_PAIRs.\n
|
||||
* AV_PAIR @msdn{cc236646}
|
||||
* @param NTLM context
|
||||
*/
|
||||
|
||||
void ntlm_free_av_pairs(NTLM_CONTEXT* context)
|
||||
{
|
||||
AV_PAIRS* av_pairs = context->av_pairs;
|
||||
|
||||
if (av_pairs != NULL)
|
||||
{
|
||||
if (av_pairs->NbComputerName.value != NULL)
|
||||
free(av_pairs->NbComputerName.value);
|
||||
if (av_pairs->NbDomainName.value != NULL)
|
||||
free(av_pairs->NbDomainName.value);
|
||||
if (av_pairs->DnsComputerName.value != NULL)
|
||||
free(av_pairs->DnsComputerName.value);
|
||||
if (av_pairs->DnsDomainName.value != NULL)
|
||||
free(av_pairs->DnsDomainName.value);
|
||||
if (av_pairs->DnsTreeName.value != NULL)
|
||||
free(av_pairs->DnsTreeName.value);
|
||||
if (av_pairs->Timestamp.value != NULL)
|
||||
free(av_pairs->Timestamp.value);
|
||||
if (av_pairs->Restrictions.value != NULL)
|
||||
free(av_pairs->Restrictions.value);
|
||||
if (av_pairs->TargetName.value != NULL)
|
||||
free(av_pairs->TargetName.value);
|
||||
if (av_pairs->ChannelBindings.value != NULL)
|
||||
free(av_pairs->ChannelBindings.value);
|
||||
|
||||
free(av_pairs);
|
||||
}
|
||||
|
||||
context->av_pairs = NULL;
|
||||
}
|
||||
|
@ -31,16 +31,11 @@ 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);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, AV_ID AvId, PUNICODE_STRING pValue, LONG AvPairListSize);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_get(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_add(NTLM_AV_PAIR* pAvPairList, NTLM_AV_ID AvId, PBYTE Value, UINT16 AvLen);
|
||||
NTLM_AV_PAIR* ntlm_av_pair_add_copy(NTLM_AV_PAIR* pAvPairList, NTLM_AV_PAIR* pAvPair);
|
||||
|
||||
void ntlm_construct_server_target_info(NTLM_CONTEXT* context);
|
||||
|
||||
void ntlm_input_av_pairs(NTLM_CONTEXT* context, PStream s);
|
||||
void ntlm_output_av_pairs(NTLM_CONTEXT* context, PSecBuffer buffer);
|
||||
void ntlm_populate_av_pairs(NTLM_CONTEXT* context);
|
||||
void ntlm_populate_server_av_pairs(NTLM_CONTEXT* context);
|
||||
void ntlm_print_av_pairs(NTLM_CONTEXT* context);
|
||||
void ntlm_free_av_pairs(NTLM_CONTEXT* context);
|
||||
void ntlm_construct_challenge_target_info(NTLM_CONTEXT* context);
|
||||
void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context);
|
||||
|
||||
#endif /* WINPR_SSPI_NTLM_AV_PAIRS_H */
|
||||
|
@ -148,6 +148,8 @@ void ntlm_write_ntlm_v2_response(PStream s, NTLMv2_RESPONSE* response)
|
||||
ntlm_write_ntlm_v2_client_challenge(s, &(response->Challenge));
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/**
|
||||
* Output Restriction_Encoding.\n
|
||||
* Restriction_Encoding @msdn{cc236647}
|
||||
@ -230,6 +232,8 @@ void ntlm_output_channel_bindings(NTLM_CONTEXT* context)
|
||||
PStreamFreeDetach(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Get current time, in tenths of microseconds since midnight of January 1, 1601.
|
||||
* @param[out] timestamp 64-bit little-endian timestamp
|
||||
@ -255,33 +259,14 @@ void ntlm_current_time(BYTE* timestamp)
|
||||
|
||||
void ntlm_generate_timestamp(NTLM_CONTEXT* context)
|
||||
{
|
||||
ntlm_current_time(context->Timestamp);
|
||||
BYTE ZeroTimestamp[8];
|
||||
|
||||
if (context->ntlm_v2)
|
||||
{
|
||||
if (context->av_pairs->Timestamp.length == 8)
|
||||
{
|
||||
CopyMemory(context->av_pairs->Timestamp.value, context->Timestamp, 8);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
context->ntlm_v2 = FALSE;
|
||||
context->av_pairs->Timestamp.length = 8;
|
||||
context->av_pairs->Timestamp.value = malloc(context->av_pairs->Timestamp.length);
|
||||
CopyMemory(context->av_pairs->Timestamp.value, context->Timestamp, 8);
|
||||
}
|
||||
}
|
||||
ZeroMemory(ZeroTimestamp, 8);
|
||||
|
||||
if (memcmp(ZeroTimestamp, context->ChallengeTimestamp, 8) != 0)
|
||||
CopyMemory(context->Timestamp, context->ChallengeTimestamp, 8);
|
||||
else
|
||||
{
|
||||
if (context->av_pairs->Timestamp.length != 8)
|
||||
{
|
||||
context->av_pairs->Timestamp.length = 8;
|
||||
context->av_pairs->Timestamp.value = malloc(context->av_pairs->Timestamp.length);
|
||||
}
|
||||
|
||||
CopyMemory(context->av_pairs->Timestamp.value, context->Timestamp, 8);
|
||||
}
|
||||
ntlm_current_time(context->Timestamp);
|
||||
}
|
||||
|
||||
void ntlm_fetch_ntlm_v2_hash(NTLM_CONTEXT* context, char* hash)
|
||||
@ -368,7 +353,7 @@ void ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
|
||||
SecBuffer ntlm_v2_temp;
|
||||
SecBuffer ntlm_v2_temp_chal;
|
||||
|
||||
sspi_SecBufferAlloc(&ntlm_v2_temp, context->TargetInfo.cbBuffer + 28);
|
||||
sspi_SecBufferAlloc(&ntlm_v2_temp, context->ChallengeTargetInfo.cbBuffer + 28);
|
||||
|
||||
ZeroMemory(ntlm_v2_temp.pvBuffer, ntlm_v2_temp.cbBuffer);
|
||||
blob = (BYTE*) ntlm_v2_temp.pvBuffer;
|
||||
@ -389,8 +374,8 @@ void ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
|
||||
winpr_HexDump((BYTE*) context->identity.Domain, context->identity.DomainLength * 2);
|
||||
printf("\n");
|
||||
|
||||
printf("Workstation (length = %d)\n", context->WorkstationLength);
|
||||
winpr_HexDump((BYTE*) context->Workstation, context->WorkstationLength);
|
||||
printf("Workstation (length = %d)\n", context->Workstation.Length);
|
||||
winpr_HexDump((BYTE*) context->Workstation.Buffer, context->Workstation.Length);
|
||||
printf("\n");
|
||||
|
||||
printf("NTOWFv2, NTLMv2 Hash\n");
|
||||
@ -403,10 +388,10 @@ void ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context)
|
||||
blob[1] = 1; /* HighRespType (1 byte) */
|
||||
/* Reserved1 (2 bytes) */
|
||||
/* Reserved2 (4 bytes) */
|
||||
CopyMemory(&blob[8], context->av_pairs->Timestamp.value, 8); /* Timestamp (8 bytes) */
|
||||
CopyMemory(&blob[8], context->Timestamp, 8); /* Timestamp (8 bytes) */
|
||||
CopyMemory(&blob[16], context->ClientChallenge, 8); /* ClientChallenge (8 bytes) */
|
||||
/* Reserved3 (4 bytes) */
|
||||
CopyMemory(&blob[28], context->TargetInfo.pvBuffer, context->TargetInfo.cbBuffer);
|
||||
CopyMemory(&blob[28], context->ChallengeTargetInfo.pvBuffer, context->ChallengeTargetInfo.cbBuffer);
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("NTLMv2 Response Temp Blob\n");
|
||||
|
@ -247,33 +247,23 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
|
||||
ntlm_populate_message_header((NTLM_MESSAGE_HEADER*) &message, MESSAGE_TYPE_NEGOTIATE);
|
||||
|
||||
if (context->ntlm_v2)
|
||||
if (context->NTLMv2)
|
||||
{
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_56;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_VERSION;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_OEM;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||
}
|
||||
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_get_version_info(&(message.Version));
|
||||
|
||||
@ -328,11 +318,11 @@ SECURITY_STATUS ntlm_write_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
|
||||
SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buffer)
|
||||
{
|
||||
PBYTE p;
|
||||
PStream s;
|
||||
int length;
|
||||
PBYTE StartOffset;
|
||||
PBYTE PayloadOffset;
|
||||
NTLM_AV_PAIR* AvTimestamp;
|
||||
NTLM_CHALLENGE_MESSAGE message;
|
||||
|
||||
ntlm_generate_client_challenge(context);
|
||||
@ -377,14 +367,17 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
||||
{
|
||||
ntlm_read_message_fields_buffer(s, &(message.TargetInfo));
|
||||
|
||||
context->TargetInfo.pvBuffer = message.TargetInfo.Buffer;
|
||||
context->TargetInfo.cbBuffer = message.TargetInfo.Len;
|
||||
context->ChallengeTargetInfo.pvBuffer = message.TargetInfo.Buffer;
|
||||
context->ChallengeTargetInfo.cbBuffer = message.TargetInfo.Len;
|
||||
|
||||
if (context->ntlm_v2)
|
||||
AvTimestamp = ntlm_av_pair_get((NTLM_AV_PAIR*) message.TargetInfo.Buffer, MsvAvTimestamp);
|
||||
|
||||
if (AvTimestamp != NULL)
|
||||
{
|
||||
p = StartOffset + message.TargetInfo.BufferOffset;
|
||||
StreamSetPointer(s, p);
|
||||
ntlm_input_av_pairs(context, s);
|
||||
if (context->NTLMv2)
|
||||
context->UseMIC = TRUE;
|
||||
|
||||
CopyMemory(context->ChallengeTimestamp, ntlm_av_pair_get_value_pointer(AvTimestamp), 8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,8 +401,12 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
||||
#endif
|
||||
/* AV_PAIRs */
|
||||
|
||||
if (context->ntlm_v2)
|
||||
ntlm_populate_av_pairs(context);
|
||||
if (context->NTLMv2)
|
||||
{
|
||||
ntlm_construct_authenticate_target_info(context);
|
||||
context->ChallengeTargetInfo.pvBuffer = context->AuthenticateTargetInfo.pvBuffer;
|
||||
context->ChallengeTargetInfo.cbBuffer = context->AuthenticateTargetInfo.cbBuffer;
|
||||
}
|
||||
|
||||
/* Timestamp */
|
||||
ntlm_generate_timestamp(context);
|
||||
@ -516,7 +513,7 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
ntlm_generate_timestamp(context);
|
||||
|
||||
/* TargetInfo */
|
||||
ntlm_construct_server_target_info(context);
|
||||
ntlm_construct_challenge_target_info(context);
|
||||
|
||||
/* ServerChallenge */
|
||||
CopyMemory(message.ServerChallenge, context->ServerChallenge, 8);
|
||||
@ -538,8 +535,8 @@ SECURITY_STATUS ntlm_write_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer bu
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO)
|
||||
{
|
||||
message.TargetInfo.Len = (UINT16) context->TargetInfo.cbBuffer;
|
||||
message.TargetInfo.Buffer = context->TargetInfo.pvBuffer;
|
||||
message.TargetInfo.Len = (UINT16) context->ChallengeTargetInfo.cbBuffer;
|
||||
message.TargetInfo.Buffer = context->ChallengeTargetInfo.pvBuffer;
|
||||
}
|
||||
|
||||
PayloadOffset = 48;
|
||||
@ -678,8 +675,8 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
context->NtChallengeResponse.pvBuffer = message.NtChallengeResponse.Buffer;
|
||||
context->NtChallengeResponse.cbBuffer = message.NtChallengeResponse.Len;
|
||||
|
||||
context->TargetInfo.pvBuffer = (void*) response.Challenge.AvPairs;
|
||||
context->TargetInfo.cbBuffer = message.NtChallengeResponse.Len - (28 + 16);
|
||||
context->ChallengeTargetInfo.pvBuffer = (void*) response.Challenge.AvPairs;
|
||||
context->ChallengeTargetInfo.cbBuffer = message.NtChallengeResponse.Len - (28 + 16);
|
||||
|
||||
CopyMemory(context->ClientChallenge, response.Challenge.ClientChallenge, 8);
|
||||
|
||||
@ -775,7 +772,7 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
printf("Actual MIC:\n");
|
||||
winpr_HexDump(message.MessageIntegrityCheck, 16);
|
||||
|
||||
//return SEC_E_MESSAGE_ALTERED;
|
||||
return SEC_E_MESSAGE_ALTERED;
|
||||
}
|
||||
}
|
||||
|
||||
@ -854,47 +851,38 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
{
|
||||
PStream s;
|
||||
int length;
|
||||
BYTE* MicOffset = NULL;
|
||||
UINT32 MicOffset = 0;
|
||||
UINT32 PayloadBufferOffset;
|
||||
NTLM_AUTHENTICATE_MESSAGE message;
|
||||
|
||||
ZeroMemory(&message, sizeof(message));
|
||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||
|
||||
if (context->ntlm_v2)
|
||||
if (context->NTLMv2)
|
||||
{
|
||||
/* observed: 35 82 88 e2 (0xE2888235) */
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_56;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_VERSION;
|
||||
}
|
||||
|
||||
if (context->UseMIC)
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||
}
|
||||
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_EXTENDED_SESSION_SECURITY;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
|
||||
message.NegotiateFlags |= NTLMSSP_REQUEST_TARGET;
|
||||
message.NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE;
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_get_version_info(&(message.Version));
|
||||
|
||||
message.Workstation.Len = context->WorkstationLength;
|
||||
message.Workstation.Buffer = (BYTE*) context->Workstation;
|
||||
message.Workstation.Len = context->Workstation.Length;
|
||||
message.Workstation.Buffer = (BYTE*) context->Workstation.Buffer;
|
||||
|
||||
if (context->ntlm_v2 < 1)
|
||||
if (!context->NTLMv2)
|
||||
message.Workstation.Len = 0;
|
||||
|
||||
if (message.Workstation.Len > 0)
|
||||
@ -923,7 +911,7 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
|
||||
PayloadBufferOffset = 64;
|
||||
|
||||
if (context->ntlm_v2)
|
||||
if (context->UseMIC)
|
||||
PayloadBufferOffset += 16; /* Message Integrity Check */
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
@ -968,10 +956,10 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
ntlm_write_version_info(s, &(message.Version));
|
||||
|
||||
if (context->ntlm_v2)
|
||||
if (context->UseMIC)
|
||||
{
|
||||
/* Message Integrity Check */
|
||||
MicOffset = s->p;
|
||||
MicOffset = StreamGetOffset(s);
|
||||
StreamZero(s, 16);
|
||||
}
|
||||
|
||||
@ -998,14 +986,14 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
CopyMemory(context->AuthenticateMessage.pvBuffer, s->data, length);
|
||||
buffer->cbBuffer = length;
|
||||
|
||||
if (context->ntlm_v2)
|
||||
if (context->UseMIC)
|
||||
{
|
||||
/* Message Integrity Check */
|
||||
ntlm_compute_message_integrity_check(context);
|
||||
|
||||
s->p = MicOffset;
|
||||
StreamSetOffset(s, MicOffset);
|
||||
StreamWrite(s, context->MessageIntegrityCheck, 16);
|
||||
s->p = s->data + length;
|
||||
StreamSetOffset(s, length);
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
@ -1025,19 +1013,10 @@ SECURITY_STATUS ntlm_write_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
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)
|
||||
if (context->UseMIC)
|
||||
{
|
||||
printf("MessageIntegrityCheck (length = 16)\n");
|
||||
winpr_HexDump(MicOffset, 16);
|
||||
winpr_HexDump(context->MessageIntegrityCheck, 16);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user