LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File curl-CVE-2016-0755.patch of Package curl (Project home:mge1512:aide-static)

From 54b2c806edc3bbd2dada86055f2be41c4cbed762 Mon Sep 17 00:00:00 2001
From: Isaac Boukris <iboukris@gmail.com>
Date: Wed, 13 Jan 2016 11:05:51 +0200
Subject: [PATCH] NTLM: Fix ConnectionExists to compare Proxy credentials

Proxy NTLM authentication should compare credentials when
re-using a connection similar to host authentication, as it
authenticate the connection.

Example:
curl -v -x http://proxy:port http://host/ -U good_user:good_pwd
  --proxy-ntlm --next -x http://proxy:port http://host/
    [-U fake_user:fake_pwd --proxy-ntlm]
---
 lib/url.c | 62 ++++++++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 40 insertions(+), 22 deletions(-)

Index: curl-7.37.0/lib/url.c
===================================================================
--- curl-7.37.0.orig/lib/url.c	2016-01-21 14:22:16.901799861 +0100
+++ curl-7.37.0/lib/url.c	2016-01-21 14:33:51.010227399 +0100
@@ -2939,11 +2939,16 @@ ConnectionExists(struct SessionHandle *d
   struct connectdata *check;
   struct connectdata *chosen = 0;
   bool canPipeline = IsPipeliningPossible(data, needle);
-  bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
-                       (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
-    (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
   struct connectbundle *bundle;
 
+  bool wantNTLMhttp = ((data->state.authhost.want &
+                      (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+                      (needle->handler->protocol & PROTO_FAMILY_HTTP));
+  bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
+                           ((data->state.authproxy.want &
+                           (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
+                           (needle->handler->protocol & PROTO_FAMILY_HTTP)));
+
   *force_reuse = FALSE;
 
   /* We can't pipe if the site is blacklisted */
@@ -2972,7 +2977,6 @@ ConnectionExists(struct SessionHandle *d
     curr = bundle->conn_list->head;
     while(curr) {
       bool match = FALSE;
-      bool credentialsMatch = FALSE;
       size_t pipeLen;
 
       /*
@@ -3096,16 +3100,14 @@ ConnectionExists(struct SessionHandle *d
           continue;
       }
 
-      if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
-         (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)) {
-        /* This protocol requires credentials per connection or is HTTP+NTLM,
+      if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
+        /* This protocol requires credentials per connection,
            so verify that we're using the same name and password as well */
         if(!strequal(needle->user, check->user) ||
            !strequal(needle->passwd, check->passwd)) {
           /* one of them was different */
           continue;
         }
-        credentialsMatch = TRUE;
       }
 
       if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
@@ -3163,16 +3165,39 @@ ConnectionExists(struct SessionHandle *d
            possible. (Especially we must not reuse the same connection if
            partway through a handshake!) */
         if(wantNTLMhttp) {
-          if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
-            chosen = check;
+          if(!strequal(needle->user, check->user) ||
+             !strequal(needle->passwd, check->passwd))
+            continue;
+        }
+        else if(check->ntlm.state != NTLMSTATE_NONE) {
+          /* Connection is using NTLM auth but we don't want NTLM */
+          continue;
+        }
+
+        /* Same for Proxy NTLM authentication */
+        if(wantProxyNTLMhttp) {
+          if(!strequal(needle->proxyuser, check->proxyuser) ||
+             !strequal(needle->proxypasswd, check->proxypasswd))
+            continue;
+        }
+        else if(check->proxyntlm.state != NTLMSTATE_NONE) {
+          /* Proxy connection is using NTLM auth but we don't want NTLM */
+          continue;
+        }
 
+        if(wantNTLMhttp || wantProxyNTLMhttp) {
+          /* Credentials are already checked, we can use this connection */
+          chosen = check;
+ 
+          if((wantNTLMhttp &&
+             (check->ntlm.state != NTLMSTATE_NONE)) ||
+              (wantProxyNTLMhttp &&
+               (check->proxyntlm.state != NTLMSTATE_NONE))) {
             /* We must use this connection, no other */
             *force_reuse = TRUE;
             break;
           }
-          else if(credentialsMatch)
-            /* this is a backup choice */
-            chosen = check;
+          /* Continue look up for a better connection */
           continue;
         }