aboutsummaryrefslogtreecommitdiff
path: root/lib/http.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2011-10-20 13:05:09 +0200
committerDaniel Stenberg <daniel@haxx.se>2011-10-20 13:12:02 +0200
commitff0a295cdbc9cf95db0c364ede5cca4063ba2882 (patch)
treef1887cc9921025df91396d7a77ece112177c0622 /lib/http.c
parent4fa01661739eaa2fd91f618df660662ef3f886f8 (diff)
Curl_http_input_auth: handle multiple auths in WWW-Authenticate
The fix is pretty much the one Nick Zitzmann provided, just edited to do the right indent levels and with test case 1204 added to verify the fix. Bug: http://curl.haxx.se/mail/lib-2011-10/0190.html Reported by: Nick Zitzmann
Diffstat (limited to 'lib/http.c')
-rw-r--r--lib/http.c186
1 files changed, 98 insertions, 88 deletions
diff --git a/lib/http.c b/lib/http.c
index 5b30f8aa0..e41cb7af3 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -731,95 +731,73 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
*
*/
+ while(*start) {
#ifdef USE_HTTP_NEGOTIATE
- if(checkprefix("GSS-Negotiate", start) ||
- checkprefix("Negotiate", start)) {
- int neg;
- *availp |= CURLAUTH_GSSNEGOTIATE;
- authp->avail |= CURLAUTH_GSSNEGOTIATE;
-
- if(data->state.negotiate.state == GSS_AUTHSENT) {
- /* if we sent GSS authentication in the outgoing request and we get this
- back, we're in trouble */
- infof(data, "Authentication problem. Ignoring this.\n");
- data->state.authproblem = TRUE;
- }
- else {
- neg = Curl_input_negotiate(conn, (httpcode == 407)?TRUE:FALSE, start);
- if(neg == 0) {
- DEBUGASSERT(!data->req.newurl);
- data->req.newurl = strdup(data->change.url);
- if(!data->req.newurl)
- return CURLE_OUT_OF_MEMORY;
- data->state.authproblem = FALSE;
- /* we received GSS auth info and we dealt with it fine */
- data->state.negotiate.state = GSS_AUTHRECV;
- }
- else {
+ if(checkprefix("GSS-Negotiate", start) ||
+ checkprefix("Negotiate", start)) {
+ int neg;
+ *availp |= CURLAUTH_GSSNEGOTIATE;
+ authp->avail |= CURLAUTH_GSSNEGOTIATE;
+
+ if(data->state.negotiate.state == GSS_AUTHSENT) {
+ /* if we sent GSS authentication in the outgoing request and we get
+ this back, we're in trouble */
+ infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
- }
- }
- else
-#endif
-#ifdef USE_NTLM
- /* NTLM support requires the SSL crypto libs */
- if(checkprefix("NTLM", start)) {
- *availp |= CURLAUTH_NTLM;
- authp->avail |= CURLAUTH_NTLM;
- if(authp->picked == CURLAUTH_NTLM ||
- authp->picked == CURLAUTH_NTLM_WB) {
- /* NTLM authentication is picked and activated */
- CURLcode ntlm =
- Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
- if(CURLE_OK == ntlm) {
+ else {
+ neg = Curl_input_negotiate(conn, (httpcode == 407)?TRUE:FALSE, start);
+ if(neg == 0) {
+ DEBUGASSERT(!data->req.newurl);
+ data->req.newurl = strdup(data->change.url);
+ if(!data->req.newurl)
+ return CURLE_OUT_OF_MEMORY;
data->state.authproblem = FALSE;
-#ifdef NTLM_WB_ENABLED
- if(authp->picked == CURLAUTH_NTLM_WB) {
- *availp &= ~CURLAUTH_NTLM;
- authp->avail &= ~CURLAUTH_NTLM;
- *availp |= CURLAUTH_NTLM_WB;
- authp->avail |= CURLAUTH_NTLM_WB;
-
- /* Get the challenge-message which will be passed to
- * ntlm_auth for generating the type 3 message later */
- while(*start && ISSPACE(*start))
- start++;
- if(checkprefix("NTLM", start)) {
- start += strlen("NTLM");
- while(*start && ISSPACE(*start))
- start++;
- if(*start)
- if((conn->challenge_header = strdup(start)) == NULL)
- return CURLE_OUT_OF_MEMORY;
- }
- }
-#endif
+ /* we received GSS auth info and we dealt with it fine */
+ data->state.negotiate.state = GSS_AUTHRECV;
}
else {
- infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
}
}
else
#endif
-#ifndef CURL_DISABLE_CRYPTO_AUTH
- if(checkprefix("Digest", start)) {
- if((authp->avail & CURLAUTH_DIGEST) != 0) {
- infof(data, "Ignoring duplicate digest auth header.\n");
- }
- else {
- CURLdigest dig;
- *availp |= CURLAUTH_DIGEST;
- authp->avail |= CURLAUTH_DIGEST;
-
- /* We call this function on input Digest headers even if Digest
- * authentication isn't activated yet, as we need to store the
- * incoming data from this header in case we are gonna use Digest. */
- dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
-
- if(CURLDIGEST_FINE != dig) {
+#ifdef USE_NTLM
+ /* NTLM support requires the SSL crypto libs */
+ if(checkprefix("NTLM", start)) {
+ *availp |= CURLAUTH_NTLM;
+ authp->avail |= CURLAUTH_NTLM;
+ if(authp->picked == CURLAUTH_NTLM ||
+ authp->picked == CURLAUTH_NTLM_WB) {
+ /* NTLM authentication is picked and activated */
+ CURLcode ntlm =
+ Curl_input_ntlm(conn, (httpcode == 407)?TRUE:FALSE, start);
+ if(CURLE_OK == ntlm) {
+ data->state.authproblem = FALSE;
+#ifdef NTLM_WB_ENABLED
+ if(authp->picked == CURLAUTH_NTLM_WB) {
+ *availp &= ~CURLAUTH_NTLM;
+ authp->avail &= ~CURLAUTH_NTLM;
+ *availp |= CURLAUTH_NTLM_WB;
+ authp->avail |= CURLAUTH_NTLM_WB;
+
+ /* Get the challenge-message which will be passed to
+ * ntlm_auth for generating the type 3 message later */
+ while(*start && ISSPACE(*start))
+ start++;
+ if(checkprefix("NTLM", start)) {
+ start += strlen("NTLM");
+ while(*start && ISSPACE(*start))
+ start++;
+ if(*start)
+ if((conn->challenge_header = strdup(start)) == NULL)
+ return CURLE_OUT_OF_MEMORY;
+ }
+ }
+#endif
+ }
+ else {
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
@@ -827,19 +805,51 @@ CURLcode Curl_http_input_auth(struct connectdata *conn,
}
else
#endif
- if(checkprefix("Basic", start)) {
- *availp |= CURLAUTH_BASIC;
- authp->avail |= CURLAUTH_BASIC;
- if(authp->picked == CURLAUTH_BASIC) {
- /* We asked for Basic authentication but got a 40X back
- anyway, which basically means our name+password isn't
- valid. */
- authp->avail = CURLAUTH_NONE;
- infof(data, "Authentication problem. Ignoring this.\n");
- data->state.authproblem = TRUE;
+#ifndef CURL_DISABLE_CRYPTO_AUTH
+ if(checkprefix("Digest", start)) {
+ if((authp->avail & CURLAUTH_DIGEST) != 0) {
+ infof(data, "Ignoring duplicate digest auth header.\n");
+ }
+ else {
+ CURLdigest dig;
+ *availp |= CURLAUTH_DIGEST;
+ authp->avail |= CURLAUTH_DIGEST;
+
+ /* We call this function on input Digest headers even if Digest
+ * authentication isn't activated yet, as we need to store the
+ * incoming data from this header in case we are gonna use
+ * Digest. */
+ dig = Curl_input_digest(conn, (httpcode == 407)?TRUE:FALSE, start);
+
+ if(CURLDIGEST_FINE != dig) {
+ infof(data, "Authentication problem. Ignoring this.\n");
+ data->state.authproblem = TRUE;
+ }
+ }
}
- }
+ else
+#endif
+ if(checkprefix("Basic", start)) {
+ *availp |= CURLAUTH_BASIC;
+ authp->avail |= CURLAUTH_BASIC;
+ if(authp->picked == CURLAUTH_BASIC) {
+ /* We asked for Basic authentication but got a 40X back
+ anyway, which basically means our name+password isn't
+ valid. */
+ authp->avail = CURLAUTH_NONE;
+ infof(data, "Authentication problem. Ignoring this.\n");
+ data->state.authproblem = TRUE;
+ }
+ }
+ /* there may be multiple methods on one line, so keep reading */
+ while(*start && *start != ',') /* read up to the next comma */
+ start++;
+ if(*start == ',') /* if we're on a comma, skip it */
+ start++;
+ while(*start && ISSPACE(*start))
+ start++;
+ }
return CURLE_OK;
}