[tbb-commits] [tor-browser] 81/85: Bug 28005: Implement .onion alias urlbar rewrites

gitolite role git at cupani.torproject.org
Fri Jun 10 17:02:12 UTC 2022


This is an automated email from the git hooks/post-receive script.

pierov pushed a commit to branch tor-browser-91.9.0esr-11.5-2
in repository tor-browser.

commit 0edd5ddc3a36baa95a6ad776d9a029e8ad2167a9
Author: Alex Catarineu <acat at torproject.org>
AuthorDate: Thu Feb 13 13:24:33 2020 +0100

    Bug 28005: Implement .onion alias urlbar rewrites
    
    The old patch to support .tor.onion hosts was implemented through
    HTTPS-Everywhere.
    Now that the extension has been deprecated (or is going to soon), we
    have a new implementation, so we need only the code that interacts with
    HTTPS-Everywhere, which we use to remove all SecureDrop channels,
    rather than adding the 2021 one.
    
    When we stop shipping HTTPS-Everywhere, we will be able to remove this
    patch, and keep only the one for #40458.
---
 .../onionservices/ExtensionMessaging.jsm           |  77 +++++++++++++
 .../onionservices/HttpsEverywhereControl.jsm       | 127 +++++++++++++++++++++
 browser/components/onionservices/moz.build         |   6 +
 3 files changed, 210 insertions(+)

