Henri Verbeet : secur32: Basic implementation of schannel AcquireCredentialsHandle/ FreeCredentialsHandle.
Alexandre Julliard
julliard at winehq.org
Tue Sep 23 09:28:33 CDT 2008
Module: wine
Branch: master
Commit: 7176dc261da2fef8742f5e8291d211ce18abbd6e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=7176dc261da2fef8742f5e8291d211ce18abbd6e
Author: Henri Verbeet <hverbeet at gmail.com>
Date: Mon Sep 22 22:14:04 2008 +0200
secur32: Basic implementation of schannel AcquireCredentialsHandle/FreeCredentialsHandle.
All this does so far is create a handle and store the credential type in there.
---
dlls/secur32/schannel.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 136 insertions(+), 3 deletions(-)
diff --git a/dlls/secur32/schannel.c b/dlls/secur32/schannel.c
index 67ce770..1633a70 100644
--- a/dlls/secur32/schannel.c
+++ b/dlls/secur32/schannel.c
@@ -32,6 +32,89 @@ WINE_DEFAULT_DEBUG_CHANNEL(secur32);
#ifdef SONAME_LIBGNUTLS
+enum schan_handle_type
+{
+ SCHAN_HANDLE_CRED,
+ SCHAN_HANDLE_FREE
+};
+
+struct schan_handle
+{
+ void *object;
+ enum schan_handle_type type;
+};
+
+struct schan_credentials
+{
+ ULONG credential_use;
+};
+
+static struct schan_handle *schan_handle_table;
+static struct schan_handle *schan_free_handles;
+static SIZE_T schan_handle_table_size;
+static SIZE_T schan_handle_count;
+
+static ULONG_PTR schan_alloc_handle(void *object, enum schan_handle_type type)
+{
+ struct schan_handle *handle;
+
+ if (schan_free_handles)
+ {
+ /* Use a free handle */
+ handle = schan_free_handles;
+ if (handle->type != SCHAN_HANDLE_FREE)
+ {
+ ERR("Handle %d(%p) is in the free list, but has type %#x.\n", (handle-schan_handle_table), handle, handle->type);
+ return -1;
+ }
+ schan_free_handles = (struct schan_handle *)handle->object;
+ handle->object = object;
+ handle->type = type;
+
+ return handle - schan_handle_table;
+ }
+ if (!(schan_handle_count < schan_handle_table_size))
+ {
+ /* Grow the table */
+ SIZE_T new_size = schan_handle_table_size + (schan_handle_table_size >> 1);
+ struct schan_handle *new_table = HeapReAlloc(GetProcessHeap(), 0, schan_handle_table, new_size * sizeof(*schan_handle_table));
+ if (!new_table)
+ {
+ ERR("Failed to grow the handle table\n");
+ return -1;
+ }
+ schan_handle_table = new_table;
+ schan_handle_table_size = new_size;
+ }
+
+ handle = &schan_handle_table[schan_handle_count++];
+ handle->object = object;
+ handle->type = type;
+
+ return handle - schan_handle_table;
+}
+
+static void *schan_free_handle(ULONG_PTR handle_idx, enum schan_handle_type type)
+{
+ struct schan_handle *handle;
+ void *object;
+
+ if (handle_idx == -1) return NULL;
+ handle = &schan_handle_table[handle_idx];
+ if (handle->type != type)
+ {
+ ERR("Handle %ld(%p) is not of type %#x\n", handle_idx, handle, type);
+ return NULL;
+ }
+
+ object = handle->object;
+ handle->object = schan_free_handles;
+ handle->type = SCHAN_HANDLE_FREE;
+ schan_free_handles = handle;
+
+ return object;
+}
+
static SECURITY_STATUS schan_QueryCredentialsAttributes(
PCredHandle phCredential, ULONG ulAttribute, const VOID *pBuffer)
{
@@ -162,6 +245,8 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan
{
SECURITY_STATUS st = SEC_E_OK;
+ TRACE("schanCred %p, phCredential %p, ptsExpiry %p\n", schanCred, phCredential, ptsExpiry);
+
if (schanCred)
{
st = schan_CheckCreds(schanCred);
@@ -174,7 +259,24 @@ static SECURITY_STATUS schan_AcquireClientCredentials(const SCHANNEL_CRED *schan
*/
if (st == SEC_E_OK)
{
- phCredential->dwUpper = SECPKG_CRED_OUTBOUND;
+ ULONG_PTR handle;
+ struct schan_credentials *creds;
+
+ creds = HeapAlloc(GetProcessHeap(), 0, sizeof(*creds));
+ if (!creds) return SEC_E_INSUFFICIENT_MEMORY;
+
+ handle = schan_alloc_handle(creds, SCHAN_HANDLE_CRED);
+ if (handle == -1)
+ {
+ HeapFree(GetProcessHeap(), 0, creds);
+ return SEC_E_INTERNAL_ERROR;
+ }
+
+ creds->credential_use = SECPKG_CRED_OUTBOUND;
+
+ phCredential->dwLower = handle;
+ phCredential->dwUpper = 0;
+
/* Outbound credentials have no expiry */
if (ptsExpiry)
{
@@ -190,12 +292,30 @@ static SECURITY_STATUS schan_AcquireServerCredentials(const SCHANNEL_CRED *schan
{
SECURITY_STATUS st;
+ TRACE("schanCred %p, phCredential %p, ptsExpiry %p\n", schanCred, phCredential, ptsExpiry);
+
if (!schanCred) return SEC_E_NO_CREDENTIALS;
st = schan_CheckCreds(schanCred);
if (st == SEC_E_OK)
{
- phCredential->dwUpper = SECPKG_CRED_INBOUND;
+ ULONG_PTR handle;
+ struct schan_credentials *creds;
+
+ creds = HeapAlloc(GetProcessHeap(), 0, sizeof(*creds));
+ if (!creds) return SEC_E_INSUFFICIENT_MEMORY;
+ creds->credential_use = SECPKG_CRED_INBOUND;
+
+ handle = schan_alloc_handle(creds, SCHAN_HANDLE_CRED);
+ if (handle == -1)
+ {
+ HeapFree(GetProcessHeap(), 0, creds);
+ return SEC_E_INTERNAL_ERROR;
+ }
+
+ phCredential->dwLower = handle;
+ phCredential->dwUpper = 0;
+
/* FIXME: get expiry from cert */
}
return st;
@@ -242,7 +362,17 @@ static SECURITY_STATUS SEC_ENTRY schan_AcquireCredentialsHandleW(
static SECURITY_STATUS SEC_ENTRY schan_FreeCredentialsHandle(
PCredHandle phCredential)
{
- FIXME("(%p): stub\n", phCredential);
+ struct schan_credentials *creds;
+
+ TRACE("phCredential %p\n", phCredential);
+
+ if (!phCredential) return SEC_E_INVALID_HANDLE;
+
+ creds = schan_free_handle(phCredential->dwLower, SCHAN_HANDLE_CRED);
+ if (!creds) return SEC_E_INVALID_HANDLE;
+
+ HeapFree(GetProcessHeap(), 0, creds);
+
return SEC_E_OK;
}
@@ -397,6 +527,9 @@ void SECUR32_initSchannelSP(void)
SECUR32_addPackages(provider, sizeof(info) / sizeof(info[0]), NULL,
info);
+
+ schan_handle_table = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 64 * sizeof(*schan_handle_table));
+ schan_handle_table_size = 64;
}
}
More information about the wine-cvs
mailing list