@@ -109,7 +109,7 @@ static int curl_save_cookies;
109
109
struct credential http_auth = CREDENTIAL_INIT ;
110
110
static int http_proactive_auth ;
111
111
static const char * user_agent ;
112
- static int curl_empty_auth ;
112
+ static int curl_empty_auth = -1 ;
113
113
114
114
enum http_follow_config http_follow_config = HTTP_FOLLOW_INITIAL ;
115
115
@@ -125,6 +125,14 @@ static struct credential cert_auth = CREDENTIAL_INIT;
125
125
static int ssl_cert_password_required ;
126
126
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
127
127
static unsigned long http_auth_methods = CURLAUTH_ANY ;
128
+ static int http_auth_methods_restricted ;
129
+ /* Modes for which empty_auth cannot actually help us. */
130
+ static unsigned long empty_auth_useless =
131
+ CURLAUTH_BASIC
132
+ #ifdef CURLAUTH_DIGEST_IE
133
+ | CURLAUTH_DIGEST_IE
134
+ #endif
135
+ | CURLAUTH_DIGEST ;
128
136
#endif
129
137
130
138
static struct curl_slist * pragma_header ;
@@ -333,7 +341,10 @@ static int http_options(const char *var, const char *value, void *cb)
333
341
return git_config_string (& user_agent , var , value );
334
342
335
343
if (!strcmp ("http.emptyauth" , var )) {
336
- curl_empty_auth = git_config_bool (var , value );
344
+ if (value && !strcmp ("auto" , value ))
345
+ curl_empty_auth = -1 ;
346
+ else
347
+ curl_empty_auth = git_config_bool (var , value );
337
348
return 0 ;
338
349
}
339
350
@@ -382,10 +393,37 @@ static int http_options(const char *var, const char *value, void *cb)
382
393
return git_default_config (var , value , cb );
383
394
}
384
395
396
+ static int curl_empty_auth_enabled (void )
397
+ {
398
+ if (curl_empty_auth >= 0 )
399
+ return curl_empty_auth ;
400
+
401
+ #ifndef LIBCURL_CAN_HANDLE_AUTH_ANY
402
+ /*
403
+ * Our libcurl is too old to do AUTH_ANY in the first place;
404
+ * just default to turning the feature off.
405
+ */
406
+ #else
407
+ /*
408
+ * In the automatic case, kick in the empty-auth
409
+ * hack as long as we would potentially try some
410
+ * method more exotic than "Basic" or "Digest".
411
+ *
412
+ * But only do this when this is our second or
413
+ * subsequent request, as by then we know what
414
+ * methods are available.
415
+ */
416
+ if (http_auth_methods_restricted &&
417
+ (http_auth_methods & ~empty_auth_useless ))
418
+ return 1 ;
419
+ #endif
420
+ return 0 ;
421
+ }
422
+
385
423
static void init_curl_http_auth (CURL * result )
386
424
{
387
425
if (!http_auth .username || !* http_auth .username ) {
388
- if (curl_empty_auth )
426
+ if (curl_empty_auth_enabled () )
389
427
curl_easy_setopt (result , CURLOPT_USERPWD , ":" );
390
428
return ;
391
429
}
@@ -1079,7 +1117,7 @@ struct active_request_slot *get_active_slot(void)
1079
1117
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
1080
1118
curl_easy_setopt (slot -> curl , CURLOPT_HTTPAUTH , http_auth_methods );
1081
1119
#endif
1082
- if (http_auth .password || curl_empty_auth )
1120
+ if (http_auth .password || curl_empty_auth_enabled () )
1083
1121
init_curl_http_auth (slot -> curl );
1084
1122
1085
1123
return slot ;
@@ -1347,6 +1385,10 @@ static int handle_curl_result(struct slot_results *results)
1347
1385
} else {
1348
1386
#ifdef LIBCURL_CAN_HANDLE_AUTH_ANY
1349
1387
http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE ;
1388
+ if (results -> auth_avail ) {
1389
+ http_auth_methods &= results -> auth_avail ;
1390
+ http_auth_methods_restricted = 1 ;
1391
+ }
1350
1392
#endif
1351
1393
return HTTP_REAUTH ;
1352
1394
}
0 commit comments