From 971b7690860c677374cbe14ee64558b1bd174718 Mon Sep 17 00:00:00 2001 From: Ruben Rodriguez Date: Mon, 20 Oct 2014 02:25:28 +0200 Subject: https-everywhere updated to 4.0.2 --- data/extensions/https-everywhere@eff.org/Changelog | 90 ++ .../https-everywhere@eff.org/chrome.manifest | 15 +- .../chrome/content/about.xul | 4 +- .../chrome/content/code/AndroidUI.jsm | 226 ++++ .../chrome/content/code/HTTPS.js | 15 +- .../chrome/content/code/X509ChainWhitelist.js | 1304 ++++++++++---------- .../chrome/content/ruleset-tests.js | 55 +- .../chrome/content/toolbar_button.js | 100 +- .../chrome/content/toolbar_button.xul | 7 +- .../chrome/skin/https-everywhere-128.png | Bin 0 -> 13300 bytes .../chrome/skin/https-everywhere-16-red.png | Bin 0 -> 724 bytes .../chrome/skin/https-everywhere-24-red.png | Bin 0 -> 1238 bytes .../chrome/skin/https-everywhere.css | 7 +- .../components/https-everywhere.js | 134 +- .../components/ssl-observatory.js | 280 ++--- .../defaults/preferences/preferences.js | 11 +- .../defaults/rulesets.sqlite | Bin 4258816 -> 1473536 bytes .../https-everywhere@eff.org/install.rdf | 30 +- 18 files changed, 1304 insertions(+), 974 deletions(-) create mode 100644 data/extensions/https-everywhere@eff.org/chrome/content/code/AndroidUI.jsm create mode 100644 data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-128.png create mode 100644 data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-16-red.png create mode 100644 data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-24-red.png diff --git a/data/extensions/https-everywhere@eff.org/Changelog b/data/extensions/https-everywhere@eff.org/Changelog index c5f270b..e846210 100644 --- a/data/extensions/https-everywhere@eff.org/Changelog +++ b/data/extensions/https-everywhere@eff.org/Changelog @@ -1,3 +1,93 @@ +4.0.2 (2014-10-15) + * Disable SSL 3 to Prevent POODLE attack: + https://github.com/EFForg/https-everywhere/pull/674 + * NEW: HTTP Nowhere mode. Block all plaintext http + * Updates to Yahoo APIs, Fastly, VMWare, Netflix, Maashable, LinkedIn , + Gitorious, Mozilla, msecnd, Hotmail, Live, Eniro, Steam, Phoronix, + net-security.org, Flickr, Craigslist, Apache.org, Joomla.org, Samsung, + Google IMages, Expedia, Akamai, Trip Advisor, Ikea, CEll, Leo.org, Facebook, + F-Secure, Dropbox, Courage Campaign, Box, Atlassian, Internet Archvie, + localbitcoins.com, SOny, SciVerse, Web.com, Urgan Dictionary, Pornhub, + Fool.com, ClickBank, MGID, Which?, Microsoft, Barnes and Noble, Royal + Institute of GB, Wall Street Journal + + +4.0.1 (2014-09-11) + + * Significant new coverage: Reddit, Quora + * Fixes include: + Frontier Networks, Hotmail / Live, Microsoft, Mozilla, Ohio State, Rackspace, SJ.se, Timbo.se + https://github.com/EFForg/https-everywhere/issues/310 + https://github.com/EFForg/https-everywhere/issues/500 + https://trac.torproject.org/projects/tor/ticket/11402 + https://trac.torproject.org/projects/tor/ticket/11418 + https://trac.torproject.org/projects/tor/ticket/12583 + https://trac.torproject.org/projects/tor/ticket/12104 + https://trac.torproject.org/projects/tor/ticket/9466 + https://github.com/EFForg/https-everywhere/issues/144 + * Enhancements to MCB detection and subsequent ruleset fixes + https://github.com/EFForg/https-everywhere/issues/529 + +chrome-2014.8.22 (2014-08-22) + * Rulesets from 4.0.0 + * German translation + +4.0.0 (2014-08-04) + * Ruleset fixes to wikimedia, stanford-university, joyent, and gaytorrents. + * Merge Android Firefox branch, so Android now has the same release cycle + as the stable HTTPS Everywhere branch for Firefox. + * Remove old unused ContentPolicy code. + +5.0development.0 (2014-07-28) + * Various rules for new gaming sites: + https://github.com/EFForg/https-everywhere/pull/387 + * Add exception for flashproxy: + https://github.com/EFForg/https-everywhere/issues/357 + * Updates to joyent, moevideo, FreeDesktop, Gfycat, Bytemark, tchibo, + Kantonalbank rules, godaddy, Bing, Pcwelt.de, Gamestar.de, o2-online, + heise.de, mozdev.org, Wikimedia, Spotify, Stanford-University, various Swiss + websites, SourceForge, utwente.nl, teamfortress.com, Fastly, mozilla.org, + AmazonAws, Technology Review, jitsi, googlecode.com, CDT, and other rules. + * Add Denh.am, justeatuk, owncloud, seanmckaybeck.com, strimoid.pl, + elkosmasgr, mantisbt, IAPC, ReadTheDocs, tox.im, and other rules. + * Initialize Convergence's NSS.js with nss library path: + https://github.com/EFForg/https-everywhere/pull/315 + * Add filter for OCSP and other requests that should be unrewritten: + https://github.com/EFForg/https-everywhere/pull/332 + * Add testing framework and a few basic extension tests: + https://github.com/EFForg/https-everywhere/pull/338 + * Fix Chrome redirect loop detection: + https://github.com/EFForg/https-everywhere/issues/289 + * Fix loading of user rules: + https://github.com/EFForg/https-everywhere/pull/293 + * Fix SSL Obs. preferences XML parsing bug. + * Add experimental "HTTP Nowhere" mode (blocks all HTTP requests): + https://github.com/EFForg/https-everywhere/pull/379 + +chrome-2014.6.26 (2014-06-25) + * Ruleset fixes (same as 3.5.3) + * Fix redirect loop detection for HTTPS to HTTPS redirects (Github #289) + * Remove item from rule cache when it is disabled by the user + +3.5.3 (2014-06-25) + * Ruleset fixes to Mozilla, PCWorld, MacWorld, Google Books, 4chan blog, + BuzzFeed, BBC, googlecode, TechDirt, Wikia, Technology Review, Google + Translate, CDT, Science Direct, Sourceforge + * Fix rulesets.sqlite path, allowing global installation (Github #255) + * Revert components/ssl-observatory.js to 3.4.5, possibly fixing crash bug + (Github #262) + * Update observatory whitelist + +4.0development.17 (2014-05-23) + * Re-enable ability to see all rulesets in enable/disable dialog. + * Fix allowing global installation: + https://github.com/EFForg/https-everywhere/pull/255 + * Better observatory whitelisting: + https://github.com/EFForg/https-everywhere/pull/276 + * Add option for SSL obs. revoked cert warnings: + https://github.com/EFForg/https-everywhere/pull/278 + * Numerous ruleset updates + 3.5.1 (2014-04-25) * Revert https://github.com/EFForg/https-everywhere/pull/134 due to YouTube breakage. diff --git a/data/extensions/https-everywhere@eff.org/chrome.manifest b/data/extensions/https-everywhere@eff.org/chrome.manifest index 4869afe..3764fa6 100644 --- a/data/extensions/https-everywhere@eff.org/chrome.manifest +++ b/data/extensions/https-everywhere@eff.org/chrome.manifest @@ -41,13 +41,16 @@ component {32c165b4-fe5e-4964-9250-603c410631b4} components/https-everywhere.js contract @eff.org/https-everywhere;1 {32c165b4-fe5e-4964-9250-603c410631b4} category profile-after-change HTTPSEverywhere @eff.org/https-everywhere;1 -category content-policy HTTPSEverywhere @eff.org/https-everywhere;1 -overlay chrome://browser/content/browser.xul chrome://https-everywhere/content/toolbar_button.xul -overlay chrome://navigator/content/navigator.xul chrome://https-everywhere/content/toolbar_button.xul +# XUL gets included in every non-mobile build +# Android has some non-XUL UI that is loaded from the +# sessionstore-windows-restored observer in https-everywhere.js +overlay chrome://browser/content/browser.xul chrome://https-everywhere/content/toolbar_button.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} application={3550f703-e582-4d05-9a08-453d09bdfdc6} application={a79fe89b-6662-4ff4-8e88-09950ad4dfde} +overlay chrome://navigator/content/navigator.xul chrome://https-everywhere/content/toolbar_button.xul application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} application={3550f703-e582-4d05-9a08-453d09bdfdc6} application={a79fe89b-6662-4ff4-8e88-09950ad4dfde} style chrome://global/content/customizeToolbar.xul chrome://https-everywhere/skin/https-everywhere.css -component {0f9ab521-986d-4ad8-9c1f-6934e195c15c} components/ssl-observatory.js -contract @eff.org/ssl-observatory;1 {0f9ab521-986d-4ad8-9c1f-6934e195c15c} -category profile-after-change SSLObservatory @eff.org/ssl-observatory;1 +# Observatory does not yet have mobile-friendly UI +component {0f9ab521-986d-4ad8-9c1f-6934e195c15c} components/ssl-observatory.js application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} application={3550f703-e582-4d05-9a08-453d09bdfdc6} application={a79fe89b-6662-4ff4-8e88-09950ad4dfde} +contract @eff.org/ssl-observatory;1 {0f9ab521-986d-4ad8-9c1f-6934e195c15c} application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} application={3550f703-e582-4d05-9a08-453d09bdfdc6} application={a79fe89b-6662-4ff4-8e88-09950ad4dfde} +category profile-after-change SSLObservatory @eff.org/ssl-observatory;1 application={ec8030f7-c20a-464f-9b0e-13a3a9e97384} application={92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} application={3550f703-e582-4d05-9a08-453d09bdfdc6} application={a79fe89b-6662-4ff4-8e88-09950ad4dfde} diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/about.xul b/data/extensions/https-everywhere@eff.org/chrome/content/about.xul index cf57e9d..6bf5e40 100644 --- a/data/extensions/https-everywhere@eff.org/chrome/content/about.xul +++ b/data/extensions/https-everywhere@eff.org/chrome/content/about.xul @@ -21,12 +21,12 @@ - + - + diff --git a/data/extensions/https-everywhere@eff.org/chrome/content/code/AndroidUI.jsm b/data/extensions/https-everywhere@eff.org/chrome/content/code/AndroidUI.jsm new file mode 100644 index 0000000..e476345 --- /dev/null +++ b/data/extensions/https-everywhere@eff.org/chrome/content/code/AndroidUI.jsm @@ -0,0 +1,226 @@ +const CC = Components.classes; +const CI = Components.interfaces; +const CU = Components.utils; + +var HTTPSEverywhere = CC["@eff.org/https-everywhere;1"] + .getService(CI.nsISupports).wrappedJSObject; + +CU.import("resource://gre/modules/Prompt.jsm"); + +var menuId; +var urlbarId; +var aWindow = getWindow(); + + +/* + * Setup/Teardown for the UI + */ + +function loadIntoWindow() { + if (!aWindow) { + return; + } + var enabled = HTTPSEverywhere.prefs.getBoolPref("globalEnabled"); + addToggleItemToMenu(enabled); + if (enabled) { + urlbarId = aWindow.NativeWindow.pageactions.add(urlbarOptions); + } else if (urlbarId) { + aWindow.NativeWindow.pageactions.remove(urlbarId); + } +} + +function unloadFromWindow() { + if (!aWindow) { + return; + } + aWindow.NativeWindow.menu.remove(menuId); + aWindow.NativeWindow.pageactions.remove(urlbarId); +} + + +/* + * Add a menu item to toggle HTTPS Everywhere + */ + +function addToggleItemToMenu(enabled) { + if (menuId) { aWindow.NativeWindow.menu.remove(menuId); } + var menuLabel = enabled ? "HTTPS Everywhere on" : "HTTPS Everywhere off"; + menuId = aWindow.NativeWindow.menu.add(menuLabel, null, function() { + popupToggleMenu(aWindow, enabled); + }); +} + +function popupToggleMenu(aWindow, enabled) { + var buttons = [ + { + label: "Yes", + callback: function() { + toggleEnabledState(); + var msg = enabled ? "HTTPS Everywhere disabled!" : "HTTPS Everywhere enabled!"; + aWindow.NativeWindow.toast.show(msg, "short"); + return true; + } + }, { + label: "No", + callback: function() { return false; } + } + ]; + var newState = enabled ? "off?" : "on?"; + aWindow.NativeWindow.doorhanger.show("Would you like to turn HTTPS Everywhere "+newState, + "doorhanger-toggle", buttons); +} + + +/* + * The HTTPS Everywhere icon in the URL bar shows a popup of rules that the + * user can activate/deactivate. On long click, reset all rules to defaults. + */ + +var popupInfo = { + rules: [], + ruleItems: [], + ruleStatus: [], + alist: null, + getApplicableList: function() { + var domWin = aWindow.BrowserApp.selectedTab.window; + return HTTPSEverywhere.getApplicableListForDOMWin(domWin); + }, + fill: function() { + this.clear(); + this.alist = this.getApplicableList(); + HTTPSEverywhere.log(4,"applicable list active: "+JSON.stringify(this.alist.active)); + HTTPSEverywhere.log(4,"applicable list inactive: "+JSON.stringify(this.alist.inactive)); + for (var rule in this.alist.all) { + if (this.alist.active.hasOwnProperty(rule)) { + // active rules are checked and toggleable + this.ruleItems.push({ label: rule, selected: true }); + this.ruleStatus.push(true); + this.rules.push(this.alist.active[rule]); + } else if (this.alist.moot.hasOwnProperty(rule)) { + // moot rules are checked and toggleable too + this.ruleItems.push({ label: rule, selected: true }); + this.ruleStatus.push(true); + this.rules.push(this.alist.moot[rule]); + } else if (this.alist.inactive.hasOwnProperty(rule)) { + // inactive rules are unchecked and toggleable + this.ruleItems.push({ label: rule }); + this.ruleStatus.push(false); + this.rules.push(this.alist.inactive[rule]); + } else if (this.alist.breaking.hasOwnProperty(rule)) { + // breaking rules are get a unicode clockwise arrow next to them + var ruleLabel = "\u21B7"+rule; + var isSelected = this.alist.breaking[rule].active; + this.ruleItems.push({ label: ruleLabel, selected: isSelected }); + this.ruleStatus.push(isSelected); + this.rules.push(this.alist.breaking[rule]); + } + } + }, + clear: function() { + this.rules = []; + this.ruleItems = []; + this.ruleStatus = []; + this.alist = {}; + } +}; + +var urlbarOptions = { + + title: "HTTPS Everywhere", + + icon: "chrome://https-everywhere/skin/https-everywhere-128.png", + + clickCallback: function() { + popupInfo.fill(); + rulesPrompt.setMultiChoiceItems(popupInfo.ruleItems); + rulesPrompt.show(function(data) { + var db = data.button; + if (db === -1) { return null; } // user didn't click the accept button + if (popupInfo.rules.length !== db.length) { + // Why does db sometimes have an extra entry that doesn't correspond + // to any of the ruleItems? No idea, but let's log it. + HTTPSEverywhere.log(5,"Got length mismatch between popupInfo.ruleItems and data.button"); + HTTPSEverywhere.log(4,"Applicable rules: "+JSON.stringify(popupInfo.rules)); + HTTPSEverywhere.log(4, "data.button: "+JSON.stringify(db)); + } + for (var i=0; i 0) { + urls.push({ + url: 'http://'+target, + target: target, + ruleset_ids: active_ids + }); + } +} + function testRunner() { Components.utils.import("resource://gre/modules/PopupNotifications.jsm"); @@ -34,14 +59,24 @@ function testRunner() { var output = []; var urls = []; var num = 0; + var targets_to_ids = HTTPSEverywhere.https_rules.targets; + var ruleset_ids; + accepted_test_targets = {}; // reset each time - 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] - }); + // we need every ruleset loaded from DB to check if it's active + HTTPSEverywhere.https_rules.loadAllRulesets(); + + for(var target in targets_to_ids) { + ruleset_ids = targets_to_ids[target]; + if(target.indexOf("*") == -1) { + addTestTarget(urls, target, ruleset_ids); + } else { + // target is like *.example.wildcard.com, or www.example.* + // let's see what we can do... + var t = target.replace(left_star, "www."); + if (t.indexOf("*") == -1) { + addTestTarget(urls, t, ruleset_ids); + } } } @@ -72,8 +107,8 @@ function testRunner() { if(PopupNotifications.getNotification("mixed-content-blocked", gBrowser.getBrowserForTab(tab))) { // build output to log ruleset_xmls = ''; - for(let i=0; i - + + + + oncommand="httpsEverywhere.toolbarButton.toggleShowCounter()" class="hide-on-disable"/> diff --git a/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-128.png b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-128.png new file mode 100644 index 0000000..317ecf9 Binary files /dev/null and b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-128.png differ diff --git a/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-16-red.png b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-16-red.png new file mode 100644 index 0000000..cad9162 Binary files /dev/null and b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-16-red.png differ diff --git a/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-24-red.png b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-24-red.png new file mode 100644 index 0000000..7866d2a Binary files /dev/null and b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere-24-red.png differ diff --git a/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere.css b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere.css index 6c03b83..df0c1a7 100644 --- a/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere.css +++ b/data/extensions/https-everywhere@eff.org/chrome/skin/https-everywhere.css @@ -16,10 +16,15 @@ toolbar #https-everywhere-button > .https-everywhere-button { } /* Use CSS attribute selector for changing icon */ +#https-everywhere-button[http_nowhere="true"] > .https-everywhere-button { + list-style-image: url("chrome://https-everywhere/skin/https-everywhere-24-red.png"); +} #https-everywhere-button[status="disabled"] > .https-everywhere-button { list-style-image: url("chrome://https-everywhere/skin/https-everywhere-24-gray.png"); } - +toolbar[iconsize="small"] #https-everywhere-button[http_nowhere="true"] > .https-everywhere-button { + list-style-image: url("chrome://https-everywhere/skin/https-everywhere-16-red.png"); +} toolbar[iconsize="small"] #https-everywhere-button[status="disabled"] > .https-everywhere-button { list-style-image: url("chrome://https-everywhere/skin/https-everywhere-16-gray.png"); } diff --git a/data/extensions/https-everywhere@eff.org/components/https-everywhere.js b/data/extensions/https-everywhere@eff.org/components/https-everywhere.js index 90f55e2..72788ef 100644 --- a/data/extensions/https-everywhere@eff.org/components/https-everywhere.js +++ b/data/extensions/https-everywhere@eff.org/components/https-everywhere.js @@ -7,8 +7,9 @@ NOTE=4; WARN=5; // PREFERENCE BRANCHES -PREFBRANCH_ROOT=0; -PREFBRANCH_RULE_TOGGLE=1; +let PREFBRANCH_ROOT=0; +let PREFBRANCH_RULE_TOGGLE=1; +let PREFBRANCH_NONE=2; //--------------- @@ -165,7 +166,7 @@ function StorageController(command) { this.command = command; this.data = {}; this.wrappedJSObject = this; -} +}; /*var Controller = Class("Controller", XPCOM(CI.nsIController), { init: function (command, data) { @@ -186,9 +187,18 @@ function HTTPSEverywhere() { this.INCLUDE=INCLUDE; this.ApplicableList = ApplicableList; this.browser_initialised = false; // the browser is completely loaded - + + this.prefs = this.get_prefs(); this.rule_toggle_prefs = this.get_prefs(PREFBRANCH_RULE_TOGGLE); + + this.httpNowhereEnabled = this.prefs.getBoolPref("http_nowhere.enabled"); + this.isMobile = this.doMobileCheck(); + + // Disable SSLv3 to prevent POODLE attack. + // https://www.imperialviolet.org/2014/10/14/poodle.html + var root_prefs = this.get_prefs(PREFBRANCH_NONE); + root_prefs.setIntPref("security.tls.version.min", 1); // We need to use observers instead of categories for FF3.0 for these: // https://developer.mozilla.org/en/Observer_Notifications @@ -199,11 +209,16 @@ function HTTPSEverywhere() { this.obsService = CC["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); - if(this.prefs.getBoolPref("globalEnabled")){ + if (this.prefs.getBoolPref("globalEnabled")) { this.obsService.addObserver(this, "profile-before-change", false); this.obsService.addObserver(this, "profile-after-change", false); this.obsService.addObserver(this, "sessionstore-windows-restored", false); this.obsService.addObserver(this, "browser:purge-session-history", false); + } else { + // Need this to initialize FF for Android UI even when HTTPS-E is off + if (this.isMobile) { + this.obsService.addObserver(this, "sessionstore-windows-restored", false); + } } var pref_service = Components.classes["@mozilla.org/preferences-service;1"] @@ -219,43 +234,6 @@ function HTTPSEverywhere() { } -// nsIContentPolicy interface -// we use numeric constants for performance sake: -const TYPE_OTHER = 1; -const TYPE_SCRIPT = 2; -const TYPE_IMAGE = 3; -const TYPE_STYLESHEET = 4; -const TYPE_OBJECT = 5; -const TYPE_DOCUMENT = 6; -const TYPE_SUBDOCUMENT = 7; -const TYPE_REFRESH = 8; -const TYPE_XBL = 9; -const TYPE_PING = 10; -const TYPE_XMLHTTPREQUEST = 11; -const TYPE_OBJECT_SUBREQUEST = 12; -const TYPE_DTD = 13; -const TYPE_FONT = 14; -const TYPE_MEDIA = 15; -// -------------- -// REJECT_SERVER = -3 -// ACCEPT = 1 - - -// Some of these types are known by arbitrary assertion at -// https://bugzilla.mozilla.org/show_bug.cgi?id=677643#c47 -// TYPE_FONT was required to fix https://trac.torproject.org/projects/tor/ticket/4194 -// TYPE_SUBDOCUMENT was required to fix https://trac.torproject.org/projects/tor/ticket/4149 -// I have NO IDEA why JS won't let me use the constants above in defining this -const shouldLoadTargets = { - 1 : true, - 3 : true, - 5 : true, - 12 : true, - 14 : true, - 7 : true -}; - - /* In recent versions of Firefox and HTTPS Everywhere, the call stack for performing an HTTP -> HTTPS rewrite looks like this: @@ -322,7 +300,7 @@ HTTPSEverywhere.prototype = { _xpcom_categories: [ { category: "app-startup", - }, + } ], // QueryInterface implementation, e.g. using the generateQI helper @@ -421,6 +399,8 @@ HTTPSEverywhere.prototype = { } } + if (!loadContext) { return null; } + let domWin = loadContext.associatedWindow; if (!domWin) { this.log(NOTE, "failed to get DOMWin for " + channel.URI.spec); @@ -455,7 +435,7 @@ HTTPSEverywhere.prototype = { return null; } var dw = domWin.top; - var alist= this.getExpando(dw,"applicable_rules",null); + var alist= this.getExpando(dw,"applicable_rules"); if (alist) { //this.log(DBUG,"get AL success in " + where); return alist; @@ -483,7 +463,7 @@ HTTPSEverywhere.prototype = { else this.log(NOTE,"Failed to indicate breakage in content menu"); return; } - HTTPS.replaceChannel(lst, channel); + HTTPS.replaceChannel(lst, channel, this.httpNowhereEnabled); } else if (topic == "http-on-examine-response") { this.log(DBUG, "Got http-on-examine-response @ "+ (channel.URI ? channel.URI.spec : '') ); HTTPS.handleSecureCookies(channel); @@ -542,7 +522,13 @@ HTTPSEverywhere.prototype = { } } else if (topic == "sessionstore-windows-restored") { this.log(DBUG,"Got sessionstore-windows-restored"); - this.maybeShowObservatoryPopup(); + if (!this.isMobile) { + this.maybeShowObservatoryPopup(); + } else { + this.log(WARN, "Initializing Firefox for Android UI"); + Cu.import("chrome://https-everywhere/content/code/AndroidUI.jsm"); + AndroidUI.init(); + } this.browser_initialised = true; } else if (topic == "nsPref:changed") { // If the user toggles the Mixed Content Blocker settings, reload the rulesets @@ -645,7 +631,7 @@ HTTPSEverywhere.prototype = { return; } var alist = this.juggleApplicableListsDuringRedirection(oldChannel, newChannel); - HTTPS.replaceChannel(alist,newChannel); + HTTPS.replaceChannel(alist,newChannel, this.httpNowhereEnabled); }, juggleApplicableListsDuringRedirection: function(oldChannel, newChannel) { @@ -655,10 +641,10 @@ HTTPSEverywhere.prototype = { var domWin = this.getWindowForChannel(oldChannel); var old_alist = null; if (domWin) - old_alist = this.getExpando(domWin,"applicable_rules", null); + old_alist = this.getExpando(domWin,"applicable_rules"); domWin = this.getWindowForChannel(newChannel); if (!domWin) return null; - var new_alist = this.getExpando(domWin,"applicable_rules", null); + var new_alist = this.getExpando(domWin,"applicable_rules"); if (old_alist && !new_alist) { new_alist = old_alist; this.setExpando(domWin,"applicable_rules",new_alist); @@ -680,8 +666,10 @@ HTTPSEverywhere.prototype = { // get our preferences branch object // FIXME: Ugly hack stolen from https var branch_name; - if(prefBranch == PREFBRANCH_RULE_TOGGLE) + if(prefBranch === PREFBRANCH_RULE_TOGGLE) branch_name = "extensions.https_everywhere.rule_toggle."; + else if (prefBranch === PREFBRANCH_NONE) + branch_name = ""; else branch_name = "extensions.https_everywhere."; var o_prefs = false; @@ -720,6 +708,13 @@ HTTPSEverywhere.prototype = { return o_branch; }, + // Are we on Firefox for Android? + doMobileCheck: function() { + let appInfo = CC["@mozilla.org/xre/app-info;1"].getService(CI.nsIXULAppInfo); + let ANDROID_ID = "{aa3c5121-dab2-40e2-81ca-7ea25febc110}"; + return (appInfo.ID === ANDROID_ID); + }, + chrome_opener: function(uri, args) { // we don't use window.open, because we need to work around TorButton's // state control @@ -743,9 +738,10 @@ HTTPSEverywhere.prototype = { toggleEnabledState: function() { if(this.prefs.getBoolPref("globalEnabled")){ try{ + // toggling some of these after startup may be inconsequential... + // this.obsService.removeObserver(this, "sessionstore-windows-restored"); this.obsService.removeObserver(this, "profile-before-change"); this.obsService.removeObserver(this, "profile-after-change"); - this.obsService.removeObserver(this, "sessionstore-windows-restored"); OS.removeObserver(this, "cookie-changed"); OS.removeObserver(this, "http-on-modify-request"); OS.removeObserver(this, "http-on-examine-merged-response"); @@ -769,7 +765,7 @@ HTTPSEverywhere.prototype = { try{ this.obsService.addObserver(this, "profile-before-change", false); this.obsService.addObserver(this, "profile-after-change", false); - this.obsService.addObserver(this, "sessionstore-windows-restored", false); + // this.obsService.addObserver(this, "sessionstore-windows-restored", false); OS.addObserver(this, "cookie-changed", false); OS.addObserver(this, "http-on-modify-request", false); OS.addObserver(this, "http-on-examine-merged-response", false); @@ -797,6 +793,40 @@ HTTPSEverywhere.prototype = { this.log(WARN, "Couldn't add observers: " + e); } } + }, + + toggleHttpNowhere: function() { + let prefService = Services.prefs; + let thisBranch = + prefService.getBranch("extensions.https_everywhere.http_nowhere."); + let securityBranch = prefService.getBranch("security."); + + // Whether cert is treated as invalid when OCSP connection fails + let OCSP_REQUIRED = "OCSP.require"; + + // Branch to save original settings + let ORIG_OCSP_REQUIRED = "orig.ocsp.required"; + + + if (thisBranch.getBoolPref("enabled")) { + // Restore original OCSP settings. TODO: What if user manually edits + // these while HTTP Nowhere is enabled? + let origOcspRequired = thisBranch.getBoolPref(ORIG_OCSP_REQUIRED); + securityBranch.setBoolPref(OCSP_REQUIRED, origOcspRequired); + + thisBranch.setBoolPref("enabled", false); + this.httpNowhereEnabled = false; + } else { + // Save original OCSP settings in HTTP Nowhere preferences branch. + let origOcspRequired = securityBranch.getBoolPref(OCSP_REQUIRED); + thisBranch.setBoolPref(ORIG_OCSP_REQUIRED, origOcspRequired); + + // Disable OCSP enforcement + securityBranch.setBoolPref(OCSP_REQUIRED, false); + + thisBranch.setBoolPref("enabled", true); + this.httpNowhereEnabled = true; + } } }; diff --git a/data/extensions/https-everywhere@eff.org/components/ssl-observatory.js b/data/extensions/https-everywhere@eff.org/components/ssl-observatory.js index 7b301d1..15df1db 100644 --- a/data/extensions/https-everywhere@eff.org/components/ssl-observatory.js +++ b/data/extensions/https-everywhere@eff.org/components/ssl-observatory.js @@ -5,7 +5,6 @@ const Cr = Components.results; const CI = Components.interfaces; const CC = Components.classes; const CR = Components.results; -const CU = Components.utils; // Log levels VERB=1; @@ -15,12 +14,12 @@ NOTE=4; WARN=5; BASE_REQ_SIZE=4096; +TIMEOUT = 60000; MAX_OUTSTANDING = 20; // Max # submission XHRs in progress MAX_DELAYED = 32; // Max # XHRs are waiting around to be sent or retried -TIMEOUT = 60000; ASN_PRIVATE = -1; // Do not record the ASN this cert was seen on -ASN_IMPLICIT = -2; // ASN can be learned from connecting IP +ASN_IMPLICIT = -2 // ASN can be learned from connecting IP ASN_UNKNOWABLE = -3; // Cert was seen in the absence of [trustworthy] Internet access // XXX: We should make the _observatory tree relative. @@ -52,7 +51,7 @@ const INCLUDE = function(name) { dump("INCLUDE " + name + ": " + e + "\n"); } } -}; +} INCLUDE('Root-CAs'); INCLUDE('sha256'); @@ -72,10 +71,6 @@ function SSLObservatory() { this.torbutton_installed = false; } - this.HTTPSEverywhere = CC["@eff.org/https-everywhere;1"] - .getService(Components.interfaces.nsISupports) - .wrappedJSObject; - /* The proxy test result starts out null until the test is attempted. * This is for UI notification purposes */ this.proxy_test_successful = null; @@ -89,6 +84,7 @@ function SSLObservatory() { // Clear these on cookies-cleared observer event this.already_submitted = {}; this.delayed_submissions = {}; + OS.addObserver(this, "cookie-changed", false); // Figure out the url to submit to this.submit_host = null; @@ -97,32 +93,14 @@ function SSLObservatory() { // Used to track current number of pending requests to the server this.current_outstanding_requests = 0; - // We can't always know private browsing state per request, sometimes - // we have to guess based on what we've seen in the past - this.everSeenPrivateBrowsing = false; - // Generate nonce to append to url, to catch in nsIProtocolProxyFilter // and to protect against CSRF this.csrf_nonce = "#"+Math.random().toString()+Math.random().toString(); this.compatJSON = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON); - var pref_service = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranchInternal); - var branch = pref_service.QueryInterface(Components.interfaces.nsIPrefBranchInternal); - - branch.addObserver("extensions.https_everywhere._observatory.enabled", - this, false); - - if (this.myGetBoolPref("enabled")) { - OS.addObserver(this, "cookie-changed", false); - OS.addObserver(this, "http-on-examine-response", false); - - var dls = CC['@mozilla.org/docloaderservice;1'] - .getService(CI.nsIWebProgress); - dls.addProgressListener(this, - Ci.nsIWebProgress.NOTIFY_STATE_REQUEST); - } + // Register observer + OS.addObserver(this, "http-on-examine-response", false); // Register protocolproxyfilter this.pps = CC["@mozilla.org/network/protocol-proxy-service;1"] @@ -152,9 +130,7 @@ SSLObservatory.prototype = { [ CI.nsIObserver, CI.nsIProtocolProxyFilter, //CI.nsIWifiListener, - CI.nsIWebProgressListener, - CI.nsISupportsWeakReference, - CI.nsIInterfaceRequestor]), + CI.nsIBadCertListener2]), wrappedJSObject: null, // Initialized by constructor @@ -164,7 +140,7 @@ SSLObservatory.prototype = { contractID: SERVICE_CTRID, // https://developer.mozilla.org/En/How_to_check_the_security_state_of_an_XMLHTTPRequest_over_SSL - getSSLCertChain: function(channel) { + getSSLCert: function(channel) { try { // Do we have a valid channel argument? if (!channel instanceof Ci.nsIChannel) { @@ -314,29 +290,6 @@ SSLObservatory.prototype = { return (cert.md5Fingerprint+cert.sha1Fingerprint).replace(":", "", "g"); }, - // onSecurity is used to listen for bad cert warnings - // There is also onSecurityStateChange, but it does not handle subdocuments. See git - // history for an implementation stub. - onStateChange: function(aProgress, aRequest, aState, aStatus) { - if (!aRequest) return; - var chan = null; - try { - chan = aRequest.QueryInterface(Ci.nsIHttpChannel); - } catch(e) { - return; - } - if (chan) { - if (!this.observatoryActive(chan)) return; - var certchain = this.getSSLCertChain(chan); - if (certchain) { - this.log(INFO, "Got state cert chain for " - + chan.originalURI.spec + "->" + chan.URI.spec + ", state: " + aState); - var warning = true; - this.submitCertChainForChannel(certchain, chan, warning); - } - } - }, - observe: function(subject, topic, data) { if (topic == "cookie-changed" && data == "cleared") { this.already_submitted = {}; @@ -345,13 +298,16 @@ SSLObservatory.prototype = { return; } - if ("http-on-examine-response" == topic) { - var channel = subject; - if (!this.observatoryActive(channel)) return; - - var certchain = this.getSSLCertChain(subject); - var warning = false; - this.submitCertChainForChannel(certchain, channel, warning); + if (topic == "nsPref:changed") { + // XXX: We somehow need to only call this once. Right now, we'll make + // like 3 calls to getClientASN().. The only thing I can think + // of is a timer... + if (data == "network.proxy.ssl" || data == "network.proxy.ssl_port" || + data == "network.proxy.socks" || data == "network.proxy.socks_port") { + this.log(INFO, "Proxy settings have changed. Getting new ASN"); + this.getClientASN(); + } + return; } if (topic == "network:offline-status-changed" && data == "online") { @@ -360,98 +316,55 @@ SSLObservatory.prototype = { return; } - if (topic == "nsPref:changed") { - // If the user toggles the SSL Observatory settings, we need to add or remove - // our observers - switch (data) { - case "network.proxy.ssl": - case "network.proxy.ssl_port": - case "network.proxy.socks": - case "network.proxy.socks_port": - // XXX: We somehow need to only call this once. Right now, we'll make - // like 3 calls to getClientASN().. The only thing I can think - // of is a timer... - this.log(INFO, "Proxy settings have changed. Getting new ASN"); - this.getClientASN(); - break; - case "extensions.https_everywhere._observatory.enabled": - if (this.myGetBoolPref("enabled")) { - this.pps.registerFilter(this, 0); - OS.addObserver(this, "cookie-changed", false); - OS.addObserver(this, "http-on-examine-response", false); - - var dls = CC['@mozilla.org/docloaderservice;1'] - .getService(CI.nsIWebProgress); - dls.addProgressListener(this, - Ci.nsIWebProgress.NOTIFY_STATE_REQUEST); - this.log(INFO,"SSL Observatory is now enabled via pref change!"); - } else { - try { - this.pps.unregisterFilter(this); - OS.removeObserver(this, "cookie-changed"); - OS.removeObserver(this, "http-on-examine-response"); - - var dls = CC['@mozilla.org/docloaderservice;1'] - .getService(CI.nsIWebProgress); - dls.removeProgressListener(this); - this.log(INFO,"SSL Observatory is now disabled via pref change!"); - } catch(e) { - this.log(WARN, "Removing SSL Observatory observers failed: "+e); - } - } - break; - } - return; - } - - }, + if ("http-on-examine-response" == topic) { - submitCertChainForChannel: function(certchain, channel, warning) { - if (!certchain) { - return; - } - var host_ip = "-1"; - var httpchannelinternal = channel.QueryInterface(Ci.nsIHttpChannelInternal); - try { - host_ip = httpchannelinternal.remoteAddress; - } catch(e) { - this.log(INFO, "Could not get server IP address."); - } + if (!this.observatoryActive()) return; - channel.QueryInterface(Ci.nsIHttpChannel); - var chainEnum = certchain.getChain(); - var chainArray = []; - var chainArrayFpStr = ''; - var fps = []; - for(var i = 0; i < chainEnum.length; i++) { - var cert = chainEnum.queryElementAt(i, Ci.nsIX509Cert); - chainArray.push(cert); - var fp = this.ourFingerprint(cert); - fps.push(fp); - chainArrayFpStr = chainArrayFpStr + fp; - } - var chain_hash = sha256_digest(chainArrayFpStr).toUpperCase(); - this.log(INFO, "SHA-256 hash of cert chain for "+new String(channel.URI.host)+" is "+ chain_hash); + var host_ip = "-1"; + var httpchannelinternal = subject.QueryInterface(Ci.nsIHttpChannelInternal); + try { + host_ip = httpchannelinternal.remoteAddress; + } catch(e) { + this.log(INFO, "Could not get server IP address."); + } + subject.QueryInterface(Ci.nsIHttpChannel); + var certchain = this.getSSLCert(subject); + if (certchain) { + var chainEnum = certchain.getChain(); + var chainArray = []; + var chainArrayFpStr = ''; + var fps = []; + for(var i = 0; i < chainEnum.length; i++) { + var cert = chainEnum.queryElementAt(i, Ci.nsIX509Cert); + chainArray.push(cert); + var fp = this.ourFingerprint(cert); + fps.push(fp); + chainArrayFpStr = chainArrayFpStr + fp; + } + var chain_hash = sha256_digest(chainArrayFpStr).toUpperCase(); + this.log(INFO, "SHA-256 hash of cert chain for "+new String(subject.URI.host)+" is "+ chain_hash); - if(!this.myGetBoolPref("use_whitelist")) { - this.log(WARN, "Not using whitelist to filter cert chains."); - } - else if (this.isChainWhitelisted(chain_hash)) { - this.log(INFO, "This cert chain is whitelisted. Not submitting."); - return; - } - else { - this.log(INFO, "Cert chain is NOT whitelisted. Proceeding with submission."); - } + if(!this.myGetBoolPref("use_whitelist")) { + this.log(WARN, "Not using whitelist to filter cert chains."); + } + else if (this.isChainWhitelisted(chain_hash)) { + this.log(INFO, "This cert chain is whitelisted. Not submitting."); + return; + } + else { + this.log(INFO, "Cert chain is NOT whitelisted. Proceeding with submission."); + } - if (channel.URI.port == -1) { - this.submitChainArray(chainArray, fps, new String(channel.URI.host), channel, host_ip, warning, false); - } else { - this.submitChainArray(chainArray, fps, channel.URI.host+":"+channel.URI.port, channel, host_ip, warning, false); + if (subject.URI.port == -1) { + this.submitChain(chainArray, fps, new String(subject.URI.host), subject, host_ip, false); + } else { + this.submitChain(chainArray, fps, subject.URI.host+":"+subject.URI.port, subject, host_ip, false); + } + } } }, - observatoryActive: function(channel) { + observatoryActive: function() { if (!this.myGetBoolPref("enabled")) return false; @@ -477,43 +390,14 @@ SSLObservatory.prototype = { // submit certs without strong anonymisation. Because the // anonymisation is weak, we avoid submitting during private browsing // mode. - var pbm = this.inPrivateBrowsingMode(channel); - this.log(DBUG, "Private browsing mode: " + pbm); - return !pbm; - } - }, - - inPrivateBrowsingMode: function(channel) { - // In classic firefox fashion, there are multiple versions of this API - // https://developer.mozilla.org/EN/docs/Supporting_per-window_private_browsing - try { - // Firefox 20+, this state is per-window; - // should raise an exception on FF < 20 - CU.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); - if (!(channel instanceof CI.nsIHttpChannel)) { - this.log(NOTE, "observatoryActive() without a channel"); - // This is a windowless request. We cannot tell if private browsing - // applies. Conservatively, if we have ever seen PBM, it might be - // active now - return this.everSeenPrivateBrowsing; - } - var win = this.HTTPSEverywhere.getWindowForChannel(channel); - if (!win) return this.everSeenPrivateBrowsing; // windowless request - - if (PrivateBrowsingUtils.isWindowPrivate(win)) { - this.everSeenPrivateBrowsing = true; - return true; - } - } catch (e) { - // Firefox < 20, this state is global try { var pbs = CC["@mozilla.org/privatebrowsing;1"].getService(CI.nsIPrivateBrowsingService); - if (pbs.privateBrowsingEnabled) { - this.everSeenPrivateBrowsing = true; - return true; - } - } catch (e) { /* seamonkey or very old firefox */ } + if (pbs.privateBrowsingEnabled) return false; + } catch (e) { /* seamonkey or old firefox */ } + + return true; } + return false; }, @@ -621,7 +505,7 @@ SSLObservatory.prototype = { shouldSubmit: function(chain, domain) { // Return true if we should submit this chain to the SSL Observatory var rootidx = this.findRootInChain(chain.certArray); - var ss = false; // ss: self-signed + var ss= false; if (chain.leaf.issuerName == chain.leaf.subjectName) ss = true; @@ -652,7 +536,7 @@ SSLObservatory.prototype = { return true; }, - submitChainArray: function(certArray, fps, domain, channel, host_ip, warning, resubmitting) { + submitChain: function(certArray, fps, domain, channel, host_ip, resubmitting) { var base64Certs = []; // Put all this chain data in one object so that it can be modified by // subroutines if required @@ -669,7 +553,7 @@ SSLObservatory.prototype = { if (Object.keys(this.delayed_submissions).length < MAX_DELAYED) if (!(c.fps[0] in this.delayed_submissions)) { this.log(WARN, "Planning to retry submission..."); - let retry = function() { this.submitChainArray(certArray, fps, domain, channel, host_ip, warning, true); }; + let retry = function() { this.submitChain(certArray, fps, domain, channel, host_ip, true); }; this.delayed_submissions[c.fps[0]] = retry; } return; @@ -696,20 +580,16 @@ SSLObservatory.prototype = { if (resubmitting) { reqParams.push("client_asn="+ASN_UNKNOWABLE); - } else { + } + else { reqParams.push("client_asn="+this.client_asn); } if (this.myGetBoolPref("priv_dns")) { reqParams.push("private_opt_in=1"); - } else { - reqParams.push("private_opt_in=0"); } - - if (warning) { - reqParams.push("browser_warning=1"); - } else { - reqParams.push("browser_warning=0"); + else { + reqParams.push("private_opt_in=0"); } var params = reqParams.join("&") + "&padding=0"; @@ -728,7 +608,10 @@ SSLObservatory.prototype = { var that = this; // We have neither SSLObservatory nor this in scope in the lambda - var win = channel ? this.HTTPSEverywhere.getWindowForChannel(channel) : null; + var HTTPSEverywhere = CC["@eff.org/https-everywhere;1"] + .getService(Components.interfaces.nsISupports) + .wrappedJSObject; + var win = channel ? HTTPSEverywhere.getWindowForChannel(channel) : null; var req = this.buildRequest(params); req.timeout = TIMEOUT; @@ -775,7 +658,7 @@ SSLObservatory.prototype = { if (Object.keys(that.delayed_submissions).length < MAX_DELAYED) if (!(c.fps[0] in that.delayed_submissions)) { that.log(WARN, "Planning to retry submission..."); - let retry = function() { that.submitChainArray(certArray, fps, domain, channel, host_ip, warning, true); }; + let retry = function() { that.submitChain(certArray, fps, domain, channel, host_ip, true); }; that.delayed_submissions[c.fps[0]] = retry; } @@ -857,7 +740,6 @@ SSLObservatory.prototype = { if(req.status == 200) { if(!req.responseXML) { that.log(INFO, "Tor check failed: No XML returned by check service."); - that.proxyTestFinished(); return; } @@ -882,7 +764,6 @@ SSLObservatory.prototype = { that.proxy_test_callback(that.proxy_test_successful); that.proxy_test_callback = null; } - that.proxyTestFinished(); } }; req.send(null); @@ -896,13 +777,6 @@ SSLObservatory.prototype = { this.proxy_test_callback(this.proxy_test_successful); this.proxy_test_callback = null; } - that.proxyTestFinished(); - } - }, - - proxyTestFinished: function() { - if (!this.myGetBoolPref("enabled")) { - this.pps.unregisterFilter(this); } }, diff --git a/data/extensions/https-everywhere@eff.org/defaults/preferences/preferences.js b/data/extensions/https-everywhere@eff.org/defaults/preferences/preferences.js index 205bf8d..a8cc052 100644 --- a/data/extensions/https-everywhere@eff.org/defaults/preferences/preferences.js +++ b/data/extensions/https-everywhere@eff.org/defaults/preferences/preferences.js @@ -15,6 +15,10 @@ pref("extensions.https_everywhere.performance_tests", false); // enable rulesets that trigger mixed content blocking pref("extensions.https_everywhere.enable_mixed_rulesets", false); +// HTTP Nowhere preferences +pref("extensions.https_everywhere.http_nowhere.enabled", false); +pref("extensions.https_everywhere.http_nowhere.orig.ocsp.required", false); + // SSl Observatory preferences pref("extensions.https_everywhere._observatory.enabled",false); @@ -31,8 +35,7 @@ pref("extensions.https_everywhere._observatory.submit_during_nontor",true); pref("extensions.https_everywhere._observatory.cache_submitted",true); pref("extensions.https_everywhere._observatory.use_custom_proxy",false); -pref("extensions.https_everywhere._observatory.popup_shown",true); -pref("extensions.https_everywhere.toolbar_hint_shown",true); +pref("extensions.https_everywhere._observatory.popup_shown",false); pref("extensions.https_everywhere._observatory.proxy_host",""); pref("extensions.https_everywhere._observatory.proxy_port",0); pref("extensions.https_everywhere._observatory.proxy_type","direct"); @@ -43,3 +46,7 @@ pref("extensions.https_everywhere._observatory.priv_dns",false); pref("extensions.https_everywhere._observatory.send_asn",true); pref("extensions.https_everywhere._observatory.use_whitelist",true); pref("extensions.https_everywhere._observatory.clean_config",false); + +// Icecat integration +pref("extensions.https_everywhere._observatory.popup_shown",true); +pref("extensions.https_everywhere.toolbar_hint_shown",true); diff --git a/data/extensions/https-everywhere@eff.org/defaults/rulesets.sqlite b/data/extensions/https-everywhere@eff.org/defaults/rulesets.sqlite index 6141547..c8e52c7 100644 Binary files a/data/extensions/https-everywhere@eff.org/defaults/rulesets.sqlite and b/data/extensions/https-everywhere@eff.org/defaults/rulesets.sqlite differ diff --git a/data/extensions/https-everywhere@eff.org/install.rdf b/data/extensions/https-everywhere@eff.org/install.rdf index ddb6e14..af8bea3 100644 --- a/data/extensions/https-everywhere@eff.org/install.rdf +++ b/data/extensions/https-everywhere@eff.org/install.rdf @@ -4,11 +4,12 @@ HTTPS-Everywhere - Mike Perry & Peter Eckersley + Mike Perry, Peter Eckersley, & Yan Zhu chrome://https-everywhere/content/about.xul https-everywhere@eff.org + 2 Encrypt the Web! Automatically use HTTPS security on many sites. - 3.5.1 + 4.0.2 https://www.eff.org/https-everywhere chrome://https-everywhere/content/meta-preferences.xul chrome://https-everywhere/skin/https-everywhere.png @@ -16,11 +17,12 @@ true MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbqOzQb2eyW15YFjDDEMI0ZOzt8f504obNs920lDnpPD2/KqgsfjOgw2K7xWDJIj/18xUvWPk3LDkrnokNiRkA3KOx3W6fHycKL+zID7zy+xZYBuh2fLyQtWV1VGQ45iNRp9+Zo7rH86cdfgkdnWTlNSHyTLW9NbXvyv/E12bppPcEvgCTAQXgnDVJ0/sqmeiijn9tTFh03aM+R2V/21h8aTraAS24qiPCz6gkmYGC8yr6mglcnNoYbsLNYZ69zF1XHcXPduCPdPdfLlzVlKK1/U7hkA28eG3BIAMh6uJYBRJTpiGgaGdPd7YekUB8S6cy+CQIDAQAB + {ec8030f7-c20a-464f-9b0e-13a3a9e97384} - 20 - 32.* + 20.0 + 37.0 @@ -28,15 +30,15 @@ {92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a} 2.17 - 3.* + 2.32 - - - + + + {3550f703-e582-4d05-9a08-453d09bdfdc6} - 17.0.5 - 32 + 17.* + 35.* @@ -47,5 +49,13 @@ 99.* + + + + {aa3c5121-dab2-40e2-81ca-7ea25febc110} + 21.0 + 35.0 + + -- cgit v1.2.3