From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: [PATCHv3 06/13] credential: apply helper config
Date: Sat, 10 Dec 2011 05:31:24 -0500 [thread overview]
Message-ID: <20111210103124.GF16529@sigill.intra.peff.net> (raw)
In-Reply-To: <20111210102827.GA16460@sigill.intra.peff.net>
The functionality for credential storage helpers is already
there; we just need to give the users a way to turn it on.
This patch provides a "credential.helper" configuration
variable which allows the user to provide one or more helper
strings.
Rather than simply matching credential.helper, we will also
compare URLs in subsection headings to the current context.
This means you can apply configuration to a subset of
credentials. For example:
[credential "https://example.com"]
helper = foo
would match a request for "https://example.com/foo.git", but
not one for "https://kernel.org/foo.git".
This is overkill for the "helper" variable, since users are
unlikely to want different helpers for different sites (and
since helpers run arbitrary code, they could do the matching
themselves anyway).
However, future patches will add new config variables where
this extra feature will be more useful.
Signed-off-by: Jeff King <peff@peff.net>
---
credential.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++
credential.h | 5 +++-
t/t0300-credentials.sh | 42 +++++++++++++++++++++++++++++++++
t/t5550-http-fetch.sh | 12 +++++++++
4 files changed, 119 insertions(+), 1 deletions(-)
diff --git a/credential.c b/credential.c
index c349b9a..96be1c2 100644
--- a/credential.c
+++ b/credential.c
@@ -22,6 +22,61 @@ void credential_clear(struct credential *c)
credential_init(c);
}
+int credential_match(const struct credential *want,
+ const struct credential *have)
+{
+#define CHECK(x) (!want->x || (have->x && !strcmp(want->x, have->x)))
+ return CHECK(protocol) &&
+ CHECK(host) &&
+ CHECK(path) &&
+ CHECK(username);
+#undef CHECK
+}
+
+static int credential_config_callback(const char *var, const char *value,
+ void *data)
+{
+ struct credential *c = data;
+ const char *key, *dot;
+
+ key = skip_prefix(var, "credential.");
+ if (!key)
+ return 0;
+
+ if (!value)
+ return config_error_nonbool(var);
+
+ dot = strrchr(key, '.');
+ if (dot) {
+ struct credential want = CREDENTIAL_INIT;
+ char *url = xmemdupz(key, dot - key);
+ int matched;
+
+ credential_from_url(&want, url);
+ matched = credential_match(&want, c);
+
+ credential_clear(&want);
+ free(url);
+
+ if (!matched)
+ return 0;
+ key = dot + 1;
+ }
+
+ if (!strcmp(key, "helper"))
+ string_list_append(&c->helpers, value);
+
+ return 0;
+}
+
+static void credential_apply_config(struct credential *c)
+{
+ if (c->configured)
+ return;
+ git_config(credential_config_callback, c);
+ c->configured = 1;
+}
+
static void credential_describe(struct credential *c, struct strbuf *out)
{
if (!c->protocol)
@@ -195,6 +250,8 @@ void credential_fill(struct credential *c)
if (c->username && c->password)
return;
+ credential_apply_config(c);
+
for (i = 0; i < c->helpers.nr; i++) {
credential_do(c, c->helpers.items[i].string, "get");
if (c->username && c->password)
@@ -215,6 +272,8 @@ void credential_approve(struct credential *c)
if (!c->username || !c->password)
return;
+ credential_apply_config(c);
+
for (i = 0; i < c->helpers.nr; i++)
credential_do(c, c->helpers.items[i].string, "store");
c->approved = 1;
@@ -224,6 +283,8 @@ void credential_reject(struct credential *c)
{
int i;
+ credential_apply_config(c);
+
for (i = 0; i < c->helpers.nr; i++)
credential_do(c, c->helpers.items[i].string, "erase");
diff --git a/credential.h b/credential.h
index 8a6d162..e504272 100644
--- a/credential.h
+++ b/credential.h
@@ -5,7 +5,8 @@
struct credential {
struct string_list helpers;
- unsigned approved:1;
+ unsigned approved:1,
+ configured:1;
char *username;
char *password;
@@ -25,5 +26,7 @@ struct credential {
int credential_read(struct credential *, FILE *);
void credential_from_url(struct credential *, const char *url);
+int credential_match(const struct credential *have,
+ const struct credential *want);
#endif /* CREDENTIAL_H */
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
index 81a455f..42d0f5b 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -192,4 +192,46 @@ test_expect_success 'internal getpass does not ask for known username' '
EOF
'
+HELPER="!f() {
+ cat >/dev/null
+ echo username=foo
+ echo password=bar
+ }; f"
+test_expect_success 'respect configured credentials' '
+ test_config credential.helper "$HELPER" &&
+ check fill <<-\EOF
+ --
+ username=foo
+ password=bar
+ --
+ EOF
+'
+
+test_expect_success 'match configured credential' '
+ test_config credential.https://example.com.helper "$HELPER" &&
+ check fill <<-\EOF
+ protocol=https
+ host=example.com
+ path=repo.git
+ --
+ username=foo
+ password=bar
+ --
+ EOF
+'
+
+test_expect_success 'do not match configured credential' '
+ test_config credential.https://foo.helper "$HELPER" &&
+ check fill <<-\EOF
+ protocol=https
+ host=bar
+ --
+ username=askpass-username
+ password=askpass-password
+ --
+ askpass: Username for '\''https://bar'\'':
+ askpass: Password for '\''https://askpass-username@bar'\'':
+ EOF
+'
+
test_done
diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh
index 398a2d2..c59908f 100755
--- a/t/t5550-http-fetch.sh
+++ b/t/t5550-http-fetch.sh
@@ -101,6 +101,18 @@ test_expect_success 'http auth can request both user and pass' '
expect_askpass both user@host
'
+test_expect_success 'http auth respects credential helper config' '
+ test_config_global credential.helper "!f() {
+ cat >/dev/null
+ echo username=user@host
+ echo password=user@host
+ }; f" &&
+ >askpass-query &&
+ echo wrong >askpass-response &&
+ git clone "$HTTPD_URL/auth/repo.git" clone-auth-helper &&
+ expect_askpass none
+'
+
test_expect_success 'fetch changes via http' '
echo content >>file &&
git commit -a -m two &&
--
1.7.8.rc2.40.gaf387
next prev parent reply other threads:[~2011-12-10 10:31 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-10 10:28 [PATCHv3 0/13] credential helpers Jeff King
2011-12-10 10:30 ` [PATCHv3 01/13] test-lib: add test_config_global variant Jeff King
2011-12-10 10:30 ` [PATCHv3 02/13] t5550: fix typo Jeff King
2011-12-10 10:31 ` [PATCHv3 03/13] introduce credentials API Jeff King
2011-12-10 11:43 ` Jakub Narebski
2011-12-10 19:48 ` Jeff King
2011-12-10 10:31 ` [PATCHv3 04/13] credential: add function for parsing url components Jeff King
2011-12-10 10:31 ` [PATCHv3 05/13] http: use credential API to get passwords Jeff King
2011-12-10 10:31 ` Jeff King [this message]
2011-12-10 10:31 ` [PATCHv3 07/13] credential: add credential.*.username Jeff King
2011-12-10 10:31 ` [PATCHv3 08/13] credential: make relevance of http path configurable Jeff King
2011-12-10 11:50 ` Jakub Narebski
2011-12-10 19:50 ` Jeff King
2011-12-10 10:31 ` [PATCHv3 09/13] docs: end-user documentation for the credential subsystem Jeff King
2011-12-10 10:34 ` [PATCHv3 10/13] credentials: add "cache" helper Jeff King
2012-01-10 1:50 ` Jonathan Nieder
2012-01-10 4:44 ` Jeff King
2012-01-10 4:57 ` Jeff King
2012-01-10 16:59 ` Junio C Hamano
2012-01-17 6:02 ` Jeff King
2012-01-17 6:51 ` Junio C Hamano
2012-01-10 17:44 ` Jonathan Nieder
2012-01-10 17:53 ` Jeff King
2012-01-11 23:50 ` Jonathan Nieder
2012-01-12 3:07 ` Jeff King
2011-12-10 10:34 ` [PATCHv3 11/13] strbuf: add strbuf_add*_urlencode Jeff King
2011-12-10 11:57 ` Jakub Narebski
2011-12-10 20:09 ` Jeff King
2011-12-10 10:34 ` [PATCHv3 12/13] credentials: add "store" helper Jeff King
2011-12-10 10:35 ` [PATCHv3 13/13] t: add test harness for external credential helpers Jeff King
2011-12-10 10:39 ` [PATCHv2 0/9] echo characters in username prompt Jeff King
2011-12-10 10:40 ` [PATCHv2 1/9] imap-send: avoid buffer overflow Jeff King
2011-12-10 10:40 ` [PATCHv2 2/9] imap-send: don't check return value of git_getpass Jeff King
2011-12-10 10:40 ` [PATCHv2 3/9] move git_getpass to its own source file Jeff King
2011-12-10 10:40 ` [PATCHv2 4/9] refactor git_getpass into generic prompt function Jeff King
2011-12-10 10:41 ` [PATCHv2 5/9] add generic terminal " Jeff King
2011-12-15 12:48 ` Pete Wyckoff
2011-12-15 13:39 ` Jeff King
2011-12-15 21:59 ` Pete Wyckoff
2011-12-10 10:41 ` [PATCHv2 6/9] prompt: use git_terminal_prompt Jeff King
2011-12-10 10:41 ` [PATCHv2 7/9] credential: use git_prompt instead of git_getpass Jeff King
2011-12-10 10:41 ` [PATCHv2 8/9] Makefile: linux has /dev/tty Jeff King
2011-12-10 10:41 ` [PATCHv2 9/9] Makefile: OS X " Jeff King
2011-12-12 21:10 ` [PATCH 1/2] Makefile: Windows lacks /dev/tty Johannes Sixt
2011-12-12 21:12 ` [PATCH 2/2] Makefile: optionally exclude code that needs Unix sockets Johannes Sixt
2011-12-12 21:39 ` Jeff King
2011-12-12 23:31 ` Junio C Hamano
2011-12-13 0:58 ` Jeff King
2011-12-13 0:45 ` Junio C Hamano
2011-12-13 20:00 ` Johannes Sixt
2011-12-14 0:14 ` Junio C Hamano
2011-12-12 21:18 ` [PATCH 1/2] Makefile: Windows lacks /dev/tty Jeff King
2011-12-12 21:52 ` Johannes Sixt
2011-12-10 10:53 ` [PATCH 1/1] contrib: add credential helper for OS X Keychain Jeff King
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:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20111210103124.GF16529@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* 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.
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).