- Alexey Borzov filed bug report #2535504

(http://curl.haxx.se/bug/view.cgi?id=2535504) pointing out that realms with
  quoted quotation marks in HTTP Digest headers didn't work. I've now added
  test case 1095 that verifies my fix.
This commit is contained in:
Daniel Stenberg 2009-01-26 13:19:03 +00:00
parent f29e383575
commit 82ca52713b
5 changed files with 169 additions and 20 deletions

View File

@ -7,6 +7,11 @@
Changelog
Daniel Stenberg (26 Jan 2009)
- Alexey Borzov filed bug report #2535504
(http://curl.haxx.se/bug/view.cgi?id=2535504) pointing out that realms with
quoted quotation marks in HTTP Digest headers didn't work. I've now added
test case 1095 that verifies my fix.
- Craig A West brought CURLOPT_NOPROXY and the corresponding --noproxy option.
They basically offer the same thing the NO_PROXY environment variable only
offered previously: list a set of host names that shall not use the proxy

View File

@ -15,6 +15,7 @@ This release includes the following bugfixes:
o missing ssh.obj in VS makefiles
o FTP ;type=i URLs now work with CURLOPT_PROXY_TRANSFER_MODE in Turkish locale
o realms with quoted quotation marks in HTTP Digest headers
This release includes the following known bugs:
@ -23,6 +24,6 @@ This release includes the following known bugs:
This release would not have looked like this without help, code, reports and
advice from friends like these:
Lisa Xu, Daniel Fandrich, Craig A West
Lisa Xu, Daniel Fandrich, Craig A West, Alexey Borzov
Thanks! (and sorry if I forgot to mention someone)

View File

@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
@ -47,6 +47,77 @@
/* The last #include file should be: */
#include "memdebug.h"
#define MAX_VALUE_LENGTH 256
#define MAX_CONTENT_LENGTH 1024
/*
* Return 0 on success and then the buffers are filled in fine.
*
* Non-zero means failure to parse.
*/
static int get_pair(const char *str, char *value, char *content,
const char **endptr)
{
int c;
bool starts_with_quote = FALSE;
bool escape = FALSE;
for(c=MAX_VALUE_LENGTH-1; (*str && (*str != '=') && c--); )
*value++ = *str++;
*value=0;
if('=' != *str++)
/* eek, no match */
return 1;
if('\"' == *str) {
/* this starts with a quote so it must end with one as well! */
str++;
starts_with_quote = TRUE;
}
for(c=MAX_CONTENT_LENGTH-1; *str && c--; str++) {
switch(*str) {
case '\\':
if(!escape) {
/* possibly the start of an escaped quote */
escape = TRUE;
*content++ = '\\'; /* even though this is an escape character, we still
store it as-is in the target buffer */
continue;
}
break;
case ',':
if(!starts_with_quote) {
/* this signals the end of the content if we didn't get a starting quote
and then we do "sloppy" parsing */
c=0; /* the end */
continue;
}
break;
case '\r':
case '\n':
/* end of string */
c=0;
continue;
case '\"':
if(!escape && starts_with_quote) {
/* end of string */
c=0;
continue;
}
break;
}
escape = FALSE;
*content++ = *str;
}
*content=0;
*endptr = str;
return 0; /* all is fine! */
}
/* Test example headers:
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
@ -90,26 +161,16 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
Curl_digest_cleanup_one(d);
while(more) {
char value[256];
char content[1024];
char value[MAX_VALUE_LENGTH];
char content[MAX_CONTENT_LENGTH];
size_t totlen=0;
while(*header && ISSPACE(*header))
header++;
/* how big can these strings be? */
if((2 == sscanf(header, "%255[^=]=\"%1023[^\"]\"",
value, content)) ||
/* try the same scan but without quotes around the content but don't
include the possibly trailing comma, newline or carriage return */
(2 == sscanf(header, "%255[^=]=%1023[^\r\n,]",
value, content)) ) {
if(!strcmp("\"\"", content)) {
/* for the name="" case where we get only the "" in the content
* variable, simply clear the content then
*/
content[0]=0;
}
/* extract a value=content pair */
if(!get_pair(header, value, content, &header)) {
if(Curl_raw_equal(value, "nonce")) {
d->nonce = strdup(content);
if(!d->nonce)
@ -185,7 +246,6 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
else
break; /* we're done here */
header += totlen;
/* pass all additional spaces here */
while(*header && ISSPACE(*header))
header++;
@ -247,7 +307,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
#ifdef CURL_DOES_CONVERSIONS
CURLcode rc;
/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
It converts digest text to ASCII so the MD5 will be correct for
It converts digest text to ASCII so the MD5 will be correct for
what ultimately goes over the network.
*/
#define CURL_OUTPUT_DIGEST_CONV(a, b) \

View File

@ -60,7 +60,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 \
test1080 test1081 test1082 test1083 test1084 test1085 test633 test634 \
test635 test636 test637 test558 test559 test1086 test1087 test1088 \
test1089 test1090 test1091 test1092 test1093 test1094
test1089 test1090 test1091 test1092 test1093 test1094 test1095
filecheck:
@mkdir test-place; \

83
tests/data/test1095 Normal file
View File

@ -0,0 +1,83 @@
<testcase>
<info>
<keywords>
HTTP
HTTP GET
HTTP Digest auth
</keywords>
</info>
# Server-side
<reply>
<data>
HTTP/1.1 401 Authorization Required swsclose
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
WWW-Authenticate: Digest realm="test \"this\" realm!!", nonce="1053604145"
Content-Type: text/html; charset=iso-8859-1
Content-Length: 26
This is not the real page
</data>
# This is supposed to be returned when the server gets a
# Authorization: Digest line passed-in from the client
<data1000>
HTTP/1.1 200 OK swsclose
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
Content-Type: text/html; charset=iso-8859-1
Content-Length: 23
This IS the real page!
</data1000>
<datacheck>
HTTP/1.1 401 Authorization Required swsclose
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
WWW-Authenticate: Digest realm="test \"this\" realm!!", nonce="1053604145"
Content-Type: text/html; charset=iso-8859-1
Content-Length: 26
HTTP/1.1 200 OK swsclose
Server: Apache/1.3.27 (Darwin) PHP/4.1.2
Content-Type: text/html; charset=iso-8859-1
Content-Length: 23
This IS the real page!
</datacheck>
</reply>
# Client-side
<client>
<server>
http
</server>
<features>
crypto
</features>
<name>
HTTP with Digest and realm with quoted quotes
</name>
<command>
http://%HOSTIP:%HTTPPORT/1095 -u testuser:testpass --digest
</command>
</client>
# Verify data after the test has been "shot"
<verify>
<strip>
^User-Agent:.*
</strip>
<protocol>
GET /1095 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
Accept: */*
GET /1095 HTTP/1.1
Authorization: Digest username="testuser", realm="test \"this\" realm!!", nonce="1053604145", uri="/1095", response="a1c7931ece9e8617bae2715045e4f49f"
User-Agent: curl/7.10.5 (i686-pc-linux-gnu) libcurl/7.10.5 OpenSSL/0.9.7a ipv6 zlib/1.1.3
Host: %HOSTIP:%HTTPPORT
Accept: */*
</protocol>
</verify>
</testcase>