- 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 verifies
  this.
This commit is contained in:
Daniel Stenberg 2004-04-22 20:07:41 +00:00
parent 84406b3e2c
commit 2ff30d067c
6 changed files with 86 additions and 7 deletions

View File

@ -7,6 +7,13 @@
Changelog Changelog
Daniel (22 April 2004) 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 - 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 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 the control connection. To avoid the risk that it will "hang" waiting for

View File

@ -396,8 +396,13 @@ CURLcode Curl_http_auth(struct connectdata *conn,
if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) { if(data->state.authwant == CURLAUTH_GSSNEGOTIATE) {
/* if exactly this is wanted, go */ /* if exactly this is wanted, go */
int neg = Curl_input_negotiate(conn, start); int neg = Curl_input_negotiate(conn, start);
if (neg == 0) if (neg == 0) {
conn->newurl = strdup(data->change.url); 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 else
if(data->state.authwant & CURLAUTH_GSSNEGOTIATE) if(data->state.authwant & CURLAUTH_GSSNEGOTIATE)
@ -414,10 +419,14 @@ CURLcode Curl_http_auth(struct connectdata *conn,
CURLntlm ntlm = CURLntlm ntlm =
Curl_input_ntlm(conn, (bool)(httpcode == 407), start); Curl_input_ntlm(conn, (bool)(httpcode == 407), start);
if(CURLNTLM_BAD != ntlm) if(CURLNTLM_BAD != ntlm) {
conn->newurl = strdup(data->change.url); /* clone string */ conn->newurl = strdup(data->change.url); /* clone string */
else data->state.authproblem = (conn->newurl == NULL);
}
else {
infof(data, "Authentication problem. Ignoring this.\n"); infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
} }
else else
if(data->state.authwant & CURLAUTH_NTLM) if(data->state.authwant & CURLAUTH_NTLM)
@ -431,12 +440,16 @@ CURLcode Curl_http_auth(struct connectdata *conn,
/* Digest authentication is activated */ /* Digest authentication is activated */
CURLdigest dig = Curl_input_digest(conn, start); 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 /* We act on it. Store our new url, which happens to be
the same one we already use! */ the same one we already use! */
conn->newurl = strdup(data->change.url); /* clone string */ conn->newurl = strdup(data->change.url); /* clone string */
else data->state.authproblem = (conn->newurl == NULL);
}
else {
infof(data, "Authentication problem. Ignoring this.\n"); infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
} }
else else
if(data->state.authwant & CURLAUTH_DIGEST) { if(data->state.authwant & CURLAUTH_DIGEST) {
@ -458,9 +471,17 @@ CURLcode Curl_http_auth(struct connectdata *conn,
valid. */ valid. */
data->state.authavail = CURLAUTH_NONE; data->state.authavail = CURLAUTH_NONE;
infof(data, "Authentication problem. Ignoring this.\n"); infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
} }
else if(data->state.authwant & CURLAUTH_BASIC) { else if(data->state.authwant & CURLAUTH_BASIC) {
data->state.authavail |= 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; return CURLE_OK;
@ -531,13 +552,17 @@ int Curl_http_should_fail(struct connectdata *conn)
*/ */
#if 0 /* set to 1 when debugging this functionality */ #if 0 /* set to 1 when debugging this functionality */
infof(data,"%s: authstage = %d\n",__FUNCTION__,data->state.authstage); 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: httpcode = %d\n",__FUNCTION__,k->httpcode);
infof(data,"%s: authdone = %d\n",__FUNCTION__,data->state.authdone); 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 #endif
if (data->state.authstage && if (data->state.authstage &&
(data->state.authstage == k->httpcode)) (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 ** Either we're not authenticating, or we're supposed to

View File

@ -1499,6 +1499,7 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
/* set preferred authentication, default to basic */ /* set preferred authentication, default to basic */
data->state.authstage = 0; /* initialize authentication later */ 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, /* If there was a list of cookie files to read and we haven't done it before,
do it now! */ do it now! */

View File

@ -725,6 +725,7 @@ struct UrlState {
depending on authstage) */ depending on authstage) */
long authavail; /* what the server reports */ 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 bool authdone; /* TRUE when the auth phase is done and ready
to do the *actual* request */ to do the *actual* request */
#ifdef USE_ARES #ifdef USE_ARES

View File

@ -22,7 +22,7 @@ test80 test81 test82 test83 test84 test85 test86 test87 test507 \
test149 test88 test89 test90 test508 test91 test92 test203 test93 \ test149 test88 test89 test90 test508 test91 test92 test203 test93 \
test94 test95 test509 test510 test97 test98 test99 test150 test151 \ test94 test95 test509 test510 test97 test98 test99 test150 test151 \
test152 test153 test154 test155 test156 test157 test158 test159 test511 \ 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 # 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 # work. We need to fix the test suite's FTPS server first, then bring them

45
tests/data/test162 Normal file
View File

@ -0,0 +1,45 @@
# Server-side
<reply>
<data1001 nocheck=1>
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
</data1001>
</reply>
# Client-side
<client>
<server>
http
</server>
<name>
HTTP GET asking for --proxy-ntlm when some other authentication is required
</name>
<command>
http://%HOSTIP:%HOSTPORT/162 --proxy http://%HOSTIP:%HOSTPORT --proxy-user foo:bar --proxy-ntlm --fail
</command>
</test>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent: curl/.*
</strip>
<protocol>
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: */*
</protocol>
<errorcode>
22
</errorcode>
</verify>