@@ -129,7 +129,8 @@ enum http_follow_config http_follow_config = HTTP_FOLLOW_INITIAL;
129129
130130static struct credential cert_auth = CREDENTIAL_INIT ;
131131static int ssl_cert_password_required ;
132- static unsigned long http_auth_methods = CURLAUTH_ANY ;
132+ static unsigned long http_auth_any = CURLAUTH_ANY & ~CURLAUTH_NTLM ;
133+ static unsigned long http_auth_methods ;
133134static int http_auth_methods_restricted ;
134135/* Modes for which empty_auth cannot actually help us. */
135136static unsigned long empty_auth_useless =
@@ -430,6 +431,15 @@ static int http_options(const char *var, const char *value,
430431 return 0 ;
431432 }
432433
434+ if (!strcmp ("http.allowntlmauth" , var )) {
435+ if (git_config_bool (var , value )) {
436+ http_auth_any |= CURLAUTH_NTLM ;
437+ } else {
438+ http_auth_any &= ~CURLAUTH_NTLM ;
439+ }
440+ return 0 ;
441+ }
442+
433443 if (!strcmp ("http.schannelcheckrevoke" , var )) {
434444 if (value && !strcmp (value , "best-effort" )) {
435445 http_schannel_check_revoke_mode =
@@ -653,6 +663,11 @@ static void init_curl_http_auth(CURL *result)
653663
654664 credential_fill (the_repository , & http_auth , 1 );
655665
666+ if (http_auth .ntlm_allow && !(http_auth_methods & CURLAUTH_NTLM )) {
667+ http_auth_methods |= CURLAUTH_NTLM ;
668+ curl_easy_setopt (result , CURLOPT_HTTPAUTH , http_auth_methods );
669+ }
670+
656671 if (http_auth .password ) {
657672 if (always_auth_proactively ()) {
658673 /*
@@ -712,11 +727,11 @@ static void init_curl_proxy_auth(CURL *result)
712727 if (i == ARRAY_SIZE (proxy_authmethods )) {
713728 warning ("unsupported proxy authentication method %s: using anyauth" ,
714729 http_proxy_authmethod );
715- curl_easy_setopt (result , CURLOPT_PROXYAUTH , CURLAUTH_ANY );
730+ curl_easy_setopt (result , CURLOPT_PROXYAUTH , http_auth_any );
716731 }
717732 }
718733 else
719- curl_easy_setopt (result , CURLOPT_PROXYAUTH , CURLAUTH_ANY );
734+ curl_easy_setopt (result , CURLOPT_PROXYAUTH , http_auth_any );
720735}
721736
722737static int has_cert_password (void )
@@ -1063,7 +1078,7 @@ static CURL *get_curl_handle(void)
10631078 }
10641079
10651080 curl_easy_setopt (result , CURLOPT_NETRC , CURL_NETRC_OPTIONAL );
1066- curl_easy_setopt (result , CURLOPT_HTTPAUTH , CURLAUTH_ANY );
1081+ curl_easy_setopt (result , CURLOPT_HTTPAUTH , http_auth_any );
10671082
10681083#ifdef CURLGSSAPI_DELEGATION_FLAG
10691084 if (curl_deleg ) {
@@ -1458,6 +1473,8 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
14581473 set_long_from_env (& curl_tcp_keepintvl , "GIT_TCP_KEEPINTVL" );
14591474 set_long_from_env (& curl_tcp_keepcnt , "GIT_TCP_KEEPCNT" );
14601475
1476+ http_auth_methods = http_auth_any ;
1477+
14611478 curl_default = get_curl_handle ();
14621479}
14631480
@@ -1889,6 +1906,12 @@ static int handle_curl_result(struct slot_results *results)
18891906 } else if (missing_target (results ))
18901907 return HTTP_MISSING_TARGET ;
18911908 else if (results -> http_code == 401 ) {
1909+ http_auth .ntlm_suppressed = (results -> auth_avail & CURLAUTH_NTLM ) &&
1910+ !(http_auth_any & CURLAUTH_NTLM );
1911+ if (http_auth .ntlm_suppressed && http_auth .ntlm_allow ) {
1912+ http_auth_methods |= CURLAUTH_NTLM ;
1913+ return HTTP_REAUTH ;
1914+ }
18921915 if ((http_auth .username && http_auth .password ) || \
18931916 (http_auth .authtype && http_auth .credential )) {
18941917 if (http_auth .multistage ) {
@@ -1898,6 +1921,16 @@ static int handle_curl_result(struct slot_results *results)
18981921 credential_reject (the_repository , & http_auth );
18991922 if (always_auth_proactively ())
19001923 http_proactive_auth = PROACTIVE_AUTH_NONE ;
1924+ if (http_auth .ntlm_suppressed ) {
1925+ warning (_ ("Due to its cryptographic weaknesses, "
1926+ "NTLM authentication has been\n"
1927+ "disabled in Git by default. You can "
1928+ "re-enable it for trusted servers\n"
1929+ "by running:\n\n"
1930+ "git config set "
1931+ "http.%s://%s.allowNTLMAuth true" ),
1932+ http_auth .protocol , http_auth .host );
1933+ }
19011934 return HTTP_NOAUTH ;
19021935 } else {
19031936 http_auth_methods &= ~CURLAUTH_GSSNEGOTIATE ;
0 commit comments