From 495b08e32d7e55f2e77295269f457eeb9caae676 Mon Sep 17 00:00:00 2001 From: marco Date: Wed, 2 Nov 2011 17:46:44 -0500 Subject: move cookies to own file --- cookie.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 cookie.c (limited to 'cookie.c') diff --git a/cookie.c b/cookie.c new file mode 100644 index 0000000..5712549 --- /dev/null +++ b/cookie.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2010, 2011 Marco Peereboom + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "xxxterm.h" + +#define XT_REJECT_FILE ("rejected.txt") +#define XT_COOKIE_FILE ("cookies.txt") + +/* hooked functions */ +void (*_soup_cookie_jar_add_cookie)(SoupCookieJar *, SoupCookie *); +void (*_soup_cookie_jar_delete_cookie)(SoupCookieJar *, + SoupCookie *); + +void +print_cookie(char *msg, SoupCookie *c) +{ + if (c == NULL) + return; + + if (msg) + DNPRINTF(XT_D_COOKIE, "%s\n", msg); + DNPRINTF(XT_D_COOKIE, "name : %s\n", c->name); + DNPRINTF(XT_D_COOKIE, "value : %s\n", c->value); + DNPRINTF(XT_D_COOKIE, "domain : %s\n", c->domain); + DNPRINTF(XT_D_COOKIE, "path : %s\n", c->path); + DNPRINTF(XT_D_COOKIE, "expires : %s\n", + c->expires ? soup_date_to_string(c->expires, SOUP_DATE_HTTP) : ""); + DNPRINTF(XT_D_COOKIE, "secure : %d\n", c->secure); + DNPRINTF(XT_D_COOKIE, "http_only: %d\n", c->http_only); + DNPRINTF(XT_D_COOKIE, "====================================\n"); +} + +void +set_hook(void **hook, char *name) +{ + if (hook == NULL) + errx(1, "set_hook"); + + if (*hook == NULL) { + *hook = dlsym(RTLD_NEXT, name); + if (*hook == NULL) + errx(1, "can't hook %s", name); + } +} + +/* override libsoup soup_cookie_equal because it doesn't look at domain */ +gboolean +soup_cookie_equal(SoupCookie *cookie1, SoupCookie *cookie2) +{ + g_return_val_if_fail(cookie1, FALSE); + g_return_val_if_fail(cookie2, FALSE); + + return (!strcmp (cookie1->name, cookie2->name) && + !strcmp (cookie1->value, cookie2->value) && + !strcmp (cookie1->path, cookie2->path) && + !strcmp (cookie1->domain, cookie2->domain)); +} + +void +transfer_cookies(void) +{ + GSList *cf; + SoupCookie *sc, *pc; + + cf = soup_cookie_jar_all_cookies(p_cookiejar); + + for (;cf; cf = cf->next) { + pc = cf->data; + sc = soup_cookie_copy(pc); + _soup_cookie_jar_add_cookie(s_cookiejar, sc); + } + + soup_cookies_free(cf); +} + +void +soup_cookie_jar_delete_cookie(SoupCookieJar *jar, SoupCookie *c) +{ + GSList *cf; + SoupCookie *ci; + + print_cookie("soup_cookie_jar_delete_cookie", c); + + if (cookies_enabled == 0) + return; + + if (jar == NULL || c == NULL) + return; + + /* find and remove from persistent jar */ + cf = soup_cookie_jar_all_cookies(p_cookiejar); + + for (;cf; cf = cf->next) { + ci = cf->data; + if (soup_cookie_equal(ci, c)) { + _soup_cookie_jar_delete_cookie(p_cookiejar, ci); + break; + } + } + + soup_cookies_free(cf); + + /* delete from session jar */ + _soup_cookie_jar_delete_cookie(s_cookiejar, c); +} + +void +soup_cookie_jar_add_cookie(SoupCookieJar *jar, SoupCookie *cookie) +{ + struct domain *d = NULL; + SoupCookie *c; + FILE *r_cookie_f; + + DNPRINTF(XT_D_COOKIE, "soup_cookie_jar_add_cookie: %p %p %p\n", + jar, p_cookiejar, s_cookiejar); + + if (cookies_enabled == 0) + return; + + /* see if we are up and running */ + if (p_cookiejar == NULL) { + _soup_cookie_jar_add_cookie(jar, cookie); + return; + } + /* disallow p_cookiejar adds, shouldn't happen */ + if (jar == p_cookiejar) + return; + + /* sanity */ + if (jar == NULL || cookie == NULL) + return; + + if (enable_cookie_whitelist && + (d = wl_find(cookie->domain, &c_wl)) == NULL) { + blocked_cookies++; + DNPRINTF(XT_D_COOKIE, + "soup_cookie_jar_add_cookie: reject %s\n", + cookie->domain); + if (save_rejected_cookies) { + if ((r_cookie_f = fopen(rc_fname, "a+")) == NULL) { + show_oops(NULL, "can't open reject cookie file"); + return; + } + fseek(r_cookie_f, 0, SEEK_END); + fprintf(r_cookie_f, "%s%s\t%s\t%s\t%s\t%lu\t%s\t%s\n", + cookie->http_only ? "#HttpOnly_" : "", + cookie->domain, + *cookie->domain == '.' ? "TRUE" : "FALSE", + cookie->path, + cookie->secure ? "TRUE" : "FALSE", + cookie->expires ? + (gulong)soup_date_to_time_t(cookie->expires) : + 0, + cookie->name, + cookie->value); + fflush(r_cookie_f); + fclose(r_cookie_f); + } + if (!allow_volatile_cookies) + return; + } + + if (cookie->expires == NULL && session_timeout) { + soup_cookie_set_expires(cookie, + soup_date_new_from_now(session_timeout)); + print_cookie("modified add cookie", cookie); + } + + /* see if we are white listed for persistence */ + if ((d && d->handy) || (enable_cookie_whitelist == 0)) { + /* add to persistent jar */ + c = soup_cookie_copy(cookie); + print_cookie("soup_cookie_jar_add_cookie p_cookiejar", c); + _soup_cookie_jar_add_cookie(p_cookiejar, c); + } + + /* add to session jar */ + print_cookie("soup_cookie_jar_add_cookie s_cookiejar", cookie); + _soup_cookie_jar_add_cookie(s_cookiejar, cookie); +} + +void +setup_cookies(void) +{ + char file[PATH_MAX]; + + set_hook((void *)&_soup_cookie_jar_add_cookie, + "soup_cookie_jar_add_cookie"); + set_hook((void *)&_soup_cookie_jar_delete_cookie, + "soup_cookie_jar_delete_cookie"); + + if (cookies_enabled == 0) + return; + + /* + * the following code is intricate due to overriding several libsoup + * functions. + * do not alter order of these operations. + */ + + /* rejected cookies */ + if (save_rejected_cookies) + snprintf(rc_fname, sizeof file, "%s/%s", work_dir, + XT_REJECT_FILE); + + /* persistent cookies */ + snprintf(file, sizeof file, "%s/%s", work_dir, XT_COOKIE_FILE); + p_cookiejar = soup_cookie_jar_text_new(file, read_only_cookies); + + /* session cookies */ + s_cookiejar = soup_cookie_jar_new(); + g_object_set(G_OBJECT(s_cookiejar), SOUP_COOKIE_JAR_ACCEPT_POLICY, + cookie_policy, (void *)NULL); + transfer_cookies(); + + soup_session_add_feature(session, (SoupSessionFeature*)s_cookiejar); +} + -- cgit 1.4.1-2-gfad0