diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-08-28 19:51:16 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2023-08-28 19:51:16 +0300 |
commit | bc92d2c7ac6bd85f2447dbc37c886a4e72076005 (patch) | |
tree | 87aff14baf4e48caf2e31077164f3eccd7da0ff6 /contrib | |
parent | e839608295c0b6abd2a1f609916cba4ca1810241 (diff) | |
parent | cb626f8e5cb76ce081ab0a02656611f05a54cfb5 (diff) |
Merge branch 'mh/credential-erase-improvements-more'
Update two credential helpers to correctly match which credential
to erase; they dropped not the ones with stale password.
* mh/credential-erase-improvements-more:
credential/wincred: erase matching creds only
credential/libsecret: erase matching creds only
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/credential/libsecret/git-credential-libsecret.c | 17 | ||||
-rw-r--r-- | contrib/credential/wincred/git-credential-wincred.c | 20 |
2 files changed, 33 insertions, 4 deletions
diff --git a/contrib/credential/libsecret/git-credential-libsecret.c b/contrib/credential/libsecret/git-credential-libsecret.c index 31cf32ad96..215a81d8ba 100644 --- a/contrib/credential/libsecret/git-credential-libsecret.c +++ b/contrib/credential/libsecret/git-credential-libsecret.c @@ -54,6 +54,8 @@ struct credential_operation { #define CREDENTIAL_OP_END { NULL, NULL } +static void credential_clear(struct credential *c); + /* ----------------- Secret Service functions ----------------- */ static const SecretSchema schema = { @@ -237,6 +239,7 @@ static int keyring_erase(struct credential *c) { GHashTable *attributes = NULL; GError *error = NULL; + struct credential existing = CREDENTIAL_INIT; /* * Sanity check that we actually have something to match @@ -249,6 +252,20 @@ static int keyring_erase(struct credential *c) if (!c->protocol && !c->host && !c->path && !c->username) return EXIT_FAILURE; + if (c->password) { + existing.host = g_strdup(c->host); + existing.path = g_strdup(c->path); + existing.port = c->port; + existing.protocol = g_strdup(c->protocol); + existing.username = g_strdup(c->username); + keyring_get(&existing); + if (existing.password && strcmp(c->password, existing.password)) { + credential_clear(&existing); + return EXIT_SUCCESS; + } + credential_clear(&existing); + } + attributes = make_attr_list(c); secret_password_clearv_sync(&schema, attributes, diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index 96f10613ae..4cd56c42e2 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@ -109,7 +109,18 @@ static int match_part_last(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim) return match_part_with_last(ptarget, want, delim, 1); } -static int match_cred(const CREDENTIALW *cred) +static int match_cred_password(const CREDENTIALW *cred) { + int ret; + WCHAR *cred_password = xmalloc(cred->CredentialBlobSize); + wcsncpy_s(cred_password, cred->CredentialBlobSize, + (LPCWSTR)cred->CredentialBlob, + cred->CredentialBlobSize / sizeof(WCHAR)); + ret = !wcscmp(cred_password, password); + free(cred_password); + return ret; +} + +static int match_cred(const CREDENTIALW *cred, int match_password) { LPCWSTR target = cred->TargetName; if (wusername && wcscmp(wusername, cred->UserName ? cred->UserName : L"")) @@ -119,7 +130,8 @@ static int match_cred(const CREDENTIALW *cred) match_part(&target, protocol, L"://") && match_part_last(&target, wusername, L"@") && match_part(&target, host, L"/") && - match_part(&target, path, L""); + match_part(&target, path, L"") && + (!match_password || match_cred_password(cred)); } static void get_credential(void) @@ -134,7 +146,7 @@ static void get_credential(void) /* search for the first credential that matches username */ for (i = 0; i < num_creds; ++i) - if (match_cred(creds[i])) { + if (match_cred(creds[i], 0)) { write_item("username", creds[i]->UserName, creds[i]->UserName ? wcslen(creds[i]->UserName) : 0); write_item("password", @@ -196,7 +208,7 @@ static void erase_credential(void) return; for (i = 0; i < num_creds; ++i) { - if (match_cred(creds[i])) + if (match_cred(creds[i], password != NULL)) CredDeleteW(creds[i]->TargetName, creds[i]->Type, 0); } |