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
This commit is contained in:
Junio C Hamano 2023-08-28 09:51:16 -07:00
Родитель e839608295 cb626f8e5c
Коммит bc92d2c7ac
2 изменённых файлов: 33 добавлений и 4 удалений

Просмотреть файл

@ -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,

Просмотреть файл

@ -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);
}