Esempio n. 1
0
int
set_cookie_header_cb (const char *hdr, void *closure)
{
  struct url *u = (struct url *)closure;
  struct cookie *cookie;

  cookies_now = time (NULL);

  cookie = parse_set_cookies (hdr);
  if (!cookie)
    goto out;

  /* Sanitize parts of cookie. */

  if (!cookie->domain)
    cookie->domain = xstrdup (u->host);
  else
    {
      if (!check_domain_match (cookie->domain, u->host))
	{
	  DEBUGP (("Attempt to fake the domain: %s, %s\n",
		   cookie->domain, u->host));
	  goto out;
	}
    }
  if (!cookie->path)
    cookie->path = xstrdup (u->path);
  else
    {
      if (!check_path_match (cookie->path, u->path))
	{
	  DEBUGP (("Attempt to fake the path: %s, %s\n",
		   cookie->path, u->path));
	  goto out;
	}
    }

  cookie->port = u->port;

  if (cookie->discard_requested)
    {
      discard_matching_cookie (cookie);
      delete_cookie (cookie);
      return 1;
    }

  store_cookie (cookie);
  return 1;

 out:
  if (cookie)
    delete_cookie (cookie);
  return 1;
}
Esempio n. 2
0
static void
process_altavista_cookie(const char *cookie, char **new_cookie) {
  CookieNodeType *cl;
  ustring ucookie = USTRING_INITIALIZER;
  *new_cookie = NULL;

  cl = parse_cookies(cookie);
  if(!cl) {
    nag("Error parsing cookies\n");
    goto cleanup;
  }

  delete_cookie(&cl, "AV_ALL");
  if(set_cookie_value(&cl, " AV_PG", "1")) {
    nag("Error setting new cookie value\n");
    goto cleanup;
  }

  if(rebuild_cookie(cl, &ucookie)) {
    nag("Error rebuilding cookie\n");
    goto cleanup;
  }
  
  *new_cookie = Strdup(ucookie.string);

 cleanup:
  delete_cookie_list(cl);
  reset_ustring(&ucookie);
}
Esempio n. 3
0
static void
soup_cookie_jar_text_changed (SoupCookieJar *jar,
			      SoupCookie    *old_cookie,
			      SoupCookie    *new_cookie)
{
	FILE *out;
	SoupCookieJarTextPrivate *priv =
		SOUP_COOKIE_JAR_TEXT_GET_PRIVATE (jar);

	/* We can sort of ignore the semantics of the 'changed'
	 * signal here and simply delete the old cookie if present
	 * and write the new cookie if present. That will do the
	 * right thing for all 'added', 'deleted' and 'modified'
	 * meanings.
	 */
	/* Also, delete_cookie takes the filename and write_cookie
	 * a FILE pointer. Seems more convenient that way considering
	 * the implementations of the functions
	 */
	if (old_cookie)
		delete_cookie (priv->filename, old_cookie);

	if (new_cookie) {
		gboolean write_header = FALSE;

		if (!g_file_test (priv->filename, G_FILE_TEST_EXISTS))
			write_header = TRUE;

		out = fopen (priv->filename, "a");
		if (!out) {
			/* FIXME: error? */
			return;
		}

		if (write_header) {
			fprintf (out, "# HTTP Cookie File\n");
			fprintf (out, "# http://www.netscape.com/newsref/std/cookie_spec.html\n");
			fprintf (out, "# This is a generated file!  Do not edit.\n");
			fprintf (out, "# To delete cookies, use the Cookie Manager.\n\n");
		}

		if (new_cookie->expires)
			write_cookie (out, new_cookie);

		if (fclose (out) != 0) {
			/* FIXME: error? */
			return;
		}
	}
}
Esempio n. 4
0
static void
discard_matching_cookie (struct cookie *cookie)
{
  struct cookie *prev, *victim;

  if (!cookies_hash_table
      || !hash_table_count (cookies_hash_table))
    /* No elements == nothing to discard. */
    return;

  victim = find_matching_cookie (cookie, &prev);
  if (victim)
    {
      if (prev)
	/* Simply unchain the victim. */
	prev->next = victim->next;
      else
	{
	  /* VICTIM was head of its chain.  We need to place a new
	     cookie at the head.  */

	  char *hostport;
	  char *chain_key = NULL;
	  int res;

	  SET_HOSTPORT (victim->domain, victim->port, hostport);
	  res = hash_table_get_pair (cookies_hash_table, hostport,
				     &chain_key, NULL);
	  assert (res != 0);
	  if (!victim->next)
	    {
	      /* VICTIM was the only cookie in the chain.  Destroy the
		 chain and deallocate the chain key.  */

	      hash_table_remove (cookies_hash_table, hostport);
	      xfree (chain_key);
	    }
	  else
	    hash_table_put (cookies_hash_table, chain_key, victim->next);
	}
      delete_cookie (victim);
      DEBUGP (("Discarded old cookie.\n"));
    }
}
Esempio n. 5
0
static void
delete_cookie_item(struct listbox_item *item, int last)
{
    struct cookie *cookie = (struct cookie *)item->udata;

    if (item->type == BI_FOLDER) {
        struct listbox_item *next, *root = item;

        /* Releasing refcounts on the cookie_server will automagically
         * delete it. */
        foreachsafe (item, next, root->child)
        delete_cookie_item(item, 0);
    } else {
        assert(!is_object_used(cookie));

        delete_cookie(cookie);
        set_cookies_dirty();
    }
}
Esempio n. 6
0
static int
delete_cookie_chain_mapper (void *value, void *key, void *arg_ignored)
{
  char *chain_key = (char *)value;
  struct cookie *chain = (struct cookie *)key;

  /* Remove the chain from the table and free the key. */
  hash_table_remove (cookies_hash_table, chain_key);
  xfree (chain_key);

  /* Then delete all the cookies in the chain. */
  while (chain)
    {
      struct cookie *next = chain->next;
      delete_cookie (chain);
      chain = next;
    }

  /* Keep mapping. */
  return 0;
}
Esempio n. 7
0
static struct cookie *
parse_set_cookies (const char *sc)
{
  struct cookie *cookie = cookie_new ();

  enum { S_NAME_PRE, S_NAME, S_NAME_POST,
	 S_VALUE_PRE, S_VALUE, S_VALUE_TRAILSPACE_MAYBE,
	 S_QUOTED_VALUE, S_QUOTED_VALUE_POST,
	 S_ATTR_ACTION,
	 S_DONE, S_ERROR } state = S_NAME_PRE;

  const char *p = sc;
  char c;

  const char *name_b  = NULL, *name_e  = NULL;
  const char *value_b = NULL, *value_e = NULL;

  FETCH (c, p);

  while (state != S_DONE && state != S_ERROR)
    {
      switch (state)
	{
	case S_NAME_PRE:
	  if (ISSPACE (c))
	    FETCH (c, p);
	  else if (ATTR_NAME_CHAR (c))
	    {
	      name_b = p - 1;
	      FETCH1 (c, p);
	      state = S_NAME;
	    }
	  else
	    /* empty attr name not allowed */
	    state = S_ERROR;
	  break;
	case S_NAME:
	  if (ATTR_NAME_CHAR (c))
	    FETCH1 (c, p);
	  else if (!c || c == ';' || c == '=' || ISSPACE (c))
	    {
	      name_e = p - 1;
	      state = S_NAME_POST;
	    }
	  else
	    state = S_ERROR;
	  break;
	case S_NAME_POST:
	  if (ISSPACE (c))
	    FETCH1 (c, p);
	  else if (!c || c == ';')
	    {
	      value_b = value_e = NULL;
	      state = S_ATTR_ACTION;
	    }
	  else if (c == '=')
	    {
	      FETCH1 (c, p);
	      state = S_VALUE_PRE;
	    }
	  else
	    state = S_ERROR;
	  break;
	case S_VALUE_PRE:
	  if (ISSPACE (c))
	    FETCH1 (c, p);
	  else if (c == '"')
	    {
	      value_b = p;
	      FETCH (c, p);
	      state = S_QUOTED_VALUE;
	    }
	  else if (c == ';' || c == '\0')
	    {
	      value_b = value_e = p - 1;
	      state = S_ATTR_ACTION;
	    }
	  else
	    {
	      value_b = p - 1;
	      value_e = NULL;
	      state = S_VALUE;
	    }
	  break;
	case S_VALUE:
	  if (c == ';' || c == '\0')
	    {
	      if (!value_e)
		value_e = p - 1;
	      state = S_ATTR_ACTION;
	    }
	  else if (ISSPACE (c))
	    {
	      value_e = p - 1;
	      FETCH1 (c, p);
	      state = S_VALUE_TRAILSPACE_MAYBE;
	    }
	  else
	    {
	      value_e = NULL;	/* no trailing space */
	      FETCH1 (c, p);
	    }
	  break;
	case S_VALUE_TRAILSPACE_MAYBE:
	  if (ISSPACE (c))
	    FETCH1 (c, p);
	  else
	    state = S_VALUE;
	  break;
	case S_QUOTED_VALUE:
	  if (c == '"')
	    {
	      value_e = p - 1;
	      FETCH1 (c, p);
	      state = S_QUOTED_VALUE_POST;
	    }
	  else
	    FETCH (c, p);
	  break;
	case S_QUOTED_VALUE_POST:
	  if (c == ';' || !c)
	    state = S_ATTR_ACTION;
	  else if (ISSPACE (c))
	    FETCH1 (c, p);
	  else
	    state = S_ERROR;
	  break;
	case S_ATTR_ACTION:
	  {
	    int legal = update_cookie_field (cookie, name_b, name_e,
					     value_b, value_e);
	    if (!legal)
	      {
		char *name;
		BOUNDED_TO_ALLOCA (name_b, name_e, name);
		logprintf (LOG_NOTQUIET,
			   _("Error in Set-Cookie, field `%s'"), name);
		state = S_ERROR;
		break;
	      }

	    if (c)
	      FETCH1 (c, p);
	    if (!c)
	      state = S_DONE;
	    else
	      state = S_NAME_PRE;
	  }
	  break;
	case S_DONE:
	case S_ERROR:
	  /* handled by loop condition */
	  break;
	}
    }
  if (state == S_DONE)
    return cookie;

  delete_cookie (cookie);
  if (state == S_ERROR)
    logprintf (LOG_NOTQUIET, _("Syntax error in Set-Cookie at character `%c'.\n"), c);
  else
    abort ();
  return NULL;

 eof:
  delete_cookie (cookie);
  logprintf (LOG_NOTQUIET,
	     _("Syntax error in Set-Cookie: premature end of string.\n"));
  return NULL;
}
Esempio n. 8
0
static void
store_cookie (struct cookie *cookie)
{
  struct cookie *chain_head;
  char *hostport;
  char *chain_key;

  if (!cookies_hash_table)
    /* If the hash table is not initialized, do so now, because we'll
       need to store things.  */
    cookies_hash_table = make_nocase_string_hash_table (0);

  /* Initialize hash table key.  */
  SET_HOSTPORT (cookie->domain, cookie->port, hostport);

  if (hash_table_get_pair (cookies_hash_table, hostport,
			   &chain_key, &chain_head))
    {
      /* There already exists a chain of cookies with this exact
         domain.  We need to check for duplicates -- if an existing
         cookie exactly matches our domain, path and name, we replace
         it.  */
      struct cookie *prev;
      struct cookie *victim = find_matching_cookie (cookie, &prev);

      if (victim)
	{
	  /* Remove VICTIM from the chain.  COOKIE will be placed at
	     the head. */
	  if (prev)
	    {
	      prev->next = victim->next;
	      cookie->next = chain_head;
	    }
	  else
	    {
	      /* prev is NULL; apparently VICTIM was at the head of
		 the chain.  This place will be taken by COOKIE, so
		 all we need to do is:  */
	      cookie->next = victim->next;
	    }
	  delete_cookie (victim);
	  DEBUGP (("Deleted old cookie (to be replaced.)\n"));
	}
      else
	cookie->next = chain_head;
    }
  else
    {
      /* We are now creating the chain.  Allocate the string that will
	 be used as a key.  It is unsafe to use cookie->domain for
	 that, because it might get deallocated by the above code at
	 some point later.  */
      cookie->next = NULL;
      chain_key = xstrdup (hostport);
    }

  hash_table_put (cookies_hash_table, chain_key, cookie);

  DEBUGP (("\nStored cookie %s %d %s %s %d %s %s %s\n",
	   cookie->domain, cookie->port, cookie->path,
	   cookie->permanent ? "permanent" : "nonpermanent",
	   cookie->secure,
	   asctime (localtime ((time_t *)&cookie->expiry_time)),
	   cookie->attr, cookie->value));
}
Esempio n. 9
0
void
load_cookies (const char *file)
{
  char *line;
  FILE *fp = fopen (file, "r");
  if (!fp)
    {
      logprintf (LOG_NOTQUIET, "Cannot open cookies file `%s': %s\n",
		 file, strerror (errno));
      return;
    }
  cookies_now = time (NULL);

  for (; ((line = read_whole_line (fp)) != NULL); xfree (line))
    {
      struct cookie *cookie;
      char *p = line;

      int port;

      char *domain_b  = NULL, *domain_e  = NULL;
      char *ignore_b  = NULL, *ignore_e  = NULL;
      char *path_b    = NULL, *path_e    = NULL;
      char *secure_b  = NULL, *secure_e  = NULL;
      char *expires_b = NULL, *expires_e = NULL;
      char *name_b    = NULL, *name_e    = NULL;
      char *value_b   = NULL, *value_e   = NULL;

      SKIP_WS (p);

      if (!*p || *p == '#')
	/* empty line */
	continue;

      SET_WORD_BOUNDARIES (p, domain_b,  domain_e);
      SET_WORD_BOUNDARIES (p, ignore_b,  ignore_e);
      SET_WORD_BOUNDARIES (p, path_b,    path_e);
      SET_WORD_BOUNDARIES (p, secure_b,  secure_e);
      SET_WORD_BOUNDARIES (p, expires_b, expires_e);
      SET_WORD_BOUNDARIES (p, name_b,    name_e);

      /* Don't use SET_WORD_BOUNDARIES for value because it may
	 contain whitespace.  Instead, set value_e to the end of line,
	 modulo trailing space (this will skip the line separator.) */
      SKIP_WS (p);
      value_b = p;
      value_e = p + strlen (p);
      while (value_e > value_b && ISSPACE (*(value_e - 1)))
	--value_e;
      if (value_b == value_e)
	/* Hmm, should we check for empty value?  I guess that's
	   legal, so I leave it.  */
	;

      cookie = cookie_new ();

      cookie->attr    = strdupdelim (name_b, name_e);
      cookie->value   = strdupdelim (value_b, value_e);
      cookie->path    = strdupdelim (path_b, path_e);

      if (BOUNDED_EQUAL (secure_b, secure_e, "TRUE"))
	cookie->secure = 1;

      /* DOMAIN needs special treatment because we might need to
	 extract the port.  */
      port = domain_port (domain_b, domain_e, (const char **)&domain_e);
      if (port)
	cookie->port = port;
      else
	cookie->port = cookie->secure ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT;

      cookie->domain  = strdupdelim (domain_b, domain_e);

      /* safe default in case EXPIRES field is garbled. */
      cookie->expiry_time = cookies_now - 1;

      /* I don't like changing the line, but it's completely safe.
	 (line is malloced.)  */
      *expires_e = '\0';
      sscanf (expires_b, "%lu", &cookie->expiry_time);
      if (cookie->expiry_time < cookies_now)
	/* ignore stale cookie. */
	goto abort;
      cookie->permanent = 1;

      store_cookie (cookie);

    next:
      continue;

    abort:
      delete_cookie (cookie);
    }
  fclose (fp);
}