From 50c13d4f3f305e1a0f5cf7a5bedc687f5f3b60b8 Mon Sep 17 00:00:00 2001 From: Henri Verbeet Date: Mon, 22 Sep 2008 22:14:04 +0200 Subject: secur32: Allocate schannel client credentials --- dlls/secur32/schannel.c | 55 +++++++++++++++++++++++++++++++++++++++++- dlls/secur32/secur32.c | 2 + dlls/secur32/secur32_priv.h | 3 ++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c index 9531794..11428de 100644 --- a/dlls/secur32/schannel.c +++ b/dlls/secur32/schannel.c @@ -19,19 +19,33 @@ * implementation. */ #include "config.h" +#include "wine/port.h" #include +#ifdef SONAME_LIBGNUTLS +#include +#endif + #include "windef.h" #include "winbase.h" #include "sspi.h" #include "schannel.h" #include "secur32_priv.h" #include "wine/debug.h" +#include "wine/library.h" WINE_DEFAULT_DEBUG_CHANNEL(secur32); #ifdef SONAME_LIBGNUTLS +static void *libgnutls_handle; +#define MAKE_FUNCPTR(f) static typeof(f) * p##f +MAKE_FUNCPTR(gnutls_certificate_allocate_credentials); +MAKE_FUNCPTR(gnutls_certificate_free_credentials); +MAKE_FUNCPTR(gnutls_global_deinit); +MAKE_FUNCPTR(gnutls_global_init); +#undef MAKE_FUNCPTR + enum schan_handle_type { SCHAN_HANDLE_CRED, @@ -47,6 +61,7 @@ struct schan_handle struct schan_credentials { ULONG credential_use; + gnutls_certificate_credentials_t credentials; }; static struct schan_handle *schan_handle_table; @@ -273,6 +288,7 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan } creds->credential_use = SECPKG_CRED_OUTBOUND; + pgnutls_certificate_allocate_credentials(&creds->credentials); phCredential->dwLower = handle; phCredential->dwUpper = 0; @@ -371,6 +387,8 @@ static SECURITY_STATUS SEC_ENTRY schan_FreeCredentialsHandle( creds = schan_free_handle(phCredential->dwLower, SCHAN_HANDLE_CRED); if (!creds) return SEC_E_INVALID_HANDLE; + if (creds->credential_use == SECPKG_CRED_OUTBOUND) + pgnutls_certificate_free_credentials(creds->credentials); HeapFree(GetProcessHeap(), 0, creds); return SEC_E_OK; @@ -496,8 +514,32 @@ static const WCHAR schannelDllName[] = { 's','c','h','a','n','n','e','l','.','d' void SECUR32_initSchannelSP(void) { - SecureProvider *provider = SECUR32_addProvider(&schanTableA, &schanTableW, - schannelDllName); + SecureProvider *provider; + + + libgnutls_handle = wine_dlopen(SONAME_LIBGNUTLS, RTLD_NOW, NULL, 0); + if (!libgnutls_handle) + { + WARN("Failed to load libgnutls.\n"); + return; + } + +#define LOAD_FUNCPTR(f) \ + if (!(p##f = wine_dlsym(libgnutls_handle, #f, NULL, 0))) \ + { \ + ERR("Failed to load %s\n", #f); \ + wine_dlclose(libgnutls_handle, NULL, 0); \ + libgnutls_handle = NULL; \ + return; \ + } + + LOAD_FUNCPTR(gnutls_certificate_allocate_credentials) + LOAD_FUNCPTR(gnutls_certificate_free_credentials) + LOAD_FUNCPTR(gnutls_global_deinit) + LOAD_FUNCPTR(gnutls_global_init) +#undef LOAD_FUNCPTR + + provider = SECUR32_addProvider(&schanTableA, &schanTableW, schannelDllName); if (provider) { @@ -530,12 +572,21 @@ void SECUR32_initSchannelSP(void) schan_handle_table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 64 * sizeof(*schan_handle_table)); schan_handle_table_size = 64; + + pgnutls_global_init(); } } +void SECUR32_deinitSchannelSP(void) +{ + pgnutls_global_deinit(); + if (libgnutls_handle) wine_dlclose(libgnutls_handle, NULL, 0); +} + #else /* SONAME_LIBGNUTLS */ void SECUR32_initSchannelSP(void) {} +void SECUR32_deinitSchannelSP(void) {} #endif /* SONAME_LIBGNUTLS */ diff --git a/dlls/secur32/secur32.c b/dlls/secur32/secur32.c index 4a434ac..27e0263 100644 --- a/dlls/secur32/secur32.c +++ b/dlls/secur32/secur32.c @@ -673,6 +673,8 @@ static void SECUR32_freeProviders(void) TRACE("\n"); EnterCriticalSection(&cs); + SECUR32_deinitSchannelSP(); + if (packageTable) { LIST_FOR_EACH_ENTRY(package, &packageTable->table, SecurePackage, entry) diff --git a/dlls/secur32/secur32_priv.h b/dlls/secur32/secur32_priv.h index 6f9c1e7..9eed1a5 100644 --- a/dlls/secur32/secur32_priv.h +++ b/dlls/secur32/secur32_priv.h @@ -124,6 +124,9 @@ void SECUR32_initSchannelSP(void); void SECUR32_initNegotiateSP(void); void SECUR32_initNTLMSP(void); +/* Cleanup functions for built-in providers */ +void SECUR32_deinitSchannelSP(void); + /* Functions from dispatcher.c used elsewhere in the code */ SECURITY_STATUS fork_helper(PNegoHelper *new_helper, const char *prog, char * const argv[]); -- 1.5.6.4