SHARE
TWEET

HTTPS Everywhere 2013.8.16 loop fix

a guest Aug 17th, 2013 53 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function Rule(from, to) {
  2.   //this.from = from;
  3.   this.to = to;
  4.   this.from_c = new RegExp(from);
  5. }
  6.  
  7. function Exclusion(pattern) {
  8.   //this.pattern = pattern;
  9.   this.pattern_c = new RegExp(pattern);
  10. }
  11.  
  12. function CookieRule(host, cookiename) {
  13.   this.host = host
  14.   this.host_c = new RegExp(host);
  15.   this.name = cookiename;
  16.   this.name_c = new RegExp(cookiename);
  17. }
  18.  
  19. function RuleSet(set_name, match_rule, default_state, note) {
  20.   this.name = set_name;
  21.   if (match_rule)
  22.     this.ruleset_match_c = new RegExp(match_rule);
  23.   else
  24.     this.ruleset_match_c = null;
  25.   this.rules = [];
  26.   this.exclusions = [];
  27.   this.targets = [];
  28.   this.cookierules = [];
  29.   this.active = default_state;
  30.   this.default_state = default_state;
  31.   this.note = note;
  32. }
  33.  
  34. RuleSet.prototype = {
  35.   apply: function(urispec) {
  36.     var returl = null;
  37.     // If a rulset has a match_rule and it fails, go no further
  38.     if (this.ruleset_match_c && !this.ruleset_match_c.test(urispec)) {
  39.       log(VERB, "ruleset_match_c excluded " + urispec);
  40.       return null;
  41.     }
  42.     // Even so, if we're covered by an exclusion, go home
  43.     for(var i = 0; i < this.exclusions.length; ++i) {
  44.       if (this.exclusions[i].pattern_c.test(urispec)) {
  45.         log(DBUG,"excluded uri " + urispec);
  46.         return null;
  47.       }
  48.     }
  49.     // Okay, now find the first rule that triggers
  50.     for(var i = 0; i < this.rules.length; ++i) {
  51.       returl = urispec.replace(this.rules[i].from_c,
  52.                                this.rules[i].to);
  53.       if (returl != urispec) {
  54.         return returl;
  55.       }
  56.     }
  57.     if (this.ruleset_match_c) {
  58.       // This is not an error, because we do not insist the matchrule
  59.       // precisely describes to target space of URLs ot redirected
  60.       log(DBUG,"Ruleset "+this.name
  61.               +" had an applicable match-rule but no matching rules");
  62.     }
  63.     return null;
  64.   },
  65.  
  66. };
  67.  
  68.  
  69. function RuleSets() {
  70.   // Load rules into structure
  71.   this.targets = {};
  72.  
  73.   for(var i = 0; i < rule_list.length; i++) {
  74.     var xhr = new XMLHttpRequest();
  75.     // Use blocking XHR to ensure everything is loaded by the time
  76.     // we return.
  77.     //var that = this;
  78.     //xhr.onreadystatechange = function() { that.loadRuleSet(xhr); }
  79.     xhr.open("GET", chrome.extension.getURL(rule_list[i]), false);
  80.     //xhr.open("GET", chrome.extension.getURL(rule_list[i]), true);
  81.     xhr.send(null);
  82.     this.loadRuleSet(xhr);
  83.   }
  84.   this.global_rulesets = this.targets["*"] ? this.targets["*"] : [];
  85. }
  86.  
  87. RuleSets.prototype = {
  88.   localPlatformRegexp: new RegExp("chromium"),
  89.  
  90.   loadRuleSet: function(xhr) {
  91.     // Get file contents
  92.     if (xhr.readyState != 4) {
  93.       return;
  94.     }
  95.  
  96.     // XXX: Validation + error checking
  97.     var sets = xhr.responseXML.getElementsByTagName("ruleset");
  98.     for (var i = 0; i < sets.length; ++i) {
  99.       this.parseOneRuleset(sets[i]);
  100.     }
  101.   },
  102.   parseOneRuleset: function(ruletag) {
  103.     var default_state = true;
  104.     var note = "";
  105.     if (ruletag.attributes.default_off) {
  106.       default_state = false;
  107.       note += ruletag.attributes.default_off.value + "\n";
  108.     }
  109.  
  110.     // If a ruleset declares a platform, and we don't match it, treat it as
  111.     // off-by-default
  112.     var platform = ruletag.getAttribute("platform");
  113.     if (platform) {
  114.       if (platform.search(this.localPlatformRegexp) == -1) {
  115.         default_state = false;
  116.       }
  117.       note += "Platform(s): " + platform + "\n";
  118.     }
  119.  
  120.     var rule_set = new RuleSet(ruletag.getAttribute("name"),
  121.                                ruletag.getAttribute("match_rule"),
  122.                                default_state,
  123.                                note.trim());
  124.  
  125.     // Read user prefs
  126.     if (rule_set.name in localStorage) {
  127.       rule_set.active = (localStorage[rule_set.name] == "true");
  128.     }
  129.  
  130.     var rules = ruletag.getElementsByTagName("rule");
  131.     for(var j = 0; j < rules.length; j++) {
  132.       rule_set.rules.push(new Rule(rules[j].getAttribute("from"),
  133.                                     rules[j].getAttribute("to")));
  134.     }
  135.  
  136.     var exclusions = ruletag.getElementsByTagName("exclusion");
  137.     for(var j = 0; j < exclusions.length; j++) {
  138.       rule_set.exclusions.push(
  139.             new Exclusion(exclusions[j].getAttribute("pattern")));
  140.     }
  141.  
  142.     var cookierules = ruletag.getElementsByTagName("securecookie");
  143.     for(var j = 0; j < cookierules.length; j++) {
  144.       rule_set.cookierules.push(new CookieRule(cookierules[j].getAttribute("host"),
  145.                                            cookierules[j].getAttribute("name")));
  146.     }
  147.  
  148.     var targets = ruletag.getElementsByTagName("target");
  149.     for(var j = 0; j < targets.length; j++) {
  150.        var host = targets[j].getAttribute("host");
  151.        if (!(host in this.targets)) {
  152.          this.targets[host] = [];
  153.        }
  154.        this.targets[host].push(rule_set);
  155.     }
  156.   },
  157.  
  158.   potentiallyApplicableRulesets: function(host) {
  159.     // Return a list of rulesets that apply to this host
  160.     var i, tmp, t;
  161.     var results = this.global_rulesets;
  162.     if (this.targets[host])
  163.       results = results.concat(this.targets[host]);
  164.     // replace each portion of the domain with a * in turn
  165.     var segmented = host.split(".");
  166.     for (var i = 0; i < segmented.length; ++i) {
  167.       tmp = segmented[i];
  168.       segmented[i] = "*";
  169.       t = segmented.join(".");
  170.       segmented[i] = tmp;
  171.       if (this.targets[t])
  172.         results = results.concat(this.targets[t]);
  173.     }
  174.     // now eat away from the left, with *, so that for x.y.z.google.com we
  175.     // check *.z.google.com and *.google.com (we did *.y.z.google.com above)
  176.     for (var i = 1; i <= segmented.length - 2; ++i) {
  177.       t = "*." + segmented.slice(i,segmented.length).join(".");
  178.       if (this.targets[t])
  179.         results = results.concat(this.targets[t]);
  180.     }
  181.     log(DBUG,"Applicable rules for " + host + ":");
  182.     if (results.length == 0)
  183.       log(DBUG, "  None");
  184.     else
  185.       for (var i = 0; i < results.length; ++i)
  186.         log(DBUG, "  " + results[i].name);
  187.     return results;
  188.   },
  189.  
  190.   shouldSecureCookie: function(cookie, knownHttps) {
  191.     // Check to see if the Cookie object c meets any of our cookierule citeria
  192.     // for being marked as secure.  knownHttps is true if the context for this
  193.     // cookie being set is known to be https.
  194.     //log(DBUG, "Testing cookie:");
  195.     //log(DBUG, "  name: " + cookie.name);
  196.     //log(DBUG, "  host: " + cookie.host);
  197.     //log(DBUG, "  domain: " + cookie.domain);
  198.     //log(DBUG, "  rawhost: " + cookie.rawHost);
  199.     var i,j;
  200.     var hostname = cookie.domain;
  201.     // cookie domain scopes can start with .
  202.     while (hostname.charAt(0) == ".")
  203.       hostname = hostname.slice(1);
  204.  
  205.     var rs = this.potentiallyApplicableRulesets(hostname);
  206.     for (var i = 0; i < rs.length; ++i) {
  207.       var ruleset = rs[i];
  208.       if (ruleset.active) {
  209.         if (!knownHttps && !this.safeToSecureCookie(hostname))
  210.           continue;
  211.         for (var j = 0; j < ruleset.cookierules.length; j++) {
  212.           var cr = ruleset.cookierules[j];
  213.           if (cr.host_c.test(cookie.domain) && cr.name_c.test(cookie.name)) {
  214.             return ruleset;
  215.           }
  216.           //log(WARN, "no match domain " + cr.host_c.test(cookie.domain) +
  217.           //          " name " + cr.name_c.test(cookie.name));
  218.           //log(WARN, "with " + cookie.domain + " " + cookie.name);
  219.           //log(WARN, "and " + cr.host + " " + cr.name);
  220.         }
  221.       }
  222.     }
  223.     return null;
  224.   },
  225.  
  226.   safeToSecureCookie: function(domain) {
  227.     // Check if the domain might be being served over HTTP.  If so, it isn't
  228.     // safe to secure a cookie!  We can't always know this for sure because
  229.     // observing cookie-changed doesn't give us enough context to know the
  230.     // full origin URI.
  231.  
  232.     // First, if there are any redirect loops on this domain, don't secure
  233.     // cookies.  XXX This is not a very satisfactory heuristic.  Sometimes we
  234.     // would want to secure the cookie anyway, because the URLs that loop are
  235.     // not authenticated or not important.  Also by the time the loop has been
  236.     // observed and the domain blacklisted, a cookie might already have been
  237.     // flagged as secure.
  238.  
  239.     if (domain in domainBlacklist) {
  240.       log(INFO, "cookies for " + domain + "blacklisted");
  241.       return false;
  242.     }
  243.  
  244.     // If we passed that test, make up a random URL on the domain, and see if
  245.     // we would HTTPSify that.
  246.  
  247.     try {
  248.       var nonce_path = "/" + Math.random().toString();
  249.       nonce_path = nonce_path + nonce_path;
  250.       var test_uri = "http://" + domain + nonce_path;
  251.     } catch (e) {
  252.       log(WARN, "explosion in safeToSecureCookie for " + domain + "\n"
  253.                       + "(" + e + ")");
  254.       return false;
  255.     }
  256.  
  257.     log(INFO, "Testing securecookie applicability with " + test_uri);
  258.     var rs = this.potentiallyApplicableRulesets(domain);
  259.     for (var i = 0; i < rs.length; ++i) {
  260.       if (!rs[i].active) continue;
  261.       var rewrite = rs[i].apply(test_uri);
  262.       if (rewrite) {
  263.         log(INFO, "Yes: " + rewrite);
  264.         return true;
  265.       }
  266.     }
  267.     log(INFO, "(NO)");
  268.     return false;
  269.   },
  270.  
  271.   rewriteURI: function(urispec, host) {
  272.     var i = 0;
  273.     var newuri = null
  274.     var rs = this.potentiallyApplicableRulesets(host);
  275.     for(i = 0; i < rs.length; ++i) {
  276.       if (rs[i].active && (newuri = rs[i].apply(urispec)))
  277.         return newuri;
  278.     }
  279.     return null;
  280.   },
  281. };
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top