components/curl/patches/001-CVE-2016-0755.patch
branchs11u3-sru
changeset 7033 a49f9f0272f2
equal deleted inserted replaced
7025:c81434078faa 7033:a49f9f0272f2
       
     1 CVE-2016-0755: libcurl will reuse NTLM-authenticated proxy connections without
       
     2 properly making sure that the connection was authenticated with the same
       
     3 credentials as set for this transfer. 
       
     4 
       
     5 CVE webpage for this problem:
       
     6 http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2016-0755
       
     7 
       
     8 Relevant upstream patch:
       
     9 http://curl.haxx.se/CVE-2016-0755.patch
       
    10 
       
    11 --- lib/url.c.orig
       
    12 +++ lib/url.c
       
    13 @@ -3126,15 +3126,20 @@ ConnectionExists(struct SessionHandle *data,
       
    14  {
       
    15    struct connectdata *check;
       
    16    struct connectdata *chosen = 0;
       
    17    bool canPipeline = IsPipeliningPossible(data, needle);
       
    18 +  struct connectbundle *bundle;
       
    19 +
       
    20  #ifdef USE_NTLM
       
    21 -  bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
       
    22 -                       (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
       
    23 -    (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
       
    24 +  bool wantNTLMhttp = ((data->state.authhost.want &
       
    25 +                      (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
       
    26 +                      (needle->handler->protocol & PROTO_FAMILY_HTTP));
       
    27 +  bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
       
    28 +                           ((data->state.authproxy.want &
       
    29 +                           (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
       
    30 +                           (needle->handler->protocol & PROTO_FAMILY_HTTP)));
       
    31  #endif
       
    32 -  struct connectbundle *bundle;
       
    33  
       
    34    *force_reuse = FALSE;
       
    35    *waitpipe = FALSE;
       
    36  
       
    37    /* We can't pipe if the site is blacklisted */
       
    38 @@ -3186,13 +3191,10 @@ ConnectionExists(struct SessionHandle *data,
       
    39      }
       
    40  
       
    41      curr = bundle->conn_list->head;
       
    42      while(curr) {
       
    43        bool match = FALSE;
       
    44 -#if defined(USE_NTLM)
       
    45 -      bool credentialsMatch = FALSE;
       
    46 -#endif
       
    47        size_t pipeLen;
       
    48  
       
    49        /*
       
    50         * Note that if we use a HTTP proxy, we check connections to that
       
    51         * proxy and not to the actual remote server.
       
    52 @@ -3298,25 +3300,18 @@ ConnectionExists(struct SessionHandle *data,
       
    53             !needle->localdev ||
       
    54             strcmp(check->localdev, needle->localdev))
       
    55            continue;
       
    56        }
       
    57  
       
    58 -      if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST))
       
    59 -#ifdef USE_NTLM
       
    60 -         || (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)
       
    61 -#endif
       
    62 -        ) {
       
    63 -        /* This protocol requires credentials per connection or is HTTP+NTLM,
       
    64 +      if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
       
    65 +        /* This protocol requires credentials per connection,
       
    66             so verify that we're using the same name and password as well */
       
    67          if(!strequal(needle->user, check->user) ||
       
    68             !strequal(needle->passwd, check->passwd)) {
       
    69            /* one of them was different */
       
    70            continue;
       
    71          }
       
    72 -#if defined(USE_NTLM)
       
    73 -        credentialsMatch = TRUE;
       
    74 -#endif
       
    75        }
       
    76  
       
    77        if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
       
    78           (needle->bits.httpproxy && check->bits.httpproxy &&
       
    79            needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
       
    80 @@ -3372,24 +3367,47 @@ ConnectionExists(struct SessionHandle *data,
       
    81             already authenticating with the right credentials. If not, keep
       
    82             looking so that we can reuse NTLM connections if
       
    83             possible. (Especially we must not reuse the same connection if
       
    84             partway through a handshake!) */
       
    85          if(wantNTLMhttp) {
       
    86 -          if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
       
    87 -            chosen = check;
       
    88 +          if(!strequal(needle->user, check->user) ||
       
    89 +             !strequal(needle->passwd, check->passwd))
       
    90 +            continue;
       
    91 +        }
       
    92 +        else if(check->ntlm.state != NTLMSTATE_NONE) {
       
    93 +          /* Connection is using NTLM auth but we don't want NTLM */
       
    94 +          continue;
       
    95 +        }
       
    96 +
       
    97 +        /* Same for Proxy NTLM authentication */
       
    98 +        if(wantProxyNTLMhttp) {
       
    99 +          if(!strequal(needle->proxyuser, check->proxyuser) ||
       
   100 +             !strequal(needle->proxypasswd, check->proxypasswd))
       
   101 +            continue;
       
   102 +        }
       
   103 +        else if(check->proxyntlm.state != NTLMSTATE_NONE) {
       
   104 +          /* Proxy connection is using NTLM auth but we don't want NTLM */
       
   105 +          continue;
       
   106 +        }
       
   107 +
       
   108 +        if(wantNTLMhttp || wantProxyNTLMhttp) {
       
   109 +          /* Credentials are already checked, we can use this connection */
       
   110 +          chosen = check;
       
   111  
       
   112 +          if((wantNTLMhttp &&
       
   113 +             (check->ntlm.state != NTLMSTATE_NONE)) ||
       
   114 +              (wantProxyNTLMhttp &&
       
   115 +               (check->proxyntlm.state != NTLMSTATE_NONE))) {
       
   116              /* We must use this connection, no other */
       
   117              *force_reuse = TRUE;
       
   118              break;
       
   119            }
       
   120 -          else if(credentialsMatch)
       
   121 -            /* this is a backup choice */
       
   122 -            chosen = check;
       
   123 +
       
   124 +          /* Continue look up for a better connection */
       
   125            continue;
       
   126          }
       
   127  #endif
       
   128 -
       
   129          if(canPipeline) {
       
   130            /* We can pipeline if we want to. Let's continue looking for
       
   131               the optimal connection to use, i.e the shortest pipe that is not
       
   132               blacklisted. */
       
   133  
       
   134 -- 
       
   135 2.7.0.rc3
       
   136