http: add option to try authentication without username
authorbrian m. carlson <sandals@crustytoothpaste.net>
Mon, 15 Feb 2016 18:44:46 +0000 (18:44 +0000)
committerJunio C Hamano <gitster@pobox.com>
Mon, 15 Feb 2016 22:13:37 +0000 (14:13 -0800)
Performing GSS-Negotiate authentication using Kerberos does not require
specifying a username or password, since that information is already
included in the ticket itself. However, libcurl refuses to perform
authentication if it has not been provided with a username and password.
Add an option, http.emptyAuth, that provides libcurl with an empty
username and password to make it attempt authentication anyway.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/config.txt
http.c
index f61788668e89b659439e2fa5d600aebabdd733a5..d9abfbb4277ac93b5697ccd2e8299c8c5d17ae66 100644 (file)
@@ -1600,6 +1600,12 @@ http.proxy::
        `curl(1)`).  This can be overridden on a per-remote basis; see
        remote.<name>.proxy
 
+http.emptyAuth::
+       Attempt authentication without seeking a username or password.  This
+       can be used to attempt GSS-Negotiate authentication without specifying
+       a username in the URL, as libcurl normally requires a username for
+       authentication.
+
 http.cookieFile::
        File containing previously stored cookie lines which should be used
        in the Git http session, if they match the server. The file format
diff --git a/http.c b/http.c
index 0da9e6639832a493f932e3ba332683d3d4ae73ae..fe494ab36c6828ff2a6123b087877a3884fdb61c 100644 (file)
--- a/http.c
+++ b/http.c
@@ -67,6 +67,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;
 
 #if LIBCURL_VERSION_NUM >= 0x071700
 /* Use CURLOPT_KEYPASSWD as is */
@@ -273,14 +274,22 @@ static int http_options(const char *var, const char *value, void *cb)
        if (!strcmp("http.useragent", var))
                return git_config_string(&user_agent, var, value);
 
+       if (!strcmp("http.emptyauth", var)) {
+               curl_empty_auth = git_config_bool(var, value);
+               return 0;
+       }
+
        /* Fall back on the default ones */
        return git_default_config(var, value, cb);
 }
 
 static void init_curl_http_auth(CURL *result)
 {
-       if (!http_auth.username)
+       if (!http_auth.username) {
+               if (curl_empty_auth)
+                       curl_easy_setopt(result, CURLOPT_USERPWD, ":");
                return;
+       }
 
        credential_fill(&http_auth);
 
@@ -695,7 +704,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)
+       if (http_auth.password || curl_empty_auth)
                init_curl_http_auth(slot->curl);
 
        return slot;