|
|
a2d4e1 |
From 5f543b36b2b05cbe52a9861ad7cb15e0a7c78c80 Mon Sep 17 00:00:00 2001
|
|
|
a2d4e1 |
From: Daniel Stenberg <daniel@haxx.se>
|
|
|
a2d4e1 |
Date: Tue, 21 May 2013 23:28:59 +0200
|
|
|
a2d4e1 |
Subject: [PATCH] Curl_cookie_add: handle IPv6 hosts
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
1 - don't skip host names with a colon in them in an attempt to bail out
|
|
|
a2d4e1 |
on HTTP headers in the cookie file parser. It was only a shortcut anyway
|
|
|
a2d4e1 |
and trying to parse a file with HTTP headers will still be handled, only
|
|
|
a2d4e1 |
slightly slower.
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
2 - don't skip domain names based on number of dots. The original
|
|
|
a2d4e1 |
netscape cookie spec had this oddity mentioned and while our code
|
|
|
a2d4e1 |
decreased the check to only check for two, the existing cookie spec has
|
|
|
a2d4e1 |
no such dot counting required.
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
Bug: http://curl.haxx.se/bug/view.cgi?id=1221
|
|
|
a2d4e1 |
Reported-by: Stefan Neis
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
Upstream-commit: 85b9dc80232d1d7d48ee4dea6db5a2263ee68efd
|
|
|
a2d4e1 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
a2d4e1 |
---
|
|
|
a2d4e1 |
lib/cookie.c | 93 +++++++++++++++++-------------------------------------------
|
|
|
a2d4e1 |
1 file changed, 26 insertions(+), 67 deletions(-)
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
diff --git a/lib/cookie.c b/lib/cookie.c
|
|
|
a2d4e1 |
index 764bbc9..956efd4 100644
|
|
|
a2d4e1 |
--- a/lib/cookie.c
|
|
|
a2d4e1 |
+++ b/lib/cookie.c
|
|
|
a2d4e1 |
@@ -347,6 +347,9 @@ static bool isip(const char *domain)
|
|
|
a2d4e1 |
*
|
|
|
a2d4e1 |
* Add a single cookie line to the cookie keeping object.
|
|
|
a2d4e1 |
*
|
|
|
a2d4e1 |
+ * Be aware that sometimes we get an IP-only host name, and that might also be
|
|
|
a2d4e1 |
+ * a numerical IPv6 address.
|
|
|
a2d4e1 |
+ *
|
|
|
a2d4e1 |
***************************************************************************/
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
struct Cookie *
|
|
|
a2d4e1 |
@@ -458,73 +461,35 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
a2d4e1 |
}
|
|
|
a2d4e1 |
}
|
|
|
a2d4e1 |
else if(Curl_raw_equal("domain", name)) {
|
|
|
a2d4e1 |
- /* note that this name may or may not have a preceding dot, but
|
|
|
a2d4e1 |
- we don't care about that, we treat the names the same anyway */
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- const char *domptr=whatptr;
|
|
|
a2d4e1 |
- const char *nextptr;
|
|
|
a2d4e1 |
- int dotcount=1;
|
|
|
a2d4e1 |
+ bool is_ip;
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
- /* Count the dots, we need to make sure that there are enough
|
|
|
a2d4e1 |
- of them. */
|
|
|
a2d4e1 |
+ /* Now, we make sure that our host is within the given domain,
|
|
|
a2d4e1 |
+ or the given domain is not valid and thus cannot be set. */
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
if('.' == whatptr[0])
|
|
|
a2d4e1 |
- /* don't count the initial dot, assume it */
|
|
|
a2d4e1 |
- domptr++;
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- do {
|
|
|
a2d4e1 |
- nextptr = strchr(domptr, '.');
|
|
|
a2d4e1 |
- if(nextptr) {
|
|
|
a2d4e1 |
- if(domptr != nextptr)
|
|
|
a2d4e1 |
- dotcount++;
|
|
|
a2d4e1 |
- domptr = nextptr+1;
|
|
|
a2d4e1 |
+ whatptr++; /* ignore preceding dot */
|
|
|
a2d4e1 |
+
|
|
|
a2d4e1 |
+ is_ip = isip(domain ? domain : whatptr);
|
|
|
a2d4e1 |
+
|
|
|
a2d4e1 |
+ if(!domain
|
|
|
a2d4e1 |
+ || (is_ip && !strcmp(whatptr, domain))
|
|
|
a2d4e1 |
+ || (!is_ip && tailmatch(whatptr, domain))) {
|
|
|
a2d4e1 |
+ strstore(&co->domain, whatptr);
|
|
|
a2d4e1 |
+ if(!co->domain) {
|
|
|
a2d4e1 |
+ badcookie = TRUE;
|
|
|
a2d4e1 |
+ break;
|
|
|
a2d4e1 |
}
|
|
|
a2d4e1 |
- } while(nextptr);
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- /* The original Netscape cookie spec defined that this domain name
|
|
|
a2d4e1 |
- MUST have three dots (or two if one of the seven holy TLDs),
|
|
|
a2d4e1 |
- but it seems that these kinds of cookies are in use "out there"
|
|
|
a2d4e1 |
- so we cannot be that strict. I've therefore lowered the check
|
|
|
a2d4e1 |
- to not allow less than two dots. */
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- if(dotcount < 2) {
|
|
|
a2d4e1 |
- /* Received and skipped a cookie with a domain using too few
|
|
|
a2d4e1 |
- dots. */
|
|
|
a2d4e1 |
- badcookie=TRUE; /* mark this as a bad cookie */
|
|
|
a2d4e1 |
- infof(data, "skipped cookie with illegal dotcount domain: %s\n",
|
|
|
a2d4e1 |
- whatptr);
|
|
|
a2d4e1 |
+ if(!is_ip)
|
|
|
a2d4e1 |
+ co->tailmatch=TRUE; /* we always do that if the domain name was
|
|
|
a2d4e1 |
+ given */
|
|
|
a2d4e1 |
}
|
|
|
a2d4e1 |
else {
|
|
|
a2d4e1 |
- bool is_ip;
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- /* Now, we make sure that our host is within the given domain,
|
|
|
a2d4e1 |
- or the given domain is not valid and thus cannot be set. */
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- if('.' == whatptr[0])
|
|
|
a2d4e1 |
- whatptr++; /* ignore preceding dot */
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- is_ip = isip(domain ? domain : whatptr);
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
- if(!domain
|
|
|
a2d4e1 |
- || (is_ip && !strcmp(whatptr, domain))
|
|
|
a2d4e1 |
- || (!is_ip && tailmatch(whatptr, domain))) {
|
|
|
a2d4e1 |
- strstore(&co->domain, whatptr);
|
|
|
a2d4e1 |
- if(!co->domain) {
|
|
|
a2d4e1 |
- badcookie = TRUE;
|
|
|
a2d4e1 |
- break;
|
|
|
a2d4e1 |
- }
|
|
|
a2d4e1 |
- if(!is_ip)
|
|
|
a2d4e1 |
- co->tailmatch=TRUE; /* we always do that if the domain name was
|
|
|
a2d4e1 |
- given */
|
|
|
a2d4e1 |
- }
|
|
|
a2d4e1 |
- else {
|
|
|
a2d4e1 |
- /* we did not get a tailmatch and then the attempted set domain
|
|
|
a2d4e1 |
- is not a domain to which the current host belongs. Mark as
|
|
|
a2d4e1 |
- bad. */
|
|
|
a2d4e1 |
- badcookie=TRUE;
|
|
|
a2d4e1 |
- infof(data, "skipped cookie with bad tailmatch domain: %s\n",
|
|
|
a2d4e1 |
- whatptr);
|
|
|
a2d4e1 |
- }
|
|
|
a2d4e1 |
+ /* we did not get a tailmatch and then the attempted set domain
|
|
|
a2d4e1 |
+ is not a domain to which the current host belongs. Mark as
|
|
|
a2d4e1 |
+ bad. */
|
|
|
a2d4e1 |
+ badcookie=TRUE;
|
|
|
a2d4e1 |
+ infof(data, "skipped cookie with bad tailmatch domain: %s\n",
|
|
|
a2d4e1 |
+ whatptr);
|
|
|
a2d4e1 |
}
|
|
|
a2d4e1 |
}
|
|
|
a2d4e1 |
else if(Curl_raw_equal("version", name)) {
|
|
|
a2d4e1 |
@@ -696,12 +661,6 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
firstptr=strtok_r(lineptr, "\t", &tok_buf); /* tokenize it on the TAB */
|
|
|
a2d4e1 |
|
|
|
a2d4e1 |
- /* Here's a quick check to eliminate normal HTTP-headers from this */
|
|
|
a2d4e1 |
- if(!firstptr || strchr(firstptr, ':')) {
|
|
|
a2d4e1 |
- free(co);
|
|
|
a2d4e1 |
- return NULL;
|
|
|
a2d4e1 |
- }
|
|
|
a2d4e1 |
-
|
|
|
a2d4e1 |
/* Now loop through the fields and init the struct we already have
|
|
|
a2d4e1 |
allocated */
|
|
|
a2d4e1 |
for(ptr=firstptr, fields=0; ptr && !badcookie;
|
|
|
a2d4e1 |
--
|
|
|
a2d4e1 |
2.5.5
|
|
|
a2d4e1 |
|