File handle-credential-partial-url-key.patch of Package git.37098
From 12294990c90e043862be9eb7eb22c3784b526340 Mon Sep 17 00:00:00 2001
From: Johannes Schindelin <johannes.schindelin@gmx.de>
Date: Fri, 24 Apr 2020 22:35:49 +0000
Subject: [PATCH] credential: handle `credential.<partial-URL>.<key>` again
In the patches for CVE-2020-11008, the ability to specify credential
settings in the config for partial URLs got lost. For example, it used
to be possible to specify a credential helper for a specific protocol:
[credential "https://"]
helper = my-https-helper
Likewise, it used to be possible to configure settings for a specific
host, e.g.:
[credential "dev.azure.com"]
useHTTPPath = true
Let's reinstate this behavior.
While at it, increase the test coverage to document and verify the
behavior with a couple other categories of partial URLs.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
credential.c | 27 +++++++++++++++++++++++++++
t/t0300-credentials.sh | 38 ++++++++++++++++++++++++++++++++++++++
urlmatch.c | 10 +++++++---
urlmatch.h | 5 +++++
4 files changed, 77 insertions(+), 3 deletions(-)
diff --git a/credential.c b/credential.c
index b8f693fa28821d..4e7197d97a96d2 100644
--- a/credential.c
+++ b/credential.c
@@ -37,6 +37,10 @@ int credential_match(const struct credential *want,
#undef CHECK
}
+
+static int credential_from_potentially_partial_url(struct credential *c,
+ const char *url);
+
static int credential_config_callback(const char *var, const char *value,
void *data)
{
@@ -82,6 +86,22 @@ static int select_all(const struct urlmatch_item *a,
return 0;
}
+static int match_partial_url(const char *url, void *cb)
+{
+ struct credential *c = cb;
+ struct credential want = CREDENTIAL_INIT;
+ int matches = 0;
+
+ if (credential_from_potentially_partial_url(&want, url) < 0)
+ warning(_("skipping credential lookup for key: credential.%s"),
+ url);
+ else
+ matches = credential_match(&want, c);
+ credential_clear(&want);
+
+ return matches;
+}
+
static void credential_apply_config(struct credential *c)
{
char *normalized_url;
@@ -101,6 +121,7 @@ static void credential_apply_config(struct credential *c)
config.collect_fn = credential_config_callback;
config.cascade_fn = NULL;
config.select_fn = select_all;
+ config.fallback_match_fn = match_partial_url;
config.cb = c;
credential_format(c, &url);
@@ -468,6 +489,12 @@ static int credential_from_url_1(struct credential *c, const char *url,
return 0;
}
+static int credential_from_potentially_partial_url(struct credential *c,
+ const char *url)
+{
+ return credential_from_url_1(c, url, 1, 0);
+}
+
int credential_from_url_gently(struct credential *c, const char *url, int quiet)
{
return credential_from_url_1(c, url, 0, quiet);
diff --git a/urlmatch.c b/urlmatch.c
index 29272a5c4f4d4a..33a2ccd306b6a7 100644
--- a/urlmatch.c
+++ b/urlmatch.c
@@ -572,10 +572,14 @@ int urlmatch_config_entry(const char *var, const char *value, void *cb)
config_url = xmemdupz(key, dot - key);
norm_url = url_normalize_1(config_url, &norm_info, 1);
+ if (norm_url)
+ retval = match_urls(url, &norm_info, &matched);
+ else if (collect->fallback_match_fn)
+ retval = collect->fallback_match_fn(config_url,
+ collect->cb);
+ else
+ retval = 0;
free(config_url);
- if (!norm_url)
- return 0;
- retval = match_urls(url, &norm_info, &matched);
free(norm_url);
if (!retval)
return 0;
diff --git a/urlmatch.h b/urlmatch.h
index 2407520731f9f0..6ff42f81b0c1e0 100644
--- a/urlmatch.h
+++ b/urlmatch.h
@@ -59,6 +59,11 @@ struct urlmatch_config {
* specificity rules) than existing.
*/
int (*select_fn)(const struct urlmatch_item *found, const struct urlmatch_item *existing);
+ /*
+ * An optional callback to allow e.g. for partial URLs; it shall
+ * return 1 or 0 depending whether `url` matches or not.
+ */
+ int (*fallback_match_fn)(const char *url, void *cb);
};
int urlmatch_config_entry(const char *var, const char *value, void *cb);