Module: wine Branch: master Commit: 2b77b0bb6b220979278bc4153d0fa854f8eeb5e7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2b77b0bb6b220979278bc4153d...
Author: Hans Leidekker hans@codeweavers.com Date: Tue Sep 12 09:59:06 2017 +0200
winhttp: Implement WINHTTP_OPTION_SECURE_PROTOCOLS.
Signed-off-by: Hans Leidekker hans@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winhttp/request.c | 19 ++++++++++++++++++- dlls/winhttp/session.c | 11 +++++++++++ dlls/winhttp/tests/winhttp.c | 7 ++++++- dlls/winhttp/winhttp_private.h | 1 + include/winhttp.h | 12 ++++++++---- 5 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 4103a84..f3f4cf8 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -1093,11 +1093,28 @@ static void cache_connection( netconn_t *netconn ) LeaveCriticalSection( &connection_pool_cs ); }
+static DWORD map_secure_protocols( DWORD mask ) +{ + DWORD ret = 0; + if (mask & WINHTTP_FLAG_SECURE_PROTOCOL_SSL2) ret |= SP_PROT_SSL2_CLIENT; + if (mask & WINHTTP_FLAG_SECURE_PROTOCOL_SSL3) ret |= SP_PROT_SSL3_CLIENT; + if (mask & WINHTTP_FLAG_SECURE_PROTOCOL_TLS1) ret |= SP_PROT_TLS1_CLIENT; + if (mask & WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1) ret |= SP_PROT_TLS1_1_CLIENT; + if (mask & WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2) ret |= SP_PROT_TLS1_2_CLIENT; + return ret; +} + static BOOL ensure_cred_handle( session_t *session ) { + SCHANNEL_CRED cred; SECURITY_STATUS status; + if (session->cred_handle_initialized) return TRUE; - if ((status = AcquireCredentialsHandleW( NULL, (WCHAR *)UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, NULL, + + memset( &cred, 0, sizeof(cred) ); + cred.dwVersion = SCHANNEL_CRED_VERSION; + cred.grbitEnabledProtocols = map_secure_protocols( session->secure_protocols ); + if ((status = AcquireCredentialsHandleW( NULL, (WCHAR *)UNISP_NAME_W, SECPKG_CRED_OUTBOUND, NULL, &cred, NULL, NULL, &session->cred_handle, NULL )) != SEC_E_OK) { WARN( "AcquireCredentialsHandleW failed: 0x%08x\n", status ); diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index a448869..b54e77b 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -184,6 +184,17 @@ static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffe hdr->redirect_policy = policy; return TRUE; } + case WINHTTP_OPTION_SECURE_PROTOCOLS: + { + if (buflen != sizeof(session->secure_protocols)) + { + set_last_error( ERROR_INSUFFICIENT_BUFFER ); + return FALSE; + } + session->secure_protocols = *(DWORD *)buffer; + TRACE("0x%x\n", session->secure_protocols); + return TRUE; + } case WINHTTP_OPTION_DISABLE_FEATURE: set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE ); return FALSE; diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c index c9f5ecd..2babe98 100644 --- a/dlls/winhttp/tests/winhttp.c +++ b/dlls/winhttp/tests/winhttp.c @@ -974,7 +974,7 @@ static void test_secure_connection(void) { static const char data_start[] = "<!DOCTYPE html PUBLIC"; HINTERNET ses, con, req; - DWORD size, status, policy, bitness, read_size, err, available_size; + DWORD size, status, policy, bitness, read_size, err, available_size, protocols; BOOL ret; CERT_CONTEXT *cert; WINHTTP_CERTIFICATE_INFO info; @@ -987,6 +987,11 @@ static void test_secure_connection(void) ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy)); ok(ret, "failed to set redirect policy %u\n", GetLastError());
+ protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2; + ret = WinHttpSetOption(ses, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols)); + err = GetLastError(); + ok(ret || (!ret && err == ERROR_INVALID_PARAMETER) /* < win7 */, "failed to set protocols %u\n", err); + con = WinHttpConnect(ses, test_winehq, 443, 0); ok(con != NULL, "failed to open a connection %u\n", GetLastError());
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index dcbfa84..ee41481 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -122,6 +122,7 @@ typedef struct HANDLE unload_event; CredHandle cred_handle; BOOL cred_handle_initialized; + DWORD secure_protocols; } session_t;
typedef struct diff --git a/include/winhttp.h b/include/winhttp.h index 52c60e4..e873e77 100644 --- a/include/winhttp.h +++ b/include/winhttp.h @@ -440,10 +440,14 @@ typedef int INTERNET_SCHEME, *LPINTERNET_SCHEME; #define WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE 0x00000040 #define WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR 0x80000000
-#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 0x00000008 -#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 0x00000020 -#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 0x00000080 -#define WINHTTP_FLAG_SECURE_PROTOCOL_ALL (WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 | WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1) +#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 0x00000008 +#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 0x00000020 +#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 0x00000080 +#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 0x00000200 +#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 0x00000800 +#define WINHTTP_FLAG_SECURE_PROTOCOL_ALL (WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 |\ + WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 |\ + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1)
#define WINHTTP_AUTH_SCHEME_BASIC 0x00000001 #define WINHTTP_AUTH_SCHEME_NTLM 0x00000002