Beispiel #1
0
void mget_cookie_store_cookies(MGET_VECTOR *cookies)
{
	int it;

	for (it = mget_vector_size(cookies) - 1; it >= 0; it--) {
		MGET_COOKIE *cookie = mget_vector_get(cookies, it);
		mget_cookie_store_cookie(cookie);
		mget_vector_remove(cookies, it);
	}
}
Beispiel #2
0
void mget_cookie_store_cookies(mget_cookie_db_t *cookie_db, mget_vector_t *cookies)
{
	if (cookie_db) {
		int it;

		for (it = mget_vector_size(cookies) - 1; it >= 0; it--) {
			mget_cookie_t *cookie = mget_vector_get(cookies, it);
			mget_cookie_store_cookie(cookie_db, cookie); // stores a shallow copy of 'cookie'
			mget_vector_remove_nofree(cookies, it);
			xfree(cookie); // shallow free of 'cookie'
		}
	}
}
Beispiel #3
0
static void test_cookies(void)
{
	static const struct test_data {
		const char
			*uri,
			*set_cookie,
			*name, *value, *domain, *path, *expires;
		unsigned int
			domain_dot : 1, // for compatibility with Netscape cookie format
			normalized : 1,
			persistent : 1,
			host_only : 1,
			secure_only : 1, // cookie should be used over secure connections only (TLS/HTTPS)
			http_only : 1; // just use the cookie via HTTP/HTTPS protocol
		int
			result,
			psl_result;
	} test_data[] = {
		{	// allowed cookie
			"www.example.com",
			"ID=65=abcd; expires=Tuesday, 07-May-2013 07:48:53 GMT; path=/; domain=.example.com; HttpOnly",
			"ID", "65=abcd", "example.com", "/", "Tue, 07 May 2013 07:48:53 GMT",
			1, 1, 1, 0, 0, 1,
			0, 0
		},
		{	// allowed cookie ANSI C's asctime format
			"www.example.com",
			"ID=65=abcd; expires=Tue May 07 07:48:53 2013; path=/; domain=.example.com",
			"ID", "65=abcd", "example.com", "/", "Tue, 07 May 2013 07:48:53 GMT",
			1, 1, 1, 0, 0, 0,
			0, 0
		},
		{	// allowed cookie without path
			"www.example.com",
			"ID=65=abcd; expires=Tue, 07-May-2013 07:48:53 GMT; domain=.example.com",
			"ID", "65=abcd", "example.com", "/", "Tue, 07 May 2013 07:48:53 GMT",
			1, 1, 1, 0, 0, 0,
			0, 0
		},
		{	// allowed cookie without domain
			"www.example.com",
			"ID=65=abcd; expires=Tue, 07-May-2013 07:48:53 GMT; path=/",
			"ID", "65=abcd", "www.example.com", "/", "Tue, 07 May 2013 07:48:53 GMT",
			0, 1, 1, 1, 0, 0,
			0, 0
		},
		{	// allowed cookie without domain, path and expires
			"www.example.com",
			"ID=65=abcd",
			"ID", "65=abcd", "www.example.com", "/", "Tue, 07 May 2013 07:48:53 GMT",
			0, 1, 0, 1, 0, 0,
			0, 0
		},
		{	// illegal cookie
			"www.example.com",
			"ID=65=abcd; expires=Tue, 07-May-2013 07:48:53 GMT; path=/; domain=.example.org",
			"ID", "65=abcd", "example.org", "/", "Tue, 07 May 2013 07:48:53 GMT",
			1, 0, 1, 0, 0, 0,
			-1, 0
		},
#ifdef WITH_LIBPSL
		{	// supercookie, accepted by normalization (rule 'com') but not by mget_cookie_check_psl())
			"www.example.com",
			"ID=65=abcd; expires=Mon, 29-Feb-2016 07:48:54 GMT; path=/; domain=.com; HttpOnly; Secure",
			"ID", "65=abcd", "com", "/", "Mon, 29 Feb 2016 07:48:54 GMT",
			1, 0, 1, 0, 1, 1,
			0, -1
		},
		{	// supercookie, accepted by normalization  (rule '*.ar') but not by mget_cookie_check_psl())
			"www.sa.gov.au",
			"ID=65=abcd; expires=Tue, 29-Feb-2000 07:48:55 GMT; path=/; domain=.sa.gov.au",
			"ID", "65=abcd", "sa.gov.au", "/", "Tue, 29 Feb 2000 07:48:55 GMT",
			1, 0, 1, 0, 0, 0,
			0, -1
		},
#endif
		{	// exception rule '!educ.ar', accepted by normalization
			"www.educ.ar",
			"ID=65=abcd; path=/; domain=.educ.ar",
			"ID", "65=abcd", "educ.ar", "/", NULL,
			1, 1, 0, 0, 0, 0,
			0, 0
		},
	};
	mget_cookie_t cookie;
	mget_cookie_db_t *cookies;
	mget_iri_t *iri;
	unsigned it;
	int result, result_psl;

	cookies = mget_cookie_db_init(NULL);
	mget_cookie_db_load_psl(cookies, DATADIR "/effective_tld_names.dat");

	for (it = 0; it < countof(test_data); it++) {
		const struct test_data *t = &test_data[it];
		char thedate[32], *header;

		iri = mget_iri_parse(t->uri, "utf-8");
		mget_http_parse_setcookie(t->set_cookie, &cookie);
		if ((result = mget_cookie_normalize(iri, &cookie)) != t->result) {
			failed++;
			info_printf("Failed [%u]: normalize_cookie(%s) -> %d (expected %d)\n", it, t->set_cookie, result, t->result);
			mget_cookie_deinit(&cookie);
			goto next;
		} else {
			if ((result_psl = mget_cookie_check_psl(cookies, &cookie)) != t->psl_result) {
				failed++;
				info_printf("Failed [%u]: PSL check(%s) -> %d (expected %d)\n", it, t->set_cookie, result_psl, t->psl_result);
			}
			mget_cookie_deinit(&cookie);
			goto next;
		}

		if (cookie.expires) {
			mget_http_print_date(cookie.expires, thedate, sizeof(thedate));
			if (strcmp(thedate, t->expires)) {
				failed++;
				info_printf("Failed [%u]: expires mismatch: '%s' != '%s' (time_t %lld)\n", it, thedate, t->expires, (long long)cookie.expires);
				mget_cookie_deinit(&cookie);
				goto next;
			}
		}

		if (strcmp(cookie.name, t->name) ||
			strcmp(cookie.value, t->value) ||
			strcmp(cookie.domain, t->domain) ||
			strcmp(cookie.path, t->path) ||
			cookie.domain_dot != t->domain_dot ||
			cookie.normalized != t->normalized ||
			cookie.persistent != t->persistent ||
			cookie.host_only != t->host_only ||
			cookie.secure_only != t->secure_only ||
			cookie.http_only != t->http_only)
		{
			failed++;

			info_printf("Failed [%u]: cookie (%s) differs:\n", it, t->set_cookie);
			if (strcmp(cookie.name, t->name))
				info_printf("  name %s (expected %s)\n", cookie.name, t->name);
			if (strcmp(cookie.value, t->value))
				info_printf("  value %s (expected %s)\n", cookie.value, t->value);
			if (strcmp(cookie.domain, t->domain))
				info_printf("  domain %s (expected %s)\n", cookie.domain, t->domain);
			if (strcmp(cookie.path, t->path))
				info_printf("  path %s (expected %s)\n", cookie.path, t->path);
			if (cookie.domain_dot != t->domain_dot)
				info_printf("  domain_dot %d (expected %d)\n", cookie.domain_dot, t->domain_dot);
			if (cookie.normalized != t->normalized)
				info_printf("  normalized %d (expected %d)\n", cookie.normalized, t->normalized);
			if (cookie.persistent != t->persistent)
				info_printf("  persistent %d (expected %d)\n", cookie.persistent, t->persistent);
			if (cookie.host_only != t->host_only)
				info_printf("  host_only %d (expected %d)\n", cookie.host_only, t->host_only);
			if (cookie.secure_only != t->secure_only)
				info_printf("  secure_only %d (expected %d)\n", cookie.secure_only, t->secure_only);
			if (cookie.http_only != t->http_only)
				info_printf("  http_only %d (expected %d)\n", cookie.http_only, t->http_only);

			mget_cookie_deinit(&cookie);
			goto next;
		}

		mget_cookie_store_cookie(cookies, &cookie);

		info_printf("%s\n", header = mget_cookie_create_request_header(cookies, iri));
		xfree(header);

		ok++;

next:
		mget_iri_free(&iri);
	}

	mget_cookie_db_free(&cookies);
}
Beispiel #4
0
int mget_cookie_load(const char *fname, int keep_session_cookies)
{
	MGET_COOKIE cookie;
	FILE *fp;
	int ncookies = 0;
	char *buf = NULL, *linep, *p;
	size_t bufsize = 0;
	ssize_t buflen;
	time_t now = time(NULL);

	if ((fp = fopen(fname, "r"))) {
		mget_cookie_init_cookie(&cookie);

		while ((buflen = mget_getline(&buf, &bufsize, fp)) >= 0) {
			linep = buf;

			while (isspace(*linep)) linep++; // ignore leading whitespace
			if (!*linep) continue; // skip empty lines

			if (*linep == '#') {
				if (strncmp(linep, "#HttpOnly_", 10))
					continue; // skip comments

				linep = linep + 10;
				cookie.http_only = 1;
			} else {
				cookie.http_only = 0;
			}

			// strip off \r\n
			while (buflen > 0 && (buf[buflen] == '\n' || buf[buflen] == '\r'))
				buf[--buflen] = 0;

			// parse domain
			for (p = linep; *linep && *linep != '\t';) linep++;
			if (*p == '.') {
				p++;
				cookie.domain_dot = 1;
			}
			cookie.domain = strndup(p, linep - p);

			// parse inverse host_only (FALSE: host_only=1)
			for (p = *linep ? ++linep : linep; *linep && *linep != '\t';) linep++;
			cookie.host_only = strncasecmp(p, "TRUE", 4);

			// parse path
			for (p = *linep ? ++linep : linep; *linep && *linep != '\t';) linep++;
			if (p != linep)
				cookie.path = strndup(p, linep - p);
			else
				cookie.path = strdup("/"); // allow empty paths

			// parse secure_only
			for (p = *linep ? ++linep : linep; *linep && *linep != '\t';) linep++;
			cookie.secure_only = !strncasecmp(p, "TRUE", 4);

			// parse expires
			for (p = *linep ? ++linep : linep; *linep && *linep != '\t';) linep++;
			cookie.expires = atol(p);
			if (cookie.expires && cookie.expires < now) {
				// drop expired cookie
				mget_cookie_free_cookie(&cookie);
				continue;
			}
			if (!cookie.expires && !keep_session_cookies) {
				// drop session cookies
				mget_cookie_free_cookie(&cookie);
				continue;
			}

			// parse name
			for (p = *linep ? ++linep : linep; *linep && *linep != '\t';) linep++;
			if (linep == p) {
				error_printf(_("Incomplete entry in '%s': %s\n"), fname, buf);
				mget_cookie_free_cookie(&cookie);
				continue;
			}
			cookie.name = strndup(p, linep - p);

			// parse value, until end of line
			for (p = *linep ? ++linep : linep; *linep;) linep++;
			cookie.value = strndup(p, linep - p);

			if (mget_cookie_normalize_cookie(NULL, &cookie) != 0) {
				ncookies++;
				mget_cookie_store_cookie(&cookie);
			} else
				mget_cookie_free_cookie(&cookie);
		}

		xfree(buf);
		fclose(fp);
	} else
		error_printf(_("Failed to open cookie file '%s'\n"), fname);

	info_printf(_("loaded %d cookie%s from '%s'\n"), ncookies, ncookies !=1 ? "s" : "", fname);

	return ncookies;
}