@@ -42,7 +42,7 @@ static long curl_low_speed_time = -1;
42
42
static int curl_ftp_no_epsv ;
43
43
static const char * curl_http_proxy ;
44
44
static const char * curl_cookie_file ;
45
- static char * user_name , * user_pass ;
45
+ static char * user_name , * user_pass , * description ;
46
46
static const char * user_agent ;
47
47
48
48
#if LIBCURL_VERSION_NUM >= 0x071700
@@ -139,6 +139,27 @@ static void process_curl_messages(void)
139
139
}
140
140
#endif
141
141
142
+ static char * git_getpass_with_description (const char * what , const char * desc )
143
+ {
144
+ struct strbuf prompt = STRBUF_INIT ;
145
+ char * r ;
146
+
147
+ if (desc )
148
+ strbuf_addf (& prompt , "%s for '%s': " , what , desc );
149
+ else
150
+ strbuf_addf (& prompt , "%s: " , what );
151
+ /*
152
+ * NEEDSWORK: for usernames, we should do something less magical that
153
+ * actually echoes the characters. However, we need to read from
154
+ * /dev/tty and not stdio, which is not portable (but getpass will do
155
+ * it for us). http.c uses the same workaround.
156
+ */
157
+ r = git_getpass (prompt .buf );
158
+
159
+ strbuf_release (& prompt );
160
+ return xstrdup (r );
161
+ }
162
+
142
163
static int http_options (const char * var , const char * value , void * cb )
143
164
{
144
165
if (!strcmp ("http.sslverify" , var )) {
@@ -214,7 +235,7 @@ static void init_curl_http_auth(CURL *result)
214
235
if (user_name ) {
215
236
struct strbuf up = STRBUF_INIT ;
216
237
if (!user_pass )
217
- user_pass = xstrdup (git_getpass ("Password: " ));
238
+ user_pass = xstrdup (git_getpass_with_description ("Password" , description ));
218
239
strbuf_addf (& up , "%s:%s" , user_name , user_pass );
219
240
curl_easy_setopt (result , CURLOPT_USERPWD ,
220
241
strbuf_detach (& up , NULL ));
@@ -229,7 +250,7 @@ static int has_cert_password(void)
229
250
return 0 ;
230
251
/* Only prompt the user once. */
231
252
ssl_cert_password_required = -1 ;
232
- ssl_cert_password = git_getpass ("Certificate Password: " );
253
+ ssl_cert_password = git_getpass_with_description ("Certificate Password" , description );
233
254
if (ssl_cert_password != NULL ) {
234
255
ssl_cert_password = xstrdup (ssl_cert_password );
235
256
return 1 ;
@@ -307,7 +328,7 @@ static CURL *get_curl_handle(void)
307
328
308
329
static void http_auth_init (const char * url )
309
330
{
310
- char * at , * colon , * cp , * slash ;
331
+ const char * at , * colon , * cp , * slash , * host ;
311
332
312
333
cp = strstr (url , "://" );
313
334
if (!cp )
@@ -323,16 +344,22 @@ static void http_auth_init(const char *url)
323
344
at = strchr (cp , '@' );
324
345
colon = strchr (cp , ':' );
325
346
slash = strchrnul (cp , '/' );
326
- if (!at || slash <= at )
327
- return ; /* No credentials */
328
- if (!colon || at <= colon ) {
347
+ if (!at || slash <= at ) {
348
+ /* No credentials, but we may have to ask for some later */
349
+ host = cp ;
350
+ }
351
+ else if (!colon || at <= colon ) {
329
352
/* Only username */
330
353
user_name = url_decode_mem (cp , at - cp );
331
354
user_pass = NULL ;
355
+ host = at + 1 ;
332
356
} else {
333
357
user_name = url_decode_mem (cp , colon - cp );
334
358
user_pass = url_decode_mem (colon + 1 , at - (colon + 1 ));
359
+ host = at + 1 ;
335
360
}
361
+
362
+ description = url_decode_mem (host , slash - host );
336
363
}
337
364
338
365
static void set_from_env (const char * * var , const char * envname )
@@ -828,7 +855,7 @@ static int http_request(const char *url, void *result, int target, int options)
828
855
* but that is non-portable. Using git_getpass() can at least be stubbed
829
856
* on other platforms with a different implementation if/when necessary.
830
857
*/
831
- user_name = xstrdup (git_getpass ("Username: " ));
858
+ user_name = xstrdup (git_getpass_with_description ("Username" , description ));
832
859
init_curl_http_auth (slot -> curl );
833
860
ret = HTTP_REAUTH ;
834
861
}
0 commit comments