[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-115.1.0esr-13.0-1] 9 commits: fixup! Add TorStrings module for localization

Pier Angelo Vendrame (@pierov) git at gitlab.torproject.org
Mon Jul 31 18:47:21 UTC 2023



Pier Angelo Vendrame pushed to branch tor-browser-115.1.0esr-13.0-1 at The Tor Project / Applications / Tor Browser


Commits:
c3d2496b by Pier Angelo Vendrame at 2023-07-27T21:07:52+02:00
fixup! Add TorStrings module for localization

Move the `getLocale` function here from TorButton util.js and stop
importing it.

- - - - -
642df684 by Pier Angelo Vendrame at 2023-07-27T21:07:53+02:00
fixup! Bug 40933: Add tor-launcher functionality

Fix a couple of problems in TorLauncherUtil and TorParsers.

Also, moved the function to parse bridges in TorParsers.

- - - - -
9e825b61 by Pier Angelo Vendrame at 2023-07-27T21:07:53+02:00
fixup! Bug 31286: Implementation of bridge, proxy, and firewall settings in about:preferences#connection

Use the bridge line parser from TorParsers.

- - - - -
8061f810 by Pier Angelo Vendrame at 2023-07-27T21:07:53+02:00
fixup! Bug 40933: Add tor-launcher functionality

Use actual private members for TorProcess.

- - - - -
f5a3f4af by Pier Angelo Vendrame at 2023-07-27T21:07:54+02:00
fixup! Bug 40933: Add tor-launcher functionality

Group arg pushes in one line (keys and values together).

- - - - -
71b08c4e by Pier Angelo Vendrame at 2023-07-27T21:07:54+02:00
fixup! Bug 40933: Add tor-launcher functionality

TorProcess: use real private properties instead of _, and removed the
dependency on TorProtocolService (temporarily moved it to
TorMonitorService, but eventually we should unify TorProtocolService
and TorMonitorService, to then split them again in a smarter way).

- - - - -
e1a69b4e by Pier Angelo Vendrame at 2023-07-27T21:07:55+02:00
fixup! Bug 10760: Integrate TorButton to TorBrowser core

Move the SOCKS preference updater to TorProtocolService.
We will need to refactor all this kind of stuff, but at least let's get
it in a single place.

Also, since this was the last bit of the startup service, remove the
file, the component and what else was needed to add them.

- - - - -
d457b6f8 by Pier Angelo Vendrame at 2023-07-31T20:42:54+02:00
fixup! Bug 40933: Add tor-launcher functionality

Hashing the control port password is needed only on the process, so move
this function to TorProcess.

- - - - -
c4e8cd0f by Pier Angelo Vendrame at 2023-07-31T20:42:57+02:00
fixup! Bug 10760: Integrate TorButton to TorBrowser core

The hashpassword parameter has been removed.

- - - - -


13 changed files:

- browser/components/torpreferences/content/connectionPane.js
- browser/installer/package-manifest.in
- browser/modules/TorStrings.jsm
- toolkit/components/tor-launcher/TorLauncherUtil.sys.mjs
- toolkit/components/tor-launcher/TorMonitorService.sys.mjs
- toolkit/components/tor-launcher/TorParsers.sys.mjs
- toolkit/components/tor-launcher/TorProcess.sys.mjs
- toolkit/components/tor-launcher/TorProtocolService.sys.mjs
- toolkit/torbutton/chrome/content/torbutton.js
- toolkit/torbutton/components.conf
- − toolkit/torbutton/modules/TorbuttonStartupObserver.jsm
- toolkit/torbutton/moz.build
- − toolkit/torbutton/torbutton.manifest


Changes:

