bug 1263765 - remove nsIBadCertListener2 implementation from the add certificate exception dialog r=jcj
authorDavid Keeler <dkeeler@mozilla.com>
Thu, 11 Jan 2018 15:25:05 -0800
changeset 453809 d5dd45fa551c84f7e978f0cc862747242cee8297
parent 453808 a1a5efa349c4a213049e2b8fcf4e4a77acb8e1ba
child 453810 45b5309a73cbde68fab5b75168bbeaba076ff238
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcj
bugs1263765
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 1263765 - remove nsIBadCertListener2 implementation from the add certificate exception dialog r=jcj This reworks the certificate-fetching portion of the add certificate exception dialog so as to not require a nsIBadCertListener2 implementation, which is deprecated. The solution is simple: use the onerror/onload callbacks on the XMLHttpRequest object to grab the appropriate information. MozReview-Commit-ID: IjNrNfYA28P
security/manager/pki/resources/content/exceptionDialog.js
--- a/security/manager/pki/resources/content/exceptionDialog.js
+++ b/security/manager/pki/resources/content/exceptionDialog.js
@@ -12,43 +12,16 @@ var gCert;
 var gChecking;
 var gBroken;
 var gNeedReset;
 var gSecHistogram;
 var gNsISecTel;
 
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 
-function badCertListener() {}
-badCertListener.prototype = {
-  getInterface(aIID) {
-    return this.QueryInterface(aIID);
-  },
-  QueryInterface(aIID) {
-    if (aIID.equals(Components.interfaces.nsIBadCertListener2) ||
-        aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
-        aIID.equals(Components.interfaces.nsISupports)) {
-      return this;
-    }
-
-    throw new Error(Components.results.NS_ERROR_NO_INTERFACE);
-  },
-  handle_test_result() {
-    if (gSSLStatus) {
-      gCert = gSSLStatus.QueryInterface(Components.interfaces.nsISSLStatus).serverCert;
-    }
-  },
-  notifyCertProblem: function MSR_notifyCertProblem(socketInfo, sslStatus, targetHost) {
-    gBroken = true;
-    gSSLStatus = sslStatus;
-    this.handle_test_result();
-    return true; // suppress error UI
-  }
-};
-
 function initExceptionDialog() {
   gNeedReset = false;
   gDialog = document.documentElement;
   gBundleBrand = document.getElementById("brand_bundle");
   gPKIBundle = document.getElementById("pippki_bundle");
   gSecHistogram = Services.telemetry.getHistogramById("SECURITY_UI");
   gNsISecTel = Components.interfaces.nsISecurityUITelemetry;
 
@@ -84,54 +57,60 @@ function initExceptionDialog() {
     }
 
     // Set out parameter to false by default
     args[0].exceptionAdded = false;
   }
 }
 
 /**
+ * Helper function for checkCert. Set as the onerror/onload callbacks for an
+ * XMLHttpRequest. Sets gSSLStatus, gCert, gBroken, and gChecking according to
+ * the load information from the request. Probably should not be used directly.
+ *
+ * @param {XMLHttpRequest} req
+ *        The XMLHttpRequest created and sent by checkCert.
+ * @param {Event} evt
+ *        The load or error event.
+ */
+function grabCert(req, evt) {
+  if (req.channel && req.channel.securityInfo) {
+    gSSLStatus = req.channel.securityInfo
+                    .QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
+    gCert = gSSLStatus ? gSSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert
+                       : null;
+  }
+  gBroken = evt.type == "error";
+  gChecking = false;
+  updateCertStatus();
+}
+
+/**
  * Attempt to download the certificate for the location specified, and populate
  * the Certificate Status section with the result.
  */
 function checkCert() {
   gCert = null;
   gSSLStatus = null;
   gChecking = true;
   gBroken = false;
   updateCertStatus();
 
-  var uri = getURI();
+  let uri = getURI();
 
-  var req = new XMLHttpRequest();
-  try {
-    if (uri) {
-      req.open("GET", uri.prePath, false);
-      req.channel.notificationCallbacks = new badCertListener();
-      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
-    Components.utils.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);
-  } finally {
+  if (uri) {
+    let req = new XMLHttpRequest();
+    req.open("GET", uri.prePath);
+    req.onerror = grabCert.bind(this, req);
+    req.onload = grabCert.bind(this, req);
+    req.send(null);
+  } else {
     gChecking = false;
+    updateCertStatus();
   }
-
-  if (req.channel && req.channel.securityInfo) {
-    const Ci = Components.interfaces;
-    gSSLStatus = req.channel.securityInfo
-                    .QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
-    gCert = gSSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
-  }
-
-  updateCertStatus();
 }
 
 /**
  * Build and return a URI, based on the information supplied in the
  * Certificate Location fields
  *
  * @returns {nsIURI}
  *          URI constructed from the information supplied on success, null