mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2024-11-27 11:54:44 +08:00
libwinpr-sspi: get partial server-side NLA functionality with mstsc.exe as a client
This commit is contained in:
parent
bf559e37eb
commit
6d7f1e427c
@ -537,6 +537,12 @@ int credssp_server_authenticate(rdpCredssp* credssp)
|
||||
status = SEC_I_CONTINUE_NEEDED;
|
||||
}
|
||||
|
||||
if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED))
|
||||
{
|
||||
printf("AcceptSecurityContext status: 0x%08X\n", status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* send authentication token */
|
||||
|
||||
#ifdef WITH_DEBUG_CREDSSP
|
||||
|
@ -86,12 +86,12 @@ NTLM_CONTEXT* ntlm_ContextNew()
|
||||
|
||||
if (context != NULL)
|
||||
{
|
||||
context->ntlm_v2 = TRUE;
|
||||
context->ntlm_v2 = FALSE;
|
||||
context->NegotiateFlags = 0;
|
||||
context->SendVersionInfo = TRUE;
|
||||
context->LmCompatibilityLevel = 3;
|
||||
context->state = NTLM_STATE_INITIAL;
|
||||
context->SuppressExtendedProtection = 1;
|
||||
context->SuppressExtendedProtection = TRUE;
|
||||
context->av_pairs = (AV_PAIRS*) malloc(sizeof(AV_PAIRS));
|
||||
ZeroMemory(context->av_pairs, sizeof(AV_PAIRS));
|
||||
}
|
||||
|
@ -147,6 +147,16 @@ struct _NTLM_VERSION_INFO
|
||||
};
|
||||
typedef struct _NTLM_VERSION_INFO NTLM_VERSION_INFO;
|
||||
|
||||
struct _NTLM_RESTRICTION_ENCODING
|
||||
{
|
||||
UINT32 Size;
|
||||
UINT32 Z4;
|
||||
UINT32 IntegrityLevel;
|
||||
UINT32 SubjectIntegrityLevel;
|
||||
BYTE MachineId[32];
|
||||
};
|
||||
typedef struct _NTLM_RESTRICTION_ENCODING NTLM_RESTRICTION_ENCODING;
|
||||
|
||||
struct _NTLM_RESPONSE
|
||||
{
|
||||
BYTE Response[24];
|
||||
@ -236,7 +246,7 @@ struct _NTLM_CONTEXT
|
||||
NTLM_STATE state;
|
||||
int SendSeqNum;
|
||||
int RecvSeqNum;
|
||||
int SendVersionInfo;
|
||||
BOOL SendVersionInfo;
|
||||
BOOL confidentiality;
|
||||
RC4_KEY SendRc4Seal;
|
||||
RC4_KEY RecvRc4Seal;
|
||||
|
@ -219,8 +219,8 @@ SECURITY_STATUS ntlm_read_NegotiateMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
||||
context->NegotiateMessage.BufferType = buffer->BufferType;
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("NEGOTIATE_MESSAGE (length = %d)\n", length);
|
||||
winpr_HexDump(s->data, length);
|
||||
printf("NEGOTIATE_MESSAGE (length = %d)\n", (int) context->NegotiateMessage.cbBuffer);
|
||||
winpr_HexDump(context->NegotiateMessage.pvBuffer, context->NegotiateMessage.cbBuffer);
|
||||
printf("\n");
|
||||
|
||||
ntlm_print_negotiate_flags(message.NegotiateFlags);
|
||||
@ -353,7 +353,8 @@ SECURITY_STATUS ntlm_read_ChallengeMessage(NTLM_CONTEXT* context, PSecBuffer buf
|
||||
/* TargetNameFields (8 bytes) */
|
||||
ntlm_read_message_fields(s, &(message.TargetName));
|
||||
|
||||
StreamRead_UINT32(s, context->NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
StreamRead_UINT32(s, message.NegotiateFlags); /* NegotiateFlags (4 bytes) */
|
||||
context->NegotiateFlags = message.NegotiateFlags;
|
||||
|
||||
StreamRead(s, message.ServerChallenge, 8); /* ServerChallenge (8 bytes) */
|
||||
CopyMemory(context->ServerChallenge, message.ServerChallenge, 8);
|
||||
@ -602,11 +603,17 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
{
|
||||
PStream s;
|
||||
int length;
|
||||
UINT32 flags = 0;
|
||||
UINT32 flags;
|
||||
UINT32 MicOffset;
|
||||
NTLM_AV_PAIR* AvFlags;
|
||||
NTLMv2_RESPONSE response;
|
||||
UINT32 PayloadBufferOffset;
|
||||
NTLM_AUTHENTICATE_MESSAGE message;
|
||||
|
||||
flags = 0;
|
||||
MicOffset = 0;
|
||||
AvFlags = NULL;
|
||||
|
||||
ZeroMemory(&message, sizeof(message));
|
||||
s = PStreamAllocAttach(buffer->pvBuffer, buffer->cbBuffer);
|
||||
|
||||
@ -664,12 +671,16 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
|
||||
if (message.NtChallengeResponse.Len > 0)
|
||||
{
|
||||
NTLM_AV_PAIR* AvFlags;
|
||||
|
||||
PStream s = PStreamAllocAttach(message.NtChallengeResponse.Buffer, message.NtChallengeResponse.Len);
|
||||
ntlm_read_ntlm_v2_response(s, &response);
|
||||
PStreamFreeDetach(s);
|
||||
|
||||
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);
|
||||
|
||||
CopyMemory(context->ClientChallenge, response.Challenge.ClientChallenge, 8);
|
||||
|
||||
AvFlags = ntlm_av_pair_get(response.Challenge.AvPairs, MsvAvFlags);
|
||||
@ -682,25 +693,23 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
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;
|
||||
|
||||
StreamSetOffset(s, PayloadBufferOffset);
|
||||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
MicOffset = StreamGetOffset(s);
|
||||
StreamRead(s, message.MessageIntegrityCheck, 16);
|
||||
PayloadBufferOffset += 16;
|
||||
}
|
||||
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
printf("AUTHENTICATE_MESSAGE (length = %d)\n", length);
|
||||
winpr_HexDump(s->data, length);
|
||||
printf("AUTHENTICATE_MESSAGE (length = %d)\n", (int) context->AuthenticateMessage.cbBuffer);
|
||||
winpr_HexDump(context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer);
|
||||
printf("\n");
|
||||
|
||||
if (message.NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
|
||||
@ -751,6 +760,25 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer
|
||||
/* ExportedSessionKey */
|
||||
ntlm_generate_exported_session_key(context);
|
||||
|
||||
if (flags & MSV_AV_FLAGS_MESSAGE_INTEGRITY_CHECK)
|
||||
{
|
||||
ZeroMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[MicOffset], 16);
|
||||
ntlm_compute_message_integrity_check(context);
|
||||
CopyMemory(&((PBYTE) context->AuthenticateMessage.pvBuffer)[MicOffset], message.MessageIntegrityCheck, 16);
|
||||
|
||||
if (memcmp(context->MessageIntegrityCheck, message.MessageIntegrityCheck, 16) != 0)
|
||||
{
|
||||
printf("Message Integrity Check (MIC) verification failed!\n");
|
||||
|
||||
printf("Expected MIC:\n");
|
||||
winpr_HexDump(context->MessageIntegrityCheck, 16);
|
||||
printf("Actual MIC:\n");
|
||||
winpr_HexDump(message.MessageIntegrityCheck, 16);
|
||||
|
||||
//return SEC_E_MESSAGE_ALTERED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Generate signing keys */
|
||||
ntlm_generate_client_signing_key(context);
|
||||
ntlm_generate_server_signing_key(context);
|
||||
|
Loading…
Reference in New Issue
Block a user