Skip to content

Commit 7144dee

Browse files
hickfordgitster
authored andcommitted
credential/libsecret: erase matching creds only
The credential erase request typically includes protocol, host, username and password. credential-libsecret erases a stored credential if it matches protocol, host and username, regardless of password. This is confusing in the case the stored password differs from that in the request. This case can occur when multiple credential helpers are configured. Only erase credential if stored password matches request (or request omits password). This fixes test "helper (libsecret) does not erase a password distinct from input" when t0303 is run with GIT_TEST_CREDENTIAL_HELPER set to "libsecret". This test was added in aeb21ce (credential: avoid erasing distinct password, 2023-06-13). Signed-off-by: M Hickford <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 6c26da8 commit 7144dee

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

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

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

5353
#define CREDENTIAL_OP_END { NULL, NULL }
5454

55+
static void credential_clear(struct credential *c);
56+
5557
/* ----------------- Secret Service functions ----------------- */
5658

5759
static char *make_label(struct credential *c)
@@ -185,6 +187,7 @@ static int keyring_erase(struct credential *c)
185187
{
186188
GHashTable *attributes = NULL;
187189
GError *error = NULL;
190+
struct credential existing = CREDENTIAL_INIT;
188191

189192
/*
190193
* Sanity check that we actually have something to match
@@ -197,6 +200,20 @@ static int keyring_erase(struct credential *c)
197200
if (!c->protocol && !c->host && !c->path && !c->username)
198201
return EXIT_FAILURE;
199202

203+
if (c->password) {
204+
existing.host = g_strdup(c->host);
205+
existing.path = g_strdup(c->path);
206+
existing.port = c->port;
207+
existing.protocol = g_strdup(c->protocol);
208+
existing.username = g_strdup(c->username);
209+
keyring_get(&existing);
210+
if (existing.password && strcmp(c->password, existing.password)) {
211+
credential_clear(&existing);
212+
return EXIT_SUCCESS;
213+
}
214+
credential_clear(&existing);
215+
}
216+
200217
attributes = make_attr_list(c);
201218
secret_password_clearv_sync(SECRET_SCHEMA_COMPAT_NETWORK,
202219
attributes,

0 commit comments

Comments
 (0)