From 118250728e1aa46c19d4d258950b2ba15cb6d5d2 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Sat, 10 Dec 2011 05:31:24 -0500 Subject: credential: apply helper config 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 Signed-off-by: Junio C Hamano --- credential.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'credential.c') diff --git a/credential.c b/credential.c index c349b9aac3..96be1c22dd 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"); -- cgit v1.2.1