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
This commit is contained in:
Dana Keeler 2019-03-06 20:46:32 +00:00
Родитель 1de0040101
Коммит 60d0ba7429
4 изменённых файлов: 42 добавлений и 143 удалений

Просмотреть файл

@ -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";

Просмотреть файл

@ -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";

Просмотреть файл

@ -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);
},
};

Просмотреть файл

@ -42,7 +42,6 @@ EXTRA_JS_MODULES += [
'SelectHelper.jsm',
'SharedPreferences.jsm',
'Snackbars.jsm',
'SSLExceptions.jsm',
'WebrtcUI.jsm',
'WebsiteMetadata.jsm'
]