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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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 */