mirror of
https://github.com/moparisthebest/curl
synced 2024-08-13 17:03:50 -04:00
- 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:
parent
f29e383575
commit
82ca52713b
5
CHANGES
5
CHANGES
@ -7,6 +7,11 @@
|
|||||||
Changelog
|
Changelog
|
||||||
|
|
||||||
Daniel Stenberg (26 Jan 2009)
|
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.
|
- Craig A West brought CURLOPT_NOPROXY and the corresponding --noproxy option.
|
||||||
They basically offer the same thing the NO_PROXY environment variable only
|
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
|
offered previously: list a set of host names that shall not use the proxy
|
||||||
|
@ -15,6 +15,7 @@ This release includes the following bugfixes:
|
|||||||
|
|
||||||
o missing ssh.obj in VS makefiles
|
o missing ssh.obj in VS makefiles
|
||||||
o FTP ;type=i URLs now work with CURLOPT_PROXY_TRANSFER_MODE in Turkish locale
|
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:
|
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
|
This release would not have looked like this without help, code, reports and
|
||||||
advice from friends like these:
|
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)
|
Thanks! (and sorry if I forgot to mention someone)
|
||||||
|
@ -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
|
* This software is licensed as described in the file COPYING, which
|
||||||
* you should have received as part of this distribution. The terms
|
* you should have received as part of this distribution. The terms
|
||||||
@ -47,6 +47,77 @@
|
|||||||
/* The last #include file should be: */
|
/* The last #include file should be: */
|
||||||
#include "memdebug.h"
|
#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:
|
/* Test example headers:
|
||||||
|
|
||||||
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
WWW-Authenticate: Digest realm="testrealm", nonce="1053604598"
|
||||||
@ -90,26 +161,16 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
Curl_digest_cleanup_one(d);
|
Curl_digest_cleanup_one(d);
|
||||||
|
|
||||||
while(more) {
|
while(more) {
|
||||||
char value[256];
|
char value[MAX_VALUE_LENGTH];
|
||||||
char content[1024];
|
char content[MAX_CONTENT_LENGTH];
|
||||||
size_t totlen=0;
|
size_t totlen=0;
|
||||||
|
|
||||||
while(*header && ISSPACE(*header))
|
while(*header && ISSPACE(*header))
|
||||||
header++;
|
header++;
|
||||||
|
|
||||||
/* how big can these strings be? */
|
/* extract a value=content pair */
|
||||||
if((2 == sscanf(header, "%255[^=]=\"%1023[^\"]\"",
|
if(!get_pair(header, value, content, &header)) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
if(Curl_raw_equal(value, "nonce")) {
|
if(Curl_raw_equal(value, "nonce")) {
|
||||||
d->nonce = strdup(content);
|
d->nonce = strdup(content);
|
||||||
if(!d->nonce)
|
if(!d->nonce)
|
||||||
@ -185,7 +246,6 @@ CURLdigest Curl_input_digest(struct connectdata *conn,
|
|||||||
else
|
else
|
||||||
break; /* we're done here */
|
break; /* we're done here */
|
||||||
|
|
||||||
header += totlen;
|
|
||||||
/* pass all additional spaces here */
|
/* pass all additional spaces here */
|
||||||
while(*header && ISSPACE(*header))
|
while(*header && ISSPACE(*header))
|
||||||
header++;
|
header++;
|
||||||
@ -247,7 +307,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
|||||||
#ifdef CURL_DOES_CONVERSIONS
|
#ifdef CURL_DOES_CONVERSIONS
|
||||||
CURLcode rc;
|
CURLcode rc;
|
||||||
/* The CURL_OUTPUT_DIGEST_CONV macro below is for non-ASCII machines.
|
/* 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.
|
what ultimately goes over the network.
|
||||||
*/
|
*/
|
||||||
#define CURL_OUTPUT_DIGEST_CONV(a, b) \
|
#define CURL_OUTPUT_DIGEST_CONV(a, b) \
|
||||||
|
@ -60,7 +60,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
|||||||
test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 \
|
test1072 test1073 test1074 test1075 test1076 test1077 test1078 test1079 \
|
||||||
test1080 test1081 test1082 test1083 test1084 test1085 test633 test634 \
|
test1080 test1081 test1082 test1083 test1084 test1085 test633 test634 \
|
||||||
test635 test636 test637 test558 test559 test1086 test1087 test1088 \
|
test635 test636 test637 test558 test559 test1086 test1087 test1088 \
|
||||||
test1089 test1090 test1091 test1092 test1093 test1094
|
test1089 test1090 test1091 test1092 test1093 test1094 test1095
|
||||||
|
|
||||||
filecheck:
|
filecheck:
|
||||||
@mkdir test-place; \
|
@mkdir test-place; \
|
||||||
|
83
tests/data/test1095
Normal file
83
tests/data/test1095
Normal 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>
|
Loading…
Reference in New Issue
Block a user