RequestPolicy-like patch

[email protected]
Newsgroups gmane.comp.web.dillo.devel
Message-ID <20120808002657.GA15219@machine>
Patch implements functions similar to Firefox addon RequestPolicy. [1]
It allows user to control automatic requests more flexible than
filter_auto_requests option. Patch removes this option and replaces it
with file .dillo/domainrc that looks like this:

default deny
wikipedia.org .wikimedia.org
wikisource.org .wikimedia.org
wikitionary.org .wikimedia.org
wikiversity.org .wikimedia.org

That way most requests are denied, but images on wikipedia are loaded
from wikimedia.org without clicking on them.

Patterns can start with "." to allow subdomains.

Special pattern "*" can be used to allow requests to any domains from
some domain (for example if it is a website full of external images) or
to allow requests from any domain to some domain (maybe CDN).

Without domainrc file all cross-domain requests are denied.

[1] https://www.requestpolicy.com/

_______________________________________________
Dillo-dev mailing list
[email protected]
http://lists.auriga.wearlab.de/cgi-bin/mailman/listinfo/dillo-dev
requestpolicy.diff (text/plain, 9.5 KB)
diff -r d2083fbee8e5 dillorc
--- a/dillorc
+++ b/dillorc
@@ -26,13 +26,6 @@
 # (While browsing, this can be changed from the tools/settings menu.)
 #parse_embedded_css=YES
 
-# How should Dillo restrict automatic requests (e.g., redirections,
-# pages containing images or stylesheets)?
-# allow_all
-# same_domain : Permit www.example.org to load an image from img.example.org,
-#               but not from the unrelated ad.doubleclick.net.
-#filter_auto_requests=same_domain
-
 # Change the buffering scheme for drawing
 # 0 no double buffering - useful for debugging
 # 1 light buffering using a single back buffer for all windows
diff -r d2083fbee8e5 src/Makefile.am
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -68,8 +68,6 @@
 	timeout.hh \
 	dialog.cc \
 	dialog.hh \
-	\
-	\
 	web.cc \
 	web.hh \
 	nav.c \
@@ -82,6 +80,8 @@
 	dicache.h \
 	capi.c \
 	capi.h \
+	crossdomain.c \
+	crossdomain.h \
 	css.cc \
 	css.hh \
 	cssparser.cc \
diff -r d2083fbee8e5 src/cache.c
--- a/src/cache.c
+++ b/src/cache.c
@@ -29,7 +29,7 @@
 #include "capi.h"
 #include "decode.h"
 #include "auth.h"
-
+#include "crossdomain.h"
 #include "timeout.hh"
 #include "uicmd.hh"
 
@@ -679,8 +679,7 @@
          /* 30x: URL redirection */
          DilloUrl *location_url = a_Url_new(location_str,URL_STR_(entry->Url));
 
