X-Git-Url: http://sjero.net/git/?p=wget;a=blobdiff_plain;f=src%2Fcookies.c;h=a46aeeef293a4e03026da21d1c2d09b2d6d2050d;hp=d3b64a9f031db79defb948bd39b4ce176e45ea54;hb=4d77b190fda05fb796185654203dc17bab8a5c2e;hpb=c2c71c32cf7e75336bb45fc299658910e0f9f8af
diff --git a/src/cookies.c b/src/cookies.c
index d3b64a9f..a46aeeef 100644
--- a/src/cookies.c
+++ b/src/cookies.c
@@ -1,6 +1,6 @@
/* Support for cookies.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free
- Software Foundation, Inc.
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010, 2011 Free Software Foundation, Inc.
This file is part of GNU Wget.
@@ -17,15 +17,16 @@ General Public License for more details.
You should have received a copy of the GNU General Public License
along with Wget. If not, see .
-In addition, as a special exception, the Free Software Foundation
-gives permission to link the code of its release of Wget with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version. */
+Additional permission under GNU GPL version 3 section 7
+
+If you modify this program, or any covered work, by linking or
+combining it with the OpenSSL project's OpenSSL library (or a
+modified version of that library), containing parts covered by the
+terms of the OpenSSL or SSLeay licenses, the Free Software Foundation
+grants you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts of OpenSSL used as well
+as that of the covered work. */
/* Written by Hrvoje Niksic. Parts are loosely inspired by the
cookie patch submitted by Tomasz Wegrzanowski.
@@ -42,7 +43,7 @@ so, delete this exception statement from your version. */
sites that do send Set-Cookie2 also emit Set-Cookie for
compatibility. */
-#include
+#include "wget.h"
#include
#include
@@ -50,8 +51,9 @@ so, delete this exception statement from your version. */
#include
#include
#include
-
-#include "wget.h"
+#ifdef HAVE_LIBPSL
+# include
+#endif
#include "utils.h"
#include "hash.h"
#include "cookies.h"
@@ -96,7 +98,7 @@ struct cookie {
int port; /* port number */
char *path; /* path prefix of the cookie */
- unsigned discard_requested :1; /* whether cookie was created to
+ unsigned discard_requested :1;/* whether cookie was created to
request discarding another
cookie. */
@@ -347,14 +349,21 @@ parse_set_cookie (const char *set_cookie, bool silent)
struct cookie *cookie = cookie_new ();
param_token name, value;
- if (!extract_param (&ptr, &name, &value, ';'))
+ if (!extract_param (&ptr, &name, &value, ';', NULL))
goto error;
if (!value.b)
goto error;
+
+ /* If the value is quoted, do not modify it. */
+ if (*(value.b - 1) == '"')
+ value.b--;
+ if (*value.e == '"')
+ value.e++;
+
cookie->attr = strdupdelim (name.b, name.e);
cookie->value = strdupdelim (value.b, value.e);
- while (extract_param (&ptr, &name, &value, ';'))
+ while (extract_param (&ptr, &name, &value, ';', NULL))
{
if (TOKEN_IS (name, "domain"))
{
@@ -385,6 +394,9 @@ parse_set_cookie (const char *set_cookie, bool silent)
goto error;
BOUNDED_TO_ALLOCA (value.b, value.e, value_copy);
+ /* Check if expiration spec is valid.
+ If not, assume default (cookie doesn't expire, but valid only for
+ this session.) */
expires = http_atotm (value_copy);
if (expires != (time_t) -1)
{
@@ -396,10 +408,6 @@ parse_set_cookie (const char *set_cookie, bool silent)
if (cookie->expiry_time < cookies_now)
cookie->discard_requested = 1;
}
- else
- /* Error in expiration spec. Assume default (cookie doesn't
- expire, but valid only for this session.) */
- ;
}
else if (TOKEN_IS (name, "max-age"))
{
@@ -427,9 +435,7 @@ parse_set_cookie (const char *set_cookie, bool silent)
/* ignore value completely */
cookie->secure = 1;
}
- else
- /* Ignore unrecognized attribute. */
- ;
+ /* else: Ignore unrecognized attribute. */
}
if (*ptr)
/* extract_param has encountered a syntax error */
@@ -442,7 +448,8 @@ parse_set_cookie (const char *set_cookie, bool silent)
if (!silent)
logprintf (LOG_NOTQUIET,
_("Syntax error in Set-Cookie: %s at position %d.\n"),
- escnonprint (set_cookie), (int) (ptr - set_cookie));
+ quotearg_style (escape_quoting_style, set_cookie),
+ (int) (ptr - set_cookie));
delete_cookie (cookie);
return NULL;
}
@@ -456,9 +463,9 @@ parse_set_cookie (const char *set_cookie, bool silent)
#define REQUIRE_DIGITS(p) do { \
- if (!ISDIGIT (*p)) \
+ if (!c_isdigit (*p)) \
return false; \
- for (++p; ISDIGIT (*p); p++) \
+ for (++p; c_isdigit (*p); p++) \
; \
} while (0)
@@ -499,14 +506,27 @@ numeric_address_p (const char *addr)
static bool
check_domain_match (const char *cookie_domain, const char *host)
{
+
+#ifdef HAVE_LIBPSL
DEBUGP (("cdm: 1"));
+ const psl_ctx_t *psl;
+ int is_acceptable;
- /* Numeric address requires exact match. It also requires HOST to
- be an IP address. */
- if (numeric_address_p (cookie_domain))
- return 0 == strcmp (cookie_domain, host);
+ if (!(psl = psl_builtin()))
+ {
+ DEBUGP (("\nlibpsl not built with a public suffix list. "
+ "Falling back to simple heuristics.\n"));
+ goto no_psl;
+ }
+
+ is_acceptable = psl_is_cookie_domain_acceptable (psl, host, cookie_domain);
+ return true ? (is_acceptable == 1) : false;
- DEBUGP ((" 2"));
+no_psl:
+#endif
+
+ /* For efficiency make some elementary checks first */
+ DEBUGP (("cdm: 2"));
/* For the sake of efficiency, check for exact match first. */
if (0 == strcasecmp (cookie_domain, host))
@@ -587,7 +607,7 @@ check_domain_match (const char *cookie_domain, const char *host)
if (dccount == 2)
{
- int i;
+ size_t i;
int known_toplevel = false;
static const char *known_toplevel_domains[] = {
".com", ".edu", ".net", ".org", ".gov", ".mil", ".int"
@@ -669,9 +689,6 @@ cookie_handle_set_cookie (struct cookie_jar *jar,
if (!cookie->domain)
{
- copy_domain:
- /* If the domain was not provided, we use the one we're talking
- to, and set exact match. */
cookie->domain = xstrdup (host);
cookie->domain_exact = 1;
/* Set the port, but only if it's non-default. */
@@ -683,10 +700,12 @@ cookie_handle_set_cookie (struct cookie_jar *jar,
if (!check_domain_match (cookie->domain, host))
{
logprintf (LOG_NOTQUIET,
- _("Cookie coming from %s attempted to set domain to %s\n"),
- escnonprint (host), escnonprint (cookie->domain));
- xfree (cookie->domain);
- goto copy_domain;
+ _("Cookie coming from %s attempted to set domain to "),
+ quotearg_style (escape_quoting_style, host));
+ logprintf (LOG_NOTQUIET,
+ _("%s\n"),
+ quotearg_style (escape_quoting_style, cookie->domain));
+ cookie->discard_requested = true;
}
}
@@ -732,7 +751,7 @@ cookie_handle_set_cookie (struct cookie_jar *jar,
/* Support for sending out cookies in HTTP requests, based on
previously stored cookies. Entry point is
`build_cookies_request'. */
-
+
/* Return a count of how many times CHR occurs in STRING. */
static int
@@ -1102,7 +1121,7 @@ domain_port (const char *domain_b, const char *domain_e,
const char *colon = memchr (domain_b, ':', domain_e - domain_b);
if (!colon)
return 0;
- for (p = colon + 1; p < domain_e && ISDIGIT (*p); p++)
+ for (p = colon + 1; p < domain_e && c_isdigit (*p); p++)
port = 10 * port + (*p - '0');
if (p < domain_e)
/* Garbage following port number. */
@@ -1126,17 +1145,20 @@ domain_port (const char *domain_b, const char *domain_e,
void
cookie_jar_load (struct cookie_jar *jar, const char *file)
{
- char *line;
+ char *line = NULL;
+ size_t bufsize = 0;
+
FILE *fp = fopen (file, "r");
if (!fp)
{
- logprintf (LOG_NOTQUIET, _("Cannot open cookies file `%s': %s\n"),
- file, strerror (errno));
+ logprintf (LOG_NOTQUIET, _("Cannot open cookies file %s: %s\n"),
+ quote (file), strerror (errno));
return;
}
+
cookies_now = time (NULL);
- for (; ((line = read_whole_line (fp)) != NULL); xfree (line))
+ while (getline (&line, &bufsize, fp) > 0)
{
struct cookie *cookie;
char *p = line;
@@ -1153,7 +1175,7 @@ cookie_jar_load (struct cookie_jar *jar, const char *file)
char *value_b = NULL, *value_e = NULL;
/* Skip leading white-space. */
- while (*p && ISSPACE (*p))
+ while (*p && c_isspace (*p))
++p;
/* Ignore empty lines. */
if (!*p || *p == '#')
@@ -1230,6 +1252,8 @@ cookie_jar_load (struct cookie_jar *jar, const char *file)
abort_cookie:
delete_cookie (cookie);
}
+
+ xfree(line);
fclose (fp);
}
@@ -1248,8 +1272,8 @@ cookie_jar_save (struct cookie_jar *jar, const char *file)
fp = fopen (file, "w");
if (!fp)
{
- logprintf (LOG_NOTQUIET, _("Cannot open cookies file `%s': %s\n"),
- file, strerror (errno));
+ logprintf (LOG_NOTQUIET, _("Cannot open cookies file %s: %s\n"),
+ quote (file), strerror (errno));
return;
}
@@ -1285,11 +1309,11 @@ cookie_jar_save (struct cookie_jar *jar, const char *file)
}
out:
if (ferror (fp))
- logprintf (LOG_NOTQUIET, _("Error writing to `%s': %s\n"),
- file, strerror (errno));
+ logprintf (LOG_NOTQUIET, _("Error writing to %s: %s\n"),
+ quote (file), strerror (errno));
if (fclose (fp) < 0)
- logprintf (LOG_NOTQUIET, _("Error closing `%s': %s\n"),
- file, strerror (errno));
+ logprintf (LOG_NOTQUIET, _("Error closing %s: %s\n"),
+ quote (file), strerror (errno));
DEBUGP (("Done saving cookies.\n"));
}
@@ -1369,7 +1393,7 @@ test_cookies (void)
param_token name, value;
const char *ptr = data;
int j = 0;
- while (extract_param (&ptr, &name, &value, ';'))
+ while (extract_param (&ptr, &name, &value, ';', NULL))
{
char *n = strdupdelim (name.b, name.e);
char *v = strdupdelim (value.b, value.e);