mirror of
https://github.com/curl/curl.git
synced 2024-12-03 06:20:31 +08:00
digest: unquote realm and nonce before processing
RFC 7616 (and 2617) requires values to be "unquoted" before used for digest calculations. The only place where unquoting can be done correctly is header parsing function (realm="DOMAIN\\host" and realm=DOMAN\\host are different realms). This commit adds unquoting (de-escaping) of all values during header parsing and quoting of the values during header forming. This approach should be most straightforward and easy to read/maintain as all values are processed in the same way as required by RFC. Closes #8912
This commit is contained in:
parent
f810047f9d
commit
3a6fe0c767
@ -81,12 +81,12 @@ bool Curl_auth_digest_get_pair(const char *str, char *value, char *content,
|
||||
for(c = DIGEST_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;
|
||||
if(starts_with_quote) {
|
||||
if(!escape) {
|
||||
/* the start of an escaped quote */
|
||||
escape = TRUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -664,6 +664,8 @@ static CURLcode auth_create_digest_http_message(
|
||||
char *cnonce = NULL;
|
||||
size_t cnonce_sz = 0;
|
||||
char *userp_quoted;
|
||||
char *realm_quoted;
|
||||
char *nonce_quoted;
|
||||
char *response = NULL;
|
||||
char *hashthis = NULL;
|
||||
char *tmp = NULL;
|
||||
@ -786,16 +788,27 @@ static CURLcode auth_create_digest_http_message(
|
||||
nonce="1053604145", uri="/64", response="c55f7f30d83d774a3d2dcacf725abaca"
|
||||
|
||||
Digest parameters are all quoted strings. Username which is provided by
|
||||
the user will need double quotes and backslashes within it escaped. For
|
||||
the other fields, this shouldn't be an issue. realm, nonce, and opaque
|
||||
are copied as is from the server, escapes and all. cnonce is generated
|
||||
with web-safe characters. uri is already percent encoded. nc is 8 hex
|
||||
the user will need double quotes and backslashes within it escaped.
|
||||
realm, nonce, and opaque will need backslashes as well as they were
|
||||
de-escaped when copied from request header. cnonce is generated with
|
||||
web-safe characters. uri is already percent encoded. nc is 8 hex
|
||||
characters. algorithm and qop with standard values only contain web-safe
|
||||
characters.
|
||||
*/
|
||||
userp_quoted = auth_digest_string_quoted(digest->userhash ? userh : userp);
|
||||
if(!userp_quoted)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
realm_quoted = auth_digest_string_quoted(digest->realm);
|
||||
if(!realm_quoted) {
|
||||
free(userp_quoted);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
nonce_quoted = auth_digest_string_quoted(digest->nonce);
|
||||
if(!nonce_quoted) {
|
||||
free(realm_quoted);
|
||||
free(userp_quoted);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if(digest->qop) {
|
||||
response = aprintf("username=\"%s\", "
|
||||
@ -807,8 +820,8 @@ static CURLcode auth_create_digest_http_message(
|
||||
"qop=%s, "
|
||||
"response=\"%s\"",
|
||||
userp_quoted,
|
||||
digest->realm,
|
||||
digest->nonce,
|
||||
realm_quoted,
|
||||
nonce_quoted,
|
||||
uripath,
|
||||
digest->cnonce,
|
||||
digest->nc,
|
||||
@ -827,18 +840,26 @@ static CURLcode auth_create_digest_http_message(
|
||||
"uri=\"%s\", "
|
||||
"response=\"%s\"",
|
||||
userp_quoted,
|
||||
digest->realm,
|
||||
digest->nonce,
|
||||
realm_quoted,
|
||||
nonce_quoted,
|
||||
uripath,
|
||||
request_digest);
|
||||
}
|
||||
free(nonce_quoted);
|
||||
free(realm_quoted);
|
||||
free(userp_quoted);
|
||||
if(!response)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
/* Add the optional fields */
|
||||
if(digest->opaque) {
|
||||
char *opaque_quoted;
|
||||
/* Append the opaque */
|
||||
opaque_quoted = auth_digest_string_quoted(digest->opaque);
|
||||
if(!opaque_quoted) {
|
||||
free(response);
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
tmp = aprintf("%s, opaque=\"%s\"", response, digest->opaque);
|
||||
free(response);
|
||||
if(!tmp)
|
||||
|
@ -73,7 +73,7 @@ Accept: */*
|
||||
|
||||
GET /%TESTNUMBER HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
Authorization: Digest username="testuser", realm="test \"this\" realm!!", nonce="1053604145", uri="/%TESTNUMBER", response="a1c7931ece9e8617bae2715045e4f49f"
|
||||
Authorization: Digest username="testuser", realm="test \"this\" realm!!", nonce="1053604145", uri="/%TESTNUMBER", response="df3246f44d2bc8de0e9f8fc4d7cf6e95"
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user