1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 12:59:41 +01:00

credential: erase all matching credentials

`credential reject` sends the erase action to each helper, but the
exact behaviour of erase isn't specified in documentation or tests.
Some helpers (such as credential-store and credential-libsecret) delete
all matching credentials, others (such as credential-cache) delete at
most one matching credential.

Test that helpers erase all matching credentials. This behaviour is
easiest to reason about. Users expect that `echo
"url=https://example.com" | git credential reject` or `echo
"url=https://example.com\nusername=tim" | git credential reject` erase
all matching credentials.

Fix credential-cache.

Signed-off-by: M Hickford <mirth.hickford@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
M Hickford 2023-06-15 19:19:33 +00:00 committed by Junio C Hamano
parent aeb21ce22e
commit 6c26da8404
4 changed files with 44 additions and 8 deletions

View file

@ -39,7 +39,7 @@ for later use.
If the action is `reject`, git-credential will send the description to
any configured credential helpers, which may erase any stored
credential matching the description.
credentials matching the description.
If the action is `approve` or `reject`, no output should be emitted.

View file

@ -260,7 +260,7 @@ appended to its command line, which is one of:
`erase`::
Remove a matching credential, if any, from the helper's storage.
Remove matching credentials, if any, from the helper's storage.
The details of the credential will be provided on the helper's stdin
stream. The exact format is the same as the input/output format of the

View file

@ -33,12 +33,12 @@ static void cache_credential(struct credential *c, int timeout)
e->expiration = time(NULL) + timeout;
}
static struct credential_cache_entry *lookup_credential(const struct credential *c, int match_password)
static struct credential_cache_entry *lookup_credential(const struct credential *c)
{
int i;
for (i = 0; i < entries_nr; i++) {
struct credential *e = &entries[i].item;
if (credential_match(c, e, match_password))
if (credential_match(c, e, 0))
return &entries[i];
}
return NULL;
@ -48,9 +48,12 @@ static void remove_credential(const struct credential *c, int match_password)
{
struct credential_cache_entry *e;
e = lookup_credential(c, match_password);
if (e)
e->expiration = 0;
int i;
for (i = 0; i < entries_nr; i++) {
e = &entries[i];
if (credential_match(c, &e->item, match_password))
e->expiration = 0;
}
}
static timestamp_t check_expirations(void)
@ -127,7 +130,7 @@ static void serve_one_client(FILE *in, FILE *out)
if (read_request(in, &c, &action, &timeout) < 0)
/* ignore error */ ;
else if (!strcmp(action.buf, "get")) {
struct credential_cache_entry *e = lookup_credential(&c, 0);
struct credential_cache_entry *e = lookup_credential(&c);
if (e) {
fprintf(out, "username=%s\n", e->item.username);
fprintf(out, "password=%s\n", e->item.password);

View file

@ -46,6 +46,8 @@ helper_test_clean() {
reject $1 https example.com user4
reject $1 https example.com user-distinct-pass
reject $1 https example.com user-overwrite
reject $1 https example.com user-erase1
reject $1 https example.com user-erase2
reject $1 http path.tld user
reject $1 https timeout.tld user
reject $1 https sso.tld
@ -342,6 +344,37 @@ helper_test() {
EOF
'
test_expect_success "helper ($HELPER) erases all matching credentials" '
check approve $HELPER <<-\EOF &&
protocol=https
host=example.com
username=user-erase1
password=pass1
EOF
check approve $HELPER <<-\EOF &&
protocol=https
host=example.com
username=user-erase2
password=pass1
EOF
check reject $HELPER <<-\EOF &&
protocol=https
host=example.com
EOF
check fill $HELPER <<-\EOF
protocol=https
host=example.com
--
protocol=https
host=example.com
username=askpass-username
password=askpass-password
--
askpass: Username for '\''https://example.com'\'':
askpass: Password for '\''https://askpass-username@example.com'\'':
EOF
'
: ${GIT_TEST_LONG_CRED_BUFFER:=1024}
# 23 bytes accounts for "wwwauth[]=basic realm=" plus NUL
LONG_VALUE_LEN=$((GIT_TEST_LONG_CRED_BUFFER - 23))