mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <>
To: Johannes Schindelin <>
Cc: "Ævar Arnfjörð Bjarmason" <>,
	"Martin Langhoff" <>,
	"Git Mailing List" <>
Subject: [PATCH 3/3] clone: auto-enable git-credential-store when necessary
Date: Sun, 19 May 2019 01:16:04 -0400	[thread overview]
Message-ID: <> (raw)
In-Reply-To: <>

If the user clones with a URL containing a password and has no
credential helper configured, we're stuck. We don't want to write the
password into .git/config because that risks accidentally disclosing it.
But if we don't record it somewhere, subsequent fetches will fail unless
the user is there to input the password.

The best advice we can give the user is to set up a credential helper.
But we can actually go a step further and enable the "store" helper for
them. This still records the password in plaintext, but:

  1. It's not inside the repo directory, which makes it slightly less
     likely to be disclosed.

  2. The permissions on the storage file are tighter than what would be
     on .git/config.

So this is generally a security win over the old behavior of writing it
into .git/config. And it's a usability win over the more recent behavior
of just forgetting the password entirely.

The biggest downside is that it's a bit magical from the user's
perspective, because now the password is off in some other file (usually
~/.git-credentials, but sometimes in $XDG_CONFIG_HOME). Which
complicates things if they want to purge the repo and password, for
example, because now they can't just delete the repository directory.

The file location is documented, though, and we point people to the
documentation. So perhaps it will be enough (and better still, may lead
to them configuring a more secure helper).

Signed-off-by: Jeff King <>
If we do decide this is too magical, I think the best alternate path is
to advise them on credential helpers, and how to seed the password into
the helper (basically configure the helper and then "git fetch"
should work).

One other thing I wondered: if they do have a helper configured this
patch will omit the advice entirely, but we'll still print the warning.
Is that useful (to remind them that passwords in URLs are a bad thing),
or is it just annoying?

 builtin/clone.c            | 19 ++++++++++++++++---
 credential.c               | 13 +++++++++++++
 credential.h               |  6 ++++++
 t/ |  2 +-
 4 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/builtin/clone.c b/builtin/clone.c
index 15fffc3268..94d2659154 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -31,6 +31,7 @@
 #include "packfile.h"
 #include "list-objects-filter-options.h"
 #include "object-store.h"
+#include "credential.h"
  * Overall FIXMEs:
@@ -894,8 +895,14 @@ static int dir_exists(const char *path)
 static const char sanitized_url_advice[] = N_(
 "The URL you provided to Git contains a password. It will be\n"
 "used to clone the repository, but to avoid accidental disclosure\n"
-"the password will not be recorded. Further fetches from the remote\n"
-"may require you to provide the password interactively.\n"
+"the password will not be recorded in the repository config.\n"
+"Since you have no credential helper configured, the \"store\" helper\n"
+"has been enabled for this repository, and will provide the password\n"
+"for further fetches.\n"
+"Note that the password is still stored in plaintext in the filesystem;\n"
+"consider configuring a more secure helper. See \"git help gitcredentials\"\n"
+"and \"git help git-credential-store\" for details.\n"
 int cmd_clone(int argc, const char **argv, const char *prefix)
@@ -1090,7 +1097,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	sanitized_repo = transport_strip_url(repo, 0);
 	if (strcmp(repo, sanitized_repo)) {
 		warning(_("omitting password while storing URL in on-disk config"));
-		advise(_(sanitized_url_advice));
+		if (!url_has_credential_helper(sanitized_repo)) {
+			strbuf_addf(&key, "credential.%s.helper",
+				    sanitized_repo);
+			git_config_set(key.buf, "store");
+			strbuf_reset(&key);
+			advise(_(sanitized_url_advice));
+		}
 	strbuf_addf(&key, "remote.%s.url", option_origin);
 	git_config_set(key.buf, sanitized_repo);
diff --git a/credential.c b/credential.c
index 62be651b03..0a70edcee5 100644
--- a/credential.c
+++ b/credential.c
@@ -372,3 +372,16 @@ void credential_from_url(struct credential *c, const char *url)
 			*p-- = '\0';
+int url_has_credential_helper(const char *url)
+	struct credential c = CREDENTIAL_INIT;
+	int ret;
+	credential_from_url(&c, url);
+	credential_apply_config(&c);
+	ret = > 0;
+	credential_clear(&c);
+	return ret;
diff --git a/credential.h b/credential.h
index 6b0cd16be2..e6d6d6fa40 100644
--- a/credential.h
+++ b/credential.h
@@ -32,4 +32,10 @@ void credential_from_url(struct credential *, const char *url);
 int credential_match(const struct credential *have,
 		     const struct credential *want);
+ * Return true if feeding "url" to the credential system would trigger one
+ * or more helpers.
+ */
+int url_has_credential_helper(const char *url);
 #endif /* CREDENTIAL_H */
diff --git a/t/ b/t/
index d8c85f3126..2723e91ae0 100755
--- a/t/
+++ b/t/
@@ -70,7 +70,7 @@ test_expect_success 'username is retained in URL, password is not' '
 	! grep pass url
-test_expect_failure 'fetch of password-URL clone uses stored auth' '
+test_expect_success 'fetch of password-URL clone uses stored auth' '
 	set_askpass wrong &&
 	git -C clone-auth-none fetch &&
 	expect_askpass none

  parent reply	other threads:[~2019-05-19 18:42 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-15 17:49 Git ransom campaign incident report - May 2019 Martin Langhoff
2019-05-15 18:59 ` Ævar Arnfjörð Bjarmason
2019-05-16  4:27   ` Jeff King
2019-05-17 19:39     ` Johannes Schindelin
2019-05-17 22:20       ` Jeff King
2019-05-17 23:13         ` Martin Langhoff
2019-05-19  5:07         ` Jeff King
2019-05-19  5:10           ` [PATCH 1/3] transport_anonymize_url(): support retaining username Jeff King
2019-05-19 23:28             ` Eric Sunshine
2019-05-20 16:14             ` René Scharfe
2019-05-20 16:36             ` Johannes Schindelin
2019-05-20 16:43             ` Johannes Schindelin
2019-05-19  5:12           ` [PATCH 2/3] clone: avoid storing URL passwords in config Jeff King
2019-05-19  5:16           ` Jeff King [this message]
2019-05-20 11:28             ` [PATCH 3/3] clone: auto-enable git-credential-store when necessary Eric Sunshine
2019-05-20 12:31               ` Jeff King
2019-05-20 16:48                 ` Johannes Schindelin
2019-05-20 13:56             ` Ævar Arnfjörð Bjarmason
2019-05-20 14:08               ` Jeff King
2019-05-20 15:17                 ` Ævar Arnfjörð Bjarmason
2019-05-20 15:24                   ` Jeff King
2019-05-20 17:08             ` Ævar Arnfjörð Bjarmason
2019-05-20 14:43           ` Git ransom campaign incident report - May 2019 Johannes Schindelin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

  List information:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \ \ \ \

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

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 read-only IMAP folder(s) and NNTP newsgroup(s).