Skip to content

Commit c9e10b3

Browse files
committed
HTTP proxy: don't eagerly send a Basic auth header.
Now, we always try an initial CONNECT request with no auth at all, and wait for the proxy to reject it before sending a second try with auth. That way, we can wait to see what _kind_ of authentication the proxy requests, which will enable us to support something more secure than Basic, such as HTTP Digest. (I mean, it would _work_ to try Basic in request github#1 and then retrying with Digest in github#2 when the proxy asks for it. But if the aim of using Digest is to avoid sending the password in cleartext, it defeats the entire purpose to have sent it in cleartext anyway by the time you realise the server is prepared to do something better!)
1 parent 9a0b1fa commit c9e10b3

1 file changed

Lines changed: 17 additions & 3 deletions

File tree

proxy/http.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct HttpProxyNegotiator {
4949
strbuf *username, *password;
5050
int http_status;
5151
bool connection_close;
52+
bool tried_no_auth, try_auth_from_conf;
5253
prompts_t *prompts;
5354
int username_prompt_index, password_prompt_index;
5455
size_t content_length;
@@ -160,6 +161,8 @@ static void proxy_http_process_queue(ProxyNegotiator *pn)
160161
*/
161162
put_dataz(s->username, conf_get_str(pn->ps->conf, CONF_proxy_username));
162163
put_dataz(s->password, conf_get_str(pn->ps->conf, CONF_proxy_password));
164+
if (s->username->len || s->password->len)
165+
s->try_auth_from_conf = true;
163166

164167
while (true) {
165168
/*
@@ -175,10 +178,12 @@ static void proxy_http_process_queue(ProxyNegotiator *pn)
175178
}
176179

177180
/*
178-
* Optionally send an HTTP Basic auth header with the username and
179-
* password.
181+
* Optionally send an HTTP Basic auth header with the username
182+
* and password. We do this only after we've first tried no
183+
* authentication at all (even if we have a password to start
184+
* with).
180185
*/
181-
{
186+
if (s->tried_no_auth) {
182187
if (s->username->len || s->password->len) {
183188
put_datalit(pn->output, "Proxy-Authorization: Basic ");
184189

@@ -197,6 +202,8 @@ static void proxy_http_process_queue(ProxyNegotiator *pn)
197202
smemclr(base64_output, sizeof(base64_output));
198203
put_datalit(pn->output, "\r\n");
199204
}
205+
} else {
206+
s->tried_no_auth = true;
200207
}
201208

202209
/*
@@ -300,6 +307,13 @@ static void proxy_http_process_queue(ProxyNegotiator *pn)
300307
crStopV;
301308
}
302309

310+
/* If we have auth details from the Conf and haven't tried
311+
* them yet, that's our first step. */
312+
if (s->try_auth_from_conf) {
313+
s->try_auth_from_conf = false;
314+
continue;
315+
}
316+
303317
/* Either we never had a password in the first place, or
304318
* the one we already presented was rejected. We can only
305319
* proceed from here if we have a way to ask the user

0 commit comments

Comments
 (0)