@@ -129,6 +129,10 @@ static int credential_config_callback(const char *var, const char *value,
129129 }
130130 else if (!strcmp (key , "usehttppath" ))
131131 c -> use_http_path = git_config_bool (var , value );
132+ else if (!strcmp (key , "sanitizeprompt" ))
133+ c -> sanitize_prompt = git_config_bool (var , value );
134+ else if (!strcmp (key , "protectprotocol" ))
135+ c -> protect_protocol = git_config_bool (var , value );
132136
133137 return 0 ;
134138}
@@ -226,7 +230,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
226230 strbuf_addch (out , '@' );
227231 }
228232 if (c -> host )
229- strbuf_addstr (out , c -> host );
233+ strbuf_add_percentencode (out , c -> host ,
234+ STRBUF_ENCODE_HOST_AND_PORT );
230235 if (c -> path ) {
231236 strbuf_addch (out , '/' );
232237 strbuf_add_percentencode (out , c -> path , 0 );
@@ -240,7 +245,10 @@ static char *credential_ask_one(const char *what, struct credential *c,
240245 struct strbuf prompt = STRBUF_INIT ;
241246 char * r ;
242247
243- credential_describe (c , & desc );
248+ if (c -> sanitize_prompt )
249+ credential_format (c , & desc );
250+ else
251+ credential_describe (c , & desc );
244252 if (desc .len )
245253 strbuf_addf (& prompt , "%s for '%s': " , what , desc .buf );
246254 else
@@ -381,7 +389,8 @@ int credential_read(struct credential *c, FILE *fp,
381389 return 0 ;
382390}
383391
384- static void credential_write_item (FILE * fp , const char * key , const char * value ,
392+ static void credential_write_item (const struct credential * c ,
393+ FILE * fp , const char * key , const char * value ,
385394 int required )
386395{
387396 if (!value && required )
@@ -390,41 +399,45 @@ static void credential_write_item(FILE *fp, const char *key, const char *value,
390399 return ;
391400 if (strchr (value , '\n' ))
392401 die ("credential value for %s contains newline" , key );
402+ if (c -> protect_protocol && strchr (value , '\r' ))
403+ die ("credential value for %s contains carriage return\n"
404+ "If this is intended, set `credential.protectProtocol=false`" ,
405+ key );
393406 fprintf (fp , "%s=%s\n" , key , value );
394407}
395408
396409void credential_write (const struct credential * c , FILE * fp ,
397410 enum credential_op_type op_type )
398411{
399412 if (credential_has_capability (& c -> capa_authtype , op_type ))
400- credential_write_item (fp , "capability[]" , "authtype" , 0 );
413+ credential_write_item (c , fp , "capability[]" , "authtype" , 0 );
401414 if (credential_has_capability (& c -> capa_state , op_type ))
402- credential_write_item (fp , "capability[]" , "state" , 0 );
415+ credential_write_item (c , fp , "capability[]" , "state" , 0 );
403416
404417 if (credential_has_capability (& c -> capa_authtype , op_type )) {
405- credential_write_item (fp , "authtype" , c -> authtype , 0 );
406- credential_write_item (fp , "credential" , c -> credential , 0 );
418+ credential_write_item (c , fp , "authtype" , c -> authtype , 0 );
419+ credential_write_item (c , fp , "credential" , c -> credential , 0 );
407420 if (c -> ephemeral )
408- credential_write_item (fp , "ephemeral" , "1" , 0 );
421+ credential_write_item (c , fp , "ephemeral" , "1" , 0 );
409422 }
410- credential_write_item (fp , "protocol" , c -> protocol , 1 );
411- credential_write_item (fp , "host" , c -> host , 1 );
412- credential_write_item (fp , "path" , c -> path , 0 );
413- credential_write_item (fp , "username" , c -> username , 0 );
414- credential_write_item (fp , "password" , c -> password , 0 );
415- credential_write_item (fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
423+ credential_write_item (c , fp , "protocol" , c -> protocol , 1 );
424+ credential_write_item (c , fp , "host" , c -> host , 1 );
425+ credential_write_item (c , fp , "path" , c -> path , 0 );
426+ credential_write_item (c , fp , "username" , c -> username , 0 );
427+ credential_write_item (c , fp , "password" , c -> password , 0 );
428+ credential_write_item (c , fp , "oauth_refresh_token" , c -> oauth_refresh_token , 0 );
416429 if (c -> password_expiry_utc != TIME_MAX ) {
417430 char * s = xstrfmt ("%" PRItime , c -> password_expiry_utc );
418- credential_write_item (fp , "password_expiry_utc" , s , 0 );
431+ credential_write_item (c , fp , "password_expiry_utc" , s , 0 );
419432 free (s );
420433 }
421434 for (size_t i = 0 ; i < c -> wwwauth_headers .nr ; i ++ )
422- credential_write_item (fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
435+ credential_write_item (c , fp , "wwwauth[]" , c -> wwwauth_headers .v [i ], 0 );
423436 if (credential_has_capability (& c -> capa_state , op_type )) {
424437 if (c -> multistage )
425- credential_write_item (fp , "continue" , "1" , 0 );
438+ credential_write_item (c , fp , "continue" , "1" , 0 );
426439 for (size_t i = 0 ; i < c -> state_headers_to_send .nr ; i ++ )
427- credential_write_item (fp , "state[]" , c -> state_headers_to_send .v [i ], 0 );
440+ credential_write_item (c , fp , "state[]" , c -> state_headers_to_send .v [i ], 0 );
428441 }
429442}
430443
0 commit comments