bug 1263765 - remove nsIBadCertListener2 implementation from the add certificate exception dialog r?jcj draft
authorDavid Keeler <dkeeler@mozilla.com>
Thu, 11 Jan 2018 15:25:05 -0800
changeset 721163 d4c0782b9b378b4563042a3f1bb162cb2645d152
parent 720975 9be7249e74fd7f6d9163b59d3386ed01038197a0
child 746253 688647c0f5b69ecf5399d21e911990b9a285a8d6
push id95752
push userbmo:dkeeler@mozilla.com
push dateTue, 16 Jan 2018 21:04:42 +0000
reviewersjcj
bugs1263765
milestone59.0a1
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