@@ -130,6 +130,10 @@ static int credential_config_callback(const char *var, const char *value,
130
130
}
131
131
else if (!strcmp (key , "usehttppath" ))
132
132
c -> use_http_path = git_config_bool (var , value );
133
+ else if (!strcmp (key , "sanitizeprompt" ))
134
+ c -> sanitize_prompt = git_config_bool (var , value );
135
+ else if (!strcmp (key , "protectprotocol" ))
136
+ c -> protect_protocol = git_config_bool (var , value );
133
137
134
138
return 0 ;
135
139
}
@@ -227,7 +231,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
227
231
strbuf_addch (out , '@' );
228
232
}
229
233
if (c -> host )
230
- strbuf_addstr (out , c -> host );
234
+ strbuf_add_percentencode (out , c -> host ,
235
+ STRBUF_ENCODE_HOST_AND_PORT );
231
236
if (c -> path ) {
232
237
strbuf_addch (out , '/' );
233
238
strbuf_add_percentencode (out , c -> path , 0 );
@@ -241,7 +246,10 @@ static char *credential_ask_one(const char *what, struct credential *c,
241
246
struct strbuf prompt = STRBUF_INIT ;
242
247
char * r ;
243
248
244
- credential_describe (c , & desc );
249
+ if (c -> sanitize_prompt )
250
+ credential_format (c , & desc );
251
+ else
252
+ credential_describe (c , & desc );
245
253
if (desc .len )
246
254
strbuf_addf (& prompt , "%s for '%s': " , what , desc .buf );
247
255
else
@@ -382,7 +390,8 @@ int credential_read(struct credential *c, FILE *fp,
382
390
return 0 ;
383
391
}
384
392
385
- static void credential_write_item (FILE * fp , const char * key , const char * value ,
393
+ static void credential_write_item (const struct credential * c ,
394
+ FILE * fp , const char * key , const char * value ,
386
395
int required )
387
396
{
388
397
if (!value && required )
@@ -391,41 +400,45 @@ static void credential_write_item(FILE *fp, const char *key, const char *value,
391
400
return ;
392
401
if (strchr (value , '\n' ))
393
402
die ("credential value for %s contains newline" , key );
403
+ if (c -> protect_protocol && strchr (value , '\r' ))
404
+ die ("credential value for %s contains carriage return\n"
405
+ "If this is intended, set `credential.protectProtocol=false`" ,
406
+ key );
394
407
fprintf (fp , "%s=%s\n" , key , value );
395
408
}
396
409
397
410
void credential_write (const struct credential * c , FILE * fp ,
398
411
enum credential_op_type op_type )
399
412
{
400
413
if (credential_has_capability (& c -> capa_authtype , op_type ))
401
- credential_write_item (fp , "capability[]" , "authtype" , 0 );
414
+ credential_write_item (c , fp , "capability[]" , "authtype" , 0 );
402
415
if (credential_has_capability (& c -> capa_state , op_type ))
403
- credential_write_item (fp , "capability[]" , "state" , 0 );
416
+ credential_write_item (c , fp , "capability[]" , "state" , 0 );
404
417
405
418
if (credential_has_capability (& c -> capa_authtype , op_type )) {
406
- credential_write_item (fp , "authtype" , c -> authtype , 0 );
407
- credential_write_item (fp , "credential" , c -> credential , 0 );
419
+ credential_write_item (c , fp , "authtype" , c -> authtype , 0 );
420
+ credential_write_item (c , fp , "credential" , c -> credential , 0 );
408
421
if (c -> ephemeral )
409
- credential_write_item (fp , "ephemeral" , "1" , 0 );
422
+ credential_write_item (c , fp , "ephemeral" , "1" , 0 );
410
423
}
411
- credential_write_item (fp , "protocol" , c -> protocol , 1 );
412
- credential_write_item (fp , "host" , c -> host , 1 );
413
- credential_write_item (fp , "path" , c -> path , 0 );
414
- credential_write_item (fp , "username" , c -> username , 0 );
415
- credential_write_item (fp , "password" , c -> password , 0 );
416
- credential_write_item (fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
424
+ credential_write_item (c , fp , "protocol" , c -> protocol , 1 );
425
+ credential_write_item (c , fp , "host" , c -> host , 1 );
426
+ credential_write_item (c , fp , "path" , c -> path , 0 );
427
+ credential_write_item (c , fp , "username" , c -> username , 0 );
428
+ credential_write_item (c , fp , "password" , c -> password , 0 );
429
+ credential_write_item (c , fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
417
430
if (c -> password_expiry_utc != TIME_MAX ) {
418
431
char * s = xstrfmt ("%" PRItime , c -> password_expiry_utc );
419
- credential_write_item (fp , "password_expiry_utc" , s , 0 );
432
+ credential_write_item (c , fp , "password_expiry_utc" , s , 0 );
420
433
free (s );
421
434
}
422
435
for (size_t i = 0 ; i < c -> wwwauth_headers .nr ; i ++ )
423
- credential_write_item (fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
436
+ credential_write_item (c , fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
424
437
if (credential_has_capability (& c -> capa_state , op_type )) {
425
438
if (c -> multistage )
426
- credential_write_item (fp , "continue" , "1" , 0 );
439
+ credential_write_item (c , fp , "continue" , "1" , 0 );
427
440
for (size_t i = 0 ; i < c -> state_headers_to_send .nr ; i ++ )
428
- credential_write_item (fp , "state[]" , c -> state_headers_to_send .v [i ], 0 );
441
+ credential_write_item (c , fp , "state[]" , c -> state_headers_to_send .v [i ], 0 );
429
442
}
430
443
}
431
444
0 commit comments