git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] remote-curl: fall back to Basic auth if Negotiate fails
@ 2015-01-01 19:56 brian m. carlson
  2015-01-08  0:29 ` [PATCH v3] " brian m. carlson
  0 siblings, 1 reply; 18+ messages in thread
From: brian m. carlson @ 2015-01-01 19:56 UTC (permalink / raw)
  To: git; +Cc: Dan Langille (dalangil), Jeff King, Jonathan Nieder,
	Junio C Hamano

Apache servers using mod_auth_kerb can be configured to allow the user
to authenticate either using Negotiate (using the Kerberos ticket) or
Basic authentication (using the Kerberos password).  Often, one will
want to use Negotiate authentication if it is available, but fall back
to Basic authentication if the ticket is missing or expired.

However, libcurl will try very hard to use something other than Basic
auth, even over HTTPS.  If Basic and something else are offered, libcurl
will never attempt to use Basic, even if the other option fails.
Teach the HTTP client code to stop trying authentication mechanisms that
don't use a password (currently Negotiate) after the first failure,
since if they failed the first time, they will never succeed.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 http.c        | 16 ++++++++++++++++
 http.h        |  3 +++
 remote-curl.c | 11 ++++++++++-
 3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/http.c b/http.c
index 040f362..815194d 100644
--- a/http.c
+++ b/http.c
@@ -62,6 +62,8 @@ static const char *user_agent;
 
 static struct credential cert_auth = CREDENTIAL_INIT;
 static int ssl_cert_password_required;
+/* Should we allow non-password-based authentication (e.g. GSSAPI)? */
+int http_passwordless_auth = 1;
 
 static struct curl_slist *pragma_header;
 static struct curl_slist *no_pragma_header;
@@ -986,6 +988,16 @@ static void extract_content_type(struct strbuf *raw, struct strbuf *type,
 		strbuf_addstr(charset, "ISO-8859-1");
 }
 
+void disable_passwordless_auth(struct active_request_slot *slot)
+{
+#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
+#define HTTP_AUTH_PASSWORDLESS (CURLAUTH_GSSNEGOTIATE)
+	curl_easy_setopt(slot->curl, CURLOPT_HTTPAUTH,
+			 CURLAUTH_ANY & ~HTTP_AUTH_PASSWORDLESS);
+#endif
+}
+
+
 /* http_request() targets */
 #define HTTP_REQUEST_STRBUF	0
 #define HTTP_REQUEST_FILE	1
@@ -1035,6 +1047,9 @@ static int http_request(const char *url,
 	curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
 	curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
 
+	if (!http_passwordless_auth)
+		disable_passwordless_auth(slot);
+
 	ret = run_one_slot(slot, &results);
 
 	if (options && options->content_type) {
@@ -1139,6 +1154,7 @@ static int http_request_reauth(const char *url,
 	}
 
 	credential_fill(&http_auth);
+	http_passwordless_auth = 0;
 
 	return http_request(url, result, target, options);
 }
diff --git a/http.h b/http.h
index 473179b..71943d3 100644
--- a/http.h
+++ b/http.h
@@ -98,6 +98,8 @@ extern int handle_curl_result(struct slot_results *results);
 int run_one_slot(struct active_request_slot *slot,
 		 struct slot_results *results);
 
+void disable_passwordless_auth(struct active_request_slot *slot);
+
 #ifdef USE_CURL_MULTI
 extern void fill_active_slots(void);
 extern void add_fill_function(void *data, int (*fill)(void *));
@@ -112,6 +114,7 @@ extern int active_requests;
 extern int http_is_verbose;
 extern size_t http_post_buffer;
 extern struct credential http_auth;
+extern int http_passwordless_auth;
 
 extern char curl_errorstr[CURL_ERROR_SIZE];
 
diff --git a/remote-curl.c b/remote-curl.c
index dd63bc2..4ca5447 100644
--- a/remote-curl.c
+++ b/remote-curl.c
@@ -467,6 +467,9 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results)
 	curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer);
 	curl_easy_setopt(slot->curl, CURLOPT_FILE, &buf);
 
+	if (!http_passwordless_auth)
+		disable_passwordless_auth(slot);
+
 	err = run_slot(slot, results);
 
 	curl_slist_free_all(headers);
@@ -510,8 +513,10 @@ static int post_rpc(struct rpc_state *rpc)
 
 		do {
 			err = probe_rpc(rpc, &results);
-			if (err == HTTP_REAUTH)
+			if (err == HTTP_REAUTH) {
 				credential_fill(&http_auth);
+				http_passwordless_auth = 0;
+			}
 		} while (err == HTTP_REAUTH);
 		if (err != HTTP_OK)
 			return -1;
@@ -533,6 +538,9 @@ retry:
 	curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
 	curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
 
+	if (!http_passwordless_auth)
+		disable_passwordless_auth(slot);
+
 	if (large_request) {
 		/* The request body is large and the size cannot be predicted.
 		 * We must use chunked encoding to send it.
@@ -617,6 +625,7 @@ retry:
 	err = run_slot(slot, NULL);
 	if (err == HTTP_REAUTH && !large_request) {
 		credential_fill(&http_auth);
+		http_passwordless_auth = 0;
 		goto retry;
 	}
 	if (err != HTTP_OK)
-- 
2.2.1.209.g41e5f3a

^ permalink raw reply related	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2021-03-22 16:18 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <pull.849.git.1611921008282.gitgitgadget@gmail.com>
2021-02-16 16:57 ` [PATCH v2] remote-curl: fall back to basic auth if Negotiate fails Christopher via GitGitGadget
2021-03-22 11:51   ` [PATCH v3] " Christopher via GitGitGadget
     [not found]   ` <xmqq35xvpr8q.fsf@gitster.c.googlers.com>
2021-03-22 16:08     ` [PATCH v2] " Christopher Schenk
2015-01-01 19:56 [PATCH v2] remote-curl: fall back to Basic " brian m. carlson
2015-01-08  0:29 ` [PATCH v3] " brian m. carlson
2015-01-20 16:40   ` Dan Langille (dalangil)
2015-01-21  0:22     ` Junio C Hamano
2015-01-22 14:47       ` Dan Langille (dalangil)
2015-02-17 23:05       ` Dan Langille (dalangil)
2015-02-17 23:36         ` Junio C Hamano
2015-02-18 16:17           ` Dan Langille (dalangil)
2015-02-19 20:35             ` brian m. carlson
2015-02-24 21:03               ` Dan Langille (dalangil)
2015-02-25 20:59                 ` Dan Langille (dalangil)
2015-03-10 18:05                   ` Dan Langille (dalangil)
2015-03-10 22:29                     ` brian m. carlson
2015-03-11 19:33                       ` Dan Langille (dalangil)
2015-03-11 21:59                         ` brian m. carlson
2015-03-12 13:09                           ` Dan Langille (dalangil)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).