-         if (prefs.filter_auto_requests == PREFS_FILTER_SAME_DOMAIN &&
-             !a_Url_same_organization(entry->Url, location_url)) {
+         if (!a_Crossdomain_check(entry->Url, location_url)) {
             /* don't redirect; just show body like usual (if any) */
             MSG("Redirection not followed from %s to %s\n",
                 URL_HOST(entry->Url), URL_STR(location_url));
diff -r d2083fbee8e5 src/capi.c
--- a/src/capi.c
+++ b/src/capi.c
@@ -26,6 +26,7 @@
 #include "nav.h"
 #include "dpiapi.h"
 #include "uicmd.hh"
+#include "crossdomain.h"
 #include "../dpip/dpip.h"
 
 /* for testing dpi chat */
@@ -375,40 +376,10 @@
 static bool_t Capi_filters_test(const DilloUrl *wanted,
                                 const DilloUrl *requester)
 {
-   bool_t ret;
-
-   if (requester == NULL) {
+   if (requester == NULL)
       /* request made by user */
-      ret = TRUE;
-   } else {
-      switch (prefs.filter_auto_requests) {
-         case PREFS_FILTER_SAME_DOMAIN:
-         {
-            const char *req_host = URL_HOST(requester),
-                       *want_host = URL_HOST(wanted);
-            if (want_host[0] == '\0') {
-               ret = (req_host[0] == '\0' ||
-                      !dStrAsciiCasecmp(URL_SCHEME(wanted), "data"))
-                     ? TRUE : FALSE;
-            } else {
-               /* This will regard "www.dillo.org" and "www.dillo.org." as
-                * different, but it doesn't seem worth caring about.
-                */
-               ret = a_Url_same_organization(wanted, requester);
-            }
-            if (ret == FALSE) {
-               MSG("Capi_filters_test: deny from '%s' to '%s'\n", req_host,
-                   want_host);
-            }
-            break;
-         }
-         case PREFS_FILTER_ALLOW_ALL:
-         default:
-            ret = TRUE;
-            break;
-      }
-   }
-   return ret;
+      return TRUE;
+   return a_Crossdomain_check(requester, wanted);
 }
 
 /*
diff -r d2083fbee8e5 src/crossdomain.c
--- /dev/null
+++ b/src/crossdomain.c
@@ -0,0 +1,138 @@
+#include <stdlib.h>
+
+#include "d_size.h"
+#include "msg.h"
+#include "crossdomain.h"
+
+typedef struct Rule Rule;
+
+struct Rule {
+	char *origin;
+	char *destination;
+	Rule *next;
+};
+
+static Rule *rules;
+static bool_t defaultrule = FALSE;
+
+void a_Crossdomain_init(void)
+{
+   char *filename, *line, *tok1, *tok2, *saveptr;
+   const char *delim = " \t";
+   FILE *fp;
+   size_t len;
+   ssize_t read;
+   Rule *rule;
+
+   MSG("Reading domainrc\n");
+   filename = dStrconcat(dGethomedir(), "/.dillo/domainrc", NULL);
+   fp = fopen(filename, "r");
+   dFree(filename);
+   if (fp == NULL) {
+      /* TODO: some fallback */
+      MSG("No domainrc, deny all cross-domain requests\n");
+      return;
+   }
+
+   line = NULL;
+   len = 0;
+   while ((read = getline(&line, &len, fp)) != -1) {
+      dStrstrip(line);
+
+      /* Skip comments. */
+      if (line[0] == '#')
+         continue;
+
+      tok1 = strtok_r(line, delim, &saveptr);
+      if (tok1 == NULL)
+         continue; /* Skip empty line. */
+
+      tok2 = strtok_r(NULL, delim, &saveptr);
+      if (tok2 == NULL) {
+         MSG("expected two tokens, found one");
+	 continue;
+      }
+
+      if(strtok_r(NULL, delim, &saveptr) != NULL) {
+         MSG("extra tokens");
+         continue;
+      }
+
+      if (dStrAsciiCasecmp(tok1, "default") == 0) {
+	 if (dStrAsciiCasecmp(tok2, "allow") == 0)
+            defaultrule = TRUE;
+	 else if (dStrAsciiCasecmp(tok2, "deny") == 0)
+            defaultrule = FALSE;
+	 else
+            MSG("default rule '%s' is not recognized", tok2);
+      } else {
+         rule = dMalloc(sizeof *rule);
+	 rule->origin = dStrdup(tok1);
+	 rule->destination = dStrdup(tok2);
+	 rule->next = rules;
+	 rules = rule;
+      }
+   }
+   free(line);
+
+   fclose(fp);
+}
+
+void a_Crossdomain_freeall(void)
+{
+   Rule *next;
+
+   while(rules != NULL) {
+      next = rules->next;
+      dFree(rules);
+      rules = next;
+   }
+}
+
+static bool_t Crossdomain_domainmatch(const char *domain, const char *pattern) {
+   int diff;
+
+   if (dStrAsciiCasecmp(pattern, "*") == 0)
+      return TRUE;
+
+   if (pattern[0] != '.')
+      return dStrAsciiCasecmp(domain, pattern) == 0;
+
+   diff = strlen(domain) - strlen(pattern);
+
+   if (diff == -1)
+      return dStrAsciiCasecmp(domain, pattern + 1); /* example.com matches .example.com */
+
+   if (diff >= 0)
+      return dStrAsciiCasecmp(domain + diff, pattern) == 0;
+
+   return FALSE;
+}
+
+bool_t a_Crossdomain_check(const DilloUrl *source, const DilloUrl *destination)
+{
+
+   const char *source_host = URL_HOST(source),
+              *destination_host = URL_HOST(destination);
+   bool_t ret;
+   Rule *rule;
+
+   if (destination_host[0] == '\0')
+      return source_host[0] == '\0' || !dStrAsciiCasecmp(URL_SCHEME(destination), "data");
+
+   /* This will regard "www.dillo.org" and "www.dillo.org." as
+    * different, but it doesn't seem worth caring about.
+    */
+   if(a_Url_same_organization(source, destination))
+      return TRUE;
+
+   ret = defaultrule;
+   for(rule = rules; rule != NULL; rule = rule->next)
+      if(Crossdomain_domainmatch(source_host, rule->origin) &&
+         Crossdomain_domainmatch(destination_host, rule->destination))
+	 ret = !defaultrule;
+
+   if(!ret)
+      MSG("request from %s to %s is denied\n", source_host, destination_host);
+   return ret;
+}
diff -r d2083fbee8e5 src/crossdomain.h
--- /dev/null
+++ b/src/crossdomain.h
@@ -0,0 +1,16 @@
+#ifndef __CROSSDOMAIN_H__
+#define __CROSSDOMAIN_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void a_Crossdomain_init(void);
+void a_Crossdomain_freeall(void);
+bool_t a_Crossdomain_check(const DilloUrl *, const DilloUrl *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -r d2083fbee8e5 src/dillo.cc
--- a/src/dillo.cc
+++ b/src/dillo.cc
@@ -46,6 +46,7 @@
 #include "capi.h"
 #include "dicache.h"
 #include "cookies.h"
+#include "crossdomain.h"
 #include "auth.h"
 
 #include "dw/fltkcore.hh"
@@ -350,6 +351,7 @@
    a_Dicache_init();
    a_Bw_init();
    a_Cookies_init();
+   a_Crossdomain_init();
    a_Auth_init();
 
    /* command line options override preferences */
@@ -441,6 +443,7 @@
     * (This can be left to the OS, but we'll do it, with a view to test
     *  and fix our memory management)
     */
+   a_Crossdomain_freeall();
    a_Cookies_freeall();
    a_Cache_freeall();
    a_Dicache_freeall();
diff -r d2083fbee8e5 src/prefs.c
--- a/src/prefs.c
+++ b/src/prefs.c
@@ -41,7 +41,6 @@
    prefs.buffered_drawing = 1;
    prefs.contrast_visited_color = TRUE;
    prefs.enterpress_forces_submit = FALSE;
-   prefs.filter_auto_requests = PREFS_FILTER_SAME_DOMAIN;
    prefs.focus_new_tab = TRUE;
    prefs.font_cursive = dStrdup(PREFS_FONT_CURSIVE);
    prefs.font_factor = 1.0;
diff -r d2083fbee8e5 src/prefs.h
--- a/src/prefs.h
+++ b/src/prefs.h
@@ -77,7 +77,6 @@
    bool_t load_images;
    bool_t load_stylesheets;
    bool_t parse_embedded_css;
-   int filter_auto_requests;
    int32_t buffered_drawing;
    char *font_serif;
    char *font_sans_serif;
diff -r d2083fbee8e5 src/prefsparser.cc
--- a/src/prefsparser.cc
+++ b/src/prefsparser.cc
@@ -29,7 +29,6 @@
    PREFS_INT32,
    PREFS_DOUBLE,
    PREFS_GEOMETRY,
-   PREFS_FILTER,
    PREFS_PANEL_SIZE
 } PrefType_t;
 
