Skip to content

Commit

Permalink
CC: curl: fix CVE-2016-0755
Browse files Browse the repository at this point in the history
This fixes the following security problem:
CVE-2016-0755: NTLM credentials not-checked for proxy connection re-use
http://curl.haxx.se/docs/adv_20160127B.html

backport of r48614.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>


git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@48872 3c298f89-4303-0410-b956-a3cf2f4a3e73
  • Loading branch information
hauke committed Mar 1, 2016
1 parent e982dbd commit 380df1a
Showing 1 changed file with 126 additions and 0 deletions.
126 changes: 126 additions & 0 deletions package/network/utils/curl/patches/018-CVE-2016-0755.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
From d41dcba4e9b69d6b761e3460cc6ae7e8fd8f621f 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]

CVE-2016-0755

Bug: http://curl.haxx.se/docs/adv_20160127A.html
---
lib/url.c | 62 ++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 40 insertions(+), 22 deletions(-)

--- a/lib/url.c
+++ b/lib/url.c
@@ -3044,11 +3044,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 */
@@ -3077,9 +3082,6 @@ ConnectionExists(struct SessionHandle *d
curr = bundle->conn_list->head;
while(curr) {
bool match = FALSE;
-#if defined(USE_NTLM)
- bool credentialsMatch = FALSE;
-#endif
size_t pipeLen;

/*
@@ -3185,21 +3187,14 @@ ConnectionExists(struct SessionHandle *d
}

if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
-#if defined(USE_NTLM)
- (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)) {
-#else
wantNTLMhttp) {
-#endif
- /* This protocol requires credentials per connection or is HTTP+NTLM,
+ /* 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;
}
-#if defined(USE_NTLM)
- credentialsMatch = TRUE;
-#endif
}

if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
@@ -3258,20 +3253,43 @@ 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;
}
#endif
-
if(canPipeline) {
/* We can pipeline if we want to. Let's continue looking for
the optimal connection to use, i.e the shortest pipe that is not

0 comments on commit 380df1a

Please sign in to comment.