[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-115.4.0esr-13.0-1] 2 commits: fixup! Bug 27476: Implement about:torconnect captive portal within Tor Browser

richard (@richard) git at gitlab.torproject.org
Mon Nov 6 23:18:52 UTC 2023



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


Commits:
f83bd860 by Henry Wilkes at 2023-11-06T23:18:21+00:00
fixup! Bug 27476: Implement about:torconnect captive portal within Tor Browser

Bug 42184: Make torconnect redirect compatible with blank home page.

- - - - -
f0ddec98 by Henry Wilkes at 2023-11-06T23:18:28+00:00
fixup! Bug 40597: Implement TorSettings module

Bug 42184: Split out URI fixup logic to fixupURIs and simplify. This
method is used in TorConnectParent to fixup the home page preference.

- - - - -


4 changed files:

- browser/components/torconnect/TorConnectChild.sys.mjs
- browser/components/torconnect/TorConnectParent.sys.mjs
- browser/components/torconnect/content/aboutTorConnect.js
- browser/modules/TorConnect.sys.mjs


Changes:

=====================================
browser/components/torconnect/TorConnectChild.sys.mjs
=====================================
@@ -2,4 +2,78 @@
 
 import { RemotePageChild } from "resource://gre/actors/RemotePageChild.sys.mjs";
 
-export class TorConnectChild extends RemotePageChild {}
+export class TorConnectChild extends RemotePageChild {
+  /**
+   * Whether we have redirected the page (after bootstrapping) or not.
+   *
+   * @type {boolean}
+   */
+  #redirected = false;
+
+  /**
+   * If bootstrapping is complete, or TorConnect is disabled, we redirect the
+   * page.
+   */
+  async #maybeRedirect() {
+    if (await this.sendQuery("torconnect:should-show")) {
+      // Enabled and not yet bootstrapped.
+      return;
+    }
+    if (this.#redirected) {
+      return;
+    }
+    this.#redirected = true;
+
+    const redirect = new URLSearchParams(
+      new URL(this.contentWindow.document.location.href).search
+    ).get("redirect");
+
+    // Fallback in error cases:
+    let replaceURI = "about:tor";
+    try {
+      const url = new URL(
+        redirect
+          ? decodeURIComponent(redirect)
+          : // NOTE: We expect no redirect when address is entered manually, or
+            // about:torconnect is opened from preferences or urlbar.
+            // Go to the home page.
+            await this.sendQuery("torconnect:home-page")
+      );
+      // Do not allow javascript URI. See tor-browser#41766
+      if (
+        ["about:", "file:", "https:", "http:"].includes(url.protocol) ||
+        // Allow blank page. See tor-browser#42184.
+        // Blank page's are given as a chrome URL rather than "about:blank".
+        url.href === "chrome://browser/content/blanktab.html"
+      ) {
+        replaceURI = url.href;
+      } else {
+        console.error(`Scheme is not allowed "${redirect}"`);
+      }
+    } catch {
+      console.error(`Invalid redirect URL "${redirect}"`);
+    }
+
+    // Replace the destination to prevent "about:torconnect" entering the
+    // history.
+    // NOTE: This is done here, in the window actor, rather than in content
+    // because we have the privilege to redirect to a "chrome:" uri here (for
+    // when the HomePage is set to be blank).
+    this.contentWindow.location.replace(replaceURI);
+  }
+
+  actorCreated() {
+    super.actorCreated();
+    // about:torconnect could need to be immediately redirected. E.g. if it is
+    // reached after bootstrapping.
+    this.#maybeRedirect();
+  }
+
+  receiveMessage(message) {
+    super.receiveMessage(message);
+
+    if (message.name === "torconnect:state-change") {
+      this.#maybeRedirect();
+    }
+  }
+}


=====================================
browser/components/torconnect/TorConnectParent.sys.mjs
=====================================
@@ -1,5 +1,7 @@
 // Copyright (c) 2021, The Tor Project, Inc.
 
