aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/http.c68
-rw-r--r--lib/http.h17
-rw-r--r--lib/urldata.h3
3 files changed, 48 insertions, 40 deletions
diff --git a/lib/http.c b/lib/http.c
index 1e9693f8a..9c9d6d533 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -168,29 +168,25 @@ static CURLcode Curl_output_basic(struct connectdata *conn, bool proxy)
static bool pickoneauth(struct auth *pick)
{
bool picked;
- if(pick->avail) {
- /* only deal with authentication we want */
- long avail = pick->avail & pick->want;
- picked = TRUE;
-
- /* The order of these checks is highly relevant, as this will be the order
- of preference in case of the existance of multiple accepted types. */
- if(avail & CURLAUTH_GSSNEGOTIATE)
- pick->picked = CURLAUTH_GSSNEGOTIATE;
- else if(avail & CURLAUTH_DIGEST)
- pick->picked = CURLAUTH_DIGEST;
- else if(avail & CURLAUTH_NTLM)
- pick->picked = CURLAUTH_NTLM;
- else if(avail & CURLAUTH_BASIC)
- pick->picked = CURLAUTH_BASIC;
- else {
- pick->picked = CURLAUTH_NONE; /* none was picked clear it */
- picked = FALSE;
- }
- pick->avail = CURLAUTH_NONE; /* clear it here */
+ /* only deal with authentication we want */
+ long avail = pick->avail & pick->want;
+ picked = TRUE;
+
+ /* The order of these checks is highly relevant, as this will be the order
+ of preference in case of the existance of multiple accepted types. */
+ if(avail & CURLAUTH_GSSNEGOTIATE)
+ pick->picked = CURLAUTH_GSSNEGOTIATE;
+ else if(avail & CURLAUTH_DIGEST)
+ pick->picked = CURLAUTH_DIGEST;
+ else if(avail & CURLAUTH_NTLM)
+ pick->picked = CURLAUTH_NTLM;
+ else if(avail & CURLAUTH_BASIC)
+ pick->picked = CURLAUTH_BASIC;
+ else {
+ pick->picked = CURLAUTH_PICKNONE; /* we select to use nothing */
+ picked = FALSE;
}
- else
- return FALSE;
+ pick->avail = CURLAUTH_NONE; /* clear it here */
return picked;
}
@@ -212,14 +208,16 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
if(data->state.authproblem)
return data->set.http_fail_on_error?CURLE_HTTP_RETURNED_ERROR:CURLE_OK;
- if(conn->bits.user_passwd) {
+ if(conn->bits.user_passwd &&
+ ((conn->keep.httpcode == 401) || conn->bits.authprobe)) {
pickhost = pickoneauth(&data->state.authhost);
- if(!pickhost && (conn->keep.httpcode == 401))
+ if(!pickhost)
data->state.authproblem = TRUE;
}
- if(conn->bits.proxy_user_passwd) {
+ if(conn->bits.proxy_user_passwd &&
+ ((conn->keep.httpcode == 407) || conn->bits.authprobe) ) {
pickproxy = pickoneauth(&data->state.authproxy);
- if(!pickproxy && (conn->keep.httpcode == 407))
+ if(!pickproxy)
data->state.authproblem = TRUE;
}
@@ -283,21 +281,17 @@ Curl_http_output_auth(struct connectdata *conn,
return CURLE_OK; /* no authentication with no user or password */
}
- if(data->state.authhost.want &&
- !data->state.authhost.picked) {
+ if(data->state.authhost.want && !data->state.authhost.picked)
/* The app has selected one or more methods, but none has been picked
so far by a server round-trip. Then we set the picked one to the
want one, and if this is one single bit it'll be used instantly. */
data->state.authhost.picked = data->state.authhost.want;
- }
- if(data->state.authproxy.want &&
- !data->state.authproxy.picked) {
- /* The app has selected one or more methods, but none has been picked
- so far by a server round-trip. Then we set the picked one to the
- want one, and if this is one single bit it'll be used instantly. */
+ if(data->state.authproxy.want && !data->state.authproxy.picked)
+ /* The app has selected one or more methods, but none has been picked so
+ far by a proxy round-trip. Then we set the picked one to the want one,
+ and if this is one single bit it'll be used instantly. */
data->state.authproxy.picked = data->state.authproxy.want;
- }
/* To prevent the user+password to get sent to other than the original
host due to a location-follow, we do some weirdo checks here */
@@ -1313,7 +1307,11 @@ CURLcode Curl_http(struct connectdata *conn)
httpreq = HTTPREQ_HEAD;
request = (char *)"HEAD";
conn->bits.no_body = TRUE;
+ conn->bits.authprobe = TRUE; /* this is a request done to probe for
+ authentication methods */
}
+ else
+ conn->bits.authprobe = FALSE;
Curl_safefree(conn->allocptr.ref);
if(data->change.referer && !checkheaders(data, "Referer:"))
diff --git a/lib/http.h b/lib/http.h
index 2d3b39dca..80c180798 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -2,10 +2,10 @@
#define __HTTP_H
/***************************************************************************
- * _ _ ____ _
- * Project ___| | | | _ \| |
- * / __| | | | |_) | |
- * | (__| |_| | _ <| |___
+ * _ _ ____ _
+ * Project ___| | | | _ \| |
+ * / __| | | | |_) | |
+ * | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2004, Daniel Stenberg, <daniel@haxx.se>, et al.
@@ -13,7 +13,7 @@
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://curl.haxx.se/docs/copyright.html.
- *
+ *
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
@@ -50,5 +50,12 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
CURLcode Curl_http_auth_act(struct connectdata *conn);
int Curl_http_should_fail(struct connectdata *conn);
+
+/* If only the PICKNONE bit is set, there has been a round-trip and we
+ selected to use no auth at all. Ie, we actively select no auth, as opposed
+ to not having one selected. The other CURLAUTH_* defines are present in the
+ public curl/curl.h header. */
+#define CURLAUTH_PICKNONE (1<<30) /* don't use auth */
+
#endif
#endif
diff --git a/lib/urldata.h b/lib/urldata.h
index 550d9580d..74bef224c 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -319,6 +319,9 @@ struct ConnectBits {
This is implicit when SSL-protocols are used through
proxies, but can also be enabled explicitly by
apps */
+ bool authprobe; /* set TRUE when this transfer is done to probe for auth
+ types, as when asking for "any" type when speaking
+ HTTP */
};
struct hostname {