@@ -125,6 +125,10 @@ static int credential_config_callback(const char *var, const char *value,
125
125
}
126
126
else if (!strcmp (key , "usehttppath" ))
127
127
c -> use_http_path = git_config_bool (var , value );
128
+ else if (!strcmp (key , "sanitizeprompt" ))
129
+ c -> sanitize_prompt = git_config_bool (var , value );
130
+ else if (!strcmp (key , "protectprotocol" ))
131
+ c -> protect_protocol = git_config_bool (var , value );
128
132
129
133
return 0 ;
130
134
}
@@ -222,7 +226,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
222
226
strbuf_addch (out , '@' );
223
227
}
224
228
if (c -> host )
225
- strbuf_addstr (out , c -> host );
229
+ strbuf_add_percentencode (out , c -> host ,
230
+ STRBUF_ENCODE_HOST_AND_PORT );
226
231
if (c -> path ) {
227
232
strbuf_addch (out , '/' );
228
233
strbuf_add_percentencode (out , c -> path , 0 );
@@ -236,7 +241,10 @@ static char *credential_ask_one(const char *what, struct credential *c,
236
241
struct strbuf prompt = STRBUF_INIT ;
237
242
char * r ;
238
243
239
- credential_describe (c , & desc );
244
+ if (c -> sanitize_prompt )
245
+ credential_format (c , & desc );
246
+ else
247
+ credential_describe (c , & desc );
240
248
if (desc .len )
241
249
strbuf_addf (& prompt , "%s for '%s': " , what , desc .buf );
242
250
else
@@ -355,7 +363,8 @@ int credential_read(struct credential *c, FILE *fp,
355
363
return 0 ;
356
364
}
357
365
358
- static void credential_write_item (FILE * fp , const char * key , const char * value ,
366
+ static void credential_write_item (const struct credential * c ,
367
+ FILE * fp , const char * key , const char * value ,
359
368
int required )
360
369
{
361
370
if (!value && required )
@@ -364,41 +373,45 @@ static void credential_write_item(FILE *fp, const char *key, const char *value,
364
373
return ;
365
374
if (strchr (value , '\n' ))
366
375
die ("credential value for %s contains newline" , key );
376
+ if (c -> protect_protocol && strchr (value , '\r' ))
377
+ die ("credential value for %s contains carriage return\n"
378
+ "If this is intended, set `credential.protectProtocol=false`" ,
379
+ key );
367
380
fprintf (fp , "%s=%s\n" , key , value );
368
381
}
369
382
370
383
void credential_write (const struct credential * c , FILE * fp ,
371
384
enum credential_op_type op_type )
372
385
{
373
386
if (credential_has_capability (& c -> capa_authtype , op_type ))
374
- credential_write_item (fp , "capability[]" , "authtype" , 0 );
387
+ credential_write_item (c , fp , "capability[]" , "authtype" , 0 );
375
388
if (credential_has_capability (& c -> capa_state , op_type ))
376
- credential_write_item (fp , "capability[]" , "state" , 0 );
389
+ credential_write_item (c , fp , "capability[]" , "state" , 0 );
377
390
378
391
if (credential_has_capability (& c -> capa_authtype , op_type )) {
379
- credential_write_item (fp , "authtype" , c -> authtype , 0 );
380
- credential_write_item (fp , "credential" , c -> credential , 0 );
392
+ credential_write_item (c , fp , "authtype" , c -> authtype , 0 );
393
+ credential_write_item (c , fp , "credential" , c -> credential , 0 );
381
394
if (c -> ephemeral )
382
- credential_write_item (fp , "ephemeral" , "1" , 0 );
395
+ credential_write_item (c , fp , "ephemeral" , "1" , 0 );
383
396
}
384
- credential_write_item (fp , "protocol" , c -> protocol , 1 );
385
- credential_write_item (fp , "host" , c -> host , 1 );
386
- credential_write_item (fp , "path" , c -> path , 0 );
387
- credential_write_item (fp , "username" , c -> username , 0 );
388
- credential_write_item (fp , "password" , c -> password , 0 );
389
- credential_write_item (fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
397
+ credential_write_item (c , fp , "protocol" , c -> protocol , 1 );
398
+ credential_write_item (c , fp , "host" , c -> host , 1 );
399
+ credential_write_item (c , fp , "path" , c -> path , 0 );
400
+ credential_write_item (c , fp , "username" , c -> username , 0 );
401
+ credential_write_item (c , fp , "password" , c -> password , 0 );
402
+ credential_write_item (c , fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
390
403
if (c -> password_expiry_utc != TIME_MAX ) {
391
404
char * s = xstrfmt ("%" PRItime , c -> password_expiry_utc );
392
- credential_write_item (fp , "password_expiry_utc" , s , 0 );
405
+ credential_write_item (c , fp , "password_expiry_utc" , s , 0 );
393
406
free (s );
394
407
}
395
408
for (size_t i = 0 ; i < c -> wwwauth_headers .nr ; i ++ )
396
- credential_write_item (fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
409
+ credential_write_item (c , fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
397
410
if (credential_has_capability (& c -> capa_state , op_type )) {
398
411
if (c -> multistage )
399
- credential_write_item (fp , "continue" , "1" , 0 );
412
+ credential_write_item (c , fp , "continue" , "1" , 0 );
400
413
for (size_t i = 0 ; i < c -> state_headers_to_send .nr ; i ++ )
401
- credential_write_item (fp , "state[]" , c -> state_headers_to_send .v [i ], 0 );
414
+ credential_write_item (c , fp , "state[]" , c -> state_headers_to_send .v [i ], 0 );
402
415
}
403
416
}
404
417
0 commit comments