diff --git a/CHANGES b/CHANGES index dcafc6ba5..dd7843b02 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,13 @@ Changelog Daniel (22 April 2004) +- David Byron found and fixed a small bug with the --fail and authentication + stuff added a few weeks ago. Turns out that if you specify --proxy-ntlm and + communicate with a proxy that requires basic authentication, the proxy + properly returns a 407, but the failure detection code doesn't realize it + should give up, so curl returns with exit code 0. Test case 162 added to + verify the functionality. + - If a transfer is found out to be only partial, libcurl will now treat that as a problem serious enough to skip the final QUIT command before closing the control connection. To avoid the risk that it will "hang" waiting for diff --git a/lib/http.c b/lib/http.c index b2f919f67..0922b9eda 100644 --- a/lib/http.c +++ b/lib/http.c @@ -396,8 +396,13 @@ CURLcode Curl_http_auth(struct connectdata *conn, if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) { /* if exactly this is wanted, go */ int neg = Curl_input_negotiate(conn, start); - if (neg == 0) + if (neg == 0) { conn->newurl = strdup(data->change.url); + data->state.authproblem = (conn->newurl == NULL); + else { + infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } } else if(data->state.authwant & CURLAUTH_GSSNEGOTIATE) @@ -414,10 +419,14 @@ CURLcode Curl_http_auth(struct connectdata *conn, CURLntlm ntlm = Curl_input_ntlm(conn, (bool)(httpcode == 407), start); - if(CURLNTLM_BAD != ntlm) + if(CURLNTLM_BAD != ntlm) { conn->newurl = strdup(data->change.url); /* clone string */ - else + data->state.authproblem = (conn->newurl == NULL); + } + else { infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } } else if(data->state.authwant & CURLAUTH_NTLM) @@ -431,12 +440,16 @@ CURLcode Curl_http_auth(struct connectdata *conn, /* Digest authentication is activated */ CURLdigest dig = Curl_input_digest(conn, start); - if(CURLDIGEST_FINE == dig) + if(CURLDIGEST_FINE == dig) { /* We act on it. Store our new url, which happens to be the same one we already use! */ conn->newurl = strdup(data->change.url); /* clone string */ - else + data->state.authproblem = (conn->newurl == NULL); + } + else { infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; + } } else if(data->state.authwant & CURLAUTH_DIGEST) { @@ -458,9 +471,17 @@ CURLcode Curl_http_auth(struct connectdata *conn, valid. */ data->state.authavail = CURLAUTH_NONE; infof(data, "Authentication problem. Ignoring this.\n"); + data->state.authproblem = TRUE; } else if(data->state.authwant & CURLAUTH_BASIC) { data->state.authavail |= CURLAUTH_BASIC; + } else { + /* + ** We asked for something besides basic but got + ** Basic anyway. This is no good. + */ + infof(data, "Server expects Basic auth, but we're doing something else.\n"); + data->state.authproblem = TRUE; } } return CURLE_OK; @@ -531,13 +552,17 @@ int Curl_http_should_fail(struct connectdata *conn) */ #if 0 /* set to 1 when debugging this functionality */ infof(data,"%s: authstage = %d\n",__FUNCTION__,data->state.authstage); + infof(data,"%s: authwant = 0x%08x\n",__FUNCTION__,data->state.authwant); + infof(data,"%s: authavail = 0x%08x\n",__FUNCTION__,data->state.authavail); infof(data,"%s: httpcode = %d\n",__FUNCTION__,k->httpcode); infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone); + infof(data,"%s: newurl = %s\n",__FUNCTION__,conn->newurl ? conn->newurl : "(null)"); + infof(data,"%s: authproblem = %d\n",__FUNCTION__,data->state.authproblem); #endif if (data->state.authstage && (data->state.authstage == k->httpcode)) - return data->state.authdone; + return (data->state.authdone || data->state.authproblem); /* ** Either we're not authenticating, or we're supposed to diff --git a/lib/transfer.c b/lib/transfer.c index 2d0b4aa33..1151e05b6 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -1499,6 +1499,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data) /* set preferred authentication, default to basic */ data->state.authstage = 0; /* initialize authentication later */ + data->state.authproblem = FALSE; /* If there was a list of cookie files to read and we haven't done it before, do it now! */ diff --git a/lib/urldata.h b/lib/urldata.h index 55070ccbf..7642cb9a1 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -725,6 +725,7 @@ struct UrlState { depending on authstage) */ long authavail; /* what the server reports */ + bool authproblem; /* TRUE if there's some problem authenticating */ bool authdone; /* TRUE when the auth phase is done and ready to do the *actual* request */ #ifdef USE_ARES diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 39c807a39..abce9bdef 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -22,7 +22,7 @@ test80 test81 test82 test83 test84 test85 test86 test87 test507 \ test149 test88 test89 test90 test508 test91 test92 test203 test93 \ test94 test95 test509 test510 test97 test98 test99 test150 test151 \ test152 test153 test154 test155 test156 test157 test158 test159 test511 \ -test160 test161 +test160 test161 test162 # The following tests have been removed from the dist since they no longer # work. We need to fix the test suite's FTPS server first, then bring them diff --git a/tests/data/test162 b/tests/data/test162 new file mode 100644 index 000000000..27576c0f9 --- /dev/null +++ b/tests/data/test162 @@ -0,0 +1,45 @@ +# Server-side + + +HTTP/1.0 407 BAD BOY +Proxy-Authenticate: Basic realm="Squid proxy-caching web server" +Server: swsclose +Content-Type: text/html + +Even though it's the response code that triggers authentication, we're +using NTLM and the server isn't, so we should fail. We know the server +isn't because there's no Proxy-Authorization: NTLM header + + + +# Client-side + + +http + + +HTTP GET asking for --proxy-ntlm when some other authentication is required + + +http://%HOSTIP:%HOSTPORT/162 --proxy http://%HOSTIP:%HOSTPORT --proxy-user foo:bar --proxy-ntlm --fail + + + +# Verify data after the test has been "shot" + + +^User-Agent: curl/.* + + +GET http://127.0.0.1:8999/162 HTTP/1.1 +Proxy-Authorization: NTLM TlRMTVNTUAABAAAAAgIAAAAAAAAgAAAAAAAAACAAAAA= +User-Agent: curl/7.8.1-pre3 (sparc-sun-solaris2.7) libcurl 7.8.1-pre3 (OpenSSL 0.9.6a) (krb4 enabled) +Host: 127.0.0.1:8999 +Pragma: no-cache +Accept: */* + + + +22 + +