1 From d41dcba4e9b69d6b761e3460cc6ae7e8fd8f621f Mon Sep 17 00:00:00 2001
2 From: Isaac Boukris <iboukris@gmail.com>
3 Date: Wed, 13 Jan 2016 11:05:51 +0200
4 Subject: [PATCH] NTLM: Fix ConnectionExists to compare Proxy credentials
6 Proxy NTLM authentication should compare credentials when
7 re-using a connection similar to host authentication, as it
8 authenticate the connection.
11 curl -v -x http://proxy:port http://host/ -U good_user:good_pwd
12 --proxy-ntlm --next -x http://proxy:port http://host/
13 [-U fake_user:fake_pwd --proxy-ntlm]
17 Bug: http://curl.haxx.se/docs/adv_20160127A.html
19 lib/url.c | 62 ++++++++++++++++++++++++++++++++++++++++----------------------
20 1 file changed, 40 insertions(+), 22 deletions(-)
24 @@ -3044,11 +3044,16 @@ ConnectionExists(struct SessionHandle *d
25 struct connectdata *check;
26 struct connectdata *chosen = 0;
27 bool canPipeline = IsPipeliningPossible(data, needle);
28 - bool wantNTLMhttp = ((data->state.authhost.want & CURLAUTH_NTLM) ||
29 - (data->state.authhost.want & CURLAUTH_NTLM_WB)) &&
30 - (needle->handler->protocol & PROTO_FAMILY_HTTP) ? TRUE : FALSE;
31 struct connectbundle *bundle;
33 + bool wantNTLMhttp = ((data->state.authhost.want &
34 + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
35 + (needle->handler->protocol & PROTO_FAMILY_HTTP));
36 + bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd &&
37 + ((data->state.authproxy.want &
38 + (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) &&
39 + (needle->handler->protocol & PROTO_FAMILY_HTTP)));
43 /* We can't pipe if the site is blacklisted */
44 @@ -3077,9 +3082,6 @@ ConnectionExists(struct SessionHandle *d
45 curr = bundle->conn_list->head;
48 -#if defined(USE_NTLM)
49 - bool credentialsMatch = FALSE;
54 @@ -3185,21 +3187,14 @@ ConnectionExists(struct SessionHandle *d
57 if((!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) ||
58 -#if defined(USE_NTLM)
59 - (wantNTLMhttp || check->ntlm.state != NTLMSTATE_NONE)) {
63 - /* This protocol requires credentials per connection or is HTTP+NTLM,
64 + /* This protocol requires credentials per connection,
65 so verify that we're using the same name and password as well */
66 if(!strequal(needle->user, check->user) ||
67 !strequal(needle->passwd, check->passwd)) {
68 /* one of them was different */
71 -#if defined(USE_NTLM)
72 - credentialsMatch = TRUE;
76 if(!needle->bits.httpproxy || needle->handler->flags&PROTOPT_SSL ||
77 @@ -3258,20 +3253,43 @@ ConnectionExists(struct SessionHandle *d
78 possible. (Especially we must not reuse the same connection if
79 partway through a handshake!) */
81 - if(credentialsMatch && check->ntlm.state != NTLMSTATE_NONE) {
83 + if(!strequal(needle->user, check->user) ||
84 + !strequal(needle->passwd, check->passwd))
87 + else if(check->ntlm.state != NTLMSTATE_NONE) {
88 + /* Connection is using NTLM auth but we don't want NTLM */
92 + /* Same for Proxy NTLM authentication */
93 + if(wantProxyNTLMhttp) {
94 + if(!strequal(needle->proxyuser, check->proxyuser) ||
95 + !strequal(needle->proxypasswd, check->proxypasswd))
98 + else if(check->proxyntlm.state != NTLMSTATE_NONE) {
99 + /* Proxy connection is using NTLM auth but we don't want NTLM */
103 + if(wantNTLMhttp || wantProxyNTLMhttp) {
104 + /* Credentials are already checked, we can use this connection */
107 + if((wantNTLMhttp &&
108 + (check->ntlm.state != NTLMSTATE_NONE)) ||
109 + (wantProxyNTLMhttp &&
110 + (check->proxyntlm.state != NTLMSTATE_NONE))) {
111 /* We must use this connection, no other */
115 - else if(credentialsMatch)
116 - /* this is a backup choice */
119 + /* Continue look up for a better connection */
125 /* We can pipeline if we want to. Let's continue looking for
126 the optimal connection to use, i.e the shortest pipe that is not