Skip to content

Commit

Permalink
Merge branch 'emptyauth-auto'
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
dscho committed Feb 25, 2017
2 parents ed710b9 + 44ae0bc commit d4baef1
Showing 1 changed file with 47 additions and 4 deletions.
51 changes: 47 additions & 4 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ static int curl_save_cookies;
struct credential http_auth = CREDENTIAL_INIT;
static int http_proactive_auth;
static const char *user_agent;
static int curl_empty_auth = 1;
static int curl_empty_auth = -1;

enum http_follow_config http_follow_config = HTTP_FOLLOW_INITIAL;

Expand All @@ -125,6 +125,7 @@ static struct credential cert_auth = CREDENTIAL_INIT;
static int ssl_cert_password_required;
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
static unsigned long http_auth_methods = CURLAUTH_ANY;
static int http_auth_methods_restricted;
#endif

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

if (!strcmp("http.emptyauth", var)) {
curl_empty_auth = git_config_bool(var, value);
if (value && !strcmp("auto", value))
curl_empty_auth = -1;
else
curl_empty_auth = git_config_bool(var, value);
return 0;
}

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

static int curl_empty_auth_enabled(void)
{
if (curl_empty_auth >= 0)
return curl_empty_auth;

#ifndef LIBCURL_CAN_HANDLE_AUTH_ANY
/*
* Our libcurl is too old to do AUTH_ANY in the first place;
* just default to turning the feature off.
*/
#else
/*
* In the automatic case, kick in the empty-auth
* hack as long as we would potentially try some
* method more exotic than "Basic".
*
* But only do this when this is our second or
* subsequent * request, as by then we know what
* methods are available.
*/
if (http_auth_methods_restricted)
switch (http_auth_methods) {
case CURLAUTH_BASIC:
case CURLAUTH_DIGEST:
#ifdef CURLAUTH_DIGEST_IE
case CURLAUTH_DIGEST_IE:
#endif
return 0;
default:
return 1;
}
#endif
return 0;
}

static void init_curl_http_auth(CURL *result)
{
if (!http_auth.username || !*http_auth.username) {
if (curl_empty_auth)
if (curl_empty_auth_enabled())
curl_easy_setopt(result, CURLOPT_USERPWD, ":");
return;
}
Expand Down Expand Up @@ -1079,7 +1118,7 @@ struct active_request_slot *get_active_slot(void)
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH, http_auth_methods);
#endif
if (http_auth.password || curl_empty_auth)
if (http_auth.password || curl_empty_auth_enabled())
init_curl_http_auth(slot->curl);

return slot;
Expand Down Expand Up @@ -1347,6 +1386,10 @@ static int handle_curl_result(struct slot_results *results)
} else {
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE;
if (results->auth_avail) {
http_auth_methods &= results->auth_avail;
http_auth_methods_restricted = 1;
}
#endif
return HTTP_REAUTH;
}
Expand Down

0 comments on commit d4baef1

Please sign in to comment.