diff --git a/CHANGES b/CHANGES index 15a74c6e0..0f0f7029c 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,22 @@ Changelog +Daniel Stenberg (11 Dec 2008) +- Internet Explorer had a broken HTTP digest authentication before v7 and + there are servers "out there" that relies on the client doing this broken + Digest authentication. Apache even comes with an option to work with such + broken clients. + + The difference is only for URLs that contain a query-part (a '?'-letter and + text to the right of it). + + libcurl now supports this quirk, and you enable it by setting the + CURLAUTH_DIGEST_IE bit in the bitmask you pass to the CURLOPT_HTTPAUTH or + CURLOPT_PROXYAUTH options. They are thus individually controlled to server + and proxy. + + (note that there's no way to activate this with the curl tool yet) + Daniel Fandrich (9 Dec 2008) - Added test cases 1089 and 1090 to test --write-out after a redirect to test a report that the size didn't work, but these test cases pass. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 5c8af40ed..06e3893d5 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -9,7 +9,7 @@ Curl and libcurl 7.19.3 This release includes the following changes: - o + o CURLAUTH_DIGEST_IE bit added for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH This release includes the following bugfixes: diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index 38fe0ff40..5e51aeffc 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -21,7 +21,7 @@ .\" * $Id$ .\" ************************************************************************** .\" -.TH curl_easy_setopt 3 "28 Oct 2008" "libcurl 7.19.1" "libcurl Manual" +.TH curl_easy_setopt 3 "11 Dec 2008" "libcurl 7.19.3" "libcurl Manual" .SH NAME curl_easy_setopt \- set options for a curl easy handle .SH SYNOPSIS @@ -661,6 +661,13 @@ others. HTTP Digest authentication. Digest authentication is defined in RFC2617 and is a more secure way to do authentication over public networks than the regular old-fashioned Basic method. +.IP CURLAUTH_DIGEST_IE +HTTP Digest authentication with an IE flavor. Digest authentication is +defined in RFC2617 and is a more secure way to do authentication over public +networks than the regular old-fashioned Basic method. The IE flavor is simply +that libcurl will use a special "quirk" that IE is known to have used before +version 7 and that some servers require the client to use. (This define was +added in 7.19.3) .IP CURLAUTH_GSSNEGOTIATE HTTP GSS-Negotiate authentication. The GSS-Negotiate (also known as plain \&"Negotiate") method was designed by Microsoft and is used in their web diff --git a/include/curl/curl.h b/include/curl/curl.h index daa925fa8..e94ff5f9d 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -474,8 +474,9 @@ typedef enum { #define CURLAUTH_DIGEST (1<<1) /* Digest */ #define CURLAUTH_GSSNEGOTIATE (1<<2) /* GSS-Negotiate */ #define CURLAUTH_NTLM (1<<3) /* NTLM */ -#define CURLAUTH_ANY ~0 /* all types set */ -#define CURLAUTH_ANYSAFE (~CURLAUTH_BASIC) +#define CURLAUTH_DIGEST_IE (1<<4) /* Digest with IE flavour */ +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) /* all fine types set */ +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) #define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ #define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ diff --git a/lib/http_digest.c b/lib/http_digest.c index be5ca5a8d..bab95e9de 100644 --- a/lib/http_digest.c +++ b/lib/http_digest.c @@ -356,7 +356,25 @@ CURLcode Curl_output_digest(struct connectdata *conn, 5.1.1 of RFC 2616) */ - md5this = (unsigned char *)aprintf("%s:%s", request, uripath); + /* So IE browsers < v7 cut off the URI part at the query part when they + evaluate the MD5 and some (IIS?) servers work with them so we may need to + do the Digest IE-style. Note that the different ways cause different MD5 + sums to get sent. + + Apache servers can be set to do the Digest IE-style automatically using + the BrowserMatch feature: + http://httpd.apache.org/docs/2.2/mod/mod_auth_digest.html#msie + + Further details on Digest implementation differences: + http://www.fngtps.com/2006/09/http-authentication + */ + if(authp->iestyle && (tmp = strchr((char *)uripath, '?'))) { + md5this = (unsigned char *)aprintf("%s:%.*s", request, + (int)(tmp - (char *)uripath), uripath); + } + else + md5this = (unsigned char *)aprintf("%s:%s", request, uripath); + if(!md5this) { free(ha1); return CURLE_OUT_OF_MEMORY; diff --git a/lib/url.c b/lib/url.c index 9037bf920..1cf8b08da 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1319,6 +1319,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ { long auth = va_arg(param, long); + + /* the DIGEST_IE bit is only used to set a special marker, for all the + rest we need to handle it as normal DIGEST */ + data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; + + if(auth & CURLAUTH_DIGEST_IE) { + auth |= CURLAUTH_DIGEST; /* set standard digest bit */ + auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ + } + /* switch off bits we can't support */ #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ @@ -1354,6 +1364,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, */ { long auth = va_arg(param, long); + + /* the DIGEST_IE bit is only used to set a special marker, for all the + rest we need to handle it as normal DIGEST */ + data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE; + + if(auth & CURLAUTH_DIGEST_IE) { + auth |= CURLAUTH_DIGEST; /* set standard digest bit */ + auth &= ~CURLAUTH_DIGEST_IE; /* unset ie digest bit */ + } /* switch off bits we can't support */ #ifndef USE_NTLM auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */ diff --git a/lib/urldata.h b/lib/urldata.h index aafa26eab..07dab3ee1 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -1139,7 +1139,8 @@ struct auth { request */ bool multi; /* TRUE if this is not yet authenticated but within the auth multipass negotiation */ - + bool iestyle; /* TRUE if digest should be done IE-style or FALSE if it should + be RFC compliant */ }; struct conncache {