Author: sserapion
Date: Mon May 30 21:02:50 2011
New Revision: 52014

URL: http://svn.reactos.org/svn/reactos?rev=52014&view=rev
Log:
[NTLMSSP]
- Implement NtlmHandleNegotiateMessage NtlmHandleChallengeMessage and 
NtlmHandleAuthenticateMessage
- all wine client server tests pass
- still missing a lot of stuff (WIP code)

Modified:
    branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c
    branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c
    branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h
    branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c
    branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h

Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c
URL: 
http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c?rev=52014&r1=52013&r2=52014&view=diff
==============================================================================
--- branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c [iso-8859-1] 
(original)
+++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c [iso-8859-1] Mon 
May 30 21:02:50 2011
@@ -391,13 +391,7 @@
         ret = NtlmGenerateNegotiateMessage(newContext,
                                            fContextReq,
                                            InputToken1,
-                                           &OutputToken1);
-
-        if(!NT_SUCCESS(ret))
-        {
-            ERR("NtlmGenerateNegotiateMessage failed with %lx\n", ret);
-            goto fail;
-        }
+                                           OutputToken1);
 
         /* set result */
         phNewContext->dwUpper = NegotiateFlags;
@@ -406,7 +400,6 @@
     else        /* challenge! */
     {
         TRACE("ISC challenged!\n");
-        *phNewContext = *phContext;
         if (fContextReq & ISC_REQ_USE_SUPPLIED_CREDS)
         {
             /* get second input token */
@@ -421,6 +414,7 @@
             }
         }
 
+        *phNewContext = *phContext;
         ret = NtlmHandleChallengeMessage(phNewContext->dwLower,
                                          fContextReq,
                                          InputToken1,
@@ -430,13 +424,12 @@
                                          pfContextAttr,
                                          ptsExpiry,
                                          &NegotiateFlags);
-
-        if(!NT_SUCCESS(ret))
-        {
-            ERR("NtlmHandleChallengeMessage failed with %lx\n", ret);
-            goto fail;
-        }
-
+    }
+
+    if(!NT_SUCCESS(ret))
+    {
+        ERR("failed with %lx\n", ret);
+        goto fail;
     }
 
     /* build blob with the output message */
@@ -575,7 +568,7 @@
 {
     SECURITY_STATUS ret = SEC_E_OK;
     PSecBuffer InputToken1, InputToken2;
-    PSecBuffer OutputToken1;
+    PSecBuffer OutputToken1, OutputToken2;
 
     TRACE("AcceptSecurityContext %p %p %p %lx %lx %p %p %p %p\n", 
phCredential, phContext, pInput,
         fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, 
ptsExpiry);
@@ -614,29 +607,56 @@
     }
 
     /* first call */
-    if(!phContext && !InputToken2)
+    if(!phContext)// && !InputToken2)
     {
         if(!phCredential)
         {
             ret = SEC_E_INVALID_HANDLE;
             goto fail;
         }
-
+        TRACE("phNewContext->dwLower %lx\n", phNewContext->dwLower);
         ret = NtlmHandleNegotiateMessage(phCredential->dwLower,
-                                         &phNewContext->dwLower,
+                                         phNewContext->dwLower,
                                          fContextReq,
                                          InputToken1,
-                                         &OutputToken1,
+                                         InputToken2,
+                                         OutputToken1,
+                                         OutputToken2,
                                          pfContextAttr,
                                          ptsExpiry);
     }
     else
     {
-        WARN("Handle Authenticate UNIMPLEMENTED!\n");
-    }
-    //if(!NT_SUCCESS(ret))
-
-    UNIMPLEMENTED;
+        *phNewContext = *phContext;
+        USER_SESSION_KEY sessionKey;
+        ULONG userflags;
+        TRACE("phNewContext->dwLower %lx\n", phNewContext->dwLower);
+        ret = NtlmHandleAuthenticateMessage(phNewContext->dwLower,
+                                            fContextReq,
+                                            InputToken1,
+                                            OutputToken1,
+                                            pfContextAttr,
+                                            ptsExpiry,
+                                            (PUCHAR)&sessionKey,
+                                            &userflags);
+    }
+
+    if(!NT_SUCCESS(ret))
+    {
+        ERR("failed with %lx\n", ret);
+        goto fail;
+    }
+
+    /* build blob with the output message */
+    SecBufferDesc BufferDesc;
+    BufferDesc.ulVersion = SECBUFFER_VERSION;
+    BufferDesc.cBuffers = 1;
+    BufferDesc.pBuffers = OutputToken1;
+
+    if(fContextReq & ASC_REQ_ALLOCATE_MEMORY)
+        *pfContextAttr |= ASC_RET_ALLOCATED_MEMORY;
+
+    *pOutput = BufferDesc;
     return ret;
 fail:
     return ret;
@@ -703,7 +723,6 @@
 ApplyControlToken(IN PCtxtHandle phContext,
                   IN PSecBufferDesc pInput)
 {
-
     UNIMPLEMENTED;
     return SEC_E_UNSUPPORTED_FUNCTION;
 }

Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c
URL: 
http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c?rev=52014&r1=52013&r2=52014&view=diff
==============================================================================
--- branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c [iso-8859-1] 
(original)
+++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c [iso-8859-1] 
Mon May 30 21:02:50 2011
@@ -53,7 +53,7 @@
 
     /* sanity */
     ASSERT(cred);
