/* Support for cookies.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- 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.
#include <assert.h>
#include <errno.h>
#include <time.h>
+#include <libpsl.h>
#include "utils.h"
#include "hash.h"
#include "cookies.h"
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. */
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"))
{
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)
{
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"))
{
/* ignore value completely */
cookie->secure = 1;
}
- else
- /* Ignore unrecognized attribute. */
- ;
+ /* else: Ignore unrecognized attribute. */
}
if (*ptr)
/* extract_param has encountered a syntax error */
#define REQUIRE_DIGITS(p) do { \
- if (!c_isdigit (*p)) \
+ if (!c_isdigit (*p)) \
return false; \
- for (++p; c_isdigit (*p); p++) \
+ for (++p; c_isdigit (*p); p++) \
; \
} while (0)
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;
+ }
- DEBUGP ((" 2"));
+ is_acceptable = psl_is_cookie_domain_acceptable (psl, host, cookie_domain);
+ return true ? (is_acceptable == 1) : false;
+
+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))
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. */
if (!check_domain_match (cookie->domain, host))
{
logprintf (LOG_NOTQUIET,
- _("Cookie coming from %s attempted to set domain to %s\n"),
- quotearg_style (escape_quoting_style, host),
+ _("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));
- xfree (cookie->domain);
- goto copy_domain;
+ cookie->discard_requested = true;
}
}
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)
{
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;
abort_cookie:
delete_cookie (cookie);
}
+
+ xfree(line);
fclose (fp);
}
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);