@@ -56,7 +55,6 @@
       { "contrast_visited_color", &prefs.contrast_visited_color, PREFS_BOOL },
       { "enterpress_forces_submit", &prefs.enterpress_forces_submit,
         PREFS_BOOL },
-      { "filter_auto_requests", &prefs.filter_auto_requests, PREFS_FILTER },
       { "focus_new_tab", &prefs.focus_new_tab, PREFS_BOOL },
       { "font_cursive", &prefs.font_cursive, PREFS_STRING },
       { "font_factor", &prefs.font_factor, PREFS_DOUBLE },
@@ -166,15 +164,6 @@
       a_Misc_parse_geometry(value, &prefs.xpos, &prefs.ypos,
                             &prefs.width, &prefs.height);
       break;
-   case PREFS_FILTER:
-      if (!dStrAsciiCasecmp(value, "same_domain"))
-         prefs.filter_auto_requests = PREFS_FILTER_SAME_DOMAIN;
-      else {
-         if (dStrAsciiCasecmp(value, "allow_all"))
-            MSG_WARN("prefs: unrecognized value for filter_auto_requests\n");
-         prefs.filter_auto_requests = PREFS_FILTER_ALLOW_ALL;
-      }
-      break;
    case PREFS_PANEL_SIZE:
       if (!dStrAsciiCasecmp(value, "tiny"))
          prefs.panel_size = P_tiny;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.