Re: GIT, libcurl and GSS-Negotiate

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, May 16, 2014 at 10:34:10PM +0000, brian m. carlson wrote:

> > The tricky part is figuring out when to return HTTP_NOAUTH ("do not try
> > again, we failed") versus HTTP_REAUTH ("get credentials and try again")
> > in handle_curl_result. Right now the decision is based on "did we have a
> > username and password for this request?" I'm not clear on what extra
> > bits would be needed to decide to continue in the case you guys are
> > discussing.
> 
> I'm honestly not sure, either.  That's why I said, "how to do that is
> unknown".
> 
> However, if you base64-decode the two Negotiate replies in the
> successful attempt with WinHTTP and pass it through od -tc, you'll see
> that the second reply contains some form of user ID that the first one
> does not.  The curl binary sends an identical reply for the first pass,
> but then gives up and does not try a second pass.  I don't know if
> libcurl is able to provide the data required in the second pass.
> 
> All of this is way outside my knowledge, since my Kerberos/GSSAPI
> Negotiate requests look very different than the NTLM ones.

Mine too. I think a good place to start would be somebody who has a
setup to replicate the problem dumping the curl data (either from
GIT_CURL_VERBOSE, or instrumenting git with some curl_easy_getinfo
calls), and seeing what is interesting.

> > Yeah, we just set CURLAUTH_ANY now, but it would be fairly trivial to
> > add "http.authtype" and "http.proxyauthtype" to map to CURLOPT_HTTPAUTH
> > and CURLOPT_PROXYAUTH.
> 
> This might be the easiest option.

I can help with working up a patch, but I don't have any meaningful way
to test it.

The patch below might help somebody get started. I don't know if
CURLAUTH_ONLY would be useful to be able to set, too.

diff --git a/http.c b/http.c
index 94e1afd..ba56f7e 100644
--- a/http.c
+++ b/http.c
@@ -51,6 +51,9 @@ struct credential http_auth = CREDENTIAL_INIT;
 static int http_proactive_auth;
 static const char *user_agent;
 
+static long curl_http_authtype;
+static long curl_proxy_authtype;
+
 #if LIBCURL_VERSION_NUM >= 0x071700
 /* Use CURLOPT_KEYPASSWD as is */
 #elif LIBCURL_VERSION_NUM >= 0x070903
@@ -143,6 +146,37 @@ static void process_curl_messages(void)
 }
 #endif
 
+static int parse_auth_type(const char *var, const char *value, long *type)
+{
+	static struct {
+		const char *name;
+		long value;
+	} types[] = {
+		 { "basic", CURLAUTH_BASIC },
+		 { "digest", CURLAUTH_DIGEST },
+#if CURL_VERSION >= 0x071303
+		 { "digest-ie", CURLAUTH_DIGEST_IE },
+#endif
+		 { "negotiate", CURLAUTH_GSSNEGOTIATE },
+#if CURL_VERSION >= 0x071600
+		 { "ntlm-wb", CURLAUTH_NTLM_WB },
+#endif
+		 { "ntlm", CURLAUTH_NTLM }
+	};
+	int i;
+
+	if (!value)
+		return config_error_nonbool(var);
+
+	for (i = 0; i < ARRAY_SIZE(types); i++)
+		if (!strcmp(value, types[i].name))
+			*type |= types[i].value;
+
+	if (i == ARRAY_SIZE(types))
+		return error("unknown auth type for '%s': %s", var, value);
+	return 0;
+}
+
 static int http_options(const char *var, const char *value, void *cb)
 {
 	if (!strcmp("http.sslverify", var)) {
@@ -216,6 +250,11 @@ 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.authtype", var))
+		return parse_auth_type(var, value, &curl_http_authtype);
+	if (!strcmp("http.proxyauthtype", var))
+		return parse_auth_type(var, value, &curl_proxy_authtype);
+
 	/* Fall back on the default ones */
 	return git_default_config(var, value, cb);
 }
@@ -296,6 +335,17 @@ static void set_curl_keepalive(CURL *c)
 }
 #endif
 
+static void set_curl_authtype(CURL *c, CURLoption option, long value)
+{
+	if (value)
+		curl_easy_setopt(c, option, value);
+	else {
+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
+		curl_easy_setopt(c, option, CURLAUTH_ANY);
+#endif
+	}
+}
+
 static CURL *get_curl_handle(void)
 {
 	CURL *result = curl_easy_init();
@@ -313,8 +363,13 @@ static CURL *get_curl_handle(void)
 #if LIBCURL_VERSION_NUM >= 0x070907
 	curl_easy_setopt(result, CURLOPT_NETRC, CURL_NETRC_OPTIONAL);
 #endif
-#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
-	curl_easy_setopt(result, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+
+#if LIBCURL_VERSION_NUM >= 0x070a06
+	set_curl_authtype(result, CURLOPT_HTTPAUTH, curl_http_authtype);
+#endif
+
+#if LIBCURL_VERSION_NUM >= 0x070a07
+	set_curl_authtype(result, CURLOPT_PROXYAUTH, curl_proxy_authtype);
 #endif
 
 	if (http_proactive_auth)
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]