Commit 4222e615 authored by henry's avatar henry Committed by Pier Angelo Vendrame
Browse files

fixup! Bug 30237: Add v3 onion services client authentication prompt

Bug 42542: Remove the OnionServicesAuthPrompt class.

The class is merged into OnionAuthPrompt. This currently only works when
only one tab triggers the prompt at a time.

Not linted to improve commit readability.
parent 485671e5
Loading
Loading
Loading
Loading
+36 −56
Original line number Diff line number Diff line
@@ -2,36 +2,20 @@

"use strict";

const OnionAuthPrompt = (function () {
var OnionAuthPrompt = {
  // Only import to our internal scope, rather than the global scope of
  // browser.xhtml.
  const lazy = {};
  ChromeUtils.defineESModuleGetters(lazy, {
    TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
    TorStrings: "resource://gre/modules/TorStrings.sys.mjs",
    CommonUtils: "resource://services-common/utils.sys.mjs",
  });

  // OnionServicesAuthPrompt objects run within the main/chrome process.
  // aReason is the topic passed within the observer notification that is
  // causing this auth prompt to be displayed.
  function OnionServicesAuthPrompt(aBrowser, aFailedURI, aReason, aOnionName) {
    this._browser = aBrowser;
    this._failedURI = aFailedURI;
    this._reasonForPrompt = aReason;
    this._onionHostname = aOnionName;
  }
  _lazy: {},

  const topics = {
  _topics: {
    clientAuthMissing: "tor-onion-services-clientauth-missing",
    clientAuthIncorrect: "tor-onion-services-clientauth-incorrect",
  };
  },

  OnionServicesAuthPrompt.prototype = {
    show(aWarningMessage) {
      let mainAction = {
        label: lazy.TorStrings.onionServices.authPrompt.done,
        accessKey: lazy.TorStrings.onionServices.authPrompt.doneAccessKey,
        label: this.TorStrings.onionServices.authPrompt.done,
        accessKey: this.TorStrings.onionServices.authPrompt.doneAccessKey,
        leaveOpen: true, // Callback is responsible for closing the notification.
        callback: this._onDone.bind(this),
      };
@@ -87,7 +71,7 @@ const OnionAuthPrompt = (function () {
        // string ourselves so we can show the onion name as bold text.
        // We do this by splitting the localized string and creating
        // several HTML <span> elements.
        const fmtString = lazy.TorStrings.onionServices.authPrompt.description;
        const fmtString = this.TorStrings.onionServices.authPrompt.description;
        const [prefix, suffix] = fmtString.split("%S");

        const domainEl = xulDoc.createElement("span");
@@ -106,7 +90,7 @@ const OnionAuthPrompt = (function () {
      if (learnMoreElem) {
        learnMoreElem.setAttribute(
          "value",
          lazy.TorStrings.onionServices.learnMore
          this.TorStrings.onionServices.learnMore
        );
        learnMoreElem.setAttribute(
          "href",
@@ -127,7 +111,7 @@ const OnionAuthPrompt = (function () {
      if (keyElem) {
        keyElem.setAttribute(
          "placeholder",
          lazy.TorStrings.onionServices.authPrompt.keyPlaceholder
          this.TorStrings.onionServices.authPrompt.keyPlaceholder
        );
        this._boundOnKeyFieldKeyPress = this._onKeyFieldKeyPress.bind(this);
        this._boundOnKeyFieldInput = this._onKeyFieldInput.bind(this);
@@ -174,14 +158,14 @@ const OnionAuthPrompt = (function () {

      const base64key = this._keyToBase64(keyElem.value);
      if (!base64key) {
        this._showWarning(lazy.TorStrings.onionServices.authPrompt.invalidKey);
        this._showWarning(this.TorStrings.onionServices.authPrompt.invalidKey);
        return;
      }

      this._prompt.remove();

      const controllerFailureMsg =
        lazy.TorStrings.onionServices.authPrompt.failedToSetKey;
        this.TorStrings.onionServices.authPrompt.failedToSetKey;
      try {
        // ^(subdomain.)*onionserviceid.onion$ (case-insensitive)
        const onionServiceIdRegExp =
@@ -193,7 +177,7 @@ const OnionAuthPrompt = (function () {

        const checkboxElem = this._getCheckboxElement();
        const isPermanent = checkboxElem && checkboxElem.checked;
        const provider = await lazy.TorProviderBuilder.build();
        const provider = await this._lazy.TorProviderBuilder.build();
        await provider.onionAuthAdd(onionServiceId, base64key, isPermanent);
        // Success! Reload the page.
        this._browser.sendMessageToActor("Browser:Reload", {}, "BrowserTab");
@@ -215,7 +199,7 @@ const OnionAuthPrompt = (function () {
      // this authentication prompt.
      const failedURI = this._failedURI.spec;
      const errorCode =
        this._reasonForPrompt === topics.clientAuthMissing
        this._reasonForPrompt === this._topics.clientAuthMissing
          ? Cr.NS_ERROR_TOR_ONION_SVC_MISSING_CLIENT_AUTH
          : Cr.NS_ERROR_TOR_ONION_SVC_BAD_CLIENT_AUTH;
      const io =
@@ -275,7 +259,7 @@ const OnionAuthPrompt = (function () {
        // a tor onion-auth file (which uses lowercase).
        let rawKey;
        try {
          rawKey = lazy.CommonUtils.decodeBase32(aKeyString.toUpperCase());
          rawKey = this._lazy.CommonUtils.decodeBase32(aKeyString.toUpperCase());
        } catch (e) {}

        if (rawKey) {
@@ -295,25 +279,32 @@ const OnionAuthPrompt = (function () {

      return base64key;
    },
  };

  let retval = {
    init() {
      Services.obs.addObserver(this, topics.clientAuthMissing);
      Services.obs.addObserver(this, topics.clientAuthIncorrect);
      const { TorStrings } = ChromeUtils.importESModule(
        "resource://gre/modules/TorStrings.sys.mjs"
      );
      this.TorStrings = TorStrings;
      ChromeUtils.defineESModuleGetters(this._lazy, {
        TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
        CommonUtils: "resource://services-common/utils.sys.mjs",
      });

      Services.obs.addObserver(this, this._topics.clientAuthMissing);
      Services.obs.addObserver(this, this._topics.clientAuthIncorrect);
    },

    uninit() {
      Services.obs.removeObserver(this, topics.clientAuthMissing);
      Services.obs.removeObserver(this, topics.clientAuthIncorrect);
      Services.obs.removeObserver(this, this._topics.clientAuthMissing);
      Services.obs.removeObserver(this, this._topics.clientAuthIncorrect);
    },

    // aSubject is the DOM Window or browser where the prompt should be shown.
    // aData contains the .onion name.
    observe(aSubject, aTopic, aData) {
      if (
        aTopic != topics.clientAuthMissing &&
        aTopic != topics.clientAuthIncorrect
        aTopic != this._topics.clientAuthMissing &&
        aTopic != this._topics.clientAuthIncorrect
      ) {
        return;
      }
@@ -331,21 +322,10 @@ const OnionAuthPrompt = (function () {
      }

      let failedURI = browser.currentURI;
      let authPrompt = new OnionServicesAuthPrompt(
        browser,
        failedURI,
        aTopic,
        aData
      );
      authPrompt.show(undefined);
      this._browser = browser;
      this._failedURI = failedURI;
      this._reasonForPrompt = aTopic;
      this._onionHostname = aData;
      this.show(undefined);
    },
};

  return retval;
})(); /* OnionAuthPrompt */

Object.defineProperty(this, "OnionAuthPrompt", {
  value: OnionAuthPrompt,
  enumerable: true,
  writable: false,
});