Skip to content

Commit bc92d2c

Browse files
committed
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
2 parents e839608 + cb626f8 commit bc92d2c

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

contrib/credential/libsecret/git-credential-libsecret.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ struct credential_operation {
5454

5555
#define CREDENTIAL_OP_END { NULL, NULL }
5656

57+
static void credential_clear(struct credential *c);
58+
5759
/* ----------------- Secret Service functions ----------------- */
5860

5961
static const SecretSchema schema = {
@@ -237,6 +239,7 @@ static int keyring_erase(struct credential *c)
237239
{
238240
GHashTable *attributes = NULL;
239241
GError *error = NULL;
242+
struct credential existing = CREDENTIAL_INIT;
240243

241244
/*
242245
* Sanity check that we actually have something to match
@@ -249,6 +252,20 @@ static int keyring_erase(struct credential *c)
249252
if (!c->protocol && !c->host && !c->path && !c->username)
250253
return EXIT_FAILURE;
251254

255+
if (c->password) {
256+
existing.host = g_strdup(c->host);
257+
existing.path = g_strdup(c->path);
258+
existing.port = c->port;
259+
existing.protocol = g_strdup(c->protocol);
260+
existing.username = g_strdup(c->username);
261+
keyring_get(&existing);
262+
if (existing.password && strcmp(c->password, existing.password)) {
263+
credential_clear(&existing);
264+
return EXIT_SUCCESS;
265+
}
266+
credential_clear(&existing);
267+
}
268+
252269
attributes = make_attr_list(c);
253270
secret_password_clearv_sync(&schema,
254271
attributes,

contrib/credential/wincred/git-credential-wincred.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,18 @@ static int match_part_last(LPCWSTR *ptarget, LPCWSTR want, LPCWSTR delim)
109109
return match_part_with_last(ptarget, want, delim, 1);
110110
}
111111

112-
static int match_cred(const CREDENTIALW *cred)
112+
static int match_cred_password(const CREDENTIALW *cred) {
113+
int ret;
114+
WCHAR *cred_password = xmalloc(cred->CredentialBlobSize);
115+
wcsncpy_s(cred_password, cred->CredentialBlobSize,
116+
(LPCWSTR)cred->CredentialBlob,
117+
cred->CredentialBlobSize / sizeof(WCHAR));
118+
ret = !wcscmp(cred_password, password);
119+
free(cred_password);
120+
return ret;
121+
}
122+
123+
static int match_cred(const CREDENTIALW *cred, int match_password)
113124
{
114125
LPCWSTR target = cred->TargetName;
115126
if (wusername && wcscmp(wusername, cred->UserName ? cred->UserName : L""))
@@ -119,7 +130,8 @@ static int match_cred(const CREDENTIALW *cred)
119130
match_part(&target, protocol, L"://") &&
120131
match_part_last(&target, wusername, L"@") &&
121132
match_part(&target, host, L"/") &&
122-
match_part(&target, path, L"");
133+
match_part(&target, path, L"") &&
134+
(!match_password || match_cred_password(cred));
123135
}
124136

125137
static void get_credential(void)
@@ -134,7 +146,7 @@ static void get_credential(void)
134146

135147
/* search for the first credential that matches username */
136148
for (i = 0; i < num_creds; ++i)
137-
if (match_cred(creds[i])) {
149+
if (match_cred(creds[i], 0)) {
138150
write_item("username", creds[i]->UserName,
139151
creds[i]->UserName ? wcslen(creds[i]->UserName) : 0);
140152
write_item("password",
@@ -196,7 +208,7 @@ static void erase_credential(void)
196208
return;
197209

198210
for (i = 0; i < num_creds; ++i) {
199-
if (match_cred(creds[i]))
211+
if (match_cred(creds[i], password != NULL))
200212
CredDeleteW(creds[i]->TargetName, creds[i]->Type, 0);
201213
}
202214

0 commit comments

Comments
 (0)