From 60d0ba74292ea642b90cf2ea3e9d33dc6838ac0e Mon Sep 17 00:00:00 2001 From: Dana Keeler Date: Wed, 6 Mar 2019 20:46:32 +0000 Subject: [PATCH] bug 1531924 - remove unnecessary nsIBadCertListener2 in Firefox for Android and improve adding certificate error overrides r=snorp Before this patch, Firefox for Android (and GeckoView) would make an extra (unnecessary) XHR to gather the information it needed to add a certificate error override. However, the docShell already has the required information (via failedChannel.securityInfo), so this patch makes it so. Differential Revision: https://phabricator.services.mozilla.com/D21791 --HG-- extra : moz-landing-system : lando --- mobile/android/chrome/content/browser.js | 34 +++--- .../chrome/geckoview/ErrorPageEventHandler.js | 37 +++--- mobile/android/modules/SSLExceptions.jsm | 113 ------------------ mobile/android/modules/moz.build | 1 - 4 files changed, 42 insertions(+), 143 deletions(-) delete mode 100644 mobile/android/modules/SSLExceptions.jsm diff --git a/mobile/android/chrome/content/browser.js b/mobile/android/chrome/content/browser.js index 772597e4ce77..7d664fda20cc 100644 --- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -59,9 +59,6 @@ ChromeUtils.defineModuleGetter(this, "Prompt", ChromeUtils.defineModuleGetter(this, "HelperApps", "resource://gre/modules/HelperApps.jsm"); -ChromeUtils.defineModuleGetter(this, "SSLExceptions", - "resource://gre/modules/SSLExceptions.jsm"); - ChromeUtils.defineModuleGetter(this, "FormHistory", "resource://gre/modules/FormHistory.jsm"); @@ -5048,18 +5045,27 @@ var ErrorPageEventHandler = { let temp = errorDoc.getElementById("temporaryExceptionButton"); if (target == temp || target == perm) { // Handle setting an cert exception and reloading the page - try { - // Add a new SSL exception for this URL - let uri = Services.io.newURI(errorDoc.location.href); - let sslExceptions = new SSLExceptions(); - - if (target == perm) - sslExceptions.addPermanentException(uri, errorDoc.defaultView); - else - sslExceptions.addTemporaryException(uri, errorDoc.defaultView); - } catch (e) { - dump("Failed to set cert exception: " + e + "\n"); + let uri = Services.io.newURI(errorDoc.location.href); + let docShell = BrowserApp.selectedBrowser.docShell; + let securityInfo = docShell.failedChannel.securityInfo; + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + let cert = securityInfo.serverCert; + let overrideService = Cc["@mozilla.org/security/certoverride;1"] + .getService(Ci.nsICertOverrideService); + let flags = 0; + if (securityInfo.isUntrusted) { + flags |= overrideService.ERROR_UNTRUSTED; } + if (securityInfo.isDomainMismatch) { + flags |= overrideService.ERROR_MISMATCH; + } + if (securityInfo.isNotValidAtThisTime) { + flags |= overrideService.ERROR_TIME; + } + let temporary = (target == temp) || + PrivateBrowsingUtils.isWindowPrivate(errorDoc.defaultView); + overrideService.rememberValidityOverride(uri.asciiHost, uri.port, cert, flags, + temporary); errorDoc.location.reload(); } else if (target == errorDoc.getElementById("getMeOutOfHereButton")) { errorDoc.location = "about:home"; diff --git a/mobile/android/chrome/geckoview/ErrorPageEventHandler.js b/mobile/android/chrome/geckoview/ErrorPageEventHandler.js index ee550e59a597..ee12caf85afb 100644 --- a/mobile/android/chrome/geckoview/ErrorPageEventHandler.js +++ b/mobile/android/chrome/geckoview/ErrorPageEventHandler.js @@ -4,14 +4,12 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ const {GeckoViewUtils} = ChromeUtils.import("resource://gre/modules/GeckoViewUtils.jsm"); +const {PrivateBrowsingUtils} = ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); const {debug, warn} = GeckoViewUtils.initLogging("ErrorPageEventHandler"); // eslint-disable-line no-unused-vars -ChromeUtils.defineModuleGetter(this, "SSLExceptions", - "resource://gre/modules/SSLExceptions.jsm"); - XPCOMUtils.defineLazyModuleGetters(this, { Services: "resource://gre/modules/Services.jsm", }); @@ -35,19 +33,28 @@ var ErrorPageEventHandler = { let perm = errorDoc.getElementById("permanentExceptionButton"); let temp = errorDoc.getElementById("temporaryExceptionButton"); if (target == temp || target == perm) { - // Handle setting a cert exception and reloading the page - try { - // Add a new SSL exception for this URL - let uri = Services.io.newURI(errorDoc.location.href); - let sslExceptions = new SSLExceptions(); - - if (target == perm) - sslExceptions.addPermanentException(uri, errorDoc.defaultView); - else - sslExceptions.addTemporaryException(uri, errorDoc.defaultView); - } catch (e) { - warn `Failed to set cert exception: ${e}`; + // Handle setting an cert exception and reloading the page + let uri = Services.io.newURI(errorDoc.location.href); + let docShell = BrowserApp.selectedBrowser.docShell; + let securityInfo = docShell.failedChannel.securityInfo; + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + let cert = securityInfo.serverCert; + let overrideService = Cc["@mozilla.org/security/certoverride;1"] + .getService(Ci.nsICertOverrideService); + let flags = 0; + if (securityInfo.isUntrusted) { + flags |= overrideService.ERROR_UNTRUSTED; } + if (securityInfo.isDomainMismatch) { + flags |= overrideService.ERROR_MISMATCH; + } + if (securityInfo.isNotValidAtThisTime) { + flags |= overrideService.ERROR_TIME; + } + let temporary = (target == temp) || + PrivateBrowsingUtils.isWindowPrivate(errorDoc.defaultView); + overrideService.rememberValidityOverride(uri.asciiHost, uri.port, cert, flags, + temporary); errorDoc.location.reload(); } else if (target == errorDoc.getElementById("getMeOutOfHereButton")) { errorDoc.location = "about:home"; diff --git a/mobile/android/modules/SSLExceptions.jsm b/mobile/android/modules/SSLExceptions.jsm deleted file mode 100644 index c2d884e2e280..000000000000 --- a/mobile/android/modules/SSLExceptions.jsm +++ /dev/null @@ -1,113 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -"use strict"; - -const {PrivateBrowsingUtils} = ChromeUtils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); -const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); - -XPCOMUtils.defineLazyGlobalGetters(this, ["XMLHttpRequest"]); - -var EXPORTED_SYMBOLS = ["SSLExceptions"]; - -/** - A class to add exceptions to override SSL certificate problems. The functionality - itself is borrowed from exceptionDialog.js. -*/ -function SSLExceptions() { - this._overrideService = Cc["@mozilla.org/security/certoverride;1"] - .getService(Ci.nsICertOverrideService); -} - - -SSLExceptions.prototype = { - _overrideService: null, - _secInfo: null, - - getInterface: function SSLE_getInterface(aIID) { - return this.QueryInterface(aIID); - }, - QueryInterface: ChromeUtils.generateQI(["nsIBadCertListener2"]), - - /** - To collect the SSL status we intercept the certificate error here - and store the status for later use. - */ - notifyCertProblem: function SSLE_notifyCertProblem(socketInfo, - secInfo, - targetHost) { - this._secInfo = secInfo; - return true; // suppress error UI - }, - - /** - Attempt to download the certificate for the location specified to get the SSLState - for the certificate and the errors. - */ - _checkCert: function SSLE_checkCert(aURI) { - this._secInfo = null; - - let req = new XMLHttpRequest(); - try { - if (aURI) { - req.open("GET", aURI.prePath, false); - req.channel.notificationCallbacks = this; - req.send(null); - } - } catch (e) { - // We *expect* exceptions if there are problems with the certificate - // presented by the site. Log it, just in case, but we can proceed here, - // with appropriate sanity checks - Cu.reportError("Attempted to connect to a site with a bad certificate in the add exception dialog. " + - "This results in a (mostly harmless) exception being thrown. " + - "Logged for information purposes only: " + e); - } - - return this._secInfo; - }, - - /** - Internal method to create an override. - */ - _addOverride: function SSLE_addOverride(aURI, aWindow, aTemporary) { - let secInfo = this._checkCert(aURI); - let certificate = secInfo.serverCert; - - let flags = 0; - - // in private browsing do not store exceptions permanently ever - if (PrivateBrowsingUtils.isWindowPrivate(aWindow)) { - aTemporary = true; - } - - if (secInfo.isUntrusted) - flags |= this._overrideService.ERROR_UNTRUSTED; - if (secInfo.isDomainMismatch) - flags |= this._overrideService.ERROR_MISMATCH; - if (secInfo.isNotValidAtThisTime) - flags |= this._overrideService.ERROR_TIME; - - this._overrideService.rememberValidityOverride( - aURI.asciiHost, - aURI.port, - certificate, - flags, - aTemporary); - }, - - /** - Creates a permanent exception to override all overridable errors for - the given URL. - */ - addPermanentException: function SSLE_addPermanentException(aURI, aWindow) { - this._addOverride(aURI, aWindow, false); - }, - - /** - Creates a temporary exception to override all overridable errors for - the given URL. - */ - addTemporaryException: function SSLE_addTemporaryException(aURI, aWindow) { - this._addOverride(aURI, aWindow, true); - }, -}; diff --git a/mobile/android/modules/moz.build b/mobile/android/modules/moz.build index 2208905283e4..7fb450192c71 100644 --- a/mobile/android/modules/moz.build +++ b/mobile/android/modules/moz.build @@ -42,7 +42,6 @@ EXTRA_JS_MODULES += [ 'SelectHelper.jsm', 'SharedPreferences.jsm', 'Snackbars.jsm', - 'SSLExceptions.jsm', 'WebrtcUI.jsm', 'WebsiteMetadata.jsm' ]