stale proto
[xombrero.git] / whitelist.c
blob4c85e5da0b89a1a6d8dc77d59518d61602695a1c
1 /*
2 * Copyright (c) 2010, 2011 Marco Peereboom <marco@peereboom.us>
3 * Copyright (c) 2011 Stevan Andjelkovic <stevan@student.chalmers.se>
4 * Copyright (c) 2010, 2011 Edd Barrett <vext01@gmail.com>
5 * Copyright (c) 2011 Todd T. Fries <todd@fries.net>
6 * Copyright (c) 2011 Raphael Graf <r@undefined.ch>
7 * Copyright (c) 2011 Michal Mazurek <akfaew@jasminek.net>
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22 #include "xxxterm.h"
24 gchar *
25 find_domain(const gchar *s, int toplevel)
27 SoupURI *uri;
28 gchar *ret, *p;
30 if (s == NULL)
31 return (NULL);
33 uri = soup_uri_new(s);
35 if (uri == NULL || !SOUP_URI_VALID_FOR_HTTP(uri)) {
36 return (NULL);
39 if (toplevel && !isdigit(uri->host[strlen(uri->host) - 1])) {
40 if ((p = strrchr(uri->host, '.')) != NULL) {
41 while(--p >= uri->host && *p != '.');
42 p++;
43 } else
44 p = uri->host;
45 } else
46 p = uri->host;
48 ret = g_strdup_printf(".%s", p);
50 soup_uri_free(uri);
52 return (ret);
55 struct domain *
56 wl_find(const gchar *search, struct domain_list *wl)
58 int i;
59 struct domain *d = NULL, dfind;
60 gchar *s = NULL;
62 if (search == NULL || wl == NULL)
63 return (NULL);
64 if (strlen(search) < 2)
65 return (NULL);
67 if (search[0] != '.')
68 s = g_strdup_printf(".%s", search);
69 else
70 s = g_strdup(search);
72 for (i = strlen(s) - 1; i >= 0; i--) {
73 if (s[i] == '.') {
74 dfind.d = &s[i];
75 d = RB_FIND(domain_list, wl, &dfind);
76 if (d)
77 goto done;
81 done:
82 if (s)
83 g_free(s);
85 return (d);
88 int
89 wl_save(struct tab *t, struct karg *args, int list)
91 char file[PATH_MAX], *lst_str = NULL;
92 FILE *f;
93 char *line = NULL, *lt = NULL, *dom = NULL;
94 size_t linelen;
95 const gchar *uri;
96 struct karg a;
97 struct domain *d;
98 GSList *cf;
99 SoupCookie *ci, *c;
101 if (t == NULL || args == NULL)
102 return (1);
104 if (runtime_settings[0] == '\0')
105 return (1);
107 snprintf(file, sizeof file, "%s/%s", work_dir, runtime_settings);
108 if ((f = fopen(file, "r+")) == NULL)
109 return (1);
111 switch (list) {
112 case XT_WL_JAVASCRIPT:
113 lst_str = "JavaScript";
114 lt = g_strdup_printf("js_wl=%s", dom);
115 break;
116 case XT_WL_COOKIE:
117 lst_str = "Cookie";
118 lt = g_strdup_printf("cookie_wl=%s", dom);
119 break;
120 case XT_WL_PLUGIN:
121 lst_str = "Plugin";
122 lt = g_strdup_printf("pl_wl=%s", dom);
123 break;
124 default:
125 show_oops(t, "Invalid list id: %d", list);
126 return (1);
129 uri = get_uri(t);
130 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
131 if (uri == NULL || dom == NULL ||
132 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
133 show_oops(t, "Can't add domain to %s white list", lst_str);
134 goto done;
137 while (!feof(f)) {
138 line = fparseln(f, &linelen, NULL, NULL, 0);
139 if (line == NULL)
140 continue;
141 if (!strcmp(line, lt))
142 goto done;
143 free(line);
144 line = NULL;
147 fprintf(f, "%s\n", lt);
149 a.i = XT_WL_ENABLE;
150 a.i |= args->i;
151 switch (list) {
152 case XT_WL_JAVASCRIPT:
153 d = wl_find(dom, &js_wl);
154 if (!d) {
155 settings_add("js_wl", dom);
156 d = wl_find(dom, &js_wl);
158 toggle_js(t, &a);
159 break;
161 case XT_WL_COOKIE:
162 d = wl_find(dom, &c_wl);
163 if (!d) {
164 settings_add("cookie_wl", dom);
165 d = wl_find(dom, &c_wl);
167 toggle_cwl(t, &a);
169 /* find and add to persistent jar */
170 cf = soup_cookie_jar_all_cookies(s_cookiejar);
171 for (;cf; cf = cf->next) {
172 ci = cf->data;
173 if (!strcmp(dom, ci->domain) ||
174 !strcmp(&dom[1], ci->domain)) /* deal with leading . */ {
175 c = soup_cookie_copy(ci);
176 _soup_cookie_jar_add_cookie(p_cookiejar, c);
179 soup_cookies_free(cf);
180 break;
182 case XT_WL_PLUGIN:
183 d = wl_find(dom, &pl_wl);
184 if (!d) {
185 settings_add("pl_wl", dom);
186 d = wl_find(dom, &pl_wl);
188 toggle_pl(t, &a);
189 break;
190 default:
191 abort(); /* can't happen */
193 if (d)
194 d->handy = 1;
196 done:
197 if (line)
198 free(line);
199 if (dom)
200 g_free(dom);
201 if (lt)
202 g_free(lt);
203 fclose(f);
205 return (0);
209 wl_show(struct tab *t, struct karg *args, char *title, struct domain_list *wl)
211 struct domain *d;
212 char *tmp, *body;
214 body = g_strdup("");
216 /* p list */
217 if (args->i & XT_WL_PERSISTENT) {
218 tmp = body;
219 body = g_strdup_printf("%s<h2>Persistent</h2>", body);
220 g_free(tmp);
221 RB_FOREACH(d, domain_list, wl) {
222 if (d->handy == 0)
223 continue;
224 tmp = body;
225 body = g_strdup_printf("%s%s<br/>", body, d->d);
226 g_free(tmp);
230 /* s list */
231 if (args->i & XT_WL_SESSION) {
232 tmp = body;
233 body = g_strdup_printf("%s<h2>Session</h2>", body);
234 g_free(tmp);
235 RB_FOREACH(d, domain_list, wl) {
236 if (d->handy == 1)
237 continue;
238 tmp = body;
239 body = g_strdup_printf("%s%s<br/>", body, d->d);
240 g_free(tmp);
244 tmp = get_html_page(title, body, "", 0);
245 g_free(body);
246 if (wl == &js_wl)
247 load_webkit_string(t, tmp, XT_URI_ABOUT_JSWL);
248 else if (wl == &c_wl)
249 load_webkit_string(t, tmp, XT_URI_ABOUT_COOKIEWL);
250 else
251 load_webkit_string(t, tmp, XT_URI_ABOUT_PLUGINWL);
252 g_free(tmp);
253 return (0);
256 void
257 wl_add(char *str, struct domain_list *wl, int handy)
259 struct domain *d;
260 int add_dot = 0;
261 char *p;
263 if (str == NULL || wl == NULL || strlen(str) < 2)
264 return;
266 DNPRINTF(XT_D_COOKIE, "wl_add in: %s\n", str);
268 /* treat *.moo.com the same as .moo.com */
269 if (str[0] == '*' && str[1] == '.')
270 str = &str[1];
271 else if (str[0] == '.')
272 str = &str[0];
273 else
274 add_dot = 1;
276 /* slice off port number */
277 p = g_strrstr(str, ":");
278 if (p)
279 *p = '\0';
281 d = g_malloc(sizeof *d);
282 if (add_dot)
283 d->d = g_strdup_printf(".%s", str);
284 else
285 d->d = g_strdup(str);
286 d->handy = handy;
288 if (RB_INSERT(domain_list, wl, d))
289 goto unwind;
291 DNPRINTF(XT_D_COOKIE, "wl_add: %s\n", d->d);
292 return;
293 unwind:
294 if (d) {
295 if (d->d)
296 g_free(d->d);
297 g_free(d);
302 add_cookie_wl(struct settings *s, char *entry)
304 wl_add(entry, &c_wl, 1);
305 return (0);
309 add_js_wl(struct settings *s, char *entry)
311 wl_add(entry, &js_wl, 1 /* persistent */);
312 return (0);
316 add_pl_wl(struct settings *s, char *entry)
318 wl_add(entry, &pl_wl, 1 /* persistent */);
319 return (0);
323 toggle_cwl(struct tab *t, struct karg *args)
325 struct domain *d;
326 const gchar *uri;
327 char *dom = NULL;
328 int es;
330 if (args == NULL)
331 return (1);
333 uri = get_uri(t);
334 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
336 if (uri == NULL || dom == NULL ||
337 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
338 show_oops(t, "Can't toggle domain in cookie white list");
339 goto done;
341 d = wl_find(dom, &c_wl);
343 if (d == NULL)
344 es = 0;
345 else
346 es = 1;
348 if (args->i & XT_WL_TOGGLE)
349 es = !es;
350 else if ((args->i & XT_WL_ENABLE) && es != 1)
351 es = 1;
352 else if ((args->i & XT_WL_DISABLE) && es != 0)
353 es = 0;
355 if (es)
356 /* enable cookies for domain */
357 wl_add(dom, &c_wl, 0);
358 else {
359 /* disable cookies for domain */
360 if (d)
361 RB_REMOVE(domain_list, &c_wl, d);
364 if (args->i & XT_WL_RELOAD)
365 webkit_web_view_reload(t->wv);
367 done:
368 g_free(dom);
369 return (0);
373 toggle_js(struct tab *t, struct karg *args)
375 int es;
376 const gchar *uri;
377 struct domain *d;
378 char *dom = NULL;
380 if (args == NULL)
381 return (1);
383 g_object_get(G_OBJECT(t->settings),
384 "enable-scripts", &es, (char *)NULL);
385 if (args->i & XT_WL_TOGGLE)
386 es = !es;
387 else if ((args->i & XT_WL_ENABLE) && es != 1)
388 es = 1;
389 else if ((args->i & XT_WL_DISABLE) && es != 0)
390 es = 0;
391 else
392 return (1);
394 uri = get_uri(t);
395 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
397 if (uri == NULL || dom == NULL ||
398 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
399 show_oops(t, "Can't toggle domain in JavaScript white list");
400 goto done;
403 if (es) {
404 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PLAY);
405 wl_add(dom, &js_wl, 0 /* session */);
406 } else {
407 d = wl_find(dom, &js_wl);
408 if (d)
409 RB_REMOVE(domain_list, &js_wl, d);
410 button_set_stockid(t->js_toggle, GTK_STOCK_MEDIA_PAUSE);
412 g_object_set(G_OBJECT(t->settings),
413 "enable-scripts", es, (char *)NULL);
414 g_object_set(G_OBJECT(t->settings),
415 "javascript-can-open-windows-automatically", es, (char *)NULL);
416 webkit_web_view_set_settings(t->wv, t->settings);
418 if (args->i & XT_WL_RELOAD)
419 webkit_web_view_reload(t->wv);
420 done:
421 if (dom)
422 g_free(dom);
423 return (0);
427 toggle_pl(struct tab *t, struct karg *args)
429 int es;
430 const gchar *uri;
431 struct domain *d;
432 char *dom = NULL;
434 if (args == NULL)
435 return (1);
437 g_object_get(G_OBJECT(t->settings),
438 "enable-plugins", &es, (char *)NULL);
439 if (args->i & XT_WL_TOGGLE)
440 es = !es;
441 else if ((args->i & XT_WL_ENABLE) && es != 1)
442 es = 1;
443 else if ((args->i & XT_WL_DISABLE) && es != 0)
444 es = 0;
445 else
446 return (1);
448 uri = get_uri(t);
449 dom = find_domain(uri, args->i & XT_WL_TOPLEVEL);
451 if (uri == NULL || dom == NULL ||
452 webkit_web_view_get_load_status(t->wv) == WEBKIT_LOAD_FAILED) {
453 show_oops(t, "Can't toggle domain in plugins white list");
454 goto done;
457 if (es)
458 wl_add(dom, &pl_wl, 0 /* session */);
459 else {
460 d = wl_find(dom, &pl_wl);
461 if (d)
462 RB_REMOVE(domain_list, &pl_wl, d);
464 g_object_set(G_OBJECT(t->settings),
465 "enable-plugins", es, (char *)NULL);
466 webkit_web_view_set_settings(t->wv, t->settings);
468 if (args->i & XT_WL_RELOAD)
469 webkit_web_view_reload(t->wv);
470 done:
471 if (dom)
472 g_free(dom);
473 return (0);