]> git.ipfire.org Git - thirdparty/git.git/commitdiff
credential: handle `credential.<partial-URL>.<key>` again
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Fri, 24 Apr 2020 11:49:52 +0000 (11:49 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 29 Apr 2020 15:37:36 +0000 (08:37 -0700)
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>
Reviewed-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
credential.c
t/t0300-credentials.sh

index 7dbbf26f1748717d8b5fddb1f7543192e183e0fe..c1a9ca4e4852bd752f70d7d6ec39388bcd709a6a 100644 (file)
@@ -35,6 +35,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)
 {
@@ -53,7 +57,13 @@ static int credential_config_callback(const char *var, const char *value,
                char *url = xmemdupz(key, dot - key);
                int matched;
 
-               credential_from_url(&want, url);
+               if (credential_from_potentially_partial_url(&want, url) < 0) {
+                       warning(_("skipping credential lookup for key: %s"),
+                               var);
+                       credential_clear(&want);
+                       free(url);
+                       return 0;
+               }
                matched = credential_match(&want, c);
 
                credential_clear(&want);
@@ -430,6 +440,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);
index efed3ea2955a80b75dbdf646752cd1093d21faaa..da4b315d6dcab7fa44c665d9c8544cb9687c24c3 100755 (executable)
@@ -448,4 +448,42 @@ test_expect_success 'credential system refuses to work with missing protocol' '
        test_i18ncmp expect stderr
 '
 
+test_expect_success 'credential config with partial URLs' '
+       echo "echo password=yep" | write_script git-credential-yep &&
+       test_write_lines url=https://user@example.com/repo.git >stdin &&
+       for partial in \
+               example.com \
+               user@example.com \
+               https:// \
+               https://example.com \
+               https://example.com/ \
+               https://user@example.com \
+               https://user@example.com/ \
+               https://example.com/repo.git \
+               https://user@example.com/repo.git \
+               /repo.git
+       do
+               git -c credential.$partial.helper=yep \
+                       credential fill <stdin >stdout &&
+               grep yep stdout ||
+               return 1
+       done &&
+
+       for partial in \
+               dont.use.this \
+               http:// \
+               /repo
+       do
+               git -c credential.$partial.helper=yep \
+                       credential fill <stdin >stdout &&
+               ! grep yep stdout ||
+               return 1
+       done &&
+
+       git -c credential.$partial.helper=yep \
+               -c credential.with%0anewline.username=uh-oh \
+               credential fill <stdin >stdout 2>stderr &&
+       test_i18ngrep "skipping credential lookup for key" stderr
+'
+
 test_done