diff --git a/lib/http.c b/lib/http.c index a7ad947e1..44ef29e8f 100644 --- a/lib/http.c +++ b/lib/http.c @@ -670,7 +670,9 @@ CURLcode Curl_http(struct connectdata *conn) if(result) return result; } - else if((conn->bits.user_passwd) && !checkheaders(data, "Authorization:")) { + else if(!data->set.httpdigest && /* not if Digest is enabled */ + conn->bits.user_passwd && + !checkheaders(data, "Authorization:")) { char *authorization; /* To prevent the user+password to get sent to other than the original diff --git a/lib/http_digest.c b/lib/http_digest.c index 2aeb3b8e9..7f62c26b4 100644 --- a/lib/http_digest.c +++ b/lib/http_digest.c @@ -65,7 +65,8 @@ CURLdigest Curl_input_digest(struct connectdata *conn, if(checkprefix("Digest", header)) { header += strlen("Digest"); - data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */ + /* clear off any former leftovers and init to defaults */ + Curl_digest_cleanup(data); while(more) { char value[32]; @@ -207,4 +208,21 @@ CURLcode Curl_output_digest(struct connectdata *conn, return CURLE_OK; } +void Curl_digest_cleanup(struct SessionHandle *data) +{ + if(data->state.digest.nonce) + free(data->state.digest.nonce); + data->state.digest.nonce = NULL; + + if(data->state.digest.cnonce) + free(data->state.digest.cnonce); + data->state.digest.cnonce = NULL; + + if(data->state.digest.realm) + free(data->state.digest.realm); + data->state.digest.realm = NULL; + + data->state.digest.algo = CURLDIGESTALGO_MD5; /* default algorithm */ +} + #endif diff --git a/lib/http_digest.h b/lib/http_digest.h index 622567361..1e7feac21 100644 --- a/lib/http_digest.h +++ b/lib/http_digest.h @@ -43,4 +43,6 @@ CURLdigest Curl_input_digest(struct connectdata *conn, char *header); CURLcode Curl_output_digest(struct connectdata *conn, unsigned char *request, unsigned char *uripath); +void Curl_digest_cleanup(struct SessionHandle *data); + #endif diff --git a/lib/transfer.c b/lib/transfer.c index c8c127348..9bc9f1020 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -704,15 +704,20 @@ CURLcode Curl_readwrite(struct connectdata *conn, } else if(checkprefix("WWW-Authenticate:", k->p) && (401 == k->httpcode) && - 1 /* TODO: replace with a check for Digest authentication - activated */) { - CURLdigest dig = Curl_input_digest(conn, k->p+ - strlen("WWW-Authenticate:")); - if(CURLDIGEST_FINE == dig) { + data->set.httpdigest /* Digest authentication is + activated */) { + CURLdigest dig = CURLDIGEST_BAD; + + if(data->state.digest.nonce) + infof(data, "Authentication problem. Ignoring this."); + else + dig = Curl_input_digest(conn, + k->p+strlen("WWW-Authenticate:")); + + 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 if ((k->httpcode >= 300 && k->httpcode < 400) && checkprefix("Location:", k->p)) { @@ -797,7 +802,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* HTTP-only checks */ if (conn->newurl) { /* abort after the headers if "follow Location" is set */ - infof (data, "Follow to new URL: %s\n", conn->newurl); + infof (data, "Send request to this URL: %s\n", conn->newurl); k->keepon &= ~KEEP_READ; FD_ZERO(&k->rkeepfd); *done = TRUE; @@ -1568,7 +1573,7 @@ CURLcode Curl_follow(struct SessionHandle *data, data->change.url = newurl; newurl = NULL; /* don't free! */ - infof(data, "Follows Location: to new URL: '%s'\n", data->change.url); + infof(data, "Issue another request to this URL: '%s'\n", data->change.url); /* * We get here when the HTTP code is 300-399. We need to perform diff --git a/lib/urldata.h b/lib/urldata.h index 31a755355..58f700677 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -671,6 +671,7 @@ struct UserDefined { char *set_proxy; /* proxy to use */ long use_port; /* which port to use (when not using default) */ char *userpwd; /* , if used */ + bool httpdigest; /* if HTTP Digest is enabled */ char *set_range; /* range, if used. See README for detailed specification on this syntax. */ long followlocation; /* as in HTTP Location: */