diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 5cce12758ba..d0d02d535ea 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 b72d2c1800e..4103a84725f 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 877794af45b..a448869e3bb 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 a5cea89d725..dcbfa844ede 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;