[3/3] winhttp: Implement WINHTTP_OPTION_SECURE_PROTOCOLS.

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


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 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
-- 
2.1.4




More information about the wine-patches mailing list