length += av_pairs->ChannelBindings.length + 4;
if (av_pairs->TargetName.length > 0)
- length += av_pairs->TargetName.length + 4;
+ length += av_pairs->TargetName.length + 4;
length += 4;
}
/**
+ * Populate array of AV_PAIRs (server).\n
+ * AV_PAIR @msdn{cc236646}
+ * @param NTLM context
+ */
+
+char* test_NbDomainName = "FREERDP";
+char* test_NbComputerName = "FREERDP";
+char* test_DnsDomainName = "FreeRDP";
+char* test_DnsComputerName = "FreeRDP";
+
+void ntlm_populate_server_av_pairs(NTLM_CONTEXT* context)
+{
+ int length;
+ size_t size;
+ AV_PAIRS* av_pairs = context->av_pairs;
+
+ av_pairs->NbDomainName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_NbDomainName, &size);
+ av_pairs->NbDomainName.length = (uint16) size;
+
+ av_pairs->NbComputerName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_NbComputerName, &size);
+ av_pairs->NbComputerName.length = (uint16) size;
+
+ av_pairs->DnsDomainName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_DnsDomainName, &size);
+ av_pairs->DnsDomainName.length = (uint16) size;
+
+ av_pairs->DnsComputerName.value = (uint8*) freerdp_uniconv_out(context->uniconv, test_DnsComputerName, &size);
+ av_pairs->DnsComputerName.length = (uint16) size;
+
+ length = ntlm_compute_av_pairs_length(context) + 4;
+ sspi_SecBufferAlloc(&context->TargetInfo, length);
+ ntlm_output_av_pairs(context, &context->TargetInfo);
+}
+
+/**
* Print array of AV_PAIRs.\n
* AV_PAIR @msdn{cc236646}
* @param NTLM context
uint16 TargetInfoMaxLen;
uint32 TargetInfoBufferOffset;
+ ntlm_generate_client_challenge(context);
+
s = stream_new(0);
stream_attach(s, buffer->pvBuffer, buffer->cbBuffer);
{
STREAM* s;
int length;
+ uint32 PayloadOffset;
uint16 TargetNameLen;
uint8* TargetNameBuffer;
uint32 TargetNameBufferOffset;
uint8* TargetInfoBuffer;
uint32 TargetInfoBufferOffset;
+ /* Server Challenge */
+ ntlm_generate_server_challenge(context);
+
+ /* Timestamp */
+ ntlm_generate_timestamp(context);
+
+ /* TargetInfo */
+ ntlm_populate_server_av_pairs(context);
+
s = stream_new(0);
stream_attach(s, buffer->pvBuffer, buffer->cbBuffer);
stream_write(s, NTLM_SIGNATURE, 8); /* Signature (8 bytes) */
stream_write_uint32(s, MESSAGE_TYPE_CHALLENGE); /* MessageType */
- TargetNameLen = context->TargetName.cbBuffer;
- TargetNameBuffer = context->TargetName.pvBuffer;
+ if (context->NegotiateFlags & NTLMSSP_REQUEST_TARGET)
+ {
+ TargetNameLen = context->TargetName.cbBuffer;
+ TargetNameBuffer = context->TargetName.pvBuffer;
+ }
+ else
+ {
+ TargetNameLen = 0;
+ TargetNameBuffer = NULL;
+ }
+
+ context->NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
- TargetInfoLen = context->TargetInfo.cbBuffer;
- TargetInfoBuffer = context->TargetInfo.pvBuffer;
+ if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO)
+ {
+ TargetInfoLen = context->TargetInfo.cbBuffer;
+ TargetInfoBuffer = context->TargetInfo.pvBuffer;
+ }
+ else
+ {
+ TargetInfoLen = 0;
+ TargetInfoBuffer = NULL;
+ }
- TargetNameBufferOffset = 56;
+ PayloadOffset = 48;
+
+ if (context->NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
+ PayloadOffset += 8;
+
+ TargetNameBufferOffset = PayloadOffset;
TargetInfoBufferOffset = TargetNameBufferOffset + TargetNameLen;
/* TargetNameFields (8 bytes) */
printf("\n");
#endif
+ /* Initialize RC4 seal state */
+ ntlm_init_rc4_seal_states(context);
+
+#ifdef WITH_DEBUG_NTLM
+ printf("ServerChallenge\n");
+ freerdp_hexdump(context->ServerChallenge, 8);
+ printf("\n");
+#endif
+
context->state = NTLM_STATE_AUTHENTICATE;
stream_detach(s);
uint32 NegotiateFlags;
uint16 DomainNameLen;
uint16 DomainNameMaxLen;
+ uint8* DomainNameBuffer;
uint32 DomainNameBufferOffset;
uint16 UserNameLen;
uint16 UserNameMaxLen;
+ uint8* UserNameBuffer;
uint32 UserNameBufferOffset;
uint16 WorkstationLen;
uint16 WorkstationMaxLen;
+ uint8* WorkstationBuffer;
uint32 WorkstationBufferOffset;
uint16 LmChallengeResponseLen;
uint16 LmChallengeResponseMaxLen;
+ uint8* LmChallengeResponseBuffer;
uint32 LmChallengeResponseBufferOffset;
uint16 NtChallengeResponseLen;
uint16 NtChallengeResponseMaxLen;
+ uint8* NtChallengeResponseBuffer;
uint32 NtChallengeResponseBufferOffset;
uint16 EncryptedRandomSessionKeyLen;
uint16 EncryptedRandomSessionKeyMaxLen;
+ uint8* EncryptedRandomSessionKeyBuffer;
uint32 EncryptedRandomSessionKeyBufferOffset;
s = stream_new(0);
if (NegotiateFlags & NTLMSSP_NEGOTIATE_VERSION)
{
/* Only present if NTLMSSP_NEGOTIATE_VERSION is set */
+
+#ifdef WITH_DEBUG_NTLM
+ printf("Version (length = 8)\n");
+ freerdp_hexdump(s->p, 8);
+ printf("\n");
+#endif
+
stream_seek(s, 8); /* Version (8 bytes) */
}
printf("\n");
#endif
+ /* DomainName */
+ if (DomainNameLen > 0)
+ {
+ DomainNameBuffer = s->data + DomainNameBufferOffset;
+#ifdef WITH_DEBUG_NTLM
+ printf("DomainName (length = %d, offset = %d)\n", DomainNameLen, DomainNameBufferOffset);
+ freerdp_hexdump(DomainNameBuffer, DomainNameLen);
+ printf("\n");
+#endif
+ }
+
+ /* UserName */
+ if (UserNameLen > 0)
+ {
+ UserNameBuffer = s->data + UserNameBufferOffset;
+#ifdef WITH_DEBUG_NTLM
+ printf("UserName (length = %d, offset = %d)\n", UserNameLen, UserNameBufferOffset);
+ freerdp_hexdump(UserNameBuffer, UserNameLen);
+ printf("\n");
+#endif
+ }
+
+ /* Workstation */
+ if (WorkstationLen > 0)
+ {
+ WorkstationBuffer = s->data + WorkstationBufferOffset;
+#ifdef WITH_DEBUG_NTLM
+ printf("Workstation (length = %d, offset = %d)\n", WorkstationLen, WorkstationBufferOffset);
+ freerdp_hexdump(WorkstationBuffer, WorkstationLen);
+ printf("\n");
+#endif
+ }
+
+ /* LmChallengeResponse */
+ if (LmChallengeResponseLen > 0)
+ {
+ LmChallengeResponseBuffer = s->data + LmChallengeResponseBufferOffset;
+#ifdef WITH_DEBUG_NTLM
+ printf("LmChallengeResponse (length = %d, offset = %d)\n", LmChallengeResponseLen, LmChallengeResponseBufferOffset);
+ freerdp_hexdump(LmChallengeResponseBuffer, LmChallengeResponseLen);
+ printf("\n");
+#endif
+ }
+
+ /* NtChallengeResponse */
+ if (NtChallengeResponseLen > 0)
+ {
+ NtChallengeResponseBuffer = s->data + NtChallengeResponseBufferOffset;
+#ifdef WITH_DEBUG_NTLM
+ printf("NtChallengeResponse (length = %d, offset = %d)\n", NtChallengeResponseLen, NtChallengeResponseBufferOffset);
+ freerdp_hexdump(NtChallengeResponseBuffer, NtChallengeResponseLen);
+ printf("\n");
+#endif
+ }
+
+ /* EncryptedRandomSessionKey */
+ if (EncryptedRandomSessionKeyLen > 0)
+ {
+ EncryptedRandomSessionKeyBuffer = s->data + EncryptedRandomSessionKeyBufferOffset;
+#ifdef WITH_DEBUG_NTLM
+ printf("EncryptedRandomSessionKey (length = %d, offset = %d)\n", EncryptedRandomSessionKeyLen, EncryptedRandomSessionKeyBufferOffset);
+ freerdp_hexdump(EncryptedRandomSessionKeyBuffer, EncryptedRandomSessionKeyLen);
+ printf("\n");
+#endif
+ }
+
context->state = NTLM_STATE_FINAL;
stream_detach(s);