@@ -125,6 +125,10 @@ static int credential_config_callback(const char *var, const char *value,
125125 }
126126 else if (!strcmp (key , "usehttppath" ))
127127 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 );
128132
129133 return 0 ;
130134}
@@ -222,7 +226,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
222226 strbuf_addch (out , '@' );
223227 }
224228 if (c -> host )
225- strbuf_addstr (out , c -> host );
229+ strbuf_add_percentencode (out , c -> host ,
230+ STRBUF_ENCODE_HOST_AND_PORT );
226231 if (c -> path ) {
227232 strbuf_addch (out , '/' );
228233 strbuf_add_percentencode (out , c -> path , 0 );
@@ -236,7 +241,10 @@ static char *credential_ask_one(const char *what, struct credential *c,
236241 struct strbuf prompt = STRBUF_INIT ;
237242 char * r ;
238243
239- credential_describe (c , & desc );
244+ if (c -> sanitize_prompt )
245+ credential_format (c , & desc );
246+ else
247+ credential_describe (c , & desc );
240248 if (desc .len )
241249 strbuf_addf (& prompt , "%s for '%s': " , what , desc .buf );
242250 else
@@ -355,7 +363,8 @@ int credential_read(struct credential *c, FILE *fp,
355363 return 0 ;
356364}
357365
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 ,
359368 int required )
360369{
361370 if (!value && required )
@@ -364,41 +373,45 @@ static void credential_write_item(FILE *fp, const char *key, const char *value,
364373 return ;
365374 if (strchr (value , '\n' ))
366375 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 );
367380 fprintf (fp , "%s=%s\n" , key , value );
368381}
369382
370383void credential_write (const struct credential * c , FILE * fp ,
371384 enum credential_op_type op_type )
372385{
373386 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 );
375388 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 );
377390
378391 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 );
381394 if (c -> ephemeral )
382- credential_write_item (fp , "ephemeral" , "1" , 0 );
395+ credential_write_item (c , fp , "ephemeral" , "1" , 0 );
383396 }
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 );
390403 if (c -> password_expiry_utc != TIME_MAX ) {
391404 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 );
393406 free (s );
394407 }
395408 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 );
397410 if (credential_has_capability (& c -> capa_state , op_type )) {
398411 if (c -> multistage )
399- credential_write_item (fp , "continue" , "1" , 0 );
412+ credential_write_item (c , fp , "continue" , "1" , 0 );
400413 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 );
402415 }
403416}
404417
0 commit comments