=====================================
browser/components/torpreferences/content/connectionPane.js
=====================================
@@ -14,8 +14,11 @@ const { setTimeout, clearTimeout } = ChromeUtils.import(
 const { TorSettings, TorSettingsTopics, TorSettingsData, TorBridgeSource } =
   ChromeUtils.import("resource:///modules/TorSettings.jsm");
 
-const { TorProtocolService } = ChromeUtils.import(
-  "resource://gre/modules/TorProtocolService.jsm"
+const { TorParsers } = ChromeUtils.importESModule(
+  "resource://gre/modules/TorParsers.sys.mjs"
+);
+const { TorProtocolService } = ChromeUtils.importESModule(
+  "resource://gre/modules/TorProtocolService.sys.mjs"
 );
 const { TorMonitorService, TorMonitorTopics } = ChromeUtils.import(
   "resource://gre/modules/TorMonitorService.jsm"
@@ -495,7 +498,7 @@ const gConnectionPane = (function () {
         });
         const idString = TorStrings.settings.bridgeId;
         const id = card.querySelector(selectors.bridges.cardId);
-        const details = parseBridgeLine(bridgeString);
+        const details = TorParsers.parseBridgeLine(bridgeString);
         if (details && details.id !== undefined) {
           card.setAttribute("data-bridge-id", details.id);
         }
@@ -1111,23 +1114,3 @@ function makeBridgeId(bridgeString) {
     hash & 0x000000ff,
   ];
 }
-
-function parseBridgeLine(line) {
-  const re =
-    /^\s*(\S+\s+)?([0-9a-fA-F\.\[\]\:]+:\d{1,5})(\s+[0-9a-fA-F]{40})?(\s+.+)?/;
-  const matches = line.match(re);
-  if (!matches) {
-    return null;
-  }
-  let bridge = { addr: matches[2] };
-  if (matches[1] !== undefined) {
-    bridge.transport = matches[1].trim();
-  }
-  if (matches[3] !== undefined) {
-    bridge.id = matches[3].trim().toUpperCase();
-  }
-  if (matches[4] !== undefined) {
-    bridge.args = matches[4].trim();
-  }
-  return bridge;
-}


=====================================
browser/installer/package-manifest.in
=====================================
@@ -228,7 +228,6 @@
 @RESPATH@/components/tor-launcher.manifest
 @RESPATH@/chrome/torbutton.manifest
 @RESPATH@/chrome/torbutton/*
- at RESPATH@/components/torbutton.manifest
 @RESPATH@/chrome/toolkit at JAREXT@
 @RESPATH@/chrome/toolkit.manifest
 #ifdef MOZ_GTK


=====================================
browser/modules/TorStrings.jsm
=====================================
@@ -11,9 +11,11 @@ const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
 const { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
-const { getLocale } = ChromeUtils.import(
-  "resource://torbutton/modules/utils.js"
-);
+
+function getLocale() {
+  const locale = Services.locale.appLocaleAsBCP47;
+  return locale === "ja-JP-macos" ? "ja" : locale;
+}
 
 /*
   Tor Property String Bundle


=====================================
toolkit/components/tor-launcher/TorLauncherUtil.sys.mjs
=====================================
@@ -5,6 +5,12 @@
  * Tor Launcher Util JS Module
  *************************************************************************/
 
+const lazy = {};
+
+ChromeUtils.defineESModuleGetters(lazy, {
+  FileUtils: "resource://gre/modules/FileUtils.sys.jsm",
+});
+
 const kPropBundleURI = "chrome://torbutton/locale/torlauncher.properties";
 const kPropNamePrefix = "torlauncher.";
 const kIPCDirPrefName = "extensions.torlauncher.tmp_ipc_dir";
@@ -209,14 +215,15 @@ class TorFile {
   // and return a file object. The control and SOCKS IPC objects will be
   // created by tor.
   normalize() {
-    if (!this.file.exists() && !this.isIPC) {
+    if (this.file.exists()) {
+      try {
+        this.file.normalize();
+      } catch (e) {
+        console.warn("Normalization of the path failed", e);
+      }
+    } else if (!this.isIPC) {
       throw new Error(`${this.fileType} file not found: ${this.file.path}`);
     }
-    try {
-      this.file.normalize();
-    } catch (e) {
-      console.warn("Normalization of the path failed", e);
-    }
 
     // Ensure that the IPC path length is short enough for use by the
     // operating system. If not, create and use a unique directory under
@@ -452,6 +459,154 @@ export const TorLauncherUtil = Object.freeze({
     return result ? result : "";
   },
 
+  /**
+   * Determine what kind of SOCKS port has been requested for this session or
+   * the browser has been configured for.
+   * On Windows (where Unix domain sockets are not supported), TCP is always
+   * used.
+   *
+   * The following environment variables are supported and take precedence over
+   * preferences:
+   *    TOR_TRANSPROXY (do not use a proxy)
+   *    TOR_SOCKS_IPC_PATH (file system path; ignored on Windows)
+   *    TOR_SOCKS_HOST
+   *    TOR_SOCKS_PORT
+   *
+   * The following preferences are consulted:
+   *    network.proxy.socks
+   *    network.proxy.socks_port
+   *    extensions.torlauncher.socks_port_use_ipc (Boolean)
+   *    extensions.torlauncher.socks_ipc_path (file system path)
+   * If extensions.torlauncher.socks_ipc_path is empty, a default path is used.
+   *
+   * When using TCP, if a value is not defined via an env variable it is
+   * taken from the corresponding browser preference if possible. The
+   * exceptions are:
+   *   If network.proxy.socks contains a file: URL, a default value of
+   *     "127.0.0.1" is used instead.
+   *   If the network.proxy.socks_port value is not valid (outside the
+   *     (0; 65535] range), a default value of 9150 is used instead.
+   *
+   * The SOCKS configuration will not influence the launch of a tor daemon and
+   * the configuration of the control port in any way.
+   * When a SOCKS configuration is required without TOR_SKIP_LAUNCH, the browser
+   * will try to configure the tor instance to use the required configuration.
+   * This also applies to TOR_TRANSPROXY (at least for now): tor will be
+   * launched with its defaults.
+   *
+   * TODO: add a preference to ignore the current configuration, and let tor
+   * listen on any free port. Then, the browser will prompt the daemon the port
+   * to use through the control port (even though this is quite dangerous at the
+   * moment, because with network disabled tor will disable also the SOCKS
+   * listeners, so it means that we will have to check it every time we change
+   * the network status).
+   */
+  getPreferredSocksConfiguration() {
+    if (Services.env.exists("TOR_TRANSPROXY")) {
+      Services.prefs.setBoolPref("network.proxy.socks_remote_dns", false);
+      Services.prefs.setIntPref("network.proxy.type", 0);
+      Services.prefs.setIntPref("network.proxy.socks_port", 0);
+      Services.prefs.setCharPref("network.proxy.socks", "");
+      return { transproxy: true };
+    }
+
+    let useIPC;
+    const socksPortInfo = {
+      transproxy: false,
+    };
+
+    if (!this.isWindows && Services.env.exists("TOR_SOCKS_IPC_PATH")) {
+      useIPC = true;
+      const ipcPath = Services.env.get("TOR_SOCKS_IPC_PATH");
+      if (ipcPath) {
+        socksPortInfo.ipcFile = new lazy.FileUtils.File(ipcPath);
+      }
+    } else {
+      // Check for TCP host and port environment variables.
+      if (Services.env.exists("TOR_SOCKS_HOST")) {
+        socksPortInfo.host = Services.env.get("TOR_SOCKS_HOST");
+        useIPC = false;
+      }
+      if (Services.env.exists("TOR_SOCKS_PORT")) {
+        const port = parseInt(Services.env.get("TOR_SOCKS_PORT"), 10);
+        if (Number.isInteger(port) && port > 0 && port <= 65535) {
+          socksPortInfo.port = port;
+          useIPC = false;
+        }
+      }
+    }
+
+    if (useIPC === undefined) {
+      socksPortInfo.useIPC =
+        !this.isWindows &&
+        Services.prefs.getBoolPref(
+          "extensions.torlauncher.socks_port_use_ipc",
+          false
+        );
+    }
+
+    // Fill in missing SOCKS info from prefs.
+    if (socksPortInfo.useIPC) {
+      if (!socksPortInfo.ipcFile) {
+        socksPortInfo.ipcFile = TorLauncherUtil.getTorFile("socks_ipc", false);
+      }
+    } else {
+      if (!socksPortInfo.host) {
+        let socksAddr = Services.prefs.getCharPref(
+          "network.proxy.socks",
+          "127.0.0.1"
+        );
+        let socksAddrHasHost = socksAddr && !socksAddr.startsWith("file:");
+        socksPortInfo.host = socksAddrHasHost ? socksAddr : "127.0.0.1";
+      }
+
+      if (!socksPortInfo.port) {
+        let socksPort = Services.prefs.getIntPref(
+          "network.proxy.socks_port",
+          0
+        );
+        // This pref is set as 0 by default in Firefox, use 9150 if we get 0.
+        socksPortInfo.port =
+          socksPort > 0 && socksPort <= 65535 ? socksPort : 9150;
+      }
+    }
+
+    return socksPortInfo;
+  },
+
+  setProxyConfiguration(socksPortInfo) {
+    if (socksPortInfo.transproxy) {
+      return;
+    }
+
+    if (socksPortInfo.useIPC) {
+      const fph = Services.io
+        .getProtocolHandler("file")
+        .QueryInterface(Ci.nsIFileProtocolHandler);
+      const fileURI = fph.newFileURI(socksPortInfo.ipcFile);
+      Services.prefs.setCharPref("network.proxy.socks", fileURI.spec);
+      Services.prefs.setIntPref("network.proxy.socks_port", 0);
+    } else {
+      if (socksPortInfo.host) {
+        Services.prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
+      }
+      if (socksPortInfo.port) {
+        Services.prefs.setIntPref(
+          "network.proxy.socks_port",
+          socksPortInfo.port
+        );
+      }
+    }
+
+    if (socksPortInfo.ipcFile || socksPortInfo.host || socksPortInfo.port) {
+      Services.prefs.setBoolPref("network.proxy.socks_remote_dns", true);
+      Services.prefs.setIntPref("network.proxy.type", 1);
+    }
+
+    // Force prefs to be synced to disk
+    Services.prefs.savePrefFile(null);
+  },
+
   get shouldStartAndOwnTor() {
     const kPrefStartTor = "extensions.torlauncher.start_tor";
     try {


=====================================
toolkit/components/tor-launcher/TorMonitorService.sys.mjs
=====================================
@@ -13,6 +13,10 @@ import { TorLauncherUtil } from "resource://gre/modules/TorLauncherUtil.sys.mjs"
 
 const lazy = {};
 
+ChromeUtils.defineESModuleGetters(lazy, {
+  TorProtocolService: "resource://gre/modules/TorProtocolService.sys.mjs",
+});
+
 ChromeUtils.defineModuleGetter(
   lazy,
   "controller",
@@ -233,7 +237,10 @@ export const TorMonitorService = {
     // TorProcess should be instanced once, then always reused and restarted
     // only through the prompt it exposes when the controlled process dies.
     if (!this._torProcess) {
-      this._torProcess = new TorProcess();
+      this._torProcess = new TorProcess(
+        lazy.TorProtocolService.torControlPortInfo,
+        lazy.TorProtocolService.torSOCKSPortInfo
+      );
       this._torProcess.onExit = () => {
         this._shutDownEventMonitor();
         Services.obs.notifyObservers(null, TorTopics.ProcessExited);
@@ -254,6 +261,7 @@ export const TorMonitorService = {
       await this._torProcess.start();
       if (this._torProcess.isRunning) {
         logger.info("tor started");
+        this._torProcessStartTime = Date.now();
       }
     } catch (e) {
       // TorProcess already logs the error.


=====================================
toolkit/components/tor-launcher/TorParsers.sys.mjs
=====================================
@@ -267,4 +267,18 @@ export const TorParsers = Object.freeze({
     rv += aStr.substring(lastAdded, aStr.length - 1);
     return rv;
   },
+
+  parseBridgeLine(line) {
+    const re =
+      /\s*(?:(?<transport>\S+)\s+)?(?<addr>[0-9a-fA-F\.\[\]\:]+:\d{1,5})(?:\s+(?<id>[0-9a-fA-F]{40}))?(?:\s+(?<args>.+))?/;
+    const match = re.exec(line);
+    if (!match) {
+      throw new Error("Invalid bridge line.");
+    }
+    const bridge = match.groups;
+    if (!bridge.transport) {
+      bridge.transport = "vanilla";
+    }
+    return bridge;
+  },
 });


=====================================
toolkit/components/tor-launcher/TorProcess.sys.mjs
=====================================
@@ -1,21 +1,17 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
 import { setTimeout } from "resource://gre/modules/Timer.sys.mjs";
 import { ConsoleAPI } from "resource://gre/modules/Console.sys.mjs";
 import { Subprocess } from "resource://gre/modules/Subprocess.sys.mjs";
 
 const lazy = {};
 
-ChromeUtils.defineModuleGetter(
-  lazy,
-  "TorProtocolService",
-  "resource://gre/modules/TorProtocolService.jsm"
-);
-const { TorLauncherUtil } = ChromeUtils.import(
-  "resource://gre/modules/TorLauncherUtil.jsm"
-);
-
-const { TorParsers } = ChromeUtils.import(
-  "resource://gre/modules/TorParsers.jsm"
-);
+ChromeUtils.defineESModuleGetters(lazy, {
+  TorLauncherUtil: "resource://gre/modules/TorLauncherUtil.sys.mjs",
+  TorParsers: "resource://gre/modules/TorParsers.sys.mjs",
+});
 
 const TorProcessStatus = Object.freeze({
   Unknown: 0,
@@ -30,53 +26,86 @@ const logger = new ConsoleAPI({
 });
 
 export class TorProcess {
-  _exeFile = null;
-  _dataDir = null;
-  _args = [];
-  _subprocess = null;
-  _status = TorProcessStatus.Unknown;
-  _torProcessStartTime = null; // JS Date.now()
-  _didConnectToTorControlPort = false; // Have we ever made a connection?
+  #controlSettings;
+  #socksSettings;
+  #exeFile = null;
+  #dataDir = null;
+  #args = [];
+  #subprocess = null;
+  #status = TorProcessStatus.Unknown;
+  // Have we ever made a connection on the control port?
+  #didConnectToTorControlPort = false;
+
+  onExit = exitCode => {};
+  onRestart = () => {};
+
+  constructor(controlSettings, socksSettings) {
+    if (
+      controlSettings &&
+      !controlSettings.password &&
+      !controlSettings.cookieFilePath
+    ) {
+      throw new Error("Unauthenticated control port is not supported");
+    }
 
-  onExit = null;
-  onRestart = null;
+    const checkPort = port =>
+      port === undefined ||
+      (Number.isInteger(controlSettings.port) &&
+        controlSettings.port > 0 &&
+        controlSettings.port < 65535);
+    if (!checkPort(controlSettings?.port)) {
+      throw new Error("Invalid control port");
+    }
+    if (!checkPort(socksSettings.port)) {
+      throw new Error("Invalid port specified for the SOCKS port");
+    }
+
+    this.#controlSettings = { ...controlSettings };
+    const ipcFileToString = file =>
+      "unix:" + lazy.TorParsers.escapeString(file.path);
+    if (controlSettings.ipcFile) {
+      this.#controlSettings.ipcFile = ipcFileToString(controlSettings.ipcFile);
+    }
+    this.#socksSettings = { ...socksSettings };
+    if (socksSettings.ipcFile) {
+      this.#socksSettings.ipcFile = ipcFileToString(socksSettings.ipcFile);
+    }
+  }
 
   get status() {
-    return this._status;
+    return this.#status;
   }
 
   get isRunning() {
     return (
-      this._status === TorProcessStatus.Starting ||
-      this._status === TorProcessStatus.Running
+      this.#status === TorProcessStatus.Starting ||
+      this.#status === TorProcessStatus.Running
     );
   }
 
   async start() {
-    if (this._subprocess) {
+    if (this.#subprocess) {
       return;
     }
 
-    this._status = TorProcessStatus.Unknown;
+    this.#status = TorProcessStatus.Unknown;
 
     try {
-      this._makeArgs();
-      this._addControlPortArg();
-      this._addSocksPortArg();
+      this.#makeArgs();
+      this.#addControlPortArgs();
+      this.#addSocksPortArg();
 
       const pid = Services.appinfo.processID;
       if (pid !== 0) {
-        this._args.push("__OwningControllerProcess");
-        this._args.push("" + pid);
+        this.#args.push("__OwningControllerProcess", pid.toString());
       }
 
-      if (TorLauncherUtil.shouldShowNetworkSettings) {
-        this._args.push("DisableNetwork");
-        this._args.push("1");
+      if (lazy.TorLauncherUtil.shouldShowNetworkSettings) {
+        this.#args.push("DisableNetwork", "1");
       }
 
-      this._status = TorProcessStatus.Starting;
-      this._didConnectToTorControlPort = false;
+      this.#status = TorProcessStatus.Starting;
+      this.#didConnectToTorControlPort = false;
 
       // useful for simulating slow tor daemon launch
       const kPrefTorDaemonLaunchDelay = "extensions.torlauncher.launch_delay";
@@ -88,29 +117,31 @@ export class TorProcess {
         await new Promise(resolve => setTimeout(() => resolve(), launchDelay));
       }
 
-      logger.debug(`Starting ${this._exeFile.path}`, this._args);
+      logger.debug(`Starting ${this.#exeFile.path}`, this.#args);
       const options = {
-        command: this._exeFile.path,
-        arguments: this._args,
+        command: this.#exeFile.path,
+        arguments: this.#args,
         stderr: "stdout",
-        workdir: TorLauncherUtil.getTorFile("pt-startup-dir", false).path,
+        workdir: lazy.TorLauncherUtil.getTorFile("pt-startup-dir", false).path,
       };
-      this._subprocess = await Subprocess.call(options);
-      this._dumpStdout();
-      this._watchProcess();
-      this._status = TorProcessStatus.Running;
-      this._torProcessStartTime = Date.now();
+      this.#subprocess = await Subprocess.call(options);
+      this.#status = TorProcessStatus.Running;
     } catch (e) {
-      this._status = TorProcessStatus.Exited;
-      this._subprocess = null;
+      this.#status = TorProcessStatus.Exited;
+      this.#subprocess = null;
       logger.error("startTor error:", e);
       throw e;
     }
+
+    // Do not await the following functions, as they will return only when the
+    // process exits.
+    this.#dumpStdout();
+    this.#watchProcess();
   }
 
   // Forget about a process.
   //
-  // Instead of killing the tor process, we  rely on the TAKEOWNERSHIP feature
+  // Instead of killing the tor process, we rely on the TAKEOWNERSHIP feature
   // to shut down tor when we close the control port connection.
   //
   // Previously, we sent a SIGNAL HALT command to the tor control port,
@@ -123,36 +154,38 @@ export class TorProcess {
   // Still, before closing the owning connection, this class should forget about
   // the process, so that future notifications will be ignored.
   forget() {
-    this._subprocess = null;
-    this._status = TorProcessStatus.Exited;
+    this.#subprocess = null;
+    this.#status = TorProcessStatus.Exited;
   }
 
   // The owner of the process can use this function to tell us that they
   // successfully connected to the control port. This information will be used
   // only to decide which text to show in the confirmation dialog if tor exits.
   connectionWorked() {
-    this._didConnectToTorControlPort = true;
+    this.#didConnectToTorControlPort = true;
   }
 
-  async _dumpStdout() {
+  async #dumpStdout() {
     let string;
     while (
-      this._subprocess &&
-      (string = await this._subprocess.stdout.readString())
+      this.#subprocess &&
+      (string = await this.#subprocess.stdout.readString())
     ) {
       dump(string);
     }
   }
 
-  async _watchProcess() {
-    const watched = this._subprocess;
+  async #watchProcess() {
+    const watched = this.#subprocess;
     if (!watched) {
       return;
     }
+    let processExitCode;
     try {
       const { exitCode } = await watched.wait();
+      processExitCode = exitCode;
 
-      if (watched !== this._subprocess) {
+      if (watched !== this.#subprocess) {
         logger.debug(`A Tor process exited with code ${exitCode}.`);
       } else if (exitCode) {
         logger.warn(`The watched Tor process exited with code ${exitCode}.`);
@@ -163,30 +196,31 @@ export class TorProcess {
       logger.error("Failed to watch the tor process", e);
     }
 
-    if (watched === this._subprocess) {
-      this._processExitedUnexpectedly();
+    if (watched === this.#subprocess) {
+      this.#processExitedUnexpectedly(processExitCode);
     }
   }
 
-  _processExitedUnexpectedly() {
-    this._subprocess = null;
-    this._status = TorProcessStatus.Exited;
+  #processExitedUnexpectedly(exitCode) {
+    this.#subprocess = null;
+    this.#status = TorProcessStatus.Exited;
 
     // TODO: Move this logic somewhere else?
     let s;
-    if (!this._didConnectToTorControlPort) {
+    if (!this.#didConnectToTorControlPort) {
       // tor might be misconfigured, becauser we could never connect to it
       const key = "tor_exited_during_startup";
-      s = TorLauncherUtil.getLocalizedString(key);
+      s = lazy.TorLauncherUtil.getLocalizedString(key);
     } else {
       // tor exited suddenly, so configuration should be okay
       s =
-        TorLauncherUtil.getLocalizedString("tor_exited") +
+        lazy.TorLauncherUtil.getLocalizedString("tor_exited") +
         "\n\n" +
-        TorLauncherUtil.getLocalizedString("tor_exited2");
+        lazy.TorLauncherUtil.getLocalizedString("tor_exited2");
     }
     logger.info(s);
-    const defaultBtnLabel = TorLauncherUtil.getLocalizedString("restart_tor");
+    const defaultBtnLabel =
+      lazy.TorLauncherUtil.getLocalizedString("restart_tor");
     let cancelBtnLabel = "OK";
     try {
       const kSysBundleURI = "chrome://global/locale/commonDialogs.properties";
@@ -196,51 +230,43 @@ export class TorProcess {
       logger.warn("Could not localize the cancel button", e);
     }
 
-    const restart = TorLauncherUtil.showConfirm(
+    const restart = lazy.TorLauncherUtil.showConfirm(
       null,
       s,
       defaultBtnLabel,
       cancelBtnLabel
     );
     if (restart) {
-      this.start().then(() => {
-        if (this.onRestart) {
-          this.onRestart();
-        }
-      });
-    } else if (this.onExit) {
-      this.onExit();
+      this.start().then(this.onRestart);
+    } else {
+      this.onExit(exitCode);
     }
   }
 
-  _makeArgs() {
-    // Ideally, we would cd to the Firefox application directory before
-    // starting tor (but we don't know how to do that). Instead, we
-    // rely on the TBB launcher to start Firefox from the right place.
-
+  #makeArgs() {
+    this.#exeFile = lazy.TorLauncherUtil.getTorFile("tor", false);
+    const torrcFile = lazy.TorLauncherUtil.getTorFile("torrc", true);
     // Get the Tor data directory first so it is created before we try to
     // construct paths to files that will be inside it.
-    this._exeFile = TorLauncherUtil.getTorFile("tor", false);
-    const torrcFile = TorLauncherUtil.getTorFile("torrc", true);
-    this._dataDir = TorLauncherUtil.getTorFile("tordatadir", true);
-    const onionAuthDir = TorLauncherUtil.getTorFile("toronionauthdir", true);
-    const hashedPassword = lazy.TorProtocolService.torGetPassword(true);
+    this.#dataDir = lazy.TorLauncherUtil.getTorFile("tordatadir", true);
+    const onionAuthDir = lazy.TorLauncherUtil.getTorFile(
+      "toronionauthdir",
+      true
+    );
     let detailsKey;
-    if (!this._exeFile) {
+    if (!this.#exeFile) {
       detailsKey = "tor_missing";
     } else if (!torrcFile) {
       detailsKey = "torrc_missing";
-    } else if (!this._dataDir) {
+    } else if (!this.#dataDir) {
       detailsKey = "datadir_missing";
     } else if (!onionAuthDir) {
       detailsKey = "onionauthdir_missing";
-    } else if (!hashedPassword) {
-      detailsKey = "password_hash_missing";
     }
     if (detailsKey) {
-      const details = TorLauncherUtil.getLocalizedString(detailsKey);
+      const details = lazy.TorLauncherUtil.getLocalizedString(detailsKey);
       const key = "unable_to_start_tor";
-      const err = TorLauncherUtil.getFormattedLocalizedString(
+      const err = lazy.TorLauncherUtil.getFormattedLocalizedString(
         key,
         [details],
         1
@@ -248,7 +274,7 @@ export class TorProcess {
       throw new Error(err);
     }
 
-    const torrcDefaultsFile = TorLauncherUtil.getTorFile(
+    const torrcDefaultsFile = lazy.TorLauncherUtil.getTorFile(
       "torrc-defaults",
       false
     );
@@ -258,77 +284,131 @@ export class TorProcess {
     const geoip6File = torrcDefaultsFile.clone();
     geoip6File.leafName = "geoip6";
 
-    this._args = [];
+    this.#args = [];
     if (torrcDefaultsFile) {
-      this._args.push("--defaults-torrc");
-      this._args.push(torrcDefaultsFile.path);
+      this.#args.push("--defaults-torrc", torrcDefaultsFile.path);
     }
-    this._args.push("-f");
-    this._args.push(torrcFile.path);
-    this._args.push("DataDirectory");
-    this._args.push(this._dataDir.path);
-    this._args.push("ClientOnionAuthDir");
-    this._args.push(onionAuthDir.path);
-    this._args.push("GeoIPFile");
-    this._args.push(geoipFile.path);
-    this._args.push("GeoIPv6File");
-    this._args.push(geoip6File.path);
-    this._args.push("HashedControlPassword");
-    this._args.push(hashedPassword);
+    this.#args.push("-f", torrcFile.path);
+    this.#args.push("DataDirectory", this.#dataDir.path);
+    this.#args.push("ClientOnionAuthDir", onionAuthDir.path);
+    this.#args.push("GeoIPFile", geoipFile.path);
+    this.#args.push("GeoIPv6File", geoip6File.path);
   }
 
-  _addControlPortArg() {
-    // Include a ControlPort argument to support switching between
-    // a TCP port and an IPC port (e.g., a Unix domain socket). We
-    // include a "+__" prefix so that (1) this control port is added
-    // to any control ports that the user has defined in their torrc
-    // file and (2) it is never written to torrc.
+  /**
+   * Add all the arguments related to the control port.
+   * We use the + prefix so that the the port is added to any other port already
+   * defined in the torrc, and the __ prefix so that it is never written to
+   * torrc.
+   */
+  #addControlPortArgs() {
+    if (!this.#controlSettings) {
+      return;
+    }
+
     let controlPortArg;
-    const controlIPCFile = lazy.TorProtocolService.torGetControlIPCFile();
-    const controlPort = lazy.TorProtocolService.torGetControlPort();
-    if (controlIPCFile) {
-      controlPortArg = this._ipcPortArg(controlIPCFile);
-    } else if (controlPort) {
-      controlPortArg = "" + controlPort;
+    if (this.#controlSettings.ipcFile) {
+      controlPortArg = this.#controlSettings.ipcFile;
+    } else if (this.#controlSettings.port) {
+      controlPortArg = this.#controlSettings.host
+        ? `${this.#controlSettings.host}:${this.#controlSettings.port}`
+        : this.#controlSettings.port.toString();
     }
     if (controlPortArg) {
-      this._args.push("+__ControlPort");
-      this._args.push(controlPortArg);
+      this.#args.push("+__ControlPort", controlPortArg);
+    }
+
+    if (this.#controlSettings.password) {
+      this.#args.push(
+        "HashedControlPassword",
+        this.#hashPassword(this.#controlSettings.password)
+      );
+    }
+    if (this.#controlSettings.cookieFilePath) {
+      this.#args.push("CookieAuthentication", "1");
+      this.#args.push("CookieAuthFile", this.#controlSettings.cookieFilePath);
     }
   }
 
-  _addSocksPortArg() {
-    // Include a SocksPort argument to support switching between
-    // a TCP port and an IPC port (e.g., a Unix domain socket). We
-    // include a "+__" prefix so that (1) this SOCKS port is added
-    // to any SOCKS ports that the user has defined in their torrc
-    // file and (2) it is never written to torrc.
-    const socksPortInfo = lazy.TorProtocolService.torGetSOCKSPortInfo();
-    if (socksPortInfo) {
-      let socksPortArg;
-      if (socksPortInfo.ipcFile) {
-        socksPortArg = this._ipcPortArg(socksPortInfo.ipcFile);
-      } else if (socksPortInfo.host && socksPortInfo.port != 0) {
-        socksPortArg = socksPortInfo.host + ":" + socksPortInfo.port;
-      }
-      if (socksPortArg) {
-        let socksPortFlags = Services.prefs.getCharPref(
-          "extensions.torlauncher.socks_port_flags",
-          "IPv6Traffic PreferIPv6 KeepAliveIsolateSOCKSAuth"
-        );
-        if (socksPortFlags) {
-          socksPortArg += " " + socksPortFlags;
-        }
-        this._args.push("+__SocksPort");
-        this._args.push(socksPortArg);
+  /**
+   * Add the argument related to the control port.
+   * We use the + prefix so that the the port is added to any other port already
+   * defined in the torrc, and the __ prefix so that it is never written to
+   * torrc.
+   */
+  #addSocksPortArg() {
+    let socksPortArg;
+    if (this.#socksSettings.ipcFile) {
+      socksPortArg = this.#socksSettings.ipcFile;
+    } else if (this.#socksSettings.port != 0) {
+      socksPortArg = this.#socksSettings.host
+        ? `${this.#socksSettings.host}:${this.#socksSettings.port}`
+        : this.#socksSettings.port.toString();
+    }
+    if (socksPortArg) {
+      const socksPortFlags = Services.prefs.getCharPref(
+        "extensions.torlauncher.socks_port_flags",
+        "IPv6Traffic PreferIPv6 KeepAliveIsolateSOCKSAuth"
+      );
+      if (socksPortFlags) {
+        socksPortArg += " " + socksPortFlags;
       }
+      this.#args.push("+__SocksPort", socksPortArg);
+    }
+  }
+
+  // Based on Vidalia's TorSettings::hashPassword().
+  #hashPassword(aHexPassword) {
+    if (!aHexPassword) {
+      return null;
     }
+
+    // Generate a random, 8 byte salt value.
+    const salt = Array.from(crypto.getRandomValues(new Uint8Array(8)));
+
+    // Convert hex-encoded password to an array of bytes.
+    const password = [];
+    for (let i = 0; i < aHexPassword.length; i += 2) {
+      password.push(parseInt(aHexPassword.substring(i, i + 2), 16));
+    }
+
+    // Run through the S2K algorithm and convert to a string.
+    const toHex = v => v.toString(16).padStart(2, "0");
+    const arrayToHex = aArray => aArray.map(toHex).join("");
+    const kCodedCount = 96;
+    const hashVal = this.#cryptoSecretToKey(password, salt, kCodedCount);
+    return "16:" + arrayToHex(salt) + toHex(kCodedCount) + arrayToHex(hashVal);
   }
 
-  // Return a ControlPort or SocksPort argument for aIPCFile (an nsIFile).
-  // The result is unix:/path or unix:"/path with spaces" with appropriate
-  // C-style escaping within the path portion.
-  _ipcPortArg(aIPCFile) {
-    return "unix:" + TorParsers.escapeString(aIPCFile.path);
+  // #cryptoSecretToKey() is similar to Vidalia's crypto_secret_to_key().
+  // It generates and returns a hash of aPassword by following the iterated
+  // and salted S2K algorithm (see RFC 2440 section 3.6.1.3).
+  // See also https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/control-spec.txt#L3824.
+  // Returns an array of bytes.
+  #cryptoSecretToKey(aPassword, aSalt, aCodedCount) {
+    const inputArray = aSalt.concat(aPassword);
+
+    // Subtle crypto only has the final digest, and does not allow incremental
+    // updates.
+    const hasher = Cc["@mozilla.org/security/hash;1"].createInstance(
+      Ci.nsICryptoHash
+    );
+    hasher.init(hasher.SHA1);
+    const kEXPBIAS = 6;
+    let count = (16 + (aCodedCount & 15)) << ((aCodedCount >> 4) + kEXPBIAS);
+    while (count > 0) {
+      if (count > inputArray.length) {
+        hasher.update(inputArray, inputArray.length);
+        count -= inputArray.length;
+      } else {
+        const finalArray = inputArray.slice(0, count);
+        hasher.update(finalArray, finalArray.length);
+        count = 0;
+      }
+    }
+    return hasher
+      .finish(false)
+      .split("")
+      .map(b => b.charCodeAt(0));
   }
 }


=====================================
toolkit/components/tor-launcher/TorProtocolService.sys.mjs
=====================================
@@ -289,9 +289,8 @@ export const TorProtocolService = {
   // are also used in torbutton.
 
   // Returns Tor password string or null if an error occurs.
-  torGetPassword(aPleaseHash) {
-    const pw = this._controlPassword;
-    return aPleaseHash ? this._hashPassword(pw) : pw;
+  torGetPassword() {
+    return this._controlPassword;
   },
 
   torGetControlIPCFile() {
@@ -306,6 +305,24 @@ export const TorProtocolService = {
     return this._SOCKSPortInfo;
   },
 
+  get torControlPortInfo() {
+    const info = {
+      password: this._controlPassword,
+    };
+    if (this._controlIPCFile) {
+      info.ipcFile = this._controlIPCFile?.clone();
+    }
+    if (this._controlPort) {
+      info.host = this._controlHost;
+      info.port = this._controlPort;
+    }
+    return info;
+  },
+
+  get torSOCKSPortInfo() {
+    return this._SOCKSPortInfo;
+  },
+
   // Public, but called only internally
 
   // Executes a command on the control port.
@@ -469,115 +486,8 @@ export const TorProtocolService = {
         this._controlPassword = this._generateRandomPassword();
       }
 
-      // Determine what kind of SOCKS port Tor and the browser will use.
-      // On Windows (where Unix domain sockets are not supported), TCP is
-      // always used.
-      //
-      // The following environment variables are supported and take
-      // precedence over preferences:
-      //    TOR_SOCKS_IPC_PATH  (file system path; ignored on Windows)
-      //    TOR_SOCKS_HOST
-      //    TOR_SOCKS_PORT
-      //
-      // The following preferences are consulted:
-      //    network.proxy.socks
-      //    network.proxy.socks_port
-      //    extensions.torlauncher.socks_port_use_ipc (Boolean)
-      //    extensions.torlauncher.socks_ipc_path (file system path)
-      // If extensions.torlauncher.socks_ipc_path is empty, a default
-      // path is used (<tor-data-directory>/socks.socket).
-      //
-      // When using TCP, if a value is not defined via an env variable it is
-      // taken from the corresponding browser preference if possible. The
-      // exceptions are:
-      //   If network.proxy.socks contains a file: URL, a default value of
-      //     "127.0.0.1" is used instead.
-      //   If the network.proxy.socks_port value is 0, a default value of
-      //     9150 is used instead.
-      //
-      // Supported scenarios:
-      // 1. By default, an IPC object at a default path is used.
-      // 2. If extensions.torlauncher.socks_port_use_ipc is set to false,
-      //    a TCP socket at 127.0.0.1:9150 is used, unless different values
-      //    are set in network.proxy.socks and network.proxy.socks_port.
-      // 3. If the TOR_SOCKS_IPC_PATH env var is set, an IPC object at that
-      //    path is used (e.g., a Unix domain socket).
-      // 4. If the TOR_SOCKS_HOST and/or TOR_SOCKS_PORT env vars are set, TCP
-      //    is used. Values not set via env vars will be taken from the
-      //    network.proxy.socks and network.proxy.socks_port prefs as described
-      //    above.
-      // 5. If extensions.torlauncher.socks_port_use_ipc is true and
-      //    extensions.torlauncher.socks_ipc_path is set, an IPC object at
-      //    the specified path is used.
-      // 6. Tor Launcher is disabled. Torbutton will respect the env vars if
-      //    present; if not, the values in network.proxy.socks and
-      //    network.proxy.socks_port are used without modification.
-
-      let useIPC;
-      this._SOCKSPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
-      if (!isWindows && Services.env.exists("TOR_SOCKS_IPC_PATH")) {
-        let ipcPath = Services.env.get("TOR_SOCKS_IPC_PATH");
-        this._SOCKSPortInfo.ipcFile = new lazy.FileUtils.File(ipcPath);
-        useIPC = true;
-      } else {
-        // Check for TCP host and port environment variables.
-        if (Services.env.exists("TOR_SOCKS_HOST")) {
-          this._SOCKSPortInfo.host = Services.env.get("TOR_SOCKS_HOST");
-          useIPC = false;
-        }
-        if (Services.env.exists("TOR_SOCKS_PORT")) {
-          this._SOCKSPortInfo.port = parseInt(
-            Services.env.get("TOR_SOCKS_PORT"),
-            10
-          );
-          useIPC = false;
-        }
-      }
-
-      if (useIPC === undefined) {
-        useIPC =
-          !isWindows &&
-          Services.prefs.getBoolPref(
-            "extensions.torlauncher.socks_port_use_ipc",
-            false
-          );
-      }
-
-      // Fill in missing SOCKS info from prefs.
-      if (useIPC) {
-        if (!this._SOCKSPortInfo.ipcFile) {
-          this._SOCKSPortInfo.ipcFile = TorLauncherUtil.getTorFile(
-            "socks_ipc",
-            false
-          );
-        }
-      } else {
-        if (!this._SOCKSPortInfo.host) {
-          let socksAddr = Services.prefs.getCharPref(
-            "network.proxy.socks",
-            "127.0.0.1"
-          );
-          let socksAddrHasHost = socksAddr && !socksAddr.startsWith("file:");
-          this._SOCKSPortInfo.host = socksAddrHasHost ? socksAddr : "127.0.0.1";
-        }
-
-        if (!this._SOCKSPortInfo.port) {
-          let socksPort = Services.prefs.getIntPref(
-            "network.proxy.socks_port",
-            0
-          );
-          // This pref is set as 0 by default in Firefox, use 9150 if we get 0.
-          this._SOCKSPortInfo.port = socksPort != 0 ? socksPort : 9150;
-        }
-      }
-
-      logger.info("SOCKS port type: " + (useIPC ? "IPC" : "TCP"));
-      if (useIPC) {
-        logger.info(`ipcFile: ${this._SOCKSPortInfo.ipcFile.path}`);
-      } else {
-        logger.info(`SOCKS host: ${this._SOCKSPortInfo.host}`);
-        logger.info(`SOCKS port: ${this._SOCKSPortInfo.port}`);
-      }
+      this._SOCKSPortInfo = TorLauncherUtil.getPreferredSocksConfiguration();
+      TorLauncherUtil.setProxyConfiguration(this._SOCKSPortInfo);
 
       // Set the global control port info parameters.
       // These values may be overwritten by torbutton when it initializes, but
@@ -781,38 +691,6 @@ export const TorProtocolService = {
     return pwd;
   },
 
-  // Based on Vidalia's TorSettings::hashPassword().
-  _hashPassword(aHexPassword) {
-    if (!aHexPassword) {
-      return null;
-    }
-
-    // Generate a random, 8 byte salt value.
-    const salt = Array.from(crypto.getRandomValues(new Uint8Array(8)));
-
-    // Convert hex-encoded password to an array of bytes.
-    const password = [];
-    for (let i = 0; i < aHexPassword.length; i += 2) {
-      password.push(parseInt(aHexPassword.substring(i, i + 2), 16));
-    }
-
-    // Run through the S2K algorithm and convert to a string.
-    const kCodedCount = 96;
-    const hashVal = this._cryptoSecretToKey(password, salt, kCodedCount);
-    if (!hashVal) {
-      logger.error("_cryptoSecretToKey() failed");
-      return null;
-    }
-
-    const arrayToHex = aArray =>
-      aArray.map(item => this._toHex(item, 2)).join("");
-    let rv = "16:";
-    rv += arrayToHex(salt);
-    rv += this._toHex(kCodedCount, 2);
-    rv += arrayToHex(hashVal);
-    return rv;
-  },
-
   // Returns -1 upon failure.
   _cryptoRandInt(aMax) {
     // Based on tor's crypto_rand_int().
@@ -831,43 +709,6 @@ export const TorProtocolService = {
     return val % aMax;
   },
 
-  // _cryptoSecretToKey() is similar to Vidalia's crypto_secret_to_key().
-  // It generates and returns a hash of aPassword by following the iterated
-  // and salted S2K algorithm (see RFC 2440 section 3.6.1.3).
-  // Returns an array of bytes.
-  _cryptoSecretToKey(aPassword, aSalt, aCodedCount) {
-    if (!aPassword || !aSalt) {
-      return null;
-    }
-
-    const inputArray = aSalt.concat(aPassword);
-
-    // Subtle crypto only has the final digest, and does not allow incremental
-    // updates. Also, it is async, so we should hash and keep the hash in a
-    // variable if we wanted to switch to getters.
-    // So, keeping this implementation should be okay for now.
-    const hasher = Cc["@mozilla.org/security/hash;1"].createInstance(
-      Ci.nsICryptoHash
-    );
-    hasher.init(hasher.SHA1);
-    const kEXPBIAS = 6;
-    let count = (16 + (aCodedCount & 15)) << ((aCodedCount >> 4) + kEXPBIAS);
-    while (count > 0) {
-      if (count > inputArray.length) {
-        hasher.update(inputArray, inputArray.length);
-        count -= inputArray.length;
-      } else {
-        const finalArray = inputArray.slice(0, count);
-        hasher.update(finalArray, finalArray.length);
-        count = 0;
-      }
-    }
-    return hasher
-      .finish(false)
-      .split("")
-      .map(b => b.charCodeAt(0));
-  },
-
   _toHex(aValue, aMinLen) {
     return aValue.toString(16).padStart(aMinLen, "0");
   },


=====================================
toolkit/torbutton/chrome/content/torbutton.js
=====================================
@@ -60,7 +60,7 @@ var torbutton_init;
     } else {
       try {
         // Try to get password from Tor Launcher.
-        m_tb_control_pass = TorProtocolService.torGetPassword(false);
+        m_tb_control_pass = TorProtocolService.torGetPassword();
       } catch (e) {}
     }
 


=====================================
toolkit/torbutton/components.conf
=====================================
@@ -1,12 +1,4 @@
 Classes = [
-    {
-        "cid": "{06322def-6fde-4c06-aef6-47ae8e799629}",
-        "contract_ids": [
-            "@torproject.org/startup-observer;1"
-        ],
-        "jsm": "resource://torbutton/modules/TorbuttonStartupObserver.jsm",
-        "constructor": "StartupObserver",
-    },
     {
         "cid": "{f36d72c9-9718-4134-b550-e109638331d7}",
         "contract_ids": [


=====================================
toolkit/torbutton/modules/TorbuttonStartupObserver.jsm deleted
=====================================
@@ -1,138 +0,0 @@
-// Bug 1506 P1-3: This code is mostly hackish remnants of session store
-// support. There are a couple of observer events that *might* be worth
-// listening to. Search for 1506 in the code.
-
-/*************************************************************************
- * Startup observer (JavaScript XPCOM component)
- *
- * Cases tested (each during Tor and Non-Tor, FF4 and FF3.6)
- *    1. Crash
- *    2. Upgrade
- *    3. Fresh install
- *
- *************************************************************************/
-
-var EXPORTED_SYMBOLS = ["StartupObserver"];
-
-const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-const { XPCOMUtils } = ChromeUtils.import(
-  "resource://gre/modules/XPCOMUtils.jsm"
-);
-
-const { TorProtocolService } = ChromeUtils.import(
-  "resource://gre/modules/TorProtocolService.jsm"
-);
-
-const lazy = {};
-
-XPCOMUtils.defineLazyModuleGetters(lazy, {
-  FileUtils: "resource://gre/modules/FileUtils.jsm",
-});
-
-function StartupObserver() {
-  this.logger = Cc["@torproject.org/torbutton-logger;1"].getService(
-    Ci.nsISupports
-  ).wrappedJSObject;
-  this._prefs = Services.prefs;
-  this.logger.log(3, "Startup Observer created");
-
-  try {
-    // XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
-    // before the initial SSL-Observatory test... If we lose the race, Firefox
-    // caches the old proxy settings for check.tp.o somehwere, and it never loads :(
-    this.setProxySettings();
-  } catch (e) {
-    this.logger.log(
-      4,
-      "Early proxy change failed. Will try again at profile load. Error: " + e
-    );
-  }
-}
-
-StartupObserver.prototype = {
-  // Bug 6803: We need to get the env vars early due to
-  // some weird proxy caching code that showed up in FF15.
-  // Otherwise, homepage domain loads fail forever.
-  setProxySettings() {
-    // Bug 1506: Still want to get these env vars
-    if (Services.env.exists("TOR_TRANSPROXY")) {
-      this.logger.log(3, "Resetting Tor settings to transproxy");
-      this._prefs.setBoolPref("network.proxy.socks_remote_dns", false);
-      this._prefs.setIntPref("network.proxy.type", 0);
-      this._prefs.setIntPref("network.proxy.socks_port", 0);
-      this._prefs.setCharPref("network.proxy.socks", "");
-    } else {
-      // Try to retrieve SOCKS proxy settings from Tor Launcher.
-      let socksPortInfo;
-      try {
-        socksPortInfo = TorProtocolService.torGetSOCKSPortInfo();
-      } catch (e) {
-        this.logger.log(3, "tor launcher failed " + e);
-      }
-
-      // If Tor Launcher is not available, check environment variables.
-      if (!socksPortInfo) {
-        socksPortInfo = { ipcFile: undefined, host: undefined, port: 0 };
-
-        let isWindows = Services.appinfo.OS === "WINNT";
-        if (!isWindows && Services.env.exists("TOR_SOCKS_IPC_PATH")) {
-          socksPortInfo.ipcFile = new lazy.FileUtils.File(
-            Services.env.get("TOR_SOCKS_IPC_PATH")
-          );
-        } else {
-          if (Services.env.exists("TOR_SOCKS_HOST")) {
-            socksPortInfo.host = Services.env.get("TOR_SOCKS_HOST");
-          }
-          if (Services.env.exists("TOR_SOCKS_PORT")) {
-            socksPortInfo.port = parseInt(Services.env.get("TOR_SOCKS_PORT"));
-          }
-        }
-      }
-
-      // Adjust network.proxy prefs.
-      if (socksPortInfo.ipcFile) {
-        let fph = Services.io
-          .getProtocolHandler("file")
-          .QueryInterface(Ci.nsIFileProtocolHandler);
-        let fileURI = fph.newFileURI(socksPortInfo.ipcFile);
-        this.logger.log(3, "Reset socks to " + fileURI.spec);
-        this._prefs.setCharPref("network.proxy.socks", fileURI.spec);
-        this._prefs.setIntPref("network.proxy.socks_port", 0);
-      } else {
-        if (socksPortInfo.host) {
-          this._prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
-          this.logger.log(3, "Reset socks host to " + socksPortInfo.host);
-        }
-        if (socksPortInfo.port) {
-          this._prefs.setIntPref(
-            "network.proxy.socks_port",
-            socksPortInfo.port
-          );
-          this.logger.log(3, "Reset socks port to " + socksPortInfo.port);
-        }
-      }
-
-      if (socksPortInfo.ipcFile || socksPortInfo.host || socksPortInfo.port) {
-        this._prefs.setBoolPref("network.proxy.socks_remote_dns", true);
-        this._prefs.setIntPref("network.proxy.type", 1);
-      }
-    }
-
-    // Force prefs to be synced to disk
-    Services.prefs.savePrefFile(null);
-
-    this.logger.log(3, "Synced network settings to environment.");
-  },
-
-  observe(subject, topic, data) {
-    if (topic == "profile-after-change") {
-      this.setProxySettings();
-    }
-
-    // In all cases, force prefs to be synced to disk
-    Services.prefs.savePrefFile(null);
-  },
-
-  // Hack to get us registered early to observe recovery
-  _xpcom_categories: [{ category: "profile-after-change" }],
-};


=====================================
toolkit/torbutton/moz.build
=====================================
@@ -8,7 +8,3 @@ JAR_MANIFESTS += ['jar.mn']
 XPCOM_MANIFESTS += [
     "components.conf",
 ]
-
-EXTRA_COMPONENTS += [
-    "torbutton.manifest",
-]


=====================================
toolkit/torbutton/torbutton.manifest deleted
=====================================
@@ -1 +0,0 @@
-category profile-after-change StartupObserver @torproject.org/startup-observer;1



View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/f0493f9f8602a2c59c30cc2614f53b56c29f4f40...c4e8cd0f05884220aaf13fad10b1ac16d561a2a6

-- 
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/f0493f9f8602a2c59c30cc2614f53b56c29f4f40...c4e8cd0f05884220aaf13fad10b1ac16d561a2a6
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/20230731/76f62e16/attachment-0001.htm>


More information about the tor-commits mailing list