Пример #1
0
int parse_new_cookie(http_request req, const char* value, meta_error e)
{
	cookie c;

	assert(NULL != req);
	assert(NULL != value);

	if( (c = cookie_new()) == NULL) 
		return set_os_error(e, ENOMEM);

	/* New cookies require this field! */
	if(!parse_new_cookie_version(c, value, e)) {
		cookie_free(c);
		return 0;
	}

	/* Now for the rest of the attributes */
	if(!parse_new_cookie_name(c, value, e)
	|| !parse_new_cookie_path(c, value, e)
	|| !parse_new_cookie_domain(c, value, e)
	|| !parse_new_cookie_secure(c, value, e)) {
		cookie_free(c);
		return 0;
	}

	if(!request_add_cookie(req, c)) {
		set_os_error(e, errno);
		cookie_free(c);
		return 0;
	}
	else
		return 1;
}
Пример #2
0
/*
 * The old cookie format is (hopefully) name=value
 * where value may be quoted.
 */
int parse_old_cookie(http_request req, const char* input, meta_error e)
{
	cookie c = NULL;
	cstring name = NULL, value = NULL;

	if( (name = cstring_new()) == NULL
	||  (value = cstring_new()) == NULL) 
		goto memerr;

	while(*input != '\0' && *input != '=') {
		if(!cstring_charcat(name, *input++)) 
			goto memerr;
	}

	if(*input != '=') {
		cstring_free(name);
		cstring_free(value);
		return set_http_error(e, HTTP_400_BAD_REQUEST);
	}

	input++; /* Skip '=' */
	if(!cstring_copy(value, input)) 
		goto memerr;

	if( (c = cookie_new()) == NULL) 
		goto memerr;

	if(!cookie_set_name(c, c_str(name)) 
	|| !cookie_set_value(c, c_str(value))) 
		goto memerr;

	cstring_free(name);
	cstring_free(value);
	cookie_set_version(c, 0);
	if(!request_add_cookie(req, c)) {
		set_os_error(e, errno);
		cookie_free(c);
		return 0;
	}

	return 1;

memerr:
	cstring_free(name);
	cstring_free(value);
	cookie_free(c);
	return set_os_error(e, ENOMEM);
}
Пример #3
0
int main(void)
{
	cookie c;
	size_t i, niter = 10000;
	const char* name = "name";
	const char* value = "value"; 
	const char* domain = "DOMAIN";
	const char* path = "PATH";
	const char* comment = "THIS IS A COMMENT";
	int max_age = 0;
	int secure = 1;
	int version = 1;

	for(i = 0; i < niter; i++) {
		if( (c = cookie_new()) == NULL)
			return 77;

		if(!cookie_set_name(c, name)) return 77;
		if(!cookie_set_value(c, value)) return 77;
		if(!cookie_set_domain(c, domain)) return 77;
		if(!cookie_set_path(c, path)) return 77;
		if(!cookie_set_comment(c, comment)) return 77;
		if(!cookie_set_max_age(c, max_age)) return 77;
		cookie_set_secure(c, secure);
		cookie_set_version(c, version);

		if(strcmp(cookie_get_name(c), name) != 0) return 77;
		if(strcmp(cookie_get_value(c), value) != 0) return 77;
		if(strcmp(cookie_get_domain(c), domain) != 0) return 77;
		if(strcmp(cookie_get_path(c), path) != 0) return 77;
		if(strcmp(cookie_get_comment(c), comment) != 0) return 77;
		if(cookie_get_max_age(c) != max_age) return 77;
		if(cookie_get_secure(c) != secure) return 77;
		if(cookie_get_version(c) != version) return 77;

		cookie_free(c);
	}

	return 0;
}
Пример #4
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;
}
Пример #5
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);
}