From f765337085bac0986c9f20dca96d484d55759f45 Mon Sep 17 00:00:00 2001 From: kush789 Date: Fri, 29 Jan 2016 13:42:06 +0530 Subject: [PATCH] Added recommendations from draft-West --- src/cookies.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- src/cookies.h | 5 ++++- src/http.c | 2 +- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/cookies.c b/src/cookies.c index 81ecfa5..b2bfb54 100644 --- a/src/cookies.c +++ b/src/cookies.c @@ -122,6 +122,13 @@ struct cookie { same domain. */ }; +static int +find_chains_of_host (struct cookie_jar *jar, const char *host, + struct cookie *dest[]); + +static int +count_char (const char *string, char chr); + #define PORT_ANY (-1) /* Allocate and return a new, empty cookie structure. */ @@ -350,7 +357,8 @@ discard_matching_cookie (struct cookie_jar *jar, struct cookie *cookie) filled. */ static struct cookie * -parse_set_cookie (const char *set_cookie, bool silent) +parse_set_cookie (const char *set_cookie, enum url_scheme scheme, + bool silent) { const char *ptr = set_cookie; struct cookie *cookie = cookie_new (); @@ -439,8 +447,21 @@ parse_set_cookie (const char *set_cookie, bool silent) } else if (TOKEN_IS (name, "secure")) { - /* ignore value completely */ - cookie->secure = 1; + if (scheme == SCHEME_HTTP) + { + /* Deleting cookie since secure only flag is set but connection + is not secure. */ + if (!silent) + logprintf (LOG_NOTQUIET, + _("Trying to create secure only cookie, but connection is not secure.\nSet-Cookie : %s\n"), + quotearg_style (escape_quoting_style, set_cookie)); + delete_cookie (cookie); + return NULL; + } + else + /* Ignore value completely since secure is a value-less + attribute*/ + cookie->secure = 1; } /* else: Ignore unrecognized attribute. */ } @@ -461,6 +482,7 @@ parse_set_cookie (const char *set_cookie, bool silent) return NULL; } + #undef TOKEN_IS #undef TOKEN_NON_EMPTY @@ -707,9 +729,12 @@ check_path_match (const char *cookie_path, const char *path) void cookie_handle_set_cookie (struct cookie_jar *jar, const char *host, int port, - const char *path, const char *set_cookie) + const char *path, enum url_scheme scheme, + const char *set_cookie) { - struct cookie *cookie; + struct cookie *cookie, *old_cookie; + struct cookie **chains; + int chain_count, i; cookies_now = time (NULL); /* Wget's paths don't begin with '/' (blame rfc1808), but cookie @@ -717,7 +742,7 @@ cookie_handle_set_cookie (struct cookie_jar *jar, simply prepend slash to PATH. */ PREPEND_SLASH (path); - cookie = parse_set_cookie (set_cookie, false); + cookie = parse_set_cookie (set_cookie, scheme, false); if (!cookie) goto out; @@ -767,6 +792,29 @@ cookie_handle_set_cookie (struct cookie_jar *jar, } } + if ((cookie->secure == 0) && (scheme == SCHEME_HTTP)) + { + /* If an old cookie exists such that the all of the following are + true, then discard the new cookie. + + - The "domain" domain-matches the domain of the new cookie + - The "name" matches the "name" of the new cookie + - Secure-only flag of old cookie is set */ + + chains = alloca_array (struct cookie *, 1 + count_char (host, '.')); + chain_count = find_chains_of_host (jar, host, chains); + + for (i = 0; i < chain_count; i++) + for (old_cookie = chains[i]; old_cookie; old_cookie = old_cookie->next) + { + if (!cookie_expired_p(old_cookie) + && !(old_cookie->domain_exact + && 0 != strcasecmp (host, old_cookie->domain)) + && 0 == strcasecmp(old_cookie->attr, cookie->attr) + && 1 == old_cookie->secure) + goto out; + } + } /* Now store the cookie, or discard an existing cookie, if discarding was requested. */ @@ -795,9 +843,12 @@ count_char (const char *string, char chr) { const char *p; int count = 0; - for (p = string; *p; p++) - if (*p == chr) - ++count; + p = string; + while ((p = strchr(p, chr)) != NULL) + { + ++count; + p++; + } return count; } diff --git a/src/cookies.h b/src/cookies.h index b4281e1..d565b09 100644 --- a/src/cookies.h +++ b/src/cookies.h @@ -31,13 +31,16 @@ as that of the covered work. */ #ifndef COOKIES_H #define COOKIES_H +#include "url.h" + struct cookie_jar; struct cookie_jar *cookie_jar_new (void); void cookie_jar_delete (struct cookie_jar *); void cookie_handle_set_cookie (struct cookie_jar *, const char *, int, - const char *, const char *); + const char *, enum url_scheme, + const char *); char *cookie_header (struct cookie_jar *, const char *, int, const char *, bool); diff --git a/src/http.c b/src/http.c index 8916d2b..f7d42b2 100644 --- a/src/http.c +++ b/src/http.c @@ -3276,7 +3276,7 @@ gethttp (struct url *u, struct http_stat *hs, int *dt, struct url *proxy, { char *set_cookie; BOUNDED_TO_ALLOCA (scbeg, scend, set_cookie); cookie_handle_set_cookie (wget_cookie_jar, u->host, u->port, - u->path, set_cookie); + u->path, u->scheme, set_cookie); } } -- 1.9.1