[tbb-commits] [Git][tpo/applications/tor-browser][tor-browser-115.2.1esr-13.0-1] 6 commits: fixup! Bug 30237: Add v3 onion services client authentication prompt

richard (@richard) git at gitlab.torproject.org
Tue Sep 19 01:26:45 UTC 2023



richard pushed to branch tor-browser-115.2.1esr-13.0-1 at The Tor Project / Applications / Tor Browser


Commits:
de6b3303 by Henry Wilkes at 2023-09-19T01:24:50+00:00
fixup! Bug 30237: Add v3 onion services client authentication prompt

Bug 42091: Tidy up authPrompt.jsm.

Stop importing modules to the global scope and remove authUtil.jsm.

Refactor the description string handling.

- - - - -
1a422b66 by Henry Wilkes at 2023-09-19T01:24:50+00:00
fixup! Add TorStrings module for localization

Bug 42091: Remove authPrompt "Learn More" href from TorStrings.

- - - - -
7c864096 by Henry Wilkes at 2023-09-19T01:24:50+00:00
Bug 42110: Add TorUIUtils module for common tor component methods.

- - - - -
6662e2dd by Henry Wilkes at 2023-09-19T01:24:50+00:00
fixup! Bug 41600: Add a tor circuit display panel.

Bug 42091: Use TorUIUtils to shorten the onion address.

- - - - -
d66b44eb by Henry Wilkes at 2023-09-19T01:24:50+00:00
fixup! Bug 30237: Add v3 onion services client authentication prompt

Bug 42091: Shorten the shown onion address in the auth prompt.

- - - - -
6f0199ab by Henry Wilkes at 2023-09-19T01:24:50+00:00
fixup! Bug 23247: Communicating security expectations for .onion

Bug 42091: Shorten onion address in site identity panel to be consistent
with the circuit display.

- - - - -


10 changed files:

- browser/base/content/browser-siteIdentity.js
- browser/base/content/browser.js
- browser/components/onionservices/content/authPreferences.js
- browser/components/onionservices/content/authPrompt.js
- − browser/components/onionservices/content/authUtil.jsm
- browser/components/onionservices/jar.mn
- browser/components/torcircuit/content/torCircuitPanel.js
- browser/modules/TorStrings.jsm
- + browser/modules/TorUIUtils.sys.mjs
- browser/modules/moz.build


Changes:

=====================================
browser/base/content/browser-siteIdentity.js
=====================================
@@ -729,7 +729,15 @@ var gIdentityHandler = {
       host = this._uri.specIgnoringRef;
     }
 
-    return host;
+    // For tor browser we want to shorten onion addresses for the site identity
+    // panel (gIdentityHandler) to match the circuit display and the onion
+    // authorization panel.
+    // See tor-browser#42091 and tor-browser#41600.
+    // This will also shorten addresses for other consumers of this method,
+    // which includes the permissions panel (gPermissionPanel) and the
+    // protections panel (gProtectionsHandler), although the latter is hidden in
+    // tor browser.
+    return TorUIUtils.shortenOnionAddress(host);
   },
 
   /**


=====================================
browser/base/content/browser.js
=====================================
@@ -67,6 +67,7 @@ ChromeUtils.defineESModuleGetters(this, {
     "resource:///modules/firefox-view-tabs-setup-manager.sys.mjs",
   TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.sys.mjs",
   TorDomainIsolator: "resource://gre/modules/TorDomainIsolator.sys.mjs",
+  TorUIUtils: "resource:///modules/TorUIUtils.sys.mjs",
   TranslationsParent: "resource://gre/actors/TranslationsParent.sys.mjs",
   UITour: "resource:///modules/UITour.sys.mjs",
   UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs",


=====================================
browser/components/onionservices/content/authPreferences.js
=====================================
@@ -42,10 +42,11 @@ const OnionServicesAuthPreferences = {
 
     elem = groupbox.querySelector(this.selector.learnMore);
     elem.setAttribute("value", TorStrings.onionServices.learnMore);
-    elem.setAttribute("href", TorStrings.onionServices.learnMoreURL);
-    if (TorStrings.onionServices.learnMoreURL.startsWith("about:")) {
-      elem.setAttribute("useoriginprincipal", "true");
-    }
+    elem.setAttribute(
+      "href",
+      "about:manual#onion-services_onion-service-authentication"
+    );
+    elem.setAttribute("useoriginprincipal", "true");
 
     elem = groupbox.querySelector(this.selector.savedKeysButton);
     elem.setAttribute(


=====================================
browser/components/onionservices/content/authPrompt.js
=====================================
@@ -1,20 +1,19 @@
-// Copyright (c) 2020, The Tor Project, Inc.
+/* eslint-env mozilla/browser-window */
 
 "use strict";
 
