Skip to content

Commit 40220f4

Browse files
bk2204gitster
authored andcommitted
credential-cache: implement authtype capability
Now that we have full support in Git for the authtype capability, let's add support to the cache credential helper. When parsing data, we always set the initial capabilities because we're the helper, and we need both the initial and helper capabilities to be set in order to have the helper capabilities take effect. When emitting data, always emit the supported capability and make sure we emit items only if we have them and they're supported by the caller. Since we may no longer have a username or password, be sure to emit those conditionally as well so we don't segfault on a NULL pointer. Similarly, when comparing credentials, consider both the password and credential fields when we're matching passwords. Adjust the partial credential detection code so that we can store credentials missing a username or password as long as they have an authtype and credential. Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 30c0a30 commit 40220f4

File tree

4 files changed

+28
-6
lines changed

4 files changed

+28
-6
lines changed

builtin/credential-cache--daemon.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ static int read_request(FILE *fh, struct credential *c,
115115
return error("client sent bogus timeout line: %s", item.buf);
116116
*timeout = atoi(p);
117117

118+
credential_set_all_capabilities(c, CREDENTIAL_OP_INITIAL);
119+
118120
if (credential_read(c, fh, CREDENTIAL_OP_HELPER) < 0)
119121
return -1;
120122
return 0;
@@ -131,8 +133,18 @@ static void serve_one_client(FILE *in, FILE *out)
131133
else if (!strcmp(action.buf, "get")) {
132134
struct credential_cache_entry *e = lookup_credential(&c);
133135
if (e) {
134-
fprintf(out, "username=%s\n", e->item.username);
135-
fprintf(out, "password=%s\n", e->item.password);
136+
e->item.capa_authtype.request_initial = 1;
137+
e->item.capa_authtype.request_helper = 1;
138+
139+
fprintf(out, "capability[]=authtype\n");
140+
if (e->item.username)
141+
fprintf(out, "username=%s\n", e->item.username);
142+
if (e->item.password)
143+
fprintf(out, "password=%s\n", e->item.password);
144+
if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.authtype)
145+
fprintf(out, "authtype=%s\n", e->item.authtype);
146+
if (credential_has_capability(&c.capa_authtype, CREDENTIAL_OP_HELPER) && e->item.credential)
147+
fprintf(out, "credential=%s\n", e->item.credential);
136148
if (e->item.password_expiry_utc != TIME_MAX)
137149
fprintf(out, "password_expiry_utc=%"PRItime"\n",
138150
e->item.password_expiry_utc);
@@ -157,8 +169,10 @@ static void serve_one_client(FILE *in, FILE *out)
157169
else if (!strcmp(action.buf, "store")) {
158170
if (timeout < 0)
159171
warning("cache client didn't specify a timeout");
160-
else if (!c.username || !c.password)
172+
else if ((!c.username || !c.password) && (!c.authtype && !c.credential))
161173
warning("cache client gave us a partial credential");
174+
else if (c.ephemeral)
175+
warning("not storing ephemeral credential");
162176
else {
163177
remove_credential(&c, 0);
164178
cache_credential(&c, timeout);

credential.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ int credential_match(const struct credential *want,
8080
CHECK(host) &&
8181
CHECK(path) &&
8282
CHECK(username) &&
83-
(!match_password || CHECK(password));
83+
(!match_password || CHECK(password)) &&
84+
(!match_password || CHECK(credential));
8485
#undef CHECK
8586
}
8687

@@ -248,8 +249,8 @@ static void credential_getpass(struct credential *c)
248249
PROMPT_ASKPASS);
249250
}
250251

251-
static int credential_has_capability(const struct credential_capability *capa,
252-
enum credential_op_type op_type)
252+
int credential_has_capability(const struct credential_capability *capa,
253+
enum credential_op_type op_type)
253254
{
254255
/*
255256
* We're checking here if each previous step indicated that we had the

credential.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,12 @@ void credential_clear_secrets(struct credential *c);
263263
*/
264264
void credential_next_state(struct credential *c);
265265

266+
/**
267+
* Return true if the capability is enabled for an operation of op_type.
268+
*/
269+
int credential_has_capability(const struct credential_capability *capa,
270+
enum credential_op_type op_type);
271+
266272
int credential_read(struct credential *, FILE *,
267273
enum credential_op_type);
268274
void credential_write(const struct credential *, FILE *,

t/t0301-credential-cache.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ test_atexit 'git credential-cache exit'
3131
helper_test cache
3232
helper_test_password_expiry_utc cache
3333
helper_test_oauth_refresh_token cache
34+
helper_test_authtype cache
3435

3536
test_expect_success 'socket defaults to ~/.cache/git/credential/socket' '
3637
test_when_finished "

0 commit comments

Comments
 (0)