forked from curl/curl-www
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CVE-2016-0755.patch
150 lines (136 loc) · 5.38 KB
/
CVE-2016-0755.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From d41dcba4e9b69d6b761e3460cc6ae7e8fd8f621f Mon Sep 17 00:00:00 2001
From: Isaac Boukris <[email protected]>
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: https://curl.se/docs/adv_20160127A.html
---
lib/url.c | 62 ++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 40 insertions(+), 22 deletions(-)
diff --git a/lib/url.c b/lib/url.c
index 02a7ace..42bf1eb 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -3126,16 +3126,21 @@ ConnectionExists(struct SessionHandle *data,
{
struct connectdata *check;
struct connectdata *chosen = 0;
bool foundPendingCandidate = FALSE;
bool canPipeline = IsPipeliningPossible(data, needle);
+ struct connectbundle *bundle;
+
#ifdef USE_NTLM
- bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
- (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
- (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
+ 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)));
#endif
- struct connectbundle *bundle;
*force_reuse = FALSE;
*waitpipe = FALSE;
/* We can't pipe if the site is blacklisted */
@@ -3186,13 +3191,10 @@ ConnectionExists(struct SessionHandle *data,
}
curr = bundle->conn_list->head;
while(curr) {
bool match = FALSE;
-#if defined(USE_NTLM)
- bool credentialsMatch = FALSE;
-#endif
size_t pipeLen;
/*
* Note that if we use a HTTP proxy, we check connections to that
* proxy and not to the actual remote server.
@@ -3298,25 +3300,18 @@ ConnectionExists(struct SessionHandle *data,
!needle->localdev ||
strcmp(check->localdev, needle->localdev))
continue;
}
- if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST))
-#ifdef USE_NTLM
- || (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)
-#endif
- ) {
- /* 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;
}
-#if defined(USE_NTLM)
- credentialsMatch = TRUE;
-#endif
}
if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
(needle->bits.httpproxy && check->bits.httpproxy &&
needle->bits.tunnel_proxy && check->bits.tunnel_proxy &&
@@ -3372,24 +3367,47 @@ ConnectionExists(struct SessionHandle *data,
already authenticating with the right credentials. If not, keep
looking so that we can reuse NTLM connections if
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
blacklisted. */
--
2.7.0