ma1 pushed to branch tor-browser-115.4.0esr-13.5-1 at The Tor Project / Applications / Tor Browser
Commits:
365b399d by Henry Wilkes at 2023-10-19T16:09:40+01:00
fixup! Bug 27476: Implement about:torconnect captive portal within Tor Browser
Bug 42184: Make torconnect redirect compatible with blank home page.
- - - - -
8982a325 by Henry Wilkes at 2023-10-19T16:09:41+01: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/ef3a54…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/ef3a54…
You're receiving this email because of your account on gitlab.torproject.org.