-    TRACE("%p refcount %d\n",cred, cred->RefCount);
+    TRACE("%p refcount %lx\n",cred, cred->RefCount);
     ASSERT(cred->RefCount > 0);
 
     /* reference */
@@ -73,7 +73,7 @@
 
     /* sanity */
     ASSERT(cred);
-    TRACE("%p refcount %d\n",cred, cred->RefCount);
+    TRACE("%p refcount %lx\n",cred, cred->RefCount);
     ASSERT(cred->RefCount >= 1);
 
     /* decrement reference */
@@ -137,7 +137,7 @@
 {
     SECURITY_STATUS ret;
 
-    TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
+    TRACE("(%p, %lx, %p)\n", phCredential, ulAttribute, pBuffer);
 
     if(ulAttribute == SECPKG_ATTR_NAMES)
     {
@@ -158,7 +158,7 @@
 {
     SECURITY_STATUS ret;
 
-    TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
+    TRACE("(%p, %lx, %p)\n", phCredential, ulAttribute, pBuffer);
 
     if(ulAttribute == SECPKG_ATTR_NAMES)
     {

Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h
URL: 
http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h?rev=52014&r1=52013&r2=52014&view=diff
==============================================================================
--- branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h [iso-8859-1] 
(original)
+++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h [iso-8859-1] Mon 
May 30 21:02:50 2011
@@ -46,9 +46,12 @@
 
 extern UNICODE_STRING NtlmComputerNameString;
 extern UNICODE_STRING NtlmDomainNameString;
+extern UNICODE_STRING NtlmDnsNameString;
 extern OEM_STRING NtlmOemComputerNameString;
 extern OEM_STRING NtlmOemDomainNameString;
+extern OEM_STRING NtlmOemDnsNameString;
 extern HANDLE NtlmSystemSecurityToken;
+extern UNICODE_STRING NtlmAvTargetInfo; // contains AV pairs with local info
 
 typedef enum _NTLM_MODE {
     NtlmLsaMode = 1,

Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c
URL: 
http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c?rev=52014&r1=52013&r2=52014&view=diff
==============================================================================
--- branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c [iso-8859-1] 
(original)
+++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c [iso-8859-1] Mon 
May 30 21:02:50 2011
@@ -26,7 +26,7 @@
 NtlmGenerateNegotiateMessage(IN ULONG_PTR Context,
                              IN ULONG ContextReq,
                              IN PSecBuffer InputToken,
-                             OUT PSecBuffer *OutputToken)
+                             OUT PSecBuffer OutputToken)
 {
     PNTLMSSP_CONTEXT context = (PNTLMSSP_CONTEXT)Context;
     PNTLMSSP_CREDENTIAL cred = context->Credential;
@@ -35,13 +35,13 @@
     ULONG_PTR offset;
     NTLM_BLOB blobBuffer[2]; //nego contains 2 blobs
 
-    if(!*OutputToken)
+    if(!OutputToken)
     {
         ERR("No output token!\n");
         return SEC_E_BUFFER_TOO_SMALL;
     }
 
-    if(!((*OutputToken)->pvBuffer))
+    if(!(OutputToken->pvBuffer))
     {
         /* according to wine test */
         ERR("No output buffer!\n");
@@ -56,23 +56,21 @@
     if (!(ContextReq & ISC_REQ_ALLOCATE_MEMORY))
     {
         /* not enough space */
-        if(messageSize > (*OutputToken)->cbBuffer)
+        if(messageSize > OutputToken->cbBuffer)
             return SEC_E_BUFFER_TOO_SMALL;
     }
     else
     {
         /* allocate */
-        (*OutputToken)->pvBuffer = NtlmAllocate(messageSize);
-        (*OutputToken)->cbBuffer = messageSize;
-
-        if(!(*OutputToken)->pvBuffer)
+        OutputToken->pvBuffer = NtlmAllocate(messageSize);
+        OutputToken->cbBuffer = messageSize;
+
+        if(!OutputToken->pvBuffer)
             return SEC_E_INSUFFICIENT_MEMORY;
     }
 
     /* allocate a negotiate message */
-    message = (PNEGOTIATE_MESSAGE) NtlmAllocate(messageSize);
-
-    if(!message)
+    if(!(message = (PNEGOTIATE_MESSAGE) NtlmAllocate(messageSize)))
         return SEC_E_INSUFFICIENT_MEMORY;
 
     /* build message */
@@ -110,11 +108,12 @@
         blobBuffer[1].Offset = offset+1;
     }
 
+    /* zero struct */
     memset(&message->Version, 0, sizeof(NTLM_WINDOWS_VERSION));
 
     /* send it back */
-    memcpy((*OutputToken)->pvBuffer, message, messageSize);
-    (*OutputToken)->cbBuffer = messageSize;
+    memcpy(OutputToken->pvBuffer, message, messageSize);
+    OutputToken->cbBuffer = messageSize;
     context->State = NegotiateSent;
 
     TRACE("context %p context->NegotiateFlags:\n",context);
@@ -128,40 +127,53 @@
 
 SECURITY_STATUS
 NtlmHandleNegotiateMessage(IN ULONG_PTR hCredential,
-                           IN OUT PULONG_PTR phContext,
+                           IN OUT ULONG_PTR hContext,
                            IN ULONG ContextReq,
                            IN PSecBuffer InputToken,
-                           OUT PSecBuffer *pOutputToken,
+                           IN PSecBuffer InputToken2,
+                           OUT PSecBuffer OutputToken,
+                           OUT PSecBuffer OutputToken2,
                            OUT PULONG pContextAttr,
                            OUT PTimeStamp ptsExpiry)
 {
     SECURITY_STATUS ret = SEC_E_OK;
     PNEGOTIATE_MESSAGE negoMessage = NULL;
     PNTLMSSP_CREDENTIAL cred = NULL;
-    PNTLMSSP_CONTEXT newContext = NULL;
-
-    ERR("NtlmHandleNegotiateMessage called!\n");
-
-    /* InputToken should contain a negotiate message*/
+    PNTLMSSP_CONTEXT context = NULL;
+    UNICODE_STRING targetName;
+    OEM_STRING OemDomainName, OemWorkstationName;
+    ULONG targetFlags = 0;
+    BOOLEAN isUnicode;
+
+    TRACE("NtlmHandleNegotiateMessage hContext %lx\n", hContext);
+    if(!(context = NtlmAllocateContext()))
+    {
+        ret = SEC_E_INSUFFICIENT_MEMORY;
+        ERR("SEC_E_INSUFFICIENT_MEMORY!\n");
+        goto exit;
+    }
+
+    hContext = (ULONG_PTR)context;
+    TRACE("NtlmHandleNegotiateMessage hContext %lx\n", hContext);
+
+    /* InputToken should contain a negotiate message */
     if(InputToken->cbBuffer > NTLM_MAX_BUF ||
         InputToken->cbBuffer < sizeof(NEGOTIATE_MESSAGE))
     {
-        ERR("Input token too big!!\n");
+        ERR("Input wrong size!!\n");
         ret = SEC_E_INVALID_TOKEN;
         goto exit;
     }
 
     /* allocate a buffer for it */
-    negoMessage = NtlmAllocate(InputToken->cbBuffer);
-
-    if(!negoMessage)
+    if(!(negoMessage = NtlmAllocate(sizeof(NEGOTIATE_MESSAGE))))
     {
         ret = SEC_E_INSUFFICIENT_MEMORY;
         goto exit;
     }
 
     /* copy it */
-    memcpy(negoMessage, InputToken->pvBuffer, InputToken->cbBuffer);
+    memcpy(negoMessage, InputToken->pvBuffer, sizeof(NEGOTIATE_MESSAGE));
 
     /* validate it */
     if(strncmp(negoMessage->Signature, NTLMSSP_SIGNATURE, 8) &&
@@ -176,9 +188,11 @@
     NtlmPrintNegotiateFlags(negoMessage->NegotiateFlags);
 
     /* get credentials */
-    cred = NtlmReferenceCredential(hCredential);
-    if(!cred)
+    if(!(cred = NtlmReferenceCredential(hCredential)))
+    {
+        ret = SEC_E_INVALID_TOKEN;
         goto exit;
+    }
 
     /* must be an incomming request */
     if(!(cred->UseFlags & SECPKG_CRED_INBOUND))
@@ -187,72 +201,199 @@
         goto exit;
     }
 
-    /* create new context */
-    newContext = NtlmAllocateContext();
-    if(!newContext)
+    /* convert flags */
+    if(ContextReq & ASC_REQ_IDENTIFY)
+    {
+        *pContextAttr |= ASC_RET_IDENTIFY;
+        context->ContextFlags |= ASC_RET_IDENTIFY;
+    }
+
+    if(ContextReq & ASC_REQ_DATAGRAM)
+    {
+        *pContextAttr |= ASC_RET_DATAGRAM;
+        context->ContextFlags |= ASC_RET_DATAGRAM;
+    }
+
+    if(ContextReq & ASC_REQ_CONNECTION)
+    {
+        *pContextAttr |= ASC_RET_CONNECTION;
+        context->ContextFlags |= ASC_RET_CONNECTION;
+    }
+
+    if(ContextReq & ASC_REQ_INTEGRITY)
+    {
+        *pContextAttr |= ASC_RET_INTEGRITY;
+        context->ContextFlags |= ASC_RET_INTEGRITY;
+    }
+
+    if(ContextReq & ASC_REQ_REPLAY_DETECT)
+    {
+        *pContextAttr |= ASC_RET_REPLAY_DETECT;
+        context->ContextFlags |= ASC_RET_REPLAY_DETECT;
+    }
+
+    if(ContextReq & ASC_REQ_SEQUENCE_DETECT)
+    {
+        *pContextAttr |= ASC_RET_SEQUENCE_DETECT;
+        context->ContextFlags |= ASC_RET_SEQUENCE_DETECT;
+    }
+
+    if(ContextReq & ASC_REQ_ALLOW_NULL_SESSION)
+    {
+        context->ContextFlags |= ASC_REQ_ALLOW_NULL_SESSION;
+    }
+
+    if(ContextReq & ASC_REQ_ALLOW_NON_USER_LOGONS)
+    {
+        *pContextAttr |= ASC_RET_ALLOW_NON_USER_LOGONS;
+        context->ContextFlags |= ASC_RET_ALLOW_NON_USER_LOGONS;
+    }
+
+    /* encryption */
+    if(ContextReq & ASC_REQ_CONFIDENTIALITY)
+    {
+        *pContextAttr |= ASC_RET_CONFIDENTIALITY;
+        context->ContextFlags |= ASC_RET_CONFIDENTIALITY;
+    }
+
+    if (negoMessage->NegotiateFlags & 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY ||
+        negoMessage->NegotiateFlags & NTLMSSP_REQUEST_TARGET)
+    {
+        targetFlags |= NTLMSSP_TARGET_TYPE_SERVER | NTLMSSP_REQUEST_TARGET | 
NTLMSSP_NEGOTIATE_TARGET_INFO;
+
+        if (negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE)
+        {
+            isUnicode = TRUE;
+            targetFlags |= NTLMSSP_NEGOTIATE_UNICODE;
+            RtlInitUnicodeString(&targetName, NtlmComputerNameString.Buffer);
+        }
+        else if(negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_OEM)
+        {
+            isUnicode = FALSE;
+            targetFlags |= NTLMSSP_NEGOTIATE_OEM;
+            RtlInitUnicodeString(&targetName, 
(PWCHAR)&NtlmOemComputerNameString.Buffer);
+        }
+        else
+        {
+            ret = SEC_E_INVALID_TOKEN;
+            ERR("flags invalid!\n");
+            goto exit;
+        }
+    }
+
+    /* create a challenge message */
+    PCHALLENGE_MESSAGE chaMessage = NULL;
+    ULONG messageSize = sizeof(CHALLENGE_MESSAGE)+ targetName.Length + 1 + 
NtlmAvTargetInfo.Length;
+    ULONG offset;
+
+    /* ntlm does not listen to ASC_REQ_ALLOCATE_MEMORY or lack thereof */
+    /* further more the buffer size is always NTLM_MAX_BUF */
+    /* allocate output buffer */
+    OutputToken->pvBuffer = NtlmAllocate(NTLM_MAX_BUF);
+    OutputToken->cbBuffer = messageSize;
+
+    if(!OutputToken->pvBuffer)
     {
         ret = SEC_E_INSUFFICIENT_MEMORY;
         goto exit;
     }
 
-    *phContext = (ULONG_PTR)newContext;
-
-    if(ContextReq & ASC_REQ_IDENTIFY)
-    {
+    /* allocate message */
+    if (!(chaMessage = (PCHALLENGE_MESSAGE)NtlmAllocate(messageSize)))
+    {
+        ret = SEC_E_INSUFFICIENT_MEMORY;
+        goto exit;
+    }
+
+    TRACE("message %p size %lu\n", chaMessage, messageSize);
+
+    /* build message */
+    strcpy(chaMessage->Signature, NTLMSSP_SIGNATURE);
+    chaMessage->MsgType = NtlmChallenge;
+    chaMessage->NegotiateFlags = context->NegotiateFlags;
+    chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLM;
+
+    /* generate challenge */
+    NtlmGenerateRandomBits(chaMessage->ServerChallenge, 
MSV1_0_CHALLENGE_LENGTH);
+    memcpy(context->Challenge, chaMessage->ServerChallenge, 
MSV1_0_CHALLENGE_LENGTH);
+
+    offset = (ULONG_PTR)(chaMessage+1);
+
+    if(negoMessage->NegotiateFlags & 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
+    {
+        negoMessage->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
+        chaMessage->NegotiateFlags |= 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY;
+    }
+    else if(negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_LM_KEY)
+    {
+        chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_LM_KEY;
+    }
+
+    if(negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
+        chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
+
+    if(negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_SIGN)
+    {
+        chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
+        *pContextAttr |= (ASC_RET_SEQUENCE_DETECT | ASC_RET_REPLAY_DETECT);
+        context->ContextFlags |= (ASC_RET_SEQUENCE_DETECT | 
ASC_RET_REPLAY_DETECT);
+    }
+
+    if (negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL)
+    {
+        chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL;
+        *pContextAttr |= ASC_RET_CONFIDENTIALITY;
+        context->ContextFlags |= ASC_RET_CONFIDENTIALITY;
+    }
+
+    if(negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_KEY_EXCH)
+        chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
+
+    /* client requested encryption */
+    if(negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_128)
+        chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_128;
+    else if(negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_56)
+        chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_56;
+
+    if(negoMessage->NegotiateFlags & NTLMSSP_REQUEST_INIT_RESP)
+    {
+        chaMessage->NegotiateFlags |= NTLMSSP_REQUEST_INIT_RESP;
         *pContextAttr |= ASC_RET_IDENTIFY;
-        newContext->ContextFlags |= ASC_RET_IDENTIFY;
-    }
-
-    if(ContextReq & ASC_REQ_DATAGRAM)
-    {
-        *pContextAttr |= ASC_RET_DATAGRAM;
-        newContext->ContextFlags |= ASC_RET_DATAGRAM;
-    }
-
-    if(ContextReq & ASC_REQ_CONNECTION)
-    {
-        *pContextAttr |= ASC_RET_CONNECTION;
-        newContext->ContextFlags |= ASC_RET_CONNECTION;
-    }
-
-    if(ContextReq & ASC_REQ_INTEGRITY)
-    {
-        *pContextAttr |= ASC_RET_INTEGRITY;
-        newContext->ContextFlags |= ASC_RET_INTEGRITY;
-    }
-
-    if(ContextReq & ASC_REQ_REPLAY_DETECT)
-    {
-        *pContextAttr |= ASC_RET_REPLAY_DETECT;
-        newContext->ContextFlags |= ASC_RET_REPLAY_DETECT;
-    }
-
-    if(ContextReq & ASC_REQ_SEQUENCE_DETECT)
-    {
-        *pContextAttr |= ASC_RET_SEQUENCE_DETECT;
-        newContext->ContextFlags |= ASC_RET_SEQUENCE_DETECT;
-    }
-
-    if(ContextReq & ASC_REQ_ALLOW_NULL_SESSION)
-    {
-        newContext->ContextFlags |= ASC_REQ_ALLOW_NULL_SESSION;
-    }
-
-    if(ContextReq & ASC_REQ_ALLOW_NON_USER_LOGONS)
-    {
-        *pContextAttr |= ASC_RET_ALLOW_NON_USER_LOGONS;
-        newContext->ContextFlags |= ASC_RET_ALLOW_NON_USER_LOGONS;
-    }
-
-    /* encryption */
-    if(ContextReq & ASC_REQ_CONFIDENTIALITY)
-    {
-        *pContextAttr |= ASC_RET_CONFIDENTIALITY;
-        newContext->ContextFlags |= ASC_RET_CONFIDENTIALITY;
-    }
+        context->ContextFlags |= ASC_RET_IDENTIFY;
+    }
+
+    /* check for local call */
+    if((negoMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) &&
+        (negoMessage->NegotiateFlags & 
NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED))
+    {
+        NtlmBlobToUnicodeString(InputToken, negoMessage->OemDomainName, 
(PUNICODE_STRING)&OemDomainName);
+        NtlmBlobToUnicodeString(InputToken, negoMessage->OemWorkstationName, 
(PUNICODE_STRING)&OemWorkstationName);
+
+        if (RtlEqualString(&OemWorkstationName, &NtlmOemComputerNameString, 
FALSE)&&
+            RtlEqualString(&OemDomainName, &NtlmOemDomainNameString, FALSE))
+        {
+            TRACE("local negotiate detected!\n");
+            chaMessage->NegotiateFlags |= NTLMSSP_NEGOTIATE_LOCAL_CALL;
+        }
+    }
+
+    NtlmUnicodeStringToBlob((PVOID)chaMessage, &targetName, 
&chaMessage->TargetName, &offset);
+    NtlmUnicodeStringToBlob((PVOID)chaMessage, &NtlmAvTargetInfo, 
&chaMessage->TargetInfo, &offset);
+    chaMessage->NegotiateFlags |= targetFlags;
+
+    memcpy(OutputToken->pvBuffer, chaMessage, messageSize);
+    OutputToken->cbBuffer = messageSize;
+    context->State = ChallengeSent;
+    ret = SEC_I_CONTINUE_NEEDED;
 
 exit:
-    ERR("FIXME: HERE!!!!!!!!!!!!!!!");
+    if(chaMessage) NtlmFree(chaMessage);
+    if(negoMessage) NtlmFree(negoMessage);
+    if(cred) NtlmDereferenceCredential((ULONG_PTR)cred);
+    if(targetName.Buffer) NtlmFree(targetName.Buffer);
+    if(OemDomainName.Buffer) NtlmFree(OemDomainName.Buffer);
+    if(OemWorkstationName.Buffer) NtlmFree(OemWorkstationName.Buffer);
+
     return ret;
 }
 
@@ -261,59 +402,60 @@
                            IN ULONG ContextReq,
                            IN PSecBuffer InputToken1,
                            IN PSecBuffer InputToken2,
-                           IN OUT PSecBuffer *OutputToken1,
-                           IN OUT PSecBuffer *OutputToken2,
+                           IN OUT PSecBuffer OutputToken1,
+                           IN OUT PSecBuffer OutputToken2,
                            OUT PULONG pContextAttr,
                            OUT PTimeStamp ptsExpiry,
                            OUT PULONG NegotiateFlags)
 {
     SECURITY_STATUS ret = SEC_E_OK;
-    PNTLMSSP_CONTEXT context;
-    PCHALLENGE_MESSAGE challenge;
+    PNTLMSSP_CONTEXT context = NULL;
+    PCHALLENGE_MESSAGE challenge = NULL;
+    PNTLMSSP_CREDENTIAL cred = NULL;
     BOOLEAN isUnicode;
 
+    TRACE("NtlmHandleChallengeMessage hContext %lx\n", hContext);
     /* get context */
     context = NtlmReferenceContext(hContext);
     if(!context || !context->Credential)
     {
         ERR("NtlmHandleChallengeMessage invalid handle!\n");
         ret = SEC_E_INVALID_HANDLE;
-        goto exit;
+        goto fail;
     }
 
     /* re-authenticate call */
     if(context->State == AuthenticateSent)
     {
         UNIMPLEMENTED;
+        goto fail;
     }
     else if(context->State != NegotiateSent)
     {
-        ERR("Context not in negotiate sent state!\n");
+        ERR("Context not in correct state!\n");
         ret = SEC_E_OUT_OF_SEQUENCE;
-        goto exit;
+        goto fail;
     }
 
     /* InputToken1 should contain a challenge message */
-    TRACE("input token size %lx\n", InputToken1->cbBuffer);
     if(InputToken1->cbBuffer > NTLM_MAX_BUF ||
         InputToken1->cbBuffer < sizeof(CHALLENGE_MESSAGE))
     {
         ERR("Input token invalid!\n");
         ret = SEC_E_INVALID_TOKEN;
-        goto exit;
+        goto fail;
     }
 
     /* allocate a buffer for it */
-    challenge = NtlmAllocate(InputToken1->cbBuffer);
-    if(!challenge)
+    if(!(challenge = NtlmAllocate(sizeof(CHALLENGE_MESSAGE))))
     {
         ERR("failed to allocate challenge buffer!\n");
         ret = SEC_E_INSUFFICIENT_MEMORY;
-        goto exit;
+        goto fail;
     }
 
     /* copy it */
-    memcpy(challenge, InputToken1->pvBuffer, InputToken1->cbBuffer);
+    memcpy(challenge, InputToken1->pvBuffer, sizeof(CHALLENGE_MESSAGE));
 
     /* validate it */
     if(strncmp(challenge->Signature, NTLMSSP_SIGNATURE, 8) &&
@@ -321,14 +463,14 @@
     {
         ERR("Input message not valid!\n");
         ret = SEC_E_INVALID_TOKEN;
-        goto exit;
+        goto fail;
     }
 
     TRACE("Got valid challege message! with flags:\n");
     NtlmPrintNegotiateFlags(challenge->NegotiateFlags);
 
     /* print challenge message and payloads */
-    NtlmPrintHexDump((PBYTE)challenge, InputToken1->cbBuffer);
+    NtlmPrintHexDump((PBYTE)InputToken1->pvBuffer, InputToken1->cbBuffer);
 
     if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM)
     {
@@ -364,14 +506,14 @@
         /* these flags must be bad! */
         ERR("challenge flags did not specify unicode or oem!\n");
         ret = SEC_E_INVALID_TOKEN;
-        goto exit;
+        goto fail;
     }
 
     /* support ntlm2 */
     if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
     {
         challenge->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
-        context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_LM_KEY);
+        context->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
     }
     else
     {
@@ -383,7 +525,7 @@
         {
             ERR("netware authentication not supported!!!\n");
             ret = SEC_E_UNSUPPORTED_FUNCTION;
-            goto exit;
+            goto fail;
         }
     }
 
@@ -430,7 +572,7 @@
         if(!NT_SUCCESS(ret))
         {
             ERR("could not get target info!\n");
-            goto exit;
+            goto fail;
         }
     }
     else
@@ -444,20 +586,23 @@
         if(!NT_SUCCESS(ret))
         {
             ERR("could not get target info!\n");
-            goto exit;
+            goto fail;
         }
         if(isUnicode)
             FIXME("convert to unicode!\n");
     }
-    TRACE("ServerName %s\n", debugstr_w(ServerName.Buffer));
-
-    PNTLMSSP_CREDENTIAL cred = 
NtlmReferenceCredential((ULONG_PTR)context->Credential);
+
+
     MSV1_0_NTLM3_RESPONSE NtResponse;
     LM2_RESPONSE Lm2Response;
     USER_SESSION_KEY UserSessionKey;
     LM_SESSION_KEY LmSessionKey;
 
-    NtlmUnProtectMemory(cred->Password.Buffer, cred->Password.Length * 
sizeof(WCHAR));
+    if(!(cred = NtlmReferenceCredential((ULONG_PTR)context->Credential)))
+        goto fail;
+
+    /* unscramble password */
+    NtlmUnProtectMemory(cred->Password.Buffer, cred->Password.Length);
 
     TRACE("cred: %s %s %s\n", debugstr_w(cred->UserName.Buffer),
         debugstr_w(cred->Password.Buffer), 
debugstr_w(cred->DomainName.Buffer));
@@ -472,9 +617,255 @@
                           &UserSessionKey,
                           &LmSessionKey);
 
-exit:
+    PAUTHENTICATE_MESSAGE authmessage = NULL;
+    ULONG_PTR offset;
+
+    UNICODE_STRING NtResponseString;
+    //UNICODE_STRING LmResponseString;
+    UNICODE_STRING UserSessionKeyString;
+    UNICODE_STRING LmSessionKeyString;
+
+#define InitString(str, input) str.MaximumLength = str.Length = 
sizeof(input)*sizeof(WCHAR); str.Buffer = (WCHAR*)&input
+    InitString(NtResponseString, NtResponse);
+    //InitString(LmResponseString, Lm2Response);
+    InitString(UserSessionKeyString, UserSessionKey);
+    InitString(LmSessionKeyString, LmSessionKey);
+
+    ULONG messageSize = sizeof(AUTHENTICATE_MESSAGE) +
+        ServerName.Length + cred->UserName.Length + cred->DomainName.Length +
+        NtResponseString.Length + UserSessionKeyString.Length + 
LmSessionKeyString.Length;
+        //LmResponseString.Length;
+
+    if(!(authmessage = NtlmAllocate(messageSize)))
+    {
+        ret = SEC_E_INSUFFICIENT_MEMORY;
+        goto fail;
+    }
+
+    strcpy(authmessage->Signature, NTLMSSP_SIGNATURE);
+    authmessage->MsgType = NtlmAuthenticate;
+
+    offset = (ULONG_PTR)(authmessage+1);
+
+    NtlmUnicodeStringToBlob((PVOID)authmessage,
+                            &cred->DomainName,
+                            &authmessage->DomainName,
+                            &offset);
+    
+    NtlmUnicodeStringToBlob((PVOID)authmessage,
+                            &cred->UserName,
+                            &authmessage->UserName,
+                            &offset);
+
+    NtlmUnicodeStringToBlob((PVOID)authmessage,
+                            &ServerName,
+                            &authmessage->WorkstationName,
+                            &offset);
+
+    //if(targetinfo)
+    //NtlmUnicodeStringToBlob((PVOID)authmessage,
+    //                        &LmResponseString,
+    //                        &authmessage->LmChallengeResponse,
+    //                        &offset);
+
+    NtlmUnicodeStringToBlob((PVOID)authmessage,
+                            &NtResponseString,
+                            &authmessage->NtChallengeResponse,
+                            &offset);
+
+    NtlmUnicodeStringToBlob((PVOID)authmessage,
+                            &UserSessionKeyString,
+                            &authmessage->EncryptedRandomSessionKey,
+                            &offset);
+
+    /* if should not allocate */
+    if (!(ContextReq & ISC_REQ_ALLOCATE_MEMORY))
+    {
+        /* not enough space */
+        if(messageSize > OutputToken1->cbBuffer)
+        {
+            ret = SEC_E_BUFFER_TOO_SMALL;
+            goto fail;
+        }
+    }
+    else
+    {
+        /* allocate */
+        if(!(OutputToken1->pvBuffer = NtlmAllocate(messageSize)))
+        {
+            ret = SEC_E_INSUFFICIENT_MEMORY;
+            goto fail;
+        }
+    }
+
+    OutputToken1->cbBuffer = messageSize; /* says wine test */
+    memcpy(OutputToken1->pvBuffer, authmessage, messageSize);
+    context->State = AuthenticateSent;
+    ret = SEC_E_OK;
+
+fail:
+    if(authmessage) NtlmFree(authmessage);
+    if(context) NtlmDereferenceContext((ULONG_PTR)context);
+    if(cred) NtlmDereferenceCredential((ULONG_PTR)cred);
     ERR("handle challenge end\n");
-
     return ret;
 }
 
+SECURITY_STATUS
+NtlmHandleAuthenticateMessage(IN ULONG_PTR hContext,
+                              IN ULONG ContextReq,
+                              IN PSecBuffer InputToken,
+                              OUT PSecBuffer OutputToken,
+                              OUT PULONG pContextAttr,
+                              OUT PTimeStamp ptsExpiry,
+                              OUT PUCHAR pSessionKey,
+                              OUT PULONG pfUserFlags)
+{
+    SECURITY_STATUS ret = SEC_E_OK;
+    PNTLMSSP_CONTEXT context = NULL;
+    PAUTHENTICATE_MESSAGE authMessage = NULL;
+    BOOLEAN isUnicode;
+
+    TRACE("NtlmHandleAuthenticateMessage hContext %x!\n", hContext);
+    /* get context */
+    if(!(context = NtlmReferenceContext(hContext)))
+    {
+        ret = SEC_E_INVALID_HANDLE;
+        goto fail;
+    }
+
+    TRACE("context->State %d\n", context->State);
+    if(context->State != ChallengeSent || context->State != Authenticated)
+    {
+        ERR("Context not in correct state!\n");
+        ret = SEC_E_OUT_OF_SEQUENCE;
+        goto fail;
+    }
+
+    /* re-authorize */
+    if(context->State == Authenticated)
+        UNIMPLEMENTED;
+
+    /* InputToken1 should contain a authenticate message */
+    TRACE("input token size %lx\n", InputToken->cbBuffer);
+    if(InputToken->cbBuffer > NTLM_MAX_BUF ||
+        InputToken->cbBuffer < sizeof(AUTHENTICATE_MESSAGE))
+    {
+        ERR("Input token invalid!\n");
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    /* allocate a buffer for it */
+    if(!(authMessage = NtlmAllocate(sizeof(AUTHENTICATE_MESSAGE))))
+    {
+        ERR("failed to allocate authMessage buffer!\n");
+        ret = SEC_E_INSUFFICIENT_MEMORY;
+        goto fail;
+    }
+
+    /* copy it */
+    memcpy(authMessage, InputToken->pvBuffer, sizeof(AUTHENTICATE_MESSAGE));
+
+    /* validate it */
+    if(strncmp(authMessage->Signature, NTLMSSP_SIGNATURE, 8) &&
+       authMessage->MsgType == NtlmAuthenticate)
+    {
+        ERR("Input message not valid!\n");
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    /* datagram */
+    if(context->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM)
+    {
+        /* context and message dont agree on connection type! */
+        if(!(authMessage->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM))
+        {
+            ret = SEC_E_INVALID_TOKEN;
+            goto fail;
+        }
+
+        /* use message flags */
+        context->NegotiateFlags = authMessage->NegotiateFlags;
+
+        /* need a key */
+        if(context->NegotiateFlags & (NTLMSSP_NEGOTIATE_SIGN | 
NTLMSSP_NEGOTIATE_SEAL))
+            context->NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
+
+        /* remove lm key */
+        if (context->NegotiateFlags & 
NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY)
+            context->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
+    }
+
+    /* supports unicode */
+    if(context->NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE)
+    {
+        context->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_OEM;
+        isUnicode = TRUE;
+    }
+    else if(context->NegotiateFlags & NTLMSSP_NEGOTIATE_OEM)
+    {
+        context->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_UNICODE;
+        isUnicode = FALSE;
+    }
+    else
+    {
+        /* these flags must be bad! */
+        ERR("authenticate flags did not specify unicode or oem!\n");
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    UNICODE_STRING LmChallengeResponse, NtChallengeResponse, SessionKey;
+    UNICODE_STRING UserName, Workstation, DomainName;
+
+    if(!NT_SUCCESS(NtlmBlobToUnicodeString(InputToken,
+        authMessage->LmChallengeResponse, &LmChallengeResponse)))
+    {
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    if(!NT_SUCCESS(NtlmBlobToUnicodeString(InputToken,
+        authMessage->NtChallengeResponse, &NtChallengeResponse)))
+    {
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    if(!NT_SUCCESS(NtlmBlobToUnicodeString(InputToken,
+        authMessage->UserName, &UserName)))
+    {
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    if(!NT_SUCCESS(NtlmBlobToUnicodeString(InputToken,
+        authMessage->WorkstationName, &Workstation)))
+    {
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    if(!NT_SUCCESS(NtlmBlobToUnicodeString(InputToken,
+        authMessage->DomainName, &DomainName)))
+    {
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    //if(NTLMSSP_NEGOTIATE_KEY_EXCHANGE)
+    if(!NT_SUCCESS(NtlmBlobToUnicodeString(InputToken,
+        authMessage->EncryptedRandomSessionKey, &SessionKey)))
+    {
+        ret = SEC_E_INVALID_TOKEN;
+        goto fail;
+    }
+
+    ret = SEC_I_COMPLETE_NEEDED;
+
+fail:
+    NtlmDereferenceContext((ULONG_PTR)context);
+    return ret;
+}

Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h
URL: 
http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h?rev=52014&r1=52013&r2=52014&view=diff
==============================================================================
--- branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h [iso-8859-1] 
(original)
+++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h [iso-8859-1] Mon 
May 30 21:02:50 2011
@@ -164,6 +164,14 @@
     /* payload */
 }AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
 
+typedef struct _MESSAGE_SIGNATURE
+{
+    ULONG Version;
+    ULONG RandomPad;
+    ULONG Checksum;
+    ULONG Nonce;
+}MESSAGE_SIGNATURE, *PMESSAGE_SIGNATURE;
+
 /* basic functions */
 
 VOID
@@ -173,14 +181,14 @@
 
 VOID
 NTOWFv2(
-    PWCHAR password,
-    PWCHAR user,
-    PWCHAR domain,
+    const PWCHAR password,
+    const PWCHAR user,
+    const PWCHAR domain,
     PUCHAR result);
 
 VOID
 LMOWFv1(
-    PCCHAR password,
+    const PCCHAR password,
     PUCHAR result);
 
 VOID
@@ -275,15 +283,17 @@
     IN ULONG_PTR hContext,
     IN ULONG ContextReq,
     IN PSecBuffer InputToken,
-    OUT PSecBuffer *OutputToken);
+    OUT PSecBuffer OutputToken);
 
 SECURITY_STATUS
 NtlmHandleNegotiateMessage(
     IN ULONG_PTR hCredential,
-    IN OUT PULONG_PTR phContext,
+    IN OUT ULONG_PTR hContext,
     IN ULONG fContextReq,
-    IN PSecBuffer InputToken,
-    OUT PSecBuffer *OutputToken,
+    IN PSecBuffer InputToken1,
+    IN PSecBuffer InputToken2,
+    OUT PSecBuffer OutputToken1,
+    OUT PSecBuffer OutputToken2,
     OUT PULONG pContextAttr,
     OUT PTimeStamp ptsExpiry);
 
@@ -293,8 +303,8 @@
     IN ULONG ContextReq,
     IN PSecBuffer InputToken1,
     IN PSecBuffer InputToken2,
-    IN OUT PSecBuffer *OutputToken1,
-    IN OUT PSecBuffer *OutputToken2,
+    IN OUT PSecBuffer OutputToken1,
+    IN OUT PSecBuffer OutputToken2,
     OUT PULONG ContextAttr,
     OUT PTimeStamp ptsExpiry,
     OUT PULONG NegotiateFlags);
@@ -303,15 +313,11 @@
 NtlmHandleAuthenticateMessage(
     IN ULONG_PTR hContext,
     IN ULONG fContextReq,
-    IN PSecBuffer *pInputTokens,
+    IN PSecBuffer InputToken,
     OUT PSecBuffer OutputToken,
     OUT PULONG pContextAttr,
     OUT PTimeStamp ptsExpiry,
     OUT PUCHAR pSessionKey,
-    OUT PULONG pfNegotiateFlags,
-    OUT PHANDLE TokenHandle,
-    OUT PNTSTATUS pSubStatus,
-    OUT PTimeStamp ptsPasswordExpiry,
     OUT PULONG pfUserFlags);
 
 /* helper functions */


Reply via email to