-/* globals gBrowser, PopupNotifications, Services, XPCOMUtils */
-
-ChromeUtils.defineESModuleGetters(this, {
-  TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
-});
-
-XPCOMUtils.defineLazyModuleGetters(this, {
-  OnionAuthUtil: "chrome://browser/content/onionservices/authUtil.jsm",
-  CommonUtils: "resource://services-common/utils.js",
-  TorStrings: "resource:///modules/TorStrings.jsm",
-});
-
 const OnionAuthPrompt = (function () {
+  // 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",
+    CommonUtils: "resource://services-common/utils.sys.mjs",
+  });
+  XPCOMUtils.defineLazyModuleGetters(lazy, {
+    TorStrings: "resource:///modules/TorStrings.jsm",
+  });
+
   // 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.
@@ -25,11 +24,16 @@ const OnionAuthPrompt = (function () {
     this._onionHostname = aOnionName;
   }
 
+  const topics = {
+    clientAuthMissing: "tor-onion-services-clientauth-missing",
+    clientAuthIncorrect: "tor-onion-services-clientauth-incorrect",
+  };
+
   OnionServicesAuthPrompt.prototype = {
     show(aWarningMessage) {
       let mainAction = {
-        label: TorStrings.onionServices.authPrompt.done,
-        accessKey: TorStrings.onionServices.authPrompt.doneAccessKey,
+        label: lazy.TorStrings.onionServices.authPrompt.done,
+        accessKey: lazy.TorStrings.onionServices.authPrompt.doneAccessKey,
         leaveOpen: true, // Callback is responsible for closing the notification.
         callback: this._onDone.bind(this),
       };
@@ -68,9 +72,9 @@ const OnionAuthPrompt = (function () {
 
       this._prompt = PopupNotifications.show(
         this._browser,
-        OnionAuthUtil.domid.notification,
+        "tor-clientauth",
         "",
-        OnionAuthUtil.domid.anchor,
+        "tor-clientauth-notification-icon",
         mainAction,
         [cancelAction],
         options
@@ -79,52 +83,38 @@ const OnionAuthPrompt = (function () {
 
     _onPromptShowing(aWarningMessage) {
       let xulDoc = this._browser.ownerDocument;
-      let descElem = xulDoc.getElementById(OnionAuthUtil.domid.description);
+      let descElem = xulDoc.getElementById("tor-clientauth-notification-desc");
       if (descElem) {
         // Handle replacement of the onion name within the localized
         // 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.
-        while (descElem.firstChild) {
-          descElem.firstChild.remove();
-        }
+        const fmtString = lazy.TorStrings.onionServices.authPrompt.description;
+        const [prefix, suffix] = fmtString.split("%S");
 
-        let fmtString = TorStrings.onionServices.authPrompt.description;
-        let prefix = "";
-        let suffix = "";
-        const kToReplace = "%S";
-        let idx = fmtString.indexOf(kToReplace);
-        if (idx < 0) {
-          prefix = fmtString;
-        } else {
-          prefix = fmtString.substring(0, idx);
-          suffix = fmtString.substring(idx + kToReplace.length);
-        }
+        const domainEl = xulDoc.createElement("span");
+        domainEl.id = "tor-clientauth-notification-onionname";
+        domainEl.textContent = TorUIUtils.shortenOnionAddress(
+          this._onionHostname
+        );
 
-        const kHTMLNS = "http://www.w3.org/1999/xhtml";
-        let span = xulDoc.createElementNS(kHTMLNS, "span");
-        span.textContent = prefix;
-        descElem.appendChild(span);
-        span = xulDoc.createElementNS(kHTMLNS, "span");
-        span.id = OnionAuthUtil.domid.onionNameSpan;
-        span.textContent = this._onionHostname;
-        descElem.appendChild(span);
-        span = xulDoc.createElementNS(kHTMLNS, "span");
-        span.textContent = suffix;
-        descElem.appendChild(span);
+        descElem.replaceChildren(prefix, domainEl, suffix);
       }
 
       // Set "Learn More" label and href.
-      let learnMoreElem = xulDoc.getElementById(OnionAuthUtil.domid.learnMore);
+      let learnMoreElem = xulDoc.getElementById(
+        "tor-clientauth-notification-learnmore"
+      );
       if (learnMoreElem) {
-        learnMoreElem.setAttribute("value", TorStrings.onionServices.learnMore);
+        learnMoreElem.setAttribute(
+          "value",
+          lazy.TorStrings.onionServices.learnMore
+        );
         learnMoreElem.setAttribute(
           "href",
-          TorStrings.onionServices.learnMoreURL
+          "about:manual#onion-services_onion-service-authentication"
         );
-        if (TorStrings.onionServices.learnMoreURL.startsWith("about:")) {
-          learnMoreElem.setAttribute("useoriginprincipal", "true");
-        }
+        learnMoreElem.setAttribute("useoriginprincipal", "true");
       }
 
       this._showWarning(aWarningMessage);
@@ -139,7 +129,7 @@ const OnionAuthPrompt = (function () {
       if (keyElem) {
         keyElem.setAttribute(
           "placeholder",
-          TorStrings.onionServices.authPrompt.keyPlaceholder
+          lazy.TorStrings.onionServices.authPrompt.keyPlaceholder
         );
         this._boundOnKeyFieldKeyPress = this._onKeyFieldKeyPress.bind(this);
         this._boundOnKeyFieldInput = this._onKeyFieldInput.bind(this);
@@ -186,14 +176,14 @@ const OnionAuthPrompt = (function () {
 
       const base64key = this._keyToBase64(keyElem.value);
       if (!base64key) {
-        this._showWarning(TorStrings.onionServices.authPrompt.invalidKey);
+        this._showWarning(lazy.TorStrings.onionServices.authPrompt.invalidKey);
         return;
       }
 
       this._prompt.remove();
 
       const controllerFailureMsg =
-        TorStrings.onionServices.authPrompt.failedToSetKey;
+        lazy.TorStrings.onionServices.authPrompt.failedToSetKey;
       try {
         // ^(subdomain.)*onionserviceid.onion$ (case-insensitive)
         const onionServiceIdRegExp =
@@ -205,7 +195,7 @@ const OnionAuthPrompt = (function () {
 
         const checkboxElem = this._getCheckboxElement();
         const isPermanent = checkboxElem && checkboxElem.checked;
-        const provider = await TorProviderBuilder.build();
+        const provider = await lazy.TorProviderBuilder.build();
         await provider.onionAuthAdd(onionServiceId, base64key, isPermanent);
         // Success! Reload the page.
         this._browser.sendMessageToActor("Browser:Reload", {}, "BrowserTab");
@@ -227,7 +217,7 @@ const OnionAuthPrompt = (function () {
       // this authentication prompt.
       const failedURI = this._failedURI.spec;
       const errorCode =
-        this._reasonForPrompt === OnionAuthUtil.topic.clientAuthMissing
+        this._reasonForPrompt === topics.clientAuthMissing
           ? Cr.NS_ERROR_TOR_ONION_SVC_MISSING_CLIENT_AUTH
           : Cr.NS_ERROR_TOR_ONION_SVC_BAD_CLIENT_AUTH;
       const io =
@@ -245,19 +235,17 @@ const OnionAuthPrompt = (function () {
 
     _getKeyElement() {
       let xulDoc = this._browser.ownerDocument;
-      return xulDoc.getElementById(OnionAuthUtil.domid.keyElement);
+      return xulDoc.getElementById("tor-clientauth-notification-key");
     },
 
     _getCheckboxElement() {
       let xulDoc = this._browser.ownerDocument;
-      return xulDoc.getElementById(OnionAuthUtil.domid.checkboxElement);
+      return xulDoc.getElementById("tor-clientauth-persistkey-checkbox");
     },
 
     _showWarning(aWarningMessage) {
       let xulDoc = this._browser.ownerDocument;
-      let warningElem = xulDoc.getElementById(
-        OnionAuthUtil.domid.warningElement
-      );
+      let warningElem = xulDoc.getElementById("tor-clientauth-warning");
       let keyElem = this._getKeyElement();
       if (warningElem) {
         if (aWarningMessage) {
@@ -289,7 +277,7 @@ const OnionAuthPrompt = (function () {
         // a tor onion-auth file (which uses lowercase).
         let rawKey;
         try {
-          rawKey = CommonUtils.decodeBase32(aKeyString.toUpperCase());
+          rawKey = lazy.CommonUtils.decodeBase32(aKeyString.toUpperCase());
         } catch (e) {}
 
         if (rawKey) {
@@ -313,24 +301,21 @@ const OnionAuthPrompt = (function () {
 
   let retval = {
     init() {
-      Services.obs.addObserver(this, OnionAuthUtil.topic.clientAuthMissing);
-      Services.obs.addObserver(this, OnionAuthUtil.topic.clientAuthIncorrect);
+      Services.obs.addObserver(this, topics.clientAuthMissing);
+      Services.obs.addObserver(this, topics.clientAuthIncorrect);
     },
 
     uninit() {
-      Services.obs.removeObserver(this, OnionAuthUtil.topic.clientAuthMissing);
-      Services.obs.removeObserver(
-        this,
-        OnionAuthUtil.topic.clientAuthIncorrect
-      );
+      Services.obs.removeObserver(this, topics.clientAuthMissing);
+      Services.obs.removeObserver(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 != OnionAuthUtil.topic.clientAuthMissing &&
-        aTopic != OnionAuthUtil.topic.clientAuthIncorrect
+        aTopic != topics.clientAuthMissing &&
+        aTopic != topics.clientAuthIncorrect
       ) {
         return;
       }


=====================================
browser/components/onionservices/content/authUtil.jsm deleted
=====================================
@@ -1,25 +0,0 @@
-// Copyright (c) 2020, The Tor Project, Inc.
-
-"use strict";
-
-var EXPORTED_SYMBOLS = ["OnionAuthUtil"];
-
-const OnionAuthUtil = {
-  topic: {
-    clientAuthMissing: "tor-onion-services-clientauth-missing",
-    clientAuthIncorrect: "tor-onion-services-clientauth-incorrect",
-  },
-  message: {
-    authPromptCanceled: "Tor:OnionServicesAuthPromptCanceled",
-  },
-  domid: {
-    anchor: "tor-clientauth-notification-icon",
-    notification: "tor-clientauth",
-    description: "tor-clientauth-notification-desc",
-    learnMore: "tor-clientauth-notification-learnmore",
-    onionNameSpan: "tor-clientauth-notification-onionname",
-    keyElement: "tor-clientauth-notification-key",
-    warningElement: "tor-clientauth-warning",
-    checkboxElement: "tor-clientauth-persistkey-checkbox",
-  },
-};


=====================================
browser/components/onionservices/jar.mn
=====================================
@@ -2,7 +2,6 @@ browser.jar:
     content/browser/onionservices/authPreferences.css              (content/authPreferences.css)
     content/browser/onionservices/authPreferences.js               (content/authPreferences.js)
     content/browser/onionservices/authPrompt.js                    (content/authPrompt.js)
-    content/browser/onionservices/authUtil.jsm                     (content/authUtil.jsm)
     content/browser/onionservices/netError/                        (content/netError/*)
     content/browser/onionservices/onionservices.css                (content/onionservices.css)
     content/browser/onionservices/savedKeysDialog.js               (content/savedKeysDialog.js)


=====================================
browser/components/torcircuit/content/torCircuitPanel.js
=====================================
@@ -408,21 +408,6 @@ var gTorCircuitPanel = {
     return this._fallbackStringBundle.formatStringFromName(name, args);
   },
 
-  /**
-   * Shorten the given address if it is an onion address.
-   *
-   * @param {string} address - The address to shorten.
-   *
-   * @returns {string} The shortened form of the address, or the address itself
-   *   if it was not shortened.
-   */
-  _shortenOnionAddress(address) {
-    if (!address.endsWith(".onion") || address.length <= 22) {
-      return address;
-    }
-    return `${address.slice(0, 7)}…${address.slice(-12)}`;
-  },
-
   /**
    * Updates the circuit display in the panel to show the current browser data.
    */
@@ -465,12 +450,12 @@ var gTorCircuitPanel = {
     this._panelElements.heading.textContent = this._getString(
       "torbutton.circuit_display.heading",
       // Only shorten the onion domain if it has no alias.
-      [onionAlias ? domain : this._shortenOnionAddress(domain)]
+      [TorUIUtils.shortenOnionAddress(domain)]
     );
 
     if (onionAlias) {
       this._panelElements.aliasLink.textContent =
-        this._shortenOnionAddress(onionAlias);
+        TorUIUtils.shortenOnionAddress(onionAlias);
       if (scheme === "http" || scheme === "https") {
         // We assume the same scheme as the current page for the alias, which we
         // expect to be either http or https.
@@ -521,7 +506,8 @@ var gTorCircuitPanel = {
     );
 
     // Set the address that we want to copy.
-    this._panelElements.endItem.textContent = this._shortenOnionAddress(domain);
+    this._panelElements.endItem.textContent =
+      TorUIUtils.shortenOnionAddress(domain);
 
     // Button description text, depending on whether our first node was a
     // bridge, or otherwise a guard.


=====================================
browser/modules/TorStrings.jsm
=====================================
@@ -300,7 +300,6 @@ const Loader = {
 
     const retval = {
       learnMore: getString("learnMore", "Learn more"),
-      learnMoreURL: "about:manual#onion-services_onion-service-authentication",
       errorPage: {
         browser: getString("errorPage.browser", "Browser"),
         network: getString("errorPage.network", "Network"),


=====================================
browser/modules/TorUIUtils.sys.mjs
=====================================
@@ -0,0 +1,26 @@
+/**
+ * Common methods for tor UI components.
+ */
+export const TorUIUtils = {
+  /**
+   * Shorten the given address if it is an onion address.
+   *
+   * @param {string} address - The address to shorten.
+   *
+   * @returns {string} The shortened form of the address, or the address itself
+   *   if it was not shortened.
+   */
+  shortenOnionAddress(address) {
+    if (
+      // Only shorten ".onion" addresses.
+      !address.endsWith(".onion") ||
+      // That are not "onion" aliases.
+      address.endsWith(".tor.onion") ||
+      // And are long.
+      address.length <= 21
+    ) {
+      return address;
+    }
+    return `${address.slice(0, 6)}…${address.slice(-12)}`;
+  },
+};


=====================================
browser/modules/moz.build
=====================================
@@ -152,6 +152,7 @@ EXTRA_JS_MODULES += [
     "TorConnect.sys.mjs",
     "TorSettings.sys.mjs",
     "TorStrings.jsm",
+    "TorUIUtils.sys.mjs",
     "TransientPrefs.jsm",
     "URILoadingHelper.sys.mjs",
     "webrtcUI.jsm",



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2760a7b8f44eeaeb1bd8ace24532aa61763600f0...6f0199abb78b67312ce8f330d96b6313e6b4e15b

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2760a7b8f44eeaeb1bd8ace24532aa61763600f0...6f0199abb78b67312ce8f330d96b6313e6b4e15b
You're receiving this email because of your account on gitlab.torproject.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.torproject.org/pipermail/tbb-commits/attachments/20230919/2b500102/attachment-0001.htm>


More information about the tbb-commits mailing list