]> granicus.if.org Git - curl/commitdiff
Spacen Jasset reported a problem with doing POST (with data read with a
authorDaniel Stenberg <daniel@haxx.se>
Wed, 5 Dec 2007 21:20:14 +0000 (21:20 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 5 Dec 2007 21:20:14 +0000 (21:20 +0000)
callback) over a proxy when NTLM is used as auth with the proxy. The bug
also concerned Digest and was limited to using callback only. Spacen worked
with us to provide a useful patch. I added the test case 547 and 548 to
verify two variations of POST over proxy with NTLM.

CHANGES
RELEASE-NOTES
lib/http.c
tests/data/test547 [new file with mode: 0644]
tests/data/test548
tests/libtest/lib547.c

diff --git a/CHANGES b/CHANGES
index 353229f7b6e34b98391cf85c306a4feb5ad01fef..85373a85c51d1a1012a46aae9bdbc7c490ecffec 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -7,6 +7,13 @@
                                   Changelog
 
 
+Daniel S (5 Dec 2007)
+- Spacen Jasset reported a problem with doing POST (with data read with a
+  callback) over a proxy when NTLM is used as auth with the proxy. The bug
+  also concerned Digest and was limited to using callback only. Spacen worked
+  with us to provide a useful patch. I added the test case 547 and 548 to
+  verify two variations of POST over proxy with NTLM.
+
 Daniel S (3 Dec 2007)
 - Ray Pekowski filed bug report #1842029
   (http://curl.haxx.se/bug/view.cgi?id=1842029) in which he identified a
@@ -43,7 +50,7 @@ Daniel S (25 Nov 2007)
 
 Daniel S (24 Nov 2007)
 - Internal rearrangements, so that the previous struct HandleData is no more.
-  It is now known is SingleRequest and the Curl_transfer_keeper struct within
+  It is now known as SingleRequest and the Curl_transfer_keeper struct within
   that was remove entirely. This has the upside that there are less duplicate
   struct members that made it hard to see and remember what struct that was
   used to store what data. The transfer_keeper thing was once stored on a
index b4cb07dc8cfee475eee920260550fb63096f10c2..d69a091cd5f3df17ff2579912e475c1dd757a9a4 100644 (file)
@@ -33,6 +33,7 @@ This release includes the following bugfixes:
    buffers
  o no longer default-appends ;type= on FTP URLs thru proxies
  o SSL session id caching
+ o POST with callback over proxy requiring NTLM or Digest
 
 This release includes the following known bugs:
 
@@ -52,6 +53,6 @@ advice from friends like these:
 
  Dan Fandrich, Gisle Vanem, Toby Peterson, Yang Tse, Daniel Black,
  Robin Johnson, Michal Marek, Ates Goral, Andres Garcia, Rob Crittenden,
- Emil Romanus, Alessandro Vesely, Ray Pekowski
+ Emil Romanus, Alessandro Vesely, Ray Pekowski, Spacen Jasset
  
         Thanks! (and sorry if I forgot to mention someone)
index 7cfb23f3caf2c5ed6b34620ff9dc7e38a8aff68b..70418af96986f37d8c894ebdf2a8b474c324f884 100644 (file)
@@ -2687,9 +2687,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
           /* set the upload size to the progress meter */
           Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
 
-          /* set the pointer to mark that we will send the post body using
-             the read callback */
-          http->postdata = (char *)&http->postdata;
+          /* set the pointer to mark that we will send the post body using the
+             read callback, but only if we're not in authenticate
+             negotiation  */
+          if(!conn->bits.authneg)
+            http->postdata = (char *)&http->postdata;
         }
       }
       /* issue the request */
