[2/3] winhttp: Allocate a credential handle for each session.

Hans Leidekker hans at codeweavers.com
Tue Sep 12 02:59:05 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/winhttp/net.c             | 47 +++---------------------------------------
 dlls/winhttp/request.c         | 19 ++++++++++++++++-
 dlls/winhttp/session.c         |  1 +
 dlls/winhttp/winhttp_private.h |  4 +++-
 4 files changed, 25 insertions(+), 46 deletions(-)

diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c
index 5cce127..d0d02d5 100644
--- a/dlls/winhttp/net.c
+++ b/dlls/winhttp/net.c
@@ -254,46 +254,8 @@ static DWORD netconn_verify_cert( PCCERT_CONTEXT cert, WCHAR *server, DWORD secu
     return err;
 }
 
-static SecHandle cred_handle;
-static BOOL cred_handle_initialized;
-
-static CRITICAL_SECTION init_sechandle_cs;
-static CRITICAL_SECTION_DEBUG init_sechandle_cs_debug = {
-    0, 0, &init_sechandle_cs,
-    { &init_sechandle_cs_debug.ProcessLocksList,
-      &init_sechandle_cs_debug.ProcessLocksList },
-    0, 0, { (DWORD_PTR)(__FILE__ ": init_sechandle_cs") }
-};
-static CRITICAL_SECTION init_sechandle_cs = { &init_sechandle_cs_debug, -1, 0, 0, 0, 0 };
-
-static BOOL ensure_cred_handle(void)
-{
-    BOOL ret = TRUE;
-
-    EnterCriticalSection(&init_sechandle_cs);
-
-    if(!cred_handle_initialized) {
-        SECURITY_STATUS res;
-
-        res = AcquireCredentialsHandleW(NULL, (WCHAR*)UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, NULL,
-                NULL, NULL, &cred_handle, NULL);
-        if(res == SEC_E_OK) {
-            cred_handle_initialized = TRUE;
-        }else {
-            WARN("AcquireCredentialsHandleW failed: %u\n", res);
-            ret = FALSE;
-        }
-    }
-
-    LeaveCriticalSection(&init_sechandle_cs);
-    return ret;
-}
-
 void netconn_unload( void )
 {
-    if(cred_handle_initialized)
-        FreeCredentialsHandle(&cred_handle);
-    DeleteCriticalSection(&init_sechandle_cs);
 #ifndef HAVE_GETADDRINFO
     DeleteCriticalSection(&cs_gethostbyname);
 #endif
@@ -409,7 +371,7 @@ BOOL netconn_close( netconn_t *conn )
     return TRUE;
 }
 
-BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname, DWORD security_flags )
+BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle )
 {
     SecBuffer out_buf = {0, SECBUFFER_TOKEN, NULL}, in_bufs[2] = {{0, SECBUFFER_TOKEN}, {0, SECBUFFER_EMPTY}};
     SecBufferDesc out_desc = {SECBUFFER_VERSION, 1, &out_buf}, in_desc = {SECBUFFER_VERSION, 2, in_bufs};
@@ -425,14 +387,11 @@ BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname, DWORD security_fl
     const DWORD isc_req_flags = ISC_REQ_ALLOCATE_MEMORY|ISC_REQ_USE_SESSION_KEY|ISC_REQ_CONFIDENTIALITY
         |ISC_REQ_SEQUENCE_DETECT|ISC_REQ_REPLAY_DETECT|ISC_REQ_MANUAL_CRED_VALIDATION;
 
-    if(!ensure_cred_handle())
-        return FALSE;
-
     read_buf = heap_alloc(read_buf_size);
     if(!read_buf)
         return FALSE;
 
-    status = InitializeSecurityContextW(&cred_handle, NULL, hostname, isc_req_flags, 0, 0, NULL, 0,
+    status = InitializeSecurityContextW(cred_handle, NULL, hostname, isc_req_flags, 0, 0, NULL, 0,
             &ctx, &out_desc, &attrs, NULL);
 
     assert(status != SEC_E_OK);
@@ -492,7 +451,7 @@ BOOL netconn_secure_connect( netconn_t *conn, WCHAR *hostname, DWORD security_fl
 
         in_bufs[0].cbBuffer += size;
         in_bufs[0].pvBuffer = read_buf;
-        status = InitializeSecurityContextW(&cred_handle, &ctx, hostname,  isc_req_flags, 0, 0, &in_desc,
+        status = InitializeSecurityContextW(cred_handle, &ctx, hostname,  isc_req_flags, 0, 0, &in_desc,
                 0, NULL, &out_desc, &attrs, NULL);
         TRACE("InitializeSecurityContext ret %08x\n", status);
 
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index b72d2c1..4103a84 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -35,6 +35,7 @@
 #include "initguid.h"
 #include "httprequest.h"
 #include "httprequestid.h"
+#include "schannel.h"
 #include "winhttp.h"
 
 #include "winhttp_private.h"
@@ -1092,6 +1093,20 @@ static void cache_connection( netconn_t *netconn )
     LeaveCriticalSection( &connection_pool_cs );
 }
 
+static BOOL ensure_cred_handle( session_t *session )
+{
+    SECURITY_STATUS status;
+    if (session->cred_handle_initialized) return TRUE;
+    if ((status = AcquireCredentialsHandleW( NULL, (WCHAR *)UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, NULL,
+                                             NULL, NULL, &session->cred_handle, NULL )) != SEC_E_OK)
+    {
+        WARN( "AcquireCredentialsHandleW failed: 0x%08x\n", status );
+        return FALSE;
+    }
+    session->cred_handle_initialized = TRUE;
+    return TRUE;
+}
+
 static BOOL open_connection( request_t *request )
 {
     BOOL is_secure = request->hdr.flags & WINHTTP_FLAG_SECURE;
@@ -1219,7 +1234,9 @@ static BOOL open_connection( request_t *request )
                     return FALSE;
                 }
             }
-            if (!netconn_secure_connect( netconn, connect->hostname, request->security_flags ))
+            if (!ensure_cred_handle( connect->session ) ||
+                !netconn_secure_connect( netconn, connect->hostname, request->security_flags,
+                                         &connect->session->cred_handle ))
             {
                 heap_free( addressW );
                 netconn_close( netconn );
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index 877794a..a448869 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -99,6 +99,7 @@ static void session_destroy( object_header_t *hdr )
     TRACE("%p\n", session);
 
     if (session->unload_event) SetEvent( session->unload_event );
+    if (session->cred_handle_initialized) FreeCredentialsHandle( &session->cred_handle );
 
     LIST_FOR_EACH_SAFE( item, next, &session->cookie_cache )
     {
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h
index a5cea89..dcbfa84 100644
--- a/dlls/winhttp/winhttp_private.h
+++ b/dlls/winhttp/winhttp_private.h
@@ -120,6 +120,8 @@ typedef struct
     LPWSTR proxy_password;
     struct list cookie_cache;
     HANDLE unload_event;
+    CredHandle cred_handle;
+    BOOL cred_handle_initialized;
 } session_t;
 
 typedef struct
@@ -300,7 +302,7 @@ void netconn_unload( void ) DECLSPEC_HIDDEN;
 ULONG netconn_query_data_available( netconn_t * ) DECLSPEC_HIDDEN;
 BOOL netconn_recv( netconn_t *, void *, size_t, int, int * ) DECLSPEC_HIDDEN;
 BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr_storage *, int ) DECLSPEC_HIDDEN;
-BOOL netconn_secure_connect( netconn_t *, WCHAR *, DWORD ) DECLSPEC_HIDDEN;
+BOOL netconn_secure_connect( netconn_t *, WCHAR *, DWORD, CredHandle * ) DECLSPEC_HIDDEN;
 BOOL netconn_send( netconn_t *, const void *, size_t, int * ) DECLSPEC_HIDDEN;
 DWORD netconn_set_timeout( netconn_t *, BOOL, int ) DECLSPEC_HIDDEN;
 BOOL netconn_is_alive( netconn_t * ) DECLSPEC_HIDDEN;
-- 
2.1.4




More information about the wine-patches mailing list