]> granicus.if.org Git - curl/commitdiff
Christopher R. Palmer reported a problem with HTTP-POSTing using "anyauth"
authorDaniel Stenberg <daniel@haxx.se>
Wed, 16 Feb 2005 14:31:23 +0000 (14:31 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 16 Feb 2005 14:31:23 +0000 (14:31 +0000)
that picks NTLM. Thanks to David Byron letting me test NTLM against his
servers, I could quickly repeat and fix the problem. It turned out to be:

When libcurl POSTs without knowing/using an authentication and it gets back a
list of types from which it picks NTLM, it needs to either continue sending
its data if it keeps the connection alive, or not send the data but close the
connection. Then do the first step in the NTLM auth. libcurl didn't send the
data nor close the connection but simply read the response-body and then sent
the first negotiation step. Which then failed miserably of course. The fixed
version forces a connection if there is more than 2000 bytes left to send.

CHANGES
RELEASE-NOTES
lib/http.c
lib/transfer.c

diff --git a/CHANGES b/CHANGES
index acf549a12d405f1f07709fd508699cf73a118a36..6460e2c07e0eb418f8660e26a884ed19c268f149 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,24 @@
 
                                   Changelog
 
+Daniel (16 February 2005)
+- Christopher R. Palmer reported a problem with HTTP-POSTing using "anyauth"
+  that picks NTLM. Thanks to David Byron letting me test NTLM against his
+  servers, I could quickly repeat and fix the problem. It turned out to be:
+
+  When libcurl POSTs without knowing/using an authentication and it gets back
+  a list of types from which it picks NTLM, it needs to either continue
+  sending its data if it keeps the connection alive, or not send the data but
+  close the connection. Then do the first step in the NTLM auth. libcurl
+  didn't send the data nor close the connection but simply read the
+  response-body and then sent the first negotiation step. Which then failed
+  miserably of course. The fixed version forces a connection if there is more
+  than 2000 bytes left to send.
+
+Daniel (14 February 2005)
+- The configure script didn't check for ENGINE_load_builtin_engines() so it
+  was never used.
+
 Daniel (11 February 2005)
 - Removed all uses of strftime() since it uses the localised version of the
   week day names and month names and servers don't like that.
index 91027552e6471611e5015f7f00853246812d8a40..22c3af167ccaf04826fe7b4e38dcbabed148d635 100644 (file)
@@ -16,6 +16,7 @@ This release includes the following changes:
 
 This release includes the following bugfixes:
 
+ o HTTP POST with --anyauth picking NTLM
  o SSL problems when downloading exactly 16KB data
  o out of memory conditions preserve error codes better
  o a few crashes at out of memory
@@ -31,6 +32,7 @@ Other curl-related news since the previous public release:
 This release would not have looked like this without help, code, reports and
 advice from friends like these:
 
- Gisle Vanem, David Byron, Marty Kuhrt, Maruko, Eric Vergnaud
+ Gisle Vanem, David Byron, Marty Kuhrt, Maruko, Eric Vergnaud, Christopher
+ R. Palmer
 
         Thanks! (and sorry if I forgot to mention someone)
index 706cf7e308a523d2c45e98624984335598d21b85..a5f29da3b66f89924f9827d392a2cd0f8232ff2e 100644 (file)
@@ -251,21 +251,31 @@ static CURLcode perhapsrewind(struct connectdata *conn)
 
   if((expectsend == -1) || (expectsend > bytessent)) {
     /* There is still data left to send */
-    if((data->state.authproxy.picked == CURLAUTH_NTLM) ||/* using NTLM */
-       (data->state.authhost.picked == CURLAUTH_NTLM) ) {
-      conn->bits.close = FALSE; /* don't close, keep on sending */
+    if((data->state.authproxy.picked == CURLAUTH_NTLM) ||
+       (data->state.authhost.picked == CURLAUTH_NTLM)) {
+      if(((expectsend - bytessent) < 2000) ||
+         (conn->ntlm.state != NTLMSTATE_NONE)) {
+        /* The NTLM-negotiation has started *OR* there is just a little (<2K)
+           data left to send, keep on sending. */
+
+        /* rewind data when completely done sending! */
+        if(!conn->bits.authneg)
+          conn->bits.rewindaftersend = TRUE;
+
+        return CURLE_OK;
+      }
+      if(conn->bits.close)
+        /* this is already marked to get closed */
+        return CURLE_OK;
 
-      /* rewind data when completely done sending! */
-      conn->bits.rewindaftersend = TRUE;
-      return CURLE_OK;
-    }
-    else {
-      /* If there is more than just a little data left to send, close the
-       * current connection by force.
-       */
-      conn->bits.close = TRUE;
-      conn->size = 0; /* don't download any more than 0 bytes */
+      infof(data, "NTLM send, close instead of sending %ld bytes\n",
+            expectsend - bytessent);
     }
+
+    /* This is not NTLM or NTLM with many bytes left to send: close
+     */
+    conn->bits.close = TRUE;
+    conn->size = 0; /* don't download any more than 0 bytes */
   }
 
   if(bytessent)
@@ -310,7 +320,8 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
     conn->newurl = strdup(data->change.url); /* clone URL */
 
     if((data->set.httpreq != HTTPREQ_GET) &&
-       (data->set.httpreq != HTTPREQ_HEAD)) {
+       (data->set.httpreq != HTTPREQ_HEAD) &&
+       !conn->bits.rewindaftersend) {
       code = perhapsrewind(conn);
       if(code)
         return code;
index 97a085d54fcbf73c79490d594b12095b220d16ca..7142d517bad63f047215491c0a1bdb13db011468 100644 (file)
@@ -541,6 +541,13 @@ CURLcode Curl_readwrite(struct connectdata *conn,
 
                 if(result)
                   return result;
+
+                if(conn->bits.rewindaftersend) {
+                  /* We rewind after a complete send, so thus we continue
+                     sending now */
+                  infof(data, "Keep sending data to get tossed away!\n");
+                  k->keepon |= KEEP_WRITE;
+                }
               }
 #endif   /* CURL_DISABLE_HTTP */