From ece9de5aaa78a483bef98345551a259a5f07ba58 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 15 Aug 2005 20:52:18 +0000 Subject: [PATCH] Added Negotiate security provider dummy. Removed todos from the test. --- dlls/secur32/Makefile.in | 1 + dlls/secur32/negotiate.c | 491 ++++++++++++++++++++++++++++++++++++ dlls/secur32/secur32.c | 1 + dlls/secur32/secur32_priv.h | 1 + dlls/secur32/tests/main.c | 40 ++- 5 files changed, 511 insertions(+), 23 deletions(-) create mode 100644 dlls/secur32/negotiate.c diff --git a/dlls/secur32/Makefile.in b/dlls/secur32/Makefile.in index be96f324848..b9761817016 100644 --- a/dlls/secur32/Makefile.in +++ b/dlls/secur32/Makefile.in @@ -7,6 +7,7 @@ IMPORTLIB = libsecur32.$(IMPLIBEXT) IMPORTS = user32 advapi32 kernel32 ntdll C_SRCS = \ + negotiate.c \ schannel.c \ secur32.c \ thunks.c \ diff --git a/dlls/secur32/negotiate.c b/dlls/secur32/negotiate.c new file mode 100644 index 00000000000..4bfff596e32 --- /dev/null +++ b/dlls/secur32/negotiate.c @@ -0,0 +1,491 @@ +/* + * Copyright 2005 Kai Blin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This file implements the negotiate provider. + * FIXME: So far, this beast doesn't do anything. + */ +#include +#include +#include "windef.h" +#include "winbase.h" +#include "sspi.h" +#include "secur32_priv.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(secur32); + +static char nego_name_A[] = "Negotiate"; +static WCHAR nego_name_W[] = {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0}; + +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) +{ + SECURITY_STATUS ret; + + TRACE("(%p, %ld, %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; +} + +/*********************************************************************** + * QueryCredentialsAttributesW + */ +static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW( + PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("(%p, %ld, %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; +} + +static SECURITY_STATUS nego_AcquireCredentialsHandle(ULONG fCredentialsUse, + PCredHandle phCredential, PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + if(fCredentialsUse == SECPKG_CRED_BOTH) + { + ret = SEC_E_NO_CREDENTIALS; + } + else + { + /* Ok, just store the direction like schannel does for now. + * FIXME: This should probably do something useful later on + */ + phCredential->dwUpper = fCredentialsUse; + /* Same here, shamelessly stolen from schannel.c */ + if (ptsExpiry) + ptsExpiry->QuadPart = 0; + ret = SEC_E_OK; + } + 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%08lx, %p, %p, %p, %p, %p, %p)\n", + debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse, + pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); + return nego_AcquireCredentialsHandle(fCredentialUse, phCredential, + ptsExpiry); +} + +/*********************************************************************** + * 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) +{ + TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n", + debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse, + pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry); + return nego_AcquireCredentialsHandle(fCredentialUse, phCredential, + 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; + + TRACE("%p %p %s %ld %ld %ld %p %ld %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; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * 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) +{ + SECURITY_STATUS ret; + + TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext, + debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput, + Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry); + if (phCredential) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * 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) +{ + SECURITY_STATUS ret; + + TRACE("%p %p %p %ld %ld %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; +} + +/*********************************************************************** + * CompleteAuthToken + */ +static SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext, + PSecBufferDesc pToken) +{ + SECURITY_STATUS ret; + + TRACE("%p %p\n", phContext, pToken); + if (phContext) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * DeleteSecurityContext + */ +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; +} + +/*********************************************************************** + * ApplyControlToken + */ +static SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext, + PSecBufferDesc pInput) +{ + SECURITY_STATUS ret; + + TRACE("%p %p\n", phContext, pInput); + if (phContext) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * QueryContextAttributesW + */ +static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phContext, + unsigned long ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + /* 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 %ld %p\n", phContext, ulAttribute, pBuffer); + if (phContext) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * QueryContextAttributesA + */ +static SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext, + unsigned long ulAttribute, void *pBuffer) +{ + return nego_QueryContextAttributesW(phContext, ulAttribute, pBuffer); +} + +/*********************************************************************** + * ImpersonateSecurityContext + */ +static SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + + TRACE("%p\n", phContext); + if (phContext) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * RevertSecurityContext + */ +static SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + + TRACE("%p\n", phContext); + if (phContext) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * MakeSignature + */ +static SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, ULONG fQOP, + PSecBufferDesc pMessage, ULONG MessageSeqNo) +{ + SECURITY_STATUS ret; + + TRACE("%p %ld %p %ld\n", phContext, fQOP, pMessage, MessageSeqNo); + if (phContext) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + +/*********************************************************************** + * VerifySignature + */ +static SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext, + PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +{ + SECURITY_STATUS ret; + + TRACE("%p %p %ld %p\n", phContext, pMessage, MessageSeqNo, pfQOP); + if (phContext) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + { + ret = SEC_E_INVALID_HANDLE; + } + return ret; +} + + + +static SecurityFunctionTableA negoTableA = { + 1, + NULL, /* EnumerateSecurityPackagesA */ + nego_QueryCredentialsAttributesA, /* QueryCredentialsAttributesA */ + nego_AcquireCredentialsHandleA, /* AcquireCredentialsHandleA */ + FreeCredentialsHandle, /* FreeCredentialsHandle */ + NULL, /* Reserved2 */ + nego_InitializeSecurityContextA, /* InitializeSecurityContextA */ + nego_AcceptSecurityContext, /* AcceptSecurityContext */ + nego_CompleteAuthToken, /* CompleteAuthToken */ + nego_DeleteSecurityContext, /* DeleteSecurityContext */ + nego_ApplyControlToken, /* ApplyControlToken */ + nego_QueryContextAttributesA, /* QueryContextAttributesA */ + nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */ + nego_RevertSecurityContext, /* RevertSecurityContext */ + nego_MakeSignature, /* MakeSignature */ + nego_VerifySignature, /* VerifySignature */ + FreeContextBuffer, /* FreeContextBuffer */ + NULL, /* QuerySecurityPackageInfoA */ + NULL, /* Reserved3 */ + NULL, /* Reserved4 */ + NULL, /* ExportSecurityContext */ + NULL, /* ImportSecurityContextA */ + NULL, /* AddCredentialsA */ + NULL, /* Reserved8 */ + NULL, /* QuerySecurityContextToken */ + NULL, /* EncryptMessage */ + NULL, /* DecryptMessage */ + NULL, /* SetContextAttributesA */ +}; + +static SecurityFunctionTableW negoTableW = { + 1, + NULL, /* EnumerateSecurityPackagesW */ + nego_QueryCredentialsAttributesW, /* QueryCredentialsAttributesW */ + nego_AcquireCredentialsHandleW, /* AcquireCredentialsHandleW */ + FreeCredentialsHandle, /* FreeCredentialsHandle */ + NULL, /* Reserved2 */ + nego_InitializeSecurityContextW, /* InitializeSecurityContextW */ + nego_AcceptSecurityContext, /* AcceptSecurityContext */ + nego_CompleteAuthToken, /* CompleteAuthToken */ + nego_DeleteSecurityContext, /* DeleteSecurityContext */ + nego_ApplyControlToken, /* ApplyControlToken */ + nego_QueryContextAttributesW, /* QueryContextAttributesW */ + nego_ImpersonateSecurityContext, /* ImpersonateSecurityContext */ + nego_RevertSecurityContext, /* RevertSecurityContext */ + nego_MakeSignature, /* MakeSignature */ + nego_VerifySignature, /* VerifySignature */ + FreeContextBuffer, /* FreeContextBuffer */ + NULL, /* QuerySecurityPackageInfoW */ + NULL, /* Reserved3 */ + NULL, /* Reserved4 */ + NULL, /* ExportSecurityContext */ + NULL, /* ImportSecurityContextW */ + NULL, /* AddCredentialsW */ + NULL, /* Reserved8 */ + NULL, /* QuerySecurityContextToken */ + NULL, /* EncryptMessage */ + NULL, /* DecryptMessage */ + NULL, /* SetContextAttributesW */ +}; + +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"; + + + +void SECUR32_initNegotiateSP(void) +{ + 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}; + + SECUR32_addPackages(provider, 1L, &infoA, &infoW); + +} diff --git a/dlls/secur32/secur32.c b/dlls/secur32/secur32.c index 1e89f8d3f67..894c90a290e 100644 --- a/dlls/secur32/secur32.c +++ b/dlls/secur32/secur32.c @@ -609,6 +609,7 @@ static void SECUR32_initializeProviders(void) InitializeCriticalSection(&cs); /* First load built-in providers */ SECUR32_initSchannelSP(); + SECUR32_initNegotiateSP(); /* Now load providers from registry */ apiRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, securityProvidersKeyW, 0, KEY_READ, &key); diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h index 74dad4691bb..ba21a4c01bd 100644 --- a/dlls/secur32/secur32_priv.h +++ b/dlls/secur32/secur32_priv.h @@ -79,5 +79,6 @@ PSTR SECUR32_AllocMultiByteFromWide(PCWSTR str); /* Initialization functions for built-in providers */ void SECUR32_initSchannelSP(void); +void SECUR32_initNegotiateSP(void); #endif /* ndef __SECUR32_PRIV_H__ */ diff --git a/dlls/secur32/tests/main.c b/dlls/secur32/tests/main.c index a44a50c1058..2338531f66a 100644 --- a/dlls/secur32/tests/main.c +++ b/dlls/secur32/tests/main.c @@ -88,11 +88,9 @@ static int genClientContext(PBYTE in, DWORD in_count, PBYTE out, sec_status = (sft->AcquireCredentialsHandle)(NULL, "Negotiate", SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, cred_handle, &ttl); - todo_wine{ - ok(sec_status == SEC_E_OK, - "Client AcquireCredentialsHandle should not return %s\n", - getSecStatusError(sec_status) ); - } + ok(sec_status == SEC_E_OK, + "Client AcquireCredentialsHandle should not return %s\n", + getSecStatusError(sec_status) ); } out_sec_buff_desc.ulVersion = 0; @@ -288,24 +286,20 @@ static void testQuerySecurityPackageInfo(void) sec_status = setupPackageA(sec_pkg_name, &pkg_info); - todo_wine{ - ok(sec_status == SEC_E_OK, - "Return value of QuerySecurityPackageInfo() shouldn't be %s\n", - getSecStatusError(sec_status) ); - ok(pkg_info != NULL, + ok(sec_status == SEC_E_OK, + "Return value of QuerySecurityPackageInfo() shouldn't be %s\n", + getSecStatusError(sec_status) ); + ok(pkg_info != NULL, "QuerySecurityPackageInfo should give struct SecPkgInfo, but is NULL\n"); - } + if(pkg_info != NULL){ max_token = pkg_info->cbMaxToken; version = pkg_info->wVersion; } - todo_wine{ - ok(version == 1, "wVersion always should be 1, but is %d\n", version); - ok(max_token == 12000, "cbMaxToken for Negotiate is %ld, not 12000.\n", - max_token); - } - - trace("Max token = %ld\n", max_token); + + ok(version == 1, "wVersion always should be 1, but is %d\n", version); + ok(max_token == 12000, "cbMaxToken for Negotiate is %ld, not 12000.\n", + max_token); sec_status = FreeContextBuffer(&pkg_info); @@ -360,11 +354,9 @@ void testAuthentication(void) SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &server_cred, &server_ttl); - todo_wine{ - ok(sec_status == SEC_E_OK, - "Server's AcquireCredentialsHandle returned %s.\n", - getSecStatusError(sec_status) ); - } + ok(sec_status == SEC_E_OK, + "Server's AcquireCredentialsHandle returned %s.\n", + getSecStatusError(sec_status) ); genClientContext(NULL, 0, server_buff, &count_server, &done, "foo", @@ -379,6 +371,8 @@ void testAuthentication(void) &count_server, &done, "foo", &client_cred, &client_ctxt, sft); } + FreeContextBuffer(&client_buff); + FreeContextBuffer(&server_buff); }