From 19f8c79f9eaff076edd959a0187657633216f0e8 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Thu, 10 May 2012 13:06:20 +0200 Subject: [PATCH] secur32: Implement a Negotiate provider that forwards to NTLM. --- dlls/secur32/negotiate.c | 484 ++++++++++++++++++++++++-------------------- dlls/secur32/ntlm.c | 95 ++------- dlls/secur32/secur32_priv.h | 30 +++ 3 files changed, 318 insertions(+), 291 deletions(-) diff --git a/dlls/secur32/negotiate.c b/dlls/secur32/negotiate.c index 830bc5d6c21..ac48a777e9a 100644 --- a/dlls/secur32/negotiate.c +++ b/dlls/secur32/negotiate.c @@ -1,5 +1,6 @@ /* * Copyright 2005 Kai Blin + * Copyright 2012 Hans Leidekker for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -15,137 +16,151 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * - * This file implements the negotiate provider. - * FIXME: So far, this beast doesn't do anything. + * This file implements a Negotiate provider that simply forwards to + * the NTLM provider. */ -#include + #include #include "windef.h" #include "winbase.h" #include "sspi.h" +#include "rpc.h" +#include "wincred.h" #include "secur32_priv.h" + #include "wine/debug.h" +#include "wine/unicode.h" WINE_DEFAULT_DEBUG_CHANNEL(secur32); -/* Disable for now, see longer comment for SECUR32_initNegotiateSP below */ -#if 0 -static char nego_name_A[] = "Negotiate"; -static WCHAR nego_name_W[] = {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0}; -#endif - -static SECURITY_STATUS nego_QueryCredentialsAttributes(PCredHandle phCredential, - ULONG ulAttribute, PVOID pBuffer) -{ - SECURITY_STATUS ret; - - /* FIXME: More attributes to be added here. Need to fix the sspi.h header - * for that, too. - */ - switch(ulAttribute) - { - default: - ret = SEC_E_UNSUPPORTED_FUNCTION; - } - return ret; -} - /*********************************************************************** * QueryCredentialsAttributesA */ static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA( - PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) + PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { - SECURITY_STATUS ret; - - TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer); - - switch(ulAttribute) - { - case SECPKG_CRED_ATTR_NAMES: - FIXME("SECPKG_CRED_ATTR_NAMES: stub\n"); - ret = SEC_E_UNSUPPORTED_FUNCTION; - break; - default: - ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, - pBuffer); - } - return ret; + FIXME("%p, %u, %p\n", phCredential, ulAttribute, pBuffer); + return SEC_E_UNSUPPORTED_FUNCTION; } /*********************************************************************** * QueryCredentialsAttributesW */ static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW( - PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) + PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) { + FIXME("%p, %u, %p\n", phCredential, ulAttribute, pBuffer); + return SEC_E_UNSUPPORTED_FUNCTION; +} + +/*********************************************************************** + * AcquireCredentialsHandleW + */ +static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW( + SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, + PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry ) +{ + static SEC_WCHAR ntlmW[] = {'N','T','L','M',0}; SECURITY_STATUS ret; - TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer); + TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n", + debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse, + pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); - switch(ulAttribute) + FIXME("forwarding to NTLM\n"); + ret = ntlm_AcquireCredentialsHandleW( pszPrincipal, ntlmW, fCredentialUse, + pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, + phCredential, ptsExpiry ); + if (ret == SEC_E_OK) { - case SECPKG_CRED_ATTR_NAMES: - FIXME("SECPKG_CRED_ATTR_NAMES: stub\n"); - ret = SEC_E_UNSUPPORTED_FUNCTION; - break; - default: - ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, - pBuffer); + NtlmCredentials *cred = (NtlmCredentials *)phCredential->dwLower; + cred->no_cached_credentials = (pAuthData == NULL); } return ret; } - /*********************************************************************** * AcquireCredentialsHandleA */ static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA( - SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, - PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, - PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) -{ - TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n", - debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse, - pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); - return SEC_E_UNSUPPORTED_FUNCTION; -} - -/*********************************************************************** - * AcquireCredentialsHandleW - */ -static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW( - SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, - PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, - PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) + SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, + PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry ) { - TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p) stub\n", - debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse, - pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); - return SEC_E_UNSUPPORTED_FUNCTION; -} + SECURITY_STATUS ret = SEC_E_INSUFFICIENT_MEMORY; + SEC_WCHAR *user = NULL, *domain = NULL, *passwd = NULL, *package = NULL; + SEC_WINNT_AUTH_IDENTITY_W *identityW = NULL; -/*********************************************************************** - * InitializeSecurityContextA - */ -static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA( - PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, - ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) -{ - SECURITY_STATUS ret; + TRACE("%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p\n", + debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse, + pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); - TRACE("%p %p %s 0x%08x %d %d %p %d %p %p %p %p\n", phCredential, phContext, - debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, - Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); - if(phCredential){ - ret = SEC_E_UNSUPPORTED_FUNCTION; + if (pszPackage) + { + int package_len = MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, NULL, 0 ); + package = HeapAlloc( GetProcessHeap(), 0, package_len * sizeof(SEC_WCHAR) ); + if (!package) return SEC_E_INSUFFICIENT_MEMORY; + MultiByteToWideChar( CP_ACP, 0, pszPackage, -1, package, package_len ); } - else + if (pAuthData) { - ret = SEC_E_INVALID_HANDLE; + SEC_WINNT_AUTH_IDENTITY_A *identity = pAuthData; + int user_len, domain_len, passwd_len; + + if (identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI) + { + identityW = HeapAlloc( GetProcessHeap(), 0, sizeof(*identityW) ); + if (!identityW) goto done; + + if (!identity->UserLength) user_len = 0; + else + { + user_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User, + identity->UserLength, NULL, 0 ); + user = HeapAlloc( GetProcessHeap(), 0, user_len * sizeof(SEC_WCHAR) ); + if (!user) goto done; + MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->User, identity->UserLength, + user, user_len ); + } + if (!identity->DomainLength) domain_len = 0; + else + { + domain_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain, + identity->DomainLength, NULL, 0 ); + domain = HeapAlloc( GetProcessHeap(), 0, domain_len * sizeof(SEC_WCHAR) ); + if (!domain) goto done; + MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Domain, identity->DomainLength, + domain, domain_len ); + } + if (!identity->PasswordLength) passwd_len = 0; + else + { + passwd_len = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password, + identity->PasswordLength, NULL, 0 ); + passwd = HeapAlloc( GetProcessHeap(), 0, passwd_len * sizeof(SEC_WCHAR) ); + if (!passwd) goto done; + MultiByteToWideChar( CP_ACP, 0, (LPCSTR)identity->Password, identity->PasswordLength, + passwd, passwd_len ); + } + identityW->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + identityW->User = user; + identityW->UserLength = user_len; + identityW->Domain = domain; + identityW->DomainLength = domain_len; + identityW->Password = passwd; + identityW->PasswordLength = passwd_len; + } + else identityW = (SEC_WINNT_AUTH_IDENTITY_W *)identity; } + ret = nego_AcquireCredentialsHandleW( NULL, package, fCredentialUse, pLogonID, identityW, + pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry ); +done: + HeapFree( GetProcessHeap(), 0, package ); + HeapFree( GetProcessHeap(), 0, user ); + HeapFree( GetProcessHeap(), 0, domain ); + HeapFree( GetProcessHeap(), 0, passwd ); + HeapFree( GetProcessHeap(), 0, identityW ); return ret; } @@ -153,24 +168,50 @@ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA( * InitializeSecurityContextW */ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW( - PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, - ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, - PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) + PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, + ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, + PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry ) +{ + TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n", + phCredential, phContext, debugstr_w(pszTargetName), fContextReq, + Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput, + pfContextAttr, ptsExpiry); + + return ntlm_InitializeSecurityContextW( phCredential, phContext, pszTargetName, + fContextReq, Reserved1, TargetDataRep, + pInput, Reserved2, phNewContext, + pOutput, pfContextAttr, ptsExpiry ); +} + +/*********************************************************************** + * InitializeSecurityContextA + */ +static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA( + PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, + ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, + PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry ) { SECURITY_STATUS ret; + SEC_WCHAR *target = NULL; + + TRACE("%p, %p, %s, 0x%08x, %u, %u, %p, %u, %p, %p, %p, %p\n", + phCredential, phContext, debugstr_a(pszTargetName), fContextReq, + Reserved1, TargetDataRep, pInput, Reserved1, phNewContext, pOutput, + pfContextAttr, ptsExpiry); - TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext, - debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, - Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); - if (phCredential) + if (pszTargetName) { - ret = SEC_E_UNSUPPORTED_FUNCTION; - } - else - { - ret = SEC_E_INVALID_HANDLE; + int target_len = MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, NULL, 0 ); + target = HeapAlloc(GetProcessHeap(), 0, target_len * sizeof(SEC_WCHAR) ); + if (!target) return SEC_E_INSUFFICIENT_MEMORY; + MultiByteToWideChar( CP_ACP, 0, pszTargetName, -1, target, target_len ); } + ret = nego_InitializeSecurityContextW( phCredential, phContext, target, fContextReq, + Reserved1, TargetDataRep, pInput, Reserved2, + phNewContext, pOutput, pfContextAttr, ptsExpiry ); + HeapFree( GetProcessHeap(), 0, target ); return ret; } @@ -178,24 +219,17 @@ static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW( * AcceptSecurityContext */ static SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext( - PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, - ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, - PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) + PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, + ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, + PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) { - SECURITY_STATUS ret; + TRACE("%p, %p, %p, 0x%08x, %u, %p, %p, %p, %p\n", phCredential, phContext, + pInput, fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, + ptsExpiry); - TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput, - fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, - ptsExpiry); - if (phCredential) - { - ret = SEC_E_UNSUPPORTED_FUNCTION; - } - else - { - ret = SEC_E_INVALID_HANDLE; - } - return ret; + return ntlm_AcceptSecurityContext( phCredential, phContext, pInput, + fContextReq, TargetDataRep, phNewContext, + pOutput, pfContextAttr, ptsExpiry ); } /*********************************************************************** @@ -223,18 +257,9 @@ static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext, */ static SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext) { - SECURITY_STATUS ret; - TRACE("%p\n", phContext); - if (phContext) - { - ret = SEC_E_UNSUPPORTED_FUNCTION; - } - else - { - ret = SEC_E_INVALID_HANDLE; - } - return ret; + + return ntlm_DeleteSecurityContext( phContext ); } /*********************************************************************** @@ -260,25 +285,32 @@ static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext, /*********************************************************************** * QueryContextAttributesW */ -static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phContext, - ULONG ulAttribute, void *pBuffer) +static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW( + PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) { - SECURITY_STATUS ret; + TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer); - /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is - * the SecurePackage part and the dwLower part is the actual context - * handle. It should be easy to extract the context attributes from that. - */ - TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); - if (phContext) + switch (ulAttribute) { - ret = SEC_E_UNSUPPORTED_FUNCTION; + case SECPKG_ATTR_SIZES: + { + SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)pBuffer; + sizes->cbMaxToken = 2888; + sizes->cbMaxSignature = 16; + sizes->cbSecurityTrailer = 16; + sizes->cbBlockSize = 0; + return SEC_E_OK; } - else + case SECPKG_ATTR_NEGOTIATION_INFO: { - ret = SEC_E_INVALID_HANDLE; + SecPkgContext_NegotiationInfoW *info = (SecPkgContext_NegotiationInfoW *)pBuffer; + info->PackageInfo = ntlm_package_infoW; + info->NegotiationState = SECPKG_NEGOTIATION_COMPLETE; + return SEC_E_OK; + } + default: + return ntlm_QueryContextAttributesW( phContext, ulAttribute, pBuffer ); } - return ret; } /*********************************************************************** @@ -287,7 +319,29 @@ static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phCont static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) { - return nego_QueryContextAttributesW(phContext, ulAttribute, pBuffer); + TRACE("%p, %u, %p\n", phContext, ulAttribute, pBuffer); + + switch (ulAttribute) + { + case SECPKG_ATTR_SIZES: + { + SecPkgContext_Sizes *sizes = (SecPkgContext_Sizes *)pBuffer; + sizes->cbMaxToken = 2888; + sizes->cbMaxSignature = 16; + sizes->cbSecurityTrailer = 16; + sizes->cbBlockSize = 0; + return SEC_E_OK; + } + case SECPKG_ATTR_NEGOTIATION_INFO: + { + SecPkgContext_NegotiationInfoA *info = (SecPkgContext_NegotiationInfoA *)pBuffer; + info->PackageInfo = ntlm_package_infoA; + info->NegotiationState = SECPKG_NEGOTIATION_COMPLETE; + return SEC_E_OK; + } + default: + return ntlm_QueryContextAttributesA( phContext, ulAttribute, pBuffer ); + } } /*********************************************************************** @@ -331,52 +385,64 @@ static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContex /*********************************************************************** * MakeSignature */ -static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, ULONG fQOP, - PSecBufferDesc pMessage, ULONG MessageSeqNo) +static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, + ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { - SECURITY_STATUS ret; + TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo); - TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo); - if (phContext) - { - ret = SEC_E_UNSUPPORTED_FUNCTION; - } - else - { - ret = SEC_E_INVALID_HANDLE; - } - return ret; + return ntlm_MakeSignature( phContext, fQOP, pMessage, MessageSeqNo ); } /*********************************************************************** * VerifySignature */ static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext, - PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) + PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) { - SECURITY_STATUS ret; + TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP); - TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP); - if (phContext) - { - ret = SEC_E_UNSUPPORTED_FUNCTION; - } - else - { - ret = SEC_E_INVALID_HANDLE; - } - return ret; + return ntlm_VerifySignature( phContext, pMessage, MessageSeqNo, pfQOP ); +} + +/*********************************************************************** + * FreeCredentialsHandle + */ +SECURITY_STATUS SEC_ENTRY nego_FreeCredentialsHandle(PCredHandle phCredential) +{ + TRACE("%p\n", phCredential); + + return ntlm_FreeCredentialsHandle( phCredential ); } +/*********************************************************************** + * EncryptMessage + */ +SECURITY_STATUS SEC_ENTRY nego_EncryptMessage(PCtxtHandle phContext, + ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +{ + TRACE("%p, 0x%08x, %p, %u\n", phContext, fQOP, pMessage, MessageSeqNo); + return ntlm_EncryptMessage( phContext, fQOP, pMessage, MessageSeqNo ); +} + +/*********************************************************************** + * DecryptMessage + */ +SECURITY_STATUS SEC_ENTRY nego_DecryptMessage(PCtxtHandle phContext, + PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +{ + TRACE("%p, %p, %u, %p\n", phContext, pMessage, MessageSeqNo, pfQOP); + + return ntlm_DecryptMessage( phContext, pMessage, MessageSeqNo, pfQOP ); +} static const SecurityFunctionTableA negoTableA = { 1, - NULL, /* EnumerateSecurityPackagesA */ + NULL, /* EnumerateSecurityPackagesA */ nego_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */ nego_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */ - FreeCredentialsHandle, /* FreeCredentialsHandle */ - NULL, /* Reserved2 */ + nego_FreeCredentialsHandle, /* FreeCredentialsHandle */ + NULL, /* Reserved2 */ nego_InitializeSecurityContextA, /* InitializeSecurityContextA */ nego_AcceptSecurityContext, /* AcceptSecurityContext */ nego_CompleteAuthToken, /* CompleteAuthToken */ @@ -396,18 +462,18 @@ static const SecurityFunctionTableA negoTableA = { NULL, /* AddCredentialsA */ NULL, /* Reserved8 */ NULL, /* QuerySecurityContextToken */ - NULL, /* EncryptMessage */ - NULL, /* DecryptMessage */ + nego_EncryptMessage, /* EncryptMessage */ + nego_DecryptMessage, /* DecryptMessage */ NULL, /* SetContextAttributesA */ }; static const SecurityFunctionTableW negoTableW = { 1, - NULL, /* EnumerateSecurityPackagesW */ + NULL, /* EnumerateSecurityPackagesW */ nego_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */ nego_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */ - FreeCredentialsHandle, /* FreeCredentialsHandle */ - NULL, /* Reserved2 */ + nego_FreeCredentialsHandle, /* FreeCredentialsHandle */ + NULL, /* Reserved2 */ nego_InitializeSecurityContextW, /* InitializeSecurityContextW */ nego_AcceptSecurityContext, /* AcceptSecurityContext */ nego_CompleteAuthToken, /* CompleteAuthToken */ @@ -427,51 +493,41 @@ static const SecurityFunctionTableW negoTableW = { NULL, /* AddCredentialsW */ NULL, /* Reserved8 */ NULL, /* QuerySecurityContextToken */ - NULL, /* EncryptMessage */ - NULL, /* DecryptMessage */ + nego_EncryptMessage, /* EncryptMessage */ + nego_DecryptMessage, /* DecryptMessage */ NULL, /* SetContextAttributesW */ }; -/* Disable for now, see comment below.*/ -#if 0 -static WCHAR negotiate_comment_W[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o', - 'f', 't', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', 'N', 'e', 'g', 'o', - 't', 'i', 'a', 't', 'o', 'r', 0}; +#define NEGO_MAX_TOKEN 12000 + +static WCHAR nego_name_W[] = {'N','e','g','o','t','i','a','t','e',0}; +static char nego_name_A[] = "Negotiate"; +static WCHAR negotiate_comment_W[] = + {'M','i','c','r','o','s','o','f','t',' ','P','a','c','k','a','g','e',' ', + 'N','e','g','o','t','i','a','t','o','r',0}; static CHAR negotiate_comment_A[] = "Microsoft Package Negotiator"; -#endif +#define CAPS ( \ + SECPKG_FLAG_INTEGRITY | \ + SECPKG_FLAG_PRIVACY | \ + SECPKG_FLAG_CONNECTION | \ + SECPKG_FLAG_MULTI_REQUIRED | \ + SECPKG_FLAG_EXTENDED_ERROR | \ + SECPKG_FLAG_IMPERSONATION | \ + SECPKG_FLAG_ACCEPT_WIN32_NAME | \ + SECPKG_FLAG_NEGOTIABLE | \ + SECPKG_FLAG_GSS_COMPATIBLE | \ + SECPKG_FLAG_LOGON | \ + SECPKG_FLAG_RESTRICTED_TOKENS ) void SECUR32_initNegotiateSP(void) { -/* Disable until we really implement a Negotiate provider. - * For now, the NTLM provider will pretend to be the Negotiate provider as well. - * Windows seems to be able to deal with it, and it makes several programs - * happy. */ -#if 0 - SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, - NULL); - /* According to Windows, Negotiate has the following capabilities. - */ - - static const LONG caps = - SECPKG_FLAG_INTEGRITY | - SECPKG_FLAG_PRIVACY | - SECPKG_FLAG_CONNECTION | - SECPKG_FLAG_MULTI_REQUIRED | - SECPKG_FLAG_EXTENDED_ERROR | - SECPKG_FLAG_IMPERSONATION | - SECPKG_FLAG_ACCEPT_WIN32_NAME | - SECPKG_FLAG_READONLY_WITH_CHECKSUM; - - static const USHORT version = 1; - static const USHORT rpcid = 15; - static const ULONG max_token = 12000; - const SecPkgInfoW infoW = { caps, version, rpcid, max_token, nego_name_W, - negotiate_comment_W}; - const SecPkgInfoA infoA = { caps, version, rpcid, max_token, nego_name_A, - negotiate_comment_A}; + SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW, NULL); + const SecPkgInfoW infoW = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN, + nego_name_W, negotiate_comment_W}; + const SecPkgInfoA infoA = {CAPS, 1, RPC_C_AUTHN_GSS_NEGOTIATE, NEGO_MAX_TOKEN, + nego_name_A, negotiate_comment_A}; SECUR32_addPackages(provider, 1L, &infoA, &infoW); -#endif } diff --git a/dlls/secur32/ntlm.c b/dlls/secur32/ntlm.c index 38d204547be..fdd88c0c635 100644 --- a/dlls/secur32/ntlm.c +++ b/dlls/secur32/ntlm.c @@ -43,18 +43,6 @@ WINE_DECLARE_DEBUG_CHANNEL(winediag); static CHAR ntlm_auth[] = "ntlm_auth"; -typedef struct _NtlmCredentials -{ - HelperMode mode; - - /* these are all in the Unix codepage */ - char *username_arg; - char *domain_arg; - char *password; /* not nul-terminated */ - int pwlen; - int no_cached_credentials; /* don't try to use cached Samba credentials */ -} NtlmCredentials, *PNtlmCredentials; - /*********************************************************************** * QueryCredentialsAttributesA */ @@ -136,7 +124,7 @@ static char *ntlm_GetDomainArg(LPCWSTR domainW, INT domainW_length) /*********************************************************************** * AcquireCredentialsHandleW */ -static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW( +SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW( SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) @@ -425,7 +413,7 @@ static BOOL ntlm_GetCachedCredential(const SEC_WCHAR *pszTargetName, PCREDENTIAL /*********************************************************************** * InitializeSecurityContextW */ -static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW( +SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW( PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, @@ -970,7 +958,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA( /*********************************************************************** * AcceptSecurityContext */ -static SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext( +SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext( PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry) @@ -1343,7 +1331,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken(PCtxtHandle phContext, /*********************************************************************** * DeleteSecurityContext */ -static SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext) +SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext) { PNegoHelper helper; @@ -1372,7 +1360,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContex /*********************************************************************** * QueryContextAttributesW */ -static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, +SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) { TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); @@ -1427,7 +1415,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phCont /*********************************************************************** * QueryContextAttributesA */ -static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, +SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) { return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer); @@ -1607,8 +1595,8 @@ static SECURITY_STATUS ntlm_CreateSignature(PNegoHelper helper, PSecBufferDesc p /*********************************************************************** * MakeSignature */ -static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG fQOP, - PSecBufferDesc pMessage, ULONG MessageSeqNo) +SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, + ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { PNegoHelper helper; int token_idx; @@ -1642,8 +1630,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG /*********************************************************************** * VerifySignature */ -static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, - PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, + PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) { PNegoHelper helper; ULONG fQOP = 0; @@ -1714,8 +1702,7 @@ static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, /*********************************************************************** * FreeCredentialsHandle */ -static SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle( - PCredHandle phCredential) +SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle(PCredHandle phCredential) { SECURITY_STATUS ret; @@ -1740,8 +1727,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle( /*********************************************************************** * EncryptMessage */ -static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, - ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) +SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, + ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo) { PNegoHelper helper; int token_idx, data_idx; @@ -1811,8 +1798,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, /*********************************************************************** * DecryptMessage */ -static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, - PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, + PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) { SECURITY_STATUS ret; ULONG ntlmssp_flags_save; @@ -1971,50 +1958,8 @@ static const SecPkgInfoA infoA = { ntlm_comment_A }; -#define NEGO_COMMENT { 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ', \ - 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', \ - 'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'o', 'r', 0} - -static CHAR nego_comment_A[] = NEGO_COMMENT; -static WCHAR nego_comment_W[] = NEGO_COMMENT; - -#define NEGO_NAME {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0} - -static CHAR nego_name_A[] = NEGO_NAME; -static WCHAR nego_name_W[] = NEGO_NAME; - -#define NEGO_CAPS (\ - SECPKG_FLAG_INTEGRITY | \ - SECPKG_FLAG_PRIVACY | \ - SECPKG_FLAG_CONNECTION | \ - SECPKG_FLAG_MULTI_REQUIRED | \ - SECPKG_FLAG_EXTENDED_ERROR | \ - SECPKG_FLAG_IMPERSONATION | \ - SECPKG_FLAG_ACCEPT_WIN32_NAME | \ - SECPKG_FLAG_READONLY_WITH_CHECKSUM ) - -/* Not used for now, just kept here for completeness sake. We need to use the - * NTLM_MAX_BUF value. If the hack works, we might want to refactor the code a - * bit. */ -#define NEGO_MAX_TOKEN 12000 - -static const SecPkgInfoW nego_infoW = { - NEGO_CAPS, - 1, - RPC_C_AUTHN_GSS_NEGOTIATE, - NTLM_MAX_BUF, - nego_name_W, - nego_comment_W -}; - -static const SecPkgInfoA nego_infoA = { - NEGO_CAPS, - 1, - RPC_C_AUTHN_GSS_NEGOTIATE, - NTLM_MAX_BUF, - nego_name_A, - nego_comment_A -}; +SecPkgInfoA *ntlm_package_infoA = (SecPkgInfoA *)&infoA; +SecPkgInfoW *ntlm_package_infoW = (SecPkgInfoW *)&infoW; void SECUR32_initNTLMSP(void) { @@ -2040,11 +1985,7 @@ void SECUR32_initNTLMSP(void) helper->micro >= MIN_NTLM_AUTH_MICRO_VERSION)) ) { SecureProvider *provider = SECUR32_addProvider(&ntlmTableA, &ntlmTableW, NULL); - SecureProvider *nego_provider = SECUR32_addProvider(&ntlmTableA, &ntlmTableW, NULL); - - SECUR32_addPackages(provider, 1L, &infoA, &infoW); - /* HACK: Also pretend this is the Negotiate provider */ - SECUR32_addPackages(nego_provider, 1L, &nego_infoA, &nego_infoW); + SECUR32_addPackages(provider, 1L, ntlm_package_infoA, ntlm_package_infoW); } else { diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h index c6b362b864b..3254e0bf0d0 100644 --- a/dlls/secur32/secur32_priv.h +++ b/dlls/secur32/secur32_priv.h @@ -85,6 +85,18 @@ typedef struct _NegoHelper { } crypt; } NegoHelper, *PNegoHelper; +typedef struct _NtlmCredentials +{ + HelperMode mode; + + /* these are all in the Unix codepage */ + char *username_arg; + char *domain_arg; + char *password; /* not nul-terminated */ + int pwlen; + int no_cached_credentials; /* don't try to use cached Samba credentials */ +} NtlmCredentials, *PNtlmCredentials; + typedef enum _sign_direction { NTLM_SEND, NTLM_RECV @@ -176,6 +188,24 @@ void SECUR32_arc4Cleanup(arc4_info *a4i) DECLSPEC_HIDDEN; #define NTLMSSP_NEGOTIATE_KEY_EXCHANGE 0x40000000 #define NTLMSSP_NEGOTIATE_56 0x80000000 +SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR *, SEC_WCHAR *, + ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle, PCtxtHandle, + SEC_WCHAR *, ULONG fContextReq, ULONG, ULONG, PSecBufferDesc, ULONG, PCtxtHandle, + PSecBufferDesc, ULONG *, PTimeStamp) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle, PCtxtHandle, PSecBufferDesc, + ULONG, ULONG, PCtxtHandle, PSecBufferDesc, ULONG *, PTimeStamp) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle, ULONG, void *) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle, ULONG, void *) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle, ULONG, PSecBufferDesc, ULONG) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle, PSecBufferDesc, ULONG, PULONG) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle(PCredHandle) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle, ULONG, PSecBufferDesc, ULONG) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle, PSecBufferDesc, ULONG, PULONG) DECLSPEC_HIDDEN; + +SecPkgInfoW *ntlm_package_infoW; +SecPkgInfoA *ntlm_package_infoA; /* schannel internal interface */ typedef struct schan_imp_session_opaque *schan_imp_session; -- 2.11.4.GIT