http: for basic+digest auth, do not engage on empty user+passwd
No binary (build failed)
—
(log yok)
| @@ -73,6 +73,8 @@ bool Curl_creds_equal(struct Curl_creds *c1, struct Curl_creds *c2); | |
| /* Provides properties for creds or, if creds is NULL, the empty string */ | |
| #define Curl_creds_has_user(c) ((c) && (c)->user[0]) | |
| #define Curl_creds_has_passwd(c) ((c) && (c)->passwd[0]) | |
| + | #define Curl_creds_has_user_or_pass(c) \ |
| + | ((c) && ((c)->user[0] || (c)->passwd[0])) |
| #define Curl_creds_has_oauth_bearer(c) ((c) && (c)->oauth_bearer[0]) | |
| #define Curl_creds_has_sasl_service(c) ((c) && (c)->sasl_service[0]) | |
| #define Curl_creds_user(c) ((c) ? (c)->user : "") | |
| @@ -347,8 +347,10 @@ fail: | |
| * | |
| * return TRUE if one was picked | |
| */ | |
| - | static bool pickoneauth(struct auth *pick, unsigned long mask) |
| + | static bool pickoneauth(struct auth *pick, unsigned long mask, |
| + | struct Curl_creds *creds) |
| { | |
| + | bool have_user_pass = Curl_creds_has_user_or_pass(creds); |
| bool picked; | |
| /* only deal with authentication we want */ | |
| unsigned long avail = pick->avail & pick->want & mask; | |
| @@ -356,20 +358,20 @@ static bool pickoneauth(struct auth *pick, unsigned long mask) | |
| /* The order of these checks is highly relevant, as this will be the order | |
| of preference in case of the existence of multiple accepted types. */ | |
| - | if(avail & CURLAUTH_NEGOTIATE) |
| + | if(avail & CURLAUTH_NEGOTIATE) /* available on empty creds */ |
| pick->picked = CURLAUTH_NEGOTIATE; | |
| #ifndef CURL_DISABLE_BEARER_AUTH | |
| - | else if(avail & CURLAUTH_BEARER) |
| + | else if((avail & CURLAUTH_BEARER) && Curl_creds_has_oauth_bearer(creds)) |
| pick->picked = CURLAUTH_BEARER; | |
| #endif | |
| #ifndef CURL_DISABLE_DIGEST_AUTH | |
| - | else if(avail & CURLAUTH_DIGEST) |
| + | else if((avail & CURLAUTH_DIGEST) && have_user_pass) |
| pick->picked = CURLAUTH_DIGEST; | |
| #endif | |
| else if(avail & CURLAUTH_NTLM) | |
| pick->picked = CURLAUTH_NTLM; | |
| #ifndef CURL_DISABLE_BASIC_AUTH | |
| - | else if(avail & CURLAUTH_BASIC) |
| + | else if((avail & CURLAUTH_BASIC) && have_user_pass) |
| pick->picked = CURLAUTH_BASIC; | |
| #endif | |
| #ifndef CURL_DISABLE_AWS | |
| @@ -568,7 +570,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) | |
| if(data->state.creds && | |
| ((data->req.httpcode == 401) || | |
| (data->req.authneg && data->req.httpcode < 300))) { | |
| - | pickhost = pickoneauth(&data->state.authhost, authmask); |
| + | pickhost = pickoneauth(&data->state.authhost, authmask, data->state.creds); |
| if(!pickhost) | |
| data->state.authproblem = TRUE; | |
| else | |
| @@ -586,7 +588,8 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data) | |
| ((data->req.httpcode == 407) || | |
| (data->req.authneg && data->req.httpcode < 300))) { | |
| pickproxy = pickoneauth(&data->state.authproxy, | |
| - | authmask & ~CURLAUTH_BEARER); |
| + | authmask & ~CURLAUTH_BEARER, |
| + | conn->http_proxy.creds); |
| if(!pickproxy) | |
| data->state.authproblem = TRUE; | |
| else | |
| @@ -699,10 +702,12 @@ static CURLcode output_auth_headers(struct Curl_easy *data, | |
| if( | |
| #ifndef CURL_DISABLE_PROXY | |
| (proxy && conn->http_proxy.creds && | |
| + | Curl_creds_has_user_or_pass(conn->http_proxy.creds) && |
| !Curl_checkProxyheaders(data, conn, | |
| STRCONST("Proxy-authorization"))) || | |
| #endif | |
| (!proxy && data->state.creds && | |
| + | Curl_creds_has_user_or_pass(data->state.creds) && |
| !Curl_checkheaders(data, STRCONST("Authorization")))) { | |
| auth = "Basic"; | |
| result = http_output_basic(data, conn, proxy); | |
| @@ -256,6 +256,7 @@ test2088 test2089 test2090 test2091 test2092 \ | |
| test2100 test2101 test2102 test2103 test2104 test2105 test2106 test2107 \ | |
| \ | |
| test2200 test2201 test2202 test2203 test2204 test2205 test2206 test2207 \ | |
| + | test2208 \ |
| \ | |
| test2300 test2301 test2302 test2303 test2304 test2306 test2307 test2308 \ | |
| test2309 test2310 \ | |
| @@ -0,0 +1,90 @@ | |
| + | <?xml version="1.0" encoding="US-ASCII"?> |
| + | <testcase> |
| + | <info> |
| + | <keywords> |
| + | HTTP |
| + | HTTP proxy |
| + | --location |
| + | HTTP Basic auth |
| + | </keywords> |
| + | </info> |
| + | |
| + | # Server-side |
| + | <reply> |
| + | <data> |
| + | HTTP/1.1 301 redirect |
| + | Date: Tue, 09 Nov 2010 14:49:00 GMT |
| + | Server: test-server/fake |
| + | Content-Length: 0 |
| + | Connection: close |
| + | Content-Type: text/html |
| + | Location: http://@firsthost.com:9999/a/path/%TESTNUMBER0002 |
| + | |
| + | </data> |
| + | <data2> |
| + | HTTP/1.1 200 OK |
| + | Date: Tue, 09 Nov 2010 14:49:00 GMT |
| + | Server: test-server/fake |
| + | Content-Length: 4 |
| + | Connection: close |
| + | Content-Type: text/html |
| + | |
| + | hey |
| + | </data2> |
| + | |
| + | <datacheck> |
| + | HTTP/1.1 301 redirect |
| + | Date: Tue, 09 Nov 2010 14:49:00 GMT |
| + | Server: test-server/fake |
| + | Content-Length: 0 |
| + | Connection: close |
| + | Content-Type: text/html |
| + | Location: http://@firsthost.com:9999/a/path/%TESTNUMBER0002 |
| + | |
| + | HTTP/1.1 200 OK |
| + | Date: Tue, 09 Nov 2010 14:49:00 GMT |
| + | Server: test-server/fake |
| + | Content-Length: 4 |
| + | Connection: close |
| + | Content-Type: text/html |
| + | |
| + | hey |
| + | </datacheck> |
| + | |
| + | </reply> |
| + | |
| + | # Client-side |
| + | <client> |
| + | <features> |
| + | proxy |
| + | </features> |
| + | <server> |
| + | http |
| + | </server> |
| + | <name> |
| + | HTTP auth on redirect with empty URL userinfo |
| + | </name> |
| + | <command> |
| + | -x http://%HOSTIP:%HTTPPORT http://firsthost.com -L -u joe:secret |
| + | </command> |
| + | </client> |
| + | |
| + | # Verify data after the test has been "shot" |
| + | <verify> |
| + | <protocol crlf="headers"> |
| + | GET http://firsthost.com/ HTTP/1.1 |
| + | Host: firsthost.com |
| + | Authorization: Basic %b64[joe:secret]b64% |
| + | User-Agent: curl/%VERSION |
| + | Accept: */* |
| + | Proxy-Connection: Keep-Alive |
| + | |
| + | GET http://firsthost.com:9999/a/path/%TESTNUMBER0002 HTTP/1.1 |
| + | Host: firsthost.com:9999 |
| + | User-Agent: curl/%VERSION |
| + | Accept: */* |
| + | Proxy-Connection: Keep-Alive |
| + | |
| + | </protocol> |
| + | </verify> |
| + | </testcase> |