diff --git a/tests/data/test547 b/tests/data/test547
new file mode 100644 (file)
index 0000000..7b0c732
--- /dev/null
@@ -0,0 +1,131 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP POST
+POST callback
+HTTP proxy NTLM auth
+</keywords>
+</info>
+# Server-side
+<reply>
+
+<data>
+HTTP/1.1 407 Authorization Required swsclose\r
+Server: Apache/1.3.27 (Darwin) PHP/4.1.2\r
+Proxy-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"\r
+Proxy-Authenticate: Basic realm="gimme all yer s3cr3ts"\r
+Proxy-Authenticate: NTLM\r
+Content-Type: text/html; charset=iso-8859-1\r
+Connection: close\r
+\r
+This is not the real page
+</data>
+
+# this is returned first since we get no proxy-auth
+<data1001>
+HTTP/1.1 407 Authorization Required to proxy me my dear\r
+Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==\r
+Content-Length: 34\r
+\r
+Hey you, authenticate or go away!
+</data1001>
+
+# This is supposed to be returned when the server gets the second
+# Authorization: NTLM line passed-in from the client
+<data1002>
+HTTP/1.1 200 Things are fine in proxy land swsclose\r
+Server: Microsoft-IIS/5.0\r
+Content-Type: text/html; charset=iso-8859-1\r
+Content-Length: 42\r
+\r
+Contents of that page you requested, sir.
+</data1002>
+
+<datacheck>
+HTTP/1.1 407 Authorization Required swsclose\r
+Server: Apache/1.3.27 (Darwin) PHP/4.1.2\r
+Proxy-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"\r
+Proxy-Authenticate: Basic realm="gimme all yer s3cr3ts"\r
+Proxy-Authenticate: NTLM\r
+Content-Type: text/html; charset=iso-8859-1\r
+Connection: close\r
+\r
+HTTP/1.1 407 Authorization Required to proxy me my dear\r
+Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==\r
+Content-Length: 34\r
+\r
+HTTP/1.1 200 Things are fine in proxy land swsclose\r
+Server: Microsoft-IIS/5.0\r
+Content-Type: text/html; charset=iso-8859-1\r
+Content-Length: 42\r
+\r
+Contents of that page you requested, sir.
+</datacheck>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+# tool to use
+<tool>
+lib547
+</tool>
+<features>
+NTLM
+</features>
+ <name>
+HTTP proxy auth NTLM with POST data from read callback
+ </name>
+ <command>
+http://test.remote.server.com/path/547 http://%HOSTIP:%HTTPPORT s1lly:pers0n
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent: curl/.*
+</strip>
+# We strip off a large chunk of the type-2 NTLM message since it depends on
+# the local host name and thus differs on different machines!
+<strippart>
+s/^(Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAABQAFAHAAAAA).*/$1/
+</strippart>
+<protocol>
+POST http://test.remote.server.com/path/547 HTTP/1.1\r
+User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13\r
+Host: test.remote.server.com\r
+Pragma: no-cache\r
+Accept: */*\r
+Proxy-Connection: Keep-Alive\r
+Content-Length: 36\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+this is the blurb we want to upload
+POST http://test.remote.server.com/path/547 HTTP/1.1\r
+Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=\r
+User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13\r
+Host: test.remote.server.com\r
+Pragma: no-cache\r
+Accept: */*\r
+Proxy-Connection: Keep-Alive\r
+Content-Length: 0\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+POST http://test.remote.server.com/path/547 HTTP/1.1\r
+Proxy-Authorization: NTLM TlRMTVNTUAADAAAAGAAYAEAAAAAYABgAWAAAAAAAAABwAAAABQAFAHAAAAA
+User-Agent: curl/7.13.2-CVS (i686-pc-linux-gnu) libcurl/7.13.2-CVS OpenSSL/0.9.7e zlib/1.2.2 libidn/0.5.13\r
+Host: test.remote.server.com\r
+Pragma: no-cache\r
+Accept: */*\r
+Proxy-Connection: Keep-Alive\r
+Content-Length: 36\r
+Content-Type: application/x-www-form-urlencoded\r
+\r
+this is the blurb we want to upload
+</protocol>
+</verify>
+</testcase>
index 04a1a639657dcfb0dfa04bd50a32ba0799173ee8..5db47638615e642a4419d50db2f2f5609effb131 100644 (file)
@@ -3,7 +3,6 @@
 <keywords>
 HTTP
 HTTP POST
---proxy-anyauth
 HTTP proxy NTLM auth
 </keywords>
 </info>
index 0513911d6bf0fd00dbe8d6caa04a3d8f7f72c9e6..2d4011213c3611501546639b32ffb1ca7f67950a 100644 (file)
 static size_t readcallback(void  *ptr,
                            size_t size,
                            size_t nmemb,
-                           void *stream)
+                           void *clientp)
 {
-  (void)stream; /* unused */
+  int *counter = (int *)clientp;
+
+  if(*counter) {
+    /* only do this once and then require a clearing of this */
+    fprintf(stderr, "READ ALREADY DONE!\n");
+    return 0;
+  }
+  (*counter)++; /* bump */
+
   if(size * nmemb > strlen(UPLOADTHIS)) {
+    fprintf(stderr, "READ!\n");
     strcpy(ptr, UPLOADTHIS);
     return strlen(UPLOADTHIS);
   }
+  fprintf(stderr, "READ NOT FINE!\n");
   return 0;
 }
+static curlioerr ioctlcallback(CURL *handle,
+                               int cmd,
+                               void *clientp)
+{
+  int *counter = (int *)clientp;
+  (void)handle; /* unused */
+  if(cmd == CURLIOCMD_RESTARTREAD) {
+    fprintf(stderr, "REWIND!\n");
+    *counter = 0; /* clear counter to make the read callback restart */
+  }
+  return CURLIOE_OK;
+}
+
+
+
 #endif
 
 int test(char *URL)
 {
   CURLcode res;
   CURL *curl;
+#ifndef LIB548
+  int counter=0;
+#endif
 
   if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
     fprintf(stderr, "curl_global_init() failed\n");
@@ -51,10 +79,18 @@ int test(char *URL)
   curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
   curl_easy_setopt(curl, CURLOPT_HEADER, TRUE);
 #ifdef LIB548
+  /* set the data to POST with a mere pointer to a zero-terminated string */
   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, UPLOADTHIS);
 #else
-  /* 547 style */
+  /* 547 style, which means reading the POST data from a callback */
+  curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
+  curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &counter);
   curl_easy_setopt(curl, CURLOPT_READFUNCTION, readcallback);
+  curl_easy_setopt(curl, CURLOPT_READDATA, &counter);
+  /* TODO: We should be able to do the POST fine without setting the size
+     and we should do a test to verify that but until we do that we set
+     the size of the request-body */
+  curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(UPLOADTHIS));
 #endif
   curl_easy_setopt(curl, CURLOPT_POST, 1);
   curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);