1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-22 16:18:48 -05:00

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.
This commit is contained in:
Daniel Stenberg 2007-12-05 21:20:14 +00:00
parent 59dc9085d1
commit 7d3ea12b62
6 changed files with 185 additions and 9 deletions

View File

@ -7,6 +7,13 @@
Changelog 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) Daniel S (3 Dec 2007)
- Ray Pekowski filed bug report #1842029 - Ray Pekowski filed bug report #1842029
(http://curl.haxx.se/bug/view.cgi?id=1842029) in which he identified a (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) Daniel S (24 Nov 2007)
- Internal rearrangements, so that the previous struct HandleData is no more. - 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 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 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 used to store what data. The transfer_keeper thing was once stored on a

View File

@ -33,6 +33,7 @@ This release includes the following bugfixes:
buffers buffers
o no longer default-appends ;type= on FTP URLs thru proxies o no longer default-appends ;type= on FTP URLs thru proxies
o SSL session id caching o SSL session id caching
o POST with callback over proxy requiring NTLM or Digest
This release includes the following known bugs: 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, Dan Fandrich, Gisle Vanem, Toby Peterson, Yang Tse, Daniel Black,
Robin Johnson, Michal Marek, Ates Goral, Andres Garcia, Rob Crittenden, 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) Thanks! (and sorry if I forgot to mention someone)

View File

@ -2687,8 +2687,10 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* set the upload size to the progress meter */ /* set the upload size to the progress meter */
Curl_pgrsSetUploadSize(data, postsize?postsize:-1); Curl_pgrsSetUploadSize(data, postsize?postsize:-1);
/* set the pointer to mark that we will send the post body using /* set the pointer to mark that we will send the post body using the
the read callback */ read callback, but only if we're not in authenticate
negotiation */
if(!conn->bits.authneg)
http->postdata = (char *)&http->postdata; http->postdata = (char *)&http->postdata;
} }
} }

131
tests/data/test547 Normal file
View File

@ -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
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
Proxy-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"
Proxy-Authenticate: Basic realm="gimme all yer s3cr3ts"
Proxy-Authenticate: NTLM
Content-Type: text/html; charset=iso-8859-1
Connection: close
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
Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==
Content-Length: 34
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
Server: Microsoft-IIS/5.0
Content-Type: text/html; charset=iso-8859-1
Content-Length: 42
Contents of that page you requested, sir.
</data1002>
<datacheck>
HTTP/1.1 407 Authorization Required swsclose
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
Proxy-Authenticate: Blackmagic realm="gimme all yer s3cr3ts"
Proxy-Authenticate: Basic realm="gimme all yer s3cr3ts"
Proxy-Authenticate: NTLM
Content-Type: text/html; charset=iso-8859-1
Connection: close
HTTP/1.1 407 Authorization Required to proxy me my dear
Proxy-Authenticate: NTLM TlRMTVNTUAACAAAAAgACADAAAAAGgoEAc51AYVDgyNcAAAAAAAAAAG4AbgAyAAAAQ0MCAAQAQwBDAAEAEgBFAEwASQBTAEEAQgBFAFQASAAEABgAYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAwAsAGUAbABpAHMAYQBiAGUAdABoAC4AYwBjAC4AaQBjAGUAZABlAHYALgBuAHUAAAAAAA==
Content-Length: 34
HTTP/1.1 200 Things are fine in proxy land swsclose
Server: Microsoft-IIS/5.0
Content-Type: text/html; charset=iso-8859-1
Content-Length: 42
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
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
Host: test.remote.server.com
Pragma: no-cache
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
Content-Type: application/x-www-form-urlencoded
this is the blurb we want to upload
POST http://test.remote.server.com/path/547 HTTP/1.1
Proxy-Authorization: NTLM TlRMTVNTUAABAAAABoIIAAAAAAAAAAAAAAAAAAAAAAA=
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
Host: test.remote.server.com
Pragma: no-cache
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 0
Content-Type: application/x-www-form-urlencoded
POST http://test.remote.server.com/path/547 HTTP/1.1
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
Host: test.remote.server.com
Pragma: no-cache
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 36
Content-Type: application/x-www-form-urlencoded
this is the blurb we want to upload
</protocol>
</verify>
</testcase>

View File

@ -3,7 +3,6 @@
<keywords> <keywords>
HTTP HTTP
HTTP POST HTTP POST
--proxy-anyauth
HTTP proxy NTLM auth HTTP proxy NTLM auth
</keywords> </keywords>
</info> </info>

View File

@ -20,21 +20,49 @@
static size_t readcallback(void *ptr, static size_t readcallback(void *ptr,
size_t size, size_t size,
size_t nmemb, 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)) { if(size * nmemb > strlen(UPLOADTHIS)) {
fprintf(stderr, "READ!\n");
strcpy(ptr, UPLOADTHIS); strcpy(ptr, UPLOADTHIS);
return strlen(UPLOADTHIS); return strlen(UPLOADTHIS);
} }
fprintf(stderr, "READ NOT FINE!\n");
return 0; 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 #endif
int test(char *URL) int test(char *URL)
{ {
CURLcode res; CURLcode res;
CURL *curl; CURL *curl;
#ifndef LIB548
int counter=0;
#endif
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
fprintf(stderr, "curl_global_init() failed\n"); 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_VERBOSE, 1);
curl_easy_setopt(curl, CURLOPT_HEADER, TRUE); curl_easy_setopt(curl, CURLOPT_HEADER, TRUE);
#ifdef LIB548 #ifdef LIB548
/* set the data to POST with a mere pointer to a zero-terminated string */
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, UPLOADTHIS); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, UPLOADTHIS);
#else #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_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 #endif
curl_easy_setopt(curl, CURLOPT_POST, 1); curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2); curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);