mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-11-07 05:57:07 -08:00
Closes: https://bugs.gentoo.org/984287 Signed-off-by: Sam James <sam@gentoo.org>
139 lines
4.7 KiB
Diff
139 lines
4.7 KiB
Diff
https://bugs.gentoo.org/984287
|
|
https://github.com/git/git/commit/76524c2604bceee48481909e7824494498c39a34
|
|
|
|
From 76524c2604bceee48481909e7824494498c39a34 Mon Sep 17 00:00:00 2001
|
|
From: Jeff King <peff@peff.net>
|
|
Date: Mon, 28 Sep 2026 00:01:49 -0400
|
|
Subject: [PATCH] http: handle curl stripping creds from effective url
|
|
|
|
When we detect that curl performed a redirect of a URL we requested, we
|
|
update our base URL to match the new location and flush the http_auth
|
|
credentials. This goes back to c93c92f309 (http: update base URLs when
|
|
we see redirects, 2013-09-28).
|
|
|
|
We detect the redirect by comparing the requested URL to the response
|
|
from CURLINFO_EFFECTIVE_URL, using a simple string comparison. This has
|
|
worked fine for years, but a change in the upcoming curl 8.23.0 adds a
|
|
complication. If our URL directly contains credentials (like
|
|
"https://user:pass@example.com/foo.git"), then as of 7a6bd027d0
|
|
(getinfo: make sure CURLINFO_EFFECTIVE_URL does not contain creds,
|
|
2026-09-21), curl will strip the credentials from what it returns (so
|
|
just "https://example.com/foo.git" in this case).
|
|
|
|
This breaks our direct string comparison, and we believe that we've been
|
|
redirected. We flush our http_auth credentials, and now subsequent
|
|
requests will use the reduced URL, causing us to re-request credentials
|
|
from the user. Notably this causes t5550.15 (among others) to complain;
|
|
it tries a clone with credentials in the URL, and fails if the user is
|
|
prompted at all.
|
|
|
|
We can handle this new behavior by doing a more careful comparison: if
|
|
the direct string comparison fails, we'll strip out the credentials
|
|
ourselves and compare. This is a little extra work, but in practice it
|
|
should only happen once per process.
|
|
|
|
I've used curl's curl_url() interface to do the stripping here, mostly
|
|
because its behavior should match the stripping it does internally. And
|
|
also, though we have code to parse a URL, we don't have any to
|
|
reconstruct it, making a single string comparison hard.
|
|
|
|
One alternative would be to parse with url_parse() or similar, and
|
|
compare the individual fields (skipping username/password). I think that
|
|
would probably also work in practice, but it seemed to me that the
|
|
simplest change would be sticking with string comparisons.
|
|
|
|
The curl_url() interface appeared in 7.62.0. We document that 7.61.0 is
|
|
still supported, so I've made it conditional here. Only new versions
|
|
strip the result from CURLINFO_EFFECTIVE_URL, so it's OK for very old
|
|
versions to skip the extra comparison. Likewise if we encounter any
|
|
errors, we just quietly skip the comparison. That's fine if you don't
|
|
have creds in your URLs, and if you do, you'll get end up in the
|
|
existing error path (a redirect warning, and eventually an auth
|
|
failure).
|
|
|
|
Signed-off-by: Jeff King <peff@peff.net>
|
|
Signed-off-by: Junio C Hamano <gitster@pobox.com>
|
|
---
|
|
git-curl-compat.h | 7 +++++++
|
|
http.c | 41 ++++++++++++++++++++++++++++++++++++++++-
|
|
2 files changed, 47 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/git-curl-compat.h b/git-curl-compat.h
|
|
index 032aaf7126c977..25678b5dbd2c80 100644
|
|
--- a/git-curl-compat.h
|
|
+++ b/git-curl-compat.h
|
|
@@ -28,6 +28,13 @@
|
|
* introduced, oldest first, in the official version of cURL library.
|
|
*/
|
|
|
|
+/**
|
|
+ * curl_url() interface added in 7.62.0 (October 2018)
|
|
+ */
|
|
+#if LIBCURL_VERSION_NUM >= 0x073e00
|
|
+#define GIT_CURL_HAVE_CURL_URL
|
|
+#endif
|
|
+
|
|
/**
|
|
* Versions before curl 7.66.0 (September 2019) required manually setting the
|
|
* transfer-encoding for a streaming POST; after that this is handled
|
|
diff --git a/http.c b/http.c
|
|
index c8fcfd7693e897..4af3c29c769559 100644
|
|
--- a/http.c
|
|
+++ b/http.c
|
|
@@ -2315,6 +2315,45 @@ static int http_request(const char *url,
|
|
return ret;
|
|
}
|
|
|
|
+#ifndef GIT_CURL_HAVE_CURL_URL
|
|
+#define strip_url_credential(in) NULL
|
|
+#else
|
|
+static char *strip_url_credential(const char *in)
|
|
+{
|
|
+ char *ret = NULL;
|
|
+ CURLU *url;
|
|
+
|
|
+ url = curl_url();
|
|
+ if (!url)
|
|
+ goto out;
|
|
+
|
|
+ if (curl_url_set(url, CURLUPART_URL, in, 0))
|
|
+ goto out;
|
|
+
|
|
+ curl_url_set(url, CURLUPART_USER, NULL, 0);
|
|
+ curl_url_set(url, CURLUPART_PASSWORD, NULL, 0);
|
|
+ curl_url_get(url, CURLUPART_URL, &ret, 0);
|
|
+
|
|
+out:
|
|
+ curl_url_cleanup(url);
|
|
+ return ret;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static int match_effective_url(const char *asked, const char *got)
|
|
+{
|
|
+ char *stripped;
|
|
+ int ret;
|
|
+
|
|
+ if (!strcmp(asked, got))
|
|
+ return 1;
|
|
+
|
|
+ stripped = strip_url_credential(asked);
|
|
+ ret = stripped && !strcmp(stripped, got);
|
|
+ curl_free(stripped);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
/*
|
|
* Update the "base" url to a more appropriate value, as deduced by
|
|
* redirects seen when requesting a URL starting with "url".
|
|
@@ -2347,7 +2386,7 @@ static int update_url_from_redirect(struct strbuf *base,
|
|
const char *tail;
|
|
size_t new_len;
|
|
|
|
- if (!strcmp(asked, got->buf))
|
|
+ if (match_effective_url(asked, got->buf))
|
|
return 0;
|
|
|
|
if (!skip_prefix(asked, base->buf, &tail))
|
|
|