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/*
-@RESPATH@/components/torbutton.manifest
@RESPATH@/chrome/toolkit@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….
+ // 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/f0493f…
--
View it on GitLab: https://gitlab.torproject.org/tpo/applications/tor-browser/-/compare/f0493f…
You're receiving this email because of your account on gitlab.torproject.org.