+import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
+
 const { TorStrings } = ChromeUtils.import("resource:///modules/TorStrings.jsm");
 import {
   InternetStatus,
@@ -15,6 +17,12 @@ import {
 
 const BroadcastTopic = "about-torconnect:broadcast";
 
+const lazy = {};
+
+XPCOMUtils.defineLazyModuleGetters(lazy, {
+  HomePage: "resource:///modules/HomePage.jsm",
+});
+
 /*
 This object is basically a marshalling interface between the TorConnect module
 and a particular about:torconnect page
@@ -167,6 +175,11 @@ export class TorConnectParent extends JSWindowActorParent {
 
   async receiveMessage(message) {
     switch (message.name) {
+      case "torconnect:should-show":
+        return Promise.resolve(TorConnect.shouldShowTorConnect);
+      case "torconnect:home-page":
+        // If there are multiple home pages, just load the first one.
+        return Promise.resolve(TorConnect.fixupURIs(lazy.HomePage.get())[0]);
       case "torconnect:set-quickstart":
         TorSettings.quickstart.enabled = message.data;
         TorSettings.saveToPrefs().applySettings();


=====================================
browser/components/torconnect/content/aboutTorConnect.js
=====================================
@@ -136,10 +136,6 @@ class AboutTorConnect {
     tryBridgeButton: document.querySelector(this.selectors.buttons.tryBridge),
   });
 
-  // a redirect url can be passed as a query parameter for the page to
-  // forward us to once bootstrap completes (otherwise the window will just close)
-  redirect = null;
-
   uiState = {
     currentState: UIStates.ConnectToTor,
     allowAutomaticLocation: true,
@@ -425,11 +421,6 @@ class AboutTorConnect {
     this.setLongText(TorStrings.settings.torPreferencesDescription);
     this.setProgress("", showProgressbar, 100);
     this.hideButtons();
-
-    // redirects page to the requested redirect url, removes about:torconnect
-    // from the page stack, so users cannot accidentally go 'back' to the
-    // now unresponsive page
-    window.location.replace(this.redirect);
   }
 
   update_Disabled(state) {
@@ -822,23 +813,6 @@ class AboutTorConnect {
   }
 
   async init() {
-    // if the user gets here manually or via the button in the urlbar
-    // then we will redirect to about:tor
-    this.redirect = "about:tor";
-
-    // see if a user has a final destination after bootstrapping
-    let params = new URLSearchParams(new URL(document.location.href).search);
-    if (params.has("redirect")) {
-      try {
-        const redirect = new URL(decodeURIComponent(params.get("redirect")));
-        if (/^(?:https?|about):$/.test(redirect.protocol)) {
-          this.redirect = redirect.href;
-        }
-      } catch (e) {
-        console.error(e, `Invalid redirect URL "${params.get("redirect")}"!`);
-      }
-    }
-
     let args = await RPMSendQuery("torconnect:get-init-args");
 
     // various constants


=====================================
browser/modules/TorConnect.sys.mjs
=====================================
@@ -1156,67 +1156,54 @@ export const TorConnect = (() => {
       return `about:torconnect?redirect=${encodeURIComponent(url)}`;
     },
 
+    /**
+     * Convert the given object into a list of valid URIs.
+     *
+     * The object is either from the user's homepage preference (which may
+     * contain multiple domains separated by "|") or uris passed to the browser
+     * via command-line.
+     *
+     * @param {string|string[]} uriVariant - The string to extract uris from.
+     *
+     * @return {string[]} - The array of uris found.
+     */
+    fixupURIs(uriVariant) {
+      let uriArray;
+      if (typeof uriVariant === "string") {
+        uriArray = uriVariant.split("|");
+      } else if (
+        Array.isArray(uriVariant) &&
+        uriVariant.every(entry => typeof entry === "string")
+      ) {
+        uriArray = uriVariant;
+      } else {
+        // about:tor as safe fallback
+        console.error(
+          `TorConnect: received unknown variant '${JSON.stringify(uriVariant)}'`
+        );
+        uriArray = ["about:tor"];
+      }
+
+      // Attempt to convert user-supplied string to a uri, fallback to
+      // about:tor if cannot convert to valid uri object
+      return uriArray.map(
+        uriString =>
+          Services.uriFixup.getFixupURIInfo(
+            uriString,
+            Ci.nsIURIFixup.FIXUP_FLAG_NONE
+          ).preferredURI?.spec ?? "about:tor"
+      );
+    },
+
     // called from browser.js on browser startup, passed in either the user's homepage(s)
     // or uris passed via command-line; we want to replace them with about:torconnect uris
     // which redirect after bootstrapping
     getURIsToLoad(uriVariant) {
-      // convert the object we get from browser.js
-      let uriStrings = (v => {
-        // an interop array
-        if (v instanceof Ci.nsIArray) {
-          // Transform the nsIArray of nsISupportsString's into a JS Array of
-          // JS strings.
-          return Array.from(
-            v.enumerate(Ci.nsISupportsString),
-            supportStr => supportStr.data
-          );
-          // an interop string
-        } else if (v instanceof Ci.nsISupportsString) {
-          return [v.data];
-          // a js string
-        } else if (typeof v === "string") {
-          return v.split("|");
-          // a js array of js strings
-        } else if (
-          Array.isArray(v) &&
-          v.reduce((allStrings, entry) => {
-            return allStrings && typeof entry === "string";
-          }, true)
-        ) {
-          return v;
-        }
-        // about:tor as safe fallback
-        console.log(
-          `TorConnect: getURIsToLoad() received unknown variant '${JSON.stringify(
-            v
-          )}'`
-        );
-        return ["about:tor"];
-      })(uriVariant);
-
-      // will attempt to convert user-supplied string to a uri, fallback to about:tor if cannot convert
-      // to valid uri object
-      let uriStringToUri = uriString => {
-        const fixupFlags = Ci.nsIURIFixup.FIXUP_FLAG_NONE;
-        let uri = Services.uriFixup.getFixupURIInfo(
-          uriString,
-          fixupFlags
-        ).preferredURI;
-        return uri ? uri : Services.io.newURI("about:tor");
-      };
-      let uris = uriStrings.map(uriStringToUri);
-
-      // assume we have a valid uri and generate an about:torconnect redirect uri
-      let redirectUrls = uris.map(uri => this.getRedirectURL(uri.spec));
-
+      const uris = this.fixupURIs(uriVariant);
       console.log(
-        `TorConnect: Will load after bootstrap => [${uris
-          .map(uri => {
-            return uri.spec;
-          })
-          .join(", ")}]`
+        `TorConnect: Will load after bootstrap => [${uris.join(", ")}]`
       );
-      return redirectUrls;
+      return uris.map(uri => this.getRedirectURL(uri));
     },
   };
   return retval;



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2b8d06d6e74191c47fc266eca2e11e460cf075a5...f0ddec98dad6afe834c4ca0d25fe12a4449fc126

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/2b8d06d6e74191c47fc266eca2e11e460cf075a5...f0ddec98dad6afe834c4ca0d25fe12a4449fc126
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/tor-commits/attachments/20231106/31a161b5/attachment-0001.htm>


More information about the tor-commits mailing list