Bug 1456051 - Make cert an ES module. r?maja_zf draft
authorAndreas Tolfsen <ato@sny.no>
Mon, 23 Apr 2018 10:01:40 +0100
changeset 786576 1a1068207e544a6cb30ce70d2cefb021f2c645e9
parent 786521 d8ead6865f09b9eb1300eefcbf88cddc563bd2a1
child 786577 1f1ff8292e2d36cc67e02f78b868a0da55e7f66b
push id107527
push userbmo:ato@sny.no
push dateMon, 23 Apr 2018 16:11:29 +0000
reviewersmaja_zf
bugs1456051
milestone61.0a1
Bug 1456051 - Make cert an ES module. r?maja_zf In addition to the way symbols are exposed, this patch makes a few changes to what is exposed. Unexposing currentOverride and the error override bitmasks should not cause any problems. MozReview-Commit-ID: 9CWZHVyAKbg
testing/marionette/cert.js
testing/marionette/doc/internals/cert.rst
testing/marionette/driver.js
--- a/testing/marionette/cert.js
+++ b/testing/marionette/cert.js
@@ -2,118 +2,104 @@
  * 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";
 
 ChromeUtils.import("resource://gre/modules/Preferences.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 
-this.EXPORTED_SYMBOLS = ["cert"];
+this.EXPORTED_SYMBOLS = [
+  "CertificateOverrideManager",
+  "InsecureSweepingOverride",
+];
 
 const registrar =
     Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
 const sss = Cc["@mozilla.org/ssservice;1"]
     .getService(Ci.nsISiteSecurityService);
 
+const CERT_PINNING_ENFORCEMENT_PREF = "security.cert_pinning.enforcement_level";
+const CID = Components.ID("{4b67cce0-a51c-11e6-9598-0800200c9a66}");
 const CONTRACT_ID = "@mozilla.org/security/certoverride;1";
-const CERT_PINNING_ENFORCEMENT_PREF =
-    "security.cert_pinning.enforcement_level";
-const HSTS_PRELOAD_LIST_PREF =
-    "network.stricttransportsecurity.preloadlist";
+const DESC = "All-encompassing cert service that matches on a bitflag";
+const HSTS_PRELOAD_LIST_PREF = "network.stricttransportsecurity.preloadlist";
 
-/**
- * TLS certificate service override management for Marionette.
- *
- * @namespace
- */
-this.cert = {
-  Error: {
-    Untrusted: 1,
-    Mismatch: 2,
-    Time: 4,
-  },
-
-  currentOverride: null,
+const Error = {
+  Untrusted: 1,
+  Mismatch: 2,
+  Time: 4,
 };
 
-/**
- * Installs a TLS certificate service override.
- *
- * The provided |service| must implement the |register| and |unregister|
- * functions that causes a new |nsICertOverrideService| interface
- * implementation to be registered with the |nsIComponentRegistrar|.
- *
- * After |service| is registered and made the |cert.currentOverride|,
- * |nsICertOverrideService| is reinitialised to cause all Gecko components
- * to pick up the new service.
- *
- * If an override is already installed, i.e. when |cert.currentOverride|
- * is not null, this functions acts as a NOOP.
- *
- * @param {cert.Override} service
- *     Service generator that registers and unregisters the XPCOM service.
- *
- * @throws {Components.Exception}
- *     If unable to register or initialise |service|.
- */
-cert.installOverride = function(service) {
-  if (this.currentOverride) {
-    return;
+let currentOverride = null;
+
+/** TLS certificate service override management for Marionette. */
+class CertificateOverrideManager {
+  /**
+   * Installs a TLS certificate service override.
+   *
+   * The provided `service` must implement the `register` and `unregister`
+   * functions that causes a new `nsICertOverrideService` interface
+   * implementation to be registered with the `nsIComponentRegistrar`.
+   *
+   * After `service` is registered, `nsICertOverrideService` is
+   * reinitialised to cause all Gecko components to pick up the
+   * new service.
+   *
+   * If an override is already installed this functions acts as a no-op.
+   *
+   * @param {cert.Override} service
+   *     Service generator that registers and unregisters the XPCOM service.
+   *
+   * @throws {Components.Exception}
+   *     If unable to register or initialise `service`.
+   */
+  static install(service) {
+    if (currentOverride) {
+      return;
+    }
+
+    service.register();
+    currentOverride = service;
   }
 
-  service.register();
-  cert.currentOverride = service;
-};
-
-/**
- * Uninstall a TLS certificate service override.
- *
- * After the service has been unregistered, |cert.currentOverride|
- * is reset to null.
- *
- * If there no current override installed, i.e. if |cert.currentOverride|
- * is null, this function acts as a NOOP.
- */
-cert.uninstallOverride = function() {
-  if (!cert.currentOverride) {
-    return;
+  /**
+   * Uninstall a TLS certificate service override.
+   *
+   * If there is no current override installed this function acts
+   * as a no-op.
+   */
+  static uninstall() {
+    if (!currentOverride) {
+      return;
+    }
+    currentOverride.unregister();
+    currentOverride = null;
   }
-  cert.currentOverride.unregister();
-  this.currentOverride = null;
-};
+}
+this.CertificateOverrideManager = CertificateOverrideManager;
 
 /**
  * Certificate override service that acts in an all-inclusive manner
  * on TLS certificates.
  *
- * When an invalid certificate is encountered, it is overriden
- * with the |matching| bit level, which is typically a combination of
- * |cert.Error.Untrusted|, |cert.Error.Mismatch|, and |cert.Error.Time|.
- *
- * @type cert.Override
- *
  * @throws {Components.Exception}
  *     If there are any problems registering the service.
  */
-cert.InsecureSweepingOverride = function() {
-  const CID = Components.ID("{4b67cce0-a51c-11e6-9598-0800200c9a66}");
-  const DESC = "All-encompassing cert service that matches on a bitflag";
-
+function InsecureSweepingOverride() {
   // This needs to be an old-style class with a function constructor
   // and prototype assignment because... XPCOM.  Any attempt at
   // modernisation will be met with cryptic error messages which will
   // make your life miserable.
   let service = function() {};
   service.prototype = {
     hasMatchingOverride(
         aHostName, aPort, aCert, aOverrideBits, aIsTemporary) {
       aIsTemporary.value = false;
-      aOverrideBits.value =
-          cert.Error.Untrusted | cert.Error.Mismatch | cert.Error.Time;
+      aOverrideBits.value = Error.Untrusted | Error.Mismatch | Error.Time;
 
       return true;
     },
 
     QueryInterface: XPCOMUtils.generateQI([Ci.nsICertOverrideService]),
   };
   let factory = XPCOMUtils.generateSingletonFactory(service);
 
@@ -134,9 +120,10 @@ cert.InsecureSweepingOverride = function
       Preferences.reset(CERT_PINNING_ENFORCEMENT_PREF);
 
       // clear collected HSTS and HPKP state
       // through the site security service
       sss.clearAll();
       sss.clearPreloads();
     },
   };
-};
+}
+this.InsecureSweepingOverride = InsecureSweepingOverride;
--- a/testing/marionette/doc/internals/cert.rst
+++ b/testing/marionette/doc/internals/cert.rst
@@ -1,4 +1,12 @@
 cert module
 ===========
-.. js:autoclass:: cert
+
+CertificateOverrideManager
+--------------------------
+.. js:autoclass:: CertificateOverrideManager
   :members:
+
+InsecureSweepingOverride
+------------------------
+.. js:autoclass:: InsecureSweepingOverride
+  :members:
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -15,17 +15,20 @@ const {Addon} = ChromeUtils.import("chro
 ChromeUtils.import("chrome://marionette/content/assert.js");
 ChromeUtils.import("chrome://marionette/content/atom.js");
 const {
   browser,
   Context,
   WindowState,
 } = ChromeUtils.import("chrome://marionette/content/browser.js", {});
 ChromeUtils.import("chrome://marionette/content/capture.js");
-ChromeUtils.import("chrome://marionette/content/cert.js");
+const {
+  CertificateOverrideManager,
+  InsecureSweepingOverride,
+} = ChromeUtils.import("chrome://marionette/content/cert.js", {});
 ChromeUtils.import("chrome://marionette/content/cookie.js");
 const {
   ChromeWebElement,
   element,
   WebElement,
 } = ChromeUtils.import("chrome://marionette/content/element.js", {});
 const {
   InsecureCertificateError,
@@ -687,18 +690,18 @@ GeckoDriver.prototype.newSession = async
   }
   this.sessionID = WebElement.generateUUID();
 
   try {
     this.capabilities = session.Capabilities.fromJSON(cmd.parameters);
 
     if (!this.secureTLS) {
       logger.warn("TLS certificate errors will be ignored for this session");
-      let acceptAllCerts = new cert.InsecureSweepingOverride();
-      cert.installOverride(acceptAllCerts);
+      let acceptAllCerts = new InsecureSweepingOverride();
+      CertificateOverrideManager.install(acceptAllCerts);
     }
 
     if (this.proxy.init()) {
       logger.info("Proxy settings initialised: " + JSON.stringify(this.proxy));
     }
   } catch (e) {
     throw new SessionNotCreatedError(e);
   }
@@ -2810,17 +2813,17 @@ GeckoDriver.prototype.deleteSession = fu
       Services.obs.removeObserver(this.observing[topic], topic);
     }
     this.observing = null;
   }
 
   modal.removeHandler(this.dialogHandler);
 
   this.sandboxes.clear();
-  cert.uninstallOverride();
+  CertificateOverrideManager.uninstall();
 
   this.sessionID = null;
   this.capabilities = new session.Capabilities();
 };
 
 /**
  * Takes a screenshot of a web element, current frame, or viewport.
  *