]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
HTTP auth: fix proxy Negotiate bug
authorRene Bernhardt <rene.bernhardt@pcvisit.de>
Thu, 3 Nov 2011 22:25:17 +0000 (23:25 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Sun, 6 Nov 2011 16:19:37 +0000 (17:19 +0100)
If a proxy offers several Authentication schemes where NTLM and
Negotiate are offered by the proxy and you tell libcurl not to use the
Negotiate scheme then the request never returns when the proxy answers
with its HTTP 407 reply.

It is reproducible by the following steps:

- Use a proxy that offers NTLM and Negotiate ( CURLOPT_PROXY and
CURLOPT_PROXYPORT )

- Tell libcurl NOT to use Negotiate CURL_EASY_SETOPT(CURLOPT_PROXYAUTH,
CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM )

- Start the request

The call to CURL_EASY_PERFORM never returns. If you switch on debug
logging you can see that libcurl issues a new request As soon as it
received the 407 reply. Instead it should return and set the response
code to 407.

Bug: http://curl.haxx.se/mail/lib-2011-10/0323.html

lib/http.c

index f85cd6c55f0daa4f7d314f086cc64b5ee62aef9c..fe1c7fd88fef9891cf93eaa949d132fd6f08701f 100644 (file)
@@ -741,25 +741,26 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
       *availp |= CURLAUTH_GSSNEGOTIATE;
       authp->avail |= CURLAUTH_GSSNEGOTIATE;
 
-      if(data->state.negotiate.state == GSS_AUTHSENT) {
-        /* if we sent GSS authentication in the outgoing request and we get
-           this back, we're in trouble */
-        infof(data, "Authentication problem. Ignoring this.\n");
-        data->state.authproblem = TRUE;
-      }
-      else {
-        neg = Curl_input_negotiate(conn, (httpcode == 407)?TRUE:FALSE, start);
-        if(neg == 0) {
-          DEBUGASSERT(!data->req.newurl);
-          data->req.newurl = strdup(data->change.url);
-          if(!data->req.newurl)
-            return CURLE_OUT_OF_MEMORY;
-          data->state.authproblem = FALSE;
-          /* we received GSS auth info and we dealt with it fine */
-          data->state.negotiate.state = GSS_AUTHRECV;
+      if(authp->picked == CURLAUTH_GSSNEGOTIATE) {
+        if(data->state.negotiate.state == GSS_AUTHSENT) {
+          /* if we sent GSS authentication in the outgoing request and we get
+             this back, we're in trouble */
+          infof(data, "Authentication problem. Ignoring this.\n");
+          data->state.authproblem = TRUE;
         }
         else {
-          data->state.authproblem = TRUE;
+          neg = Curl_input_negotiate(conn, (bool)(httpcode == 407), start);
+          if(neg == 0) {
+            DEBUGASSERT(!data->req.newurl);
+            data->req.newurl = strdup(data->change.url);
+            if(!data->req.newurl)
+              return CURLE_OUT_OF_MEMORY;
+            data->state.authproblem = FALSE;
+            /* we received GSS auth info and we dealt with it fine */
+            data->state.negotiate.state = GSS_AUTHRECV;
+          }
+          else
+            data->state.authproblem = TRUE;
         }
       }
     }