@@ -108,12 +108,19 @@ static struct {
108108};
109109#endif
110110
111+ enum proactive_auth {
112+ PROACTIVE_AUTH_NONE = 0 ,
113+ PROACTIVE_AUTH_IF_CREDENTIALS ,
114+ PROACTIVE_AUTH_AUTO ,
115+ PROACTIVE_AUTH_BASIC ,
116+ };
117+
111118static struct credential proxy_auth = CREDENTIAL_INIT ;
112119static const char * curl_proxyuserpwd ;
113120static char * curl_cookie_file ;
114121static int curl_save_cookies ;
115122struct credential http_auth = CREDENTIAL_INIT ;
116- static int http_proactive_auth ;
123+ static enum proactive_auth http_proactive_auth ;
117124static char * user_agent ;
118125static int curl_empty_auth = -1 ;
119126
@@ -148,6 +155,12 @@ static int http_schannel_check_revoke = 1;
148155 */
149156static int http_schannel_use_ssl_cainfo ;
150157
158+ static int always_auth_proactively (void )
159+ {
160+ return http_proactive_auth != PROACTIVE_AUTH_NONE &&
161+ http_proactive_auth != PROACTIVE_AUTH_IF_CREDENTIALS ;
162+ }
163+
151164size_t fread_buffer (char * ptr , size_t eltsize , size_t nmemb , void * buffer_ )
152165{
153166 size_t size = eltsize * nmemb ;
@@ -539,6 +552,20 @@ static int http_options(const char *var, const char *value,
539552 return 0 ;
540553 }
541554
555+ if (!strcmp ("http.proactiveauth" , var )) {
556+ if (!value )
557+ return config_error_nonbool (var );
558+ if (!strcmp (value , "auto" ))
559+ http_proactive_auth = PROACTIVE_AUTH_AUTO ;
560+ else if (!strcmp (value , "basic" ))
561+ http_proactive_auth = PROACTIVE_AUTH_BASIC ;
562+ else if (!strcmp (value , "none" ))
563+ http_proactive_auth = PROACTIVE_AUTH_NONE ;
564+ else
565+ warning (_ ("Unknown value for http.proactiveauth" ));
566+ return 0 ;
567+ }
568+
542569 /* Fall back on the default ones */
543570 return git_default_config (var , value , ctx , data );
544571}
@@ -580,14 +607,29 @@ static void init_curl_http_auth(CURL *result)
580607{
581608 if ((!http_auth .username || !* http_auth .username ) &&
582609 (!http_auth .credential || !* http_auth .credential )) {
583- if (curl_empty_auth_enabled ())
610+ int empty_auth = curl_empty_auth_enabled ();
611+ if ((empty_auth != -1 && !always_auth_proactively ()) || empty_auth == 1 ) {
584612 curl_easy_setopt (result , CURLOPT_USERPWD , ":" );
585- return ;
613+ return ;
614+ } else if (!always_auth_proactively ()) {
615+ return ;
616+ } else if (http_proactive_auth == PROACTIVE_AUTH_BASIC ) {
617+ strvec_push (& http_auth .wwwauth_headers , "Basic" );
618+ }
586619 }
587620
588621 credential_fill (& http_auth , 1 );
589622
590623 if (http_auth .password ) {
624+ if (always_auth_proactively ()) {
625+ /*
626+ * We got a credential without an authtype and we don't
627+ * know what's available. Since our only two options at
628+ * the moment are auto (which defaults to basic) and
629+ * basic, use basic for now.
630+ */
631+ curl_easy_setopt (result , CURLOPT_HTTPAUTH , CURLAUTH_BASIC );
632+ }
591633 curl_easy_setopt (result , CURLOPT_USERNAME , http_auth .username );
592634 curl_easy_setopt (result , CURLOPT_PASSWORD , http_auth .password );
593635 }
@@ -1050,7 +1092,7 @@ static CURL *get_curl_handle(void)
10501092#endif
10511093 }
10521094
1053- if (http_proactive_auth )
1095+ if (http_proactive_auth != PROACTIVE_AUTH_NONE )
10541096 init_curl_http_auth (result );
10551097
10561098 if (getenv ("GIT_SSL_VERSION" ))
@@ -1294,7 +1336,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
12941336 if (curl_global_init (CURL_GLOBAL_ALL ) != CURLE_OK )
12951337 die ("curl_global_init failed" );
12961338
1297- http_proactive_auth = proactive_auth ;
1339+ if (proactive_auth && http_proactive_auth == PROACTIVE_AUTH_NONE )
1340+ http_proactive_auth = PROACTIVE_AUTH_IF_CREDENTIALS ;
12981341
12991342 if (remote && remote -> http_proxy )
13001343 curl_http_proxy = xstrdup (remote -> http_proxy );
@@ -1790,6 +1833,8 @@ static int handle_curl_result(struct slot_results *results)
17901833 return HTTP_REAUTH ;
17911834 }
17921835 credential_reject (& http_auth );
1836+ if (always_auth_proactively ())
1837+ http_proactive_auth = PROACTIVE_AUTH_NONE ;
17931838 return HTTP_NOAUTH ;
17941839 } else {
17951840 http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE ;
@@ -2186,7 +2231,12 @@ static int http_request_reauth(const char *url,
21862231 struct http_get_options * options )
21872232{
21882233 int i = 3 ;
2189- int ret = http_request (url , result , target , options );
2234+ int ret ;
2235+
2236+ if (always_auth_proactively ())
2237+ credential_fill (& http_auth , 1 );
2238+
2239+ ret = http_request (url , result , target , options );
21902240
21912241 if (ret != HTTP_OK && ret != HTTP_REAUTH )
21922242 return ret ;
0 commit comments