From: Jérôme Gardou Date: Sat, 30 Aug 2014 21:31:32 +0000 (+0000) Subject: [SECUR32] X-Git-Tag: backups/0.3.17@66124~707 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=6c31293a0b287db0f921c794ea6cb31b87747c57;hp=d7d4f8d9184face511c8683fcb50f19705392a64 [SECUR32] - Import SSPI module loading from wine svn path=/trunk/; revision=63994 --- diff --git a/reactos/dll/win32/secur32/CMakeLists.txt b/reactos/dll/win32/secur32/CMakeLists.txt index c09dc40490d..94a2b747151 100644 --- a/reactos/dll/win32/secur32/CMakeLists.txt +++ b/reactos/dll/win32/secur32/CMakeLists.txt @@ -9,6 +9,8 @@ list(APPEND SOURCE secext.c sspi.c stubs.c + thunks.c + wrapper.c precomp.h) add_library(secur32 SHARED @@ -17,11 +19,11 @@ add_library(secur32 SHARED ${CMAKE_CURRENT_BINARY_DIR}/secur32_stubs.c ${CMAKE_CURRENT_BINARY_DIR}/secur32.def) -set_module_type(secur32 win32dll UNICODE ENTRYPOINT DllMain 12) +set_module_type(secur32 win32dll UNICODE) -target_link_libraries(secur32 lsalib) +target_link_libraries(secur32 lsalib wine) -add_importlibs(secur32 advapi32 kernel32 ntdll) +add_importlibs(secur32 advapi32 msvcrt kernel32 ntdll) add_pch(secur32 precomp.h SOURCE) add_cd_file(TARGET secur32 DESTINATION reactos/system32 FOR all) diff --git a/reactos/dll/win32/secur32/precomp.h b/reactos/dll/win32/secur32/precomp.h index 427b1e0d5b3..a57daeaa66a 100644 --- a/reactos/dll/win32/secur32/precomp.h +++ b/reactos/dll/win32/secur32/precomp.h @@ -17,10 +17,15 @@ #define COM_NO_WINDOWS_H #include #include +#include +#include #define NTOS_MODE_USER #include #include #include +#include "secur32_priv.h" +#include "thunks.h" + #endif /* _SECUR32_PCH_ */ diff --git a/reactos/dll/win32/secur32/secur32.spec b/reactos/dll/win32/secur32/secur32.spec index 8ccc0ddd7c0..d08ae79ef9f 100644 --- a/reactos/dll/win32/secur32/secur32.spec +++ b/reactos/dll/win32/secur32/secur32.spec @@ -5,8 +5,7 @@ @ stdcall AddCredentialsW(ptr wstr wstr long ptr ptr ptr ptr) @ stdcall AddSecurityPackageA(str ptr) @ stdcall AddSecurityPackageW(wstr ptr) -@ stdcall ApplyControlTokenA(ptr ptr) -@ stdcall ApplyControlToken(ptr ptr) ApplyControlTokenW +@ stdcall ApplyControlToken(ptr ptr) @ stdcall CompleteAuthToken(ptr ptr) @ stub CredMarshalTargetInfo @ stub CredUnmarshalTargetInfo diff --git a/reactos/dll/win32/secur32/secur32_priv.h b/reactos/dll/win32/secur32/secur32_priv.h new file mode 100644 index 00000000000..6c675ae43c8 --- /dev/null +++ b/reactos/dll/win32/secur32/secur32_priv.h @@ -0,0 +1,57 @@ +/* + * secur32 private definitions. + * + * Copyright (C) 2004 Juan Lang + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __SECUR32_PRIV_H__ +#define __SECUR32_PRIV_H__ + +#include + +typedef struct _SecureProvider +{ + struct list entry; + BOOL loaded; + PWSTR moduleName; + HMODULE lib; + SecurityFunctionTableA fnTableA; + SecurityFunctionTableW fnTableW; +} SecureProvider; + +typedef struct _SecurePackage +{ + struct list entry; + SecPkgInfoW infoW; + SecureProvider *provider; +} SecurePackage; + +/* Tries to find the package named packageName. If it finds it, implicitly + * loads the package if it isn't already loaded. + */ +SecurePackage *SECUR32_findPackageW(PCWSTR packageName) DECLSPEC_HIDDEN; + +/* Tries to find the package named packageName. (Thunks to _findPackageW) + */ +SecurePackage *SECUR32_findPackageA(PCSTR packageName) DECLSPEC_HIDDEN; + +/* A few string helpers; will return NULL if str is NULL. Free return with + * HeapFree */ +PWSTR SECUR32_AllocWideFromMultiByte(PCSTR str) DECLSPEC_HIDDEN; +PSTR SECUR32_AllocMultiByteFromWide(PCWSTR str) DECLSPEC_HIDDEN; + +#endif /* ndef __SECUR32_PRIV_H__ */ diff --git a/reactos/dll/win32/secur32/sspi.c b/reactos/dll/win32/secur32/sspi.c index 5cb902f26d9..670d8b4851f 100644 --- a/reactos/dll/win32/secur32/sspi.c +++ b/reactos/dll/win32/secur32/sspi.c @@ -1,10 +1,53 @@ +/* Copyright (C) 2004 Juan Lang + * + * This file implements loading of SSP DLLs. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + #include "precomp.h" -#define NDEBUG -#include +#include + +#include +WINE_DEFAULT_DEBUG_CHANNEL(secur32); -SECURITY_STATUS WINAPI ApplyControlTokenW(PCtxtHandle Handle, PSecBufferDesc Buffer); -SECURITY_STATUS WINAPI ApplyControlTokenA(PCtxtHandle Handle, PSecBufferDesc Buffer); +typedef struct _SecurePackageTable +{ + DWORD numPackages; + DWORD numAllocated; + struct list table; +} SecurePackageTable; + +typedef struct _SecureProviderTable +{ + DWORD numProviders; + DWORD numAllocated; + struct list table; +} SecureProviderTable; + +static CRITICAL_SECTION cs; +static CRITICAL_SECTION_DEBUG cs_debug = +{ + 0, 0, &cs, + { &cs_debug.ProcessLocksList, &cs_debug.ProcessLocksList }, + 0, 0, { (DWORD_PTR)(__FILE__ ": cs") } +}; +static CRITICAL_SECTION cs = { &cs_debug, -1, 0, 0, 0, 0 }; +static SecurePackageTable *packageTable = NULL; +static SecureProviderTable *providerTable = NULL; static SecurityFunctionTableA securityFunctionTableA = { @@ -18,7 +61,7 @@ static SecurityFunctionTableA securityFunctionTableA = AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, - ApplyControlTokenA, + ApplyControlToken, QueryContextAttributesA, ImpersonateSecurityContext, RevertSecurityContext, @@ -50,7 +93,7 @@ static SecurityFunctionTableW securityFunctionTableW = AcceptSecurityContext, CompleteAuthToken, DeleteSecurityContext, - ApplyControlTokenW, + ApplyControlToken, QueryContextAttributesW, ImpersonateSecurityContext, RevertSecurityContext, @@ -70,52 +113,167 @@ static SecurityFunctionTableW securityFunctionTableW = NULL }; -SECURITY_STATUS -WINAPI -EnumerateSecurityPackagesW ( - PULONG pcPackages, - PSecPkgInfoW* ppPackageInfo - ) +/*********************************************************************** + * EnumerateSecurityPackagesW (SECUR32.@) + */ +SECURITY_STATUS WINAPI EnumerateSecurityPackagesW(PULONG pcPackages, + PSecPkgInfoW *ppPackageInfo) { SECURITY_STATUS ret = SEC_E_OK; + TRACE("(%p, %p)\n", pcPackages, ppPackageInfo); + + /* windows just crashes if pcPackages or ppPackageInfo is NULL, so will I */ *pcPackages = 0; - *ppPackageInfo = NULL; - /* + EnterCriticalSection(&cs); if (packageTable) { + SecurePackage *package; + size_t bytesNeeded; + bytesNeeded = packageTable->numPackages * sizeof(SecPkgInfoW); + LIST_FOR_EACH_ENTRY(package, &packageTable->table, SecurePackage, entry) + { + if (package->infoW.Name) + bytesNeeded += (lstrlenW(package->infoW.Name) + 1) * sizeof(WCHAR); + if (package->infoW.Comment) + bytesNeeded += (lstrlenW(package->infoW.Comment) + 1) * sizeof(WCHAR); + } + if (bytesNeeded) + { + *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); + if (*ppPackageInfo) + { + ULONG i = 0; + PWSTR nextString; + + *pcPackages = packageTable->numPackages; + nextString = (PWSTR)((PBYTE)*ppPackageInfo + + packageTable->numPackages * sizeof(SecPkgInfoW)); + LIST_FOR_EACH_ENTRY(package, &packageTable->table, SecurePackage, entry) + { + PSecPkgInfoW pkgInfo = *ppPackageInfo + i++; + + *pkgInfo = package->infoW; + if (package->infoW.Name) + { + TRACE("Name[%d] = %S\n", i - 1, package->infoW.Name); + pkgInfo->Name = nextString; + lstrcpyW(nextString, package->infoW.Name); + nextString += lstrlenW(nextString) + 1; + } + else + pkgInfo->Name = NULL; + if (package->infoW.Comment) + { + TRACE("Comment[%d] = %S\n", i - 1, package->infoW.Comment); + pkgInfo->Comment = nextString; + lstrcpyW(nextString, package->infoW.Comment); + nextString += lstrlenW(nextString) + 1; + } + else + pkgInfo->Comment = NULL; + } + } + else + ret = SEC_E_INSUFFICIENT_MEMORY; + } } - */ + LeaveCriticalSection(&cs); + TRACE("<-- 0x%08x\n", ret); + return ret; +} - UNIMPLEMENTED; +/* Converts info (which is assumed to be an array of cPackages SecPkgInfoW + * structures) into an array of SecPkgInfoA structures, which it returns. + */ +static PSecPkgInfoA thunk_PSecPkgInfoWToA(ULONG cPackages, + const SecPkgInfoW *info) +{ + PSecPkgInfoA ret; + + if (info) + { + size_t bytesNeeded = cPackages * sizeof(SecPkgInfoA); + ULONG i; + + for (i = 0; i < cPackages; i++) + { + if (info[i].Name) + bytesNeeded += WideCharToMultiByte(CP_ACP, 0, info[i].Name, + -1, NULL, 0, NULL, NULL); + if (info[i].Comment) + bytesNeeded += WideCharToMultiByte(CP_ACP, 0, info[i].Comment, + -1, NULL, 0, NULL, NULL); + } + ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); + if (ret) + { + PSTR nextString; + + nextString = (PSTR)((PBYTE)ret + cPackages * sizeof(SecPkgInfoA)); + for (i = 0; i < cPackages; i++) + { + PSecPkgInfoA pkgInfo = ret + i; + int bytes; + + memcpy(pkgInfo, &info[i], sizeof(SecPkgInfoA)); + if (info[i].Name) + { + pkgInfo->Name = nextString; + /* just repeat back to WideCharToMultiByte how many bytes + * it requires, since we asked it earlier + */ + bytes = WideCharToMultiByte(CP_ACP, 0, info[i].Name, -1, + NULL, 0, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, info[i].Name, -1, + pkgInfo->Name, bytes, NULL, NULL); + nextString += lstrlenA(nextString) + 1; + } + else + pkgInfo->Name = NULL; + if (info[i].Comment) + { + pkgInfo->Comment = nextString; + /* just repeat back to WideCharToMultiByte how many bytes + * it requires, since we asked it earlier + */ + bytes = WideCharToMultiByte(CP_ACP, 0, info[i].Comment, -1, + NULL, 0, NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, info[i].Comment, -1, + pkgInfo->Comment, bytes, NULL, NULL); + nextString += lstrlenA(nextString) + 1; + } + else + pkgInfo->Comment = NULL; + } + } + } + else + ret = NULL; return ret; } -SECURITY_STATUS -WINAPI -EnumerateSecurityPackagesA( - PULONG pcPackages, - PSecPkgInfoA* ppPackageInfo - ) +/*********************************************************************** + * EnumerateSecurityPackagesA (SECUR32.@) + */ +SECURITY_STATUS WINAPI EnumerateSecurityPackagesA(PULONG pcPackages, + PSecPkgInfoA *ppPackageInfo) { SECURITY_STATUS ret; - PSecPkgInfoW info = NULL; + PSecPkgInfoW info; ret = EnumerateSecurityPackagesW(pcPackages, &info); if (ret == SEC_E_OK && *pcPackages && info) { - /* *ppPackageInfo = thunk_PSecPkgInfoWToA(*pcPackages, info); + *ppPackageInfo = thunk_PSecPkgInfoWToA(*pcPackages, info); if (*pcPackages && !*ppPackageInfo) { *pcPackages = 0; ret = SEC_E_INSUFFICIENT_MEMORY; - } */ + } FreeContextBuffer(info); } - *ppPackageInfo = NULL; - UNIMPLEMENTED; - return ret; } @@ -129,461 +287,543 @@ FreeContextBuffer ( return SEC_E_OK; } -SECURITY_STATUS -WINAPI -FreeCredentialsHandle(PCredHandle Handle) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} - -SECURITY_STATUS -WINAPI -DeleteSecurityContext(PCtxtHandle Handle) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} - PSecurityFunctionTableW WINAPI InitSecurityInterfaceW(VOID) { - DPRINT("InitSecurityInterfaceW() called\n"); + TRACE("InitSecurityInterfaceW() called\n"); return &securityFunctionTableW; } -SECURITY_STATUS +PSecurityFunctionTableA WINAPI -EncryptMessage(PCtxtHandle Handle, - ULONG Foo, - PSecBufferDesc Buffer, - ULONG Bar) +InitSecurityInterfaceA(VOID) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + TRACE("InitSecurityInterfaceA() called\n"); + return &securityFunctionTableA; } -SECURITY_STATUS +BOOLEAN WINAPI -DecryptMessage(PCtxtHandle Handle, - PSecBufferDesc Buffer, - ULONG Foo, - PULONG Bar) +TranslateNameA( + LPCSTR lpAccountName, + EXTENDED_NAME_FORMAT AccountNameFormat, + EXTENDED_NAME_FORMAT DesiredNameFormat, + LPSTR lpTranslatedName, + PULONG nSize +) { UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + return FALSE; } -SECURITY_STATUS +BOOLEAN WINAPI -ApplyControlTokenW(PCtxtHandle Handle, - PSecBufferDesc Buffer) +TranslateNameW( + LPCWSTR lpAccountName, + EXTENDED_NAME_FORMAT AccountNameFormat, + EXTENDED_NAME_FORMAT DesiredNameFormat, + LPWSTR lpTranslatedName, + PULONG nSize +) { UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + return FALSE; } -SECURITY_STATUS -WINAPI -ApplyControlTokenA(PCtxtHandle Handle, - PSecBufferDesc Buffer) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} +/*** PRIVATE FUNCTIONS ***************************************************************************/ -SECURITY_STATUS -WINAPI -CompleteAuthToken(PCtxtHandle Handle, - PSecBufferDesc Buffer) +static PWSTR SECUR32_strdupW(PCWSTR str) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + PWSTR ret; + + if (str) + { + ret = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(str) + 1) * sizeof(WCHAR)); + if (ret) + lstrcpyW(ret, str); + } + else + ret = NULL; + return ret; } -SECURITY_STATUS -WINAPI -QueryContextAttributesA(PCtxtHandle Handle, - ULONG Foo, - PVOID Bar) +PWSTR SECUR32_AllocWideFromMultiByte(PCSTR str) { - UNIMPLEMENTED; + PWSTR ret; - if (Handle) - { - Bar = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } + if (str) + { + int charsNeeded = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); - return SEC_E_INVALID_HANDLE; + if (charsNeeded) + { + ret = HeapAlloc(GetProcessHeap(), 0, charsNeeded * sizeof(WCHAR)); + if (ret) + MultiByteToWideChar(CP_ACP, 0, str, -1, ret, charsNeeded); + } + else + ret = NULL; + } + else + ret = NULL; + return ret; } -SECURITY_STATUS -WINAPI -QueryContextAttributesW(PCtxtHandle Handle, - ULONG Foo, - PVOID Bar) +PSTR SECUR32_AllocMultiByteFromWide(PCWSTR str) { - UNIMPLEMENTED; + PSTR ret; - if (Handle) - { - Bar = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } + if (str) + { + int charsNeeded = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, + NULL, NULL); - return SEC_E_INVALID_HANDLE; + if (charsNeeded) + { + ret = HeapAlloc(GetProcessHeap(), 0, charsNeeded); + if (ret) + WideCharToMultiByte(CP_ACP, 0, str, -1, ret, charsNeeded, + NULL, NULL); + } + else + ret = NULL; + } + else + ret = NULL; + return ret; } -SECURITY_STATUS -WINAPI -AcquireCredentialsHandleA ( - SEC_CHAR* pszPrincipal, - SEC_CHAR* pszPackage, - ULONG fUsage, - PLUID pID, - PVOID pAuth, - SEC_GET_KEY_FN pGetKeyFn, - PVOID pvGetKeyArgument, - PCredHandle phCred, - PTimeStamp pExpires - ) +static void _makeFnTableA(PSecurityFunctionTableA fnTableA, + const SecurityFunctionTableA *inFnTableA, + const SecurityFunctionTableW *inFnTableW) { - UNIMPLEMENTED; - - if (pszPackage) - { - phCred = NULL; - pExpires = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } - - return SEC_E_SECPKG_NOT_FOUND; + if (fnTableA) + { + if (inFnTableA) + { + /* The size of the version 1 table is based on platform sdk's + * sspi.h, though the sample ssp also provided with platform sdk + * implies only functions through QuerySecurityPackageInfoA are + * implemented (yikes) + */ + size_t tableSize = inFnTableA->dwVersion == 1 ? + (const BYTE *)&inFnTableA->SetContextAttributesA - + (const BYTE *)inFnTableA : sizeof(SecurityFunctionTableA); + + memcpy(fnTableA, inFnTableA, tableSize); + /* override this, since we can do it internally anyway */ + fnTableA->QuerySecurityPackageInfoA = + QuerySecurityPackageInfoA; + } + else if (inFnTableW) + { + /* functions with thunks */ + if (inFnTableW->AcquireCredentialsHandleW) + fnTableA->AcquireCredentialsHandleA = + thunk_AcquireCredentialsHandleA; + if (inFnTableW->InitializeSecurityContextW) + fnTableA->InitializeSecurityContextA = + thunk_InitializeSecurityContextA; + if (inFnTableW->ImportSecurityContextW) + fnTableA->ImportSecurityContextA = + thunk_ImportSecurityContextA; + if (inFnTableW->AddCredentialsW) + fnTableA->AddCredentialsA = + thunk_AddCredentialsA; + if (inFnTableW->QueryCredentialsAttributesW) + fnTableA->QueryCredentialsAttributesA = + thunk_QueryCredentialsAttributesA; + if (inFnTableW->QueryContextAttributesW) + fnTableA->QueryContextAttributesA = + thunk_QueryContextAttributesA; + if (inFnTableW->SetContextAttributesW) + fnTableA->SetContextAttributesA = + thunk_SetContextAttributesA; + /* this can't be thunked, there's no extra param to know which + * package to forward to */ + fnTableA->EnumerateSecurityPackagesA = NULL; + /* functions with no thunks needed */ + fnTableA->AcceptSecurityContext = inFnTableW->AcceptSecurityContext; + fnTableA->CompleteAuthToken = inFnTableW->CompleteAuthToken; + fnTableA->DeleteSecurityContext = inFnTableW->DeleteSecurityContext; + fnTableA->ImpersonateSecurityContext = + inFnTableW->ImpersonateSecurityContext; + fnTableA->RevertSecurityContext = inFnTableW->RevertSecurityContext; + fnTableA->MakeSignature = inFnTableW->MakeSignature; + fnTableA->VerifySignature = inFnTableW->VerifySignature; + fnTableA->FreeContextBuffer = inFnTableW->FreeContextBuffer; + fnTableA->QuerySecurityPackageInfoA = + QuerySecurityPackageInfoA; + fnTableA->ExportSecurityContext = + inFnTableW->ExportSecurityContext; + fnTableA->QuerySecurityContextToken = + inFnTableW->QuerySecurityContextToken; + fnTableA->EncryptMessage = inFnTableW->EncryptMessage; + fnTableA->DecryptMessage = inFnTableW->DecryptMessage; + } + } } -SECURITY_STATUS -WINAPI -AcquireCredentialsHandleW ( - SEC_WCHAR* pszPrincipal, - SEC_WCHAR* pszPackage, - ULONG fUsage, - PLUID pID, - PVOID pAuth, - SEC_GET_KEY_FN pGetKeyFn, - PVOID pvGetKeyArgument, - PCredHandle phCred, - PTimeStamp pExpires - ) +static void _makeFnTableW(PSecurityFunctionTableW fnTableW, + const SecurityFunctionTableA *inFnTableA, + const SecurityFunctionTableW *inFnTableW) { - UNIMPLEMENTED; - - if (pszPackage) - { - phCred = NULL; - pExpires = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } - - return SEC_E_SECPKG_NOT_FOUND; + if (fnTableW) + { + if (inFnTableW) + { + /* The size of the version 1 table is based on platform sdk's + * sspi.h, though the sample ssp also provided with platform sdk + * implies only functions through QuerySecurityPackageInfoA are + * implemented (yikes) + */ + size_t tableSize = inFnTableW->dwVersion == 1 ? + (const BYTE *)&inFnTableW->SetContextAttributesW - + (const BYTE *)inFnTableW : sizeof(SecurityFunctionTableW); + + memcpy(fnTableW, inFnTableW, tableSize); + /* override this, since we can do it internally anyway */ + fnTableW->QuerySecurityPackageInfoW = + QuerySecurityPackageInfoW; + } + else if (inFnTableA) + { + /* functions with thunks */ + if (inFnTableA->AcquireCredentialsHandleA) + fnTableW->AcquireCredentialsHandleW = + thunk_AcquireCredentialsHandleW; + if (inFnTableA->InitializeSecurityContextA) + fnTableW->InitializeSecurityContextW = + thunk_InitializeSecurityContextW; + if (inFnTableA->ImportSecurityContextA) + fnTableW->ImportSecurityContextW = + thunk_ImportSecurityContextW; + if (inFnTableA->AddCredentialsA) + fnTableW->AddCredentialsW = + thunk_AddCredentialsW; + if (inFnTableA->QueryCredentialsAttributesA) + fnTableW->QueryCredentialsAttributesW = + thunk_QueryCredentialsAttributesW; + if (inFnTableA->QueryContextAttributesA) + fnTableW->QueryContextAttributesW = + thunk_QueryContextAttributesW; + if (inFnTableA->SetContextAttributesA) + fnTableW->SetContextAttributesW = + thunk_SetContextAttributesW; + /* this can't be thunked, there's no extra param to know which + * package to forward to */ + fnTableW->EnumerateSecurityPackagesW = NULL; + /* functions with no thunks needed */ + fnTableW->AcceptSecurityContext = inFnTableA->AcceptSecurityContext; + fnTableW->CompleteAuthToken = inFnTableA->CompleteAuthToken; + fnTableW->DeleteSecurityContext = inFnTableA->DeleteSecurityContext; + fnTableW->ImpersonateSecurityContext = + inFnTableA->ImpersonateSecurityContext; + fnTableW->RevertSecurityContext = inFnTableA->RevertSecurityContext; + fnTableW->MakeSignature = inFnTableA->MakeSignature; + fnTableW->VerifySignature = inFnTableA->VerifySignature; + fnTableW->FreeContextBuffer = inFnTableA->FreeContextBuffer; + fnTableW->QuerySecurityPackageInfoW = + QuerySecurityPackageInfoW; + fnTableW->ExportSecurityContext = + inFnTableA->ExportSecurityContext; + fnTableW->QuerySecurityContextToken = + inFnTableA->QuerySecurityContextToken; + fnTableW->EncryptMessage = inFnTableA->EncryptMessage; + fnTableW->DecryptMessage = inFnTableA->DecryptMessage; + } + } } -SECURITY_STATUS -WINAPI -InitializeSecurityContextW ( - PCredHandle phCred, - PCtxtHandle phContext, - SEC_WCHAR* pszTarget, - ULONG fContextReq, - ULONG Reserved, - ULONG TargetData, - PSecBufferDesc pInput, - ULONG Reserved2, - PCtxtHandle phNewContext, - PSecBufferDesc pOut, - PULONG pfContextAttributes, - PTimeStamp pExpires - ) +static void _copyPackageInfo(PSecPkgInfoW info, const SecPkgInfoA *inInfoA, + const SecPkgInfoW *inInfoW) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + if (info && (inInfoA || inInfoW)) + { + /* odd, I know, but up until Name and Comment the structures are + * identical + */ + memcpy(info, inInfoW ? inInfoW : (const SecPkgInfoW *)inInfoA, sizeof(*info)); + if (inInfoW) + { + info->Name = SECUR32_strdupW(inInfoW->Name); + info->Comment = SECUR32_strdupW(inInfoW->Comment); + } + else + { + info->Name = SECUR32_AllocWideFromMultiByte(inInfoA->Name); + info->Comment = SECUR32_AllocWideFromMultiByte(inInfoA->Comment); + } + } } -SECURITY_STATUS -WINAPI -InitializeSecurityContextA ( - PCredHandle phCred, - PCtxtHandle phContext, - SEC_CHAR* pszTarget, - ULONG fContextReq, - ULONG Reserved, - ULONG TargetData, - PSecBufferDesc pInput, - ULONG Reserved2, - PCtxtHandle phNewContext, - PSecBufferDesc pOut, - PULONG pfContextAttributes, - PTimeStamp pExpires - ) +static +SecureProvider *SECUR32_addProvider(const SecurityFunctionTableA *fnTableA, + const SecurityFunctionTableW *fnTableW, PCWSTR moduleName) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + SecureProvider *ret; + EnterCriticalSection(&cs); -SECURITY_STATUS -SEC_ENTRY -MakeSignature( - PCtxtHandle phContext, - ULONG fQOP, - PSecBufferDesc pMessage, - ULONG MessageSeqNo - ) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + if (!providerTable) + { + providerTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SecureProviderTable)); + if (!providerTable) + { + LeaveCriticalSection(&cs); + return NULL; + } + list_init(&providerTable->table); + } -SECURITY_STATUS -SEC_ENTRY -VerifySignature( - PCtxtHandle phContext, - PSecBufferDesc pMessage, - ULONG MessageSeqNo, - PULONG pfQOP - ) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + ret = HeapAlloc(GetProcessHeap(), 0, sizeof(SecureProvider)); + if (!ret) + { + LeaveCriticalSection(&cs); + return NULL; + } -SECURITY_STATUS -SEC_ENTRY -QuerySecurityPackageInfoA( - SEC_CHAR* pszPackageName, - PSecPkgInfoA* ppPackageInfo -) -{ - UNIMPLEMENTED; + list_add_tail(&providerTable->table, &ret->entry); + ret->lib = NULL; - if (pszPackageName) - { - *ppPackageInfo = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } - return SEC_E_SECPKG_NOT_FOUND; + if (fnTableA || fnTableW) + { + ret->moduleName = moduleName ? SECUR32_strdupW(moduleName) : NULL; + _makeFnTableA(&ret->fnTableA, fnTableA, fnTableW); + _makeFnTableW(&ret->fnTableW, fnTableA, fnTableW); + ret->loaded = !moduleName; + } + else + { + ret->moduleName = SECUR32_strdupW(moduleName); + ret->loaded = FALSE; + } + + LeaveCriticalSection(&cs); + return ret; } -SECURITY_STATUS -SEC_ENTRY -QuerySecurityPackageInfoW( - SEC_WCHAR* pszPackageName, - PSecPkgInfoW* ppPackageInfo -) +static +void SECUR32_addPackages(SecureProvider *provider, ULONG toAdd, + const SecPkgInfoA *infoA, const SecPkgInfoW *infoW) { - UNIMPLEMENTED; + ULONG i; - if (pszPackageName) - { - *ppPackageInfo = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } - return SEC_E_SECPKG_NOT_FOUND; -} + assert(provider); + assert(infoA || infoW); -SECURITY_STATUS -WINAPI -AcceptSecurityContext( - PCredHandle phCredential, - PCtxtHandle phContext, - PSecBufferDesc pInput, - ULONG fContextReq, - ULONG TargetDataRep, - PCtxtHandle phNewContext, - PSecBufferDesc pOutput, - ULONG *pfContextAttr, - PTimeStamp ptsExpiry -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + EnterCriticalSection(&cs); -SECURITY_STATUS -WINAPI -AddCredentialsA( - PCredHandle hCredentials, - SEC_CHAR *pszPrincipal, - SEC_CHAR *pszPackage, - ULONG fCredentialUse, - LPVOID pAuthData, - SEC_GET_KEY_FN pGetKeyFn, - LPVOID pvGetKeyArgument, - PTimeStamp ptsExpiry -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + if (!packageTable) + { + packageTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SecurePackageTable)); + if (!packageTable) + { + LeaveCriticalSection(&cs); + return; + } -SECURITY_STATUS -WINAPI -AddCredentialsW( - PCredHandle hCredentials, - SEC_WCHAR *pszPrincipal, - SEC_WCHAR *pszPackage, - ULONG fCredentialUse, - LPVOID pAuthData, - SEC_GET_KEY_FN pGetKeyFn, - LPVOID pvGetKeyArgument, - PTimeStamp ptsExpiry -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + packageTable->numPackages = 0; + list_init(&packageTable->table); + } -SECURITY_STATUS -WINAPI -ExportSecurityContext( - PCtxtHandle phContext, - ULONG fFlags, - PSecBuffer pPackedContext, - LPVOID *pToken -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + for (i = 0; i < toAdd; i++) + { + SecurePackage *package = HeapAlloc(GetProcessHeap(), 0, sizeof(SecurePackage)); + if (!package) + continue; -SECURITY_STATUS -WINAPI -ImpersonateSecurityContext( - PCtxtHandle phContext -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + list_add_tail(&packageTable->table, &package->entry); -SECURITY_STATUS -WINAPI -ImportSecurityContextA( - SEC_CHAR *pszPackage, - PSecBuffer pPackedContext, - LPVOID Token, - PCtxtHandle phContext -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + package->provider = provider; + _copyPackageInfo(&package->infoW, + infoA ? &infoA[i] : NULL, + infoW ? &infoW[i] : NULL); + } + packageTable->numPackages += toAdd; + + LeaveCriticalSection(&cs); } -SECURITY_STATUS -WINAPI -ImportSecurityContextW( - SEC_WCHAR *pszPackage, - PSecBuffer pPackedContext, - LPVOID Token, - PCtxtHandle phContext -) +static void _tryLoadProvider(PWSTR moduleName) { - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + HMODULE lib = LoadLibraryW(moduleName); + + if (lib) + { + INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW = + (INIT_SECURITY_INTERFACE_W)GetProcAddress(lib, + SECURITY_ENTRYPOINT_ANSIW); + INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA = + (INIT_SECURITY_INTERFACE_A)GetProcAddress(lib, + SECURITY_ENTRYPOINT_ANSIA); + + TRACE("loaded %S, InitSecurityInterfaceA is %p, InitSecurityInterfaceW is %p\n", + moduleName, pInitSecurityInterfaceA, + pInitSecurityInterfaceW); + if (pInitSecurityInterfaceW || pInitSecurityInterfaceA) + { + PSecurityFunctionTableA fnTableA = NULL; + PSecurityFunctionTableW fnTableW = NULL; + ULONG toAdd = 0; + PSecPkgInfoA infoA = NULL; + PSecPkgInfoW infoW = NULL; + SECURITY_STATUS ret = SEC_E_OK; + + if (pInitSecurityInterfaceA) + fnTableA = pInitSecurityInterfaceA(); + if (pInitSecurityInterfaceW) + fnTableW = pInitSecurityInterfaceW(); + if (fnTableW && fnTableW->EnumerateSecurityPackagesW) + { + if (fnTableW != &securityFunctionTableW) + ret = fnTableW->EnumerateSecurityPackagesW(&toAdd, &infoW); + else + TRACE("%S has built-in providers, skip adding\n", moduleName); + } + else if (fnTableA && fnTableA->EnumerateSecurityPackagesA) + { + if (fnTableA != &securityFunctionTableA) + ret = fnTableA->EnumerateSecurityPackagesA(&toAdd, &infoA); + else + TRACE("%S has built-in providers, skip adding\n", moduleName); + } + if (ret == SEC_E_OK && toAdd > 0 && (infoW || infoA)) + { + SecureProvider *provider = SECUR32_addProvider(NULL, NULL, + moduleName); + + if (provider) + SECUR32_addPackages(provider, toAdd, infoA, infoW); + if (infoW) + fnTableW->FreeContextBuffer(infoW); + else + fnTableA->FreeContextBuffer(infoA); + } + } + FreeLibrary(lib); + } + else + WARN("failed to load %S\n", moduleName); } -SECURITY_STATUS -WINAPI -QueryCredentialsAttributesA( - PCredHandle phCredential, - ULONG ulAttribute, - LPVOID pBuffer -) +static const WCHAR securityProvidersKeyW[] = { + 'S','Y','S','T','E','M','\\','C','u','r','r','e','n','t','C','o','n','t','r', + 'o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','S','e','c','u','r', + 'i','t','y','P','r','o','v','i','d','e','r','s','\0' + }; +static const WCHAR securityProvidersW[] = { + 'S','e','c','u','r','i','t','y','P','r','o','v','i','d','e','r','s',0 + }; + +static void SECUR32_initializeProviders(void) { - UNIMPLEMENTED; + HKEY key; + LSTATUS apiRet; - if (phCredential) - { - pBuffer = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } + /* Now load providers from registry */ + apiRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, securityProvidersKeyW, 0, + KEY_READ, &key); + if (apiRet == ERROR_SUCCESS) + { + WCHAR securityPkgNames[MAX_PATH]; /* arbitrary len */ + DWORD size = sizeof(securityPkgNames) / sizeof(WCHAR), type; - return SEC_E_INVALID_HANDLE; + apiRet = RegQueryValueExW(key, securityProvidersW, NULL, &type, + (PBYTE)securityPkgNames, &size); + if (apiRet == ERROR_SUCCESS && type == REG_SZ) + { + WCHAR *ptr; + + size = size / sizeof(WCHAR); + for (ptr = securityPkgNames; + ptr < securityPkgNames + size; ) + { + WCHAR *comma; + + for (comma = ptr; *comma && *comma != ','; comma++) + ; + if (*comma == ',') + *comma = '\0'; + for (; *ptr && isspace(*ptr) && ptr < securityPkgNames + size; + ptr++) + ; + if (*ptr) + _tryLoadProvider(ptr); + ptr += lstrlenW(ptr) + 1; + } + } + RegCloseKey(key); + } } -SECURITY_STATUS -WINAPI -QueryCredentialsAttributesW( - PCredHandle phCredential, - ULONG ulAttribute, - LPVOID pBuffer -) +SecurePackage *SECUR32_findPackageW(PCWSTR packageName) { - UNIMPLEMENTED; + SecurePackage *ret = NULL; + BOOL matched = FALSE; - if (phCredential) - { - pBuffer = NULL; - return ERROR_CALL_NOT_IMPLEMENTED; - } + if (!packageTable) + SECUR32_initializeProviders(); - return SEC_E_INVALID_HANDLE; -} + if (packageTable && packageName) + { + LIST_FOR_EACH_ENTRY(ret, &packageTable->table, SecurePackage, entry) + { + matched = !lstrcmpiW(ret->infoW.Name, packageName); + if (matched) + break; + } -SECURITY_STATUS -WINAPI -QuerySecurityContextToken( - PCtxtHandle phContext, - PHANDLE phToken -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; -} + if (!matched) + return NULL; -SECURITY_STATUS -WINAPI -RevertSecurityContext( - PCtxtHandle phContext -) -{ - UNIMPLEMENTED; - return ERROR_CALL_NOT_IMPLEMENTED; + if (ret->provider && !ret->provider->loaded) + { + ret->provider->lib = LoadLibraryW(ret->provider->moduleName); + if (ret->provider->lib) + { + INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW = + (INIT_SECURITY_INTERFACE_W) GetProcAddress(ret->provider->lib, + SECURITY_ENTRYPOINT_ANSIW); + INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA = + (INIT_SECURITY_INTERFACE_A) GetProcAddress(ret->provider->lib, + SECURITY_ENTRYPOINT_ANSIA); + PSecurityFunctionTableA fnTableA = NULL; + PSecurityFunctionTableW fnTableW = NULL; + + if (pInitSecurityInterfaceA) + fnTableA = pInitSecurityInterfaceA(); + if (pInitSecurityInterfaceW) + fnTableW = pInitSecurityInterfaceW(); + /* don't update built-in SecurityFunctionTable */ + if (fnTableA != &securityFunctionTableA) + _makeFnTableA(&ret->provider->fnTableA, fnTableA, fnTableW); + if (fnTableW != &securityFunctionTableW) + _makeFnTableW(&ret->provider->fnTableW, fnTableA, fnTableW); + ret->provider->loaded = TRUE; + } + else + ret = NULL; + } + } + return ret; } -PSecurityFunctionTableA -WINAPI -InitSecurityInterfaceA(VOID) +SecurePackage *SECUR32_findPackageA(PCSTR packageName) { - DPRINT("InitSecurityInterfaceA() called\n"); - return &securityFunctionTableA; -} + SecurePackage *ret; -BOOLEAN -WINAPI -TranslateNameA( - LPCSTR lpAccountName, - EXTENDED_NAME_FORMAT AccountNameFormat, - EXTENDED_NAME_FORMAT DesiredNameFormat, - LPSTR lpTranslatedName, - PULONG nSize -) -{ - UNIMPLEMENTED; - return FALSE; -} + if (packageName) + { + UNICODE_STRING package; -BOOLEAN -WINAPI -TranslateNameW( - LPCWSTR lpAccountName, - EXTENDED_NAME_FORMAT AccountNameFormat, - EXTENDED_NAME_FORMAT DesiredNameFormat, - LPWSTR lpTranslatedName, - PULONG nSize -) -{ - UNIMPLEMENTED; - return FALSE; + RtlCreateUnicodeStringFromAsciiz(&package, packageName); + ret = SECUR32_findPackageW(package.Buffer); + RtlFreeUnicodeString(&package); + } + else + ret = NULL; + return ret; } diff --git a/reactos/dll/win32/secur32/thunks.c b/reactos/dll/win32/secur32/thunks.c new file mode 100644 index 00000000000..6fc7258e0cc --- /dev/null +++ b/reactos/dll/win32/secur32/thunks.c @@ -0,0 +1,893 @@ +/* Copyright (C) 2004 Juan Lang + * + * This file implements thunks between wide char and multibyte functions for + * SSPs that only provide one or the other. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include "precomp.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(secur32); + +SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleA( + SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse, + PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal), + debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, + pvGetKeyArgument, phCredential, ptsExpiry); + if (pszPackage) + { + UNICODE_STRING principal, package; + + RtlCreateUnicodeStringFromAsciiz(&principal, pszPrincipal); + RtlCreateUnicodeStringFromAsciiz(&package, pszPackage); + ret = AcquireCredentialsHandleW(principal.Buffer, package.Buffer, + fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, + phCredential, ptsExpiry); + RtlFreeUnicodeString(&principal); + RtlFreeUnicodeString(&package); + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleW( + SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse, + PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal), + debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, + pvGetKeyArgument, phCredential, ptsExpiry); + if (pszPackage) + { + PSTR principal, package; + + principal = SECUR32_AllocMultiByteFromWide(pszPrincipal); + package = SECUR32_AllocMultiByteFromWide(pszPackage); + ret = AcquireCredentialsHandleA(principal, package, fCredentialsUse, + pvLogonID, pAuthData, pGetKeyFn, pvGetKeyArgument, phCredential, + ptsExpiry); + HeapFree(GetProcessHeap(), 0, principal); + HeapFree(GetProcessHeap(), 0, package); + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; +} + +/* thunking is pretty dicey for these--the output type depends on ulAttribute, + * so we have to know about every type the caller does + */ +SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesA( + PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer); + if (phCredential) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + PCredHandle cred = (PCredHandle)phCredential->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.QueryCredentialsAttributesW) + { + ret = package->provider->fnTableW.QueryCredentialsAttributesW( + cred, ulAttribute, pBuffer); + if (ret == SEC_E_OK) + { + switch (ulAttribute) + { + case SECPKG_CRED_ATTR_NAMES: + { + PSecPkgCredentials_NamesW names = + (PSecPkgCredentials_NamesW)pBuffer; + SEC_WCHAR *oldUser = names->sUserName; + + if (oldUser) + { + names->sUserName = + (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser); + package->provider->fnTableW.FreeContextBuffer( + oldUser); + } + break; + } + default: + WARN("attribute type %d unknown\n", ulAttribute); + ret = SEC_E_INTERNAL_ERROR; + } + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesW( + PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer); + if (phCredential) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + PCredHandle cred = (PCredHandle)phCredential->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableA.QueryCredentialsAttributesA) + { + ret = package->provider->fnTableA.QueryCredentialsAttributesA( + cred, ulAttribute, pBuffer); + if (ret == SEC_E_OK) + { + switch (ulAttribute) + { + case SECPKG_CRED_ATTR_NAMES: + { + PSecPkgCredentials_NamesA names = + (PSecPkgCredentials_NamesA)pBuffer; + SEC_CHAR *oldUser = names->sUserName; + + if (oldUser) + { + names->sUserName = + (PSTR)SECUR32_AllocWideFromMultiByte(oldUser); + package->provider->fnTableA.FreeContextBuffer( + oldUser); + } + break; + } + default: + WARN("attribute type %d unknown\n", ulAttribute); + ret = SEC_E_INTERNAL_ERROR; + } + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_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 %d %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) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + + if (package && package->provider) + { + if (package->provider->fnTableW.InitializeSecurityContextW) + { + UNICODE_STRING target; + + RtlCreateUnicodeStringFromAsciiz(&target, pszTargetName); + ret = package->provider->fnTableW.InitializeSecurityContextW( + phCredential, phContext, target.Buffer, fContextReq, Reserved1, + TargetDataRep, pInput, Reserved2, phNewContext, pOutput, + pfContextAttr, ptsExpiry); + RtlFreeUnicodeString(&target); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_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 %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) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + + if (package && package->provider) + { + if (package->provider->fnTableA.InitializeSecurityContextA) + { + PSTR target = SECUR32_AllocMultiByteFromWide(pszTargetName); + + ret = package->provider->fnTableA.InitializeSecurityContextA( + phCredential, phContext, target, fContextReq, Reserved1, + TargetDataRep, pInput, Reserved2, phNewContext, pOutput, + pfContextAttr, ptsExpiry); + HeapFree(GetProcessHeap(), 0, target); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsA(PCredHandle hCredentials, + SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, + void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, + PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal), + debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn, + pvGetKeyArgument, ptsExpiry); + if (hCredentials) + { + SecurePackage *package = (SecurePackage *)hCredentials->dwUpper; + PCredHandle cred = (PCtxtHandle)hCredentials->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.AddCredentialsW) + { + UNICODE_STRING szPrincipal, szPackage; + + RtlCreateUnicodeStringFromAsciiz(&szPrincipal, pszPrincipal); + RtlCreateUnicodeStringFromAsciiz(&szPackage, pszPackage); + ret = package->provider->fnTableW.AddCredentialsW( + cred, szPrincipal.Buffer, szPackage.Buffer, fCredentialUse, + pAuthData, pGetKeyFn, pvGetKeyArgument, ptsExpiry); + RtlFreeUnicodeString(&szPrincipal); + RtlFreeUnicodeString(&szPackage); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsW(PCredHandle hCredentials, + SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, + void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, + PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal), + debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn, + pvGetKeyArgument, ptsExpiry); + if (hCredentials) + { + SecurePackage *package = (SecurePackage *)hCredentials->dwUpper; + PCredHandle cred = (PCtxtHandle)hCredentials->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableA.AddCredentialsA) + { + PSTR szPrincipal = SECUR32_AllocMultiByteFromWide(pszPrincipal); + PSTR szPackage = SECUR32_AllocMultiByteFromWide(pszPackage); + + ret = package->provider->fnTableA.AddCredentialsA( + cred, szPrincipal, szPackage, fCredentialUse, pAuthData, + pGetKeyFn, pvGetKeyArgument, ptsExpiry); + HeapFree(GetProcessHeap(), 0, szPrincipal); + HeapFree(GetProcessHeap(), 0, szPackage); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +static PSecPkgInfoA _copyPackageInfoFlatWToA(const SecPkgInfoW *infoW) +{ + PSecPkgInfoA ret; + + if (infoW) + { + size_t bytesNeeded = sizeof(SecPkgInfoA); + int nameLen = 0, commentLen = 0; + + if (infoW->Name) + { + nameLen = WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1, + NULL, 0, NULL, NULL); + bytesNeeded += nameLen; + } + if (infoW->Comment) + { + commentLen = WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1, + NULL, 0, NULL, NULL); + bytesNeeded += commentLen; + } + ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); + if (ret) + { + PSTR nextString = (PSTR)((PBYTE)ret + sizeof(SecPkgInfoA)); + + memcpy(ret, infoW, sizeof(SecPkgInfoA)); + if (infoW->Name) + { + ret->Name = nextString; + WideCharToMultiByte(CP_ACP, 0, infoW->Name, -1, nextString, + nameLen, NULL, NULL); + nextString += nameLen; + } + else + ret->Name = NULL; + if (infoW->Comment) + { + ret->Comment = nextString; + WideCharToMultiByte(CP_ACP, 0, infoW->Comment, -1, nextString, + nameLen, NULL, NULL); + } + else + ret->Comment = NULL; + } + } + else + ret = NULL; + return ret; +} + +static SECURITY_STATUS thunk_ContextAttributesWToA(SecurePackage *package, + ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret = SEC_E_OK; + + if (package && pBuffer) + { + switch (ulAttribute) + { + case SECPKG_ATTR_NAMES: + { + PSecPkgContext_NamesW names = (PSecPkgContext_NamesW)pBuffer; + SEC_WCHAR *oldUser = names->sUserName; + + if (oldUser) + { + names->sUserName = + (PWSTR)SECUR32_AllocMultiByteFromWide(oldUser); + package->provider->fnTableW.FreeContextBuffer(oldUser); + } + break; + } + case SECPKG_ATTR_AUTHORITY: + { + PSecPkgContext_AuthorityW names = + (PSecPkgContext_AuthorityW)pBuffer; + SEC_WCHAR *oldAuth = names->sAuthorityName; + + if (oldAuth) + { + names->sAuthorityName = + (PWSTR)SECUR32_AllocMultiByteFromWide(oldAuth); + package->provider->fnTableW.FreeContextBuffer(oldAuth); + } + break; + } + case SECPKG_ATTR_KEY_INFO: + { + PSecPkgContext_KeyInfoW info = (PSecPkgContext_KeyInfoW)pBuffer; + SEC_WCHAR *oldSigAlgName = info->sSignatureAlgorithmName; + SEC_WCHAR *oldEncAlgName = info->sEncryptAlgorithmName; + + if (oldSigAlgName) + { + info->sSignatureAlgorithmName = + (PWSTR)SECUR32_AllocMultiByteFromWide(oldSigAlgName); + package->provider->fnTableW.FreeContextBuffer( + oldSigAlgName); + } + if (oldEncAlgName) + { + info->sEncryptAlgorithmName = + (PWSTR)SECUR32_AllocMultiByteFromWide(oldEncAlgName); + package->provider->fnTableW.FreeContextBuffer( + oldEncAlgName); + } + break; + } + case SECPKG_ATTR_PACKAGE_INFO: + { + PSecPkgContext_PackageInfoW info = + (PSecPkgContext_PackageInfoW)pBuffer; + PSecPkgInfoW oldPkgInfo = info->PackageInfo; + + if (oldPkgInfo) + { + info->PackageInfo = (PSecPkgInfoW) + _copyPackageInfoFlatWToA(oldPkgInfo); + package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); + } + break; + } + case SECPKG_ATTR_NEGOTIATION_INFO: + { + PSecPkgContext_NegotiationInfoW info = + (PSecPkgContext_NegotiationInfoW)pBuffer; + PSecPkgInfoW oldPkgInfo = info->PackageInfo; + + if (oldPkgInfo) + { + info->PackageInfo = (PSecPkgInfoW) + _copyPackageInfoFlatWToA(oldPkgInfo); + package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); + } + break; + } + case SECPKG_ATTR_NATIVE_NAMES: + { + PSecPkgContext_NativeNamesW names = + (PSecPkgContext_NativeNamesW)pBuffer; + PWSTR oldClient = names->sClientName; + PWSTR oldServer = names->sServerName; + + if (oldClient) + { + names->sClientName = (PWSTR)SECUR32_AllocMultiByteFromWide( + oldClient); + package->provider->fnTableW.FreeContextBuffer(oldClient); + } + if (oldServer) + { + names->sServerName = (PWSTR)SECUR32_AllocMultiByteFromWide( + oldServer); + package->provider->fnTableW.FreeContextBuffer(oldServer); + } + break; + } + case SECPKG_ATTR_CREDENTIAL_NAME: + { + PSecPkgContext_CredentialNameW name = + (PSecPkgContext_CredentialNameW)pBuffer; + PWSTR oldCred = name->sCredentialName; + + if (oldCred) + { + name->sCredentialName = + (PWSTR)SECUR32_AllocMultiByteFromWide(oldCred); + package->provider->fnTableW.FreeContextBuffer(oldCred); + } + break; + } + /* no thunking needed: */ + case SECPKG_ATTR_ACCESS_TOKEN: + case SECPKG_ATTR_DCE_INFO: + case SECPKG_ATTR_FLAGS: + case SECPKG_ATTR_LIFESPAN: + case SECPKG_ATTR_PASSWORD_EXPIRY: + case SECPKG_ATTR_SESSION_KEY: + case SECPKG_ATTR_SIZES: + case SECPKG_ATTR_STREAM_SIZES: + case SECPKG_ATTR_TARGET_INFORMATION: + break; + default: + WARN("attribute type %d unknown\n", ulAttribute); + ret = SEC_E_INTERNAL_ERROR; + } + } + else + ret = SEC_E_INVALID_TOKEN; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesA(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.QueryContextAttributesW) + { + ret = package->provider->fnTableW.QueryContextAttributesW( + ctxt, ulAttribute, pBuffer); + if (ret == SEC_E_OK) + ret = thunk_ContextAttributesWToA(package, ulAttribute, + pBuffer); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +static PSecPkgInfoW _copyPackageInfoFlatAToW(const SecPkgInfoA *infoA) +{ + PSecPkgInfoW ret; + + if (infoA) + { + size_t bytesNeeded = sizeof(SecPkgInfoW); + int nameLen = 0, commentLen = 0; + + if (infoA->Name) + { + nameLen = MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1, + NULL, 0); + bytesNeeded += nameLen * sizeof(WCHAR); + } + if (infoA->Comment) + { + commentLen = MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1, + NULL, 0); + bytesNeeded += commentLen * sizeof(WCHAR); + } + ret = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); + if (ret) + { + PWSTR nextString = (PWSTR)((PBYTE)ret + sizeof(SecPkgInfoW)); + + memcpy(ret, infoA, sizeof(SecPkgInfoA)); + if (infoA->Name) + { + ret->Name = nextString; + MultiByteToWideChar(CP_ACP, 0, infoA->Name, -1, nextString, + nameLen); + nextString += nameLen; + } + else + ret->Name = NULL; + if (infoA->Comment) + { + ret->Comment = nextString; + MultiByteToWideChar(CP_ACP, 0, infoA->Comment, -1, nextString, + commentLen); + } + else + ret->Comment = NULL; + } + } + else + ret = NULL; + return ret; +} + +static SECURITY_STATUS thunk_ContextAttributesAToW(SecurePackage *package, + ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret = SEC_E_OK; + + if (package && pBuffer) + { + switch (ulAttribute) + { + case SECPKG_ATTR_NAMES: + { + PSecPkgContext_NamesA names = (PSecPkgContext_NamesA)pBuffer; + SEC_CHAR *oldUser = names->sUserName; + + if (oldUser) + { + names->sUserName = + (PSTR)SECUR32_AllocWideFromMultiByte(oldUser); + package->provider->fnTableW.FreeContextBuffer(oldUser); + } + break; + } + case SECPKG_ATTR_AUTHORITY: + { + PSecPkgContext_AuthorityA names = + (PSecPkgContext_AuthorityA)pBuffer; + SEC_CHAR *oldAuth = names->sAuthorityName; + + if (oldAuth) + { + names->sAuthorityName = + (PSTR)SECUR32_AllocWideFromMultiByte(oldAuth); + package->provider->fnTableW.FreeContextBuffer(oldAuth); + } + break; + } + case SECPKG_ATTR_KEY_INFO: + { + PSecPkgContext_KeyInfoA info = (PSecPkgContext_KeyInfoA)pBuffer; + SEC_CHAR *oldSigAlgName = info->sSignatureAlgorithmName; + SEC_CHAR *oldEncAlgName = info->sEncryptAlgorithmName; + + if (oldSigAlgName) + { + info->sSignatureAlgorithmName = + (PSTR)SECUR32_AllocWideFromMultiByte(oldSigAlgName); + package->provider->fnTableW.FreeContextBuffer( + oldSigAlgName); + } + if (oldEncAlgName) + { + info->sEncryptAlgorithmName = + (PSTR)SECUR32_AllocWideFromMultiByte( + oldEncAlgName); + package->provider->fnTableW.FreeContextBuffer( + oldEncAlgName); + } + break; + } + case SECPKG_ATTR_PACKAGE_INFO: + { + PSecPkgContext_PackageInfoA info = + (PSecPkgContext_PackageInfoA)pBuffer; + PSecPkgInfoA oldPkgInfo = info->PackageInfo; + + if (oldPkgInfo) + { + info->PackageInfo = (PSecPkgInfoA) + _copyPackageInfoFlatAToW(oldPkgInfo); + package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); + } + break; + } + case SECPKG_ATTR_NEGOTIATION_INFO: + { + PSecPkgContext_NegotiationInfoA info = + (PSecPkgContext_NegotiationInfoA)pBuffer; + PSecPkgInfoA oldPkgInfo = info->PackageInfo; + + if (oldPkgInfo) + { + info->PackageInfo = (PSecPkgInfoA) + _copyPackageInfoFlatAToW(oldPkgInfo); + package->provider->fnTableW.FreeContextBuffer(oldPkgInfo); + } + break; + } + case SECPKG_ATTR_NATIVE_NAMES: + { + PSecPkgContext_NativeNamesA names = + (PSecPkgContext_NativeNamesA)pBuffer; + PSTR oldClient = names->sClientName; + PSTR oldServer = names->sServerName; + + if (oldClient) + { + names->sClientName = (PSTR)SECUR32_AllocWideFromMultiByte( + oldClient); + package->provider->fnTableW.FreeContextBuffer(oldClient); + } + if (oldServer) + { + names->sServerName = (PSTR)SECUR32_AllocWideFromMultiByte( + oldServer); + package->provider->fnTableW.FreeContextBuffer(oldServer); + } + break; + } + case SECPKG_ATTR_CREDENTIAL_NAME: + { + PSecPkgContext_CredentialNameA name = + (PSecPkgContext_CredentialNameA)pBuffer; + PSTR oldCred = name->sCredentialName; + + if (oldCred) + { + name->sCredentialName = + (PSTR)SECUR32_AllocWideFromMultiByte(oldCred); + package->provider->fnTableW.FreeContextBuffer(oldCred); + } + break; + } + /* no thunking needed: */ + case SECPKG_ATTR_ACCESS_TOKEN: + case SECPKG_ATTR_DCE_INFO: + case SECPKG_ATTR_FLAGS: + case SECPKG_ATTR_LIFESPAN: + case SECPKG_ATTR_PASSWORD_EXPIRY: + case SECPKG_ATTR_SESSION_KEY: + case SECPKG_ATTR_SIZES: + case SECPKG_ATTR_STREAM_SIZES: + case SECPKG_ATTR_TARGET_INFORMATION: + break; + default: + WARN("attribute type %d unknown\n", ulAttribute); + ret = SEC_E_INTERNAL_ERROR; + } + } + else + ret = SEC_E_INVALID_TOKEN; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesW(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableA.QueryContextAttributesA) + { + ret = package->provider->fnTableA.QueryContextAttributesA( + ctxt, ulAttribute, pBuffer); + if (ret == SEC_E_OK) + ret = thunk_ContextAttributesAToW(package, ulAttribute, + pBuffer); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesA(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider && pBuffer && cbBuffer) + { + if (package->provider->fnTableW.SetContextAttributesW) + { + /* TODO: gotta validate size too! */ + ret = thunk_ContextAttributesWToA(package, ulAttribute, + pBuffer); + if (ret == SEC_E_OK) + ret = package->provider->fnTableW.SetContextAttributesW( + ctxt, ulAttribute, pBuffer, cbBuffer); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesW(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider && pBuffer && cbBuffer) + { + if (package->provider->fnTableA.SetContextAttributesA) + { + /* TODO: gotta validate size too! */ + ret = thunk_ContextAttributesAToW(package, ulAttribute, + pBuffer); + if (ret == SEC_E_OK) + ret = package->provider->fnTableA.SetContextAttributesA( + ctxt, ulAttribute, pBuffer, cbBuffer); + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextA( + SEC_CHAR *pszPackage, PSecBuffer pPackedContext, void *Token, + PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + UNICODE_STRING package; + + TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token, + phContext); + RtlCreateUnicodeStringFromAsciiz(&package, pszPackage); + ret = ImportSecurityContextW(package.Buffer, pPackedContext, Token, + phContext); + RtlFreeUnicodeString(&package); + return ret; +} + +SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextW( + SEC_WCHAR *pszPackage, PSecBuffer pPackedContext, void *Token, + PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + PSTR package = SECUR32_AllocMultiByteFromWide(pszPackage); + + TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token, + phContext); + ret = ImportSecurityContextA(package, pPackedContext, Token, phContext); + HeapFree(GetProcessHeap(), 0, package); + return ret; +} + diff --git a/reactos/dll/win32/secur32/thunks.h b/reactos/dll/win32/secur32/thunks.h new file mode 100644 index 00000000000..7c3171e0623 --- /dev/null +++ b/reactos/dll/win32/secur32/thunks.h @@ -0,0 +1,74 @@ +/* Copyright (C) 2004 Juan Lang + * + * This file defines thunks between wide char and multibyte functions for + * SSPs that only provide one or the other. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __SECUR32_THUNKS_H__ +#define __SECUR32_THUNKS_H__ + +/* Prototypes for functions that thunk between wide char and multibyte versions, + * for SSPs that only provide one or the other. + */ +SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleA( + SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse, + PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_AcquireCredentialsHandleW( + SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse, + PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_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) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_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) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextA( + SEC_CHAR *pszPackage, PSecBuffer pPackedContext, void *Token, + PCtxtHandle phContext) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_ImportSecurityContextW( + SEC_WCHAR *pszPackage, PSecBuffer pPackedContext, void *Token, + PCtxtHandle phContext) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsA(PCredHandle hCredentials, + SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, + void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, + PTimeStamp ptsExpiry) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_AddCredentialsW(PCredHandle hCredentials, + SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, + void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, + PTimeStamp ptsExpiry) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesA( + PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_QueryCredentialsAttributesW( + PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesA( + PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_QueryContextAttributesW( + PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesA(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) DECLSPEC_HIDDEN; +SECURITY_STATUS SEC_ENTRY thunk_SetContextAttributesW(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) DECLSPEC_HIDDEN; + +#endif /* ndef __SECUR32_THUNKS_H__ */ diff --git a/reactos/dll/win32/secur32/wrapper.c b/reactos/dll/win32/secur32/wrapper.c new file mode 100644 index 00000000000..882144c5db7 --- /dev/null +++ b/reactos/dll/win32/secur32/wrapper.c @@ -0,0 +1,1121 @@ +/* Copyright (C) 2004 Juan Lang + * + * Implements secur32 functions that forward to (wrap) an SSP's implementation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include "precomp.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(secur32); + +/* Tries to allocate a new SecHandle, into which it stores package (in + * phSec->dwUpper) and a copy of realHandle (allocated with SECUR32_ALLOC, + * and stored in phSec->dwLower). SecHandle is equivalent to both a + * CredHandle and a CtxtHandle. + */ +static SECURITY_STATUS SECUR32_makeSecHandle(PSecHandle phSec, + SecurePackage *package, PSecHandle realHandle) +{ + SECURITY_STATUS ret; + + TRACE("%p %p %p\n", phSec, package, realHandle); + + if (phSec && package && realHandle) + { + PSecHandle newSec = HeapAlloc(GetProcessHeap(), 0, sizeof(SecHandle)); + + if (newSec) + { + *newSec = *realHandle; + phSec->dwUpper = (ULONG_PTR)package; + phSec->dwLower = (ULONG_PTR)newSec; + ret = SEC_E_OK; + } + else + ret = SEC_E_INSUFFICIENT_MEMORY; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * AcquireCredentialsHandleA (SECUR32.@) + */ +SECURITY_STATUS WINAPI AcquireCredentialsHandleA( + SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse, + PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal), + debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, + pvGetKeyArgument, phCredential, ptsExpiry); + if (pszPackage) + { + SecurePackage *package = SECUR32_findPackageA(pszPackage); + + if (package && package->provider) + { + if (package->provider->fnTableA.AcquireCredentialsHandleA) + { + CredHandle myCred; + + ret = package->provider->fnTableA.AcquireCredentialsHandleA( + pszPrincipal, pszPackage, fCredentialsUse, pvLogonID, + pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred, + ptsExpiry); + if (ret == SEC_E_OK) + { + ret = SECUR32_makeSecHandle(phCredential, package, &myCred); + if (ret != SEC_E_OK) + package->provider->fnTableW.FreeCredentialsHandle( + &myCred); + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; +} + +/*********************************************************************** + * AcquireCredentialsHandleW (SECUR32.@) + */ +SECURITY_STATUS WINAPI AcquireCredentialsHandleW( + SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse, + PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, + PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal), + debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn, + pvGetKeyArgument, phCredential, ptsExpiry); + if (pszPackage) + { + SecurePackage *package = SECUR32_findPackageW(pszPackage); + + if (package && package->provider) + { + if (package->provider->fnTableW.AcquireCredentialsHandleW) + { + CredHandle myCred; + + ret = package->provider->fnTableW.AcquireCredentialsHandleW( + pszPrincipal, pszPackage, fCredentialsUse, pvLogonID, + pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred, + ptsExpiry); + if (ret == SEC_E_OK) + { + ret = SECUR32_makeSecHandle(phCredential, package, &myCred); + if (ret != SEC_E_OK) + package->provider->fnTableW.FreeCredentialsHandle( + &myCred); + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; +} + +/*********************************************************************** + * FreeCredentialsHandle (SECUR32.@) + */ +SECURITY_STATUS WINAPI FreeCredentialsHandle( + PCredHandle phCredential) +{ + SECURITY_STATUS ret; + + TRACE("%p\n", phCredential); + if (phCredential) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + PCredHandle cred = (PCredHandle)phCredential->dwLower; + + if (package && package->provider && + package->provider->fnTableW.FreeCredentialsHandle) + ret = package->provider->fnTableW.FreeCredentialsHandle(cred); + else + ret = SEC_E_INVALID_HANDLE; + HeapFree(GetProcessHeap(), 0, cred); + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * QueryCredentialsAttributesA (SECUR32.@) + */ +SECURITY_STATUS WINAPI QueryCredentialsAttributesA( + PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer); + if (phCredential) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + PCredHandle cred = (PCredHandle)phCredential->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableA.QueryCredentialsAttributesA) + ret = package->provider->fnTableA.QueryCredentialsAttributesA( + cred, ulAttribute, pBuffer); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * QueryCredentialsAttributesW (SECUR32.@) + */ +SECURITY_STATUS WINAPI QueryCredentialsAttributesW( + PCredHandle phCredential, ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer); + if (phCredential) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + PCredHandle cred = (PCredHandle)phCredential->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.QueryCredentialsAttributesW) + ret = package->provider->fnTableW.QueryCredentialsAttributesW( + cred, ulAttribute, pBuffer); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * InitializeSecurityContextA (SECUR32.@) + */ +SECURITY_STATUS WINAPI 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; + SecurePackage *package = NULL; + PCredHandle cred = NULL; + PCredHandle ctxt = NULL; + + 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 (phContext) + { + package = (SecurePackage *)phContext->dwUpper; + ctxt = (PCtxtHandle)phContext->dwLower; + } + if (phCredential) + { + package = (SecurePackage *)phCredential->dwUpper; + cred = (PCredHandle)phCredential->dwLower; + } + + if (package && package->provider) + { + if (package->provider->fnTableA.InitializeSecurityContextA) + { + CtxtHandle myCtxt; + + if (phContext) + { + PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower; + myCtxt.dwUpper = realCtxt->dwUpper; + myCtxt.dwLower = realCtxt->dwLower; + } + + ret = package->provider->fnTableA.InitializeSecurityContextA( + cred, ctxt, pszTargetName, fContextReq, + Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL, + pOutput, pfContextAttr, ptsExpiry); + if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && + phNewContext && phNewContext != phContext) + { + SECURITY_STATUS ret2; + ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt); + if (ret2 != SEC_E_OK) + package->provider->fnTableA.DeleteSecurityContext(&myCtxt); + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * InitializeSecurityContextW (SECUR32.@) + */ +SECURITY_STATUS WINAPI 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; + SecurePackage *package = NULL; + PCredHandle cred = NULL; + PCredHandle ctxt = NULL; + + 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 (phContext) + { + package = (SecurePackage *)phContext->dwUpper; + ctxt = (PCtxtHandle)phContext->dwLower; + } + if (phCredential) + { + package = (SecurePackage *)phCredential->dwUpper; + cred = (PCredHandle)phCredential->dwLower; + } + + if (package && package->provider) + { + if (package->provider->fnTableW.InitializeSecurityContextW) + { + CtxtHandle myCtxt; + + if (phContext) + { + PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower; + myCtxt.dwUpper = realCtxt->dwUpper; + myCtxt.dwLower = realCtxt->dwLower; + } + + ret = package->provider->fnTableW.InitializeSecurityContextW( + cred, ctxt, pszTargetName, fContextReq, + Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL, + pOutput, pfContextAttr, ptsExpiry); + if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) && + phNewContext && phNewContext != phContext) + { + SECURITY_STATUS ret2; + ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt); + if (ret2 != SEC_E_OK) + package->provider->fnTableW.DeleteSecurityContext(&myCtxt); + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * AcceptSecurityContext (SECUR32.@) + */ +SECURITY_STATUS WINAPI 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 %d %d %p %p %p %p\n", phCredential, phContext, pInput, + fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr, + ptsExpiry); + if (phCredential) + { + SecurePackage *package = (SecurePackage *)phCredential->dwUpper; + PCredHandle cred = (PCredHandle)phCredential->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.AcceptSecurityContext) + { + CtxtHandle myCtxt; + + if(phContext) + { + PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower; + TRACE("realCtx: %p\n", realCtxt); + myCtxt.dwUpper = realCtxt->dwUpper; + myCtxt.dwLower = realCtxt->dwLower; + } + + ret = package->provider->fnTableW.AcceptSecurityContext( + cred, phContext ? &myCtxt : NULL, pInput, fContextReq, + TargetDataRep, &myCtxt, pOutput, pfContextAttr, ptsExpiry); + if (ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) + { + SECURITY_STATUS ret2; + ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt); + if (ret2 != SEC_E_OK) + package->provider->fnTableW.DeleteSecurityContext( + &myCtxt); + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * CompleteAuthToken (SECUR32.@) + */ +SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext, + PSecBufferDesc pToken) +{ + SECURITY_STATUS ret; + + TRACE("%p %p\n", phContext, pToken); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.CompleteAuthToken) + ret = package->provider->fnTableW.CompleteAuthToken(ctxt, + pToken); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * DeleteSecurityContext (SECUR32.@) + */ +SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + + TRACE("%p\n", phContext); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider && + package->provider->fnTableW.DeleteSecurityContext) + ret = package->provider->fnTableW.DeleteSecurityContext(ctxt); + else + ret = SEC_E_INVALID_HANDLE; + HeapFree(GetProcessHeap(), 0, ctxt); + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * ApplyControlToken (SECUR32.@) + */ +SECURITY_STATUS WINAPI ApplyControlToken(PCtxtHandle phContext, + PSecBufferDesc pInput) +{ + SECURITY_STATUS ret; + + TRACE("%p %p\n", phContext, pInput); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.ApplyControlToken) + ret = package->provider->fnTableW.ApplyControlToken( + ctxt, pInput); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * QueryContextAttributesA (SECUR32.@) + */ +SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableA.QueryContextAttributesA) + ret = package->provider->fnTableA.QueryContextAttributesA( + ctxt, ulAttribute, pBuffer); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * QueryContextAttributesW (SECUR32.@) + */ +SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.QueryContextAttributesW) + ret = package->provider->fnTableW.QueryContextAttributesW( + ctxt, ulAttribute, pBuffer); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * ImpersonateSecurityContext (SECUR32.@) + */ +SECURITY_STATUS WINAPI ImpersonateSecurityContext(PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + + TRACE("%p\n", phContext); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.ImpersonateSecurityContext) + ret = package->provider->fnTableW.ImpersonateSecurityContext( + ctxt); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * RevertSecurityContext (SECUR32.@) + */ +SECURITY_STATUS WINAPI RevertSecurityContext(PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + + TRACE("%p\n", phContext); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.RevertSecurityContext) + ret = package->provider->fnTableW.RevertSecurityContext( + ctxt); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * MakeSignature (SECUR32.@) + */ +SECURITY_STATUS WINAPI MakeSignature(PCtxtHandle phContext, ULONG fQOP, + PSecBufferDesc pMessage, ULONG MessageSeqNo) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.MakeSignature) + ret = package->provider->fnTableW.MakeSignature( + ctxt, fQOP, pMessage, MessageSeqNo); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * VerifySignature (SECUR32.@) + */ +SECURITY_STATUS WINAPI VerifySignature(PCtxtHandle phContext, + PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +{ + SECURITY_STATUS ret; + + TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.VerifySignature) + ret = package->provider->fnTableW.VerifySignature( + ctxt, pMessage, MessageSeqNo, pfQOP); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * QuerySecurityPackageInfoA (SECUR32.@) + */ +SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName, + PSecPkgInfoA *ppPackageInfo) +{ + SECURITY_STATUS ret; + + TRACE("%s %p\n", debugstr_a(pszPackageName), ppPackageInfo); + if (pszPackageName) + { + SecurePackage *package = SECUR32_findPackageA(pszPackageName); + + if (package) + { + size_t bytesNeeded = sizeof(SecPkgInfoA); + int nameLen = 0, commentLen = 0; + + if (package->infoW.Name) + { + nameLen = WideCharToMultiByte(CP_ACP, 0, + package->infoW.Name, -1, NULL, 0, NULL, NULL); + bytesNeeded += nameLen; + } + if (package->infoW.Comment) + { + commentLen = WideCharToMultiByte(CP_ACP, 0, + package->infoW.Comment, -1, NULL, 0, NULL, NULL); + bytesNeeded += commentLen; + } + *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); + if (*ppPackageInfo) + { + PSTR nextString = (PSTR)((PBYTE)*ppPackageInfo + + sizeof(SecPkgInfoA)); + + memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW)); + if (package->infoW.Name) + { + (*ppPackageInfo)->Name = nextString; + nextString += WideCharToMultiByte(CP_ACP, 0, + package->infoW.Name, -1, nextString, nameLen, NULL, NULL); + } + else + (*ppPackageInfo)->Name = NULL; + if (package->infoW.Comment) + { + (*ppPackageInfo)->Comment = nextString; + nextString += WideCharToMultiByte(CP_ACP, 0, + package->infoW.Comment, -1, nextString, commentLen, NULL, + NULL); + } + else + (*ppPackageInfo)->Comment = NULL; + ret = SEC_E_OK; + } + else + ret = SEC_E_INSUFFICIENT_MEMORY; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; +} + +/*********************************************************************** + * QuerySecurityPackageInfoW (SECUR32.@) + */ +SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName, + PSecPkgInfoW *ppPackageInfo) +{ + SECURITY_STATUS ret; + SecurePackage *package = SECUR32_findPackageW(pszPackageName); + + TRACE("%s %p\n", debugstr_w(pszPackageName), ppPackageInfo); + if (package) + { + size_t bytesNeeded = sizeof(SecPkgInfoW); + int nameLen = 0, commentLen = 0; + + if (package->infoW.Name) + { + nameLen = lstrlenW(package->infoW.Name) + 1; + bytesNeeded += nameLen * sizeof(WCHAR); + } + if (package->infoW.Comment) + { + commentLen = lstrlenW(package->infoW.Comment) + 1; + bytesNeeded += commentLen * sizeof(WCHAR); + } + *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded); + if (*ppPackageInfo) + { + PWSTR nextString = (PWSTR)((PBYTE)*ppPackageInfo + + sizeof(SecPkgInfoW)); + + **ppPackageInfo = package->infoW; + if (package->infoW.Name) + { + (*ppPackageInfo)->Name = nextString; + lstrcpynW(nextString, package->infoW.Name, nameLen); + nextString += nameLen; + } + else + (*ppPackageInfo)->Name = NULL; + if (package->infoW.Comment) + { + (*ppPackageInfo)->Comment = nextString; + lstrcpynW(nextString, package->infoW.Comment, commentLen); + } + else + (*ppPackageInfo)->Comment = NULL; + ret = SEC_E_OK; + } + else + ret = SEC_E_INSUFFICIENT_MEMORY; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; +} + +/*********************************************************************** + * ExportSecurityContext (SECUR32.@) + */ +SECURITY_STATUS WINAPI ExportSecurityContext(PCtxtHandle phContext, + ULONG fFlags, PSecBuffer pPackedContext, void **pToken) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p %p\n", phContext, fFlags, pPackedContext, pToken); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.ExportSecurityContext) + ret = package->provider->fnTableW.ExportSecurityContext( + ctxt, fFlags, pPackedContext, pToken); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * ImportSecurityContextA (SECUR32.@) + */ +SECURITY_STATUS WINAPI ImportSecurityContextA(SEC_CHAR *pszPackage, + PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + SecurePackage *package = SECUR32_findPackageA(pszPackage); + + TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token, + phContext); + if (package && package->provider) + { + if (package->provider->fnTableA.ImportSecurityContextA) + { + CtxtHandle myCtxt; + + ret = package->provider->fnTableA.ImportSecurityContextA( + pszPackage, pPackedContext, Token, &myCtxt); + if (ret == SEC_E_OK) + { + ret = SECUR32_makeSecHandle(phContext, package, &myCtxt); + if (ret != SEC_E_OK) + package->provider->fnTableW.DeleteSecurityContext(&myCtxt); + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; + +} + +/*********************************************************************** + * ImportSecurityContextW (SECUR32.@) + */ +SECURITY_STATUS WINAPI ImportSecurityContextW(SEC_WCHAR *pszPackage, + PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext) +{ + SECURITY_STATUS ret; + SecurePackage *package = SECUR32_findPackageW(pszPackage); + + TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token, + phContext); + if (package && package->provider) + { + if (package->provider->fnTableW.ImportSecurityContextW) + { + CtxtHandle myCtxt; + + ret = package->provider->fnTableW.ImportSecurityContextW( + pszPackage, pPackedContext, Token, &myCtxt); + if (ret == SEC_E_OK) + { + ret = SECUR32_makeSecHandle(phContext, package, &myCtxt); + if (ret != SEC_E_OK) + package->provider->fnTableW.DeleteSecurityContext(&myCtxt); + } + } + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_SECPKG_NOT_FOUND; + return ret; +} + +/*********************************************************************** + * AddCredentialsA (SECUR32.@) + */ +SECURITY_STATUS WINAPI AddCredentialsA(PCredHandle hCredentials, + SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, + void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, + PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal), + debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn, + pvGetKeyArgument, ptsExpiry); + if (hCredentials) + { + SecurePackage *package = (SecurePackage *)hCredentials->dwUpper; + PCredHandle cred = (PCtxtHandle)hCredentials->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableA.AddCredentialsA) + ret = package->provider->fnTableA.AddCredentialsA( + cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData, + pGetKeyFn, pvGetKeyArgument, ptsExpiry); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * AddCredentialsW (SECUR32.@) + */ +SECURITY_STATUS WINAPI AddCredentialsW(PCredHandle hCredentials, + SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, + void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument, + PTimeStamp ptsExpiry) +{ + SECURITY_STATUS ret; + + TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal), + debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn, + pvGetKeyArgument, ptsExpiry); + if (hCredentials) + { + SecurePackage *package = (SecurePackage *)hCredentials->dwUpper; + PCredHandle cred = (PCtxtHandle)hCredentials->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.AddCredentialsW) + ret = package->provider->fnTableW.AddCredentialsW( + cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData, + pGetKeyFn, pvGetKeyArgument, ptsExpiry); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * QuerySecurityContextToken (SECUR32.@) + */ +SECURITY_STATUS WINAPI QuerySecurityContextToken(PCtxtHandle phContext, + HANDLE *phToken) +{ + SECURITY_STATUS ret; + + TRACE("%p %p\n", phContext, phToken); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.QuerySecurityContextToken) + ret = package->provider->fnTableW.QuerySecurityContextToken( + ctxt, phToken); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * EncryptMessage (SECUR32.@) + */ +SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP, + PSecBufferDesc pMessage, ULONG MessageSeqNo) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.EncryptMessage) + ret = package->provider->fnTableW.EncryptMessage( + ctxt, fQOP, pMessage, MessageSeqNo); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * DecryptMessage (SECUR32.@) + */ +SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext, + PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP) +{ + SECURITY_STATUS ret; + + TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.DecryptMessage) + ret = package->provider->fnTableW.DecryptMessage( + ctxt, pMessage, MessageSeqNo, pfQOP); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * SetContextAttributesA (SECUR32.@) + */ +SECURITY_STATUS WINAPI SetContextAttributesA(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableA.SetContextAttributesA) + ret = package->provider->fnTableA.SetContextAttributesA( + ctxt, ulAttribute, pBuffer, cbBuffer); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +} + +/*********************************************************************** + * SetContextAttributesW (SECUR32.@) + */ +SECURITY_STATUS WINAPI SetContextAttributesW(PCtxtHandle phContext, + ULONG ulAttribute, void *pBuffer, ULONG cbBuffer) +{ + SECURITY_STATUS ret; + + TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer); + if (phContext) + { + SecurePackage *package = (SecurePackage *)phContext->dwUpper; + PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower; + + if (package && package->provider) + { + if (package->provider->fnTableW.SetContextAttributesW) + ret = package->provider->fnTableW.SetContextAttributesW( + ctxt, ulAttribute, pBuffer, cbBuffer); + else + ret = SEC_E_UNSUPPORTED_FUNCTION; + } + else + ret = SEC_E_INVALID_HANDLE; + } + else + ret = SEC_E_INVALID_HANDLE; + return ret; +}