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