libfreerdp-auth: fix NTLMv2 mode
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 27 Feb 2012 16:58:14 +0000 (11:58 -0500)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Mon, 27 Feb 2012 16:58:14 +0000 (11:58 -0500)
libfreerdp-auth/NTLM/ntlm.c
libfreerdp-auth/NTLM/ntlm_compute.c
libfreerdp-auth/NTLM/ntlm_compute.h
libfreerdp-auth/credssp.c

index fa962e4..6671944 100644 (file)
@@ -275,7 +275,25 @@ SECURITY_STATUS ntlm_InitializeSecurityContext(CRED_HANDLE* phCredential, CTXT_H
 
 SECURITY_STATUS ntlm_QueryContextAttributes(CTXT_HANDLE* phContext, uint32 ulAttribute, void* pBuffer)
 {
-       return SEC_E_OK;
+       if (!phContext)
+               return SEC_E_INVALID_HANDLE;
+
+       if (!pBuffer)
+               return SEC_E_INSUFFICIENT_MEMORY;
+
+       if (ulAttribute == SECPKG_ATTR_SIZES)
+       {
+               SEC_PKG_CONTEXT_SIZES* ContextSizes = (SEC_PKG_CONTEXT_SIZES*) pBuffer;
+
+               ContextSizes->cbMaxToken = 2010;
+               ContextSizes->cbMaxSignature = 16;
+               ContextSizes->cbBlockSize = 0;
+               ContextSizes->cbSecurityTrailer = 16;
+
+               return SEC_E_OK;
+       }
+
+       return SEC_E_UNSUPPORTED_FUNCTION;
 }
 
 SECURITY_STATUS ntlm_EncryptMessage(CTXT_HANDLE* phContext, uint32 fQOP, SEC_BUFFER_DESC* pMessage, uint32 MessageSeqNo)
index 598bc78..30139b2 100644 (file)
@@ -254,10 +254,14 @@ void ntlm_input_av_pairs(NTLM_CONTEXT* context, STREAM* s)
  * @param s
  */
 
-void ntlm_output_av_pairs(NTLM_CONTEXT* context, STREAM* s)
+void ntlm_output_av_pairs(NTLM_CONTEXT* context, SEC_BUFFER* buffer)
 {
+       STREAM* s;
        AV_PAIRS* av_pairs = context->av_pairs;
 
+       s = stream_new(0);
+       stream_attach(s, buffer->pvBuffer, buffer->cbBuffer);
+
        if (av_pairs->NbDomainName.length > 0)
        {
                stream_write_uint16(s, MsvAvNbDomainName); /* AvId */
@@ -336,6 +340,57 @@ void ntlm_output_av_pairs(NTLM_CONTEXT* context, STREAM* s)
        {
                stream_write_zero(s, 8);
        }
+
+       xfree(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;
 }
 
 /**
@@ -346,7 +401,7 @@ void ntlm_output_av_pairs(NTLM_CONTEXT* context, STREAM* s)
 
 void ntlm_populate_av_pairs(NTLM_CONTEXT* context)
 {
-       STREAM* s;
+       int length;
        AV_PAIRS* av_pairs = context->av_pairs;
 
        /* MsvAvFlags */
@@ -361,13 +416,9 @@ void ntlm_populate_av_pairs(NTLM_CONTEXT* context)
        /* ChannelBindings */
        ntlm_output_channel_bindings(context);
 
-       s = stream_new(context->TargetInfo.cbBuffer);
-       ntlm_output_av_pairs(context, s);
-
-       sspi_SecBufferAlloc(&context->TargetInfo, s->p - s->data);
-       memcpy(context->TargetInfo.pvBuffer, s->data, context->TargetInfo.cbBuffer);
-
-       xfree(s);
+       length = ntlm_compute_av_pairs_length(context);
+       sspi_SecBufferAlloc(&context->TargetInfo, length);
+       ntlm_output_av_pairs(context, &context->TargetInfo);
 }
 
 /**
index 40ca6b2..47d1e46 100644 (file)
@@ -27,7 +27,7 @@ void ntlm_output_target_name(NTLM_CONTEXT* context);
 void ntlm_output_channel_bindings(NTLM_CONTEXT* context);
 
 void ntlm_input_av_pairs(NTLM_CONTEXT* context, STREAM* s);
-void ntlm_output_av_pairs(NTLM_CONTEXT* context, STREAM* s);
+void ntlm_output_av_pairs(NTLM_CONTEXT* context, SEC_BUFFER* buffer);
 void ntlm_populate_av_pairs(NTLM_CONTEXT* context);
 void ntlm_print_av_pairs(NTLM_CONTEXT* context);
 void ntlm_free_av_pairs(NTLM_CONTEXT* context);
index b78c93a..ab62ee0 100644 (file)
@@ -230,6 +230,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
        boolean have_input_buffer;
        boolean have_pub_key_auth;
        SECURITY_FUNCTION_TABLE* table;
+       SEC_PKG_CONTEXT_SIZES ContextSizes;
        rdpSettings* settings = credssp->settings;
 
        sspi_GlobalInit();
@@ -282,6 +283,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
        have_pub_key_auth = false;
        memset(&input_sec_buffer, 0, sizeof(SEC_BUFFER));
        memset(&output_sec_buffer, 0, sizeof(SEC_BUFFER));
+       memset(&ContextSizes, 0, sizeof(SEC_PKG_CONTEXT_SIZES));
 
        fContextReq = ISC_REQ_REPLAY_DETECT | ISC_REQ_SEQUENCE_DETECT |
                        ISC_REQ_CONFIDENTIALITY | ISC_REQ_DELEGATE;
@@ -314,6 +316,12 @@ int credssp_client_authenticate(rdpCredssp* credssp)
 
                        have_pub_key_auth = true;
 
+                       if (table->QueryContextAttributes(&context, SECPKG_ATTR_SIZES, &ContextSizes) != SEC_E_OK)
+                       {
+                               printf("QueryContextAttributes SECPKG_ATTR_SIZES failure\n");
+                               return 0;
+                       }
+
                        if (have_pub_key_auth)
                        {
                                uint8* p;
@@ -327,7 +335,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
                                Buffers[0].pvBuffer = xmalloc(Buffers[0].cbBuffer);
                                memcpy(Buffers[0].pvBuffer, credssp->tls->public_key.data, Buffers[0].cbBuffer);
 
-                               Buffers[1].cbBuffer = 16;
+                               Buffers[1].cbBuffer = ContextSizes.cbMaxSignature;
                                Buffers[1].pvBuffer = xzalloc(Buffers[1].cbBuffer);
 
                                Message.cBuffers = 2;
@@ -421,7 +429,7 @@ int credssp_client_authenticate(rdpCredssp* credssp)
                Buffers[0].BufferType = SECBUFFER_PADDING; /* Signature */
                Buffers[1].BufferType = SECBUFFER_DATA; /* Encrypted TLS Public Key */
 
-               Buffers[0].cbBuffer = 16;
+               Buffers[0].cbBuffer = ContextSizes.cbMaxSignature;
                Buffers[0].pvBuffer = xmalloc(Buffers[0].cbBuffer);
                memcpy(Buffers[0].pvBuffer, pub_key_auth, Buffers[0].cbBuffer);