Kai Blin : secur32: Add handling of feature flags and session key to AcceptSecurityContext.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Aug 15 06:42:12 CDT 2006


Module: wine
Branch: master
Commit: cc17d97d2395f59f49e420f0f07d787e28187ca8
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=cc17d97d2395f59f49e420f0f07d787e28187ca8

Author: Kai Blin <kai.blin at gmail.com>
Date:   Tue Aug 15 02:02:46 2006 +0200

secur32: Add handling of feature flags and session key to AcceptSecurityContext.

---

 dlls/secur32/ntlm.c |   83 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 79 insertions(+), 4 deletions(-)

diff --git a/dlls/secur32/ntlm.c b/dlls/secur32/ntlm.c
index 44e8ac0..affc2e5 100644
--- a/dlls/secur32/ntlm.c
+++ b/dlls/secur32/ntlm.c
@@ -734,7 +734,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_Ac
  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
 {
     SECURITY_STATUS ret;
-    char *buffer;
+    char *buffer, *want_flags = NULL;
     PBYTE bin;
     int buffer_len, bin_len, max_len = NTLM_MAX_BUF;
     ULONG ctxt_attr = 0;
@@ -786,17 +786,26 @@ static SECURITY_STATUS SEC_ENTRY ntlm_Ac
             bin_len = pInput->pBuffers[0].cbBuffer;
 
         /* Handle all the flags */
+        want_flags = HeapAlloc(GetProcessHeap(), 0, 73);
+        if(want_flags == NULL)
+        {
+            TRACE("Failed to allocate memory for the want_flags!\n");
+            ret = SEC_E_INSUFFICIENT_MEMORY;
+            goto asc_end;
+        }
+        lstrcpyA(want_flags, "SF");
         if(fContextReq & ASC_REQ_ALLOCATE_MEMORY)
         {
             FIXME("ASC_REQ_ALLOCATE_MEMORY stub\n");
         }
         if(fContextReq & ASC_REQ_CONFIDENTIALITY)
         {
-            FIXME("ASC_REQ_CONFIDENTIALITY stub\n");
+            lstrcatA(want_flags, " NTLMSSP_FEATURE_SEAL");
         }
         if(fContextReq & ASC_REQ_CONNECTION)
         {
             /* This is default, so we'll enable it */
+            lstrcatA(want_flags, " NTLMSSP_FEATURE_SESSION_KEY");
             ctxt_attr |= ASC_RET_CONNECTION;
         }
         if(fContextReq & ASC_REQ_EXTENDED_ERROR)
@@ -805,7 +814,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_Ac
         }
         if(fContextReq & ASC_REQ_INTEGRITY)
         {
-            FIXME("ASC_REQ_INTEGRITY stub\n");
+            lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
         }
         if(fContextReq & ASC_REQ_MUTUAL_AUTH)
         {
@@ -825,6 +834,17 @@ static SECURITY_STATUS SEC_ENTRY ntlm_Ac
         }
         /* Done with the flags */
 
+        if(lstrlenA(want_flags) > 3)
+        {
+            TRACE("Server set want_flags: %s\n", debugstr_a(want_flags));
+            lstrcpynA(buffer, want_flags, max_len - 1);
+            if((ret = run_helper(helper, buffer, max_len, &buffer_len)) !=
+                    SEC_E_OK)
+                goto asc_end;
+            if(!strncmp(buffer, "BH", 2))
+                TRACE("Helper doesn't understand new command set\n");
+        }
+
         /* This is the YR request from the client, encode to base64 */
 
         memcpy(bin, pInput->pBuffers[0].pvBuffer, bin_len);
@@ -887,7 +907,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_Ac
             ret = SEC_E_INCOMPLETE_MESSAGE;
             goto asc_end;
         }
-        
+
         if(pInput->cBuffers < 1)
         {
             ret = SEC_E_INCOMPLETE_MESSAGE;
@@ -937,12 +957,67 @@ static SECURITY_STATUS SEC_ENTRY ntlm_Ac
         }
         pOutput->pBuffers[0].cbBuffer = 0;
         ret = SEC_E_OK;
+
+        TRACE("Getting negotiated flags\n");
+        lstrcpynA(buffer, "GF", max_len - 1);
+        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
+            goto asc_end;
+
+        if(buffer_len < 3)
+        {
+            TRACE("No flags negotiated, or helper does not support GF command\n");
+        }
+        else
+        {
+            TRACE("Negotiated %s\n", debugstr_a(buffer));
+            sscanf(buffer + 3, "%lx", &(helper->neg_flags));
+            TRACE("Stored 0x%08lx as flags\n", helper->neg_flags);
+        }
+
+        TRACE("Getting session key\n");
+        lstrcpynA(buffer, "GK", max_len - 1);
+        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
+            goto asc_end;
+
+        if(buffer_len < 3)
+            TRACE("Helper does not support GK command\n");
+        else
+        {
+            if(strncmp(buffer, "BH ", 3) == 0)
+            {
+                TRACE("Helper sent %s\n", debugstr_a(buffer+3));
+                helper->valid_session_key = FALSE;
+                helper->session_key = HeapAlloc(GetProcessHeap(), 0, 16);
+                /*FIXME: Generate the dummy session key = MD4(MD4(password))*/
+                memset(helper->session_key, 0 , 16);
+            }
+            else if(strncmp(buffer, "GK ", 3) == 0)
+            {
+                if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len, 
+                                &bin_len)) != SEC_E_OK)
+                {
+                    TRACE("Failed to decode session key\n");
+                }
+                TRACE("Session key is %s\n", debugstr_a(buffer+3));
+                helper->valid_session_key = TRUE;
+                if(!helper->session_key)
+                    helper->session_key = HeapAlloc(GetProcessHeap(), 0, bin_len);
+                if(!helper->session_key)
+                {
+                    TRACE("Failed to allocate memory for session key\n");
+                    ret = SEC_E_INTERNAL_ERROR;
+                    goto asc_end;
+                }
+                memcpy(helper->session_key, bin, bin_len);
+            }
+        }
     }
 
     phNewContext->dwUpper = ctxt_attr;
     phNewContext->dwLower = (ULONG_PTR)helper;
 
 asc_end:
+    HeapFree(GetProcessHeap(), 0, want_flags);
     HeapFree(GetProcessHeap(), 0, buffer);
     HeapFree(GetProcessHeap(), 0, bin);
     return ret;




More information about the wine-cvs mailing list