]> granicus.if.org Git - curl/commitdiff
schannel: Disable ALPN for Wine since it is causing problems
authorJay Satiro <raysatiro@yahoo.com>
Fri, 26 Aug 2016 03:57:56 +0000 (23:57 -0400)
committerJay Satiro <raysatiro@yahoo.com>
Fri, 26 Aug 2016 19:35:16 +0000 (15:35 -0400)
- Disable ALPN on Wine.

- Don't pass input secbuffer when ALPN is disabled.

When ALPN support was added a change was made to pass an input secbuffer
to initialize the context. When ALPN is enabled the buffer contains the
ALPN information, and when it's disabled the buffer is empty. In either
case this input buffer caused problems with Wine and connections would
not complete.

Bug: https://github.com/curl/curl/issues/983
Reported-by: Christian Fillion
lib/urldata.h
lib/vtls/schannel.c

index e6365be3c866d41a3e233b7da92370af77ad07ff..44f8dc5c0a6db8eed3a4282fe3be3b2852705a18 100644 (file)
@@ -330,6 +330,7 @@ struct ssl_connect_data {
   CURLcode recv_unrecoverable_err; /* schannel_recv had an unrecoverable err */
   bool recv_sspi_close_notify; /* true if connection closed by close_notify */
   bool recv_connection_closed; /* true if connection closed, regardless how */
+  bool use_alpn; /* true if ALPN is used for this connection */
 #elif defined(USE_DARWINSSL)
   SSLContextRef ssl_ctx;
   curl_socket_t ssl_sockfd;
index f991ec900e2e50b6dc6ff0c276176862080232c5..511bd11eeaa39491388f5ffc32b97ae0f0949e68 100644 (file)
@@ -127,6 +127,18 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
   infof(data, "schannel: SSL/TLS connection with %s port %hu (step 1/3)\n",
         conn->host.name, conn->remote_port);
 
+#ifdef HAS_ALPN
+  /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above.
+     Also it doesn't seem to be supported for Wine, see curl bug #983. */
+  connssl->use_alpn = conn->bits.tls_enable_alpn &&
+                      !GetProcAddress(GetModuleHandleA("ntdll"),
+                                      "wine_get_version") &&
+                      Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
+                                                  VERSION_GREATER_THAN_EQUAL);
+#else
+  connssl->use_alpn = false;
+#endif
+
   connssl->cred = NULL;
 
   /* check for an existing re-usable credential handle */
@@ -250,10 +262,7 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
   }
 
 #ifdef HAS_ALPN
-  /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above */
-  if(conn->bits.tls_enable_alpn &&
-     Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
-                                 VERSION_GREATER_THAN_EQUAL)) {
+  if(connssl->use_alpn) {
     int cur = 0;
     int list_start_index = 0;
     unsigned int* extension_len = NULL;
@@ -328,11 +337,17 @@ schannel_connect_step1(struct connectdata *conn, int sockindex)
   if(!host_name)
     return CURLE_OUT_OF_MEMORY;
 
-  /* https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx */
+  /* Schannel InitializeSecurityContext:
+     https://msdn.microsoft.com/en-us/library/windows/desktop/aa375924.aspx
 
+     At the moment we don't pass inbuf unless we're using ALPN since we only
+     use it for that, and Wine (for which we currently disable ALPN) is giving
+     us problems with inbuf regardless. https://github.com/curl/curl/issues/983
+  */
   sspi_status = s_pSecFn->InitializeSecurityContext(
-    &connssl->cred->cred_handle, NULL, host_name,
-    connssl->req_flags, 0, 0, &inbuf_desc, 0, &connssl->ctxt->ctxt_handle,
+    &connssl->cred->cred_handle, NULL, host_name, connssl->req_flags, 0, 0,
+    (connssl->use_alpn ? &inbuf_desc : NULL),
+    0, &connssl->ctxt->ctxt_handle,
     &outbuf_desc, &connssl->ret_flags, &connssl->ctxt->time_stamp);
 
   Curl_unicodefree(host_name);
@@ -651,10 +666,7 @@ schannel_connect_step3(struct connectdata *conn, int sockindex)
   }
 
 #ifdef HAS_ALPN
-  /* ALPN is only supported on Windows 8.1 / Server 2012 R2 and above */
-  if(conn->bits.tls_enable_alpn &&
-     Curl_verify_windows_version(6, 3, PLATFORM_WINNT,
-                                 VERSION_GREATER_THAN_EQUAL)) {
+  if(connssl->use_alpn) {
     sspi_status = s_pSecFn->QueryContextAttributes(&connssl->ctxt->ctxt_handle,
       SECPKG_ATTR_APPLICATION_PROTOCOL, &alpn_result);