diff --git a/browser/components/onionservices/ExtensionMessaging.jsm b/browser/components/onionservices/ExtensionMessaging.jsm
new file mode 100644
index 0000000000000..c93b8c6edf85b
--- /dev/null
+++ b/browser/components/onionservices/ExtensionMessaging.jsm
@@ -0,0 +1,77 @@
+// Copyright (c) 2020, The Tor Project, Inc.
+
+"use strict";
+
+const EXPORTED_SYMBOLS = ["ExtensionMessaging"];
+
+const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
+const { ExtensionUtils } = ChromeUtils.import(
+  "resource://gre/modules/ExtensionUtils.jsm"
+);
+const { MessageChannel } = ChromeUtils.import(
+  "resource://gre/modules/MessageChannel.jsm"
+);
+const { AddonManager } = ChromeUtils.import(
+  "resource://gre/modules/AddonManager.jsm"
+);
+
+const { XPCOMUtils } = ChromeUtils.import(
+  "resource://gre/modules/XPCOMUtils.jsm"
+);
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  ExtensionParent: "resource://gre/modules/ExtensionParent.jsm",
+});
+
+class ExtensionMessaging {
+  constructor() {
+    this._callback = null;
+    this._handlers = new Map();
+    this._messageManager = Services.cpmm;
+  }
+
+  async sendMessage(message, extensionId) {
+    const addon = await AddonManager.getAddonByID(extensionId);
+    if (!addon) {
+      throw new Error(`extension '${extensionId} does not exist`);
+    }
+    await addon.startupPromise;
+
+    const { torSendExtensionMessage } = ExtensionParent;
+    return torSendExtensionMessage(extensionId, message);
+  }
+
+  unload() {
+    if (this._callback) {
+      this._handlers.clear();
+      this._messageManager.removeMessageListener(
+        "MessageChannel:Response",
+        this._callback
+      );
+      this._callback = null;
+    }
+  }
+
+  _onMessage({ data }) {
+    const channelId = data.messageName;
+    if (this._handlers.has(channelId)) {
+      const { resolve, reject } = this._handlers.get(channelId);
+      this._handlers.delete(channelId);
+      if (data.error) {
+        reject(new Error(data.error.message));
+      } else {
+        resolve(data.value);
+      }
+    }
+  }
+
+  _init() {
+    if (this._callback === null) {
+      this._callback = this._onMessage.bind(this);
+      this._messageManager.addMessageListener(
+        "MessageChannel:Response",
+        this._callback
+      );
+    }
+  }
+}
diff --git a/browser/components/onionservices/HttpsEverywhereControl.jsm b/browser/components/onionservices/HttpsEverywhereControl.jsm
new file mode 100644
index 0000000000000..9e14b7d88b501
--- /dev/null
+++ b/browser/components/onionservices/HttpsEverywhereControl.jsm
@@ -0,0 +1,127 @@
+// Copyright (c) 2020, The Tor Project, Inc.
+
+"use strict";
+
+const EXPORTED_SYMBOLS = ["HttpsEverywhereControl"];
+
+const { ExtensionMessaging } = ChromeUtils.import(
+  "resource:///modules/ExtensionMessaging.jsm"
+);
+const { setTimeout } = ChromeUtils.import("resource://gre/modules/Timer.jsm");
+
+const EXTENSION_ID = "https-everywhere-eff at eff.org";
+const SECUREDROP_TOR_ONION_CHANNEL_2020 = {
+  name: "SecureDropTorOnion",
+  jwk: {
+    kty: "RSA",
+    e: "AQAB",
+    n:
+      "p10BbUVc5Xj2S_-MH3bACNBaISo_r9e3PVPyTTjsGsdg2qSXvqUO42fBtpFAy0zUzIGS83v4JjiRdvKJaZTIvbC8AcpymzdsTqujMm8RPTSy3hO_8mXzGa4DEsIB1uNLnUWRBKXvSGCmT9kFyxhTpkYqokNBzafVihTU34tN2Md1xFHnmZGqfYtPtbJLWAa5Z1M11EyR4lIyUxIiPTV9t1XstDbWr3iS83REJrGEFmjG1-BAgx8_lDUTa41799N2yYEhgZud7bL0M3ei8s5OERjiion5uANkUV3-s2QqUZjiVA-XR_HizXjciaUWNd683KqekpNOZ_0STh_UGwpcwU-KwG07QyiCrLrRpz8S_vH8CqGrrcWY3GSzYe9dp34jJdO65oA-G8tK6fMXtvTCFDZI6oNNaXJH71F5J0YbqO2ZqwKYc2WSi0gKVl2wd9roOVjaBmkJqvocntYuNM7t38fDEWHn5KUkmrTbi [...]
+  },
+  update_path_prefix: "https://securedrop.org/https-everywhere/",
+  scope:
+    "^https?:\\/\\/[a-z0-9-]+(?:\\.[a-z0-9-]+)*\\.securedrop\\.tor\\.onion\\/",
+  replaces_default_rulesets: false,
+};
+
+const SECUREDROP_TOR_ONION_CHANNEL = {
+  name: "SecureDropTorOnion2021",
+  jwk: {
+    kty: "RSA",
+    e: "AQAB",
+    n:
+      "vsC7BNafkRe8Uh1DUgCkv6RbPQMdJgAKKnWdSqQd7tQzU1mXfmo_k1Py_2MYMZXOWmqSZ9iwIYkykZYywJ2VyMGve4byj1sLn6YQoOkG8g5Z3V4y0S2RpEfmYumNjTzfq8nxtLnwjaYd4sCUd5wa0SzeLrpRQuXo2bF3QuUF2xcbLJloxX1MmlsMMCdBc-qGNonLJ7bpn_JuyXlDWy1Fkeyw1qgjiOdiRIbMC1x302zgzX6dSrBrNB8Cpsh-vCE0ZjUo8M9caEv06F6QbYmdGJHM0ZZY34OHMSNdf-_qUKIV_SuxuSuFE99tkAeWnbWpyI1V-xhVo1sc7NzChP8ci2TdPvI3_0JyAuCvL6zIFqJUJkZibEUghhg6F09-oNJKpy7rhUJq7zZyLXJsvuXnn0gnIxfjRvMcDfZAKUVMZKRdw7fwWzwQril4Ib0MQOVda9vb_4JMk7Gup-TUI4sfuS4NKwsnKoODIO-2U [...]
+  },
+  update_path_prefix: "https://securedrop.org/https-everywhere-2021/",
+  scope:
+    "^https?:\\/\\/[a-z0-9-]+(?:\\.[a-z0-9-]+)*\\.securedrop\\.tor\\.onion\\/",
+  replaces_default_rulesets: false,
+};
+
+class HttpsEverywhereControl {
+  constructor() {
+    this._extensionMessaging = null;
+    this._init();
+  }
+
+  async _sendMessage(type, object) {
+    return this._extensionMessaging.sendMessage(
+      {
+        type,
+        object,
+      },
+      EXTENSION_ID
+    );
+  }
+
+  static async wait(seconds = 1) {
+    return new Promise(resolve => setTimeout(resolve, seconds * 1000));
+  }
+
+  /**
+   * Uninstalls old .tor.onion update channels from https-everywhere
+   */
+  async uninstallTorOnionUpdateChannel(retries = 5) {
+
+    // TODO: https-everywhere store is initialized asynchronously, so sending a message
+    // immediately results in a `store.get is undefined` error.
+    // For now, let's wait a bit and retry a few times if there is an error, but perhaps
+    // we could suggest https-everywhere to send a message when that happens and listen
+    // for that here.
+    await HttpsEverywhereControl.wait();
+
+    // We now handle .tor.onion domains with our first-party component, so we
+    // remove known rules from HTTPS-Everywhere.
+
+    try {
+      await this._sendMessage(
+        "delete_update_channel",
+        SECUREDROP_TOR_ONION_CHANNEL_2020.name
+      );
+    } catch (e) {
+      if (retries <= 0) {
+        console.warn("Cannot uninstall the SecureDropTorOnion 2020 channel", e);
+        throw new Error("Could not uninstall the SecureDropTorOnion update channel");
+      }
+      await this.uninstallTorOnionUpdateChannel(retries - 1);
+      return;
+    }
+    try {
+      await this._sendMessage(
+        "delete_update_channel",
+        SECUREDROP_TOR_ONION_CHANNEL.name
+      );
+    } catch (e) {
+      if (retries <= 0) {
+        console.warn("Cannot uninstall the SecureDropTorOnion 2021 channel", e);
+        throw new Error("Could not uninstall the SecureDropTorOnion update channel");
+      }
+      await this.uninstallTorOnionUpdateChannel(retries - 1);
+      return;
+    }
+  }
+
+  _init() {
+    if (!this._extensionMessaging) {
+      this._extensionMessaging = new ExtensionMessaging();
+    }
+
+    // update all of the existing https-everywhere channels
+    setTimeout(async () => {
+      await this.uninstallTorOnionUpdateChannel();
+
+      let pinnedChannels = await this._sendMessage("get_pinned_update_channels");
+      for(let channel of pinnedChannels.update_channels) {
+        this._sendMessage("update_update_channel", channel);
+      }
+
+      let storedChannels = await this._sendMessage("get_stored_update_channels");
+      for(let channel of storedChannels.update_channels) {
+        this._sendMessage("update_update_channel", channel);
+      }
+
+      this._extensionMessaging.unload();
+      this._extensionMessaging = null;
+    }, 0);
+  }
+}
diff --git a/browser/components/onionservices/moz.build b/browser/components/onionservices/moz.build
index 2661ad7cb9f3d..8156853220244 100644
--- a/browser/components/onionservices/moz.build
+++ b/browser/components/onionservices/moz.build
@@ -1 +1,7 @@
 JAR_MANIFESTS += ["jar.mn"]
+
+EXTRA_JS_MODULES += [
+    "ExtensionMessaging.jsm",
+    "HttpsEverywhereControl.jsm",
+    "OnionAliasStore.jsm",
+]

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tbb-commits mailing list