diff options
Diffstat (limited to 'data/extensions/https-everywhere@eff.org/chrome/content')
31 files changed, 6323 insertions, 0 deletions
diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/about.xul b/data/extensions/https-everywhere@eff.org/chrome/content/about.xul new file mode 100644 index 0000000..cf57e9d --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/about.xul @@ -0,0 +1,72 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="chrome://https-everywhere/content/preferences.css" type="text/css"?> + +<!DOCTYPE overlay SYSTEM "chrome://https-everywhere/locale/https-everywhere.dtd"> + +<dialog id="https-everywhere-about" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + buttons="accept" + title="&https-everywhere.about.title;" + width="640" + height="480" + align="center"> + + <script type="application/x-javascript" + src="chrome://https-everywhere/content/preferences.js"/> + <vbox style="overflow:auto" flex="1"> + <label style="text-align:center; font-weight:bold; font-size:22px;">&https-everywhere.about.ext_name;</label> + <label style="text-align:center; font-size:18px; margin-bottom:10px;">&https-everywhere.about.ext_description;</label> + + <groupbox> + <caption label="&https-everywhere.about.version;" /> + <label>3.5.1</label> + </groupbox> + + <groupbox> + <caption label="&https-everywhere.about.created_by;" /> + <label>Mike Perry and Peter Eckersley</label> + </groupbox> + + <groupbox> + <caption label="&https-everywhere.about.librarians;" /> + <label>Seth Schoen, MB and Andreas Jonsson</label> + </groupbox> + + <groupbox> + <caption label="&https-everywhere.about.thanks;" /> + <label>Many many contributors, including Aaron Swartz, Alec Moskvin, + Aleksey Kosterin, Alex Xu, Anas Qtiesh, Artyom Gavrichenkov, Brian + Carpenter, Chris Palmer, Christian Inci, Christopher Liu, Claudio + Moretti, Colonel Graff, Dan Auerbach, Daniel Kahn Gillmor, dm0, The + Doctor, Felix Geyer, Fruitless Creek, George Kargiotakis, haviah, Heiko + Adams, Jeroen van der Gun, Jay Weisskopf, Jacob Taylor, Jonathan Davies, Jorge Bernal, + katmagic, Kevin Jacobs, Korte, Liam K, Leonardo Brondani Schenkel, Marti Raudsepp, Micah Lee, Mike + Cardwell, Mangix, Matthias-Christian Ott, Mikko Harhanen, Mishari Muqbil, Neheb, Ori Avtalion, Osama Khalid, + nitrox, Pablo Castellano, Paul Wise, Pavel Kazakov, Phol Paucar, Richard + Green, Roan Kattouw, Rules Moore, Stefan Tomanek, Sam Reed, Steve + Milner, Sujit Rao, TK-999, Vendo, Victor Garin, Weiland Hoffmann, Whizz + Mo and Yan Zhu. Also, portions of HTTPS Everywhere are based on code + from NoScript, by Giorgio Maone and others. We are grateful for their + excellent work!</label> + </groupbox> + + <label style="font-weight:bold; margin-top:10px;"> + &https-everywhere.about.contribute; + <label id="donate link" + value="&https-everywhere.about.donate_tor;" + style="color: blue; cursor:hand; text-decoration:underline; font-style:bold" + onmouseover="event.target.style.cursor='pointer'" + onmouseout="event.target.style.cursor='default'" + onclick="window_opener('https://www.torproject.org/donate/donate.html.en')"/> + or + <label id="donate link2" + value="&https-everywhere.about.donate_eff;" + style="color: blue; cursor:hand; text-decoration:underline; font-style:bold" + onmouseover="event.target.style.cursor='pointer'" + onmouseout="event.target.style.cursor='default'" + onclick="window_opener('https://www.eff.org/donate')"/> + </label> + </vbox> +</dialog> diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/ApplicableList.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/ApplicableList.js new file mode 100644 index 0000000..6949167 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/ApplicableList.js @@ -0,0 +1,266 @@ +// An ApplicableList is a structure used to keep track of which rulesets +// were applied, and which ones weren't but might have been, to the contents +// of a given page (top level nsIDOMWindow) + +serial_number = 0; + +function ApplicableList(logger, doc, domWin) { + this.domWin = domWin; + this.uri = doc.baseURIObject.clone(); + if (!this.uri) { + this.log(WARN,"NULL CLONING URI " + doc); + if (doc) + this.log(WARN,"NULL CLONING URI " + doc.baseURIObject); + if (doc.baseURIObject) + this.log(WARN,"NULL CLONING URI " + doc.baseURIObject.spec); + } + this.home = doc.baseURIObject.spec; // what doc we're housekeeping for + this.log = logger; + this.active = {}; + this.breaking = {}; // rulesets with redirection loops + this.inactive = {}; + this.moot={}; // rulesets that might be applicable but uris are already https + this.all={}; // active + breaking + inactive + moot + serial_number += 1; + this.serial = serial_number; + this.log(DBUG,"Alist serial #" + this.serial + " for " + this.home); +} + +ApplicableList.prototype = { + + empty: function() { + // Empty everything, used when toggles occur in order to ensure that if + // the reload fails, the resulting list is not eroneous + this.active = {}; + this.breaking = {}; + this.inactive = {}; + this.moot={}; + this.all={}; + }, + + active_rule: function(ruleset) { + this.log(INFO,"active rule " + ruleset.name +" in "+ this.home +" -> " + + this.domWin.document.baseURIObject.spec+ " serial " + this.serial); + this.active[ruleset.name] = ruleset; + this.all[ruleset.name] = ruleset; + }, + + breaking_rule: function(ruleset) { + this.log(NOTE,"breaking rule " + ruleset.name +" in "+ this.home +" -> " + + this.domWin.document.baseURIObject.spec+ " serial " + this.serial); + this.breaking[ruleset.name] = ruleset; + this.all[ruleset.name] = ruleset; + }, + + inactive_rule: function(ruleset) { + + this.log(INFO,"inactive rule " + ruleset.name +" in "+ this.home +" -> " + + this.domWin.document.baseURIObject.spec+ " serial " + this.serial); + this.inactive[ruleset.name] = ruleset; + this.all[ruleset.name] = ruleset; + }, + + moot_rule: function(ruleset) { + this.log(INFO,"moot rule " + ruleset.name +" in "+ this.home + " serial " + this.serial); + this.moot[ruleset.name] = ruleset; + this.all[ruleset.name] = ruleset; + }, + + dom_handler: function(operation,key,data,src,dst) { + // See https://developer.mozilla.org/En/DOM/UserDataHandler + if (src && dst) + dst.setUserData(key, data, this.dom_handler); + }, + + populate_list: function() { + // The base URI of the dom tends to be loaded from some /other/ + // ApplicableList, so pretend we're loading it from here. + HTTPSEverywhere.instance.https_rules.rewrittenURI(this, this.uri); + this.log(DBUG, "populating using alist #" + this.serial); + }, + + populate_menu: function(document, menupopup, weird) { + this.populate_list(); + this.document = document; + + var https_everywhere = CC["@eff.org/https-everywhere;1"].getService(Components.interfaces.nsISupports).wrappedJSObject; + + // get the menu popup + this.menupopup = menupopup; + + // empty it all of its menuitems + while(this.menupopup.firstChild.tagName != "menuseparator") { + this.menupopup.removeChild(this.menupopup.firstChild); + } + + // add global enable/disable toggle button + var strings = document.getElementById("HttpsEverywhereStrings"); + + var enableLabel = document.createElement('menuitem'); + var text = strings.getString("https-everywhere.menu.globalDisable"); + if(!https_everywhere.prefs.getBoolPref("globalEnabled")) + text = strings.getString("https-everywhere.menu.globalEnable"); + + enableLabel.setAttribute('label', text); + enableLabel.setAttribute('command', 'https-everywhere-menuitem-globalEnableToggle'); + this.prepend_child(enableLabel); + + // add the label at the top + var any_rules = false; + for(var x in this.all) { + any_rules = true; // how did JavaScript get this ugly? + break; + } + var label = document.createElement('menuitem'); + label.setAttribute('label', strings.getString('https-everywhere.menu.enableDisable')); + label.setAttribute('command', 'https-everywhere-menuitem-preferences'); + var label2 = false; + if (!any_rules) { + label2 = document.createElement('menuitem'); + if (!weird) text = strings.getString('https-everywhere.menu.noRules'); + else text = strings.getString('https-everywhere.menu.unknownRules'); + label2.setAttribute('label', text); + label2.setAttribute('command', 'https-everywhere-menuitem-preferences'); + label2.setAttribute('style', 'color:#909090;'); + } + + // create a commandset if it doesn't already exist + this.commandset = document.getElementById('https-everywhere-commandset'); + if(!this.commandset) { + this.commandset = document.createElement('commandset'); + this.commandset.setAttribute('id', 'https-everywhere-commandset'); + var win = document.getElementById('main-window'); + win.appendChild(this.commandset); + } else { + // empty commandset + while(this.commandset.firstChild) + this.commandset.removeChild(this.commandset.firstChild); + } + + var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] + .getService(Components.interfaces.nsIWindowMediator); + + var domWin = wm.getMostRecentWindow("navigator:browser").content.document.defaultView.top; + var location = domWin.document.baseURIObject.asciiSpec; //full url, including about:certerror details + + if(location.substr(0, 6) == "about:"){ + //"From" portion of the rule is retrieved from the location bar via document.getElementById("urlbar").value + + var fromHost = document.getElementById("urlbar").value; + + //scheme must be trimmed out to check for applicable rulesets + if(fromHost.indexOf("://") != -1) + fromHost = fromHost.substr(fromHost.indexOf("://") + 3, fromHost.length); + + //trim off any page locations - we only want the host - e.g. domain.com + if(fromHost.indexOf("/") != -1) + fromHost = fromHost.substr(0, fromHost.indexOf("/")); + + // Search for applicable rulesets for the host listed in the location bar + var plist = HTTPSRules.potentiallyApplicableRulesets(fromHost); + for (var i = 0 ; i < plist.length ; i++){ + //For each applicable rulset, determine active/inactive, and append to proper list. + var ruleOn = false; + try { + if(https_everywhere.rule_toggle_prefs.getBoolPref(plist[i].name)) + ruleOn = true; + } catch(e) { + if(https_everywhere.https_rules.rulesetsByName[plist[i].name].active) + ruleOn = true; + } + if(ruleOn) + this.active_rule(plist[i]); + else + this.inactive_rule(plist[i]); + } + } + + // add all applicable commands + for(var x in this.breaking) + this.add_command(this.breaking[x]); + for(var x in this.active) + this.add_command(this.active[x]); + for(var x in this.moot) + this.add_command(this.moot[x]); + for(var x in this.inactive) + this.add_command(this.inactive[x]); + + if(https_everywhere.prefs.getBoolPref("globalEnabled")){ + // add all the menu items + for (var x in this.inactive) + this.add_menuitem(this.inactive[x], 'inactive'); + // rules that are active for some uris are not really moot + for (var x in this.moot) + if (!(x in this.active)) + this.add_menuitem(this.moot[x], 'moot'); + // break once break everywhere + for (var x in this.active) + if (!(x in this.breaking)) + this.add_menuitem(this.active[x], 'active'); + for (var x in this.breaking) + this.add_menuitem(this.breaking[x], 'breaking'); + + if (label2) this.prepend_child(label2); + this.prepend_child(label); + } + + }, + + prepend_child: function(node) { + this.menupopup.insertBefore(node, this.menupopup.firstChild); + }, + + add_command: function(rule) { + var command = this.document.createElement("command"); + command.setAttribute('id', rule.id+'-command'); + command.setAttribute('label', rule.name); + command.setAttribute('oncommand', 'toggle_rule("'+rule.id+'")'); + this.commandset.appendChild(command); + }, + + // add a menu item for a rule -- type is "active", "inactive", "moot", + // or "breaking" + + add_menuitem: function(rule, type) { + // create the menuitem + var item = this.document.createElement('menuitem'); + item.setAttribute('command', rule.id+'-command'); + item.setAttribute('class', type+'-item menuitem-iconic'); + item.setAttribute('label', rule.name); + + // we can get confused if rulesets have their state changed after the + // ApplicableList was constructed + if (!rule.active && (type == 'active' || type == 'moot')) + type = 'inactive'; + if (rule.active && type == 'inactive') + type = 'moot'; + + // set the icon + var image_src; + if (type == 'active') image_src = 'tick.png'; + else if (type == 'inactive') image_src = 'cross.png'; + else if (type == 'moot') image_src = 'tick-moot.png'; + else if (type == 'breaking') image_src = 'loop.png'; + item.setAttribute('image', 'chrome://https-everywhere/skin/'+image_src); + + // all done + this.prepend_child(item); + }, + + show_applicable: function() { + this.log(WARN, "Applicable list number " + this.serial); + for (var x in this.active) + this.log(WARN,"Active: " + this.active[x].name); + + for (var x in this.breaking) + this.log(WARN,"Breaking: " + this.breaking[x].name); + + for (x in this.inactive) + this.log(WARN,"Inactive: " + this.inactive[x].name); + + for (x in this.moot) + this.log(WARN,"Moot: " + this.moot[x].name); + + } +}; + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/ChannelReplacement.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/ChannelReplacement.js new file mode 100644 index 0000000..551bcab --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/ChannelReplacement.js @@ -0,0 +1,387 @@ +function CtxCapturingListener(tracingChannel, captureObserver) {
+ this.originalListener = tracingChannel.setNewListener(this);
+ this.captureObserver = captureObserver;
+}
+CtxCapturingListener.prototype = {
+ originalListener: null,
+ originalCtx: null,
+ onStartRequest: function(request, ctx) {
+ this.originalCtx = ctx;
+ if (this.captureObserver) {
+ this.captureObserver.observeCapture(request, this);
+ }
+ },
+ onDataAvailable: function(request, ctx, inputStream, offset, count) {},
+ onStopRequest: function(request, ctx, statusCode) {},
+ QueryInterface: xpcom_generateQI([Ci.nsIStreamListener])
+};
+
+function ChannelReplacement(chan, newURI, newMethod) {
+ return this._init(chan, newURI, newMethod);
+}
+
+ChannelReplacement.supported = "nsITraceableChannel" in Ci;
+
+ChannelReplacement.runWhenPending = function(channel, callback) {
+ if (channel.isPending()) {
+ callback();
+ return false;
+ } else {
+ new LoadGroupWrapper(channel, callback);
+ return true;
+ }
+};
+
+
+ChannelReplacement.prototype = {
+ listener: null,
+ context: null,
+ oldChannel: null,
+ channel: null,
+ window: null,
+ suspended: false,
+
+ get _unsupportedError() {
+ return new Error("Can't replace channels without nsITraceableChannel!");
+ },
+
+ get _classifierClass() {
+ delete this.__proto__._classifierClass;
+ return this.__proto__._classifierClass = Cc["@mozilla.org/channelclassifier"];
+ },
+
+ _autoHeadersRx: /^(?:Host|Cookie|Authorization)$|Cache|^If-/,
+ visitHeader: function(key, val) {
+ try {
+ // we skip authorization and cache-related fields which should be automatically set
+ if (!this._autoHeadersRx.test(key)) this.channel.setRequestHeader(key, val, false);
+ } catch (e) {
+ dump(e + "\n");
+ }
+ },
+
+ _init: function(chan, newURI, newMethod) {
+ if (!(ChannelReplacement.supported && chan instanceof Ci.nsITraceableChannel))
+ throw this._unsupportedError;
+
+ newURI = newURI || chan.URI;
+
+ var newChan = IOS.newChannelFromURI(newURI);
+
+ this.oldChannel = chan;
+ this.channel = newChan;
+
+ // porting of http://mxr.mozilla.org/mozilla-central/source/netwerk/protocol/http/src/nsHttpChannel.cpp#2750
+
+ var loadFlags = chan.loadFlags;
+
+ if (chan.URI.schemeIs("https"))
+ loadFlags &= ~chan.INHIBIT_PERSISTENT_CACHING;
+
+
+ newChan.loadGroup = chan.loadGroup;
+ newChan.notificationCallbacks = chan.notificationCallbacks;
+ newChan.loadFlags = loadFlags | newChan.LOAD_REPLACE;
+ + if (!(newChan instanceof Ci.nsIHttpChannel))
+ return this;
+
+ // copy headers
+ chan.visitRequestHeaders(this);
+
+ if (!newMethod || newMethod === chan.requestMethod) {
+ if (newChan instanceof Ci.nsIUploadChannel && chan instanceof Ci.nsIUploadChannel && chan.uploadStream ) {
+ var stream = chan.uploadStream;
+ if (stream instanceof Ci.nsISeekableStream) {
+ stream.seek(stream.NS_SEEK_SET, 0);
+ }
+
+ try {
+ let ctype = chan.getRequestHeader("Content-type");
+ let clen = chan.getRequestHeader("Content-length");
+ if (ctype && clen) {
+ newChan.setUploadStream(stream, ctype, parseInt(clen, 10));
+ }
+ } catch(e) {
+ newChan.setUploadStream(stream, '', -1);
+ }
+
+ newChan.requestMethod = chan.requestMethod;
+ }
+ } else {
+ newChan.requestMethod = newMethod;
+ }
+
+ if (chan.referrer) newChan.referrer = chan.referrer;
+ newChan.allowPipelining = chan.allowPipelining;
+ newChan.redirectionLimit = chan.redirectionLimit - 1;
+ if (chan instanceof Ci.nsIHttpChannelInternal && newChan instanceof Ci.nsIHttpChannelInternal) {
+ if (chan.URI == chan.documentURI) {
+ newChan.documentURI = newURI;
+ } else {
+ newChan.documentURI = chan.documentURI;
+ }
+ }
+
+ if (chan instanceof Ci.nsIEncodedChannel && newChan instanceof Ci.nsIEncodedChannel) {
+ newChan.applyConversion = chan.applyConversion;
+ }
+
+ // we can't transfer resume information because we can't access mStartPos and mEntityID :(
+ // http://mxr.mozilla.org/mozilla-central/source/netwerk/protocol/http/src/nsHttpChannel.cpp#2826
+
+ if ("nsIApplicationCacheChannel" in Ci &&
+ chan instanceof Ci.nsIApplicationCacheChannel && newChan instanceof Ci.nsIApplicationCacheChannel) {
+ newChan.applicationCache = chan.applicationCache;
+ newChan.inheritApplicationCache = chan.inheritApplicationCache;
+ }
+
+ if (chan instanceof Ci.nsIPropertyBag && newChan instanceof Ci.nsIWritablePropertyBag)
+ for (var properties = chan.enumerator, p; properties.hasMoreElements();)
+ if ((p = properties.getNext()) instanceof Ci.nsIProperty)
+ newChan.setProperty(p.name, p.value);
+
+ if (chan.loadFlags & chan.LOAD_DOCUMENT_URI) {
+ this.window = IOUtil.findWindow(chan);
+ if (this.window) this.window._replacedChannel = chan;
+ }
+
+ return this;
+ },
+
+ _onChannelRedirect: function() {
+ var oldChan = this.oldChannel;
+ var newChan = this.channel;
+
+ if (this.realRedirect) {
+ if (oldChan.redirectionLimit === 0) {
+ oldChan.cancel(NS_ERROR_REDIRECT_LOOP);
+ throw NS_ERROR_REDIRECT_LOOP;
+ }
+ } else newChan.redirectionLimit += 1;
+
+
+
+ // nsHttpHandler::OnChannelRedirect()
+
+ const CES = Ci.nsIChannelEventSink;
+ const flags = CES.REDIRECT_INTERNAL;
+ this._callSink(
+ Cc["@mozilla.org/netwerk/global-channel-event-sink;1"].getService(CES),
+ oldChan, newChan, flags);
+ var sink;
+
+ for (let cess = Cc['@mozilla.org/categorymanager;1'].getService(CI.nsICategoryManager)
+ .enumerateCategory("net-channel-event-sinks");
+ cess.hasMoreElements();
+ ) {
+ sink = cess.getNext();
+ if (sink instanceof CES)
+ this._callSink(sink, oldChan, newChan, flags);
+ }
+ sink = IOUtil.queryNotificationCallbacks(oldChan, CES);
+ if (sink) this._callSink(sink, oldChan, newChan, flags);
+
+ // ----------------------------------
+
+ newChan.originalURI = oldChan.originalURI;
+
+ sink = IOUtil.queryNotificationCallbacks(oldChan, Ci.nsIHttpEventSink);
+ if (sink) sink.onRedirect(oldChan, newChan);
+ },
+
+ _callSink: function(sink, oldChan, newChan, flags) {
+ try {
+ if ("onChannelRedirect" in sink) sink.onChannelRedirect(oldChan, newChan, flags);
+ else sink.asyncOnChannelRedirect(oldChan, newChan, flags, this._redirectCallback);
+ } catch(e) {
+ if (e.toString().indexOf("(NS_ERROR_DOM_BAD_URI)") !== -1 && oldChan.URI.spec !== newChan.URI.spec) {
+ let oldURL = oldChan.URI.spec;
+ try {
+ oldChan.URI.spec = newChan.URI.spec;
+ this._callSink(sink, oldChan, newChan, flags);
+ } catch(e1) {
+ throw e;
+ } finally {
+ oldChan.URI.spec = oldURL;
+ }
+ } else if (e.message.indexOf("(NS_ERROR_NOT_AVAILABLE)") === -1) throw e;
+ }
+ },
+
+ _redirectCallback: ("nsIAsyncVerifyRedirectCallback" in Ci)
+ ? {
+ QueryInterface: xpcom_generateQI([Ci.nsIAsyncVerifyRedirectCallback]),
+ onRedirectVerifyCallback: function(result) {}
+ }
+ : null
+ ,
+
+ replace: function(realRedirect, callback) {
+ let self = this;
+ let oldChan = this.oldChannel;
+ this.realRedirect = !!realRedirect;
+ if (typeof(callback) !== "function") {
+ callback = this._defaultCallback;
+ }
+ ChannelReplacement.runWhenPending(oldChan, function() {
+ if (oldChan.status) return; // channel's doom had been already defined
+
+ let ccl = new CtxCapturingListener(oldChan, self);
+ self.loadGroup = oldChan.loadGroup;
+
+ oldChan.loadGroup = null; // prevents the wheel from stopping spinning
+
+
+ if (self._redirectCallback) { // Gecko >= 2
+ // this calls asyncAbort, which calls onStartRequest on our listener
+ oldChan.cancel(NS_BINDING_REDIRECTED);
+ self.suspend(); // believe it or not, this will defer asyncAbort() notifications until resume()
+ callback(self);
+ } else {
+ // legacy (Gecko < 2)
+ self.observeCapture = function(req, ccl) {
+ self.open = function() { self._redirect(ccl); };
+ callback(self);
+ };
+ oldChan.cancel(NS_BINDING_REDIRECTED);
+ }
+
+
+ });
+ },
+
+ observeCapture: function(req, ccl) {
+ this._redirect(ccl);
+ },
+
+ _defaultCallback: function(replacement) {
+ replacement.open();
+ },
+
+ open: function() {
+ this.resume(); // this triggers asyncAbort and the listeners in cascade
+ },
+ _redirect: function(ccl) {
+ let oldChan = this.oldChannel,
+ newChan = this.channel,
+ overlap;
+
+ if (!(this.window && (overlap = this.window._replacedChannel) !== oldChan)) {
+ try {
+ if (ABE.consoleDump && this.window) {
+ ABE.log("Opening delayed channel: " + oldChan.name + " - (current loading channel for this window " + (overlap && overlap.name) + ")");
+ }
+
+ oldChan.loadGroup = this.loadGroup;
+
+ this._onChannelRedirect();
+ newChan.asyncOpen(ccl.originalListener, ccl.originalCtx);
+
+ if (this.window && this.window != IOUtil.findWindow(newChan)) {
+ // late diverted load, unwanted artifact, abort
+ IOUtil.abort(newChan);
+ } else {
+ // safe browsing hook
+ if (this._classifierClass)
+ this._classifierClass.createInstance(Ci.nsIChannelClassifier).start(newChan, true);
+ }
+ } catch (e) {
+ ABE.log(e);
+ }
+ } else {
+ if (ABE.consoleDump) {
+ ABE.log("Detected double load on the same window: " + oldChan.name + " - " + (overlap && overlap.name));
+ }
+ }
+
+ this.dispose();
+ },
+
+ suspend: function() {
+ if (!this.suspended) {
+ this.oldChannel.suspend();
+ this.suspended = true;
+ }
+ },
+ resume: function() {
+ if (this.suspended) {
+ this.suspended = false;
+ try {
+ this.oldChannel.resume();
+ } catch (e) {}
+ }
+ },
+
+ dispose: function() {
+ this.resume();
+ if (this.loadGroup) {
+ try {
+ this.loadGroup.removeRequest(this.oldChannel, null, NS_BINDING_REDIRECTED);
+ } catch (e) {}
+ this.loadGroup = null;
+ }
+
+ }
+};
+
+function LoadGroupWrapper(channel, callback) {
+ this._channel = channel;
+ this._inner = channel.loadGroup;
+ this._callback = callback;
+ channel.loadGroup = this;
+}
+LoadGroupWrapper.prototype = {
+ QueryInterface: xpcom_generateQI([Ci.nsILoadGroup]),
+
+ get activeCount() {
+ return this._inner ? this._inner.activeCount : 0;
+ },
+ set defaultLoadRequest(v) {
+ return this._inner ? this._inner.defaultLoadRequest = v : v;
+ },
+ get defaultLoadRequest() {
+ return this._inner ? this._inner.defaultLoadRequest : null;
+ },
+ set groupObserver(v) {
+ return this._inner ? this._inner.groupObserver = v : v;
+ },
+ get groupObserver() {
+ return this._inner ? this._inner.groupObserver : null;
+ },
+ set notificationCallbacks(v) {
+ return this._inner ? this._inner.notificationCallbacks = v : v;
+ },
+ get notificationCallbacks() {
+ return this._inner ? this._inner.notificationCallbacks : null;
+ },
+ get requests() {
+ return this._inner ? this._inner.requests : this._emptyEnum;
+ },
+
+ addRequest: function(r, ctx) {
+ this.detach();
+ if (this._inner) try {
+ this._inner.addRequest(r, ctx);
+ } catch(e) {
+ // addRequest may have not been implemented
+ }
+ if (r === this._channel)
+ try {
+ this._callback(r, ctx);
+ } catch (e) {}
+ },
+ removeRequest: function(r, ctx, status) {
+ this.detach();
+ if (this._inner) this._inner.removeRequest(r, ctx, status);
+ },
+
+ detach: function() {
+ if (this._channel.loadGroup) this._channel.loadGroup = this._inner;
+ },
+ _emptyEnum: {
+ QueryInterface: xpcom_generateQI([Ci.nsISimpleEnumerator]),
+ getNext: function() { return null; },
+ hasMoreElements: function() { return false; }
+ }
+};
diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/Cookie.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/Cookie.js new file mode 100644 index 0000000..9afe0a8 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/Cookie.js @@ -0,0 +1,148 @@ +function Cookie(s, host) {
+ this.parse(s, host);
+}
+Cookie.computeId = function(c) {
+ return c.name + ";" + c.host + "/" + c.path;
+};
+Cookie.find = function(f) {
+ var cc = Cookie.prototype.cookieManager.enumerator;
+ var c;
+ while (cc.hasMoreElements()) {
+ if (f(c = cc.getNext())) return c;
+ }
+ return null;
+};
+
+Cookie.attributes = { host: 'domain', path: 'path', expires: 'expires', isHttpOnly: 'HttpOnly', isSecure: 'Secure' };
+Cookie.prototype = {
+
+ name: '',
+ value: '',
+ source: '',
+ domain: '',
+ host: '',
+ rawHost: '',
+ path: '',
+ secure: false,
+ httponly: false,
+ session: true,
+ expires: 0,
+
+ id: '',
+
+
+ toString: function() {
+ var c = [this['name'] + "=" + this.value];
+ var v;
+ const aa = Cookie.attributes;
+ for (var k in aa) {
+ var p = aa[k];
+ v = this[k];
+ switch(typeof(v)) {
+ case "string":
+ if (v) c.push(p + "=" + v);
+ break;
+ case "boolean":
+ if (v) c.push(p);
+ break;
+ case "number":
+ if (!this.isSession) c.push(p + "=" + new Date(v * 1000).toUTCString());
+ break;
+ }
+ }
+ return c.join("; ");
+ },
+ parse: function(s, host) {
+ var p;
+ if (this.source) {
+ // cleanup for recycle
+ for (p in this) {
+ if (typeof (p) != "function") delete this[p];
+ }
+ }
+ this.source = s;
+ this.host = host;
+
+ var parts = s.split(/;\s*/);
+ var nv = parts.shift().split("=");
+
+ this.name = nv.shift() || '';
+ this.value = nv.join('=') || '';
+
+ var n, v;
+ for each (p in parts) {
+ nv = p.split("=");
+ switch (n = nv[0].toLowerCase()) {
+ case 'expires':
+ v = Math.round(Date.parse((nv[1] || '').replace(/\-/g, ' ')) / 1000);
+ break;
+ case 'domain':
+ case 'path':
+ v = nv[1] || '';
+ break;
+ case 'secure':
+ case 'httponly':
+ v = true;
+ break;
+ default:
+ n = 'unknown';
+ }
+ this[n] = v;
+ }
+ if (!this.expires) {
+ this.session = true;
+ this.expires = Math.round(new Date() / 1000) + 31536000;
+ }
+ if (this.domain) {
+ if (!this.isDomain) this.domain = "." + this.domain;
+ this.host = this.domain;
+ }
+ this.rawHost = this.host.replace(/^\./, '');
+
+ this.id = Cookie.computeId(this);
+ },
+
+
+ get cookieManager() {
+ delete Cookie.prototype.cookieManager;
+ var cman = Cc["@mozilla.org/cookiemanager;1"]
+ .getService(Ci.nsICookieManager2).QueryInterface(Ci.nsICookieManager);
+ return Cookie.prototype.cookieManager = cman;
+ },
+ belongsTo: function(host, path) {
+ if (path && this.path && path.indexOf(this.path) != 0) return false;
+ if (host == this.rawHost) return true;
+ var d = this.domain;
+ return d && (host == d || this.isDomain && host.slice(-d.length) == d);
+ },
+ save: function() {
+ this.save = ("cookieExists" in this.cookieManager)
+ ? function() { this.cookieManager.add(this.host, this.path, this.name, this.value, this.secure, this.httponly, this.session, this.expires); }
+ : function() { this.cookieManager.add(this.host, this.path, this.name, this.value, this.secure, this.session, this.expires);}
+ ;
+ return this.save();
+ },
+ exists: function() {
+ var cc = this.cookieManager.enumerator;
+ while(cc.hasMoreElements()) {
+ if (this.sameAs(cc.getNext())) return true;
+ }
+ return false;
+ },
+
+ sameAs: function(c) {
+ (c instanceof Ci.nsICookie) && (c instanceof Ci.nsICookie2);
+ return Cookie.computeId(c) == this.id;
+ },
+
+ // nsICookie2 interface extras
+ get isSecure() { return this.secure; },
+ get expiry() { return this.expires; },
+ get isSession() { return this.session; },
+ get isHttpOnly() { return this.httponly; },
+ get isDomain() { return this.domain && this.domain[0] == '.'; },
+ policy: 0,
+ status: 0,
+ QueryInterface: xpcom_generateQI([Ci.nsICookie, Ci.nsICookie2])
+
+};
diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/HTTPS.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/HTTPS.js new file mode 100644 index 0000000..c39a0ef --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/HTTPS.js @@ -0,0 +1,296 @@ +INCLUDE('Cookie');
+// XXX: Disable STS for now.
+var STS = {
+ isSTSURI : function(uri) {
+ return false;
+ }
+};
+
+// Hack. We only need the part of the policystate that tracks content
+// policy loading.
+const PolicyState = {
+ attach: function(channel) {
+ IOUtil.attachToChannel(channel, "httpseverywhere.policyLoaded", true);
+ },
+
+ extract: function(channel) {
+ var res = IOUtil.extractFromChannel(channel,
+ "httpseverywhere.policyLoaded", true);
+ return res;
+ },
+};
+
+const HTTPS = {
+ ready: false,
+
+ secureCookies: true,
+ secureCookiesExceptions: null,
+ secureCookiesForced: null,
+ httpsForced: null,
+ httpsForcedExceptions: null,
+ httpsRewrite: null,
+
+ replaceChannel: function(applicable_list, channel) {
+ var blob = HTTPSRules.rewrittenURI(applicable_list, channel.URI.clone());
+ if (null == blob) return false; // no rewrite
+ var uri = blob.newuri;
+ if (!uri) this.log(WARN, "OH NO BAD ARGH\nARGH");
+
+ var c2 = channel.QueryInterface(CI.nsIHttpChannel);
+ this.log(DBUG, channel.URI.spec+": Redirection limit is " + c2.redirectionLimit);
+ // XXX This used to be (c2.redirectionLimit == 1), but that's very
+ // inefficient in a case (eg amazon) where this may happen A LOT.
+ // Rather than number like 10, we should use the starting value
+ // in network.http.redirection-limit minus some counter
+ if (c2.redirectionLimit < 10) {
+ this.log(WARN, "Redirection loop trying to set HTTPS on:\n " +
+ channel.URI.spec +"\n(falling back to HTTP)");
+ if (!blob.applied_ruleset) {
+ this.log(WARN,"Blacklisting rule for: " + channel.URI.spec);
+ https_everywhere_blacklist[channel.URI.spec] = true;
+ }
+ https_everywhere_blacklist[channel.URI.spec] = blob.applied_ruleset;
+ var domain = null;
+ try { domain = channel.URI.host; } catch (e) {}
+ if (domain) https_blacklist_domains[domain] = true;
+ return false;
+ }
+
+ // Check for the new internal redirect API. If it exists, use it.
+ if (!"redirectTo" in channel) {
+ this.log(WARN, "nsIHTTPChannel.redirectTo API is missing. This version of HTTPS Everywhere is useless!!!!\n!!!\n");
+ return false;
+ }
+
+ this.log(INFO, "Using nsIHttpChannel.redirectTo: " + channel.URI.spec + " -> " + uri.spec);
+ try {
+ channel.redirectTo(uri);
+ return true;
+ } catch(e) {
+ // This should not happen. We should only get exceptions if
+ // the channel was already open.
+ this.log(WARN, "Exception on nsIHttpChannel.redirectTo: "+e);
+
+ // Don't return: Fallback to NoScript ChannelReplacement.js
+ }
+ this.log(WARN,"Aborting redirection " + channel.name + ", should be HTTPS!");
+ IOUtil.abort(channel);
+ return false;
+ },
+
+ // getApplicableListForContext was remove along with the nsIContentPolicy
+ // bindings and the and forceURI path that used them.
+
+ onCrossSiteRequest: function(channel, origin, browser, rw) {
+ try {
+ this.handleCrossSiteCookies(channel, origin, browser);
+ } catch(e) {
+ this.log(WARN, e + " --- " + e.stack);
+ }
+ },
+
+ registered: false,
+ handleSecureCookies: function(req) {
+
+ try {
+ req = req.QueryInterface(CI.nsIHttpChannel);
+ } catch(e) {
+ this.log(WARN, "Request is not an nsIHttpChannel: " + req);
+ return;
+ }
+ if (!this.secureCookies) return;
+ var uri = req.URI;
+ if (!uri) {
+ this.log(WARN,"No URI inside request " +req);
+ return;
+ }
+ //this.log(DBUG, "Cookie hunting in " + uri.spec);
+ var alist = HTTPSEverywhere.instance.getApplicableListForChannel(req);
+ if (!alist)
+ this.log(INFO, "No alist for cookies for "+(req.URI) ? req.URI.spec : "???");
+
+ if (uri.schemeIs("https")) {
+ var host = uri.host;
+ try {
+ var cookies = req.getResponseHeader("Set-Cookie");
+ } catch(mayHappen) {
+ //this.log(VERB,"Exception hunting Set-Cookie in headers: " + mayHappen);
+ return;
+ }
+ if (!cookies) return;
+ var c;
+ for each (var cs in cookies.split("\n")) {
+ this.log(DBUG, "Examining cookie: ");
+ c = new Cookie(cs, host);
+ if (!c.secure && HTTPSRules.shouldSecureCookie(alist, c, true)) {
+ this.log(INFO, "Securing cookie: " + c.domain + " " + c.name);
+ c.secure = true;
+ req.setResponseHeader("Set-Cookie", c.source + ";Secure", true);
+ }
+ }
+
+ }
+ },
+
+ handleInsecureCookie: function(c) {
+ if (HTTPSRules.shouldSecureCookie(null, c, false)) {
+ this.log(INFO, "Securing cookie from event: " + c.domain + " " + c.name);
+ var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"]
+ .getService(Components.interfaces.nsICookieManager2);
+ //some braindead cookies apparently use umghzabilliontrabilions
+ var expiry = Math.min(c.expiry, Math.pow(2,31));
+ cookieManager.remove(c.host, c.name, c.path, false);
+ cookieManager.add(c.host, c.path, c.name, c.value, true, c.isHTTPOnly, c.isSession, expiry);
+ }
+ },
+
+ handleCrossSiteCookies: function(req, origin, browser) {
+
+ var unsafeCookies = this.getUnsafeCookies(browser);
+ if (!unsafeCookies) return;
+
+ var uri = req.URI;
+ var dscheme = uri.scheme;
+
+ var oparts = origin && origin.match(/^(https?):\/\/([^\/:]+).*?(\/.*)/);
+ if (!(oparts && /https?/.test(dscheme))) return;
+
+ var oscheme = oparts[1];
+ if (oscheme == dscheme) return; // we want to check only cross-scheme requests
+
+ var dsecure = dscheme == "https";
+
+ if (dsecure && !ns.getPref("secureCookies.recycle", false)) return;
+
+ var dhost = uri.host;
+ var dpath = uri.path;
+
+ var ohost = oparts[2];
+ var opath = oparts[3];
+
+ var ocookieCount = 0, totCount = 0;
+ var dcookies = [];
+ var c;
+
+ for (var k in unsafeCookies) {
+ c = unsafeCookies[k];
+ if (!c.exists()) {
+ delete unsafeCookies[k];
+ } else {
+ totCount++;
+ if (c.belongsTo(dhost, dpath) && c.secure != dsecure) { // either secure on http or not secure on https
+ dcookies.push(c);
+ }
+ if (c.belongsTo(ohost, opath)) {
+ ocookieCount++;
+ }
+ }
+ }
+
+ if (!totCount) {
+ this.setUnsafeCookies(browser, null);
+ return;
+ }
+
+ // We want to "desecurify" cookies only if cross-navigation to unsafe
+ // destination originates from a site sharing some secured cookies
+
+ if (ocookieCount == 0 && !dsecure || !dcookies.length) return;
+
+ if (dsecure) {
+ this.log(WARN,"Detected cross-site navigation with secured cookies: " + origin + " -> " + uri.spec);
+
+ } else {
+ this.log(WARN,"Detected unsafe navigation with NoScript-secured cookies: " + origin + " -> " + uri.spec);
+ this.log(WARN,uri.prePath + " cannot support secure cookies because it does not use HTTPS. Consider forcing HTTPS for " + uri.host + " in NoScript's Advanced HTTPS options panel.");
+ }
+
+ var cs = CC['@mozilla.org/cookieService;1'].getService(CI.nsICookieService).getCookieString(uri, req);
+
+ for each (c in dcookies) {
+ c.secure = dsecure;
+ c.save();
+ this.log(WARN,"Toggled secure flag on " + c);
+ }
+
+ if (cs) {
+ dcookies.push.apply(
+ dcookies, cs.split(/\s*;\s*/).map(function(cs) { var nv = cs.split("="); return { name: nv.shift(), value: nv.join("=") }; })
+ .filter(function(c) { return dcookies.every(function(x) { return x.name != c.name; }); })
+ );
+ }
+
+ cs = dcookies.map(function(c) { return c.name + "=" + c.value; }).join("; ");
+
+ this.log(WARN,"Sending Cookie for " + dhost + ": " + cs);
+ req.setRequestHeader("Cookie", cs, false); // "false" because merge syntax breaks Cookie header
+ },
+
+
+ cookiesCleanup: function(refCookie) {
+ var downgraded = [];
+
+ var ignored = this.secureCookiesExceptions;
+ var disabled = !this.secureCookies;
+ var bi = DOM.createBrowserIterator();
+ var unsafe, k, c, total, deleted;
+ for (var browser; browser = bi.next();) {
+ unsafe = this.getUnsafeCookies(browser);
+ if (!unsafe) continue;
+ total = deleted = 0;
+ for (k in unsafe) {
+ c = unsafe[k];
+ total++;
+ if (disabled || (refCookie ? c.belongsTo(refCookie.host) : ignored && ignored.test(c.rawHost))) {
+ if (c.exists()) {
+ this.log(WARN,"Cleaning Secure flag from " + c);
+ c.secure = false;
+ c.save();
+ }
+ delete unsafe[k];
+ deleted++;
+ }
+ }
+ if (total == deleted) this.setUnsafeCookies(browser, null);
+ if (!this.cookiesPerTab) break;
+ }
+ },
+
+ get cookiesPerTab() {
+ return ns.getPref("secureCookies.perTab", false);
+ },
+
+ _globalUnsafeCookies: {},
+ getUnsafeCookies: function(browser) {
+ return this.cookiesPerTab
+ ? browser && ns.getExpando(browser, "unsafeCookies")
+ : this._globalUnsafeCookies;
+ },
+ setUnsafeCookies: function(browser, value) {
+ return this.cookiesPerTab
+ ? browser && ns.setExpando(browser, "unsafeCookies", value)
+ : this._globalUnsafeCookies = value;
+ },
+
+ _getParent: function(req, w) {
+ return w && w.frameElement || DOM.findBrowserForNode(w || IOUtil.findWindow(req));
+ }
+
+};
+
+(function () {
+ ["secureCookies", "secureCookiesExceptions", "secureCookiesForced"].forEach(function(p) {
+ var v = HTTPS[p];
+ delete HTTPS[p];
+ HTTPS.__defineGetter__(p, function() {
+ return v;
+ });
+ HTTPS.__defineSetter__(p, function(n) {
+ v = n;
+ if (HTTPS.ready) HTTPS.cookiesCleanup();
+ return v;
+ });
+ });
+})();
+
+HTTPS.ready = true;
diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/HTTPSRules.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/HTTPSRules.js new file mode 100644 index 0000000..ecbaf76 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/HTTPSRules.js @@ -0,0 +1,762 @@ +// Compilation of RegExps is now delayed until they are first used... + +function Rule(from, to) { + this.to = to; + this.from_c = from; // This will become a RegExp after compilation +} + +function Exclusion(pattern) { + this.pattern_c = pattern; // Will become a RegExp after compilation +} + +function CookieRule(host, cookiename) { + this.host = host; + this.name = cookiename; + + // These will be made during compilation: + + //this.host_c = new RegExp(host); + //this.name_c = new RegExp(cookiename); +} + +function RuleSet(id, name, xmlName, match_rule, default_off, platform) { + if(xmlName == "WordPress.xml" || xmlName == "Github.xml") { + this.log(NOTE, "RuleSet( name="+name+", xmlName="+xmlName+", match_rule="+match_rule+", default_off="+default_off+", platform="+platform+" )"); + } + + this.id=id; + this.on_by_default = true; + this.compiled = false; + this.name = name; + this.xmlName = xmlName; + this.notes = ""; + if (match_rule) this.ruleset_match_c = new RegExp(match_rule); + else this.ruleset_match_c = null; + if (default_off) { + // Perhaps problematically, this currently ignores the actual content of + // the default_off XML attribute. Ideally we'd like this attribute to be + // "valueless" + this.notes = default_off; + this.on_by_default = false; + } + if (platform) + if (platform.search(HTTPSRules.localPlatformRegexp) == -1) { + this.on_by_default = false; + this.notes = "Only for " + platform; + } + + this.rules = []; + this.exclusions = []; + this.cookierules = []; + + this.rule_toggle_prefs = HTTPSEverywhere.instance.rule_toggle_prefs; + + try { + // if this pref exists, use it + this.active = this.rule_toggle_prefs.getBoolPref(name); + } catch(e) { + // if not, use the default + this.active = this.on_by_default; + } +} + +var dom_parser = Cc["@mozilla.org/xmlextras/domparser;1"].createInstance(Ci.nsIDOMParser); + +RuleSet.prototype = { + + ensureCompiled: function() { + // Postpone compilation of exclusions, rules and cookies until now, to accelerate + // browser load time. + if (this.compiled) return; + var i; + + for (i = 0; i < this.exclusions.length; ++i) { + this.exclusions[i].pattern_c = new RegExp(this.exclusions[i].pattern_c); + } + for (i = 0; i < this.rules.length; ++i) { + this.rules[i].from_c = new RegExp(this.rules[i].from_c); + } + + for (i = 0; i < this.cookierules.length; i++) { + var cr = this.cookierules[i]; + cr.host_c = new RegExp(cr.host); + cr.name_c = new RegExp(cr.name); + } + + this.compiled = true; + }, + + apply: function(urispec) { + // return null if it does not apply + // and the new url if it does apply + var i; + var returl = null; + this.ensureCompiled(); + // If a rulset has a match_rule and it fails, go no further + if (this.ruleset_match_c && !this.ruleset_match_c.test(urispec)) { + this.log(VERB, "ruleset_match_c excluded " + urispec); + return null; + } + // Even so, if we're covered by an exclusion, go home + for (i = 0; i < this.exclusions.length; ++i) { + if (this.exclusions[i].pattern_c.test(urispec)) { + this.log(DBUG,"excluded uri " + urispec); + return null; + } + } + // Okay, now find the first rule that triggers + for (i = 0; i < this.rules.length; ++i) { + // This is just for displaying inactive rules + returl = urispec.replace(this.rules[i].from_c, this.rules[i].to); + if (returl != urispec) return returl; + } + + return null; + }, + log: function(level, msg) { + https_everywhereLog(level, msg); + }, + + wouldMatch: function(hypothetical_uri, alist) { + // return true if this ruleset would match the uri, assuming it were http + // used for judging moot / inactive rulesets + // alist is optional + + // if the ruleset is already somewhere in this applicable list, we don't + // care about hypothetical wouldMatch questions + if (alist && (this.name in alist.all)) return false; + + this.log(DBUG,"Would " +this.name + " match " +hypothetical_uri.spec + + "? serial " + (alist && alist.serial)); + + var uri = hypothetical_uri.clone(); + if (uri.scheme == "https") uri.scheme = "http"; + var urispec = uri.spec; + + this.ensureCompiled(); + + if (this.ruleset_match_c && !this.ruleset_match_c.test(urispec)) + return false; + + for (var i = 0; i < this.exclusions.length; ++i) + if (this.exclusions[i].pattern_c.test(urispec)) return false; + + for (var i = 0; i < this.rules.length; ++i) + if (this.rules[i].from_c.test(urispec)) return true; + return false; + }, + + transformURI: function(uri) { + // If no rule applies, return null; if a rule would have applied but was + // inactive, return 0; otherwise, return a fresh uri instance + // for the target + var newurl = this.apply(uri.spec); + if (null == newurl) + return null; + var newuri = Components.classes["@mozilla.org/network/standard-url;1"]. + createInstance(CI.nsIStandardURL); + newuri.init(CI.nsIStandardURL.URLTYPE_STANDARD, 80, + newurl, uri.originCharset, null); + newuri = newuri.QueryInterface(CI.nsIURI); + return newuri; + }, + + enable: function() { + // Enable us. + this.rule_toggle_prefs.setBoolPref(this.name, true); + this.active = true; + }, + + disable: function() { + // Disable us. + this.rule_toggle_prefs.setBoolPref(this.name, false); + this.active = false; + }, + + toggle: function() { + this.active = !this.active; + this.rule_toggle_prefs.setBoolPref(this.name, this.active); + }, + + clear: function() { + try { + this.rule_toggle_prefs.clearUserPref(this.name); + } catch(e) { + // this ruleset has never been toggled + } + this.active = this.on_by_default; + } +}; + +const RuleWriter = { + + getCustomRuleDir: function() { + var loc = "ProfD"; // profile directory + var file = + CC["@mozilla.org/file/directory_service;1"] + .getService(CI.nsIProperties) + .get(loc, CI.nsILocalFile) + .clone(); + file.append("HTTPSEverywhereUserRules"); + // Check for existence, if not, create. + if (!file.exists()) { + file.create(CI.nsIFile.DIRECTORY_TYPE, 0700); + } + if (!file.isDirectory()) { + // XXX: Arg, death! + } + return file; + }, + + chromeToPath: function (aPath) { + if (!aPath || !(/^chrome:/.test(aPath))) + return; //not a chrome url + + var ios = + CC['@mozilla.org/network/io-service;1'] + .getService(CI.nsIIOService); + var uri = ios.newURI(aPath, "UTF-8", null); + var cr = + CC['@mozilla.org/chrome/chrome-registry;1'] + .getService(CI.nsIChromeRegistry); + var rv = cr.convertChromeURL(uri).spec; + + if (/^file:/.test(rv)) + rv = this.urlToPath(rv); + else + rv = this.urlToPath("file://"+rv); + + return rv; + }, + + urlToPath: function (aPath) { + if (!aPath || !/^file:/.test(aPath)) + return ; + + var ph = + CC["@mozilla.org/network/protocol;1?name=file"] + .createInstance(CI.nsIFileProtocolHandler); + var rv = ph.getFileFromURLSpec(aPath).path; + + return rv; + }, + + read: function(file, rule_store, ruleset_id) { + if (!file.exists()) + return null; + if ((rule_store.targets == null) && (rule_store.targets != {})) + this.log(WARN, "TARGETS IS NULL"); + var data = ""; + var fstream = CC["@mozilla.org/network/file-input-stream;1"] + .createInstance(CI.nsIFileInputStream); + var sstream = CC["@mozilla.org/scriptableinputstream;1"] + .createInstance(CI.nsIScriptableInputStream); + fstream.init(file, -1, 0, 0); + sstream.init(fstream); + + var str = sstream.read(4096); + while (str.length > 0) { + data += str; + str = sstream.read(4096); + } + + sstream.close(); + fstream.close(); + return this.readFromString(data, rule_store, ruleset_id); + }, + + readFromString: function(data, rule_store, ruleset_id) { + try { + var xmlruleset = dom_parser.parseFromString(data, "text/xml"); + } catch(e) { // file has been corrupted; XXX: handle error differently + this.log(WARN,"Error in XML data: " + e + "\n" + data); + return null; + } + this.parseOneRuleset(xmlruleset.documentElement, rule_store, ruleset_id); + }, + + parseOneRuleset: function(xmlruleset, rule_store, ruleset_id) { + // Extract an xmlruleset into the rulestore + if (!xmlruleset.getAttribute("name")) { + this.log(WARN, "This blob: '" + xmlruleset + "' is not a ruleset\n"); + return null; + } + + this.log(DBUG, "Parsing " + xmlruleset.getAttribute("name")); + + var match_rl = xmlruleset.getAttribute("match_rule"); + var dflt_off = xmlruleset.getAttribute("default_off"); + var platform = xmlruleset.getAttribute("platform"); + var rs = new RuleSet(ruleset_id, xmlruleset.getAttribute("name"), xmlruleset.getAttribute("f"), match_rl, dflt_off, platform); + + // see if this ruleset has the same name as an existing ruleset; + // if so, this ruleset is ignored; DON'T add or return it. + if (rs.name in rule_store.rulesetsByName) { + this.log(WARN, "Error: found duplicate rule name " + rs.name); + return null; + } + + // Add this ruleset id into HTTPSRules.targets if it's not already there. + // This should only happen for custom user rules. Built-in rules get + // their ids preloaded into the targets map, and have their <target> + // tags stripped when the sqlite database is built. + var targets = xmlruleset.getElementsByTagName("target"); + for (var i = 0; i < targets.length; i++) { + var host = targets[i].getAttribute("host"); + if (!host) { + this.log(WARN, "<target> missing host in " + xmlruleset.getAttribute("name")); + return null; + } + if (! rule_store.targets[host]) + rule_store.targets[host] = []; + this.log(DBUG, "Adding " + host + " to targets, pointing at " + ruleset_id); + rule_store.targets[host].push(ruleset_id); + } + + var exclusions = xmlruleset.getElementsByTagName("exclusion"); + for (var i = 0; i < exclusions.length; i++) { + var exclusion = new Exclusion(exclusions[i].getAttribute("pattern")); + rs.exclusions.push(exclusion); + } + + var rules = xmlruleset.getElementsByTagName("rule"); + for (var i = 0; i < rules.length; i++) { + var rule = new Rule(rules[i].getAttribute("from"), + rules[i].getAttribute("to")); + rs.rules.push(rule); + } + + var securecookies = xmlruleset.getElementsByTagName("securecookie"); + for (var i = 0; i < securecookies.length; i++) { + var c_rule = new CookieRule(securecookies[i].getAttribute("host"), + securecookies[i].getAttribute("name")); + rs.cookierules.push(c_rule); + this.log(DBUG,"Cookie rule "+ c_rule.host+ " " +c_rule.name); + } + + rule_store.rulesets.push(rs); + rule_store.rulesetsByID[rs.id] = rs; + rule_store.rulesetsByName[rs.name] = rs; + }, + + enumerate: function(dir) { + // file is the given directory (nsIFile) + var entries = dir.directoryEntries; + var ret = []; + while(entries.hasMoreElements()) { + var entry = entries.getNext(); + entry.QueryInterface(Components.interfaces.nsIFile); + ret.push(entry); + } + return ret; + }, +}; + + + +const HTTPSRules = { + init: function() { + try { + this.rulesets = []; + this.targets = {}; // dict mapping target host pattern -> list of + // applicable ruleset ids + this.rulesetsByID = {}; + this.rulesetsByName = {}; + var t1 = new Date().getTime(); + this.checkMixedContentHandling(); + var rulefiles = RuleWriter.enumerate(RuleWriter.getCustomRuleDir()); + this.scanRulefiles(rulefiles); + + // Initialize database connection. + var dbFile = new FileUtils.File(RuleWriter.chromeToPath("chrome://https-everywhere/content/rulesets.sqlite")); + var rulesetDBConn = Services.storage.openDatabase(dbFile); + this.queryForRuleset = rulesetDBConn.createStatement( + "select contents from rulesets where id = :id"); + + // Preload the mapping of hostname target -> ruleset ID from DB. + // This is a little slow (287 ms on a Core2 Duo @ 2.2GHz with SSD), + // but is faster than loading all of the rulesets. If this becomes a + // bottleneck, change it to load in a background webworker, or load + // a smaller bloom filter instead. + var targetsQuery = rulesetDBConn.createStatement("select host, ruleset_id from targets"); + this.log(DBUG, "Loading targets..."); + while (targetsQuery.executeStep()) { + var host = targetsQuery.row.host; + var id = targetsQuery.row.ruleset_id; + if (!this.targets[host]) { + this.targets[host] = [id]; + } else { + this.targets[host].push(id); + } + } + this.log(DBUG, "Loading adding targets."); + } catch(e) { + this.log(DBUG,"Rules Failed: "+e); + } + var t2 = new Date().getTime(); + this.log(NOTE,"Loading targets took " + (t2 - t1) / 1000.0 + " seconds"); + + var gitCommitQuery = rulesetDBConn.createStatement("select git_commit from git_commit"); + if (gitCommitQuery.executeStep()) { + this.GITCommitID = gitCommitQuery.row.git_commit; + } + + try { + if (HTTPSEverywhere.instance.prefs.getBoolPref("performance_tests")) { + this.testRulesetRetrievalPerformance(); + } + } catch(e) { + this.log(WARN, "Exception during testing " + e); + } + return; + }, + + checkMixedContentHandling: function() { + // Firefox 23+ blocks mixed content by default, so rulesets that create + // mixed content situations should be disabled there + var appInfo = CC["@mozilla.org/xre/app-info;1"].getService(CI.nsIXULAppInfo); + var platformVer = appInfo.platformVersion; + var versionChecker = CC["@mozilla.org/xpcom/version-comparator;1"] + .getService(CI.nsIVersionComparator); + var prefs = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefService).getBranch(""); + + + // If mixed content is present and enabled, and the user hasn't opted to enable + // mixed content triggering rules, leave them out. Otherwise add them in. + if(versionChecker.compare(appInfo.version, "23.0a1") >= 0 + && prefs.getBoolPref("security.mixed_content.block_active_content") + && !prefs.getBoolPref("extensions.https_everywhere.enable_mixed_rulesets")) { + this.log(INFO, "Not activating rules that trigger mixed content errors."); + this.localPlatformRegexp = new RegExp("firefox"); + } else { + this.log(INFO, "Activating rules that would normally trigger mixed content"); + this.localPlatformRegexp = new RegExp("(firefox|mixedcontent)"); + } + }, + + scanRulefiles: function(rulefiles) { + var i = 0; + var r = null; + for(i = 0; i < rulefiles.length; ++i) { + try { + this.log(DBUG,"Loading ruleset file: "+rulefiles[i].path); + var ruleset_id = "custom_" + i; + RuleWriter.read(rulefiles[i], this, ruleset_id); + } catch(e) { + this.log(WARN, "Error in ruleset file: " + e); + if (e.lineNumber) + this.log(WARN, "(line number: " + e.lineNumber + ")"); + } + } + }, + + resetRulesetsToDefaults: function() { + // Callable from within the prefs UI and also for cleaning up buggy + // configurations... + for (var i in this.rulesets) { + this.rulesets[i].clear(); + } + }, + + rewrittenURI: function(alist, input_uri) { + // This function oversees the task of working out if a uri should be + // rewritten, what it should be rewritten to, and recordkeeping of which + // applicable rulesets are and aren't active. Previously this returned + // the new uri if there was a rewrite. Now it returns a JS object with a + // newuri attribute and an applied_ruleset attribute (or null if there's + // no rewrite). + var i = 0; + userpass_present = false; // Global so that sanitiseURI can tweak it. + // Why does JS have no tuples, again? + var blob = {}; blob.newuri = null; + if (!alist) this.log(DBUG, "No applicable list rewriting " + input_uri.spec); + this.log(NOTE, "Processing " + input_uri.spec); + + var uri = this.sanitiseURI(input_uri); + + // Get the list of rulesets that target this host + try { + var rs = this.potentiallyApplicableRulesets(uri.host); + } catch(e) { + this.log(NOTE, 'Could not check applicable rules for '+uri.spec + '\n'+e); + return null; + } + + // ponder each potentially applicable ruleset, working out if it applies + // and recording it as active/inactive/moot/breaking in the applicable list + for (i = 0; i < rs.length; ++i) { + if (!rs[i].active) { + if (alist && rs[i].wouldMatch(uri, alist)) + alist.inactive_rule(rs[i]); + continue; + } + blob.newuri = rs[i].transformURI(uri); + if (blob.newuri) { + // we rewrote the uri + this.log(DBUG, "Rewrote "+input_uri.spec); + if (alist) { + if (uri.spec in https_everywhere_blacklist) + alist.breaking_rule(rs[i]); + else + alist.active_rule(rs[i]); + } + if (userpass_present) blob.newuri.userPass = input_uri.userPass; + blob.applied_ruleset = rs[i]; + return blob; + } + if (uri.scheme == "https" && alist) { + // we didn't rewrite but the rule applies to this domain and the + // requests are going over https + if (rs[i].wouldMatch(uri, alist)) alist.moot_rule(rs[i]); + continue; + } + } + return null; + }, + + sanitiseURI: function(input_uri) { + // Rulesets shouldn't try to parse usernames and passwords. If we find + // those, apply the ruleset without them (and then add them back later). + // When .userPass is absent, sometimes it is false and sometimes trying + // to read it raises an exception (probably depending on the URI type). + var uri = input_uri; + try { + if (input_uri.userPass) { + uri = input_uri.clone(); + userpass_present = true; // tweaking a global in our caller :( + uri.userPass = null; + } + } catch(e) {} + + // example.com. is equivalent to example.com + // example.com.. is invalid, but firefox would load it anyway + try { + if (uri.host) + try { + var h = uri.host; + if (h.charAt(h.length - 1) == ".") { + while (h.charAt(h.length - 1) == ".") + h = h.slice(0,-1); + uri = uri.clone(); + uri.host = h; + } + } catch(e) { + this.log(WARN, "Failed to normalise domain: "); + try {this.log(WARN, input_uri.host);} + catch(e2) {this.log(WARN, "bang" + e + " & " + e2 + " & "+ input_uri);} + } + } catch(e3) { + this.log(INFO, "uri.host is explosive!"); + try { this.log(INFO, "(" + uri.spec + ")"); } // happens for about: uris and soforth + catch(e4) { this.log(WARN, "(and unprintable!!!!!!)"); } + } + return uri; + }, + + setInsert: function(intoList, fromList) { + // Insert any elements from fromList into intoList, if they are not + // already there. fromList may be null. + if (!fromList) return; + for (var i = 0; i < fromList.length; i++) + if (intoList.indexOf(fromList[i]) == -1) + intoList.push(fromList[i]); + }, + + loadAllRulesets: function() { + for (var host in this.targets) { + var ruleset_ids = this.targets[host]; + for (var i = 0; i < ruleset_ids.length; i++) { + var id = ruleset_ids[i]; + if (!this.rulesetsByID[id]) { + this.loadRulesetById(id); + } + } + } + }, + + // Load a ruleset by numeric id, e.g. 234 + // NOTE: This call runs synchronously, which can lock up the browser UI. Is + // there any way to fix that, given that we need to run blocking in the request + // flow? Perhaps we can preload all targets from the DB into memory at startup + // so we only hit the DB when we know there is something to be had. + loadRulesetById: function(ruleset_id) { + this.log(DBUG, "Querying DB for ruleset id " + ruleset_id); + this.queryForRuleset.params.id = ruleset_id; + + try { + if (this.queryForRuleset.executeStep()) { + this.log(INFO, "Found ruleset in DB for id " + ruleset_id); + RuleWriter.readFromString(this.queryForRuleset.row.contents, this, ruleset_id); + } else { + this.log(WARN,"Couldn't find ruleset for id " + ruleset_id); + } + } finally { + this.queryForRuleset.reset(); + } + }, + + // Get all rulesets matching a given target, lazy-loading from DB as necessary. + rulesetsByTarget: function(target) { + var rulesetIds = this.targets[target]; + + var output = []; + if (rulesetIds) { + this.log(INFO, "For target " + target + ", found ids " + rulesetIds.toString()); + for (var i = 0; i < rulesetIds.length; i++) { + var id = rulesetIds[i]; + if (!this.rulesetsByID[id]) { + this.loadRulesetById(id); + } + if (this.rulesetsByID[id]) { + output.push(this.rulesetsByID[id]); + } + } + } else { + this.log(INFO, "For target " + target + ", found no ids in DB"); + } + return output; + }, + + potentiallyApplicableRulesets: function(host) { + // Return a list of rulesets that declare targets matching this host + var i, tmp, t; + var results = []; + + var attempt = function(target) { + this.setInsert(results, this.rulesetsByTarget(target)); + }.bind(this); + + attempt(host); + + // replace each portion of the domain with a * in turn + var segmented = host.split("."); + for (i = 0; i < segmented.length; ++i) { + tmp = segmented[i]; + segmented[i] = "*"; + t = segmented.join("."); + segmented[i] = tmp; + attempt(t); + } + // now eat away from the left, with *, so that for x.y.z.google.com we + // check *.z.google.com and *.google.com (we did *.y.z.google.com above) + for (i = 2; i <= segmented.length - 2; ++i) { + t = "*." + segmented.slice(i,segmented.length).join("."); + attempt(t); + } + this.log(DBUG,"Potentially applicable rules for " + host + ":"); + for (i = 0; i < results.length; ++i) + this.log(DBUG, " " + results[i].name); + return results; + }, + + testRulesetRetrievalPerformance: function() { + // We can use this function to measure the impact of changes in the ruleset + // storage architecture, potentiallyApplicableRulesets() caching + // implementations, etc. + var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(Ci.nsIXMLHttpRequest); + req.open("GET", "https://eff.org/files/alexa-top-10000-global.txt", false); + req.send(); + var domains = req.response.split("\n"); + var domains_l = domains.length - 1; // The last entry in this thing is bogus + var prefix = ""; + this.log(WARN, "Calling potentiallyApplicableRulesets() with " + domains_l + " domains"); + var count = 0; + var t1 = new Date().getTime(); + for (var n = 0; n < domains_l; n++) { + if (this.potentiallyApplicableRulesets(prefix + domains[n]).length != 0) + count++; + } + var t2 = new Date().getTime(); + this.log(NOTE, count + " hits: average call to potentiallyApplicableRulesets took " + (t2 - t1) / domains_l + " milliseconds"); + count = 0; + t1 = new Date().getTime(); + for (var n = 0; n < domains_l; n++) { + if (this.potentiallyApplicableRulesets(prefix + domains[n]).length != 0) + count++; + } + t2 = new Date().getTime(); + this.log(NOTE, count + " hits: average subsequent call to potentiallyApplicableRulesets took " + (t2 - t1) / domains_l + " milliseconds"); + }, + + shouldSecureCookie: function(applicable_list, c, known_https) { + // Check to see if the Cookie object c meets any of our cookierule citeria + // for being marked as secure. + // @applicable_list : an ApplicableList or record keeping + // @c : an nsICookie2 + // @known_https : true if we know the page setting the cookie is https + + this.log(DBUG," rawhost: " + c.rawHost + "\n name: " + c.name + "\n host" + c.host); + var i,j; + var rs = this.potentiallyApplicableRulesets(c.host); + for (i = 0; i < rs.length; ++i) { + var ruleset = rs[i]; + if (ruleset.active) { + ruleset.ensureCompiled(); + // Never secure a cookie if this page might be HTTP + if (!known_https && !this.safeToSecureCookie(c.rawHost)) + continue; + for (j = 0; j < ruleset.cookierules.length; j++) { + var cr = ruleset.cookierules[j]; + if (cr.host_c.test(c.host) && cr.name_c.test(c.name)) { + if (applicable_list) applicable_list.active_rule(ruleset); + this.log(INFO,"Active cookie rule " + ruleset.name); + return true; + } + } + if (ruleset.cookierules.length > 0) + if (applicable_list) applicable_list.moot_rule(ruleset); + } else if (ruleset.cookierules.length > 0) { + if (applicable_list) applicable_list.inactive_rule(ruleset); + this.log(INFO,"Inactive cookie rule " + ruleset.name); + } + } + return false; + }, + + safeToSecureCookie: function(domain) { + // Check if the domain might be being served over HTTP. If so, it isn't + // safe to secure a cookie! We can't always know this for sure because + // observing cookie-changed doesn't give us enough context to know the + // full origin URI. + + // First, if there are any redirect loops on this domain, don't secure + // cookies. XXX This is not a very satisfactory heuristic. Sometimes we + // would want to secure the cookie anyway, because the URLs that loop are + // not authenticated or not important. Also by the time the loop has been + // observed and the domain blacklisted, a cookie might already have been + // flagged as secure. + + if (domain in https_blacklist_domains) { + this.log(INFO, "cookies for " + domain + "blacklisted"); + return false; + } + + // If we passed that test, make up a random URL on the domain, and see if + // we would HTTPSify that. + + try { + var nonce_path = "/" + Math.random().toString(); + nonce_path = nonce_path + nonce_path; + var test_uri = "http://" + domain + nonce_path; + } catch (e) { + this.log(WARN, "explosion in safeToSecureCookie for " + domain + "\n" + + "(" + e + ")"); + return false; + } + + this.log(INFO, "Testing securecookie applicability with " + test_uri); + var rs = this.potentiallyApplicableRulesets(domain); + for (var i = 0; i < rs.length; ++i) { + if (!rs[i].active) continue; + var rewrite = rs[i].apply(test_uri); + if (rewrite) { + this.log(INFO, "Yes: " + rewrite); + return true; + } + } + this.log(INFO, "(NO)"); + return false; + } +}; diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/IOUtil.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/IOUtil.js new file mode 100644 index 0000000..96c2500 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/IOUtil.js @@ -0,0 +1,263 @@ +const IO = { + readFile: function(file, charset) { + var res; + + const is = Cc["@mozilla.org/network/file-input-stream;1"] + .createInstance(Ci.nsIFileInputStream ); + is.init(file ,0x01, 256 /*0400*/, null); + const sis = Cc["@mozilla.org/scriptableinputstream;1"] + .createInstance(Ci.nsIScriptableInputStream); + sis.init(is); + + res = sis.read(sis.available()); + is.close(); + + if (charset !== null) { // use "null" if you want uncoverted data... + const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Ci.nsIScriptableUnicodeConverter); + try { + unicodeConverter.charset = charset || "UTF-8"; + } catch(ex) { + unicodeConverter.charset = "UTF-8"; + } + res = unicodeConverter.ConvertToUnicode(res); + } + + return res; + }, + writeFile: function(file, content, charset) { + const unicodeConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"] + .createInstance(Ci.nsIScriptableUnicodeConverter); + try { + unicodeConverter.charset = charset || "UTF-8"; + } catch(ex) { + unicodeConverter.charset = "UTF-8"; + } + + content = unicodeConverter.ConvertFromUnicode(content); + const os = Cc["@mozilla.org/network/file-output-stream;1"] + .createInstance(Ci.nsIFileOutputStream); + os.init(file, 0x02 | 0x08 | 0x20, 448 /*0700*/, 0); + os.write(content, content.length); + os.close(); + }, + + safeWriteFile: function(file, content, charset) { + var tmp = file.clone(); + var name = file.leafName; + tmp.leafName = name + ".tmp"; + tmp.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, file.exists() ? file.permissions : 384 /*0600*/); + this.writeFile(tmp, content, charset); + tmp.moveTo(file.parent, name); + } +}; + + +function nsISupportsWrapper(wrapped) { + this.wrappedJSObject = wrapped; +} +nsISupportsWrapper.prototype = { + QueryInterface: xpcom_generateQI([]) +}; + +const IOUtil = { + asyncNetworking: true, + proxiedDNS: 0, + + attachToChannel: function(channel, key, requestInfo) { + if (channel instanceof Ci.nsIWritablePropertyBag2) + channel.setPropertyAsInterface(key, requestInfo); + }, + extractFromChannel: function(channel, key, preserve) { + if (channel instanceof Ci.nsIPropertyBag2) { + let p = channel.get(key); + if (p) { + if (!preserve && (channel instanceof Ci.nsIWritablePropertyBag)) channel.deleteProperty(key); + if (p.wrappedJSObject) return p.wrappedJSObject; + p instanceof Ci.nsIURL || p instanceof Ci.nsIURL; + return p; + } + } + return null; + }, + + extractInternalReferrer: function(channel) { + if (channel instanceof Ci.nsIPropertyBag2) { + const key = "docshell.internalReferrer"; + if (channel.hasKey(key)) + try { + return channel.getPropertyAsInterface(key, Ci.nsIURL); + } catch(e) {} + } + return null; + }, + extractInternalReferrerSpec: function(channel) { + var ref = this.extractInternalReferrer(channel); + return ref && ref.spec || null; + }, + + getProxyInfo: function(channel) { + return Ci.nsIProxiedChannel && (channel instanceof Ci.nsIProxiedChannel) + ? channel.proxyInfo + : Components.classes["@mozilla.org/network/protocol-proxy-service;1"] + .getService(Components.interfaces.nsIProtocolProxyService) + .resolve(channel.URI, 0); + }, + + + canDoDNS: function(channel) { + if (!channel || IOS.offline) return false; + + var proxyInfo = this.getProxyInfo(channel); + switch(this.proxiedDNS) { + case 1: + return !(proxyInfo && (proxyInfo.flags & Ci.nsIProxyInfo.TRANSPARENT_PROXY_RESOLVES_HOST)); + case 2: + return true; + default: + return !proxyInfo || proxyInfo.type == "direct"; + } + + }, + + abort: function(channel, noNetwork) { + channel.cancel(Cr.NS_ERROR_ABORT); + }, + + findWindow: function(channel) { + for each(var cb in [channel.notificationCallbacks, + channel.loadGroup && channel.loadGroup.notificationCallbacks]) { + if (cb instanceof Ci.nsIInterfaceRequestor) { + if (Ci.nsILoadContext) try { + // For Gecko 1.9.1 + return cb.getInterface(Ci.nsILoadContext).associatedWindow; + } catch(e) {} + + try { + // For Gecko 1.9.0 + return cb.getInterface(Ci.nsIDOMWindow); + } catch(e) {} + } + } + return null; + }, + + readFile: IO.readFile, + writeFile: IO.writeFile, + safeWriteFIle: IO.safeWriteFile, + + _protocols: {}, // caching them we gain a 33% speed boost in URI creation :) + newURI: function(url) { + try { + let scheme = url.substring(0, url.indexOf(':')); + return (this._protocols[scheme] || + (this._protocols[scheme] = + Cc["@mozilla.org/network/protocol;1?name=" + scheme] + .getService(Ci.nsIProtocolHandler))) + .newURI(url, null, null); + } catch(e) { + return IOS.newURI(url, null, null); + } + }, + + unwrapURL: function(url) { + try { + if (!(url instanceof Ci.nsIURI)) + url = this.newURI(url); + + switch (url.scheme) { + case "view-source": + return this.unwrapURL(url.path); + case "feed": + let u = url.spec.substring(5); + if (u.substring(0, 2) == '//') u = "http:" + u; + return this.unwrapURL(u); + case "wyciwyg": + return this.unwrapURL(url.path.replace(/^\/\/\d+\//, "")); + case "jar": + if (url instanceof Ci.nsIJARURI) + return this.unwrapURL(url.JARFile); + } + } + catch (e) {} + + return url; + }, + + + get _channelFlags() { + delete this._channelFlags; + const constRx = /^[A-Z_]+$/; + const ff = {}; + [Ci.nsIHttpChannel, Ci.nsICachingChannel].forEach(function(c) { + for (var p in c) { + if (constRx.test(p)) ff[p] = c[p]; + } + }); + return this._channelFlags = ff; + }, + humanFlags: function(loadFlags) { + var hf = []; + var c = this._channelFlags; + for (var p in c) { + if (loadFlags & c[p]) hf.push(p + "=" + c[p]); + } + return hf.join("\n"); + }, + + queryNotificationCallbacks: function(chan, iid) { + var cb; + try { + cb = chan.notificationCallbacks.getInterface(iid); + if (cb) return cb; + } catch(e) {} + + try { + return chan.loadGroup && chan.loadGroup.notificationCallbacks.getInterface(iid); + } catch(e) {} + + return null; + }, + + + anonymizeURI: function(uri, cookie) { + if (uri instanceof Ci.nsIURL) { + uri.query = this.anonymizeQS(uri.query, cookie); + } else return this.anonymizeURL(uri, cookie); + return uri; + }, + anonymizeURL: function(url, cookie) { + var parts = url.split("?"); + if (parts.length < 2) return url; + parts[1] = this.anonymizeQS(parts[1], cookie); + return parts.join("?"); + }, + + _splitName: function(nv) nv.split("=")[0], + _qsRx: /[&=]/, + _anonRx: /(?:auth|s\w+(?:id|key)$)/, + anonymizeQS: function(qs, cookie) { + if (!qs) return qs; + if (!this._qsRx.test(qs)) return ''; + + var cookieNames, hasCookies; + if ((hasCookies = !!cookie)) cookieNames = cookie.split(/\s*;\s*/).map(this._splitName); + + let parms = qs.split("&"); + for (j = parms.length; j-- > 0;) { + let nv = parms[j].split("="); + let name = nv[0]; + if (this._anonRx.test(name) || cookie && cookieNames.indexOf(name) > -1) + parms.splice(j, 1); + } + return parms.join("&"); + }, + + get TLDService() { + delete this.TLDService; + return this.TLDService = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService); + } + +}; + + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/NSS.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/NSS.js new file mode 100644 index 0000000..97a7e78 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/NSS.js @@ -0,0 +1,491 @@ +// Copyright (c) 2011 Moxie Marlinspike <moxie@thoughtcrime.org> +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 3 of the +// License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +// USA + + +/** + * This class manages the ctypes bridge to the NSS (crypto) libraries + * distributed with Mozilla. + * + **/ + +function NSS() { + +} + +NSS.initialize = function(nssPath) { + var sharedLib; + + try { + sharedLib = ctypes.open(nssPath); + } catch (e) { + dump("Failed to find nss3 in installed directory, checking system paths.\n"); + sharedLib = ctypes.open(ctypes.libraryName("nss3")); + } + + NSS.types = new Object(); + + NSS.types.CERTDistNames = ctypes.StructType("CERTDistNames"); + + NSS.types.SECItem = ctypes.StructType("SECItem", + [{'type' : ctypes.int}, + {'data' : ctypes.unsigned_char.ptr}, + {'len' : ctypes.uint32_t}]); + + NSS.types.PLArenaPool = ctypes.StructType("PLArenaPool"); + + NSS.types.CERTCertificateList = ctypes.StructType("CERTCertificateList", + [{'certs' : NSS.types.SECItem.ptr}, + {'len' : ctypes.int}, + {'arena' : NSS.types.PLArenaPool.ptr}]), + + NSS.types.CERTAVA = ctypes.StructType("CERTAVA", + [{'type' : NSS.types.SECItem}, + {'value' : NSS.types.SECItem}]); + + NSS.types.CERTRDN = ctypes.StructType("CERTRDN", + [{'avas' : NSS.types.CERTAVA.ptr.ptr}]); + + NSS.types.SECAlgorithmID = ctypes.StructType("SECAlgorithmID", + [{'algorithm' : NSS.types.SECItem}, + {'parameters' : NSS.types.SECItem}]); + + NSS.types.CERTSignedData = ctypes.StructType("CERTSignedData", + [{'data' : NSS.types.SECItem}, + {'signatureAlgorithm' : NSS.types.SECAlgorithmID}, + {'signature' : NSS.types.SECItem}]); + + NSS.types.CERTOKDomainName = ctypes.StructType("CERTOKDomainName"); + + NSS.types.NSSCertificateStr = ctypes.StructType("NSSCertificateStr"); + + NSS.types.CERTAuthKeyID = ctypes.StructType("CERTAuthKeyID"); + + NSS.types.CERTName = ctypes.StructType("CERTName", + [{'arena' : ctypes.voidptr_t}, + {'rdns' : NSS.types.CERTRDN.ptr.ptr}]); + + NSS.types.CERTValidity = ctypes.StructType("CERTValidity", + [{'arena' : ctypes.voidptr_t}, + {'notBefore' : NSS.types.SECItem}, + {'notAfter' : NSS.types.SECItem}]); + + NSS.types.CERTCertExtension = ctypes.StructType("CERTCertExtension", + [{'id' : NSS.types.SECItem}, + {'critical' : NSS.types.SECItem}, + {'value' : NSS.types.SECItem}]); + + NSS.types.CERTCertDBHandle = ctypes.StructType("CERTCertDBHandle"); + + NSS.types.PK11SlotInfo = ctypes.StructType("PK11SlotInfo"); + + NSS.types.PK11SlotListElement = ctypes.StructType("PK11SlotListElement", + [{'next' : ctypes.StructType("PK11SlotListElement").ptr}, + {'prev' : ctypes.StructType("PK11SlotListElement").ptr}, + {'slot' : NSS.types.PK11SlotInfo.ptr}, + {'refCount' : ctypes.int}]), + + NSS.types.PK11SlotList = ctypes.StructType("PK11SlotList", + [{'head' : NSS.types.PK11SlotListElement.ptr}, + {'tail' : NSS.types.PK11SlotListElement.ptr}, + {'lock' : ctypes.StructType("PZLock").ptr}]), + + NSS.types.SECKEYPrivateKey = ctypes.StructType("SECKEYPrivateKey", + [{'arena' : NSS.types.PLArenaPool.ptr}, + {'keyType' : ctypes.int}, + {'pkcs11Slot' : NSS.types.PK11SlotInfo.ptr}, + {'pkcs11ID' : ctypes.unsigned_long}, + {'pkcs11IsTemp' : ctypes.int}, + {'wincx' : ctypes.voidptr_t}, + {'staticflags' : ctypes.int32_t}]); + + NSS.types.SECKEYPublicKey = ctypes.StructType("SECKEYPublicKey"); + + NSS.types.CERTSubjectPublicKeyInfo = ctypes.StructType("CERTSubjectPublicKeyInfo", + [{'arena' : NSS.types.PLArenaPool.ptr}, + {'algorithm' : NSS.types.SECAlgorithmID}, + {'subjectPublicKey' : NSS.types.SECItem}]); + + NSS.types.CERTCertificateRequest = ctypes.StructType("CERTCertificateRequest"); + + NSS.types.SEC_ASN1Template = ctypes.StructType("SEC_ASN1Template", + [{'kind' : ctypes.unsigned_long}, + {'offset' : ctypes.unsigned_long}, + {'sub' : ctypes.voidptr_t}, + {'size' : ctypes.unsigned_int}]); + + NSS.types.PK11RSAGenParams = ctypes.StructType("PK11RSAGenParams", + [{'keySizeInBits' : ctypes.int}, + {'pe' : ctypes.unsigned_long}]); + + NSS.types.CERTCertTrust = ctypes.StructType("CERTCertTrust", + [{'sslFlags' : ctypes.uint32_t}, + {'emailFlags' : ctypes.uint32_t}, + {'objectSigningFlags' : ctypes.uint32_t}]); + + NSS.types.CERTSubjectList = ctypes.StructType("CERTSubjectList"); + + NSS.types.CERTGeneralName = ctypes.StructType("CERTGeneralName"); + + NSS.types.CERTCertificate = ctypes.StructType("CERTCertificate", + [{'arena' : NSS.types.PLArenaPool.ptr}, + {'subjectName' : ctypes.char.ptr}, + {'issuerName' : ctypes.char.ptr}, + {'signatureWrap' : NSS.types.CERTSignedData}, + {'derCert' : NSS.types.SECItem}, + {'derIssuer' : NSS.types.SECItem}, + {'derSubject' : NSS.types.SECItem}, + {'derPublicKey' : NSS.types.SECItem}, + {'certKey' : NSS.types.SECItem}, + {'version' : NSS.types.SECItem}, + {'serialNumber' : NSS.types.SECItem}, + {'signature' : NSS.types.SECAlgorithmID}, + {'issuer' : NSS.types.CERTName}, + {'validity' : NSS.types.CERTValidity}, + {'subject' : NSS.types.CERTName}, + {'subjectPublicKeyInfo' : NSS.types.CERTSubjectPublicKeyInfo}, + {'issuerID' : NSS.types.SECItem}, + {'subjectID' : NSS.types.SECItem}, + {'extensions' : NSS.types.CERTCertExtension.ptr.ptr}, + {'emailAddr' : ctypes.char.ptr}, + {'dbhandle' : NSS.types.CERTCertDBHandle.ptr}, + {'subjectKeyID' : NSS.types.SECItem}, + {'keyIDGenerated' : ctypes.int}, + {'keyUsage' : ctypes.unsigned_int}, + {'rawKeyUsage' : ctypes.unsigned_int}, + {'keyUsagePresent' : ctypes.int}, + {'nsCertType' : ctypes.uint32_t}, + {'keepSession' : ctypes.int}, + {'timeOK' : ctypes.int}, + {'domainOK' : NSS.types.CERTOKDomainName.ptr}, + {'isperm' : ctypes.int}, + {'istemp' : ctypes.int}, + {'nickname' : ctypes.char.ptr}, + {'dbnickname' : ctypes.char.ptr}, + {'nssCertificate' : NSS.types.NSSCertificateStr.ptr}, + {'trust' : NSS.types.CERTCertTrust.ptr}, + {'referenceCount' : ctypes.int}, + {'subjectList' : NSS.types.CERTSubjectList.ptr}, + {'authKeyID' : NSS.types.CERTAuthKeyID.ptr}, + {'isRoot' : ctypes.int}, + {'options' : ctypes.voidptr_t}, + {'series' : ctypes.int}, + {'slot' : NSS.types.PK11SlotInfo.ptr}, + {'pkcs11ID' : ctypes.unsigned_long}, + {'ownSlot' : ctypes.int}]); + + NSS.types.CERTBasicConstraints = ctypes.StructType("CERTBasicConstraints", + [{'isCA': ctypes.int}, + {'pathLenConstraint' : ctypes.int}]); + + + NSS.lib = { + SEC_OID_MD5 : 3, + SEC_OID_SHA1 : 4, + SEC_OID_X509_KEY_USAGE : 81, + SEC_OID_NS_CERT_EXT_COMMENT : 75, + CKM_RSA_PKCS_KEY_PAIR_GEN : 0, + buffer : ctypes.ArrayType(ctypes.char), + ubuffer : ctypes.ArrayType(ctypes.unsigned_char), + + // CERT_CertificateTemplate : sharedLib.declare("CERT_CertificateTemplate", + // NSS.types.SEC_ASN1Template), + + NSS_Get_CERT_CertificateTemplate : sharedLib.declare("NSS_Get_CERT_CertificateTemplate", + ctypes.default_abi, + NSS.types.SEC_ASN1Template.ptr), + + PK11_HashBuf : sharedLib.declare("PK11_HashBuf", + ctypes.default_abi, + ctypes.int, + ctypes.int, + ctypes.unsigned_char.ptr, + ctypes.unsigned_char.ptr, + ctypes.int32_t), + + CERT_GetDefaultCertDB : sharedLib.declare("CERT_GetDefaultCertDB", + ctypes.default_abi, + NSS.types.CERTCertDBHandle.ptr), + + CERT_ChangeCertTrust : sharedLib.declare("CERT_ChangeCertTrust", + ctypes.default_abi, + ctypes.int32_t, + NSS.types.CERTCertDBHandle.ptr, + NSS.types.CERTCertificate.ptr, + NSS.types.CERTCertTrust.ptr), + + CERT_FindCertByNickname : sharedLib.declare("CERT_FindCertByNickname", + ctypes.default_abi, + NSS.types.CERTCertificate.ptr, + NSS.types.CERTCertDBHandle.ptr, + ctypes.char.ptr), + + CERT_FindCertByDERCert : sharedLib.declare("CERT_FindCertByDERCert", + ctypes.default_abi, + NSS.types.CERTCertificate.ptr, + NSS.types.CERTCertDBHandle.ptr, + NSS.types.SECItem.ptr), + + CERT_VerifyCertNow : sharedLib.declare("CERT_VerifyCertNow", + ctypes.default_abi, + ctypes.int, + NSS.types.CERTCertDBHandle.ptr, + NSS.types.CERTCertificate.ptr, + ctypes.int, + ctypes.int, + ctypes.voidptr_t), + + CERT_CertChainFromCert : sharedLib.declare("CERT_CertChainFromCert", + ctypes.default_abi, + NSS.types.CERTCertificateList.ptr, + NSS.types.CERTCertificate.ptr, + ctypes.int, + ctypes.int), + + PK11_FindKeyByAnyCert : sharedLib.declare("PK11_FindKeyByAnyCert", + ctypes.default_abi, + NSS.types.SECKEYPrivateKey.ptr, + NSS.types.CERTCertificate.ptr, + ctypes.voidptr_t), + + PK11_GetInternalKeySlot : sharedLib.declare("PK11_GetInternalKeySlot", + ctypes.default_abi, + NSS.types.PK11SlotInfo.ptr), + + PK11_GetAllSlotsForCert : sharedLib.declare("PK11_GetAllSlotsForCert", + ctypes.default_abi, + NSS.types.PK11SlotList.ptr, + NSS.types.CERTCertificate.ptr, + ctypes.voidptr_t), + + PK11_GetTokenName : sharedLib.declare("PK11_GetTokenName", + ctypes.default_abi, + ctypes.char.ptr, + NSS.types.PK11SlotInfo.ptr), + + PK11_GenerateKeyPair : sharedLib.declare("PK11_GenerateKeyPair", + ctypes.default_abi, + NSS.types.SECKEYPrivateKey.ptr, + NSS.types.PK11SlotInfo.ptr, + ctypes.int, + NSS.types.PK11RSAGenParams.ptr, + NSS.types.SECKEYPublicKey.ptr.ptr, + ctypes.int, + ctypes.int, + ctypes.voidptr_t), + + PK11_SetPrivateKeyNickname : sharedLib.declare("PK11_SetPrivateKeyNickname", + ctypes.default_abi, + ctypes.int, + NSS.types.SECKEYPrivateKey.ptr, + ctypes.char.ptr), + + SEC_ASN1EncodeItem : sharedLib.declare("SEC_ASN1EncodeItem", + ctypes.default_abi, + NSS.types.SECItem.ptr, + NSS.types.PLArenaPool.ptr, + NSS.types.SECItem.ptr, + ctypes.voidptr_t, + NSS.types.SEC_ASN1Template.ptr), + + SEC_DerSignData : sharedLib.declare("SEC_DerSignData", + ctypes.default_abi, + ctypes.int, + NSS.types.PLArenaPool.ptr, + NSS.types.SECItem.ptr, + ctypes.unsigned_char.ptr, + ctypes.int, + NSS.types.SECKEYPrivateKey.ptr, + ctypes.int), + + SEC_GetSignatureAlgorithmOidTag : sharedLib.declare("SEC_GetSignatureAlgorithmOidTag", + ctypes.default_abi, + ctypes.int, + ctypes.int, + ctypes.int), + + SECOID_SetAlgorithmID : sharedLib.declare("SECOID_SetAlgorithmID", + ctypes.default_abi, + ctypes.int, + NSS.types.PLArenaPool.ptr, + NSS.types.SECAlgorithmID.ptr, + ctypes.int, + NSS.types.SECItem.ptr), + + + CERT_Hexify : sharedLib.declare("CERT_Hexify", + ctypes.default_abi, + ctypes.char.ptr, + NSS.types.SECItem.ptr, + ctypes.int), + + CERT_AsciiToName : sharedLib.declare("CERT_AsciiToName", + ctypes.default_abi, + NSS.types.CERTName.ptr, + ctypes.char.ptr), + + SECKEY_CreateSubjectPublicKeyInfo : sharedLib.declare("SECKEY_CreateSubjectPublicKeyInfo", + ctypes.default_abi, + NSS.types.CERTSubjectPublicKeyInfo.ptr, + NSS.types.SECKEYPublicKey.ptr), + + CERT_CreateCertificateRequest : sharedLib.declare("CERT_CreateCertificateRequest", + ctypes.default_abi, + NSS.types.CERTCertificateRequest.ptr, + NSS.types.CERTName.ptr, + NSS.types.CERTSubjectPublicKeyInfo.ptr, + NSS.types.SECItem.ptr.ptr), + + CERT_CreateCertificate : sharedLib.declare("CERT_CreateCertificate", + ctypes.default_abi, + NSS.types.CERTCertificate.ptr, + ctypes.uint32_t, + NSS.types.CERTName.ptr, + NSS.types.CERTValidity.ptr, + NSS.types.CERTCertificateRequest.ptr), + + CERT_DestroyCertificate : sharedLib.declare("CERT_DestroyCertificate", + ctypes.default_abi, + ctypes.int, + NSS.types.CERTCertificate.ptr), + + CERT_DestroyCertificateList : sharedLib.declare("CERT_DestroyCertificateList", + ctypes.default_abi, + ctypes.int, + NSS.types.CERTCertificateList.ptr), + + CERT_NewTempCertificate : sharedLib.declare("CERT_NewTempCertificate", + ctypes.default_abi, + NSS.types.CERTCertificate.ptr, + NSS.types.CERTCertDBHandle.ptr, + NSS.types.SECItem.ptr, + ctypes.char.ptr, + ctypes.int, + ctypes.int), + + CERT_CreateValidity : sharedLib.declare("CERT_CreateValidity", + ctypes.default_abi, + NSS.types.CERTValidity.ptr, + ctypes.int64_t, + ctypes.int64_t), + + CERT_CertListFromCert : sharedLib.declare("CERT_CertListFromCert", + ctypes.default_abi, + NSS.types.CERTCertificateList.ptr, + NSS.types.CERTCertificate.ptr), + + CERT_StartCertExtensions : sharedLib.declare("CERT_StartCertExtensions", + ctypes.default_abi, + ctypes.voidptr_t, + NSS.types.CERTCertificate.ptr), + + CERT_AddExtension : sharedLib.declare("CERT_AddExtension", + ctypes.default_abi, + ctypes.int, + ctypes.voidptr_t, + ctypes.int, + NSS.types.SECItem.ptr, + ctypes.int, + ctypes.int), + + + CERT_EncodeBasicConstraintValue : sharedLib.declare("CERT_EncodeBasicConstraintValue", + ctypes.default_abi, + ctypes.int, + NSS.types.PLArenaPool.ptr, + NSS.types.CERTBasicConstraints.ptr, + NSS.types.SECItem.ptr), + + CERT_EncodeAndAddBitStrExtension : sharedLib.declare("CERT_EncodeAndAddBitStrExtension", + ctypes.default_abi, + ctypes.int, + ctypes.voidptr_t, + ctypes.int, + NSS.types.SECItem.ptr, + ctypes.int), + + CERT_EncodeAltNameExtension : sharedLib.declare("CERT_EncodeAltNameExtension", + ctypes.default_abi, + ctypes.int, + NSS.types.PLArenaPool.ptr, + NSS.types.CERTGeneralName.ptr, + NSS.types.SECItem.ptr), + + CERT_FinishExtensions : sharedLib.declare("CERT_FinishExtensions", + ctypes.default_abi, + ctypes.int, + ctypes.voidptr_t), + + CERT_ImportCerts : sharedLib.declare("CERT_ImportCerts", + ctypes.default_abi, + ctypes.int, + NSS.types.CERTCertDBHandle.ptr, + ctypes.int, + ctypes.int, + NSS.types.SECItem.ptr.ptr, + NSS.types.CERTCertificate.ptr.ptr.ptr, + ctypes.int, + ctypes.int, + ctypes.char.ptr), + + PORT_NewArena : sharedLib.declare("PORT_NewArena", + ctypes.default_abi, + NSS.types.PLArenaPool.ptr, + ctypes.uint32_t), + + PORT_ArenaZAlloc : sharedLib.declare("PORT_ArenaZAlloc", + ctypes.default_abi, + ctypes.voidptr_t, + NSS.types.PLArenaPool.ptr, + ctypes.int), + + PORT_FreeArena : sharedLib.declare("PORT_FreeArena", + ctypes.default_abi, + ctypes.void_t, + NSS.types.PLArenaPool.ptr, + ctypes.int), + + CERT_GetCommonName : sharedLib.declare("CERT_GetCommonName", + ctypes.default_abi, + ctypes.char.ptr, + NSS.types.CERTName.ptr), + + CERT_GetOrgUnitName : sharedLib.declare("CERT_GetOrgUnitName", + ctypes.default_abi, + ctypes.char.ptr, + NSS.types.CERTName.ptr), + + CERT_GetCertificateNames : sharedLib.declare("CERT_GetCertificateNames", + ctypes.default_abi, + NSS.types.CERTGeneralName.ptr, + NSS.types.CERTCertificate.ptr, + NSS.types.PLArenaPool.ptr), + + CERT_DecodeDERCertificate : sharedLib.declare("__CERT_DecodeDERCertificate", + ctypes.default_abi, + NSS.types.CERTCertificate.ptr, + NSS.types.SECItem.ptr, + ctypes.int, + ctypes.char.ptr), + + CERT_FindCertExtension : sharedLib.declare("CERT_FindCertExtension", + ctypes.default_abi, + ctypes.int, + NSS.types.CERTCertificate.ptr, + ctypes.int, + NSS.types.SECItem.ptr), + }; + +}; diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/Root-CAs.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/Root-CAs.js new file mode 100644 index 0000000..49777fa --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/Root-CAs.js @@ -0,0 +1,348 @@ +// These are concatenated md5 and sha1 fingerprints for the Firefox and +// Microsoft root CAs as of Aug 2010 + +root_ca_hashes = { + '00531D1D7201D423C820D00B6088C5D143DDB1FFF3B49B73831407F6BC8B975023D07C50' : true, + '015A99C3D64FA94B3C3BB1A3AB274CBFFC219A76112F76C1C508833C9A2FA2BA84AC087A' : true, + '019408DE857F8D806CE602CA89522848750251B2C632536F9D917279543C137CD721C6E0' : true, + '0208EE8CAAB8387A6824DCB4E26A52337E206939CC5FA883635F64C750EBF5FDA9AEE653' : true, + '0226C3015E08303743A9D07DCF37E6BF323C118E1BF7B8B65254E2E2100DD6029037F096' : true, + '034287D7C1167D18AFA4703CB8312C3E4EF2E6670AC9B5091FE06BE0E5483EAAD6BA32D9' : true, + '03DC08EEC4703FFA20E5E179E81AE7C59ED18028FB1E8A9701480A7890A59ACD73DFF871' : true, + '044BFDC96CDA2A32857C598461468A64BEB5A995746B9EDF738B56E6DF437A77BE106B81' : true, + '0468E9247E41CED76C441630703DDDB9AB16DD144ECDC0FC4BAAB62ECF0408896FDE52B7' : true, + '068690F2195471FDDD3DE6EEA161CAFF7030AABF8432A800666CCCC42A887E42B7553E2B' : true, + '069F6979166690021B8C8CA2C3076F3A627F8D7827656399D27D7F9044C9FEB3F33EFA9A' : true, + '06F0171EB1E961ED7A363CA594A1374AFAAA27B8CAF5FDF5CDA98AC3378572E04CE8F2E0' : true, + '06F9EBECCC569D88BA90F5BAB01AE00216D424FE9610E17519AF232BB68774E24144BE6E' : true, + '076192047EA6B9CD5E6B007AE3BF1D0434D499426F9FC2BB27B075BAB682AAE5EFFCBA74' : true, + '087C581F522B44B43B79CD01F8C5C3C995E6ADF8D77146024DD56A21B2E73FCDF23B35FF' : true, + '0B092C1CD721866F94376FE6A7F3224D0409565B77DA582E6495AC0060A72354E64B0192' : true, + '0C412F135BA054F596662D7ECD0E03F4DA79C1711150C23439AA2B0B0C62FD55B2F9F580' : true, + '0C5ADD5AAE29F7A77679FA4151FEF035B865130BEDCA38D27F69929420770BED86EFBC10' : true, + '0C7FDD6AF42AB9C89BBD207EA9DB5C3760D68974B5C2659E8A0FC1887C88D246691B182C' : true, + '0CF89E17FCD403BDE68D9B3C0587FE8433A335C23CE8034B04E13DE5C48E791AEB8C3204' : true, + '0E40A76CDE035D8FD10FE4D18DF96CA9A9E9780814375888F20519B06D2B0D2B6016907D' : true, + '0EFA4BF7D760CD65F7A7068857986239D29F6C98BEFC6D986521543EE8BE56CEBC288CF3' : true, + '0FA01300C3558AB7D37E2D04739EDE3C8B1A1106B8E26B232980FD652E6181376441FD11' : true, + '100EADF35C841D8E035F2DC93937F552742CDF1594049CBF17A2046CC639BB3888E02E33' : true, + '10FC635DF6263E0DF325BE5F79CD6767742C3192E607E424EB4549542BE1BBC53E6174E2' : true, + '119279403CB18340E5AB664A679280DFA9628F4B98A91B4835BAD2C1463286BB66646A8C' : true, + '14F108AD9DFA64E289E71CCFA8AD7D5E3921C115C15D0ECA5CCB5BC4F07D21D8050B566A' : true, + '155EF5117AA2C1150E927E66FE3B84C3B38FECEC0B148AA686C3D00F01ECC8848E8085EB' : true, + '15ACA5C2922D79BCE87FCB67ED02CF36E7B4F69D61EC9069DB7E90A7401A3CF47D4FE8EE' : true, + '15B298A354704048703A375582C45AFA0048F8D37B153F6EA2798C323EF4F318A5624A9E' : true, + '15EE9F5AA08528DF6BDD34A3A056D8307F8A77836BDC6D068F8B0737FCC5725413068CA4' : true, + '160A1613C17FF01D887EE3D9E71261CCF88015D3F98479E1DA553D24FD42BA3F43886AEF' : true, + '173574AF7B611CEBF4F93CE2EE40F9A2925A8F8D2C6D04E0665F596AFF22D863E8256F3F' : true, + '1802B00127036A191B323B83DE9AA985D6BF7994F42BE5FA29DA0BD7587B591F47A44F22' : true, + '1898C0D6E93AFCF9B0F50CF74B014417FAB7EE36972662FB2DB02AF6BF03FDE87C4B2F9B' : true, + '18AE695D15CAB917673267D597B260C04BA7B9DDD68788E12FF852E1A024204BF286A8F6' : true, + '1AD00CB9A6E68A3B6E95860C5B8CD8195A4D0E8B5FDCFDF64E7299A36C060DB222CA78E4' : true, + '1B2E00CA2606903DADFE6F1568D36BB367650DF17E8E7E5B8240A4F4564BCFE23D69C6F0' : true, + '1BD75F76734CC0DC98CA442BCC0F78DD31E2C52CE1089BEFFDDADB26DD7C782EBC4037BD' : true, + '1C4BE2C62DB9AC3114F4400769CB1F4011C5B5F75552B011669C2E9717DE6D9BFF5FA810' : true, + '1D3554048578B03F42424DBF20730A3F02FAF3E291435468607857694DF5E45B68851868' : true, + '1D6496AF2D821A300BA0620D76BC53AA7FBB6ACD7E0AB438DAAF6FD50210D007C6C0829C' : true, + '1E240EA0F876D785A3F5F8A1493D2EBAFD1ED1E2021B0B9F73E8EB75CE23436BBCC746EB' : true, + '1E42950233926BB95FC07FDAD6B24BFCCCAB0EA04C2301D6697BDD379FCD12EB24E3949D' : true, + '1E74C3863C0C35C53EC27FEF3CAA3CD9209900B63D955728140CD13622D8C687A4EB0085' : true, + '200B4A7A88A7A942868A5F74567B880593E6AB220303B52328DCDA569EBAE4D1D1CCFB65' : true, + '206BD68B4A8F48ABE488090DE5651A500CFD83DBAE44B9A0C8F676F3B570650B94B69DBF' : true, + '2124A681C1D8F219AF4998E39DFE0BF46A174570A916FBE84453EED3D070A1D8DA442829' : true, + '21BC82AB49C4133B4BB22B5C6B909C198BAF4C9B1DF02A92F7DA128EB91BACF498604B6F' : true, + '21D84C822B990933A2EB14248D8E5FE84054DA6F1C3F4074ACED0FECCDDB79D153FB901D' : true, + '21EFB85040393F756F27FEE3EA5870EBA59C9B10EC7357515ABB660C4D94F73B9E6E9272' : true, + '222DA601EA7C0AF7F06C56433F7776D3FEB8C432DCF9769ACEAE3DD8908FFD288665647D' : true, + '224D8F8AFCF735C2BB5734907B8B22163E2BF7F2031B96F38CE6C4D8A85D3E2D58476A0F' : true, + '246DABD2F2EA4A66AE5BBCAE50AD6E56F9DD19266B2043F1FE4B3DCB0190AFF11F31A69D' : true, + '2477D9A891D13BFA882DC2FFF8CD3393D8C5388AB7301B1B6ED47AE645253A6F9F1A2761' : true, + '252AC6C5896839F9557202165EA39ED23C71D70E35A5DAA8B2E3812DC3677417F5990DF3' : true, + '255BA669B87BF8780DC18FA6EAE47063FA0882595F9CA6A11ECCBEAF65C764C0CCC311D0' : true, + '257ABA832EB6A20BDAFEF5020F08D7AD81968B3AEF1CDC70F5FA3269C292A3635BD123D3' : true, + '259DCF5EB3259D95B93F00865F47943D43F9B110D5BAFD48225231B0D0082B372FEF9A54' : true, + '266D2C1998B6706838505419EC9034600B77BEBBCB7AA24705DECC0FBD6A02FC7ABD9B52' : true, + '27DE36FE72B70003009DF4F01E6C0424DE3F40BD5093D39B6C60F6DABC076201008976C9' : true, + '27EC3947CDDA5AAFE29A016521A94CBB4D2378EC919539B5007F758F033B211EC54D8BCF' : true, + '2A5D003739469475397B11A6F29341E13F85F2BB4A62B0B58BE1614ABB0D4631B4BEF8BA' : true, + '2A954ECA79B2874573D92D90BAF99FB6A43489159A520F0D93D032CCAF37E7FE20A8B419' : true, + '2B508718392D3BFFC3917F2D7DC08A97B19DD096DCD4E3E0FD676885505A672C438D4E9C' : true, + '2B7020568682A018C807531228702172F17F6FB631DC99E3A3C87FFE1CF1811088D96033' : true, + '2C20269DCB1A4A0085B5B75AAEC201378C96BAEBDD2B070748EE303266A0F3986E7CAE58' : true, + '2C6F17A39562012065D2076EFCB83F6DB1EAC3E5B82476E9D50B1EC67D2CC11E12E0B491' : true, + '2C8C175EB154AB9317B5365ADBD1C6F2A073E5C5BD43610D864C21130A855857CC9CEA46' : true, + '2C8F9F661D1890B147269D8E86828CA96252DC40F71143A22FDE9EF7348E064251B18118' : true, + '2CC2B0D5D622C52E901EF4633F0FBB324A058FDFD761DB21B0C2EE48579BE27F42A4DA1C' : true, + '2DBBE525D3D165823AB70EFAE6EBE2E1B3EAC44776C9C81CEAF29D95B6CCA0081B67EC9D' : true, + '2E03FDC5F5D72B9464C1BE8931F1169B96995C7711E8E52DF9E34BECEC67D3CBF1B6C4D2' : true, + '30C908DDD73E63A4092814C74EB97E2CCFE4313DBA05B8A7C30063995A9EB7C247AD8FD5' : true, + '30C9E71E6BE614EB65B216692031674D3BC0380B33C3F6A60C86152293D9DFF54B81C004' : true, + '31853C62949763B9AAFD894EAF6FE0CF1F4914F7D874951DDDAE02C0BEFD3A2D82755185' : true, + '324A4BBBC863699BBE749AC6DD1D4624AD7E1C28B064EF8F6003402014C3D0E3370EB58A' : true, + '3327D16CFC9185FC8C7E98FA854EF305E70715F6F728365B5190E271DEE4C65EBEEACAF3' : true, + '33B784F55F27D76827DE14DE122AED6F0747220199CE74B97CB03D79B264A2C855E933FF' : true, + '343339FC6D033A8FA25385443270DEC45E5A168867BFFF00987D0B1DC2AB466C4264F956' : true, + '34FCB8D036DB9E14B3C2F2DB8FE494C7379A197B418545350CA60369F33C2EAF474F2079' : true, + '354895364A545A72968EE064CCEF2C8CC90D1BEA883DA7D117BE3B79F4210E1A5894A72D' : true, + '370971C4AFEB7501AE636C3016BFD1E5A399F76F0CBF4C9DA55E4AC24E8960984B2905B6' : true, + '3741491B18569A26F5ADC266FB40A54C4313BB96F1D5869BC14E6A92F6CFF63469878237' : true, + '3785445332451F20F0F395E125C4434EF48B11BFDEABBE94542071E641DE6BBE882B40B9' : true, + '37A56ED4B1258497B7FD56157AF9A200B435D4E1119D1C6690A749EBB394BD637BA782B7' : true, + '3916AAB96A41E11469DF9E6C3B72DCB6879F4BEE05DF98583BE360D633E70D3FFE9871AF' : true, + '3AB2DE229A209349F9EDC8D28AE7680D36863563FD5128C7BEA6F005CFE9B43668086CCE' : true, + '3AE550B039BEC7463633A1FE823E8D943CBB5DE0FCD6397C0588E56697BD462ABDF95C76' : true, + '3B0AE4BB416A84B39D2C575E6542BE478E1032E9245944F84791983EC9E829CB1059B4D3' : true, + '3C4C25CC0A19CAEE6AEB55160086725F23E833233E7D0CC92B7C4279AC19C2F474D604CA' : true, + '3D4129CB1EAA1174CD5DB062AFB0435BDDE1D2A901802E1D875E84B3807E4BB1FD994134' : true, + '3E455215095192E1B75D379FB187298AB1BC968BD4F49D622AA89A81F2150152A41D829C' : true, + '3E80175BADD77C104BF941B0CF1642B000EA522C8A9C06AA3ECCE0B4FA6CDC21D92E8099' : true, + '3F459639E25087F7BBFE980C3C2098E62AC8D58B57CEBF2F49AFF2FC768F511462907A41' : true, + '400125068D21436A0E43009CE743F3D5F9CD0E2CDA7624C18FBDF0F0ABB645B8F7FED57A' : true, + '410352DC0FF7501B16F0028EBA6F45C5DAC9024F54D8F6DF94935FB1732638CA6AD77C13' : true, + '41B807F7A8D109EEB49A8E704DFC1B787A74410FB0CD5C972A364B71BF031D88A6510E9E' : true, + '4265CABE019A9A4CA98C4149CDC0D57F293621028B20ED02F566C532D1D6ED909F45002F' : true, + '42769768CFA6B43824AAA11BF267DECA4178AB4CBFCE7B4102ACDAC4933E6FF50DCF715C' : true, + '4281A0E21CE35510DE558942659622E6E0B4322EB2F6A568B654538448184A5036874384' : true, + '429BD669C6D445AD2E81511D355A89624F555CE20DCD3364E0DC7C41EFDD40F50356C122' : true, + '45E1A572C5A93664409EF5E45884678C6B2F34AD8958BE62FDB06B5CCEBB9DD94F4E39F3' : true, + '45F750114EC5ADBD53688663EC7B6AE1C09AB0C8AD7114714ED5E21A5A276ADCD5E7EFCB' : true, + '468C210EAB92214659DBA6DB0061DE265A5A4DAF7861267C4B1F1E67586BAE6ED4FEB93F' : true, + '48D11E627801C26E4369A42CEE130AB564902AD7277AF3E32CD8CC1DC79DE1FD7F8069EA' : true, + '4963AE27F4D5953DD8DB2486B89C0753D3C063F219ED073E34AD5D750B327629FFD59AF2' : true, + '497904B0EB8719AC47B0BC11519B74D0D1EB23A46D17D68FD92564C2F1F1601764D8E349' : true, + '49EFA6A1F0DE8EA76AEE5B7D1E5FC4463E42A18706BD0C9CCF594750D2E4D6AB0048FDC4' : true, + '4B1C568CA0E8C79E1EF5EE32939965FE4C95A9902ABE0777CED18D6ACCC3372D2748381E' : true, + '4B6771BE33B90DB64B3A400187F08B1F7AC5FFF8DCBC5583176877073BF751735E9BD358' : true, + '4B798DD41D0392AA51EE04E5906F474954F9C163759F19045121A319F64C2D0555B7E073' : true, + '4BE2C99196650CF40E5A9392A00AFEB28CF427FD790C3AD166068DE81E57EFBB932272D4' : true, + '4C5641E50DBB2BE8CAA3ED1808AD43390483ED3399AC3608058722EDBC5E4600E3BEF9D7' : true, + '4D56677ECCE6457259B74F511172E169C0DB578157E9EE82B5917DF0DD6D82EE9039C4E2' : true, + '4FEBF1F070C280635D589FDA123CA9C4E392512F0ACFF505DFF6DE067F7537E165EA574B' : true, + '50193E2FE8B6F4055449F3AEC98B3E1947AFB915CDA26D82467B97FA42914468726138DD' : true, + '5186E81FBCB1C371B51810DB5FDCF62078E9DD0650624DB9CB36B50767F209B843BE15B3' : true, + '556EBEF54C1D7C0360C43418BC9649C1245C97DF7514E7CF2DF8BE72AE957B9E04741E85' : true, + '565FAA80611217F66721E62B6D61568E8025EFF46E70C8D472246584FE403B8A8D6ADBF5' : true, + '58EB470764D62CBAE29B96552B9700B56A6F2A8B6E2615088DF59CD24C402418AE42A3F1' : true, + '59736628512B98B410FF7D06FA22D6C8A0F8DB3F0BF417693B282EB74A6AD86DF9D448A3' : true, + '5A11B922850289E1C3F22CE14EC101844B421F7515F6AE8A6ECEF97F6982A400A4D9224E' : true, + '5B6F532CBB8188FA6C042C325DA56B967CA04FD8064C1CAA32A37AA94375038E8DF8DDC0' : true, + '5B9EFD3B6035EA688E52FE1319144AA36B81446A5CDDF474A0F800FFBE69FD0DB6287516' : true, + '5C48DCF74272EC56946D1CCC713580756631BF9EF74F9EB6C9D5A60CBA6ABED1F7BDEF7B' : true, + '5E397BDDF8BAEC82E9AC62BA0C54002BCA3AFBCF1240364B44B216208880483919937CF7' : true, + '5E809E845A0E650B1702F355182A3ED7786A74AC76AB147F9C6A3050BA9EA87EFE9ACE3C' : true, + '5F944A7322B8F7D131EC5939F78EFE6E9FC796E8F8524F863AE1496D381242105F1B78F5' : true, + '60847C5ACEDB0CD4CBA7E9FE02C6A9C0101DFA3FD50BCBBB9BB5600C1955A41AF4733A04' : true, + '649CEF2E44FCC68F5207D051738FCB3DDA40188B9189A3EDEEAEDA97FE2F9DF5B7D18A41' : true, + '65295911BB8F5166890D47824002C5AFC4674DDC6CE2967FF9C92E072EF8E8A7FBD6A131' : true, + '6558AB15AD576C1EA8A7B569ACBFFFEBE5DF743CB601C49B9843DCAB8CE86A81109FE48E' : true, + '67AC0D773011DED143AE7B737190BCA9ED8DC8386C4886AEEE079158AAC3BFE658E394B4' : true, + '67CB9DC013248A829BB2171ED11BECD4D23209AD23D314232174E40D7F9D62139786633A' : true, + '689B17C654E0E0E099551642F75A86D8027268293E5F5D17AAA4B3C3E6361E1F92575EAA' : true, + '6960ECBE8C94D76E6F2EC4782F55F08397226AAE4A7A64A59BD16787F27F841C0A001FD0' : true, + '6C397DA40E5559B23FD641B11250DE435F3B8CF2F810B37D78B4CEEC1919C37334B9C774' : true, + '6CC9A76E47F10CE3533B784C4DC26AC5B72FFF92D2CE43DE0A8D4C548C503726A81E2B93' : true, + '6D38C49B22244CA3A8B3A09345E157FA89C32E6B524E4D65388B9ECEDC637134ED4193A3' : true, + '70B57C4881953E80DC289BBAEF1EE4854072BA31FEC351438480F62E6CB95508461EAB2F' : true, + '711F0E21E7AAEA323A6623D3AB50D66996974CD6B663A7184526B1D648AD815CF51E801A' : true, + '71AA6AAF1FA5C0D50E90D40BF6AADFCC55C86F7414AC8BDD6814F4D86AF15F3710E104D0' : true, + '71E265FBCD7B0B845BE3BCD76320C598CFF810FB2C4FFC0156BFE1E1FABCB418C68D31C5' : true, + '72E44A87E369408077EABCE3F4FFF0E15F43E5B1BFF8788CAC1CC7CA4A9AC6222BCC34C6' : true, + '733A747AECBBA396A6C2E4E2C89BC0C3AEC5FB3FC8E1BFC4E54F03075A9AE800B7F7B6FA' : true, + '739DD35FC63C95FEC6ED89E58208DD897FB9E2C995C97A939F9E81A07AEA9B4D70463496' : true, + '74014A91B108C458CE47CDF0DD11530885A408C09C193E5D51587DCDD61330FD8CDE37BF' : true, + '747B820343F0009E6BB3EC47BF85A5934463C531D7CCC1006794612BB656D3BF8257846F' : true, + '74A82C81432B35609B78056B58F36582CFF360F524CB20F1FEAD89006F7F586A285B2D5B' : true, + '770D19B121FD00429C3E0CA5DD0B028E25019019CFFBD9991CB76825748D945F30939542' : true, + '774AF42C9DB027B747B515E4C762F0FCDF646DCB7B0FD3A96AEE88C64E2D676711FF9D5F' : true, + '782A02DFDB2E14D5A75F0ADFB68E9C5D4F65566336DB6598581D584A596C87934D5F2AB4' : true, + '78A5FB104BE4632ED26BFBF2B6C24B8EEC0C3716EA9EDFADD35DFBD55608E60A05D3CBF3' : true, + '79E4A9840D7D3A96D7C04FE2434C892EA8985D3A65E5E5C4B2D7D66D40C6DD2FB19C5436' : true, + '7A79544D07923B5BFF41F00EC739A298C060ED44CBD881BD0EF86C0BA287DDCF8167478C' : true, + '7BB508999A8C18BF85277D0EAEDAB2AB24BA6D6C8A5B5837A48DB5FAE919EA675C94D217' : true, + '7C62FF749D31535E684AD578AA1EBF239F744E9F2B4DBAEC0F312C50B6563B8E2D93C311' : true, + '7CA50FF85B9A7D6D30AE545AE342A28A59AF82799186C7B47507CBCF035746EB04DDB716' : true, + '7D86908F5BF1F240C0F73D62B5A4A93B72997913EC9B0DAE65D1B6D7B24A76A3AEC2EE16' : true, + '7E234E5BA7A5B425E90007741162AED67F8AB0CFD051876A66F3360F47C88D8CD335FC74' : true, + '7F667A71D3EB6978209A51149D83DA20BE36A4562FB2EE05DBB3D32323ADF445084ED656' : true, + '803ABC22C1E6FB8D9B3B274A321B9A0147BEABC922EAE80E78783462A79F45C254FDE68B' : true, + '8135B9FBFB12CA186936EBAE6978A1F1DCBB9EB7194BC47205C111752986835B53CAE4F8' : true, + '81D6ED354F1F26D031D040DD8AE5810DE0925E18C7765E22DABD9427529DA6AF4E066428' : true, + '8212F789E10B9160A4B6229F9468119268ED18B309CD5291C0D3357C1D1141BF883866B1' : true, + '824AD493004D66B6A32CA77B3536CF0B687EC17E0602E3CD3F7DFBD7E28D57A0199A3F44' : true, + '8292BA5BEFCD8A6FA63D55F984F6D6B7F9B5B632455F9CBEEC575F80DCE96E2CC7B278B7' : true, + '84901D95304956FC4181F045D776C46B439E525F5A6A47C32CEBC45C63ED39317CE5F4DF' : true, + '852FF4764CD5426CCB5E7DF717E835BD4EFCED9C6BDD0C985CA3C7D253063C5BE6FC620C' : true, + '85CA765A1BD16822DCA22312CAC680345BCDCDCC66F6DCE4441FE37D5CC3134C46F47038' : true, + '86386D5E49636C855CDB6DDC94B7D0F7ACED5F6553FD25CE015F1F7A483B6A749F6178C6' : true, + '86420509BCA79DEC1DF32E0EBAD81DD01D8259CA2127C3CBC16CD932F62C65298CA88712' : true, + '86ACDE2BC56DC3D98C2888D38D16131ECE6A64A309E42FBBD9851C453E6409EAE87D60F1' : true, + '86EF8E319D9F8569A2A41A127168BA1B90DECE77F8C825340E62EBD635E1BE20CF7327DD' : true, + '8714AB83C4041BF193C750E2D721EBEF30779E9315022E94856A3FF8BCF815B082F9AEFD' : true, + '879055F2CE31153C33D927C876E37DE13070F8833E4AA6803E09A646AE3F7D8AE1FD1654' : true, + '87CE0B7B2A0E4900E158719B37A893720563B8630D62D75ABBC8AB1E4BDFB5A899B24D43' : true, + '882C8C52B8A23CF3F7BB03EAAEAC420B74207441729CDD92EC7931D823108DC28192E2BB' : true, + '8949548CC8689A8329ECDC067321AB97A60F34C8626C81F68BF77DA9F667588A903F7D36' : true, + '8956AA4D441E59D805A1886DEAC828B26372C49DA9FFF051B8B5C7D4E5AAE30384024B9C' : true, + '8BCA525F7553D02C6F630D8F882E1CD78EB03FC3CF7BB292866268B751223DB5103405CB' : true, + '8CCADC0B22CEF5BE72AC411A11A8D81291C6D6EE3E8AC86384E548C299295C756C817B81' : true, + '8CD79FEBC7B8144C5478A7903BA935671F55E8839BAC30728BE7108EDE7B0BB0D3298224' : true, + '8D26FF2F316D5929DDE636A7E2CE6425720FC15DDC27D456D098FABF3CDD78D31EF5A8DA' : true, + '8D639B56C114E4EE9A128586119082A3D2441AA8C203AECAA96E501F124D52B68FE4C375' : true, + '8D7251DBA03ACF2077DFF265065EDFEFC8C25F169EF85074D5BEE8CDA2D43CAEE75FD257' : true, + '8EADB501AA4D81E48C1DD1E1140095193679CA35668772304D30A5FB873B0FA77BB70D54' : true, + '8F5D770627C4983C5B9378E7D77D9BCC7E784A101C8265CC2DE1F16D47B440CAD90A1945' : true, + '8F91E7EEE3FCDA86CAFCDC70EDB7B70C8250BED5A214433A66377CBC10EF83F669DA3A67' : true, + '911B3F6ECD9EABEE07FE1F71D2B36127E19FE30E8B84609E809B170D72A8C5BA6E1409BD' : true, + '91DE0625ABDAFD32170CBB25172A84672796BAE63F1801E277261BA0D77770028F20EEE4' : true, + '91F4035520A1F8632C62DEACFB611C8E21FCBD8E7F6CAF051BD1B343ECA8E76147F20F8A' : true, + '9265588BA21A317273685CB4A57A0748E621F3354379059A4B68309D8A2F74221587EC79' : true, + '932A3EF6FD23690D7120D42B47992BA6CBA1C5F8B0E35EB8B94512D3F934A2E90610D336' : true, + '937F901CED846717A4655F9BCB3002978781C25A96BDC2FB4C65064FF9390B26048A0E01' : true, + '93C28E117BD4F30319BD2875134A454AAB48F333DB04ABB9C072DA5B0CC1D057F0369B46' : true, + '93EB36130BC154F13E7505E5E01CD4375F4E1FCF31B7913B850B54F6E5FF501A2B6FC6CF' : true, + '93F1AD340B2BE7A85460E2738CA49431705D2B4565C7047A540694A79AF7ABB842BDC161' : true, + '9414777E3E5EFD8F30BD41B0CFE7D03075E0ABB6138512271C04F85FDDDE38E4B7242EFE' : true, + '96897D61D1552B27E25A39B42A6C446F8EFDCABC93E61E925D4D1DED181A4320A467A139' : true, + '9760E8575FD35047E5430C94368AB06290AEA26985FF14804C434952ECE9608477AF556F' : true, + '978FC66B3B3E40857724750B76BB55F8B5D303BF8682E152919D83F184ED05F1DCE5370C' : true, + '9A771918ED96CFDF1BB70EF58DB9882ECF74BFFF9B86815B08335440363E87B6B6F0BF73' : true, + '9AAEF722F533FB4EEC0A249DC63D7D255E997CA5945AAB75FFD14804A974BF2AE1DFE7E1' : true, + '9B340D1A315B97462698BCA6136A71969E6CEB179185A29EC6060CA53E1974AF94AF59D4' : true, + '9D666ACCFFD5F543B4BF8C16D12BA8998939576E178DF705780FCC5EC84F84F6253A4893' : true, + '9DFBF9ACED893322F428488325235BE0A69A91FD057F136A42630BB1760D2D51120C1650' : true, + '9E80FF78010C2EC136BDFE96906E08F34ABDEEEC950D359C89AEC752A12C5B29F6D6AA0C' : true, + '9F6C1F0F07AC1921F915BBD5C72CD82AF5C27CF5FFF3029ACF1A1A4BEC7EE1964C77D784' : true, + '9FDDDBABFF8EFF45215FF06C9D8FFE2B9656CD7B57969895D0E141466806FBB8C6110687' : true, + 'A10B44B3CA10D8006E9D0FD80F920AD1B80186D1EB9C86A54104CF3054F34C52B7E558C6' : true, + 'A208E4B33EEFDE084B60D0BF7952498D8CC4307BC60755E7B22DD9F7FEA245936C7CF288' : true, + 'A2339B4C747873D46CE7C1F38DCB5CE985371CA6E550143DCE2803471BDE3A09E8F8770F' : true, + 'A26F53B7EE40DB4A68E7FA18D9104B7269BD8CF49CD300FB592E1793CA556AF3ECAA35FB' : true, + 'A33D88FE161BDDF95C9F1A7FD8C89008A3E31E20B2E46A328520472D0CDE9523E7260C6D' : true, + 'A37D2C27E4A7F3AA5F75D4C49264026AB6AF5BE5F878A00114C3D7FEF8C775C34CCD17B6' : true, + 'A3EC750F2E88DFFA48014E0B5C486FFB37F76DE6077C90C5B13E931AB74110B4F2E49A27' : true, + 'A66B6090239B3F2DBB986FD6A7190D46E0AB059420725493056062023670F7CD2EFC6666' : true, + 'A771FD26FC3CE540F19906EBC1936DE9E619D25B380B7B13FDA33E8A58CD82D8A88E0515' : true, + 'A7F2E41606411150306B9CE3B49CB0C9E12DFB4B41D7D9C32B30514BAC1D81D8385E2D46' : true, + 'A80D6F3978B9436D77426D985ACC23CAD6DAA8208D09D2154D24B52FCB346EB258B28A58' : true, + 'A8EDDEEB938866D82FC3BD1DBE45BE4D7639C71847E151B5C7EA01C758FBF12ABA298F7A' : true, + 'A923759BBA49366E31C2DBF2E766BA87317A2AD07F2B335EF5A1C34E4B57E8B7D8F1FCA6' : true, + 'A981C0B73A9250BC91A521FF3D47879FCB658264EA8CDA186E1752FB52C397367EA387BE' : true, + 'AA088FF6F97BB7F2B1A71E9BEAEABD79CF9E876DD3EBFC422697A3B5A37AA076A9062348' : true, + 'AA8E5DD9F8DB0A58B78D26876C823555409D4BD917B55C27B69B64CB9822440DCD09B889' : true, + 'AABFBF6497DA981D6FC6083A957033CA394FF6850B06BE52E51856CC10E180E882B385CC' : true, + 'AB57A65B7D428219B5D85826285EFDFFB12E13634586A46F1AB2606837582DC4ACFD9497' : true, + 'ABAB8D2DB740E5973D2FF2A63BDA6A05C18211328A92B3B23809B9B5E2740A07FB12EB5E' : true, + 'ABBFEAE36B29A6CCA6783599EFAD2B802F173F7DE99667AFA57AF80AA2D1B12FAC830338' : true, + 'ACB694A59C17E0D791529BB19706A6E4D4DE20D05E66FC53FE1A50882C78DB2852CAE474' : true, + 'AD8E0F9E016BA0C574D50CD368654F1ECFDEFE102FDA05BBE4C78D2E4423589005B2571D' : true, + 'AFB8336E7CDDC60264AD58FC0D4F7BCFBC7B3C6FEF26B9F7AB10D7A1F6B67C5ED2A12D3D' : true, + 'B001EE14D9AF291894768EF169332A846E3A55A4190C195C93843CC0DB722E313061F0B1' : true, + 'B147BC1857D118A0782DEC71E82A9573204285DCF7EB764195578E136BD4B7D1E98E46A5' : true, + 'B39C25B1C32E32538015309D4D02773E6782AAE0EDEEE21A5839D3C0CD14680A4F60142A' : true, + 'B3A53E77216DAC4AC0C9FBD5413DCA0658119F0E128287EA50FDD987456F4F78DCFAD6D4' : true, + 'B44ADBE85916461E5AD86EDA064352622964B686135B5DFDDD3253A89BBC24D74B08C64D' : true, + 'B465220A7CADDF41B7D544D5ADFA9A75BC9219DDC98E14BF1A781F6E280B04C27F902712' : true, + 'B4819E89AC1724FD2A4285271D0C2B5D20CB594FB4EDD895763FD5254E959A6674C6EEB2' : true, + 'B5E83436C910445848706D2E83D4B805039EEDB80BE7A03C6953893B20D2D9323A4C2AFD' : true, + 'B75274E292B48093F275E4CCD7F2EA263BC49F48F8F373A09C1EBDF85BB1C365C7D811B3' : true, + 'B774CD487C5F9A0D3BF3FE66F41B3DFA5B4E0EC28EBD8292A51782241281AD9FEEDD4E4C' : true, + 'B7B0D1EC1A033ECEA91511CCB16FB2AEE3D73606996CDFEF61FA04C335E98EA96104264A' : true, + 'B8089AF003CC1B0DC86C0B76A1756423A0A1AB90C9FC847B3B1261E8977D5FD32261D3CC' : true, + 'B816334C4C4CF2D8D34D06B4A65B4003838E30F77FDD14AA385ED145009C0E2236494FAA' : true, + 'B8D312034E8C0C5A47C9B6C59E5B97FD0560A2C738FF98D1172A94FE45FB8A47D665371E' : true, + 'BA21EA20D6DDDB8FC1578B40ADA1FCFC801D62D07B449D5C5C035C98EA61FA443C2A58FE' : true, + 'BA926442161FCBA116481AF6405C59870456F23D1E9C43AECB0D807F1C0647551A05F456' : true, + 'BC6C5133A7E9D366635415721B2192935922A1E15AEA163521F898396A4646B0441B0FA9' : true, + 'BD8ACE34A8AE6148E85EC87A1CE8CCBFD2EDF88B41B6FE01461D6E2834EC7C8F6C77721E' : true, + 'BDD6F58A7C3CC4A6F934CCC38961F6B2CABB51672400588E6419F1D40878D0403AA20264' : true, + 'BE395ABE078AB1121725CC1D46343CB2DE990CED99E0431F60EDC3937E7CD5BF0ED9E5FA' : true, + 'BF6059A35BBAF6A77642DA6F1A7B50CF5D989CDB159611365165641B560FDBEA2AC23EF1' : true, + 'BFB5E77D3DEA6F1DF08A50BC8C1CFA1DE4554333CA390E128B8BF81D90B70F4002D1D6E9' : true, + 'C1623E23C582739C03594B2BE977497F2AB628485E78FBF3AD9E7910DD6BDF99722C96E5' : true, + 'C1D43E07AEEBECFD7589E67EA84CEBCD76B76096DD145629AC7585D37063C1BC47861C8B' : true, + 'C1D951C084B86A75E82FD7D65F7EAC460B972C9EA6E7CC58D93B20BF71EC412E7209FABF' : true, + 'C22A59ABCF152F4CF7E631A316AE840C9158C5EF987301A8903CFDAB03D72DA1D88909C9' : true, + 'C2DBAB8E9652C5EEAEF25500896D55953913853E45C439A2DA718CDFB6F3E033E04FEE71' : true, + 'C45D0E48B6AC28304E0ABCF938168757D8A6332CE0036FB185F6634F7D6A066526322827' : true, + 'C463AB44201C36E437C05F279D0F6F6E97E2E99636A547554F838FBA38B82E74F89A830A' : true, + 'C4D7F0B2A3C57D6167F004CD43D3BA5890DEDE9E4C4E9F6FD88617579DD391BC65A68964' : true, + 'C570C4A2ED53780CC810538164CBD01D23E594945195F2414803B4D564D2A3A3F5D88B8C' : true, + 'C5A1B7FF73DDD6D7343218DFFC3CAD8806083F593F15A104A069A46BA903D006B7970991' : true, + 'C5DFB849CA051355EE2DBA1AC33EB028D69B561148F01C77C54578C10926DF5B856976AD' : true, + 'C5E67BBF06D04F43EDC47A658AFB6B19339B6B1450249B557A01877284D9E02FC3D2D8E9' : true, + 'C69F6D5CB379B00389CBF03FA4C09F8AEF2DACCBEABB682D32CE4ABD6CB90025236C07BC' : true, + 'C7BD11D6918A3582C53666017C6F4779634C3B0230CF1B78B4569FECF2C04A8652EFEF0E' : true, + 'C86E97F335A729144782892391A6BEC84A3F8D6BDC0E1ECFCD72E377DEF2D7FF92C19BC7' : true, + 'C91962D0DA7E1020FCA4CD0380872DF551A44C28F313E3F9CB5E7C0A1E0E0DD2843758AE' : true, + 'C9982777281E3D0E153C8400B88503E656E0FAC03B8F18235518E5D311CAE8C24331AB66' : true, + 'CA3DD368F1035CD032FAB82B59E85ADB97817950D81C9670CC34D809CF794431367EF474' : true, + 'CB17E431673EE209FE455793F30AFA1C4EB6D578499B1CCF5F581EAD56BE3D9B6744A5E5' : true, + 'CBBDC3682DB3CB1859D32952E8C66489C9321DE6B5A82666CF6971A18A56F2D3A8675602' : true, + 'CC4DAEFB306BD838FE50EB86614BD2269C615C4D4D85103A5326C24DBAEAE4A2D2D5CC97' : true, + 'CD3B3D625B09B80936879E122F7164BA67EB337B684CEB0EC2B0760AB488278CDD9597DD' : true, + 'CD68B6A7C7C4CE75E01D4F5744619209132D0D45534B6997CDB2D5C339E25576609B5CC6' : true, + 'CD996CDB2AC296155ABF879EAEA5EE93EE29D6EA98E632C6E527E0906F0280688BDF44DC' : true, + 'CDF439F3B51850D73EA4C591A03E214BE1A45B141A21DA1A79F41A42A961D669CD0634C1' : true, + 'CE78335C5978016E18EAB936A0B92E23AE5083ED7CF45CBC8F61C621FE685D794221156E' : true, + 'CF8F3B62A3CACA711BA3E1CB4857351F5D003860F002ED829DEAA41868F788186D62127F' : true, + 'CFF4270DD4EDDC6516496D3DDABF6EDE3A44735AE581901F248661461E3B9CC45FF53A1B' : true, + 'D2EDEE7992F78272180BFED98BEC13D8A7F8390BA57705096FD36941D42E7198C6D4D9D5' : true, + 'D35376E3CE58C5B0F29FF42A05F0A1F2211165CA379FBB5ED801E31C430A62AAC109BCB4' : true, + 'D3D9BDAE9FAC6724B3C81B52E1B9A9BD4A65D5F41DEF39B8B8904A4AD3648133CFC7A1D1' : true, + 'D3F3A616C0FA6B1D59B12D964D0E112E74F8A3C3EFE7B390064B83903C21646020E5DFCE' : true, + 'D474DE575C39B2D39C8583C5C065498A5FB7EE0633E259DBAD0C4C9AE6D38F1A61C7DC25' : true, + 'D480656824F9892228DBF5A49A178F14016897E1A0B8F2C3B134665C20A727B7A158E28F' : true, + 'D59788DA6416E71D664AA6EA37FC7ADCEC93DE083C93D933A986B3D5CDE25ACB2FEECF8E' : true, + 'D5BEFFB5EE826CF0E2578EA7E5346F03D904080A4929C838E9F185ECF7A22DEF99342407' : true, + 'D5E98140C51869FC462C8975620FAA7807E032E020B72C3F192F0628A2593A19A70F069E' : true, + 'D63981C6527E9669FCFCCA66ED05F296B51C067CEE2B0C3DF855AB2D92F4FE39D4E70F0E' : true, + 'D6A5C3ED5DDD3E00C13D87921F1D3FE4B31EB1B740E36C8402DADC37D44DF5D4674952F9' : true, + 'D6ED3CCAE2660FAF10430D779B0409BF85B5FF679B0C79961FC86E4422004613DB179284' : true, + 'D7343DEF1D270928E131025B132BDDF7B172B1A56D95F91FE50287E14D37EA6A4463768A' : true, + 'D87E32EF69F8BF72031D4082E8A775AF42EFDDE6BFF35ED0BAE6ACDD204C50AE86C4F4FA' : true, + 'DA26B6E6C7C2F7B79E4659B3577718653E84D3BCC544C0F6FA19435C851F3F2FCBA8E814' : true, + 'DB233DF969FA4BB9958044735E7D4183273EE12457FDC4F90C55E82B56167F62F532E547' : true, + 'DBC8F2272EB1EA6A29235DFE563E33DFC8EC8C879269CB4BAB39E98D7E5767F31495739D' : true, + 'DC32C3A76D2557C768099DEA2DA9A2D18782C6C304353BCFD29692D2593E7D44D934FF11' : true, + 'DC6D6FAF897CDD17332FB5BA9035E9CE7F88CD7223F3C813818C994614A89C99FA3B5247' : true, + 'DD753F56BFBBC5A17A1553C690F9FBCC24A40A1F573643A67F0A4B0749F6A22BF28ABB6B' : true, + 'DF0DBC7CC836B77699A1ABF0D20F896A342CD9D3062DA48C346965297F081EBC2EF68FDC' : true, + 'DF168A83EA83845DB96501C6A65D193EDBAC3C7AA4254DA1AA5CAAD68468CB88EEDDEEA8' : true, + 'DF3C735981E7395081044C34A2CBB37B61573A11DF0ED87ED5926522EAD056D744B32371' : true, + 'DFF28073CCF1E66173FCF542E9C57CEE99A69BE61AFE886B4D2B82007CB854FC317E1539' : true, + 'E006A1C97DCFC9FC0DC0567596D862139BAAE59F56EE21CB435ABE2593DFA7F040D11DCB' : true, + 'E14B5273D71BDB9330E5BDE4096EBEFB216B2A29E62A00CE820146D8244141B92511B279' : true, + 'E1C07EA0AABBD4B77B84C228117808A7CDD4EEAE6000AC7F40C3802C171E30148030C072' : true, + 'E2D52023ECEEB872E12B5D296FFA43DA9BACF3B664EAC5A17BED08437C72E4ACDA12F7E7' : true, + 'E2D8F867F4509435FC5E05FC822295C30446C8BB9A6983C95C8A2E5464687C1115AAB74A' : true, + 'E2F8E080D0083F1EC1E9D23F8069AE06C73026E325FE21916B55C4B53A56B13DCAF3D625' : true, + 'E60BD2C9CA2D88DB1A710E4B78EB024140E78C1D523D1CD9954FAC1A1AB3BD3CBAA15BFC' : true, + 'E77ADCB11F6E061F746C591627C34BC07454535C24A3A758207E3E3ED324F816FB211649' : true, + 'E8CC9FB09B40C51F4FBA7421F952857A688B6EB807E8EDA5C7B17C4393D0795F0FAE155F' : true, + 'EBB04F1D3A2E372F1DDA6E27D6B680FA18F7C1FCC3090203FD5BAA2F861A754976C8DD25' : true, + 'EBF59D290D61F9421F7CC2BA6DE3150928903A635B5280FAE6774C0B6DA7D6BAA64AF2E8' : true, + 'EC407D2B765267052CEAF23A4F65F0D8A5EC73D48C34FCBEF1005AEB85843524BBFAB727' : true, + 'ED41F58C50C52B9C73E6EE6CEBC2A8261B4B396126276B6491A2686DD70243212D1F1D96' : true, + 'EE2931BC327E9AE6E8B5F751B4347190503006091D97D4F5AE39F7CBE7927D7D652D3431' : true, + 'EE7A41E0CF757D889280A21A9A7BA157679A4F81FC705DDEC419778DD2EBD875F4C242C6' : true, + 'EEFE6169656EF89CC62AF4D72B63EFA29FAD91A6CE6AC6C50047C44EC9D4A50D92D84979' : true, + 'EF5AF133EFF1CDBB5102EE12144B96C4A1DB6393916F17E4185509400415C70240B0AE6B' : true, + 'F058C503826717AB8FDA0310278E19C2CB44A097857C45FA187ED952086CB9841F2D51B5' : true, + 'F096B62FC510D5678E832532E85E2EE52388C9D371CC9E963DFF7D3CA7CEFCD625EC190D' : true, + 'F09E639376A595BC1861F19BFBD364DD80BF3DE9A41D768D194B293C85632CDBC8EA8CF7' : true, + 'F16A2218C9CDDFCE821D1DB7785CA9A57998A308E14D6585E6C21E153A719FBA5AD34AD9' : true, + 'F1BC636A54E0B527F5CDE71AE34D6E4A36B12B49F9819ED74C9EBC380FC6568F5DACB2F7' : true, + 'F20598E5964BBE5D55181B55B388E3929078C5A28F9A4325C2A7C73813CDFE13C20F934E' : true, + 'F27DE954E4A3220D769FE70BBBB3242B049811056AFE9FD0F5BE01685AACE6A5D1C4454C' : true, + 'F37E3A13DC746306741A3C38328CFBA9253F775B0E7797AB645F15915597C39E263631D1' : true, + 'F3D752A875FD18ECE17D35B1706EA59C968338F113E36A7BABDD08F7776391A68736582E' : true, + 'F4FF97428070FE66168BBED35315819BF44095C238AC73FC4F77BF8F98DF70F8F091BC52' : true, + 'F520DA5203862B92768D5CB72D8B93ADA65CB4733D94A5C865A864647C2C01272C89B143' : true, + 'F775AB29FB514EB7775EFF053C998EF5DE28F4A4FFE5B92FA3C503D1A349A7F9962A8212' : true, + 'F7B661AB03C25C463E2D2CF4A124D854FAA7D9FB31B746F200A85E65797613D816E063B5' : true, + 'F8387C7788DF2C16682EC2E2524BB8F95F3AFC0A8B64F686673474DF7EA9A2FEF9FA7A51' : true, + 'F8BEC46322C9A846748BB81D1E4A2BF661EF43D77FCAD46151BC98E0C35912AF9FEB6311' : true, + 'FB1B5D438A94CD44C676F2434B47E731F18B538D1BE903B6A6F056435B171589CAF36BF2' : true, + 'FC11B8D8089330006D23F97EEB521E0270179B868C00A4FA609152223F9F3E32BDE00562' : true, + 'FD49BE5B185A25ECF9C354851040E8D4086418E906CEE89C2353B6E27FBD9E7439F76316' : true +}; diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/STS.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/STS.js new file mode 100644 index 0000000..17999aa --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/STS.js @@ -0,0 +1,228 @@ +// http://lists.w3.org/Archives/Public/www-archive/2009Sep/att-0051/draft-hodges-strict-transport-sec-05.plain.html
+
+const STS = {
+
+ enabled: false,
+
+ get db() {
+ delete this.db;
+ return this.initPersistentDB();
+ },
+
+ initPersistentDB: function() {
+ return this.db = new STSDB(STSPersistence);
+ },
+
+ processRequest: function(chan) {
+ if (this.enabled) {
+ var uri = chan.URI;
+ if (uri.schemeIs("https")) {
+ try {
+ this.db.processHeader(uri.asciiHost, chan.getResponseHeader("Strict-Transport-Security"));
+ } catch (e) {}
+ }
+ }
+ },
+
+ isSTSURI: function(uri) {
+ return this.enabled && this.db.matches(uri.asciiHost);
+ },
+
+ enterPrivateBrowsing: function() {
+ try {
+ this.db.save();
+ } catch(e) {}
+
+ this.db = new STSDB(this.db);
+ },
+
+ exitPrivateBrowsing: function() {
+ this.initPersistentDB();
+ },
+
+ eraseDB: function() {
+ this.db.reset();
+ STSPersistence.save(this.db);
+ },
+
+ patchErrorPage: function(docShell, errorURI) {
+ // see #errors-in-secure-transport-establishment
+ if (!this.enabled) return;
+
+ if (!(/^about:certerror?/.test(errorURI.spec) &&
+ this.isSTSURI(docShell.currentURI))
+ ) return;
+
+ Thread.delay(function() {
+ docShell.document.getElementById("expertContent").style.display = "none";
+ }, 100);
+ },
+
+ dispose: function() {
+ this.db.save();
+ }
+};
+
+function STSDB(source) {
+ this._entries = {};
+ if (source && source._entries) { // clone
+ var entries = source._entries;
+ for (var p in entries) {
+ this._entries[p] = entries[p];
+ }
+ } else {
+ if (source && source.load) {
+ this._persistence = source;
+ this.load();
+ }
+ }
+}
+
+STSDB.prototype = {
+ _persistence: null,
+ _dirty: false,
+ _saveTimer: null,
+
+ processHeader: function(host, header) {
+ if (DNS.isIP(host)) return;
+
+ var m = header.match(/^\s*max-age\s*=\s*(\d+)\s*(;\s*includeSubDomains)?/i);
+ if (!m) return;
+ var maxAge = parseInt(m[1]);
+ var includeSubDomains = !!m[2];
+ var expiration = Math.round(Date.now() / 1000) + maxAge;
+ if (host in this._entries) {
+ var e = this._entries[host];
+ if (e.expiration == expiration && e.includeSubDomains == includeSubDomains)
+ return;
+
+ e.expiration = expiration;
+ e.includeSubDomains = includeSubDomains;
+ } else {
+ this.add(new STSEntry(host, expiration, includeSubDomains));
+ }
+ this.saveDeferred();
+ },
+
+ add: function(entry) {
+ this._entries[entry.host] = entry;
+ },
+
+ matches: function(host, asSuperDomain) {
+ if (host in this._entries) {
+ var e = this._entries[host];
+
+ if (e.expiration >= Date.now() / 1000) {
+ if ((!asSuperDomain || e.includeSubDomains))
+ return true;
+ } else {
+ delete this._entries[host];
+ }
+ }
+
+ var dotPos = host.indexOf(".");
+ var lastDotPos = host.lastIndexOf(".");
+
+ if (dotPos == lastDotPos)
+ return false;
+
+ return this.matches(host.substring(dotPos + 1), true);
+ },
+
+ serialize: function() {
+ var lines = [], ee = this._entries;
+ var e;
+ for (var h in ee) {
+ e = ee[h];
+ lines.push([e.host, e.expiration, e.includeSubDomains ? "*" : ""].join(";"));
+ }
+ return lines.join("\n");
+ },
+ restore: function(s) {
+ s.split(/\s+/).forEach(function(line) {
+ if (line) {
+ var args = line.split(";");
+ if (args.length > 1)
+ this.add(new STSEntry(args[0], parseInt(args[1]), !!args[2]));
+ }
+ }, this);
+ },
+
+ load: function() {
+ if (this._persistence) {
+ this._persistence.load(this);
+ this.purgeExpired();
+ }
+ },
+
+ save: function() {
+ if (this._dirty && this._persistence) {
+ this.purgeExpired();
+ this._persistence.save(this);
+ this._dirty = false;
+ }
+ },
+
+ saveDeferred: function() {
+ if (this._dirty || !this._persistence) return;
+ this._dirty = true;
+ if (!this._timer) this._timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._timer.initWithCallback(this, 10000, Ci.nsITimer.TYPE_ONE_SHOT);
+ },
+ notify: function(timer) {
+ this.save();
+ },
+
+ purgeExpired: function() {
+ var now = Math.round(Date.now() / 1000);
+ for (var h in this._entries) {
+ if (this._entries[h].expiration < now) delete this._entries[h];
+ }
+ },
+
+ reset: function() {
+ this._entries = {};
+ this._dirty = false;
+ }
+};
+
+function STSEntry(host, expiration, includeSubDomains) {
+ this.host = host;
+ this.expiration = expiration;
+ if (includeSubDomains) this.includeSubDomains = includeSubDomains;
+}
+
+STSEntry.prototype = {
+ includeSubDomains: false
+};
+
+
+const STSPersistence = {
+ get _file() {
+ delete this._file;
+ var f = Cc["@mozilla.org/file/directory_service;1"].getService(
+ Ci.nsIProperties).get("ProfD", Ci.nsIFile);
+ f.append("NoScriptSTS.db");
+ return this._file = f;
+ },
+ load: function(db) {
+ var f = this._file;
+ try {
+ if (f.exists()) db.restore(IO.readFile(f));
+ } catch (e) {
+ dump("STS: Error loading db from " + f.path + "!" + e + "\n");
+ return false;
+ }
+ return true;
+ },
+ save: function(db) {
+ var f = this._file;
+ try {
+ IO.safeWriteFile(f, db.serialize());
+ } catch(e) {
+ dump("STS: Error saving db to " + f.path + "!" + e + "\n");
+ return false;
+ }
+ return true;
+ }
+};
diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/Thread.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/Thread.js new file mode 100644 index 0000000..8c9daf6 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/Thread.js @@ -0,0 +1,100 @@ +
+var Thread = {
+
+ hostRunning: true,
+ activeLoops: 0,
+ _timers: [],
+
+ spin: function(ctrl) {
+ ctrl.startTime = ctrl.startTime || Date.now();
+ ctrl.timeout = false;
+ this.activeLoops++;
+ this._spinInternal(ctrl);
+ this.activeLoops--;
+ ctrl.elapsed = Date.now() - ctrl.startTime;
+ return ctrl.timeout;
+ },
+
+ _spinInternal: function(ctrl) {
+ var t = ctrl.startTime;
+ var maxTime = parseInt(ctrl.maxTime);
+ if (maxTime) {
+ while(ctrl.running && this.hostRunning) {
+ this.yield();
+ if (Date.now() - t > maxTime) {
+ ctrl.timeout = true;
+ ctrl.running = false;
+ break;
+ }
+ }
+ } else while(ctrl.running && this.hostRunning) this.yield();
+ },
+
+ yield: function() {
+ this.current.processNextEvent(true);
+ },
+
+ yieldAll: function() {
+ var t = this.current;
+ while(t.hasPendingEvents()) t.processNextEvent(false);
+ },
+
+ get current() {
+ delete this.current;
+ var obj = "@mozilla.org/thread-manager;1" in Cc
+ ? Cc["@mozilla.org/thread-manager;1"].getService()
+ : Cc["@mozilla.org/thread;1"].createInstance(Ci.nsIThread);
+ this.__defineGetter__("current", function() { return obj.currentThread; });
+ return this.current;
+ },
+
+ get currentQueue() {
+ delete this.currentQueue;
+ var eqs = null;
+ const CTRID = "@mozilla.org/event-queue-service;1";
+ if (CTRID in Cc) {
+ const IFace = Ci.nsIEventQueueService;
+ eqs = Cc[CTRID].getService(IFace);
+ }
+ this.__defineGetter__("currentQueue", eqs
+ ? function() { return eqs.getSpecialEventQueue(IFace.CURRENT_THREAD_EVENT_QUEUE); }
+ : this.__lookupGetter__("current")
+ );
+ return this.currentQueue;
+ },
+
+ delay: function(callback, time, self, args) {
+ var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this._timers.push(timer);
+ timer.initWithCallback({
+ notify: this._delayRunner,
+ context: { callback: callback, args: args || DUMMY_ARRAY, self: self || null }
+ }, time || 1, 0);
+ },
+
+ dispatch: function(runnable) {
+ this.current.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
+ },
+
+ asap: function(callback, self, args) {
+ this.current.dispatch({
+ run: function() {
+ callback.apply(self, args || DUMMY_ARRAY);
+ }
+ }, Ci.nsIEventTarget.DISPATCH_NORMAL);
+ },
+
+ _delayRunner: function(timer) {
+ var ctx = this.context;
+ try {
+ ctx.callback.apply(ctx.self, ctx.args);
+ } finally {
+ this.context = null;
+ var tt = Thread._timers;
+ var pos = tt.indexOf(timer);
+ if (pos > -1) tt.splice(pos, 1);
+ timer.cancel();
+ }
+ }
+
+};
diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/X509ChainWhitelist.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/X509ChainWhitelist.js new file mode 100644 index 0000000..b32b6e4 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/X509ChainWhitelist.js @@ -0,0 +1,1007 @@ + +// These are SHA256 fingerprints for the most common chains observed by the +// Decentralized SSL Observatory. These should not be resubmitted. +// This file is automatically generated by utils/mk_client_whitelist.py + +const X509ChainWhitelist = { + '000AA4E99FE86D84F762DFB2DC29323D0614B95AA335A270AF204EBA2F2240AF' : true, + '00487384DE9545F7F6D6709574920DB9743F0DDC4D5E1518EC00ACCCC6F9866F' : true, + '0077DFC8E3CFE0E4398F208CDCB1BC5A7A78BEEF101ED256315FCB9833283B58' : true, + '012AAE6B27B392684695FA22F87C8DD3F60CDAB564EE4D4D58DF98575D99153B' : true, + '01FC275FB7BB83082EA2C546876545030D74F68355AF2B0CCB1972993B393E58' : true, + '0261C3970364E15EC2BB646934FE28F8FCE6E1D5E0B99C7539DF636ED03A9DF0' : true, + '027017BAD8EC764424A5DB3B647AD769E78F1653A92F800FAF21212C4DB6CEF8' : true, + '034AA8D4F147FC9E93CC18EB5BC06F28FE3DF4923CA61A9CAE92F4E3E078C5F3' : true, + '03985CA59706D4A023A5CE0B2E4F870EA465A8E3803CEB2AD859FC86D3569852' : true, + '04376F22DBF0B17201EB6871797B1D31FC00EBC4743317793B9C5A5BEA8CECF4' : true, + '046C78CE6601C4D88EAC305EE65068225CED3988A6BEC42E50B57B1979742245' : true, + '04AEEFBC8685B2668E25C23D77C6D63B95C7C0BA1B8ABBF434F5EAA66BC3E7F4' : true, + '052592AA10AFA8D750861F47C540D3A0653A87138ED7427BFD02C9D197D3EF8B' : true, + '0544DC1E0D529429A1C86E848D1C78B8511CC1A2128405D276FD864B452890EF' : true, + '055C88BD28194042771FF813973E086A30710231DB219FF377B79FA075E7F2AD' : true, + '05CB56F00C8DA64EEF10F2305EF696AF839CF8DD541910D760772AC86811FDAB' : true, + '05CE45708C3882B0DB81A4504FBE064C1ACD7DABDD071A7F263744FAAF040CF5' : true, + '05F70EA23C890F1C382FB250E40DFFD3488C271006DB6B10DC96BF34B6F74420' : true, + '06808645F29D708E4C31AC40FA00000733238E10A56D2067AA62803C9736E923' : true, + '0699966F623E746BF97DB3B6BBBEB83BCF2E8CAE89D907A49A731951B158216A' : true, + '06B35EEE47D7E55F278C5DB13FF137B269B6EF91B58FEB4B2E70E7CC1DB757D2' : true, + '07CF2A06F1718D6E476B98C2B42E370A35FAFE4C1F41CF7A1DE115CDB6222FAC' : true, + '07E7123B20A807889C384460FFCE4A7F53593A5C872B0E8FD45795D71CD0F9FE' : true, + '07FC57E4C188422B53059AD4839F467B9269E4EABBF902C99B30E25DEC5EB1B7' : true, + '0834241C7C2B598E20698047C331B173BCA189B96E528FA1993AFAAE3F7D51F6' : true, + '087FAD2F33E4D28A13CCFDE11F270188E01AE0EED615D2F433DA4EF05CA6BD4C' : true, + '089979504BECAC25640130E65E562AA3E3B5D49EE148FEF6A2B77A2A1CF5FC06' : true, + '08BD4BE042F6DA7D627143ED6B2BACE65615683C3C272123AC55105DE4BD723A' : true, + '08E5080C1D69F2C11524050C9C0EFDAEBFE68A27FD30EC04AAF4DE2D590F22EB' : true, + '09250AF23BC74D92973DD48812D5ED28CE1F5C110EE5F7CA791D9CFDE04A131C' : true, + '096800FDAFA82029B3B5E3947E0EAB6FB1F1D6958DE04E9256969F99F7518C57' : true, + '0A122B87C038CAEA46E8944009B11C2168E47F4DACAA9D3BBFB92CB5F5E1BCDE' : true, + '0A36586C8EEE28E5ECA1F542691D12B3CE7815CDCF722CDF7074AA71413C2550' : true, + '0A6A1FECBADAF7F1B473305A71E454F6AA8C1B0F40941FF4660B814BFF4984B3' : true, + '0A903D7CCFBB18FFEC8E3AB05FC7E592C1E7509D0EC2DBD9A2C05236BA9FD7C9' : true, + '0A91A9CAC951DA1739ABB2F29D16A6F5FAA9F49AC87516AB59CA77150D282528' : true, + '0AA5730256323B66DBE88E3056AA3F45E52BE5E2B87C1C9DBC1986CEAF97B5D9' : true, + '0B2D2C539D3D922820B6D08E159E6763D22AE797B2C32F8202B632BB93588588' : true, + '0B39ADF22CBA98C15754A7A899C5B96871337D2178EB3EBF0B5D5F88332EA971' : true, + '0B901F548AE4E0F25EF38010E311945FB198E497F203A88FE7C44970F7ECDC40' : true, + '0C114EDF67FB7C09C532297D79A5743EE5F8576A8EBE3DF69A728B8CFC0A167C' : true, + '0C7E90EF8BCD379CB001FD07530718DCC0A33E9D7D1D333F505F0143BC6A8FD6' : true, + '0CA932C2E0929B9B6C0A8822D3F094F671522419835049CAEAC51755D1F44777' : true, + '0D4F42B386775FF404B84D58859BC5AB029F1F9CC6B7AFFF32B838F8B8C71F3E' : true, + '0D8FC5F202A5668F7F3EA7F6A73521E0C7FEB5DBF6E58BA68AB7C7E01F4C532C' : true, + '0D91DE20988EA155526570498A1A6289FEC55994A5BA888C9134765F2A0B0580' : true, + '0E3AE0C9BEDFCFB38239DC4214A3AF3E6386720E2E5F8A85EEB52BD152E4DF09' : true, + '0EEAAD4FE6818F1D723A5567CD0A6569D45E346E2DA2896222A7F3367F4AE8C7' : true, + '0EF8FA5AAD4BACDB842959378F18935855B027B0BADDCBDEADC9CC958C4C603B' : true, + '0F39AF5CA9615B05CBC12DE3C94A8C4FBA71CA8CEF541952315A9D0658DB5B28' : true, + '0F7DE9806919EBD5EE47188428BF7FE13495E4684ADBB5BA980BB15D4D0B0C22' : true, + '0F8F66953B0F42560CDD573A013D3FB809D9747210E58F28F4878CDA5A8B8AD2' : true, + '0F97235268233245499D6C1319DF1BCA3AAAFB13CF9B06EB294FCA328022E82C' : true, + '0F9E066578F4AFB0ACBDC408CB25B7D7200BC5CB7FC4DA6D32532D827EA5B232' : true, + '0FA392F6EABCE0F4DA14C7B5237B21BEEE6BDA55832A8A6090CAEBB53AC8D77B' : true, + '1049EFDE8BD0E7D94AE05D50D326ABCE41E79B0572F86FDF1F7387738262F09A' : true, + '10552D044AD79FBF1AF5357998DAB9B1FFD66D7B53C8107FC2280148D66475E3' : true, + '10E82776E55D0C2D58F6598E615CF38AA14161D1EAD97C4A09182FE1D44E695B' : true, + '10FD669D6DA882678AEAFB35A5F8A0963C2E2B3084883EA515C8956FEC4207ED' : true, + '114ED15D4B557A16DDE1D01CB4074215CE6773C180FEF60F08267CEAFB670D5E' : true, + '116A5D5F3E99CFE5F72A4AFAC8699CC225C130F4B8520CDB350A1262D9585973' : true, + '118FF53B6BEB35CBFE6592D45BE082BA1228D1817E46B2CC14B8855FCC5C9D59' : true, + '11EC553AB76EED159FE553B52E7475FA71A0FF3F4B3038CF91BC7138F50B0A7E' : true, + '11F7A939F33BDF6270E16C747C0B0918902CD4501AF1843D9EA4445A2E708C58' : true, + '1243C75D0F805DA54E780D0D9C55247B1ABB31FC09EB65A7017695945F2A0D4A' : true, + '124CE9CD70225896BB3C9DF372E0457CABCEE8585D1BCB8E16D0E6D95B94AF2F' : true, + '124E430E0E0B103B580A0436D7CF436F6ECE55908279FA8EBDF475AED08A9CE9' : true, + '12826065A034136FFC2258AA1A65F9E550A582B4017E396077917C775D42E553' : true, + '1363B86EDA0BFAF10F1141CBE7569647F2FFB370F539694288101128A38261B8' : true, + '137E64BF679E2CD24F034125EC926D48F34C7404CFD6B61B23BA9E91E55D3560' : true, + '13ECB3394571030912CDF82DDAFA05B242398929BD3ACE1598B79DBF28B701F8' : true, + '142A33AB96C13ED7C7B8782D764F374B5A8F9C4E33B4DFE9B7750E878E7C5D0D' : true, + '14587E25D8BF0150F429924144E88AC551C1F77CB5DC84F6CDDE7079014ED2EE' : true, + '14E443C709A20C11205371C5BC54C20CCD53AC434750EBC91C45B30DD0D8B53A' : true, + '14F5D6BA3842E708E3AADC26B8A9CD89FE9CF2BEF46398369521839733A4504F' : true, + '150F5BC3D839579BD7DD1254A6C3C3AFE3485D7DED21C3B8123BA6875886A91A' : true, + '154C4C43AAF5F838B7B9BE748FF671521BDF0ECF3D749EB85487F9C315239778' : true, + '15F46CDF488A5BAD54DBA0F2E2F825F956F8ECF9E3AF294551E88F62A8A0CECD' : true, + '16BE849F33D16B22C495B9793329BE704AD9C681C2A963C71FDB303D526E09B3' : true, + '17A0318A02B4E7EB14792644E1E28966257748F8162A53AF4E49697A4707C9F7' : true, + '17BE5D468B1EA071C36079A4843B8A1E69B9FCAFFA0565FB54B10A02D78B7FA8' : true, + '17D0A909CE750C728FBD0F33589A3EBFDA452D00C757A18557DB4697289287B6' : true, + '17E110287D04C595DAE0C73090051A1F30F165A37429CD78C1F8FC1754549D41' : true, + '17EC9E8F98C207F4CA7FD0680193A54DC33BC97CB364669442F5B7492D36839E' : true, + '17FD21D68D53F369EEC1E22EFCC3B79B255EB8E1031D147F6461291C4D980037' : true, + '183AE55CFEE1CAC5CCBC1C58D813DED429DF750E023362FB8BEDCB27A9F94559' : true, + '186DC5DF9C693C311857A94BF9B2810BDD02F22DAD527D2BFBC0CDF24BCE26FD' : true, + '1882C2D8D817DD1078933D244E379CFC5BA8EAAE302BCF9FA22636B08FAC86CE' : true, + '188F5D081FD0D98429D1747FFBFEAB39733EA7C2B61C8BF6B0ED62F71264C619' : true, + '1974EFA39EBF5C2D3B53D5089EF28F6545D5B4937DB660385AF579A28FD17A3F' : true, + '19778EECDA512FBEFDD9AD0507A1F828AE67C35594C20831D1D531B79F8B2F99' : true, + '19AD483D37D656F9D7844F14C53281FDD56683C0C8FB2A8F3F77DE7C810C1CFC' : true, + '19C76F18839C90F94AB9E4CD3ABC4C15E0A8DA9B8705E7DD872962CF8409DAF2' : true, + '1A5C89F300E3A9835759D6588CE3361993E336D76EF4B2F64F1DFC4D913BC6F3' : true, + '1AA7EB7CB182FF1BA09FCDFD088DE1F25F8551DAE53CE2C16D4D72D1B6091CA5' : true, + '1ADFE710199AE62734EAD27EEE6D6A4EC4D6FF19D6978A7CFBDCABA69C1617E1' : true, + '1B5827F9E4B66B4895AB47A0395BB1E135D15F7A23712147C5D382C1AD805ED5' : true, + '1B8AC4A31C75996D44252AED8CCF639282DF3A180900C660804483597238D8BF' : true, + '1BAF1A75711BC2EF2C4EB8C2BEA4B5B1B183E95ACCB247DB89B3098C324870C2' : true, + '1C1BD271327C7721AFDE3C5BE6FA98B132F2EE1911BDF05F0649121349A4537F' : true, + '1C1DAB84FAA0FC35AAA8A54760840F8A48EB449B338D7CF3902397514F4D1CD7' : true, + '1C363FBCE719D6567E55DE267E6662A454494FA085180F23FE84139E9E83527C' : true, + '1C573E491ECF04E3240144B2A63D8DDB457367055B90F5947CEFB55174A6B959' : true, + '1C923C0DC4E99E8F807E44A5499EAC4BC48022C63A3EB4CE819D556349FB57BA' : true, + '1D4D6D7E6B04F507E28EEA37367012166A6E4AFD02D2F325129A70F76894512E' : true, + '1D602FC8C0A6E38288593AF300D73F04B3A5AF89F5B08A0DAC3D935A9B69D7B9' : true, + '1E15FDE9774DDD452B000A3FD8118DAE63D16F8EAC19D26806BB08A70677F42F' : true, + '1E294231C72B07AAA6E2FE3B18BA14F1095F82718B42AF1DEE071D011740550E' : true, + '1E5D810BCB8DA3AF393761C59CC88D22669ECB7D4F926760BE1EC6CD83E60765' : true, + '1E5DD6CDAA3AAB8BB891B8D7B4E99AF2EBB7F08719F1D3B3C7B8694962EE8668' : true, + '1E84A8F15A3EB4B7921D7462C1FFF8DDC182E4E0682EB48C42FB3645BA43A6E2' : true, + '1EC6CF08000A6583160FEDE1C117794E75CA5533B666D04FAB138D8F12A4ABC1' : true, + '1F1A125828C6F4A21A9D035C28E5493FACE0F4D7DE6B6F2DD5B9FD5D426B6FC7' : true, + '1F3C4550EEA0B9B8F4608632610548B64126E8929450D285DBF906752241CEF3' : true, + '1F4C963A9BA39CE44E46F135EFEAD5B30D6A0A3A43545E18CBE59DE452A6468B' : true, + '1F6AF055216D53382D7D42AE6893552B4C04C0D6CE31A2A71B7FD24F7A607A67' : true, + '1FB6F7F8DD4B392D4BEAA5E707AAF882D2AA83C5E9720C58B616F8DDDFFA6F77' : true, + '206A33714BD518CEFF68A6904E19B0837230BCADEADEA6E056EE3745774BE3EB' : true, + '20714569334D93E90D2200B253E447A249EC53311A379538BFACDCEE457D9656' : true, + '20BE732FDB6D751C0991700E7C9D401093135652D25B1A29D3387E21D60B776B' : true, + '20F2E0109442ED3DB805D939B1FCC9F4C8E17414F748FDE98883C9EFA504397E' : true, + '20FD7A6E1659C35B1870F698D182820EADD8E02ABE97A9FCD691681B4A6493E6' : true, + '215C6D97B01A9EA11CDCB7D4D62EF74D31231F99CA59F3D21104097AD5D52868' : true, + '22BA6A5C28A505A68F7C025447822720E4772BC380FD9EA58EA71C32682CF0FC' : true, + '22DD516BE482B2A7F3C5EE268E8110EB9814E86E4102654C3CF5705743BCF870' : true, + '22E6BB3D9964F458D462BAF404323775B20EEF02F174CDBB442D4381DB98C61D' : true, + '23223C3601CC5682B21E4D4C236BB85C9098082EE3942070E33CC791CDFAD31A' : true, + '23980A7B935B10CA69315CDA05E61B4ABAE7876724C0E0C3CC7BE9748E41ACCC' : true, + '243D9193A5D38C9F2C21409EA470757D3903F8C418709E12C47F01C4EC08E5D5' : true, + '24540FC5876A301AF83E2494013ED0B4F7B1312D7238EDDFA1DB0E7736082856' : true, + '24789DF7D8F1D393F224621E436675778CAFD595AF6988D2995F28553F28B629' : true, + '24AEFDF5AA4C36F89987C960EA14B8A90CB2670CCCC66957652A21E0231D2E4E' : true, + '25531D59643B0F5E1CEE67B9CE42B0332FCF9688659F62D990C77CB8C1349E10' : true, + '258296CAC41A779D819E37CB4B120D2270F55AD8BDA24747C572165BE31849D2' : true, + '25B87ACDCD18628D9B64EB9F6366C970B2FE922B39EBB7E3DD1354899260B180' : true, + '2601092E7F1A7841A9E65C6D24D0BBC0CFE986404E6DAFF628E2C2D70667EB59' : true, + '2635178113FBBCC75EABC09C497D411C994AD0170CF9DF999A4FF5C16872CDBB' : true, + '2643995B1EC6D06457AB936E18B5A5721CEDDCC82F4E116C36EEC5096BB04DC4' : true, + '2677470F2FBD067904B7014B88988BB94F72403C014240B9843AE5A5FA21661D' : true, + '26B163AB60042EB690FF4549F6086019E19A99A3B69332AD1FE85D9C46491AA9' : true, + '26D184F574A19836878B10B209825413B48BB1C92195AB69F6B01D359FD4D07E' : true, + '2710EBB98F6790081E34A1961D7716533511A1746616DDBAB9A3D64ED32B1875' : true, + '271B4C5B8689BD69CCA837BC080C554DBEE0B20C5B1C505F68544AEC29588277' : true, + '2774F85336B9446490224280339F361F69E44891C5D8F078F03FEC5BC7C37437' : true, + '27C6EFE085FD0EF2DD467630B0A650BD3624BB4065F811F5F99CA976B4C0B871' : true, + '28002E2FB259DA7341B69C144F4EC6B5B12CB9A981C34387044926957CF9152C' : true, + '28082C3B3FB30995C3ED4D971AF00E3114C75B9FA47540DEA79E120E01C03562' : true, + '28445F7C648AB6025EB469E9C5FD10C6C8D0D21B6A20F078854EFF406C55D3F7' : true, + '287821696D43B83F1EA4A3AF5F6E5695F86D770148341106757B98DACB5C979F' : true, + '287AC69E23A84ED6C79668FD778A1C5F89D93D9E85B1F84110731B3EF007852D' : true, + '288B79B657E95C6E9FF6FF795A3E36528FDD26538925F67411B0F1F715DC9905' : true, + '2895D775D2F7F4D7BFF504B3C204939766B2C2734BC607B154CB1B2E52D76012' : true, + '28B2F8B5E2ED8681AE3D47EBB733718E32FF81FD736E97EEE68E12A6CFD3C9D6' : true, + '29AE4E3FA75E6A40E5C2D8BB9446BC39D672780F4CD6334CA2527FFEC0FBBFD3' : true, + '2A00C2E13F83FE2640D9DA1B802219AED52B811CCD54F7632622FB05531CB829' : true, + '2A227A780950EC49D49437E4FBD2306EC1D213A25343B752F116B3C4203C641A' : true, + '2A2EE56590084C2B144125731B45BDF927C357840E997888F52EF90AD6361EA5' : true, + '2AE917E3AB4B867883088BCFFED53EBEF9F87988C77AE47FE325547B181931A1' : true, + '2B372D2A09743CB535C71949D24612C108A95D542D5235B443C116426F4EC740' : true, + '2B5FC256FE24DB51001FBB200C80DEDE29EF2CCA290DEDA0EA7FA5627A8400E6' : true, + '2B804DA0656D06DB6CFF31AF9EE7A41E9621F5062C855A3FA3E69208C6BED1BB' : true, + '2B96B9494AB9EF09B7D4ACC0F7C7C8B27BB23772D8203F98A635285335B476FA' : true, + '2BB158B54FA26B5A7FDA92096D214B5AB548D13D4CD0D275B967703750B03097' : true, + '2BDDDA7C2F05123A014AFE1044AE6AD3B1AA14F0BEAE4FDE812BE52DA271F992' : true, + '2C27A3FBE2D833ED7FA00DE8A00EB1E16F40043D68C21C6FAA72A34DD839A5EB' : true, + '2C43EC0374BC603A1B191B88ADBCD5C1A0409120427995C2684A1590C7AB1432' : true, + '2C6E83BE981FD0EB0ECE7D8977D665C1B7665DFEE4C0F7DBDF5138FEC3974EBB' : true, + '2D75CD1232720CFFABA233953EB8CFD860C23034BD9CF969E8D104485B251ECE' : true, + '2D978BE3F44F069B366DB5D8E3B1FE4B02775498DE8D17EA68B423259B681FDD' : true, + '2DBAF94C053FCCFA1EC09CBB22F54DAFF2DB4ABE1B3C61CFF1BEBC31260F4821' : true, + '2E23B68E6E803E74BA36D9C9006F96D8BAC39DB4CAEEBF1C12C6CC01CFDFAD6D' : true, + '2E50DDF50FA4B9220202816F9B79405227BA4F803E61FD96D6BC95A0263E49EC' : true, + '2E6193577D9F6627E5D23883970975541C6807F1DD1F48971EECF07C204C16BD' : true, + '2E726E5D6C08B18944773DECBBBA88F95E25D586248B145354596BA8DB31DDC1' : true, + '2F0D2656CFB3D34F4775E89AD96E2AA7D3A1FCDE399BCB2E03AA2BA0A035946B' : true, + '2F36C6E796C7C4047152AD68B781475E3FA3AA785DE5CC277DA2DA20F35AD52C' : true, + '2FE442C9741D5351A016B9796E3021A01BAC6867A567ABBD1C7EB08DD359DF94' : true, + '30354519FFD4794257A7EBEDB0D47DEC9A547B4E7213199000F41EB65C233EF7' : true, + '304039981650BCAEA6BAC7B1FF2E03A9BFBC8AF4C37F37E66D59D327776EAE77' : true, + '305B4CDDF744AA543DA713E7E60C19ED5537D49ED2252330B46B7E664C4E588C' : true, + '30AF2F588C872B174436F3B68ED432C0495D651C84A04787CC8C13D6D61DF63B' : true, + '3102A33CF44D88924253BC149D22198D046E6571E79D0C6CFE106F8A725364FC' : true, + '3141118408E436FF8489E07BACF80B260A33E842C5BEC83C763B6AE73701A76A' : true, + '31C4E7F6630486BF42150967E951D3DA5ED8D382AA596FD571231CA96E0F352E' : true, + '31F411310C7FCAAF8CC265F557CF93BF32E5E277589E932442A3A840E141809D' : true, + '32CFE4F78C2B8737E9A31F4E0A2513535FE242D02F1DD83C04ADA77839CC4442' : true, + '32D398E73D053561EC78257EB01F0945C2A38D9F80674F6F2B4B10BA35A2B4E4' : true, + '32FA61C84B195BCADA9A65448CD3C8CA66B1DFE252CF97D46567ACEB59BD2D83' : true, + '330457913F88C2037F663003C36F0B6B2B3071AD972C9A4DA54998A7CEB8B148' : true, + '331C02F8B180F4E4F15DFAC71D1F03F3ACA9438FEE138AC2A60264BCA35DA54A' : true, + '3379517964657D6F875971C1ED6218D9F890BEFC7390CA654C79A666D1989A18' : true, + '3386FCF2133229E0BB6481DD2149E9D87540B5277E3FC3C3DFAE50A8D81D0653' : true, + '339C59871E132711D25988F0DDB86E0EE5D34B119972C0A5E3C3B556BC293D74' : true, + '33AD12326DC0DE4AD1CCDF7B3F1E0202B8476857E1C911B056F53CC6D4A60187' : true, + '34CADA62CE9D32857D65E868355E258447C0111D3F78CDCF4360F5B7B9F7E3E4' : true, + '34F904FEE6E8CF59E4FFE90F627D688210910D0176C9B5ACF7DAE8CABA722B63' : true, + '357E325CD50420D15B1E6779D32E62FB6029A9710017B14CC23AD41DE08A400B' : true, + '35931DC7CBFF8F707BEF6D02988B66FC79B77D05DA0A09F439040F4099A69883' : true, + '359D692646482C906B77BC217B7C262E81B6D80441DAC6FC2E317C5A0C1A72DF' : true, + '35A88292416784CF9D883274B422DDA092B8692CB98FCC788C9B926987854291' : true, + '35C8C522026971801A41CE23438829BBA27D3902953FE183E2E3B84415F6ECEC' : true, + '36267B2A60E0B5997DEEE17CDBE6AC7F7D54D279C6AB4F06CD469919F442E6AE' : true, + '362BF6E353729E4F8FDA7D87DD726C825E2661DA801BB75B857F4DA622BB9704' : true, + '363C229BA74BC61CAD1DEF35B5B808146FB5D1D34E5D37C02E1FE19B5EC6C37A' : true, + '366B123FA1EA2FF7FDBCA0422E504C8E0AB62334AC8941D307060F5ACDFB58AA' : true, + '3761FB4C3FDF80BD66FB31A506612BE2B98FAC57691A6125227B4787C35C32F6' : true, + '379F1BE4B67E89183FCD2AB1C0A3B930DE70D33CAE2C8629819DB4951600A398' : true, + '37A8C0FE01BCC73FA73F8A161566E23F12C22BAD0461D7CB9D9386EB7DD63800' : true, + '383BB79AFA098696BE4D3605F26A60FDD7C455D31FB03BE8553C3EA348F479F2' : true, + '386702317DA5549A08139017D14AC498D7DD4837E0E16F91BCAD37684AA6EB97' : true, + '388AF939697463B651AFF01141B625DC877D0FB31CBC5E234A5526BAAB68E660' : true, + '392080D12E0D8985A6C35526FCCF9CFF55219D7E62E92BF05863F7CFFC42596D' : true, + '39CA68E75049A34F875DEE1CD6929FA61DE4B250B5060D613BA9088810D60B9A' : true, + '39EC99D4093CF0A60A947685856F20DBF85966FBCAB4033890361A650294A8A8' : true, + '3A9480EEDF0D65938DD92A7FE7E9BE4D797CEB0662CADDA2321D47C04818A57D' : true, + '3AFA38F8367A45AAFBA949076A38537CBAE4A0774FC4CC40BE52F944F29F7F19' : true, + '3B00662EE3F01FFE2C40842F0F3B76C039ABB785962E371767E89E2AFA311A74' : true, + '3B1FDB5890A3C11F7149C13019F3EE43D3D3A8C174E485512E946EDCBBFFFE55' : true, + '3B3A1C7A8131E1E6A66039972C1AEF65797E783ACC2C645CF10EEAA5F20BD297' : true, + '3C40EF3135CB1E82D0E6518EF75EAEDAC43DE347CB74E2A09CBC0C5A56DB2636' : true, + '3C49B9DC9307C6B33E0DBE135836504ACB9F6204B7172A412C28E797E56CA02A' : true, + '3C91A39CC52452FB91463E511257D3BFCDCA3A149EBF39978F39E55F20FB061E' : true, + '3C96B0CE3855D125998B8DDA63F2A37AA1FC5967949393D7428C1FA97D2542B4' : true, + '3CFD92A9ACFC3B9D7BF81B2994D398500413E7B57C711D711F98DB009FD142D4' : true, + '3D04D60DD221BA390696E262A7B522815BAD5A03B79D1176931F2AD5435D494F' : true, + '3D7A71BB494A12E1F21A1EB9033CBEFCD1FE81F358B131016DAF92C1C06F1A38' : true, + '3D81B541D1B04B15AFEF518152CF8DDDB9300EE0A1BADC916FB366FA034120ED' : true, + '3D9910368BB2A01AF8277EA5E26F9CFCB045DC63CEC7397EEB2827B16C0344AE' : true, + '3DE5855D87575043D52CE7496F7486CBD8177FCB9F8C686B55F5F0EE761B2DFF' : true, + '3E09F448ED5A72584FA305F82A25706D2AE756083530B4E18665DA2AE46C1410' : true, + '3E18B028DAFB97BD9A036F1743316C8EC963C17066E362328FEA24D6FF8B2A7C' : true, + '3E486CEF660870234BD56B008730D8B318B7FBD047B55939D74545B98D8176DC' : true, + '3E5558CB92AEDC7E01DB0FBCD0825CC0F51AA7B683ABFD01D1E5E04C8A4D716B' : true, + '3E7FC707C590EECFA7E9DBBD270452366C0E2F0ABA7768B3F18E7DE34B3E15BD' : true, + '3EA82DE5DF72699D567B865AACE54C72AFF800647415E5E49D4260F422C26DA7' : true, + '3EFD44B1F0C8400130C35FE003FA304C2E47FD20612A4D1C83F88723B885CE66' : true, + '3FC8022D0C28EBFD45DC1D07E14F9E83F0CAD2E7ECEDBFDB991E01EBF2400F54' : true, + '3FC92874F07DB0DEE11CCB2CA7BDF187641DC78ECE4C76E71B2253FBBC17E3FE' : true, + '3FCBCC65096D7D731244167CCEAA21757E56D6EFC05A632AB3E062643E5B380F' : true, + '402FA5AD0E7932A07356FB849DCC1AEF11649D516ED1C5617C48F3E7F9B02356' : true, + '4093A7B65486890D2575D57070237C586DC489B3A68FA913DEF136370F2DDF9F' : true, + '40E66AA57071722F0B8E8B59A74998F82E8D5020BDDBB35D0E941851ED11921D' : true, + '4147C9CD6ECA16D7C6A8939E15E419220C822956FE754DCB2F08F2C78A99C3DC' : true, + '414CB8A3E4E86E2B4E03EB2FE71312CFE17B78945B41597F8E03AF04CFFAECC9' : true, + '4196DA17789961AAEB04CEBF7F1F77621F89102F48350D3B95E66E955FA8AA8D' : true, + '4247E57738776992C6640ACA48156C9DE580F0A739CAF0A353CDDFE3417F7C46' : true, + '4248F09AC0B07BCF41B413A2D8FF50AC42C6943D6F6D20F9C37502FDD2315171' : true, + '426334353C51D4E625F2DE937D9AD9FE6769E0F4E1425AF23D7802385103B583' : true, + '429DA945C771332087229D2822684175DC050F832EB9F0ED90F868E99B6FBFC1' : true, + '42D6DFA920BABBF7876416C3F5B30598040F6A748F22E3C3E0E2D32DEF098AD1' : true, + '431F835569D356C0C577FFCF90DDBF9B17E16D7FA9027888B708071B696E818F' : true, + '4321F690235447D71149C54E13896C885D07524C80CBA133428E1BD235123234' : true, + '43555C20820B179886354E63251A21247292B3B7BA46D8BEE860A0313258136A' : true, + '4373B2B85D4FEFE97E79B4C7935AD1762380D97FAE2C64FD61E58593F8BC8C4A' : true, + '43CFA30A34E75D16640693DF32B691B40219631AFFFC6A09DA97006AFD2811FC' : true, + '44338B3B7D1302BEC14439BFF723B5AF93DC549A7E1E417112C76C1455108EB3' : true, + '44CE10B295D3908C5CB40661F3F07EA13B27A31F32041B79D12AB7F5250B4227' : true, + '44CE6D5CE40E8F7BE79569A66792B181CA71DF0C80D3CEDA59A151F2E7CD32E3' : true, + '4533B5CC20DF3613F517118ED8D5AA328EDE18610AE99E16A5B6AF21EC0FFE17' : true, + '45CFA75EF370F3B3C2271E4AA0F99106B3339B6FEFDA5B335CC863F0C6F66323' : true, + '4603C35A8304F6057C253381D39404E8B40AE0958B4EB2CEAB7777CD85802C0C' : true, + '46236B9468DB40FAF467AFB0C35B517E514251530785695F54440E6730AAE44A' : true, + '46584E2D9BFE069862BC6449C85E904AF29A71887DCAEB14C191D75ED0AC1FCF' : true, + '46853D3090658137B446AC75E481E4593CFF61E22115C348521D70EF398C05F8' : true, + '46C05D7E95263B17CE368AAED872817DB0517CD9F388396CF42568DF88C96C67' : true, + '46E74AF8240C97D2E91E118761CA4F74371BF7D2266601BAF6084BB1924B62D6' : true, + '475971EE29368BC1FB6B66D497096A1ABA32C66A30C7D554CB11FE848345B46D' : true, + '47828F3C65E9FB0113793E5B60E19A44BC9775611C44ACB65481842FEE2FA819' : true, + '478D230215F850914D64BD43327923DEC9E52B4F14EF5E7E9122B16F40B2733D' : true, + '47A1BDC994354BC3EB242FFC12768EA8633719084BB5A159E30FC4388BED59B7' : true, + '47BE050E9E76AE62AED5EFF6EA9F2E0DF1FF0E7A3EE2B6B68D60B3C849E070EA' : true, + '47E134C83737EE674C6AC46306C325701EFF7B0A4C887B968593CC1F5FCAAF0D' : true, + '480ABF7202B5437D84FC1F475A30A19C18C7F598BDA1375E8AB84829B966D596' : true, + '4810562E0CC4EFD265AC19316F353D660806DC54231D65C906C6DB1E86EEDAC2' : true, + '486F62E8D5F6323416CF210DDBD26A256AF9AD33F70A2C1CF8915866F74C149D' : true, + '48DF42F374FDCD58EB650256F421F6C1A73F663DCB8DE0972DF9421205509F8C' : true, + '49AC28CE0DDCDA953E64E7D131DEA9EF57169FF3280EC9FC6DAA88C943EA9E76' : true, + '49B7DA13E82D9DEB867193B30E48CD1279A66A6FB44236E1B93AAF62F58EE077' : true, + '49CB0BC132E548E6D6A5BCC31C2254016BC2A181755B5B13D1D27218404D1C74' : true, + '4A12F9678B1A5B4677054BDA1CB6B41AD8A4F556A184E7E4C33669EDD31EA50D' : true, + '4A60AA57F2A0858D4A3A9696C5652432997B73BDDE06880BB3DE7879FE79B87B' : true, + '4AE41D7B98B74E61B0D6EED291348B881E5531B4ECEB9940631835EF6A8CC60F' : true, + '4AF1D354BDAA3AB076BB6A02BAA3E1BAA2503D21ABE54B54001BCF62C0982721' : true, + '4B2851A38CCC082ED3A24F9DCB8C917F572D9F064CEF218D2E07ECBAAF6EDAAB' : true, + '4B6B616E1EE80E17D1BB037A2831C3AAD7E6CDE3D89A205D1F7D6E0854F3C21A' : true, + '4BF10AC1958BCBEFA06944AC7866E3458EA70E6ED97DBDDF01A84A360C3B71CA' : true, + '4C1A5506EA02230980E66C1CA936B268A3C453E997733E44074640CF4653594C' : true, + '4C3F647343026A15ADA9E047A8B4527FF88F9D01A2B7AB7241947443F75D5E96' : true, + '4C6FC9852280F11829BD4066C38BE6C1FE4E4C053F6126EE03D15EC3D0BD5B15' : true, + '4CCB36D30DA2AD2DEFBFA838DE32AE64AC8F6AE138E0A1FA46D1E0CDB688974F' : true, + '4CE6DB77F8EF355DF6EC2ABA7A5989DD0F2D0BB228DB5DE69BE7C83E3603C69E' : true, + '4CE78AB01352DC6AD84A195DD333207A43CBA0372546FEDEC9E6803DA6375403' : true, + '4D26A014A4C4007564C743D9BBF9C2DC9A5A881C05E549DFFDAFCD3814F3966C' : true, + '4D53CEABA15DE7DACABA8689C96832B59F66AC55E9E94CB595405004A1A9AF29' : true, + '4DC47950ADC2B7FF5A9A57167E343AFDDB27155DE0D031F25149B622E608B8CB' : true, + '4DD59EC33898319B54EE610C9A4DA78A87504FB8631FCA5783223F306529FABF' : true, + '4DDCB0EAA387111F7C2E0355AFF2C3325514BD9D9A3812295F7506999838B7ED' : true, + '4E0E281DBED708FB0AF032A0233F134D3BD309224DD8BE9894E749D1AE9BA37D' : true, + '4E5AD8D52C37A505176F9BA95BAF43CB5FD5A7FC4654DC71178ABEA8188E7ED6' : true, + '4E88949F1AA84802EB493CA5C6CDA9C6DED49A4DBA0C8453139C89A9CEC2E041' : true, + '4ED3C78D58943651EDB04EDDCB696F91F7B33450831CB18ACE714720AF4523EA' : true, + '4F212E4C3A8E4EA8F7D258A988D5930F05A8E61E78D86DBF9478DA2DE8F01B54' : true, + '509A3662D987A2D5D9CE7943D1878A36DFC4A786CC185CC9DE1D58E15E2EE02A' : true, + '50C1358C5AA5556E967E2CCC1397BEA364DE2E7C6704B6950E423AD5D5BBE798' : true, + '50D5DCC8D0668D34E90722924EB28C37C803E34156DE8E61DAB296DBD37F5993' : true, + '5112E6A8D06852BA07669C1DF31EFA1BA2BE7894C3F0F7B7282FEEBB698F7F4F' : true, + '512EFAAE67E525C0DC3D7AF491ABA9FFA1B7439031207D293622E9286F0BB562' : true, + '51452CADA5B15129E04773A1BAFC3166F56C59B4CCF905060BA52EB6A877E1E9' : true, + '5184A3AD148B610511D8D02CFBCD2993AFC3BBD576721B617FE7CB1DF53C070D' : true, + '51ABE9BEDE2D96CA84110007FD6626F0ADF9881A3C74870C119CEDBFF2B4CE54' : true, + '51EE14CDF007AFBCE34D598602831B21661F6FD7B6C04B0D34817757B4D007D7' : true, + '52B8E665B8191D828F946C041ABC28AC6A5719A4AA21B1C403F7611F11A84F31' : true, + '52C584E4DA8D3FD6FD63E83B2EA0FD6D98DB0413776C26122FF0420A3F0F91A0' : true, + '52F208427F03726C6DE3F5308C776D690F580EA39DDB01595DFB54364C48377D' : true, + '5376577409E17E8F37B2CC6FD486FBD356FF2AD0B5EF520DB7CDAD06C6A6F3E0' : true, + '538735DC5CF27D0DACB0FBC4FC24E0598D8838682CBE3DA8C37CDA60F60BE64C' : true, + '53C57169154423529775809598828294B218B2D2AFBCD3F2561FD072376CA188' : true, + '552771717F5948A7FBF93067CF25E5D1D67A63C8A3DD09EF98603165874E3281' : true, + '5545F754EE0194995FACDF3F30F3E6A8B0749DD750B0B5964B16A5D9B21E9FAC' : true, + '55E0EF8E07B79720C78F3E2303981BAC4BE4FB417D858E3531716DEA81BB8D67' : true, + '56B5B8AD95FC9A853F180196FAF9BF2896A8D2E053474ECA3A19295B1D214AD1' : true, + '56B6BEB3100D40CAB0EA4E450188CDDA653F473F3F182578AAB314006E66FA5C' : true, + '56CC8586CAB1C99C3EA4C1D35E91FAA568DED02AA74364D08F480A0EEE4E4FF7' : true, + '57383F2DCB3A5959514A8C0CB208205EEF70D3A899BEA2AA7D1B6FD13BB23BD8' : true, + '57A0B57635F2D75EBC9C3B166E68E35E1CF91BD074AA9D5CBCB3359D93F02859' : true, + '585CCB444BDE628F6778320DE64727701AABA22F826C31063082CFC5835742BB' : true, + '597C180F976AF183984FD9B1D015D000C55AF0B873FE4A4F8E782D191285BAC1' : true, + '5999169B7C3C7ED6E94A194BF0DFF7D07EB7581BE8C82E77B83DE42263F6A673' : true, + '59E0DDB8377B568DA0FC1E2B7C482CC6331DA441F85E7F52FA8AE280DA90D051' : true, + '59FF0CC641EA56CD3670E81E4BD76A487163C70CCA729E0710D49AD1EAD70634' : true, + '5AA16CEF791C27E12F900F07D5FC9D0B3386A1FCCF2F547D08E94AD34BABB775' : true, + '5AA7341552FF047164227AEFB41437582F7116D76B854F54920A5D6A9B72271C' : true, + '5AEDDAC786E11B696A37E5506BF5CB702A3B803BC8506BBFF720788401D595A2' : true, + '5AFD1775AD2CAA741FCF1201AE206C4A1286C0DBF751AC035BAADE571F002927' : true, + '5B11479053C46A16C629C58DD5EB40529814B75A6BBDCD6BD6FC6BA9483D9669' : true, + '5B1D47E25C53FAFDB2894D342FB536794A99B4D0F4C0BB994DAC22CF9247F166' : true, + '5B67A7FC34D1885F7351DC949794160E0DB6E6C193286145DF8E483F21E90B80' : true, + '5B9F8603E75E06129C216E4A2DF6FB4EC184CE685F6C229BB85233DFFD2335A6' : true, + '5C07B9D0BC6C5C3634102DAF631A330FC02BF579A3421E1B8483E076953FCDF5' : true, + '5C2484F4DCA59EC5D77C5935BF71EC473995A9F7D39B0F26D2264A279C6DEC96' : true, + '5C25116119EA6FCA1D13D54D4870475E5B3D34B060605E02F9C7521D3EC47441' : true, + '5C34509E57E6B30A28891841EFB2A5F0D051493059DD80157C19B2822A97EAF4' : true, + '5C95EA9F41391B1D2609E3CBFEDDC0B9B865326B4526176D5305DF2EEF5AED52' : true, + '5CDF3C4C27BB3B1BBE8C6AB81EFF3FA995BBDFE662A0BCDED869E462BE748486' : true, + '5CE0E2F94DE7BFC370B5C429E1CE1A0635E4F38D55BAF122748D4307F1709DE9' : true, + '5CF08039C4F9AC5947E941DB6D681C0CD7971AD6E068262D919060C1A66D5FB2' : true, + '5D2112B7777AF1BBA029F1DB3D166086C0379669C01C03FCB1667645F32EAA35' : true, + '5D5F5FC12AC675264FB7F2783EF62458304D84B09BF62E19EC1B91243E3E5487' : true, + '5D77443F3FFBBAEAB8C88714A8EEE37196F7D9CE89517806EDBF897DE0215763' : true, + '5DB16AA171CA274D753222AA4EC17827814F5A69CFE72D092397F048CEEB2370' : true, + '5DFF17B36C6CED5E5607FC2A8B6559964A23AB8B08181E1CAC94E3B213767A1B' : true, + '5E579D296D274F9A01D1E1A7410A24029948FFA01595E64BD2E492EEFDD1F702' : true, + '5EC75158F235F80BBFC25F40D96AB89CC35D8578BAD11410B5D32CC33428A00E' : true, + '5F05ACF54EAA38008B650AAA2DBB3722805C793616B1A21B43E1879107254E38' : true, + '5F6795C104B707429A3E966D32F847FF1B18497C73A45F6EA5E47378EF1D3823' : true, + '5F98F1AC11CB74885CCC871AB7CB1B95989E9E3E7482BDFC32895A65A783AFE9' : true, + '5FB819ACDB4D470232F59DBE853A5BC55C3713062ED6F75AD35982304E14B32A' : true, + '5FCCA125301032F32C5C915A1AF5191FB7E0ADB6E36AB4210099490CF54C2C27' : true, + '5FEFA4F01BA5AA16F36E2A4125C2E0F808B9503355BF09B3189A623B8EA42E69' : true, + '5FFD23170DA2D4AF8278447F473A80F69D41889D6C91F3A598E41B4C1170E43E' : true, + '60234A884EF08293BDFED2AA0F7A12164317F1453966758A66FEA4AA422E9A14' : true, + '6085325DD4C19C14024B66E50D6FB600D161AE12B569A70B9C1EFFECBE9C2A3D' : true, + '60B1AE233D6CEE231FA2D0B3D5888FC9842087D2ABB3CBCC6E9C230D974F5D7E' : true, + '60B7233177358390EAA910658D1D063B57CC3D5B76F70E521CB81E39DB9AD50C' : true, + '60CC6E8C652D1CCBFFA42DAD8158217DFB7F42B9EEF9DBDB795ED372EB2AA728' : true, + '613E70A1BE3CA6314EDB7C00B2477990271E0C8DE8210EED56ACD391E8CFF28F' : true, + '6167E58071C283AEE1B24B692C593747D5FAD1B3A001B1CF11569E80FDA44152' : true, + '61F83ABFF7740C9144959145660E563D682A8D21E20B92AF581237F621A5187C' : true, + '623760585A2256D234ACE51A98E31B982EB5E5BA2D3CBD673C747FC832529F60' : true, + '624A2686ED8B75686FCCC3FD9DB8284E94981BF30BDD2453817BD653F3BD9CF2' : true, + '626042CAC6DE8C95C77C0E732144FCBD63418D72ED04CCB42FCBF260B38B21D5' : true, + '62C06D5EC111BEA1222B57F5BF5FA974B5025C3554BCFC2677048DF4A2EC0170' : true, + '62C4876E637B0361493822910A5FEBD70113B70407AEE4FDEBF249585FC4A069' : true, + '62C9A052080F8EBA5E8FEB9615B5CDDFFF1D74F8467653030CB1BA12337EB5D7' : true, + '63448627F20BDD4F11B278941D82DE56AD3A689CC06064D867FF060FCFE29A49' : true, + '634783AC64589BF61818D6D57D8C3628FBECF3354AE91725CC1CC3A6B62E4E0E' : true, + '63591FA550D322410D6B2617A3B70A23046032A8CB2F96F2CFFF9111D46489BB' : true, + '635B65E10638CE83AC12795BB42A235C6DF75DCE35AB6901255D4A3B0DE05FA0' : true, + '63C46A097FF0E3D00C6ACAC2029979168DC83ACF453ABD79E9502AEDFC9736A2' : true, + '63DBD2E32AFC1025D4AC5CABF8E6E61ED4DF6D0DE50533BFBD6E3918F40E6EEB' : true, + '63E6A22E453B17B4EA3E35C6E39EB315DBB77A237B1BBA9BFB2B3BCF675A63B9' : true, + '64261C63D988D7AD86D209177AEF7DB6EE3E62151B54C6FADF8F100C2750D0CB' : true, + '644E41BA23C44182CD1D12265833CF5D62553B2192496B051118DE945E0B5BBC' : true, + '64831454483CA9CA55859BBD324F492638DA8179EAAED19EA3CC8E16FCE7A83B' : true, + '65B9EA850436692D74A1A350E112A63BB4F2B9E4B10A602707ADBEFE76B247F2' : true, + '65E435C88F831D080BA50F37D0668230281DB9A679D705FBA84820A44D822540' : true, + '668B926F5EAA59F351B7ABFCBBE5FA17B547B01C5A7D4AE385736CE8FD13359E' : true, + '66E91987E1C56D61C6210022B93C24BBFA83C039C8C13E71A4E949A252792B77' : true, + '66E9E8A83F938165FE2D1F3E6669FD46132CFF7A2F99E5D23CC3CEEE0A07EFDA' : true, + '66F68579A292313FF975514DFBE38463C59215775C62323FD02302F539E3B252' : true, + '671DBED9969959A1ADA0F9DBAAFB7DD35CB71FB06D0337DB178E34BB5CAFA9C1' : true, + '676EC356B302BAC4392ABCD0702056E398C3092F6F3C66B61CA17171FB8196A5' : true, + '67E6D8DB673E4B9ADC12C134F94EFEBC055068A7B255AC721582D7AE3FCD3D6C' : true, + '68EE7C99FB1E2B8F0DA74C5339E58C6A1F7C2697CDE363B2A8A6D8E012D2C773' : true, + '692C08B2A888E8B373FCCDB491C531D58002CAC55188368BB037DDA1F2C829F5' : true, + '692C7B1D9E68C51DE61E300811DE5521D900BFBE44AA0E5211A4622C51A1193F' : true, + '6981222723F6C1FB0E7C14D8181D0799F0657E123C470C759F70A78D995B7102' : true, + '69A828B3AAE09B3F1EFBC53DB56353AF2444809A08F188668225B2A0EB520FC3' : true, + '69C135C5854B93D0B081254262DAFDB0FB3C0603D45EE6F5E91BD6678CF5A6E9' : true, + '69D7A817007EC6958CDE66700AE1372870F1AE4710026D3F93EE1A15E024C880' : true, + '69EEB2BDE9BE075A2C6927DCF5DB9E9427FBD153953D3843BE5151A6ECC3D560' : true, + '6A14524124841DA5A7C0A27539973C88C77C79EE8C190068EAAA9218CC35AE76' : true, + '6A525C84FBFEF83BEA806634766F1530D9C5964DFAE49BD2F678984AF29FB474' : true, + '6ABF9C8C111E6353439EF682EDBFECE4F8AF8029D4E9F3F0E638C27A347DBA14' : true, + '6AC112C1828538894A1FAC7CECE0ACFEE75658118041513498E880274BD2B7C9' : true, + '6B02CD14A3675354A800006220E94D8D4D5F9774D60EC984955FF720D927E529' : true, + '6B59DAD53B5D9FAD67626890D678177BE94BBD7C8E7815986BB28C09BD60E9D2' : true, + '6BF07AE522AE438A1736D449CDFF0D8F72F7690C120CD9F51FA2CF88160E8980' : true, + '6C636B0095B2D2ADC0DA3BEA01B82A14130410220A5692C3FA2F374E07EC03AA' : true, + '6CC97CE9EB4776E7E4EE831B97F15D992FDDE766B9AA2233B41770271C0BDD88' : true, + '6D13CD353D7F6723CC79620F59D5ADC6FF6FD185B9482C0D3044B69E8B60434B' : true, + '6D3BBB6612DF6B07FDB7630F79AE3C8B7609A853AC5E95FA5061E4248BE9CE97' : true, + '6DDA1CB95F5505512C2759E9F6ACB12B2F66CDEA160527EFA91D2F1CE057079F' : true, + '6DF2BF0E57C2A025F1FFACF32B574A50464D613CA9873BD8DF692B62CB1DFD74' : true, + '6DF8AC95B45A03538483369BAEE17EC1610F591F633E29A9A4DFD0C29E28397D' : true, + '6E01105B0FBC4CEC9790A2501D4DC5536754CD3B71480AB7C200B7A671A643B5' : true, + '6E61AF6B9F05C441F3AE6B3FE2D5A6ECF9885A2B223703D1C9660D14E6102F7F' : true, + '6E7E91E395DCD00520BAB2D41630963493456B73BF32E23ACBF4C2BBD5F0A703' : true, + '6E8D6125A9037938869D2D9C291AC9A2AC3731A6E7429D9E2037970069B7659C' : true, + '6E95E8980B03A9FF276C6A4F68B46DE8D29410A9FCF4285633DA91647BE7E10C' : true, + '6F6CA3B04E355CFF85B89EEB861EDD2D91CC874EEFE99A2D9B0A3095653D9E97' : true, + '6F8652847DB9289EECB5A58CA15FA522DA5F26A60E0BAFAA1BAAA37B32FBF465' : true, + '6FBABED892623FA77A93005871EF0A6374050AE9F3D3A346A8BD4558EE3959C1' : true, + '6FCE4CF77E254C2920BE515857DAB1929ECE7638DD8C370C1AF6A374F36517A6' : true, + '701E5C167D1D2A47E29F6E0EF64D59D978CA3287D20E3590ABF531EEFDDD885F' : true, + '70202315E3423BCD73E6A3CE51D0F541A78350111E683D8BA64AE9271A9C6369' : true, + '7066B709F68AFBA83E93FC497B97DAEE440AA3B27F8E6E32DFBB1365C3F2EE68' : true, + '70751440BEBC64501417A81F17FDB0FD31052D19DC361383EDE63E647ED1D8DA' : true, + '7081C7813097A8602BE2DFE4BF202EF4574BCD4DDF51FE8C7A2F872F93481E83' : true, + '709A501B0835742664FB4C650498359C1576F74186B0D12129A6E96A5C09080F' : true, + '70EE22590F5CFBBC659A9EA9BCFA0C876694116323562076D6FA6471E79907E9' : true, + '71168AF1899C2122E92CE1FAFCB2EE64B9CDE6D14069E7412F492C9078704F26' : true, + '713C52C05CB8B1EA3B27FBBE33649956A33D8E1AC4F222EC3B90428E52C28E00' : true, + '714F1E26865618BA75AD738AD3B843B14D776EC9B7D617CA4E7C2DBC98C8E7D2' : true, + '7180F1CD379E01A81DB181F3A839C48E64734FD493D1013367A7287181C4A7DA' : true, + '72FB0C9D7767CD725184EC22406246CC4E130E49E4630E2D5BF248187EA583D0' : true, + '72FC451177A264EC01165ACC89684C137EB92467BB44EE64962C5D1AED5F8409' : true, + '731D2388EDB673DEAA419BD26B43D6AE7D27EFDFB47B6A1124EB20D30F90965F' : true, + '7356E86E8C181E623D168491A780BA7011327CF716B416619FED3C3878A425B5' : true, + '73B26EBA4831AC03380E60772E12BE78303E9A6816058678BC432BA8D640B3F6' : true, + '745D3184B509466217C4305CF4082681DA91C917D7C176D5C8FB8C9810C1EFF0' : true, + '7464C196FA42968ABF359C05DE1A029FA4CC551380CBBE661CCBFBB1C7865E70' : true, + '74711F9774C66CEC41DE4FD32197132B13A40A6758A106DC95BCADB9298A6241' : true, + '747E80C10894375B82C313C81766E6757B1B28E5BAE75AAB0BDE87A9242E8655' : true, + '74C7149B1B6739C22FC0102A7EA2DBCA770432A85F2095812DC7961831F73EC2' : true, + '74D4CF230B19F9B9E3C674DB1B1754DEBA59A837534135CEA2A9DA3496876FD2' : true, + '74E0485AFE164965FF9F982F0999B980CF05DE73016EB7F6B38B105A5E07564D' : true, + '750C7E44BD7AE01B7D2ABEE54139FF35FC53DDE34A4E0802432CB08764E211C5' : true, + '7567AE3D698B690FB2349D4468F155CEFE64ED1975B768E791D934332970791B' : true, + '7572D3C2860E9D28159C0337E8DC7C693F307AE0F1F02E0C35E091AC1C1571F6' : true, + '75B0A587771EFCF6AD7AF92EFBDEFF0F4E5CAF9883AF521B9B13C78D247B5A4E' : true, + '75B50B0EBC80D619AC5A04DBDF5C622B1FBEE1F299594B0E4CD6B6363BEFF8CB' : true, + '75F12E7E7FEE1F0AE3C22D1B94D33E4A31EC9C3B0B30338AF4EAD52856A11D26' : true, + '7607259BFE14402887557E6AC9BB570FD9D3927DA048FF9C7926758ECE32B824' : true, + '7633A1503B4C364C9C55BAAE30CC899238244FC16BEEDF7DC22E54CB9B569A6C' : true, + '765511648B44C53C9335BA4041B2808D4B9BE5A3223FFB901ED32673D5898A4A' : true, + '767EB0B508322CA5B9E37A4A1CE1CC43F5AFEB557D509AD50261F25DA73ED0DE' : true, + '76A266265F7454F38CBC307C9FECDBE80081097444B97BCA9C722D93219EA358' : true, + '76B1A25306D53B410FE5318EF1D077B29081025ADDD40CA55ED4A0A1EF557E65' : true, + '76EBE04192726D45EAEF654FC3DFE992E2297DFDEE303BBE89C8F425269F41E7' : true, + '770784FC2B1A52F110194800E972006E868F055C52A8BE467F3AD7BCD7E441CC' : true, + '77C5EFEDC19C242BDC746C5EF4A1DF4117918CBE078CF6DD65FC274DB64CFBAD' : true, + '77CDA7C1BAC564BA322B350C6CEC0B9E813104332905F2D556603B8F661AC19A' : true, + '78C30D03D640DB32D06E482ABA1084A967544E9081BE94CA87CA4FBC2141C6E9' : true, + '79244B0AFBB3B26770A470A4F23555757DC25D3856F56D0096D9F06EB47D5889' : true, + '792EE0B202E6A45AAA85E918497D9C9F16FEAC99500A7940C0FC812ECC42120C' : true, + '79B0B3A8D1BDB11D40FE8B93868460B339CEE667DE3E94C880AD9BB14E50CBFD' : true, + '79B893E3487215CD87BE3BB3CD5CE1359CF8385BEA49A5E45BD03624A0DB3D08' : true, + '79F9792935CFEB56CBCCF76F92C17E93606B2774C0F3618F2DE9BFE9506AA04F' : true, + '7A081DEE8006EF40615953A1EF9BA820BADAA31338157E69660B3EBE7852838C' : true, + '7A0F440C38F18E15DE15BBD496D670B48571AC7A71EE56F0F696E26FE1C06C92' : true, + '7A898AD8A9DC791DD00EC4F1C6CA3F1AFBF711D2A26E99E6D0740B1B5FCEFA49' : true, + '7A938A727247270556F67BCA523A333A2F22573331A6D696E6C559302C9C1912' : true, + '7B3234A53D173A266510B9777DBDA7F372E40651E07B910899A0C1063A560787' : true, + '7B40E5E9E8A2F63FFF19CE2F4EFEC73C902CD146E75DF866ED274651288DEC80' : true, + '7B45E99CAD17290A002ED52128572713BDD96FC1544094FE297EDF28E4D40063' : true, + '7B6DCA23E77F3424FAA26C0DB800ACB6E3BBC3DC13A11EE4679049EE3DF03A02' : true, + '7C6BB49D3E96F1125169FEB59751BE733ABD4F0D2860EA0A8F1A5C9B14A62968' : true, + '7CE1119D84CDCA99D2C1040485C894E22A02106EEEAB39FD20650BFBF7CC5948' : true, + '7CEE465792A72473B5B70A88F140AA27C5DAFC6C876AD88D2E45423D9CDC6C06' : true, + '7D100CF85EE12F47C6C9755F00CEDCEBBFA513CEC80993AE5E7FAF6F68289C23' : true, + '7D3EF8DEBFDDD39FA7CA90EAC62E660639521686926488A315B10FB2A0005F6A' : true, + '7D7753734C01837BEC44A0E459A049D96683FF8D0DB78878C3BEC4C9574B412A' : true, + '7D817F280F1D664E0C9E717287D6AADB1132D4F3A3E2001B94009119733C9434' : true, + '7D886B62A526E2B996C9F715AC5B23D07EDA09AD69D18E8F54F5210166AE0C8D' : true, + '7DAB96077DBBA3345EB176EDF7919AF6889938AFD1D9BD32105BD82B0D1CBCA1' : true, + '7DBF7C36818F0BBE711267E6192080F75CE8908B48C9E6EB9626DD9B05308A7D' : true, + '7DE8C95508E4933243E3EC7D7C222F82A250E1B71C5619C547FCDA51146392FD' : true, + '7E0CD7D375698FDB4C4FFDA33ECBEEDCC86ECE5ED8942F85B216B022812A3504' : true, + '7E47F4F45DE3FCA19673D070AA99E0DBFD6049A98B94D090B6B2168A1347D6E7' : true, + '7E770FF8F54B17E68443C8D43DCF1661C1082C024BF46DC66716D39B7BC6FA80' : true, + '7F0F7FB9B5975CD10469ECD29F69E5C11CDE9EC561684535E8A36CBC514D3DBC' : true, + '7F3B3BE589085EF5F314845A6F850F9411F0594FAFDDF725D3AD3BB189BBBE99' : true, + '7FCD0B25EEE0A63FA151354DC39D42CA58AC10D8ED9EB4E0B215C652C07D4E28' : true, + '8035EB81467C64D22C3624A58022AF1B5D0D4047328109CABB74CE6B580A9A8E' : true, + '806791E1F1BCA3B3AFECAB7D1EC6FD66C2616C6CF13A3256AF0D53AB0A759BCF' : true, + '8126A7034869686473438C4C7C005631DF665491A9CE81D9B3ABAA27D327CF75' : true, + '813CF894750BE7FE8A0C8B5003B362D62D400F6F08BC1FCABF247172A63B17E7' : true, + '814461D429FB2539D44E02913E03F0698FC1ECFF7894260AD3AA9C2716B99E0B' : true, + '81A524F4768E8D164B51E023E9FDC90DFBD9EB3D6111C0DA5328B8743253BE8A' : true, + '81C82F1726447A63776BE2F5E36CC6DEDF0C62F3B11C7C8B7CE17E10309C4569' : true, + '81F32F8C3E868A588E5F34A64C6FBDB483891716BABC5C59D75391A58D8C6146' : true, + '8249977B7E0D31F533255488A5416349A1C6AAA59C330D6274C82364324C3870' : true, + '8256476D83180014AF0D76C02D405990926003E2052E205DD66B158E69DAD7AC' : true, + '82668C1629CB39A7B5D9DF6BC94349FA113F915999799DDFE31FF1862FACD095' : true, + '82C49DF2DF809141CB5FB30EAA8E41A3E510AC7F51CF203FAC2B16F20C96C2E4' : true, + '82D1AEF2AFC46271D18C5FE50811DF9A5EAB812156C2FE6F531A34FD529E75A9' : true, + '837CFD4C8E9033F38B46225EAF78A12DA6636DAA0CCA197FC964B51092C55634' : true, + '83BBDAE22AE7CC2EEC0698B2435650633DEE4E0DCF849789C974976D4D641C33' : true, + '83DD8D43E88B8D6ABAEA06F3A3A2455C8F6F79059923A08A8D2AF33233F5A63F' : true, + '840B5405310320AE110F3410F585B799CE365AC1076CA0CDCD94CA6867A9166A' : true, + '84A8C623C4304D57CE03893ACBF4E51FC9975C58658B89127508E5C33BE992A7' : true, + '84F98B7850FF7A169D5642E9EF4401DDEBE465DFD5BE957C9EF18CE9988C11AD' : true, + '8524BF9691E1C2AB2BA091218096105A335A0315C8282E59B6E8346B11E36608' : true, + '8583DD0B4F3B4EF42A66A8D6E369B1E2FCB8B7C64846B242384DF6B8FA0570BD' : true, + '85C4AABFC4B38B9B5D0A4B854DC02527DEC6BA1761B28F5698141AE36ECB15D1' : true, + '85DFEE3DF0EC8DFD281A3DE35C80A220A42FC9CFA1EA353349D98FBB58DB6E64' : true, + '86154D1D0FD89E4E1FCF72511C74A8B2B0DDF4F38E675B649192ED0C9DAF84CE' : true, + '8685E22CF1BE901D8E954A0674DB6EC013D9627DDC9FB81D3EEF752BB410DCB5' : true, + '87108514AFAE3DC15C9F52574F918D7FAE18350602652906E289802FC543E61E' : true, + '8769B55BC6349F2874697988D13507CC28F9EC6630431A7A9D360046DCBB3190' : true, + '8769C6220722FE98F6EA21C5456ED2BFDD9112CBAE15847B239AFB2E6A630DBF' : true, + '87C002662AAAB5BE7B6A7CF4B1CE9036E3A2A70A0A3CD80F64005C889ECCDDBE' : true, + '87D35135D0372CC692C261453242880BE00159B60C2450AC7D7B84DF963FCF8B' : true, + '87D61B9AF0E0A2D9F836AC304E2F5A84C543275820BC4BABBE3B75A0D182DAA0' : true, + '8858520A8D4E5C88D777C33963CC7F43E796B555E7FC573681B59DCFAFB43EFA' : true, + '887A5D0381838CCC20D204BBCFFDD864AB71C20D2BA06842921BD96BB171A796' : true, + '88BDA25A602E57FFD8A0837257CE1618DEA23AFB0051874072E85CD98F740F07' : true, + '88EBF5BCAB2CF8C43095EC58E1BD0E375518B5C734CDC394BEB34F3A7B0480EC' : true, + '8919E46CD5418E4CBC8FEA766240D5918B48BB28BAE25743EB276B996E6E7B73' : true, + '89489486E767E3C410896A44B28109680C653391FA763E7A21ED1FEB13540DFE' : true, + '8974A885ADD3112CB168E00C10557410A89955EDFA94CCC4EBA3F5A51759D8E5' : true, + '899F08AAF5A4105B9B6CD106464D7634D5B27A444CDBC70264B8CFB56D290DEF' : true, + '89CBF98E81A0F82966E19BF3BB997A2E0BCC7C90FB83A2D4627FB311B6FD1D58' : true, + '89F5AB7CB2C9A8F6123C4D2F3F4FE378BEEE92B2EF506202BFE847DB058631E8' : true, + '8BA43B5CC73958FF059423C2AC018F994F6FE3A7E88C4B4E6E89ADEC692FF1E9' : true, + '8BB672CAE5B222514864A8E4FB8C89A774200D7773F2A56347C75D5094514C74' : true, + '8BE5E1A7C8736600D204B7C20EDDA49E72107EDA9AA5E03F971FB24FA8F8C686' : true, + '8C2DDBA5CA9E4CF79937A5A3AFCA79F371B6F235B37308EB53ADF12C319A7EC9' : true, + '8C6DDA18A4CB339717E1321FBFDC9A3ACC52F2FEF6FB453EA389A2B43FFFC63C' : true, + '8C7CFA7D4BB49D306857772722769DB1FB9CDC09F565F22A8EC082D956E93694' : true, + '8C85C2F6E697880B740C96BF35FAA02B4B2F718DDBC4A8ED6ECF9EBD7FBEC1E4' : true, + '8CB93E0ED93C6730B58CC0314B8158A7A92184312C53A7CDABF05B369CC7E730' : true, + '8D0CF6F0B227BE9394DA0DADABAB81A44900D104A915645ABF030220F3AE187C' : true, + '8D0EC1B68E24C1C390A7DCE081085A14CB27FE8B5CE652A60529E04825F289DC' : true, + '8D7E00642EF079DCB1B9DE964075E3FD44C63D7DD6493AA3507D87D0E277CD25' : true, + '8E6419A3781E9E9C262AFDF8318332504EEA56B39EF770B9882523D132B85AE9' : true, + '8F8515B35B665B69D0DB9661EAE9FF0829B71CF4AFEB3BBF988BEE73985F5D3B' : true, + '8F9CE539058EA5E0587C8E79E554DBFD1971FDE7C5A96DD1EF7277AFC2EF70D3' : true, + '8FDA31393381A23479C8BFCADEA59DA75A1C390693F72CB7B546C641BC698256' : true, + '8FDDF56677555109B03ACCF8F39EAF657767096D71F1652125BBF487FC6BAEFC' : true, + '903081B318092837E460229248FA67A70B01EC6DF9C9D279188ACED18F1E6BB8' : true, + '905AF56BB5517C973A43C5B576B40C5EB69F00E615BEAA8538D294E40BBA836C' : true, + '90859FF52A82829F7DC99392C6AAD9F346F54ED3D468426C26233AD5D189FBC7' : true, + '90BDE9F4CB3DD673BDB6C641361BD8B076A985903DF004AF7E74DAD95EF82E50' : true, + '90D6AE9953E31E3DA34A67533E444BC924E67CC2C610FA468DB31E59B1A35471' : true, + '90FF35B27260290E94BE3E2FD6F62F412A3FF4303E38ACF6315E190A1980A095' : true, + '916A17B983FBECECABBDBC4ECA80A330919B2EC1F3F4BE4A54832B3874EEE5AF' : true, + '91CD0D276921BD32F4C8616BF2676078C24E39AE1B30943C5263AE0377F41F21' : true, + '91CE410FCEA8EC201D33AB8E7419BC60E8EC83509B51D10BBAD728E2B6EAFB1C' : true, + '91EE28B14AB2C7571BE6CDE2D75FD4C05C960FB033DA819EDD463D5D3C494591' : true, + '92624A843DE27E186FB6C18ADEE88F30E00A984E44BAB93108BFF565AFFD2A15' : true, + '927546232861B1DE9D105031E4A2502A170A06D65340705EE3D7ADDD34F9FE0A' : true, + '930971709C7B3F9D52B30CD42E61D03BB430A1D8641F685F5A9F730760FC78A5' : true, + '9343EA576B49D46887962DA39BEBE09276ED97EBDF47A82AA8CA4F28A04AC789' : true, + '936EC5E6437D79832DE6B015C38725C84A4638D73770965D82F3CBA4EC35C0BA' : true, + '9394C03EA88D9DCD628AACC140CF1FAAEC364252F318F577380BF2623009DFFF' : true, + '93AFEA0BFBF153CA77357087301C0F31B095EF2D5A53F7E2D02F9B13DD6E7325' : true, + '93D45B29473CACF1E89444ADB8FCB8C3626C278E2339E897C88C2A51119C1C25' : true, + '93DCEAA3D67BD8992097C446EECE4A6A02DCF89EAB0008EFAE7D0C9BE26B7C00' : true, + '94C5E69A5644B4BBFF863312752633025D60B905984BC297D103F7B58F8F1CAA' : true, + '94CE12FB5F69E4273C8F813ED37ECB954AD667BC81C4E37DD27A40C291DDB12E' : true, + '951E14CC4823E3E83E2DD0CE75826B7BDBCD45CB16FCB70A1CFBE6C6BE1157D0' : true, + '95EEDB5E6C8B8552E29D7FB0C607EC68AB3D3F88A3FF97F4C70D7BA9D69C8521' : true, + '9658D54C28C27DD6E9B79098D7D86C1EA32215492E8AE9DB225E3410EEBC39CE' : true, + '96735DA929F88A1A3292D120F963FF675FD13315DECAE2555139CCF71822F408' : true, + '96B9BCDC21A4E9187BC7BB7B5BB052A1953140044A59ECFB2F1DB1C0FC648FE6' : true, + '96BC0612871BA526E0F8AB96612077A50930AD430147A0BFD37E1BE21E0C64DD' : true, + '96DC92A327E33DF81946BB760B8C22FD7F74A2C9592987BA110F7A9D211F47B8' : true, + '974149DB587C53796C2752AE8D14C7F3E7C9A1002EECE93420AEDF52B1F48558' : true, + '9787EFF64AF68F280E2778414020672F24C44010549900A5A0487F11CADF9A41' : true, + '97907F0BB6A5CFB411D9975E742C8DD55AED77AA373C56DD74ABE6B7C9892A60' : true, + '97B09B0E6CD2378FA7CED47F365C77266C94B867F8F87B01D8B667D0DB2F5DC8' : true, + '98323FED7420A24CE2E1D0A4445B73918FA0C867BF19E2FEA18449B429D935CD' : true, + '984E447F3A932B79E9373A9EA9786E0637ADEE21B6EAA6B8127B05F26D7181FF' : true, + '98AD6C8A91B962AFCC223C26F0026802B688AE55C204BA0A4ED5BFA5619D979C' : true, + '98D9DCCD4C1EF004D7F000B29AC540E935ADC074DAB919F8ABBAC7507FC35EBF' : true, + '990477B5471E1BFF7187E419CFAFEDE674FAF3E6325182F9F8C686A2BAB085B5' : true, + '99E437DA5156E02DE52D0D95AFDE0FDBAF8F626F4D3BAD2FFFE7F4C75D76BD60' : true, + '9AE40265F51732A5A72BFE9B4C3CAA7106EE84D320F7C675C443C91550E5F701' : true, + '9B340670FFFA8B98B78247E2A470627E05F1AE05ADA505FDD049350B5A8521EC' : true, + '9B573154350FBEDA3CAC21F90DC0E59C9EB0DED7F069650E099F62B0871F3615' : true, + '9B80DD5C98B0F0A7AE343DBB896DBCE45DA52EB4E31BE057287A2A738D9CE3D6' : true, + '9B98284571E5FBB2A2BE676AE24830A6F0048748FA38D1F11CBCB252505D2E62' : true, + '9B9C56A1228EFF3D6520261D3CE06F38597A96199CEE7BFEE71D95F7EA6EB54D' : true, + '9BD01B7914B81371F2FBF23E7A0876608CAC69218A0DDB78C2AE45909744E5BE' : true, + '9BE0DD4F76D60653F0C3DF854026C8A73C5403B593504B80187730E6562FC67B' : true, + '9BF6A4CE27AD782886988DB3FC3AF54CC857946C7C5E32A9A6AB13A9F7504DB1' : true, + '9C0F47FE70B9E636409CD37362B052B40B3CF765DFE80E71D999E7EB1AE1D4C2' : true, + '9C102F918224790C649D916B43E1CC9EFC4C16ACD141E22E85F199C1C6BE7DA2' : true, + '9C109FBEC4A2FC259F1C89666AFC54EC974EF4CC52C858B3C612689CC8A943FF' : true, + '9C1C2898E71561BB2B87D8859A5066940BA97950DE95E12ED293822111EC3D35' : true, + '9C7F9776163746C45FBC96E2985B57C6AF769E83428F910C3EEF0918BC5CE593' : true, + '9CF455322FC12AA2FFE88CCC43388419F61C41ED1AEC560E11D627A009DA62EC' : true, + '9D484D53782C2FC0798843979D991B84A180C1A833D717AE002E75F90E954EFB' : true, + '9D93BBA3F1A3E4BE5D1146849473DC18A987B0CF48566E506564D4386B29C50F' : true, + '9DF287B6058B72D28B1B7E4A46CEC187EC1FF32561A6B681E2F6B6E5A4937F88' : true, + '9E2F5DDC11A878B6A7D27F9FECBF10861EF27BACAA208D8EC7ADBE2682FADE95' : true, + '9E531CB7619C8C0D5C97E7ED9B20C3A269ACE189AFC5D80DF6D2034BFFD0E804' : true, + '9E6937E5BD26C280FA683490204D1347BD8662325524F0BE4B25FC17381923E8' : true, + '9E837E2CEACD82AEE4D2CCFDFCCDD0331D305E5B2D123B317E2F3C0376BAC850' : true, + '9EA5F3B71232ACCBFFFAD71FCCD08B459DEE53DE93399DCE0A212D0034E9FE6F' : true, + '9ED22741CDF43DC2AA238D354F0BD95C28F1B5557ECE9489AABA4CC37CBFC9AF' : true, + '9EF5444454DA21B0B7D6110C9B040BDD005EA0BEA27788D00BB3F1C48D9D0F36' : true, + '9F7385E656F0E8237CE9A5E9C96A1B3CA17920EE75C112ABE9219C18F77E9E97' : true, + '9F9E4DC55925D2944C0ADE2959EED5F6E55A14BC2F6109F8864A8AAD2E4A7997' : true, + '9FC08812780624B21DB7596E278F22F0023D27DE99277E37CF07BBBD4B351590' : true, + '9FC5DF8E8AECAEAA4939A5BD94A078371135107A7AAA15ED5728C9887FF4DD8B' : true, + 'A0142CE676C4FA2524F53E7626D21042BFD8A903AC54F8AB2FB977ABB760D6D5' : true, + 'A029D3A07D53CF4D88E75038E45EA719A7A04F1084FA5C327E5AE66B229E7761' : true, + 'A03D7CE2FA040738CCFEF1F20872DDC1E321745B2C34095822A51B3BDC07D9F5' : true, + 'A03DFE739C80E109658E0B3EB41D9EE1F03EEE48162C4EB97EBC3548760402AF' : true, + 'A0AF36C48B0FB8F827459F8AFE6FB82AD1CF7D5D193057AA7BE7DE3EF5E4F69A' : true, + 'A0E9635A0A993A3C15F0D7362D4D7C1EC21A50B04AFDEC18685B4A21F69E42B3' : true, + 'A1504C131B0FE702B64AA259B901DA2D9B2AE9D85AADE02F1528C1147F98E535' : true, + 'A1712F04B99848A73D978552028EB84039AB331DCFCE329E8A7A59F678139F28' : true, + 'A1B71E94B84076BBF29645578CA796F299D5FC07CA4C2049D41760F9B53035F2' : true, + 'A2152E5BF42DA70683BFF5526B3F9B90045F74B82A034EDDDFD2F8674BD20D7F' : true, + 'A21C3F2CE357822C64D1F9C26446235137559939DBE7C7C3E5CDA218376EC1EB' : true, + 'A277B893194AE7687EBBCFA344178B3578AA6228D2B430BBE2FC8D5EAEE43135' : true, + 'A2E6C7ED88E5F8103D95E02F792372AB66EEDA5AF35CE4884316493325F971E9' : true, + 'A3554186EC7CFF6B11D03F042B490700287F9CCE71A4F581B0C5C13C2A0CE643' : true, + 'A37B9444FE3BB0FB2EC43F2677926EF458D0ED4F0688FEA6443A5F243F10C2AB' : true, + 'A44473407C78C1A951194CB7DBBFBD5010A60A0C82565E02AE1E372975C8D8E4' : true, + 'A450EA9215B45056104180FAA52CD6635B94625D0FA383A2000CD8FB0B203E28' : true, + 'A45C0F1FB81BDEAED2EF4302BD5AF171F31496B6A8D502B488BC8E3E22D5E992' : true, + 'A45C8546DF176BCD32BD7D15FFE732DA2B73EDB38D387108ADABBE4B20066275' : true, + 'A4C6A2F0F5175D6C5C1D87E61ECCECB368E6B5374F056F222FEDBD0857B83F2A' : true, + 'A4D07A0F8A6A11935F63B66461D06DAFE3D8AAC0E0001B5E842A2232F327137F' : true, + 'A5278398DC472DC37141AA3EFCF4953AD7B14AC25D3730D2E99020353CDEEA25' : true, + 'A558DE705EC13AE6FF7DF6E6B1BFDB54A7CB7FFAC1499954FB109E6B884CFC03' : true, + 'A59F7C5EA7F5C48B71DC6BB678541E4982BBA6FE8E181F5C91DBB9F9FBF49A66' : true, + 'A5B9EDB84D5E06BB960BD23A73B0AFC8A0F35C95B782BB54004EEF2430CD3351' : true, + 'A6584C2334B3B29B3F7DC858D65AC229F679D8134C75DBD5A6CC1A4B897ABB2D' : true, + 'A68F08DECE7FAEC73E7F00AFE4C758B2742EA6BCB9FFC0F3D09C3D3E79E41EBF' : true, + 'A6B6702113E87CFB26DA2066CE2151698C68EC71EA906F632FD65DD35B3E0094' : true, + 'A6D113CA991875E854CB226297662EE3B083F5D4E15E03D1FBD96AF0FA6691DB' : true, + 'A6D1CFE508A9E64AC65FDE0FB8EDB8A808D3083125E2BFA975B4A1F0373FE8B9' : true, + 'A718CF6FB0B4672FDB9BA1CDB812CDB98423DD8ACC8991780BE5E0FAEB863FBC' : true, + 'A74DA51FDF285B66F86065496D236FADC4D44051DA6400B743DAB15A81FF3B13' : true, + 'A7636BE0A08F56D7F05A8D69AF0B7199FA7C05AAC123DCE71AB57C538A4D910A' : true, + 'A806A89477E76D5B381113AFAF7D082B543E172A38A1C4B5E23645A81A411E8A' : true, + 'A84DC1DB143EEE938A45743268683770BA0FB2EE69A4EB4B131841555CF1E124' : true, + 'A8E146E7A32922CB9F5908D8FC85B2928D4BBAF44E8917F370E57C60EC479EBF' : true, + 'A9266E0A665A00C7C4360A7CE3FE0B5ADBD6E7E20A32677E43BA30FCFE112E30' : true, + 'A93B07A90F55AB3B6BDD56958FD69A808C8DEFA838DB35D323F080A4AB1E4B60' : true, + 'A982473B3AABC66BDE83F206E260A07267088862EF71389082A98858BB12C3EB' : true, + 'A99953DEB7EA51793C1A353F91A070E4702D42AECC9808E4F14805A755D1866C' : true, + 'A9C8BD62DD64EBE49F3DC28459A7756B6D7D6168A9195E8C52D41D2AB9D9CE05' : true, + 'A9DAFB7E89AA7141CD52F08D5740F09F388419744351D889C96D2B4C3153A424' : true, + 'AA1716CB8EAE12CAD75B01F3A4EC5516140813349BF4041369089A6063625EDB' : true, + 'AA55A82D7DDFFAE695312FA5ADFE893D1430057D1D8ECCCD2A9E985CEBAE3989' : true, + 'AA9F7FEBC74FE835504EE24501DB2D00409FC761AACAFA92DC8A696388AE843D' : true, + 'AAA011E89B2581C1863FB1DA1E41A8FB8EF14ED0817976F16909C68E27F4E70B' : true, + 'AAB01A25BB1EE114084DBA1E0B2B8E5C84936196D40CAAA26A16E58FC50E2B93' : true, + 'AAD7DA6E17F164E00B0B63A6338330219F40EE683F8E0CA5F6B709F2E13FB3E5' : true, + 'AADA8A48FB9966CCB61E4B8C97DB2DE50F0AF34422D74D1A770501AD00C40119' : true, + 'AB34CB23DF8A006DD182B01EBBD38DC13785C4DDD433564B5CA7579DEBF3B1AC' : true, + 'AB47045D4B45B0821E851EEEF7EA9D6571F9759DAE4F3DB1EF92597BFD2B4FF9' : true, + 'ABB5673AF0583FF328D23B1D4F35B33EF6B68DDCDD482BB3BC1DCB43D2A0367D' : true, + 'ABB5D30080E3CFE6F83F249F3F8A22C731F318DDF1BAC4D4895B2B7F7A6287E4' : true, + 'ABE9809D21AFE6E0FB253DCD55E10C31DBAB32A973EC52DFDA1C15068F89D333' : true, + 'AC3D6D1C64348ED7E068376BFDDA866A015317B4AA8A7FC0C16F7E7ED4DA9682' : true, + 'ACBD5C965EBDEE4D8D3EDEE2A5FC407A6A3A7AD5E6EC120EF1854C18118953B2' : true, + 'AD046A8C4DE2A89F32973F0566452CFD38CE0586998717364C528F5995B5E2F2' : true, + 'AD05645C0957254FE67FC48F7BFAFC24D30BEBE233B82D87DAFF3B44EF7314B4' : true, + 'AD3FC05D383E384659DA700279CE3C48DAB804AC74DE2B3DD3687F6ED355F99B' : true, + 'AD40C15657CEFAB57F6A71035796462F0184B0AAA489E601087DE329F35CD757' : true, + 'AD679FC990B740191DF7F88D51947A1F23D79F862160E3C94A22BB1169A7567D' : true, + 'AE03E5FDACD94805484DE44DB4BABB96D1D2EED4F0B9CB528CB30210C8005C6A' : true, + 'AE176A4F7AAFCDBBDC0B7A69ED5D5AE0A8FD0A5BD37BE887ED0F098239D11CE6' : true, + 'AE7960061D5D4739E2A6C0BEC6BE8E98ECE3E97994940C9BF5AB2E1C2C0D9702' : true, + 'AE7BAFD9FB7AB3D87D0D58774420B314E46538D2894DC58DF5F5614DFE7F0435' : true, + 'AEF7E370874D2001D989B258853C1974A5E45676D3D7595F74662C0B650BFE8D' : true, + 'AFEC41B1302FD09F03015FB573960516918EFAE30F68D97D027D45A51C4115B7' : true, + 'B06CD6AF9B4156B4379FF3C6C1F8CA182A923527D0DD92905394DB3446A11D5C' : true, + 'B09F332B8A115069BAC41865E1F1228DFD8ADCF3A66C1F2EC9DFF41173EE7A85' : true, + 'B0FD996D85E74BF51328181823707C4FE5E96C0028C2B3FAC104A96237B63EC6' : true, + 'B0FF4F8A6FD3F8FBB19A188351CD4925C951DC2D64633B9E0446F026670A47D1' : true, + 'B15FFE5C987B12D7299D96F1DBC1C7E85B0528D1AFAF9C6FE808361F7B0D1D06' : true, + 'B183D8E672345AABE24C849B4A13D0BD99C296AAB273ABE88C00CAA229A27154' : true, + 'B1991ED1894F821B66AEF2E26E0834CC796FFB43971A79588A44CCBF7E8B3076' : true, + 'B1D9B3EE2512A48A8E703E2D2263EEB4B0A3D24963F5165DB3719CD4750D2986' : true, + 'B20BEB685F3FB617FC974C4C624ED894EB2F7FA61DE28104C7B9EDA1F52F46FE' : true, + 'B295FDC9D7462488EBD4E5FA8E5B062FE5E2D0432C6A02B99F4CAD1F9BE6D0BB' : true, + 'B319CB30FD80959806C6836129AF6E1A8A32B8B8D39AF65674532BBCAFA2CF8C' : true, + 'B31C07387E56AA457F17CA3D3A4C485683253CF387E6DCE37469B6A8E51CBF29' : true, + 'B3251BB9A1B4F219400E69789FB08CA2BBA396C6D2FD3C4B69F4B7E1C0DDB615' : true, + 'B3381C627EFBEF5DF3BCC9DB71A9B6E4C0A4F3114F7E7408A356FB33FBA5D20B' : true, + 'B36D72C8B1F436DA49520421FC0A2869A9952DA405DA5E29EC3A1919453DD6F5' : true, + 'B38D0B1FCAFA3F435FECB2B3A25804FB004BF11DE5CD691C1461A4D76792A4B0' : true, + 'B4130785116E5A84BF7B191696B213BA8877228388B18C2DA38DCB9EE14AC8CA' : true, + 'B440A043514252DA267A339059C789BB14D1339B7964B0945262D978D9AD021E' : true, + 'B5008FE6CBE7E0EC5B158E8C9CE487FB6E5349F47007F3CDD2B1AAA69098FA40' : true, + 'B51BFFBF094EBB26247D54321DE8F7CC10B24BE9EA6D9383BF908E765D5D9594' : true, + 'B5453C09F38363BC702FCACE4B64A74538B1BE40617640C00150CA9129FCDF52' : true, + 'B55BBD123C4262662BC144E0CF4BC9B47059C4BD0A136C075BB9B3E82830799D' : true, + 'B56769F28FE8395FCD50E7552BFBC2AA549F30E1092A54921BE76B07A6A800F5' : true, + 'B5A9BD7AB128FDCB0DE3C7EAE193904867BAC57822BE195F3060369520403D6A' : true, + 'B5C58EAB37201F8A7F3C520FECBB3C016A30960C5931DD7C43ECA217A1E31774' : true, + 'B5D38F895E2681F656FEE774C8677D29749C3E5ADD3DAF7A2A91043BF5A4DDA5' : true, + 'B5F004A0997E3448A1ABE7DCE45D8BD263AC631D14B05A04CA195E98D665B679' : true, + 'B61D7AEFD0BDF0DF2C8C8E68D4E3D92EF45CF9F79AFD9EDC4729D71375916019' : true, + 'B633827A97472541F7DFF77C347301FB40604D6076D08FF4244C070FCFC9B731' : true, + 'B663B6C8C60A5969BEE4F6844813AAB8945EE2CE2253CFBA67500B991CD8A07F' : true, + 'B6CEE930054D71DEE1D167A566B9881B8971F7EB4BC4A34FCFD9DDB3DE311B9C' : true, + 'B6FAC01424B5C332C72B6B218DC93AEBE54318DDBFC5BD1277E262FA7831E5B1' : true, + 'B70CE73DC10ECA5F97059AFEA5A65F1B1CD45F3137BADD7F3A12DD1D6A468D82' : true, + 'B7135730040D8EC88C4228AF1C9482AE97526F30CEED5AA117387D20A61D7159' : true, + 'B72D29A0BC3BE16C085CE7AD38D1B7A945DC96F4A6F20F126138FC5202A072C4' : true, + 'B745A72DD07E5FED73CFA723D6BC2E98FA62B6E03ED378804EBEF7DCD83725C0' : true, + 'B76BD62A287E68C2CC8F8CA7FD5196938DF4C39E6F46DD81A3A37D22B761C158' : true, + 'B7E6A641053C86E17A4A328D98700AF4BA3BDD35E5208359AF120C2690F51E3E' : true, + 'B7EC03174DAD602E897345B072749AA86CAF05151062989E183C3039DE25569D' : true, + 'B839688B9303FEF8860B4FB2EDF19FF2A0BF5306DAC007E8CE074CBA13B39A03' : true, + 'B86F85494700264E918D8706B711B9E8C3C12AA776E0B63AF35B73CE56B15BBA' : true, + 'B8845702F28C3AF9B35D8B5F1DFFFA014CE411CF592B18395F700CD8B937F3B9' : true, + 'B8F0936622984493F4B74D087ACA8438AABAB1111DA258806EA86C23C6F6617E' : true, + 'B9772693C35DE8A4B6EDC9457AFC3B4B52ECAFDBF612CEF1A27AE7F7FAB8F79C' : true, + 'B9D8E2EC3C47B6130DB45DE0741CDB790E36E4617986AAD5A2BA232B8BD8A85D' : true, + 'BA4052C530EB5FDDBBFD98FA9EB99660BC084678009D5AFB2F9996BCA40C354B' : true, + 'BAC88F443D9F2F03CC7ABFB27373EF9600AC918E084967BB77E80650B3724266' : true, + 'BADED8CA137A9AFC4A0FE344F663C743D1A549D0A8DE663426B90E788868024C' : true, + 'BB7E9348A57593802F083CAA99351386DBDF348C83AB35E554BB7BA44FE1FA55' : true, + 'BB7F20108F934620F741F678F3D25F7DB4A50A2CD216FBAA1F4773767F645AB9' : true, + 'BBAA50F752648522389B89EDD345BF8C41FE10D4593A8A1DF467B2FFA7BF870B' : true, + 'BBB99D57C9ECE54B1634DB4BD6211C5167A5EB4DC310340BDE14B1BBCE275937' : true, + 'BBEF78F8C05ED5A5C2142C3598696B0674FF3DADFC8156896025A13EC892ECC2' : true, + 'BC0B758091A4613FE070BECD6CDC0BF1FE89727C3482DB4A2353CEC027E3AB11' : true, + 'BC17CA376A3CA716F41BFA9D3A2CED2B1941431D70543BD600B7596F4EA2E440' : true, + 'BC1FE50662610B7D575931031B1EE60479D9D9E3D94048DE6FBD44C88B9FDAF1' : true, + 'BC447B8A11DA8F1DE19285AAFB97AF1A26A35157AB8FE1E4AF80AA70B11AB65B' : true, + 'BC568DC8C01D8D7595FFCA2A7E000780F15EC24CD38AAF25EDDCE7BCD41E4FAE' : true, + 'BC622EDE87E66E364218B38609D792F6906F7CF95EE5EDD1A76BE0C48B8533F3' : true, + 'BCE02BE648B8A1EE092574F3D453388649082A1B72E7AFE7ADBA310EFBD38DE6' : true, + 'BCE27288DAB9DD76CB73B5754152983F14B11DD0466B1D4F6F55B61E27A3353D' : true, + 'BCEAEC2D8B8C18B58BD320D77850EC38285F419ACA8A9E939DAE7DFDF26696D0' : true, + 'BDE511A7E1B38D779BD9E758B2EE8F7F2DD5A242D37CA573394808CB01B78FA1' : true, + 'BEDF91AB2008A01DA4111518C8065D4BFD9ED614A29CF89A16E94CBCD5F5D17F' : true, + 'BF38E5D5BE0CC67C1CFAC96B40DFD91DE065F2DAAE427AA54893FFC5ADC73707' : true, + 'BF9B71E2C87C03CF421733610A1BDAB430C041EB20DB75ADBD9ECB3D342072CA' : true, + 'BFA0CD61FEFB0FE90D0F9025E67C62A735DC730F13B5D5FBED9B54A3DB882F91' : true, + 'BFA5B4A3751715409895D27F7C9F057F2C31EE560DB075008A3BAA21DE838FF3' : true, + 'BFE49B659622D1011F4BB655CDA77638665D068FBCAF11C73829D2DE16E43BE4' : true, + 'BFEC93327E0A7A92EB67CB3E00D29C97411077E06CFD010BB84A5C0836CD2F1B' : true, + 'C0AF523C6E9B52801FCA62602022547B25D8A107CC7008C67C438E1A093FA69B' : true, + 'C0DA5CBD6F39A5B707B0E7DD33004811FD6F925DE713C817F3E2719393163E9F' : true, + 'C1AF26C31745338DD2E13C1BA98A2E643AAA3271CF1FD5B878E93B1DDA2DB868' : true, + 'C1AFF08543BBDC3D2D796884D099D8A7B8D40FBA1F37AA31CEC16EBE2AFF0D0A' : true, + 'C27D64BA2F133417986FC42073BCD7DB4668A2FA7D2D217CDE215F25D2BD5E23' : true, + 'C284387A9875E45662ACE976D665D6A33C36F3EF2B053AF26C0918DEECBE7CB6' : true, + 'C2C65F50563C7E96AFE6602B9A0B68DE74F3C7AE5C00ECDB39B98960BDFE5B91' : true, + 'C2CE30C7F0723F2D2B25A18FA209B1CBC66662624FA8CD1EBA96BF051D969625' : true, + 'C2E60ADC4803F0F11F83C644D8DAF80DAD4B9D6A67FC108B3C2CE6F2576EB69C' : true, + 'C32E558AC4FEACD1690C227683DFC38CD26FEF103953FCEC9CBE0FAB08C176DF' : true, + 'C391E32BB11DD8F6F13BF71E0B9CE225364A50006E3F91147EDE39D2AA6E70E0' : true, + 'C3C07C187D95222D855EBFDFF827193F71C471BAA3A1B51242BFE963FD4A63F1' : true, + 'C3DEDA7A5C280862654DD266D482AF59CD7CE5C09020F8F32EDA0D0FE2345B02' : true, + 'C46DC6888470BF64D41C297E1FA082ABB128D4D0EC44DAB62E05E4FF8496B18B' : true, + 'C4D51A111115A7D06422BBB16B67ECFC73D636DB08551B27596FEB532D8CC2BA' : true, + 'C4F8364FC0A36A73AA0BDA4074FF1490B3AE07A7BEA479385BF28078288F9C3E' : true, + 'C520C3FFB5C5107BEF2E8DC44C74803713E13D9BCC99A57C6838BE15ADAAC04A' : true, + 'C55B18B5DF187AE68174C086FA4E692C6443B01FF4A19DCA743EC1F6E1B7E332' : true, + 'C58F0FF2DF810FAC8EA095F349A2E6D7E0D9C09D6FBE7D45895408530E1C75F4' : true, + 'C5B2A636DE1FD6629B4BA41FD1693F261F50577130A05366D298F9CD282E4BA7' : true, + 'C5E4575B4442687C80E6F9F290846CE80217AEE8892B9977C5F455BEBE285EDA' : true, + 'C610F374CDA9036FCB01F526005ED8561D16A27790491AFB26D56A1BF0716007' : true, + 'C6479E02F20A3596203FF184483F1F6A29EF9F95DAD258EF2A84BC6125B299DC' : true, + 'C66BA6D7D5EE44E268D2DFE0A00284BA59F2FD86AE8F738E84718A1B4C5927D3' : true, + 'C6983038573EE575734E531266D91772390BDF63A276B49E9360C81F8C813EA6' : true, + 'C69E1305EEEB633DAB5055D952D0A8FFAF35FE57D0E1896A7BB24EE37F29959B' : true, + 'C6A38936450B0D72D5C38EC5BE6FA683D25CBFE604C7415BC5E55E2DEB06A946' : true, + 'C71294A0124420512711C918C36F77192D2B45CDF8C99824B4BC862D0B31C3B0' : true, + 'C7E74023ADA70B7F3BE9085E1554B8EC7AA20B0E0A38A08B2A05DD377F7177D9' : true, + 'C821C2140114FA7DDE92FA497EED3E4B9131919A9EF3D6750013C6CE7FEE0B72' : true, + 'C86D8AEC465B23370C4D5086141E9C98935D91524E3CF68BBE62C0AB231EEEBD' : true, + 'C8726499B7FA3B32022A21230BC27CC59901DF584C69F33232EE76FD7A554F3D' : true, + 'C88BF2F611A7EE5307733DC2950EFF56A96BC832961FF595196EB88EFDDF4932' : true, + 'C8B4AB5E690CF9E14D079125CBD13232EACD4FA3F15276D2D7BC48FB84BDC0C3' : true, + 'C8CC1B97C420851221D3997B0C0E3A6B87B4D9F86D348917FF90BF710DE79351' : true, + 'C950A2AC5B35DEC3F384099AD2E3BA7FDBE79E93362A132380CB5ADD1EC2E94D' : true, + 'C9F2002F6542DA1BC5833AF9A11F6F5F144B76539CDB9E1738C7DB37097523D9' : true, + 'CA157632863D3E7B499F141741724FA84DBA48AEB51B04A53A9D3DFEA7F70BF1' : true, + 'CA362B0DE34C54F91953DDCDE461D54BF30DB252EC07AB6B4C449E45750BACED' : true, + 'CA46DA728E76E97AD214DBB6AC9CB1EA2DC87202C88C35E87CE574FC1F2E0438' : true, + 'CA846077B68DCA99AE30BAC33929143E856784B64E70098CBC7FF5BBD85C824B' : true, + 'CB42AB965E2C1CC7F20BE15F308C2173AE531C532DBBF8A36B292B1E1A891A07' : true, + 'CB6C703326037CB5C4456097438DF15387452C0CACD89D9DDAB1475A2111C197' : true, + 'CB7FF00DBEDF16D72C8A10151A30595AEEEB9A2317D3F44269966624417141F4' : true, + 'CBC3C62B44E2C35250AB62FB2C3993C55F251559259727D5F76A63002148F17A' : true, + 'CC1A62E8FD6FCF9A3BE4BAAA64AE2FC0BDEA2C2F34BAEF8F9123D991262DB210' : true, + 'CC815184FE74CDD53947DCC9733B1D5E9B9E8F31C8C96154355ABAF389BF7D63' : true, + 'CCF6435DDA033106286D7A69A4C8DD727B59C4E334826CDBCF6F66C801580FF4' : true, + 'CD35C7ABA0839C0D865DEA4C1DB624F709E5EA041A68DB55842E2C189F38BAC1' : true, + 'CD7C028069F371EBE93537094CB57A51CA0CA421B9A7F8C1422D9C454F864FD3' : true, + 'CDA01229ED05A3825448BF81C4479F02828C6E02DC3F303ADC153BC0600D1FE3' : true, + 'CDE7AA628678D4BCAEF4240A9D09B5BC7BC1A1757010006931949C83DA299B9E' : true, + 'CE01F10B612255CCF31E03F308F45E0A091C0FC41A13280F575BAA7F4F7B4A58' : true, + 'CE318D567E77FA3E2B87268B09B1FE99484916CDBC7A56B99900CE7BB7B4F967' : true, + 'CE34361030AA71334FC8EAC253C91EDDDAD3E2AF0974931325384B9A445CD116' : true, + 'CEA9DC1557689CC8AFBC740C095ABE8AA617C19AB92B761EA71F19AB2B3FBA4A' : true, + 'CF19B1004488D5D9C882E2C4D0A47789618E0BCD6475F6D9C6B5591C2BF333C9' : true, + 'CF3457D98980F7909742C974AE4EEABF2007967D9870705867C18A5B47CEB2B4' : true, + 'D010B9708329342E43370125857DBFD443ABC95CF5778898A7343E5F1C61F4E9' : true, + 'D0927B6D60E3441E11D75A8FD593A38665AA7D211F691BDA3D0E815EBE303C25' : true, + 'D0ADA8B3F0D09BD13AE5877B5E448C18376D129F92DCF2D4F1BB182725A62D3D' : true, + 'D0E5727B39200CF1054391FD251191C38F6754C103612F442673BC53F1C1634D' : true, + 'D18241A820196F4910694FBB37556273E54236F41FD53B3AF75B6C6430D93B15' : true, + 'D1B116326075EB6F65C4F8F8E6742B639DB23B56CD8420F42F8219CE615303C7' : true, + 'D1C4E4D1F014FB8F889F45AFA39485BE742F64268C662BB28494855E393ADE96' : true, + 'D1C684802932EB8EBBFA0DBD55EFA5345AB3A928653CC222D548CD29D91EEBFE' : true, + 'D249C8E95880A20CAEEFADA9A9B8E80386234DBCA6D990E78CE574B430C0E6A2' : true, + 'D2D9C57B19EABF7A90BCB421283733EABE5ECC6311B1D05089D4F4251D157E3D' : true, + 'D3525FAE9E537DD0A56F0311A27A603C422DB0376928C707A12A1E3785F2BEE7' : true, + 'D387A162888C2556F1D3B9A73201A8608A57085E1115214BD2588F315B89776A' : true, + 'D41844AFC9E00E17DC87F0ED1AE4A0559C418770A4FD7033E3D9A9997C5E204E' : true, + 'D44D1A7D80BD2F9B4A62E11BFEBBB74A5780B0366CB6038CEC9FBC8C8E19439A' : true, + 'D44DF644880E56596405F1364D8C3E5301F05ACBF82FD66B671D895288C75360' : true, + 'D53C334638CE54CB75DAA15D1AAAAD70081C9A52A2393DFC79E9C3A92D54F4D6' : true, + 'D5D9E3A7DAB437D5F8967A307F6BEDD3B2AEFCF59B229BA649C4E549F01668B5' : true, + 'D5E62D9B8F9EB17D8BA84646BC72AE6271E24D0C7787D302965A92ABAEDEE2FB' : true, + 'D6061064FEC9DF923123EDB3050700BE1532B68D9FC12FAECABB9FA82CE2B887' : true, + 'D6200C1744EDDC3BA40857A1089A20F7E86EC3B29FF413CA2BE49C060A79D19C' : true, + 'D63DF52A3A887D35ED58C64463BF73252738FDDFD73E0F8B378E318AD3057D36' : true, + 'D646154250C7883E951B03FBBE9EF7D3D00E74D60281FC82876A913A23AACB1B' : true, + 'D6ADFC439E8E9FAD7C281DF1117E0030BAE78D15E481B7886F54E72DB7DD352A' : true, + 'D7266CBBD307F97B7284312CD4C2A5BADA7D4EB123237EFA43E55D8D2F5B16A6' : true, + 'D737A5AE5F875A566A4ED4CB025D07D076998270F0D25292661B4CD581B0805C' : true, + 'D7632272521683A38E88A18C2CC6AED79B2C5E854483BDB6EE83D82BF41B96CA' : true, + 'D77C2904CEF8726B748EE36E43BE65BDBD12FC48E4A4ECA4885537745B0BFD15' : true, + 'D77D31A02283F81A4E64F7512C59BD71FF603FED5EC57F24F0A240F04B846999' : true, + 'D782121A27D3EFEBF791EFE34D5A81385358DA939F5DEB17530252BFBC8E2F02' : true, + 'D78220C9BDCD563F71BD8139B40A495879DAE9FB1968AE3225BD0D04DAF294BF' : true, + 'D796DA6F4413295EF05E79C798E92CF8A6AE172A091C862D7176384D520BA2FA' : true, + 'D7D1D7F326D3DE85FC1DFA7F45F9D5A3C64473B37143EB09DA66CE56F6258FCE' : true, + 'D82602A79F22AF46AD32D0AD123D30464371FFCB7A8AFB8C51A74841463A20FF' : true, + 'D86562629BA86C435C0965C4AC302160729F27804FEBA36E211F96CDEFB5DF8E' : true, + 'D86996C0C019AAD9DF5531836BC48F54427021AB8E24BA1AD073895574A143FA' : true, + 'D8AA8D8A7A48ACCB4C1B7E6C2228B7BFBC297EAFAB1315643744E3EE4DFA7E6C' : true, + 'D9065B6D9F7F27507D51170FB465FA6250DF528EC38BB46DAD0311C1DF63ACA1' : true, + 'D9259A35701E881FD41A9939C4AB82EDAA83A18D1ABCBBBF8329FC6850A0C6DD' : true, + 'D94290750677E2B5ECE7C2DC41AD4618C6995F173EC44DF80B23CC0E333EA654' : true, + 'D9FDB29EF83808BC82A97839FB2F22C2D20DAB2E6B67BF5862C8922BB1FA9068' : true, + 'DA5D20F1A6CF6CEC3AA7028A6E17D8F2E1A60069E497758B0CC938C08F4E76BC' : true, + 'DAA384D0D2A94A18A14E3DDF7A963E59BE41C06B978F3DC8862E1EE6C8E76DD0' : true, + 'DACA572539398A22DF7049B23BA3E59DAD6F34A44ED7D5E275457D9F79B880A8' : true, + 'DB7B1361B066EC2F777AE104F88A846DC163200AEB05B47D5BFEC91B6F13AC53' : true, + 'DB995D854C4EDEF4DB5CCF20B2B30719056F3EDAA0CCF4B9D9C5C898407C5C7A' : true, + 'DBBF19EB75C47A8473F59CE4B2A318B493EEFEE4B6719BDF40FAB2E81D9DB2D9' : true, + 'DC90A8BEF7B1C62F9E4B3D3345665DBB5D6CB46077F5E7ED0628A5C0E3DFB742' : true, + 'DCC87ABAA2524536C43A280BC52710BF117E56EBB39444873F93AEF18519A502' : true, + 'DCCFAA33D28DE7243AB2C1514FF36012E967B0C0C6E62E940325CFCE982BFC23' : true, + 'DCF5F2D0FD496B041393D2151A3C6366DB5D9E3E6FC5EEAF236CEA93B7E0126D' : true, + 'DD5A1FC87107218C43D2C1C73075C5506D6901CE1289F86DC0162E6BBB80B84C' : true, + 'DD79B321EF333A6C39D48DB57DC5A138F023A111D56851CD4CBC8EB1BD094893' : true, + 'DD7B5992561C1F706A82F7D9318E45DCB1CF508A564263893350E2D3CBC41241' : true, + 'DDB4149166CCAC259D826E4E6649B5F59DB8DE3A2ABE0D0CA88F192AC891B331' : true, + 'DDC51B2E6531407BA185447AD1A9825344FCD12E93D120D81825613F016DF297' : true, + 'DDCA648AB82DF2A942AAD4B384839255D5D98ABEAFB602B2BBA2F4B115072EDC' : true, + 'DE65D592D65A64794CCF2911A10DB5DB27C28E6C88BBBF75B75FCBC2CAF5A02A' : true, + 'DEC7DC8AB8ED70C1D2FB2875F0F99FA99FB53E6BED70CD47B244ABA2104DA5AD' : true, + 'DEEBA70EA985BD2637FA63B79F69B0EEE5D261E95E3699B97855296B23D82C3D' : true, + 'DF32CD36F2BAE47DB4BDD2610D77629F44819723F9BA4FCFF6CC7F6E5709FFFD' : true, + 'DF4482289B54CB444569A5436AEEBEBFB348D966D2FBC8C5115376F3E5496303' : true, + 'DF464344337A60D78868FE886F92848BFF8713D641C9AC5EBA29524842656CCA' : true, + 'E0BD7FDC3544BBBF78F401148ADE378A4A85214C0469EDD5EC23C5246A6F5555' : true, + 'E0EFCF7FC7033248F1933BE975F931485787F32928E47DABAC84FEC9D7365CFB' : true, + 'E0F0A23CA9D564C9EF7CCD977D01D6E6E7EF5ABD585819EE64520CF369967353' : true, + 'E18545BD6D070F0C6AFE93153C190792C4921FC90953FAA775E351B1FB1BCC44' : true, + 'E25454E967CE89CBD0F51AC02466D60FC091BDDD9CBD3093ABD027B0AC4E8174' : true, + 'E26F4C34273553354334DC7A22DC56A781F2491181799287CC91F12871FEB50D' : true, + 'E27966B8B9C67C751F9AB8315D0BD1CEE334D96A8C5F60C764070EF8B8FCE61A' : true, + 'E2C42D4BD3807D802CE3B9EBC6FACC04E34EF327F4BBEC1C7A48618A1271F5E4' : true, + 'E2FBB7B66934E9C420D496089F2C0FB5AFA193A1E6F49BF35A751EE1E1F983DA' : true, + 'E2FC1229FE0EDF06A3706DB8DBD2344B61A9364840A3E61E6B29CE49A966AC8F' : true, + 'E315468836F77DF6AA146AF392C5DB7262A83AA83FD7CD75771C70D29C3F16CB' : true, + 'E35CE61842F1093D8D4AA9923AC66D17F8D1870A03C9CFCA1A27361CE8091CBC' : true, + 'E381DF6792973BFE322D23C6CF2A6C24A4ECFC77F43F03D2FC04EE39FAD7C683' : true, + 'E3EADC69740DF00FD147B0718CB1063D7E90E172E196C96956920235CF9DB382' : true, + 'E3FFE980C209BCBE10F594806CAA472BA2D4702F6E2549AEB86DC52B46DCF773' : true, + 'E4A79C0CBC9966A44EC1185DD6E66371FF395D0FAC53C1FD2619B02F6ACC9C6D' : true, + 'E4E88DE573C9161962C072B7A9C966BE3070A6027A061DE32630C553C09EB046' : true, + 'E4F069C24D7162E3C94AB295EA33C8926BDDF79934CA28D8982A35650EB60B05' : true, + 'E50C2EC0BA6891F60BB325C0762AB06271161EFA9E0B2ADD50FF520128092FBF' : true, + 'E556C54852E6E0E61097B2A34DDCB87F12EF74CA847CE07C4CAD2348FF41D3E5' : true, + 'E5E046397DC23925AB8CAD7CB66E2A12EBD989350CE41F89EED455248A109098' : true, + 'E5FB4DB1871BDADEE779D366E7BD007F7A963FBCB00B90EC14C8077477E436AD' : true, + 'E68C4E54088AD4A308EC6053041A4A8B04A213347BAE2CE86D3F1587B1518981' : true, + 'E692108B3683F3C6362DF92476D62BAE60687035B70B9119F962190C9C215B04' : true, + 'E6A029856494D7FE48E048D60E7BDE80D2B6217FF084F64A929056E166F479C2' : true, + 'E6A6EDA8D60BE3C0A5A19631D1BC3262EDABEBFCD0144F3D19513C8F6342CD12' : true, + 'E6EB9DC7D407B4A2F308B4822E5BEA7428CD4520C59934214831D61E95F2BA34' : true, + 'E70FC0431E5B6632A30C04F99A4E0E55C860187A04CCCDA4FDC08E926E94964D' : true, + 'E7382549110E59A8E0AEADFBD5D29FFA2350B5FB2923F2095744FBFD8AD54C97' : true, + 'E7CF336F6E4E8CC153474F240D9238D41091EBA635F25CDAFCFCFC3AF2A6BA43' : true, + 'E7E7A31551051BC4346069C741DF38908FB54470BEA2FAAA789DDED2D627F09D' : true, + 'E80FA3BD00D99AF27B013B520D3CEB1A8DF8BE355EC971F08B4AE44FFCE44147' : true, + 'E8165BA89FE5F637FA2B3428FCC54E7E92BDDBB80505188C61320FC70E24F86F' : true, + 'E83B3C3A3EAA32F6C60BE4D4DA918AA4A5432FF3380D4886C2844D69094EC571' : true, + 'E893B898F708775C51A0A60748972C53C4B62787A591B96EFBF8CE28E29E87D8' : true, + 'E8AD1B8DA833226A37C21D1608E0DBA8C758EED7A943EDF323ACBB779E227C86' : true, + 'E9A176C583F8B5522A9A86B6A4409AFAF614D6A7650A5D6C32E4499319F5280B' : true, + 'E9BB3A11B595B1D403FE21DF47A3A4EB4CF43ED49259DA83FB0FAAEC048422D7' : true, + 'E9DDA8C162F91A7D746A5567060DD636491C8C1441697B600F56C00FE73AC594' : true, + 'EA64F2625FAFE2EC122B493D4754C2B090153F167213AB6F07A87C1D993E5292' : true, + 'EA6973A28807C80D7558B7636F875574C9FAD887BACF23B0F686A61C26EDBFA7' : true, + 'EA9369F9AEF701B1F9699363254A2AE007F47AA824AECE077B82F1C0B6A69197' : true, + 'EB11019A7642C75F4DDC1DC9CF3B469BFB4C44B71C615693C73175F16DCA036C' : true, + 'EB5F60FED8FCE35455A15B9A8E9E200FCF1B8B5B278D1511C8C5EE67BD99FB46' : true, + 'EBABE928B643E1B9FD6F61D67ACC4BA6A9BFCC95927D31D265F701AC4613B9AE' : true, + 'EBB8403BAC78C842A81201893DC86184BE82BC2BFEC8A51748651F938F4051B0' : true, + 'EBC9928117D91D999CC375930982E891C5DC4F9E02A3960FE692DAB13D96ADA5' : true, + 'EC3097F047F40894368CA744A97CBB177C1122963AFF3D958DDBAC299F793E71' : true, + 'EC4FC179A9A40EBCF5F9508C94C0209D9C28ABFB21EE932FE11BC87F2887C490' : true, + 'EC810B437C1FF46BD3F0DABC2AE11DBC7ADE12B9889580BCF20C097540C97A7B' : true, + 'EC869ABCCE3A1C036F1AFABE5ECD4FDA581D16C0E81E16A2734E6004A55896BC' : true, + 'ECA27FBA9090EAD50CEE16362AB7462FBD060DF8B4BE27C107328E49214D6758' : true, + 'ECA4B72D4C90C2889F21F4084AE4CB53F5B8EA5D147529B0CF72D3A9093532B4' : true, + 'ED310E1BAEB1759D2AEC00BCDE6D9A86DFA33B17563EB5105585F15327831032' : true, + 'EDEEFEA60ECD1F9063448654B3D1285B8D340B4AAE455A26C34AF221F6F96F85' : true, + 'EE5D710097EAD11639F98940D1F32793ECC114F0408856CCB6536F1EF2366704' : true, + 'EE82E118167C83EC466137DE867DF824A5063074FC61CD164D21F26976741A2E' : true, + 'EF162B09A3D267BB7B8C79D44D06A7AF21EF260518D0EF3A8CFA1730D7B89231' : true, + 'EF55226DCFD0FA606BFD3496633BFCBC146925B2D6685AB4875E142D79233600' : true, + 'F010781D39EBF1A76700CA71DB56877685A52CEC2E7250D2C5684AF659887AC8' : true, + 'F055D488944F4779BE3F17FBEAD728843701CE6598D01286AA1D525F26AEDAAB' : true, + 'F07E7F2A7106743D8C1FF2E201F944E3227363968C5A0AE31112473B93BACC7B' : true, + 'F0A9E452CB90B0B6C50FB794AAE7ECBF5E56801A10124C95292B28592FA9B003' : true, + 'F0FD8D8E64636B1A1CC2557C50DBADE7A1F0536B905F5FFC06AFEF630AB9A40B' : true, + 'F1C66D3A1C4917A59AF8ADC68A0722F7193D345BD978BA00FF669E7948D44F29' : true, + 'F1DE4066AF24E5744C9075CFE974CCEAAEC75EF9E6028B48090B1A46CC218C37' : true, + 'F205928C933AFF1F1A6411AB779CFAE3FAAF43754AB86735DB52F74DB1DA81D2' : true, + 'F233DDE8F7165F2D7AA4E736E6FE1F913570FA7CA3E3C134EFD22D5F303075DE' : true, + 'F2835EDF2E61A29F9E62FEF97476165D5FF40E553A2A4F955EDE30C0A5149E12' : true, + 'F28F54684E233C9EEC646C6E1336E33684DA3732ECBEEDB2A606E09DD29801FA' : true, + 'F2C91876EDB36EAD7E4821C2A6581144F1E5A67B2DEF4A5E4AFDF79F5E1CC4D7' : true, + 'F2F7938B7E294F17565B2833CC2E0A657DA80A237814C24B5C0AAAF35C4608F8' : true, + 'F3160DD030C118B5D5835743E78CCADD0620E5C08460E0CD1F5D9D437352105B' : true, + 'F319741878D155ED3E5DD4955A82B842700A64D86AB782B511F0CB9B25C48AFA' : true, + 'F3A6A1A957C3BC86EFB3772C6153D97C33B908124CA58480AD1F62C54CD89013' : true, + 'F3B356D9CE5B37D2B690C4EBB2E04A643CB542273C1754D2EC9803D831781737' : true, + 'F3D202454336E948C83BCA2342C4D1A0DBB4335E829229BEAE04B4125F0D508E' : true, + 'F3F90821BD1454FC7AC92F768D2C9F75B5CD79FF4DD3251F4B9D647D34024F73' : true, + 'F456775CCC8DEC02CF2F92A48101E18EBCC9C880D41FA87EBE5E2EAA0E24620D' : true, + 'F460158348B017310570CAB302E33DD12FF72526698115EEE8D3DE318383ED9C' : true, + 'F47CA7623AEE6A1849B4F3F90818A93AA937A0EFA65D6674EA769BD7EC113BF8' : true, + 'F48CB2C1C2551290BA59502BBFCEC7BF137B5176967BB92B38E79D4EAA63B7E0' : true, + 'F4AD6AEF9BCAC58CF21EA81D65C3B8C85CBC9BCF6A2807FB0C5CD332C5F9BF49' : true, + 'F4C119D9DB2CD569E75B9B1F0884B990575EFD920E8C62177990AE650B7AA274' : true, + 'F4EDB536BE8520B583202E17C56768579613187741195347DDB9BCE3AE2D5150' : true, + 'F5B52148D7155BEE637459A918CE58D22D4E024FB715325FC1B36DA4C6255357' : true, + 'F5DBA16527D871BEFEEAE706C232AD0B76FA1384EFB86A844C7BA46B96917B9D' : true, + 'F5EB7AFA398131FF3966EE221B9C8F332BEFCB634D42631E349AC0BCF367E920' : true, + 'F5F8E7786E1F61643C7D2805D86031E5C4CC97AE93FC3785FE289FBC44C381E4' : true, + 'F66ABF80914FBDBE53F794409F4E0DC895129066609E8B491506FCE246A2EEB8' : true, + 'F69B01FAC28E6126F1BA71159D0273519683F2317EA764B4C483B32BB97614B0' : true, + 'F6A08E63AF8E62D51930BCE0FA7CF25DD2944512652EFA275E150EDD9C11CF51' : true, + 'F6A7FA219283E5B13E256B4E039E4CCD93CB72B84D84086E398D5534ECA42DFE' : true, + 'F74D9E23F4CB53775CA60178347F2A029F77579000B21AA08EC62A1C2932348A' : true, + 'F754352E819D0C33E6CFC06EECBB4356DB5D8BD1FD2591C7C817CCE662BE2BC4' : true, + 'F77AF5088D4EB425ADC0997C059C641EFB5AE2CAC73669EBAEEA378EDA383186' : true, + 'F7A57247F89F0C50879598293BB33B7AFF5FB74BCE37BF7B53F8955CEFBB9511' : true, + 'F7B593D9277B72E9CF376EAC2BD5535F76CD9FA0FDA3793D7EA6B4D050602E85' : true, + 'F7FC63254BF2472575C6D5DEC8DDF02B24B6F1BDCE03D807B159A69820262D4A' : true, + 'F805AE1FEDB2D94096F0D341B703ECD4975D773A179555DDC83D424F85578571' : true, + 'F823D6220F702D0547375FC4451FE27A91F0CE2AF9DA31552235F96CBBA56326' : true, + 'F82E01B697453BD37AD7012E267DC78395DF3DF4BFB0B1657F58256616F9B355' : true, + 'F8434B1782EC41F184305BD75BB3C0206721BC6CAD62442377072C06101B70DE' : true, + 'F88D1DF97289C9ED7E062D4E4B2B2463F90946DAC91785A6FA02F2599D7FE65C' : true, + 'F8E68F837C3E9452994FD6BF08F02D12D087BF6D44137BA37F72E408620F558B' : true, + 'F9971BA9EA322BB3FCB85111FED48B9CC1C9788D7BC6985E3CCE4BB7801B0DCC' : true, + 'FA14D235A95650A4CFD7A2A4DD80BAF2AF47581E01E412D640F93D6BB79D1C06' : true, + 'FADEBB24D23CEE1E8B02430C31A939E14821E9567A25367303F20F74879AB51C' : true, + 'FB674F1642EE443BBB827B29FD871CC110D77875884B1B050FC804D2884B2B3A' : true, + 'FB6814C66D6DDA2F348BF759398AB81F7795CA223F8AE9C0D82CA295162F68AD' : true, + 'FB7EF701469F77B6412100BB2D6399B1A574BB9610186FFFCC0119E14CB2021F' : true, + 'FBCC79E05CC135E183F4963C2A206F9DFDBC2DD0D379A743D5FB301741796921' : true, + 'FC2DA5A38AD07685CC019C7C388A396159FBAEF9EA491588FC995DBDF52A0B9C' : true, + 'FCF4BA663F0032118EADF9D327B65AB502C7A8B336462A397238884E9A28508E' : true, + 'FD4E54155D3117D78872DA05046A16FE944315F63C20BF0530F986F5F3797ECF' : true, + 'FD87C175594ABB82818D5CFEE506105069ECE5D5A499CFAD2E6376A88BAEB15D' : true, + 'FD8B1849A13BBD87D072F9D09506C90C0F29D7CCBD2B6446AD31335348AF9294' : true, + 'FDEE85771EF592A9E5F47D08250AFCBC73DCE96A72418B2848AE400F3CF59341' : true, + 'FE5DBE234A59B532A12BD552A36DB75AD21EF243C48C61849A0F93AF314C5896' : true, + 'FE739A748FB17DAFB6CBA0DA5B2164B8E0435E8DA7FB85E7970BBE731B428631' : true, + 'FE9E5DFD73260F732A5F7CE93B82DFA71D84F10D772A845221204A9685089FE7' : true, + 'FEB92F19B7394B8BF0FF71AEFD233E262AB656BDD531AD89FBEB9228C5378301' : true, + 'FEE5D5CF3F51FDBCD24D5D4E9BA06AFB96BFB558CB5D4249C70066749EEA8FBA' : true, + 'FEFEF80071B0D8E2B57D6601BB353A435A425EAA701827370C3585CE09F2CE50' : true, + 'FF769AAD90F56FB48D6C6CFCC86E38F9CBC6DB23774342892AFD4680ED3560FB' : true, +} ; diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/sha256.js b/data/extensions/https-everywhere@eff.org/chrome/content/code/sha256.js new file mode 100644 index 0000000..7e15f1a --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/sha256.js @@ -0,0 +1,249 @@ +/* + * A JavaScript implementation of the SHA256 hash function. + * + * FILE:sha256.js + * VERSION:0.8 + * AUTHOR:Christoph Bichlmeier <informatik@zombiearena.de> + * + * NOTE: This version is not tested thoroughly! + * + * Copyright (c) 2003, Christoph Bichlmeier + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * ====================================================================== + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* SHA256 logical functions */ +function rotateRight(n,x) { + return ((x >>> n) | (x << (32 - n))); +} +function choice(x,y,z) { + return ((x & y) ^ (~x & z)); +} +function majority(x,y,z) { + return ((x & y) ^ (x & z) ^ (y & z)); +} +function sha256_Sigma0(x) { + return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x)); +} +function sha256_Sigma1(x) { + return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x)); +} +function sha256_sigma0(x) { + return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3)); +} +function sha256_sigma1(x) { + return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10)); +} +function sha256_expand(W, j) { + return (W[j&0x0f] += sha256_sigma1(W[(j+14)&0x0f]) + W[(j+9)&0x0f] + + sha256_sigma0(W[(j+1)&0x0f])); +} + +/* Hash constant words K: */ +var K256 = new Array( + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + ); + +/* global arrays */ +var ihash, count, buffer; +var sha256_hex_digits = "0123456789abcdef"; + +/* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters: + overflow) */ +function safe_add(x, y) +{ + var lsw = (x & 0xffff) + (y & 0xffff); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); +} + +/* Initialise the SHA256 computation */ +function sha256_init() { + ihash = new Array(8); + count = new Array(2); + buffer = new Array(64); + count[0] = count[1] = 0; + ihash[0] = 0x6a09e667; + ihash[1] = 0xbb67ae85; + ihash[2] = 0x3c6ef372; + ihash[3] = 0xa54ff53a; + ihash[4] = 0x510e527f; + ihash[5] = 0x9b05688c; + ihash[6] = 0x1f83d9ab; + ihash[7] = 0x5be0cd19; +} + +/* Transform a 512-bit message block */ +function sha256_transform() { + var a, b, c, d, e, f, g, h, T1, T2; + var W = new Array(16); + + /* Initialize registers with the previous intermediate value */ + a = ihash[0]; + b = ihash[1]; + c = ihash[2]; + d = ihash[3]; + e = ihash[4]; + f = ihash[5]; + g = ihash[6]; + h = ihash[7]; + + /* make 32-bit words */ + for(var i=0; i<16; i++) + W[i] = ((buffer[(i<<2)+3]) | (buffer[(i<<2)+2] << 8) | (buffer[(i<<2)+1] + << 16) | (buffer[i<<2] << 24)); + + for(var j=0; j<64; j++) { + T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j]; + if(j < 16) T1 += W[j]; + else T1 += sha256_expand(W, j); + T2 = sha256_Sigma0(a) + majority(a, b, c); + h = g; + g = f; + f = e; + e = safe_add(d, T1); + d = c; + c = b; + b = a; + a = safe_add(T1, T2); + } + + /* Compute the current intermediate hash value */ + ihash[0] += a; + ihash[1] += b; + ihash[2] += c; + ihash[3] += d; + ihash[4] += e; + ihash[5] += f; + ihash[6] += g; + ihash[7] += h; +} + +/* Read the next chunk of data and update the SHA256 computation */ +function sha256_update(data, inputLen) { + var i, index, curpos = 0; + /* Compute number of bytes mod 64 */ + index = ((count[0] >> 3) & 0x3f); + var remainder = (inputLen & 0x3f); + + /* Update number of bits */ + if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++; + count[1] += (inputLen >> 29); + + /* Transform as many times as possible */ + for(i=0; i+63<inputLen; i+=64) { + for(var j=index; j<64; j++) + buffer[j] = data.charCodeAt(curpos++); + sha256_transform(); + index = 0; + } + + /* Buffer remaining input */ + for(var j=0; j<remainder; j++) + buffer[j] = data.charCodeAt(curpos++); +} + +/* Finish the computation by operations such as padding */ +function sha256_final() { + var index = ((count[0] >> 3) & 0x3f); + buffer[index++] = 0x80; + if(index <= 56) { + for(var i=index; i<56; i++) + buffer[i] = 0; + } else { + for(var i=index; i<64; i++) + buffer[i] = 0; + sha256_transform(); + for(var i=0; i<56; i++) + buffer[i] = 0; + } + buffer[56] = (count[1] >>> 24) & 0xff; + buffer[57] = (count[1] >>> 16) & 0xff; + buffer[58] = (count[1] >>> 8) & 0xff; + buffer[59] = count[1] & 0xff; + buffer[60] = (count[0] >>> 24) & 0xff; + buffer[61] = (count[0] >>> 16) & 0xff; + buffer[62] = (count[0] >>> 8) & 0xff; + buffer[63] = count[0] & 0xff; + sha256_transform(); +} + +/* Split the internal hash values into an array of bytes */ +function sha256_encode_bytes() { + var j=0; + var output = new Array(32); + for(var i=0; i<8; i++) { + output[j++] = ((ihash[i] >>> 24) & 0xff); + output[j++] = ((ihash[i] >>> 16) & 0xff); + output[j++] = ((ihash[i] >>> 8) & 0xff); + output[j++] = (ihash[i] & 0xff); + } + return output; +} + +/* Get the internal hash as a hex string */ +function sha256_encode_hex() { + var output = new String(); + for(var i=0; i<8; i++) { + for(var j=28; j>=0; j-=4) + output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f); + } + return output; +} + +/* Main function: returns a hex string representing the SHA256 value of the + given data */ +function sha256_digest(data) { + sha256_init(); + sha256_update(data, data.length); + sha256_final(); + return sha256_encode_hex(); +} + +/* test if the JS-interpreter is working properly */ +function sha256_self_test() +{ + return sha256_digest("message digest") == + "f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650"; +} + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/fetch-source.js b/data/extensions/https-everywhere@eff.org/chrome/content/fetch-source.js new file mode 100644 index 0000000..a0220c8 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/fetch-source.js @@ -0,0 +1,161 @@ +/* vim: set expandtab tabstop=2 shiftwidth=2 softtabstop=2 foldmethod=marker: */ + +/** + * HTTPS Everywhere Firefox Extension: https://www.eff.org/https-everywhere/ + * + * Licensed under the GPL v3+. + * + * @copyright Copyright (C) 2010-2013 Mike Perry <mikeperry@fscked.org> + * Peter Eckersley <pde@eff.org> + * and many others. + */ + +// Define https everywhere variable object that will act as a namespace, so that +// global namespace pollution is avoided, although technically not required for +// windows created by add-on. +// See: https://developer.mozilla.org/en-US/docs/Security_best_practices_in_extensions#Code_wrapping +if (!httpsEverywhere) { var httpsEverywhere = {}; } + +/** + * JS Object for fetching the XML source of rulesets. + * + * @author Pavel Kazakov <nullishzero@gmail.com> + */ +httpsEverywhere.fetchSource = { + // TODO: look into class constants + CC: Components.classes, + CI: Components.interfaces, + + // Constants for generating URL from which source will be fetched + BASE_SITE: 'https://gitweb.torproject.org/https-everywhere.git/blob_plain/', + DIRECTORY: '/src/chrome/content/rules/', + HEAD_STRING: 'HEAD', + + /** + * Initializes the window to view source. + */ + init: function() { + var fs = httpsEverywhere.fetchSource; + + if("arguments" in window && window.arguments.length > 0) { + var filename = window.arguments[0].xmlName; + var id = window.arguments[0].GITCommitID; //GIT commit ID + var URL = fs.getURL(filename, id); + var source = fs.getSource(URL, filename, false); + } else { + // Should never happen + throw 'Invalid window arguments.'; + } + }, + + /** + * Generates a URL that can be used for viewing the ruleset source. + * + * @param filename name of ruleset to view, such as EFF.xml + * @param GITCommitID revision of ruleset + * + * @return string of URL + */ + getURL: function(filename, GITCommitID) { + var fs = httpsEverywhere.fetchSource; + return fs.BASE_SITE + GITCommitID + ":" + fs.DIRECTORY + filename; + }, + + /** + * Sends HTTP request to view ruleset source and updates the window with the + * ruleset source. + * + * @param URL HTTP request will be sent to this URL + * @param filename used for displaying ruleset source + * @param useHead whether send request to latest revision of ruleset + */ + getSource: function(URL, filename, useHead) { + var fs = httpsEverywhere.fetchSource; + fs.setFilenameText(filename); + fs.setPathText(URL); + + var req = fs.CC["@mozilla.org/xmlextras/xmlhttprequest;1"] + .createInstance(fs.CI.nsIXMLHttpRequest); + + // Use HTTP GET + req.open("GET", URL); + + // Clear User-Agent so request is pseudo-anonymous + req.setRequestHeader("User-Agent", ""); + + // handle asynchronous request + req.onreadystatechange = function(params) { + if (req.readyState == 4) { + + // HTTP Request was successful + if (req.status == 200) { + fs.setSourceText(req.responseText); + } else if (!useHead) { + // HTTP request was not successful and the request wasn't sent to + // get the latest revision. Therefore, if we can't fetch current + // revision (this project's revision might newer than lastest, for + // example), try to at least display the latest revision. + var URL = fs.getURL(filename, fs.HEAD_STRING); + fs.getSource(URL, filename, true); + } else { + // at least we tried... + fs.downloadFailed(); + } + } + }; + + req.send(); + }, + + /** + * Handle a download failure of ruleset. + */ + downloadFailed: function() { + document.getElementById("source-text").hidden = true; + document.getElementById("failure-label").hidden = false; + }, + + + /** + * Convenience method for setting ruleset source text. + * + * @param text ruleset source + */ + setSourceText: function(text) { + var textBox = document.getElementById("source-text"); + textBox.value = text; + }, + + /** + * Convenience method for setting filename text. + * + * @param text file name + */ + setFilenameText: function (text) { + var textLabel = document.getElementById("filename-text"); + textLabel.value = text; + }, + + /** + * Convenience method for setting the path (URL) that was used to fetch + * ruleset. + * + * @param text path text + */ + setPathText: function(text) { + var textLabel = document.getElementById("path-text"); + textLabel.value = text; + } +}; + +// TODO: Test resizing on mulitple platforms +// adjust window resizing +window.onresize = function() { + var textBox = document.getElementById("source-text"); + // TODO: Move to constants + textBox.width = window.innerWidth - 100; + textBox.height = window.innerHeight - 150; +}; + +// hook event for init +window.addEventListener("load", httpsEverywhere.fetchSource.init, false); diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/fetch-source.xul b/data/extensions/https-everywhere@eff.org/chrome/content/fetch-source.xul new file mode 100644 index 0000000..caa0048 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/fetch-source.xul @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE overlay SYSTEM "chrome://https-everywhere/locale/https-everywhere.dtd"> + +<dialog id="https-everywhere-fetch-xml" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + title="&https-everywhere.prefs.view_xml_source;" + persist="screenX screenY width height" + style="height:80%; resize:both;" + buttons="accept" + height="600" + width="650"> + + + <script type="application/x-javascript" src="fetch-source.js"/> + <box orient="horizontal"> + <label id="filename-label" value="&https-everywhere.source.filename;:"/> + <label id="filename-text"/> + </box> + <box orient="horizontal"> + <label id="path-label" value="URL:"/> + <label id="path-text"/> + </box> + <separator class="thin"/> + <textbox id="source-text" multiline="true" readonly="true" value="&https-everywhere.source.downloading;..."/> + <label id="failure-label" hidden="true" value="&https-everywhere.source.unable_to_download;"/> +</dialog> diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/meta-preferences.xul b/data/extensions/https-everywhere@eff.org/chrome/content/meta-preferences.xul new file mode 100644 index 0000000..3e48010 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/meta-preferences.xul @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="chrome://https-everywhere/content/preferences.css" type="text/css"?> + +<!DOCTYPE overlay SYSTEM "chrome://https-everywhere/locale/https-everywhere.dtd"> + +<window id="https-everywhere-meta-prefs" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + title="&https-everywhere.prefs.title;" + persist="screenX screenY width height" + width="600" + height="600"> + <separator class="thin" /> + <tabbox flex="1"> + <tabs> + <tab label="HTTPS Everywhere" /> + <tab label="SSL Observatory" /> + </tabs> + <tabpanels flex="1"> + <tabpanel flex="1" orient="vertical"> + <browser src="chrome://https-everywhere/content/preferences.xul" flex="1"/> + </tabpanel> + <tabpanel flex="1" orient="vertical"> + <browser src="chrome://https-everywhere/content/observatory-preferences.xul" flex="1"/> + </tabpanel> + </tabpanels> + </tabbox> + +</window> diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/observatory-popup.xul b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-popup.xul new file mode 100644 index 0000000..60da68f --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-popup.xul @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="utf-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<!DOCTYPE window SYSTEM "chrome://https-everywhere/locale/ssl-observatory.dtd"> +<window id="ssl-observatory-dialog" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + title="&ssl-observatory.popup.title;" + width="500" + height="440" + align="center" + onload="document.getElementById('ask-me-later').focus()" + > + <script type="application/x-javascript" src="observatory-xul.js" /> + <image src="chrome://https-everywhere/skin/ssl-observatory-messy.jpg" /> + <label style="padding:25px;">&ssl-observatory.popup.text;</label> + + <commandgroup> + <command id="enable" oncommand="enable_observatory() ; popup_done()" /> + <command id="nope" oncommand="disable_observatory() ; popup_done()" /> + <command id="later" oncommand="window.close()" /> + <command id="more-info" + oncommand='popup_done() ; + window.open("chrome://https-everywhere/content/observatory-preferences.xul","obsprefs", + "chrome, centerscreen")'/> + </commandgroup> + + <vbox flex="1"> + <spacer flex="5" /> + <separator class="thin"/> + <hbox> + <spacer flex="2" /> + <button label="&ssl-observatory.popup.yes;" tabindex="2" accesskey="y" + command='enable'/> + <spacer flex="1" /> + <button label="&ssl-observatory.popup.no;" tabindex="3" accesskey="n" + command='nope'/> + <spacer flex="2" /> + </hbox> + <separator class="thin"/> + <spacer flex="10" /> + <hbox> + <spacer flex="2" /> + <button label="&ssl-observatory.popup.details;" tabindex="4" accesskey="D" + command='more-info'/> + <spacer flex="1" /> + <button id="ask-me-later" label="&ssl-observatory.popup.later;" + tabindex="1" accesskey="A" command='later'/> + <spacer flex="2" /> + </hbox> + <separator class="thin"/> + <spacer flex="1" /> + </vbox> + + <!-- + <hbox style="padding-top:10px;"> + <label class="text-link" href="https://www.eff.org/" tabindex="3" value="&ssl-observatory.popup.details;" /> + <spacer flex="1" /> + <button label="&ssl-observatory.popup.later;" id="ask-me-later" tabindex="0" style="font-size:0.8em;" accesskey="l" + oncommand="doCancel()"/>- + </hbox>--> +</window> diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/observatory-preferences.xul b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-preferences.xul new file mode 100644 index 0000000..96102d0 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-preferences.xul @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> + +<!DOCTYPE overlay SYSTEM "chrome://https-everywhere/locale/ssl-observatory.dtd"> + +<dialog id="https-everywhere-prefs" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + buttons="accept" + buttonlabelaccept="&ssl-observatory.prefs.done;" + title="&ssl-observatory.prefs.title;" + width="800" + height="768" + persist="screenX screenY width height" + onload="observatory_prefs_init(document)" + ondialogaccept="observatory_prefs_accept()"> + <script type="application/x-javascript" src="observatory-xul.js" /> + <vbox flex="1" style="overflow:auto"> + <spacer flex="1" /> + <hbox flex="1"> + <spacer flex="1" /> + <image id="obs-title-logo" + src="chrome://https-everywhere/skin/ssl-observatory-messy.jpg" /> + <spacer flex="1" /> + </hbox> + <spacer flex="2" /> + <label>&ssl-observatory.prefs.explanation;</label> + <separator class="thin" /> + <label>&ssl-observatory.prefs.explanation2;</label> + <separator class="thin" /> + <commandset> + <command id="toggle-enabled" oncommand="toggle_enabled()" /> + <command id="use-obs-anon" oncommand="set_obs_anon(true)" /> + <command id="use-obs-nonanon" oncommand="set_obs_anon(false)" /> + <command id="toggle-alt-roots" oncommand="toggle_alt_roots()" /> + <command id="toggle-send-asn" oncommand="toggle_send_asn()" /> + <command id="toggle-priv-dns" oncommand="toggle_priv_dns()" /> + <command id="toggle-self-signed" oncommand="toggle_self_signed()" /> + </commandset> + <checkbox label="&ssl-observatory.prefs.use;" id="use-observatory" + command="toggle-enabled" style="font-size:1.5em;"/> + <separator class="thin"/> + <radiogroup style="margin-left:3em;" id="ssl-obs-how"> + <radio label="&ssl-observatory.prefs.anonymous;" + tooltiptext="&ssl-observatory.prefs.anonymous_tooltip;" + alt_label="&ssl-observatory.prefs.anonymous_unavailable;" + command="use-obs-anon" + class="ssl-obs-conf" id="ssl-obs-anon"/> + <radio label="&ssl-observatory.prefs.nonanon;" + tooltiptext="&ssl-observatory.prefs.nonanon_tooltip;" + command="use-obs-nonanon" + class="ssl-obs-conf" id="ssl-obs-nonanon"/> + </radiogroup> + <separator class="thin"/> + <tooltip id="asn-tip" noautohide="true"> + <label>&ssl-observatory.prefs.asn_tooltip;</label> + </tooltip> + <checkbox label="&ssl-observatory.prefs.asn;" id="send-asn" + tooltip="asn-tip" class="ssl-obs-conf" + command="toggle-send-asn"/> + <spacer flex="2" /> + <hbox> + <spacer flex="1" /> + <button label="&ssl-observatory.prefs.show;" onclick="show_advanced()" + id="show-advanced-button" class="ssl-obs-conf"/> + <button label="&ssl-observatory.prefs.hide;" onclick="hide_advanced()" + id="hide-advanced-button" hidden="true" /> + <spacer flex="1" /> + </hbox> + <spacer flex="1" /> + <vbox flex="2"> + <tooltip id="alt-roots-tip" noautohide="true"> + <label>&ssl-observatory.prefs.alt_roots_tooltip;</label> + </tooltip> + <tooltip id="priv-dns-tip" noautohide="true"> + <label>&ssl-observatory.prefs.priv_dns_tooltip;</label> + </tooltip> + <tooltip id="self-signed-tip" noautohide="true"> + <label>&ssl-observatory.prefs.self_signed_tooltip;</label> + </tooltip> + <vbox id="observatory-advanced-opts" hidden="true"> + + <groupbox hidden="true" tooltip="self-signed-tip"> + <checkbox label="&ssl-observatory.prefs.self_signed;" + class="ssl-obs-conf" id="self-signed" + command="toggle-self-signed"/> + </groupbox> + + <groupbox hidden="true" tooltip="alt-roots-tip" > + <caption hidden="true" label="&ssl-observatory.prefs.adv_priv_opts1;"/> + <checkbox label="&ssl-observatory.prefs.alt_roots;" + command="toggle-alt-roots" class="ssl-obs-conf" + id="alt-roots" /> + </groupbox> + <groupbox hidden="true" tooltip="priv-dns-tip"> + <caption hidden="true" label="&ssl-observatory.prefs.adv_priv_opts2;"/> + <checkbox label="&ssl-observatory.prefs.priv_dns;" + class="ssl-obs-conf" id="priv-dns" + command="toggle-priv-dns"/> + </groupbox> + </vbox> + </vbox> + <spacer flex="5" /> + </vbox> +</dialog> + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/observatory-warning.xul b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-warning.xul new file mode 100644 index 0000000..1f64e12 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-warning.xul @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<!DOCTYPE window SYSTEM "chrome://https-everywhere/locale/ssl-observatory.dtd"> +<window id="ssl-observatory-dialog" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + title="&ssl-observatory.warning.title;" + width="600" + height="500" + align="center" + onload="warning_populate(window.arguments[0])" + > + <script type="application/x-javascript" src="observatory-xul.js" /> + <image src="chrome://https-everywhere/skin/ssl-observatory-messy.jpg" /> + <vbox flex="1"> + <vbox id="warning-container" flex="1"> + <label style="padding:25px 25px 10px;">&ssl-observatory.warning.text;</label> + <spacer flex="1" /> + </vbox> + + <commandgroup> + <command id="showcert" oncommand="show_certs()" /> + <command id="okay" oncommand='window.close()' + /> + </commandgroup> + + <spacer flex="1" /> + <label style="padding:5px 25px 0px;">&ssl-observatory.warning.defense;</label> + <separator class="thin"/> + <hbox> + <spacer flex="2" /> + <button label="&ssl-observatory.warning.showcert;" accesskey="S" + id="show-certificate" command='showcert'/> + <spacer flex="1" /> + <button label="&ssl-observatory.warning.okay;" accesskey="I" + command='okay'/> + <spacer flex="2" /> + </hbox> + <separator class="thin" /> + </vbox> + + <!-- + <hbox style="padding-top:10px;"> + <label class="text-link" href="https://www.eff.org/" tabindex="3" value="&ssl-observatory.popup.details;" /> + <spacer flex="1" /> + <button label="&ssl-observatory.popup.later;" id="ask-me-later" tabindex="0" style="font-size:0.8em;" accesskey="l" + oncommand="doCancel()"/>- + </hbox>--> +</window> diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/observatory-xul.js b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-xul.js new file mode 100644 index 0000000..df5e623 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/observatory-xul.js @@ -0,0 +1,194 @@ +const CC = Components.classes; +const CI = Components.interfaces; +VERB=1; +DBUG=2; +INFO=3; +NOTE=4; +WARN=5; + +var ssl_observatory = CC["@eff.org/ssl-observatory;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; +var obsprefs = ssl_observatory.prefs; + +const pref_prefix = "extensions.ssl_observatory."; + +function observatory_prefs_init(doc) { + // Is the Observatory on? + var enabled = obsprefs.getBoolPref("extensions.https_everywhere._observatory.enabled"); + document.getElementById("use-observatory").checked = enabled; + set_observatory_configurability(enabled); + // Other settings + document.getElementById("alt-roots").checked = + obsprefs.getBoolPref("extensions.https_everywhere._observatory.alt_roots"); + document.getElementById("priv-dns").checked = + obsprefs.getBoolPref("extensions.https_everywhere._observatory.priv_dns"); + document.getElementById("self-signed").checked = + obsprefs.getBoolPref("extensions.https_everywhere._observatory.self_signed"); + document.getElementById("send-asn").checked = + obsprefs.getBoolPref("extensions.https_everywhere._observatory.send_asn"); + + // More complicated: is it anonymised by Tor? + var obs_how = doc.getElementById("ssl-obs-how"); + var anon_radio = document.getElementById("ssl-obs-anon"); + var nonanon_radio = document.getElementById("ssl-obs-nonanon"); + var anon = !obsprefs.getBoolPref( + "extensions.https_everywhere._observatory.use_custom_proxy"); + + // first set the radios to match the current settings variables + obs_how.selectedItem = (anon) ? anon_radio : nonanon_radio; + + // But if the user hasn't turned the observatory on, + // the default should be the maximally sensible one + var torbutton_avail = ssl_observatory.proxy_test_successful; + if (!enabled) { + set_obs_anon(torbutton_avail); + obs_how.selectedItem = (torbutton_avail) ? anon_radio : nonanon_radio; + } + //scale_title_logo(); +} + +// The user has responded to the popup in a final way; don't show it to them +// again +function popup_done() { + obsprefs.setBoolPref("extensions.https_everywhere._observatory.popup_shown", true); + obsprefs.setBoolPref("extensions.https_everywhere._observatory.clean_config", true); + window.close(); +} + + +function scale_title_logo() { + // The image is naturally 500x207, but if it's shrunk we don't want it + // distorted + var img = document.getElementById("obs-title-logo"); + alert("ch is " + img.height); + if (img.height != "207") + img.width = (500.0/207.0) * img.height; +} + +// grey/ungrey UI elements that control observatory operation +function set_observatory_configurability(enabled) { + // the relevant widgets are tagged with class="ssl-obs-conf" + var ui_elements = document.querySelectorAll(".ssl-obs-conf"); + for (var i =0; i < ui_elements.length; i++) + ui_elements[i].disabled = !enabled; + // the "use tor" option can't be ungreyed unless tor is available + if (ssl_observatory.proxy_test_successful == false) { + var tor_opt = document.getElementById("ssl-obs-anon") + tor_opt.disabled = true; + tor_opt.label = tor_opt.getAttribute("alt_label"); + } + if (!enabled) + hide_advanced(); +} + +// show/hide advanced options in the preferences dialog +function show_advanced() { + var enabled = obsprefs.getBoolPref("extensions.https_everywhere._observatory.enabled"); + if (enabled) { + var adv_opts_box = document.getElementById("observatory-advanced-opts"); + recursive_set(adv_opts_box, "hidden", "false"); + document.getElementById("show-advanced-button").hidden = true; + document.getElementById("hide-advanced-button").hidden = false; + } + //scale_title_logo(); +} +function hide_advanced() { + var adv_opts_box = document.getElementById("observatory-advanced-opts"); + recursive_set(adv_opts_box, "hidden", "true"); + document.getElementById("show-advanced-button").hidden = false; + document.getElementById("hide-advanced-button").hidden = true; +} + +function recursive_set(node, attrib, value) { + node.setAttribute(attrib, value); + for (var i=0; i < node.childNodes.length; i++) + recursive_set(node.childNodes[i], attrib, value) +} + + +function set_obs_anon(val) { + obsprefs.setBoolPref( "extensions.https_everywhere._observatory.use_custom_proxy", !val); +} + +// called from the popup only +function enable_observatory() { + obsprefs.setBoolPref("extensions.https_everywhere._observatory.enabled", true); + var torbutton_avail = ssl_observatory.proxy_test_successful; + set_obs_anon(torbutton_avail); +} + +function disable_observatory() { + // default but be sure... + obsprefs.setBoolPref("extensions.https_everywhere._observatory.enabled", false); +} + +// called from within the prefs window, we have more work to do: +function toggle_enabled() { + var use_obs = document.getElementById("use-observatory").checked; + obsprefs.setBoolPref("extensions.https_everywhere._observatory.enabled", use_obs); + set_observatory_configurability(use_obs); +} + +function toggle_send_asn() { + var send_asn = document.getElementById("send-asn").checked; + obsprefs.setBoolPref("extensions.https_everywhere._observatory.send_asn", send_asn); + if (send_asn) ssl_observatory.setupASNWatcher() + else ssl_observatory.stopASNWatcher(); +} + +function toggle_alt_roots() { + var alt_roots = document.getElementById("alt-roots").checked; + obsprefs.setBoolPref("extensions.https_everywhere._observatory.alt_roots", alt_roots); +} + +function toggle_priv_dns() { + var priv_dns = document.getElementById("priv-dns").checked; + obsprefs.setBoolPref("extensions.https_everywhere._observatory.priv_dns", priv_dns); +} + +function toggle_self_signed() { + var self_signed = document.getElementById("self-signed").checked; + obsprefs.setBoolPref("extensions.https_everywhere._observatory.self_signed", self_signed); +} + +function observatory_prefs_accept() { + // This is *horrid*, but + // https://developer.mozilla.org/en/working_with_windows_in_chrome_code#Accessing_the_elements_of_the_top-level_document_from_a_child_window + var outer = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIWebNavigation) + .QueryInterface(Components.interfaces.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindow); + + if (outer) outer.close() + else alert("no outer space"); + + return true; // https://developer.mozilla.org/en/XUL/dialog#a-ondialogaccept + // also close things if there is no out meta prefs window +} + +function warning_populate(warningObj) { + // Fill in the SSL Observatory Warning labels... + var container = document.getElementById("warning-container"); + for (var hash in warningObj) { + var label=document.createElement("label"); + label.setAttribute("style","padding:5px 25px 5px;"); + label.textContent = warningObj[hash].long_desc; + container.appendChild(label); + //var spacer=document.createElement("spacer"); + //separator.setAttribute("flex","1"); + //container.appendChild(spacer); + } +} + +function show_certs() { + var parent_win = window.arguments[1]; + var cert = window.arguments[2]; + if (!parent_win) + alert("no parent window trying to show certs"); + CC["@mozilla.org/nsCertificateDialogs;1"] + .getService(CI.nsICertificateDialogs) + .viewCert(parent_win, cert); +} diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/preferences.css b/data/extensions/https-everywhere@eff.org/chrome/content/preferences.css new file mode 100644 index 0000000..6b35c00 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/preferences.css @@ -0,0 +1,11 @@ +treechildren::-moz-tree-checkbox { /* css for unchecked cells */ + list-style-image: url("chrome://https-everywhere/skin/cross.png"); +} + +treechildren::-moz-tree-checkbox(checked) { /* css for checked cells */ + list-style-image: url("chrome://https-everywhere/skin/tick.png"); +} + +treechildren::-moz-tree-checkbox(undefined) { /* css for empty cells */ + list-style-image: url(""); +} diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/preferences.js b/data/extensions/https-everywhere@eff.org/chrome/content/preferences.js new file mode 100644 index 0000000..557b335 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/preferences.js @@ -0,0 +1,269 @@ +const CC = Components.classes; +const CI = Components.interfaces; +VERB=1; +DBUG=2; +INFO=3; +NOTE=4; +WARN=5; + +https_everywhere = CC["@eff.org/https-everywhere;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; + +rulesets = []; + +const id_prefix = "he_enable"; +const pref_prefix = "extensions.https_everywhere."; +const GITID = https_everywhere.https_rules.GITCommitID; + +// Disable all rules. +function disable_all() { + for (var i in rulesets) { + rulesets[i].disable(); + } + + treeView.treebox.invalidate(); +} + +// Reset all rules to their default state. +function reset_defaults() { + https_everywhere.https_rules.resetRulesetsToDefaults() + treeView.treebox.invalidate(); +} + +function resetSelected() { + var start = {}; + var end = {}; + var st = document.getElementById('sites_tree'); + var sel = st.view.selection; + var numRanges = sel.getRangeCount(); + + for (var t = 0; t < numRanges; t++){ + sel.getRangeAt(t, start, end); + for (var v = start.value; v <= end.value; v++){ + var rs = treeView.rules[v]; + rs.clear(); + } + } +} + +function resetSelectedMenu() { + var start = {}; + var end = {}; + var st = document.getElementById('sites_tree'); + var sel = st.view.selection; + var numRanges = sel.getRangeCount(); + var menuitem = document.getElementById("revert_menuitem"); + + for (var t = 0; t < numRanges; t++){ + sel.getRangeAt(t, start, end); + for (var v = start.value; v <= end.value; v++){ + var rs = treeView.rules[v]; + if (rs.active !== rs.on_by_default) { + menuitem.disabled = false; + return; + } + } + } + menuitem.disabled = true; +} + +function toggleSelected() { + var start = {}; + var end = {}; + var st = document.getElementById('sites_tree'); + var sel = st.view.selection; + var numRanges = sel.getRangeCount(); + var menuitem = document.getElementById("revert_menuitem"); + + for (var t = 0; t < numRanges; t++){ + sel.getRangeAt(t, start, end); + for (var v = start.value; v <= end.value; v++){ + var rs = treeView.rules[v]; + rs.toggle(); + treeView.treebox.invalidateRow(v); + } + } +} + + +function viewXMLSource() { + var start = {}; + var end = {}; + var st = document.getElementById('sites_tree'); + var sel = st.view.selection; + var numRanges = sel.getRangeCount(); + var menuitem = document.getElementById("revert_menuitem"); + + for (var t = 0; t < numRanges; t++){ + sel.getRangeAt(t, start, end); + for (var v = start.value; v <= end.value; v++){ + var rs = treeView.rules[v]; + + //This *should* not violate TorButton's State Control, but someone should double check + //this code just in case + var aWin = CC['@mozilla.org/appshell/window-mediator;1'] + .getService(CI.nsIWindowMediator) + .getMostRecentWindow('navigator:browser'); + aWin.openDialog("chrome://https-everywhere/content/fetch-source.xul", + rs.xmlName, "chrome,centerscreen", + {xmlName: rs.xmlName, GITCommitID: GITID} ); + } + } +} + +function getValue(row, col) { + switch (col.id) { + case "site_col": + return row.name; + case "note_col": + return row.notes; + case "enabled_col": + return https_everywhere.https_rules.rulesetsByName[row.name].active; + /*var ruleActive = false; + try { + if(https_everywhere.rule_toggle_prefs.getBoolPref(row.name)) + ruleActive = true; + } catch(e) { + ruleActive = https_everywhere.https_rules.rulesetsByName[row.name].active; + } + return ruleActive;*/ + default: + return; + } +} + +function compareRules(a, b, col) { + var aval = getValue(a, col).toLowerCase(); + var bval = getValue(b, col).toLowerCase(); + var ret = 0; + if (aval < bval) { + ret = -1; + } else if (aval > bval) { + ret = 1; + } else { + ret = 0; + } + return ret; +} + +function https_prefs_init(doc) { + var st = document.getElementById('sites_tree'); + https_everywhere.https_rules.loadAllRulesets(); + rulesets = Array.slice(https_everywhere.https_rules.rulesets); + + // GLOBAL VARIABLE! + treeView = { + rules: rulesets, + rowCount: rulesets.length, + getCellValue: function(row, col) { // site names + if (!this.rules[row]) return; + return getValue(this.rules[row], col); + }, + getCellText: function(row, col) { // activation indicator + return this.getCellValue(row, col); + }, + setCellValue: function(row, col, val) { // toggle a rule's activation + var rule = this.rules[row]; + + if (val == "true") { + rule.enable(); + } else { + rule.disable(); + } + + this.treebox.invalidateRow(row); + }, + isEditable: function(row, col) { + return (col.id == "enabled_col"); + }, + setTree: function(treebox) { + this.treebox = treebox; + }, + isContainer: function(row) { return false; }, + isSeparator: function(row) { return false; }, + isSorted: function() { return false; }, + getRowProperties: function(row, props) {}, + getColumnProperties: function(colid, col, props) {}, + getCellProperties: function(row, col, props) { + if ( (col.id == "enabled_col") && !(this.rules[row]) ) { + var atomS = CC["@mozilla.org/atom-service;1"]; + atomS = atomS.getService(CI.nsIAtomService); + // Starting with 22.0a1 there is no |props| available anymore. See: + // https://bugzilla.mozilla.org/show_bug.cgi?id=407956. Looking at the + // patch the following seems to work, though. + if (!props) { + return "undefined"; + } + props.AppendElement( atomS.getAtom("undefined") ); + } + }, + getLevel: function(row) { return 0; }, + getImageSrc: function(row, col) { return null; }, + search: function(query) { + var new_rules = []; + query = query.value.toLowerCase().replace(/^\s+|\s+$/g, ""); + + for (var i in rulesets) { + var rule_name = rulesets[i].name.toLowerCase(); + if ( rule_name.indexOf(query) != -1 ) { + new_rules.push(rulesets[i]); + } + } + + this.rules = new_rules; + this.rowCount = new_rules.length; + this.treebox.invalidate(); + this.treebox.scrollToRow(rulesets[0]); + }, + cycleHeader: function (col) { + var columnName; + var order = (col.element.getAttribute("sortDirection") === "ascending" ? -1 : 1); + + var compare = function (a, b) { + return compareRules(a, b, col) * order; + }; + rulesets.sort(compare); + this.rules.sort(compare); + + var cols = st.getElementsByTagName("treecol"); + for (var i = 0; i < cols.length; i++) { + cols[i].removeAttribute("sortDirection"); + } + col.element.setAttribute("sortDirection", order === 1 ? "ascending" : "descending"); + this.treebox.invalidate(); + } + }; + + st.view = treeView; +} + +function window_opener(uri) { + // we don't use window.open, because we need to work around TorButton's state control + if(typeof gBrowser == "undefined"){ + var window = CC["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator); + var browserWindow = window.getMostRecentWindow("navigator:browser").getBrowser(); + var newTab = browserWindow.addTab(uri, null, null); + browserWindow.selectedTab = newTab; + + } + else + gBrowser.selectedTab = gBrowser.addTab(uri); +} + +function https_prefs_accept() { + // This is *horrid*, but + // https://developer.mozilla.org/en/working_with_windows_in_chrome_code#Accessing_the_elements_of_the_top-level_document_from_a_child_window + var outer = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIWebNavigation) + .QueryInterface(Components.interfaces.nsIDocShellTreeItem) + .rootTreeItem + .QueryInterface(Components.interfaces.nsIInterfaceRequestor) + .getInterface(Components.interfaces.nsIDOMWindow); + + if (outer) outer.close(); + else alert("no outer space"); + + return true; // https://developer.mozilla.org/en/XUL/dialog#a-ondialogaccept + // also close things if there is no out meta prefs window +} diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/preferences.xul b/data/extensions/https-everywhere@eff.org/chrome/content/preferences.xul new file mode 100644 index 0000000..ebde85b --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/preferences.xul @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="chrome://https-everywhere/content/preferences.css" type="text/css"?> + +<!DOCTYPE overlay SYSTEM "chrome://https-everywhere/locale/https-everywhere.dtd"> + +<dialog id="https-everywhere-prefs" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + buttons="accept,extra1,extra2" + buttonlabelextra1="&https-everywhere.prefs.disable_all;" + ondialogextra1="disable_all();" + buttonlabelextra2="&https-everywhere.prefs.reset_defaults;" + ondialogextra2="reset_defaults();" + title="&https-everywhere.prefs.title;" + persist="screenX screenY width height" + style="height:80%; resize:both;" + height="600" + width="650" + onload="https_prefs_init(document)" + ondialogaccept="https_prefs_accept()"> + + <script type="application/x-javascript" src="preferences.js"/> + + <popupset> + <menupopup id="tree-contextmenu" onpopupshowing="resetSelectedMenu()"> + <menuitem label="&https-everywhere.prefs.reset_default;" oncommand="resetSelected();" id="revert_menuitem"/> + <menuitem label="&https-everywhere.prefs.toggle;" oncommand="toggleSelected();"/> + <menuitem label="&https-everywhere.prefs.view_xml_source;" oncommand="viewXMLSource();"/> + </menupopup> + </popupset> + + <groupbox flex="1"> + <caption label="&https-everywhere.prefs.list_caption;" + align="center"/> + <vbox> + &https-everywhere.prefs.search;: <textbox id="tree_search" oninput="treeView.search(this);" /> + </vbox> + <tree id="sites_tree" editable="true" flex="1" context="tree-contextmenu"> + <treecols> + <treecol id="enabled_col" type="checkbox" label="&https-everywhere.prefs.enabled;" + editable="true" class="sortDirectionIndicator" persist="sortDirection width"/> + <splitter class="tree-splitter"/> + <treecol id="site_col" label="&https-everywhere.prefs.site;" flex="1" editable="false" class="sortDirectionIndicator" persist="sortDirection width"/> + <splitter class="tree-splitter"/> + <treecol id="note_col" label="&https-everywhere.prefs.notes;" flex="1" editable="false" class="sortDirectionIndicator" persist="sortDirection width"/> + </treecols> + <treechildren/> + </tree> + </groupbox> + <separator class="thin"/> + <vbox> + &https-everywhere.prefs.ruleset_howto; + <separator class="thin"/> + <label id="ruleset link" + value="&https-everywhere.prefs.here_link;" + style="color: blue; cursor:hand; text-decoration:underline;" + onmouseover="event.target.style.cursor='pointer'" + onmouseout="event.target.style.cursor='default'" + onclick="window_opener('https://eff.org/https-everywhere/rulesets')"/>. + </vbox> +</dialog> diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/rules/00README b/data/extensions/https-everywhere@eff.org/chrome/content/rules/00README new file mode 100644 index 0000000..fcd8a77 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/rules/00README @@ -0,0 +1,17 @@ +<!-- +This directory contains web site rewriting rules for the +HTTPS Everywhere software, available from +https://www.eff.org/https-everywhere + +These rules were contributed to the project by users and aim to +enable routine secure access to as many different web sites as +possible. They are automatically installed together with the +HTTPS Everywhere software. The presence of these rules does not +mean that an HTTPS Everywhere user accessed, or intended to +access, any particular web site. + +For information about how to create additional HTTPS Everywhere +rewriting rules to add support for new sites, please see + +https://www.eff.org/https-everywhere/rulesets +--> diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.css b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.css new file mode 100644 index 0000000..30dad18 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.css @@ -0,0 +1,14 @@ +#ruleset-tests-status { + padding: 20px; +} +#wrapper { + text-align: center; +} +#progess-bar { + width: 300px; + height: 20px; +} +#log { + width: 400px; + height: 300px; +} diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.js b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.js new file mode 100644 index 0000000..0bee33e --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.js @@ -0,0 +1,31 @@ +var HTTPSEverywhere = null; + +function updateStatusBar(current_test, total_tests) { + var labelText = "Test "+current_test+" of "+total_tests; + document.getElementById("progress-bar-label").value = labelText; + + var percent = current_test / total_tests; + document.getElementById("progress-bar").value = percent; +} + +function updateLog(msg) { + document.getElementById("log").value += msg+'\n'; +} + +function cancel() { + updateLog("Canceling early ..."); + HTTPSEverywhere.httpseRulesetTests.cancel = true; +} + +function start() { + HTTPSEverywhere = Components.classes["@eff.org/https-everywhere;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; + + HTTPSEverywhere.httpseRulesetTests.updateStatusBar = updateStatusBar; + HTTPSEverywhere.httpseRulesetTests.updateLog = updateLog; + HTTPSEverywhere.httpseRulesetTests.cancel = false; + + updateLog("Starting ruleset tests ..."); + HTTPSEverywhere.httpseRulesetTests.testRunner(); +} diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.xul b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.xul new file mode 100644 index 0000000..0efcd5d --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests-status.xul @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="ruleset-tests-status.css" type="text/css"?> +<!DOCTYPE window SYSTEM "chrome://https-everywhere/locale/https-everywhere.dtd"> +<window id="ruleset-tests-status" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns:html="http://www.w3.org/1999/xhtml" + title="&https-everywhere.ruleset-tests.status_title;" + > + + <script type="application/x-javascript" src="ruleset-tests-status.js" /> + + <commandgroup> + <command id="cancel" oncommand="cancel();" /> + <command id="start" oncommand="start();" /> + </commandgroup> + + <html:div id="wrapper"> + <vbox flex="1" style="width:100%"> + <label id="progress-bar-label" value="Click Start to start the tests"></label> + + <spacer flex="1"/> + + <progressmeter id="progress-bar" mode="determined" value="0" /> + + <spacer flex="1"/> + + <textbox id="log" multiline="true" readonly="true" value="" /> + + <spacer flex="1"/> + + <button + id="cancel-button" + label="&https-everywhere.ruleset-tests.status_cancel_button;" + command="cancel" /> + + <button + id="start-button" + label="&https-everywhere.ruleset-tests.status_start_button;" + command="start" /> + </vbox> + </html:div> +</window> + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests.js b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests.js new file mode 100644 index 0000000..1aa94d8 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/ruleset-tests.js @@ -0,0 +1,155 @@ +// load the HTTPS Everywhere component +var HTTPSEverywhere = null; +try { + HTTPSEverywhere = Components.classes["@eff.org/https-everywhere;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; +} catch(e) { + // HTTPS Everywhere doesn't seem to be installed +} + +// attach testRunner to the HTTPS Everywhere component so that status.js can run it +if(HTTPSEverywhere) { + HTTPSEverywhere.httpseRulesetTests = { + testRunner: testRunner + }; +} + + +function openStatus() { + // make sure mixed content blocking preferences are correct + Services.prefs.setBoolPref("security.mixed_content.block_display_content", false); + Services.prefs.setBoolPref("security.mixed_content.block_active_content", true); + + // open the status tab + var statusTab = gBrowser.addTab('chrome://https-everywhere/content/ruleset-tests-status.xul'); + gBrowser.selectedTab = statusTab; +} + +function testRunner() { + Components.utils.import("resource://gre/modules/PopupNotifications.jsm"); + + const numTabs = 6; + var finished = false; + var output = []; + var urls = []; + var num = 0; + + for(var target in HTTPSEverywhere.https_rules.targets) { + if(!target.indexOf("*") != -1) { + urls.push({ + url: 'https://'+target, + target: target, + ruleset_names: HTTPSEverywhere.https_rules.targets[target] + }); + } + } + + function test() { + var i; + + HTTPSEverywhere.httpseRulesetTests.updateStatusBar(num, urls.length); + + // start loading all the tabs + window.focus + for(i=0; i<numTabs; i++) { + newTab(num); + } + } + + function newTab(number) { + num +=1; + // start a test in this tab + if(urls.length) { + + // open a new tab + var tab = gBrowser.addTab(urls[number].url); + + // wait for the page to load + var intervalId = window.setTimeout(function(){ + + // detect mixed content blocker + if(PopupNotifications.getNotification("mixed-content-blocked", gBrowser.getBrowserForTab(tab))) { + // build output to log + ruleset_xmls = ''; + for(let i=0; i<urls[number].ruleset_names.length; i++) { + ruleset_xmls += urls[number].ruleset_names[i].xmlName + ', '; + } + if(ruleset_xmls != '') + ruleset_xmls = ruleset_xmls.substring(ruleset_xmls.length-2, 2); + var output = 'MCB triggered: '+urls[number].url+' ('+ruleset_xmls+')'; + + HTTPSEverywhere.httpseRulesetTests.updateLog(output); + } + + // close this tab, and open another + closeTab(tab); + + }, 10000); + + } else { + + //to run if urls is empty + if (!finished) { + finished = true; + window.setTimeout(function(){ + gBrowser.removeCurrentTab(); + }, 10000); + } + } + } + + //closes tab + function closeTab(tab) { + HTTPSEverywhere.httpseRulesetTests.updateStatusBar(num, urls.length); + + gBrowser.selectedTab = tab; + gBrowser.removeCurrentTab(); + + // open a new tab, if the tests haven't been canceled + if(!HTTPSEverywhere.httpseRulesetTests.cancel) { + newTab(num); + } + } + + //manages write out of output mochilog.txt, which contains sites that trigger mcb + function writeout(weburl) { + + //initialize file + var file = Components.classes["@mozilla.org/file/directory_service;1"]. + getService(Components.interfaces.nsIProperties). + get("Home", Components.interfaces.nsIFile); + writeoutfile = "mochilog.txt"; + file.append(writeoutfile); + + //create file if it does not already exist + if(!file.exists()) { + file.create(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420); + } + + //initialize output stream + var stream = Components.classes["@mozilla.org/network/file-output-stream;1"] + .createInstance(Components.interfaces.nsIFileOutputStream); + + //permissions are set to append (will not delete existing contents) + stream.init(file, 0x02 | 0x08 | 0x10, 0666, 0); + + var content = weburl + "\n"; + + //Deal with ascii text and write out + var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"]. + createInstance(Components.interfaces.nsIConverterOutputStream); + converter.init(stream, "UTF-8", 0, 0); + converter.writeString(content); + converter.close(); + + //alternative write out if ascii is not a concern + //stream.write(content,content.length); + //stream.close(); + + } + test(); +} + + + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button.js b/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button.js new file mode 100644 index 0000000..0e90a12 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button.js @@ -0,0 +1,369 @@ +window.addEventListener("load", https_everywhere_load, true); +window.addEventListener("load", function load(event) { + // need to wrap migratePreferences in another callback so that notification + // always displays on browser restart + window.removeEventListener("load", load, false); + gBrowser.addEventListener("DOMContentLoaded", migratePreferences, true); +}, false); + +const CI = Components.interfaces; +const CC = Components.classes; + +// LOG LEVELS --- +VERB=1; +DBUG=2; +INFO=3; +NOTE=4; +WARN=5; + +HTTPSEverywhere = CC["@eff.org/https-everywhere;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; + +// avoid polluting global namespace +// see: https://developer.mozilla.org/en-US/docs/Security_best_practices_in_extensions#Code_wrapping +if (!httpsEverywhere) { var httpsEverywhere = {}; } + +/** + * JS Object that acts as a namespace for the toolbar. + * + * Used to display toolbar hints to new users and change toolbar UI for cases + * such as when the toolbar is disabled. + */ +httpsEverywhere.toolbarButton = { + + /** + * Name of preference for determining whether to show ruleset counter. + */ + COUNTER_PREF: "extensions.https_everywhere.show_counter", + + /** + * Used to determine if a hint has been previously shown. + * TODO: Probably extraneous, look into removing + */ + hintShown: false, + + /** + * Initialize the toolbar button used to hint new users and update UI on + * certain events. + */ + init: function() { + HTTPSEverywhere.log(DBUG, 'Removing listener for toolbarButton init.'); + window.removeEventListener('load', httpsEverywhere.toolbarButton.init, false); + + var tb = httpsEverywhere.toolbarButton; + + // make sure icon is proper color during init + tb.changeIcon(); + + // make sure the checkbox for showing counter is properly set + var showCounter = tb.shouldShowCounter(); + var counterItem = document.getElementById('https-everywhere-counter-item'); + counterItem.setAttribute('checked', showCounter ? 'true' : 'false'); + + // show ruleset counter when a tab is changed + tb.updateRulesetsApplied(); + gBrowser.tabContainer.addEventListener( + 'TabSelect', + tb.updateRulesetsApplied, + false + ); + + // hook event for when page loads + var onPageLoad = function() { + // Timeout is used for a number of reasons. + // 1) For Performance since we want to defer computation. + // 2) Sometimes the page is loaded before all applied rulesets are + // calculated; in such a case, a half-second wait works. + setTimeout(tb.updateRulesetsApplied, 500); + }; + + var appcontent = document.getElementById('appcontent'); + if (appcontent) { + appcontent.addEventListener('load', onPageLoad, true); + } + + // decide whether to show toolbar hint + let hintPref = "extensions.https_everywhere.toolbar_hint_shown"; + if (!Services.prefs.getPrefType(hintPref) + || !Services.prefs.getBoolPref(hintPref)) { + // only run once + Services.prefs.setBoolPref(hintPref, true); + gBrowser.addEventListener("DOMContentLoaded", tb.handleShowHint, true); + } + }, + + /** + * Shows toolbar hint if previously not shown. + */ + handleShowHint: function() { + var tb = httpsEverywhere.toolbarButton; + if (!tb.hintShown){ + tb.hintShown = true; + const faqURL = "https://www.eff.org/https-everywhere/faq"; + var nBox = gBrowser.getNotificationBox(); + var strings = document.getElementById('HttpsEverywhereStrings'); + var msg = strings.getString('https-everywhere.toolbar.hint'); + var hint = nBox.appendNotification( + msg, + 'https-everywhere', + 'chrome://https-everywhere/skin/https-everywhere-24.png', + nBox.PRIORITY_WARNING_MEDIUM, + [], + function(action) { + // see https://developer.mozilla.org/en-US/docs/XUL/Method/appendNotification#Notification_box_events + gBrowser.selectedTab = gBrowser.addTab(faqURL); + } + ); + } + gBrowser.removeEventListener("DOMContentLoaded", tb.handleShowHint, true); + }, + + /** + * Changes HTTPS Everywhere toolbar icon based on whether HTTPS Everywhere + * is enabled or disabled. + */ + changeIcon: function() { + var enabled = HTTPSEverywhere.prefs.getBoolPref("globalEnabled"); + + var toolbarbutton = document.getElementById('https-everywhere-button'); + if (enabled) { + toolbarbutton.setAttribute('status', 'enabled'); + } else { + toolbarbutton.setAttribute('status', 'disabled'); + } + }, + + /** + * Update the rulesets applied counter for the current tab. + */ + updateRulesetsApplied: function() { + var toolbarbutton = document.getElementById('https-everywhere-button'); + var enabled = HTTPSEverywhere.prefs.getBoolPref("globalEnabled"); + var showCounter = httpsEverywhere.toolbarButton.shouldShowCounter(); + if (!enabled || !showCounter) { + toolbarbutton.setAttribute('rulesetsApplied', 0); + return; + } + + var domWin = content.document.defaultView.top; + var alist = HTTPSEverywhere.getExpando(domWin,"applicable_rules", null); + if (!alist) { + return; + } + // Make sure the list is up to date + alist.populate_list(); + + var counter = 0; + for (var x in alist.active) { + if (!(x in alist.breaking)) { + ++counter; + } + } + for (var x in alist.moot) { + if (!(x in alist.active)) { + ++counter; + } + } + + toolbarbutton.setAttribute('rulesetsApplied', counter); + HTTPSEverywhere.log(INFO, 'Setting icon counter to: ' + counter); + }, + + /** + * Gets whether to show the rulesets applied counter. + * + * @return {boolean} + */ + shouldShowCounter: function() { + var tb = httpsEverywhere.toolbarButton; + var sp = Services.prefs; + + var prefExists = sp.getPrefType(tb.COUNTER_PREF); + + // the default behavior is to show the rulesets applied counter. + // if no preference exists (default) or its enabled, show the counter + return !prefExists || sp.getBoolPref(tb.COUNTER_PREF); + }, + + /** + * Toggles the user's preference for displaying the rulesets applied counter + * and updates the UI. + */ + toggleShowCounter: function() { + var tb = httpsEverywhere.toolbarButton; + var sp = Services.prefs; + + var showCounter = tb.shouldShowCounter(); + sp.setBoolPref(tb.COUNTER_PREF, !showCounter); + + tb.updateRulesetsApplied(); + } + +}; + +function https_everywhere_load() { + window.removeEventListener('load', https_everywhere_load, true); + // on first run, put the context menu in the addons bar + try { + var first_run; + try { + first_run = Services.prefs.getBoolPref("extensions.https_everywhere.firstrun_context_menu"); + } catch(e) { + Services.prefs.setBoolPref("extensions.https_everywhere.firstrun_context_menu", true); + first_run = true; + } + if(first_run) { + Services.prefs.setBoolPref("extensions.https_everywhere.firstrun_context_menu", false); + var navbar = document.getElementById("nav-bar"); + if(navbar.currentSet.indexOf("https-everywhere-button") == -1) { + var set = navbar.currentSet+',https-everywhere-button'; + navbar.setAttribute('currentset', set); + navbar.currentSet = set; + document.persist('nav-bar', 'currentset'); + } + } + } catch(e) { } +} + +function stitch_context_menu() { + // the same menu appears both under Tools and via the toolbar button: + var menu = document.getElementById("https-everywhere-menu"); + if (!menu.firstChild) { + var popup = document.getElementById("https-everywhere-context"); + menu.appendChild(popup.cloneNode(true)); + } +} +function stitch_context_menu2() { + // the same menu appears both under Tools and via the toolbar button: + var menu = document.getElementById("https-everywhere-menu2"); + if (!menu.firstChild) { + var popup = document.getElementById("https-everywhere-context"); + menu.appendChild(popup.cloneNode(true)); + } +} + +var rulesetTestsMenuItem = null; + +function show_applicable_list(menupopup) { + var domWin = content.document.defaultView.top; + if (!(domWin instanceof CI.nsIDOMWindow)) { + alert(domWin + " is not an nsIDOMWindow"); + return null; + } + + var alist = HTTPSEverywhere.getExpando(domWin,"applicable_rules", null); + var weird=false; + + if (!alist) { + // This case occurs for error pages and similar. We need a dummy alist + // because populate_menu lives in there. Would be good to refactor this + // away. + alist = new HTTPSEverywhere.ApplicableList(HTTPSEverywhere.log, document, domWin); + weird = true; + } + alist.populate_menu(document, menupopup, weird); + + // should we also show the ruleset tests menu item? + if(HTTPSEverywhere.prefs.getBoolPref("show_ruleset_tests")) { + + if(!rulesetTestsMenuItem) { + let strings = document.getElementById('HttpsEverywhereStrings'); + let label = strings.getString('https-everywhere.menu.ruleset-tests'); + + rulesetTestsMenuItem = this.document.createElement('menuitem'); + rulesetTestsMenuItem.setAttribute('command', 'https-everywhere-menuitem-ruleset-tests'); + rulesetTestsMenuItem.setAttribute('label', label); + } + + if(!menupopup.contains(rulesetTestsMenuItem)) + menupopup.appendChild(rulesetTestsMenuItem); + } + +} + +function toggle_rule(rule_id) { + // toggle the rule state + HTTPSEverywhere.https_rules.rulesetsByID[rule_id].toggle(); + var domWin = content.document.defaultView.top; + /*if (domWin instanceof CI.nsIDOMWindow) { + var alist = HTTPSEverywhere.getExpando(domWin,"applicable_rules", null); + if (alist) alist.empty(); + }*/ + reload_window(); +} + +function reload_window() { + var domWin = content.document.defaultView.top; + if (!(domWin instanceof CI.nsIDOMWindow)) { + HTTPSEverywhere.log(WARN, domWin + " is not an nsIDOMWindow"); + return null; + } + try { + var webNav = domWin.QueryInterface(CI.nsIInterfaceRequestor) + .getInterface(CI.nsIWebNavigation) + .QueryInterface(CI.nsIDocShell); + } catch(e) { + HTTPSEverywhere.log(WARN,"failed to get webNav"); + return null; + } + // This choice of flags comes from NoScript's quickReload function; not sure + // if it's optimal + webNav.reload(webNav.LOAD_FLAGS_CHARSET_CHANGE); +} + +function toggleEnabledState(){ + HTTPSEverywhere.toggleEnabledState(); + reload_window(); + + // Change icon depending on enabled state + httpsEverywhere.toolbarButton.changeIcon(); +} + +function open_in_tab(url) { + var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] + .getService(Components.interfaces.nsIWindowMediator); + var recentWindow = wm.getMostRecentWindow("navigator:browser"); + recentWindow.delayedOpenTab(url, null, null, null, null); +} + +// hook event for showing hint +HTTPSEverywhere.log(DBUG, 'Adding listener for toolbarButton init.'); +window.addEventListener("load", httpsEverywhere.toolbarButton.init, false); + +function migratePreferences() { + gBrowser.removeEventListener("DOMContentLoaded", migratePreferences, true); + let prefs_version = HTTPSEverywhere.prefs.getIntPref("prefs_version"); + + // first migration loses saved prefs + if(prefs_version == 0) { + try { + // upgrades will have old rules as preferences, such as the EFF rule + let upgrade = false; + let childList = HTTPSEverywhere.prefs.getChildList("", {}); + for(let i=0; i<childList.length; i++) { + if(childList[i] == 'EFF') { + upgrade = true; + break; + } + } + + if(upgrade) { + let nBox = gBrowser.getNotificationBox(); + let strings = document.getElementById('HttpsEverywhereStrings'); + let msg = strings.getString('https-everywhere.migration.notification0'); + nBox.appendNotification( + msg, + 'https-everywhere-migration0', + 'chrome://https-everywhere/skin/https-everywhere-24.png', + nBox.PRIORITY_WARNING_MEDIUM + ); + } + } catch(e) { + HTTPSEverywhere.log(WARN, "Migration from prefs_version 0 error: "+e); + } + + HTTPSEverywhere.prefs.setIntPref("prefs_version", prefs_version+1); + } +} + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button.xul b/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button.xul new file mode 100644 index 0000000..c3cbed0 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button.xul @@ -0,0 +1,71 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://https-everywhere/skin/https-everywhere.css" type="text/css"?> + +<!DOCTYPE overlay SYSTEM "chrome://https-everywhere/locale/https-everywhere.dtd"> + +<!-- helpful docs at + https://developer.mozilla.org/en/XUL/PopupGuide/PopupEvents --> + +<overlay id="https-everywhere-button-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + <script type="application/x-javascript" src="chrome://https-everywhere/content/toolbar_button.js"/> + <script type="application/x-javascript" src="chrome://https-everywhere/content/ruleset-tests.js"/> + + <stringbundleset id="stringbundleset"> + <stringbundle id="HttpsEverywhereStrings" + src="chrome://https-everywhere/locale/https-everywhere.properties" /> + </stringbundleset> + + <!-- this works in Firefox, we need a Seamonkey version too... --> + <menupopup id="menu_ToolsPopup" onpopupshowing="stitch_context_menu()"> + <menu id="https-everywhere-menu" label="&https-everywhere.about.ext_name;"> + <!-- "https-everywhere-context" below gets .cloneNode()ed in here --> + </menu> + </menupopup> + + <menupopup id="toolsPopup" onpopupshowing="stitch_context_menu2()"> + <menu id="https-everywhere-menu2" label="&https-everywhere.about.ext_name;"> + <!-- "https-everywhere-context" below gets .cloneNode()ed in here --> + </menu> + </menupopup> + + <toolbarpalette id="BrowserToolbarPalette"> + <toolbarbutton + id="https-everywhere-button" + tooltiptext="&https-everywhere.about.ext_name;" + label="HTTPS" + context="https-everywhere-context-menu" + oncontextmenu="this.open = true;" + oncommand="this.open = true;" + buttonstyle="pictures" + type="menu" + rulesetsApplied="0"> + + <menupopup id="https-everywhere-context" onpopupshowing="show_applicable_list(this)"> + <!-- entries will be written here by ApplicableList.populate_menu() --> + <menuseparator /> + <menuitem type="checkbox" id="https-everywhere-counter-item" label="&https-everywhere.menu.showCounter;" + oncommand="httpsEverywhere.toolbarButton.toggleShowCounter()" /> + <menuseparator /> + <menuitem label="&https-everywhere.menu.observatory;" command="https-everywhere-menuitem-observatory" /> + <menuitem label="&https-everywhere.menu.about;" command="https-everywhere-menuitem-about" /> + </menupopup> + </toolbarbutton> + </toolbarpalette> + <commandset> + <command id="https-everywhere-menuitem-globalEnableToggle" + oncommand="toggleEnabledState();" /> + <command id="https-everywhere-menuitem-preferences" + oncommand="HTTPSEverywhere.chrome_opener('chrome://https-everywhere/content/preferences.xul', 'chrome,centerscreen,resizable=yes');" /> + <command id="https-everywhere-menuitem-about" + oncommand="HTTPSEverywhere.chrome_opener('chrome://https-everywhere/content/about.xul');" /> + <command id="https-everywhere-menuitem-observatory" + oncommand="HTTPSEverywhere.chrome_opener('chrome://https-everywhere/content/observatory-preferences.xul', 'chrome,centerscreen,resizable=yes');" /> + <command id="https-everywhere-menuitem-donate-eff" + oncommand="open_in_tab('https://www.eff.org/donate');" /> + <command id="https-everywhere-menuitem-donate-tor" + oncommand="open_in_tab('https://www.torproject.org/donate');" /> + <command id="https-everywhere-menuitem-ruleset-tests" + oncommand="openStatus();" /> + </commandset> +</overlay> + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button_binding.xml b/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button_binding.xml new file mode 100644 index 0000000..1981b3a --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/toolbar_button_binding.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- +Toolbar button needs to be extended to show a counter for the number of +rulesets applied, and this can be done using XBL. + +See: https://developer.mozilla.org/en-US/docs/XBL +--> +<bindings xmlns="http://www.mozilla.org/xbl" + xmlns:xbl="http://www.mozilla.org/xbl" + xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> + + <binding id="https-everywhere-binding"> + <content> + <!-- ruleset counter (rscounter) and rulesets applied (rsapplied) --> + <xul:stack id="rscounter"> + <xul:label id="rsapplied" xbl:inherits="value=rulesetsApplied" /> + </xul:stack> + + <!-- + Https everywhere toolbar button is already defined; just use its settings. + TODO: Look into any issues with oncommand/oncontext. + --> + <xul:toolbarbutton + class="https-everywhere-button toolbarbutton-1 chromeclass-toolbar-additional" + flex="1" + allowevents="true" + xbl:inherits="type,crop,image,label,accesskey,command,align,dir,pack,orient,wrap"> + + <children includes="menupopup" /> + </xul:toolbarbutton> + </content> + </binding> +</bindings> |