Skip to content

Commit d4baef1

Browse files
committed
Merge branch 'emptyauth-auto'
An earlier attempt to support NTLM authentication better (by setting http.emptyauth=true always) failed to take into account that some servers that support only Basic authentication may be very unhappy about those "empty credentials". Jeff King came up with a beautiful fix; this topic branch reverts our earlier attempt at fixing the problem and applies those patches instead. Signed-off-by: Johannes Schindelin <[email protected]>
2 parents ed710b9 + 44ae0bc commit d4baef1

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

http.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ static int curl_save_cookies;
109109
struct credential http_auth = CREDENTIAL_INIT;
110110
static int http_proactive_auth;
111111
static const char *user_agent;
112-
static int curl_empty_auth = 1;
112+
static int curl_empty_auth = -1;
113113

114114
enum http_follow_config http_follow_config = HTTP_FOLLOW_INITIAL;
115115

@@ -125,6 +125,7 @@ static struct credential cert_auth = CREDENTIAL_INIT;
125125
static int ssl_cert_password_required;
126126
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
127127
static unsigned long http_auth_methods = CURLAUTH_ANY;
128+
static int http_auth_methods_restricted;
128129
#endif
129130

130131
static struct curl_slist *pragma_header;
@@ -333,7 +334,10 @@ static int http_options(const char *var, const char *value, void *cb)
333334
return git_config_string(&user_agent, var, value);
334335

335336
if (!strcmp("http.emptyauth", var)) {
336-
curl_empty_auth = git_config_bool(var, value);
337+
if (value && !strcmp("auto", value))
338+
curl_empty_auth = -1;
339+
else
340+
curl_empty_auth = git_config_bool(var, value);
337341
return 0;
338342
}
339343

@@ -382,10 +386,45 @@ static int http_options(const char *var, const char *value, void *cb)
382386
return git_default_config(var, value, cb);
383387
}
384388

389+
static int curl_empty_auth_enabled(void)
390+
{
391+
if (curl_empty_auth >= 0)
392+
return curl_empty_auth;
393+
394+
#ifndef LIBCURL_CAN_HANDLE_AUTH_ANY
395+
/*
396+
* Our libcurl is too old to do AUTH_ANY in the first place;
397+
* just default to turning the feature off.
398+
*/
399+
#else
400+
/*
401+
* In the automatic case, kick in the empty-auth
402+
* hack as long as we would potentially try some
403+
* method more exotic than "Basic".
404+
*
405+
* But only do this when this is our second or
406+
* subsequent * request, as by then we know what
407+
* methods are available.
408+
*/
409+
if (http_auth_methods_restricted)
410+
switch (http_auth_methods) {
411+
case CURLAUTH_BASIC:
412+
case CURLAUTH_DIGEST:
413+
#ifdef CURLAUTH_DIGEST_IE
414+
case CURLAUTH_DIGEST_IE:
415+
#endif
416+
return 0;
417+
default:
418+
return 1;
419+
}
420+
#endif
421+
return 0;
422+
}
423+
385424
static void init_curl_http_auth(CURL *result)
386425
{
387426
if (!http_auth.username || !*http_auth.username) {
388-
if (curl_empty_auth)
427+
if (curl_empty_auth_enabled())
389428
curl_easy_setopt(result, CURLOPT_USERPWD, ":");
390429
return;
391430
}
@@ -1079,7 +1118,7 @@ struct active_request_slot *get_active_slot(void)
10791118
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
10801119
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
10811120
#endif
1082-
if (http_auth.password || curl_empty_auth)
1121+
if (http_auth.password || curl_empty_auth_enabled())
10831122
init_curl_http_auth(slot->curl);
10841123

10851124
return slot;
@@ -1347,6 +1386,10 @@ static int handle_curl_result(struct slot_results *results)
13471386
} else {
13481387
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
13491388
http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE;
1389+
if (results->auth_avail) {
1390+
http_auth_methods &= results->auth_avail;
1391+
http_auth_methods_restricted = 1;
1392+
}
13501393
#endif
13511394
return HTTP_REAUTH;
13521395
}

0 commit comments

Comments
 (0)