Pier Angelo Vendrame pushed to branch tor-browser-115.8.0esr-13.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
9cecc61f
by Pier Angelo Vendrame at 2024-03-11T09:33:51+01:00
-
138e8d6b
by Pier Angelo Vendrame at 2024-03-11T16:19:47+01:00
-
6265cc34
by Pier Angelo Vendrame at 2024-03-11T16:19:52+01:00
-
e409c32a
by Pier Angelo Vendrame at 2024-03-11T16:19:52+01:00
-
f8451ae0
by Pier Angelo Vendrame at 2024-03-11T16:19:53+01:00
10 changed files:
- browser/components/torpreferences/content/connectionPane.js
- browser/components/torpreferences/content/connectionSettingsDialog.js
- toolkit/components/tor-launcher/TorControlPort.sys.mjs
- toolkit/components/tor-launcher/TorProvider.sys.mjs
- toolkit/components/tor-launcher/TorProviderBuilder.sys.mjs
- toolkit/components/tor-launcher/TorStartupService.sys.mjs
- toolkit/modules/Moat.sys.mjs
- toolkit/modules/TorAndroidIntegration.sys.mjs
- toolkit/modules/TorConnect.sys.mjs
- toolkit/modules/TorSettings.sys.mjs
Changes:
... | ... | @@ -114,10 +114,9 @@ async function setTorSettings(changes) { |
114 | 114 | // This will trigger TorSettings.#cleanupSettings()
|
115 | 115 | TorSettings.saveToPrefs();
|
116 | 116 | try {
|
117 | - // May throw.
|
|
118 | 117 | await TorSettings.applySettings();
|
119 | 118 | } catch (e) {
|
120 | - console.error("Failed to save Tor settings", e);
|
|
119 | + console.error("Failed to apply Tor settings", e);
|
|
121 | 120 | }
|
122 | 121 | } finally {
|
123 | 122 | TorSettings.thawNotifications();
|
... | ... | @@ -362,6 +362,8 @@ const gConnectionSettingsDialog = { |
362 | 362 | }
|
363 | 363 | |
364 | 364 | TorSettings.saveToPrefs();
|
365 | + // FIXME: What if this fails? Should we prevent the dialog to close and show
|
|
366 | + // an error?
|
|
365 | 367 | TorSettings.applySettings();
|
366 | 368 | },
|
367 | 369 | };
|
... | ... | @@ -838,10 +838,12 @@ export class TorController { |
838 | 838 | /**
|
839 | 839 | * Send multiple configuration values to tor.
|
840 | 840 | *
|
841 | - * @param {object} values The values to set
|
|
841 | + * @param {Array} values The values to set. It should be an array of
|
|
842 | + * [key, value] pairs to pass to SETCONF. Keys can be repeated, and array
|
|
843 | + * values will be automatically unrolled.
|
|
842 | 844 | */
|
843 | 845 | async setConf(values) {
|
844 | - const args = Object.entries(values)
|
|
846 | + const args = values
|
|
845 | 847 | .flatMap(([key, value]) => {
|
846 | 848 | if (value === undefined || value === null) {
|
847 | 849 | return [key];
|
... | ... | @@ -871,7 +873,7 @@ export class TorController { |
871 | 873 | * @param {boolean} enabled Tell whether the network should be enabled
|
872 | 874 | */
|
873 | 875 | async setNetworkEnabled(enabled) {
|
874 | - return this.setConf({ DisableNetwork: !enabled });
|
|
876 | + return this.setConf([["DisableNetwork", !enabled]]);
|
|
875 | 877 | }
|
876 | 878 | |
877 | 879 | /**
|
... | ... | @@ -15,6 +15,8 @@ ChromeUtils.defineESModuleGetters(lazy, { |
15 | 15 | TorController: "resource://gre/modules/TorControlPort.sys.mjs",
|
16 | 16 | TorProcess: "resource://gre/modules/TorProcess.sys.mjs",
|
17 | 17 | TorProcessAndroid: "resource://gre/modules/TorProcessAndroid.sys.mjs",
|
18 | + TorProxyType: "resource://gre/modules/TorSettings.sys.mjs",
|
|
19 | + TorSettings: "resource://gre/modules/TorSettings.sys.mjs",
|
|
18 | 20 | });
|
19 | 21 | |
20 | 22 | const logger = new ConsoleAPI({
|
... | ... | @@ -73,6 +75,20 @@ const Preferences = Object.freeze({ |
73 | 75 | PromptAtStartup: "extensions.torlauncher.prompt_at_startup",
|
74 | 76 | });
|
75 | 77 | |
78 | +/* Config Keys used to configure tor daemon */
|
|
79 | +const TorConfigKeys = Object.freeze({
|
|
80 | + useBridges: "UseBridges",
|
|
81 | + bridgeList: "Bridge",
|
|
82 | + socks4Proxy: "Socks4Proxy",
|
|
83 | + socks5Proxy: "Socks5Proxy",
|
|
84 | + socks5ProxyUsername: "Socks5ProxyUsername",
|
|
85 | + socks5ProxyPassword: "Socks5ProxyPassword",
|
|
86 | + httpsProxy: "HTTPSProxy",
|
|
87 | + httpsProxyAuthenticator: "HTTPSProxyAuthenticator",
|
|
88 | + reachableAddresses: "ReachableAddresses",
|
|
89 | + clientTransportPlugin: "ClientTransportPlugin",
|
|
90 | +});
|
|
91 | + |
|
76 | 92 | /**
|
77 | 93 | * This is a Tor provider for the C Tor daemon.
|
78 | 94 | *
|
... | ... | @@ -166,15 +182,6 @@ export class TorProvider { |
166 | 182 | */
|
167 | 183 | #currentBridge = null;
|
168 | 184 | |
169 | - /**
|
|
170 | - * Maintain a map of tor settings set by Tor Browser so that we don't
|
|
171 | - * repeatedly set the same key/values over and over.
|
|
172 | - * This map contains string keys to primitives or array values.
|
|
173 | - *
|
|
174 | - * @type {Map<string, any>}
|
|
175 | - */
|
|
176 | - #settingsCache = new Map();
|
|
177 | - |
|
178 | 185 | /**
|
179 | 186 | * Starts a new tor process and connect to its control port, or connect to the
|
180 | 187 | * control port of an existing tor daemon.
|
... | ... | @@ -219,13 +226,22 @@ export class TorProvider { |
219 | 226 | throw e;
|
220 | 227 | }
|
221 | 228 | |
229 | + try {
|
|
230 | + await lazy.TorSettings.initializedPromise;
|
|
231 | + await this.writeSettings(lazy.TorSettings.getSettings());
|
|
232 | + } catch (e) {
|
|
233 | + logger.warn(
|
|
234 | + "Failed to initialize TorSettings or to write our settings, so uninitializing.",
|
|
235 | + e
|
|
236 | + );
|
|
237 | + this.uninit();
|
|
238 | + throw e;
|
|
239 | + }
|
|
240 | + |
|
222 | 241 | TorLauncherUtil.setProxyConfiguration(this.#socksSettings);
|
223 | 242 | |
224 | 243 | logger.info("The Tor provider is ready.");
|
225 | 244 | |
226 | - logger.debug(`Notifying ${TorProviderTopics.ProcessIsReady}`);
|
|
227 | - Services.obs.notifyObservers(null, TorProviderTopics.ProcessIsReady);
|
|
228 | - |
|
229 | 245 | // If we are using an external Tor daemon, we might need to fetch circuits
|
230 | 246 | // already, in case streams use them. Do not await because we do not want to
|
231 | 247 | // block the intialization on this (it should not fail anyway...).
|
... | ... | @@ -252,42 +268,74 @@ export class TorProvider { |
252 | 268 | |
253 | 269 | // Provider API
|
254 | 270 | |
255 | - async writeSettings(settingsObj) {
|
|
256 | - // TODO: Move the translation from settings object to settings understood by
|
|
257 | - // tor here.
|
|
258 | - const entries =
|
|
259 | - settingsObj instanceof Map
|
|
260 | - ? Array.from(settingsObj.entries())
|
|
261 | - : Object.entries(settingsObj);
|
|
262 | - // only write settings that have changed
|
|
263 | - const newSettings = entries.filter(([setting, value]) => {
|
|
264 | - if (!this.#settingsCache.has(setting)) {
|
|
265 | - // no cached setting, so write
|
|
266 | - return true;
|
|
267 | - }
|
|
271 | + /**
|
|
272 | + * Send settings to the tor daemon.
|
|
273 | + *
|
|
274 | + * @param {object} settings A settings object, as returned by
|
|
275 | + * TorSettings.getSettings(). This allow to try settings without passing
|
|
276 | + * through TorSettings.
|
|
277 | + */
|
|
278 | + async writeSettings(settings) {
|
|
279 | + logger.debug("TorProvider.writeSettings", settings);
|
|
280 | + const torSettings = new Map();
|
|
281 | + |
|
282 | + // Bridges
|
|
283 | + const haveBridges =
|
|
284 | + settings.bridges?.enabled && !!settings.bridges.bridge_strings.length;
|
|
285 | + torSettings.set(TorConfigKeys.useBridges, haveBridges);
|
|
286 | + if (haveBridges) {
|
|
287 | + torSettings.set(
|
|
288 | + TorConfigKeys.bridgeList,
|
|
289 | + settings.bridges.bridge_strings
|
|
290 | + );
|
|
291 | + } else {
|
|
292 | + torSettings.set(TorConfigKeys.bridgeList, null);
|
|
293 | + }
|
|
268 | 294 | |
269 | - const cachedValue = this.#settingsCache.get(setting);
|
|
270 | - // Arrays are the only special case for which === could fail.
|
|
271 | - // The other values we accept (strings, booleans, numbers, null and
|
|
272 | - // undefined) work correctly with ===.
|
|
273 | - if (Array.isArray(value) && Array.isArray(cachedValue)) {
|
|
274 | - return (
|
|
275 | - value.length !== cachedValue.length ||
|
|
276 | - value.some((val, idx) => val !== cachedValue[idx])
|
|
295 | + // Proxy
|
|
296 | + torSettings.set(TorConfigKeys.socks4Proxy, null);
|
|
297 | + torSettings.set(TorConfigKeys.socks5Proxy, null);
|
|
298 | + torSettings.set(TorConfigKeys.socks5ProxyUsername, null);
|
|
299 | + torSettings.set(TorConfigKeys.socks5ProxyPassword, null);
|
|
300 | + torSettings.set(TorConfigKeys.httpsProxy, null);
|
|
301 | + torSettings.set(TorConfigKeys.httpsProxyAuthenticator, null);
|
|
302 | + if (settings.proxy && !settings.proxy.enabled) {
|
|
303 | + settings.proxy.type = null;
|
|
304 | + }
|
|
305 | + const address = settings.proxy?.address;
|
|
306 | + const port = settings.proxy?.port;
|
|
307 | + const username = settings.proxy?.username;
|
|
308 | + const password = settings.proxy?.password;
|
|
309 | + switch (settings.proxy?.type) {
|
|
310 | + case lazy.TorProxyType.Socks4:
|
|
311 | + torSettings.set(TorConfigKeys.socks4Proxy, `${address}:${port}`);
|
|
312 | + break;
|
|
313 | + case lazy.TorProxyType.Socks5:
|
|
314 | + torSettings.set(TorConfigKeys.socks5Proxy, `${address}:${port}`);
|
|
315 | + torSettings.set(TorConfigKeys.socks5ProxyUsername, username);
|
|
316 | + torSettings.set(TorConfigKeys.socks5ProxyPassword, password);
|
|
317 | + break;
|
|
318 | + case lazy.TorProxyType.HTTPS:
|
|
319 | + torSettings.set(TorConfigKeys.httpsProxy, `${address}:${port}`);
|
|
320 | + torSettings.set(
|
|
321 | + TorConfigKeys.httpsProxyAuthenticator,
|
|
322 | + `${username}:${password}`
|
|
277 | 323 | );
|
278 | - }
|
|
279 | - return value !== cachedValue;
|
|
280 | - });
|
|
281 | - |
|
282 | - // only write if new setting to save
|
|
283 | - if (newSettings.length) {
|
|
284 | - await this.#controller.setConf(Object.fromEntries(newSettings));
|
|
324 | + break;
|
|
325 | + }
|
|
285 | 326 | |
286 | - // save settings to cache after successfully writing to Tor
|
|
287 | - for (const [setting, value] of newSettings) {
|
|
288 | - this.#settingsCache.set(setting, value);
|
|
289 | - }
|
|
327 | + // Firewall
|
|
328 | + if (settings.firewall?.enabled) {
|
|
329 | + const reachableAddresses = settings.firewall.allowed_ports
|
|
330 | + .map(port => `*:${port}`)
|
|
331 | + .join(",");
|
|
332 | + torSettings.set(TorConfigKeys.reachableAddresses, reachableAddresses);
|
|
333 | + } else {
|
|
334 | + torSettings.set(TorConfigKeys.reachableAddresses, null);
|
|
290 | 335 | }
|
336 | + |
|
337 | + logger.debug("Mapped settings object", settings, torSettings);
|
|
338 | + await this.#controller.setConf(Array.from(torSettings));
|
|
291 | 339 | }
|
292 | 340 | |
293 | 341 | async flushSettings() {
|
... | ... | @@ -9,7 +9,6 @@ ChromeUtils.defineESModuleGetters(lazy, { |
9 | 9 | });
|
10 | 10 | |
11 | 11 | export const TorProviderTopics = Object.freeze({
|
12 | - ProcessIsReady: "TorProcessIsReady",
|
|
13 | 12 | ProcessExited: "TorProcessExited",
|
14 | 13 | BootstrapStatus: "TorBootstrapStatus",
|
15 | 14 | BootstrapError: "TorBootstrapError",
|
... | ... | @@ -31,15 +31,16 @@ export class TorStartupService { |
31 | 31 | }
|
32 | 32 | }
|
33 | 33 | |
34 | - async #init() {
|
|
34 | + #init() {
|
|
35 | 35 | Services.obs.addObserver(this, BrowserTopics.QuitApplicationGranted);
|
36 | 36 | |
37 | - // Do not await on this init. build() is expected to await the
|
|
38 | - // initialization, so anything that should need the Tor Provider should
|
|
39 | - // block there, instead.
|
|
37 | + lazy.TorSettings.init();
|
|
38 | + |
|
39 | + // Theoretically, build() is expected to await the initialization of the
|
|
40 | + // provider, and anything needing the Tor Provider should be able to just
|
|
41 | + // await on TorProviderBuilder.build().
|
|
40 | 42 | lazy.TorProviderBuilder.init();
|
41 | 43 | |
42 | - await lazy.TorSettings.init();
|
|
43 | 44 | lazy.TorConnect.init();
|
44 | 45 | |
45 | 46 | lazy.TorDomainIsolator.init();
|
... | ... | @@ -2,13 +2,13 @@ |
2 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
|
3 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4 | 4 | |
5 | -import { TorBridgeSource } from "resource://gre/modules/TorSettings.sys.mjs";
|
|
6 | - |
|
7 | 5 | const lazy = {};
|
8 | 6 | |
9 | 7 | ChromeUtils.defineESModuleGetters(lazy, {
|
10 | 8 | DomainFrontRequestBuilder:
|
11 | 9 | "resource://gre/modules/DomainFrontedRequests.sys.mjs",
|
10 | + TorBridgeSource: "resource://gre/modules/TorSettings.sys.mjs",
|
|
11 | + TorSettings: "resource://gre/modules/TorSettings.sys.mjs",
|
|
12 | 12 | });
|
13 | 13 | |
14 | 14 | const TorLauncherPrefs = Object.freeze({
|
... | ... | @@ -211,13 +211,23 @@ export class MoatRPC { |
211 | 211 | };
|
212 | 212 | switch (settings.bridges.source) {
|
213 | 213 | case "builtin":
|
214 | - retval.bridges.source = TorBridgeSource.BuiltIn;
|
|
214 | + retval.bridges.source = lazy.TorBridgeSource.BuiltIn;
|
|
215 | 215 | retval.bridges.builtin_type = settings.bridges.type;
|
216 | 216 | // TorSettings will ignore strings for built-in bridges, and use the
|
217 | - // ones it already knows, instead.
|
|
217 | + // ones it already knows, instead. However, when we try these settings
|
|
218 | + // in the connect assist, we skip TorSettings. Therefore, we set the
|
|
219 | + // lines also here (the ones we already known, not the ones we receive
|
|
220 | + // from Moat). This needs TorSettings to be initialized, which by now
|
|
221 | + // should have already happened (this method is used only by TorConnect,
|
|
222 | + // that needs TorSettings to be initialized).
|
|
223 | + // In any case, getBuiltinBridges will throw if the data is not ready,
|
|
224 | + // yet.
|
|
225 | + retval.bridges.bridge_strings = lazy.TorSettings.getBuiltinBridges(
|
|
226 | + settings.bridges.type
|
|
227 | + );
|
|
218 | 228 | break;
|
219 | 229 | case "bridgedb":
|
220 | - retval.bridges.source = TorBridgeSource.BridgeDB;
|
|
230 | + retval.bridges.source = lazy.TorBridgeSource.BridgeDB;
|
|
221 | 231 | if (settings.bridges.bridge_strings) {
|
222 | 232 | retval.bridges.bridge_strings = settings.bridges.bridge_strings;
|
223 | 233 | } else {
|
... | ... | @@ -150,7 +150,7 @@ class TorAndroidIntegrationImpl { |
150 | 150 | lazy.TorSettings.saveToPrefs();
|
151 | 151 | }
|
152 | 152 | if (data.apply) {
|
153 | - lazy.TorSettings.applySettings();
|
|
153 | + await lazy.TorSettings.applySettings();
|
|
154 | 154 | }
|
155 | 155 | break;
|
156 | 156 | case ListenedEvents.settingsApply:
|
... | ... | @@ -2,14 +2,17 @@ |
2 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
|
3 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
4 | 4 | |
5 | +import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
|
|
5 | 6 | import { setTimeout, clearTimeout } from "resource://gre/modules/Timer.sys.mjs";
|
6 | 7 | |
7 | 8 | const lazy = {};
|
8 | 9 | |
9 | 10 | ChromeUtils.defineESModuleGetters(lazy, {
|
11 | + ConsoleAPI: "resource://gre/modules/Console.sys.mjs",
|
|
10 | 12 | EventDispatcher: "resource://gre/modules/Messaging.sys.mjs",
|
11 | 13 | MoatRPC: "resource://gre/modules/Moat.sys.mjs",
|
12 | 14 | TorBootstrapRequest: "resource://gre/modules/TorBootstrapRequest.sys.mjs",
|
15 | + TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
13 | 16 | });
|
14 | 17 | |
15 | 18 | // TODO: Should we move this to the about:torconnect actor?
|
... | ... | @@ -20,10 +23,7 @@ ChromeUtils.defineModuleGetter( |
20 | 23 | );
|
21 | 24 | |
22 | 25 | import { TorLauncherUtil } from "resource://gre/modules/TorLauncherUtil.sys.mjs";
|
23 | -import {
|
|
24 | - TorSettings,
|
|
25 | - TorSettingsTopics,
|
|
26 | -} from "resource://gre/modules/TorSettings.sys.mjs";
|
|
26 | +import { TorSettings } from "resource://gre/modules/TorSettings.sys.mjs";
|
|
27 | 27 | |
28 | 28 | import { TorStrings } from "resource://gre/modules/TorStrings.sys.mjs";
|
29 | 29 | |
... | ... | @@ -40,6 +40,7 @@ const TorLauncherPrefs = Object.freeze({ |
40 | 40 | const TorConnectPrefs = Object.freeze({
|
41 | 41 | censorship_level: "torbrowser.debug.censorship_level",
|
42 | 42 | allow_internet_test: "torbrowser.bootstrap.allow_internet_test",
|
43 | + log_level: "torbrowser.bootstrap.log_level",
|
|
43 | 44 | });
|
44 | 45 | |
45 | 46 | export const TorConnectState = Object.freeze({
|
... | ... | @@ -59,6 +60,17 @@ export const TorConnectState = Object.freeze({ |
59 | 60 | Disabled: "Disabled",
|
60 | 61 | });
|
61 | 62 | |
63 | +XPCOMUtils.defineLazyGetter(
|
|
64 | + lazy,
|
|
65 | + "logger",
|
|
66 | + () =>
|
|
67 | + new lazy.ConsoleAPI({
|
|
68 | + maxLogLevel: "info",
|
|
69 | + maxLogLevelPref: TorConnectPrefs.log_level,
|
|
70 | + prefix: "TorConnect",
|
|
71 | + })
|
|
72 | +);
|
|
73 | + |
|
62 | 74 | /*
|
63 | 75 | TorConnect State Transitions
|
64 | 76 | |
... | ... | @@ -194,12 +206,12 @@ class StateCallback { |
194 | 206 | }
|
195 | 207 | |
196 | 208 | async begin(...args) {
|
197 | - console.log(`TorConnect: Entering ${this._state} state`);
|
|
209 | + lazy.logger.trace(`Entering ${this._state} state`);
|
|
198 | 210 | this._init();
|
199 | 211 | try {
|
200 | 212 | // this Promise will block until this StateCallback has completed its work
|
201 | 213 | await Promise.resolve(this._callback.call(this._context, ...args));
|
202 | - console.log(`TorConnect: Exited ${this._state} state`);
|
|
214 | + lazy.logger.info(`Exited ${this._state} state`);
|
|
203 | 215 | |
204 | 216 | // handled state transition
|
205 | 217 | Services.obs.notifyObservers(
|
... | ... | @@ -267,16 +279,14 @@ class InternetTest { |
267 | 279 | this.cancel();
|
268 | 280 | this._pending = true;
|
269 | 281 | |
270 | - console.log("TorConnect: starting the Internet test");
|
|
282 | + lazy.logger.info("Starting the Internet test");
|
|
271 | 283 | this._testAsync()
|
272 | 284 | .then(status => {
|
273 | 285 | this._pending = false;
|
274 | 286 | this._status = status.successful
|
275 | 287 | ? InternetStatus.Online
|
276 | 288 | : InternetStatus.Offline;
|
277 | - console.log(
|
|
278 | - `TorConnect: performed Internet test, outcome ${this._status}`
|
|
279 | - );
|
|
289 | + lazy.logger.info(`Performed Internet test, outcome ${this._status}`);
|
|
280 | 290 | this.onResult(this.status, status.date);
|
281 | 291 | })
|
282 | 292 | .catch(error => {
|
... | ... | @@ -305,7 +315,7 @@ class InternetTest { |
305 | 315 | await mrpc.init();
|
306 | 316 | status = await mrpc.testInternetConnection();
|
307 | 317 | } catch (err) {
|
308 | - console.error("Error while checking the Internet connection", err);
|
|
318 | + lazy.logger.error("Error while checking the Internet connection", err);
|
|
309 | 319 | error = err;
|
310 | 320 | } finally {
|
311 | 321 | mrpc.uninit();
|
... | ... | @@ -523,8 +533,8 @@ export const TorConnect = (() => { |
523 | 533 | // get "Building circuits: Establishing a Tor circuit failed".
|
524 | 534 | // TODO: Maybe move this logic deeper in the process to know
|
525 | 535 | // when to filter out such errors triggered by cancelling.
|
526 | - console.log(
|
|
527 | - `TorConnect: Post-cancel error => ${message}; ${details}`
|
|
536 | + lazy.logger.warn(
|
|
537 | + `Post-cancel error => ${message}; ${details}`
|
|
528 | 538 | );
|
529 | 539 | return;
|
530 | 540 | }
|
... | ... | @@ -628,7 +638,7 @@ export const TorConnect = (() => { |
628 | 638 | "vanilla",
|
629 | 639 | ]);
|
630 | 640 | } catch (err) {
|
631 | - console.error(
|
|
641 | + lazy.logger.error(
|
|
632 | 642 | "We did not get localized settings, and default settings failed as well",
|
633 | 643 | err
|
634 | 644 | );
|
... | ... | @@ -651,10 +661,19 @@ export const TorConnect = (() => { |
651 | 661 | }
|
652 | 662 | }
|
653 | 663 | |
664 | + const restoreOriginalSettings = async () => {
|
|
665 | + try {
|
|
666 | + await TorSettings.applySettings();
|
|
667 | + } catch (e) {
|
|
668 | + // We cannot do much if the original settings were bad or
|
|
669 | + // if the connection closed, so just report it in the
|
|
670 | + // console.
|
|
671 | + lazy.logger.warn("Failed to restore original settings.", e);
|
|
672 | + }
|
|
673 | + };
|
|
674 | + |
|
654 | 675 | // apply each of our settings and try to bootstrap with each
|
655 | 676 | try {
|
656 | - this.originalSettings = TorSettings.getSettings();
|
|
657 | - |
|
658 | 677 | for (const [
|
659 | 678 | index,
|
660 | 679 | currentSetting,
|
... | ... | @@ -664,14 +683,32 @@ export const TorConnect = (() => { |
664 | 683 | break;
|
665 | 684 | }
|
666 | 685 | |
667 | - console.log(
|
|
668 | - `TorConnect: Attempting Bootstrap with configuration ${
|
|
669 | - index + 1
|
|
670 | - }/${this.settings.length}`
|
|
686 | + lazy.logger.info(
|
|
687 | + `Attempting Bootstrap with configuration ${index + 1}/${
|
|
688 | + this.settings.length
|
|
689 | + }`
|
|
671 | 690 | );
|
672 | 691 | |
673 | - TorSettings.setSettings(currentSetting);
|
|
674 | - await TorSettings.applySettings();
|
|
692 | + // Send the new settings directly to the provider. We will
|
|
693 | + // save them only if the bootstrap succeeds.
|
|
694 | + // FIXME: We should somehow signal TorSettings users that we
|
|
695 | + // have set custom settings, and they should not apply
|
|
696 | + // theirs until we are done with trying ours.
|
|
697 | + // Otherwise, the new settings provided by the user while we
|
|
698 | + // were bootstrapping could be the ones that cause the
|
|
699 | + // bootstrap to succeed, but we overwrite them (unless we
|
|
700 | + // backup the original settings, and then save our new
|
|
701 | + // settings only if they have not changed).
|
|
702 | + // Another idea (maybe easier to implement) is to disable
|
|
703 | + // the settings UI while *any* bootstrap is going on.
|
|
704 | + // This is also documented in tor-browser#41921.
|
|
705 | + const provider = await lazy.TorProviderBuilder.build();
|
|
706 | + // We need to merge with old settings, in case the user is
|
|
707 | + // using a proxy or is behind a firewall.
|
|
708 | + await provider.writeSettings({
|
|
709 | + ...TorSettings.getSettings(),
|
|
710 | + ...currentSetting,
|
|
711 | + });
|
|
675 | 712 | |
676 | 713 | // build out our bootstrap request
|
677 | 714 | const tbr = new lazy.TorBootstrapRequest();
|
... | ... | @@ -679,8 +716,8 @@ export const TorConnect = (() => { |
679 | 716 | TorConnect._updateBootstrapStatus(progress, status);
|
680 | 717 | };
|
681 | 718 | tbr.onbootstraperror = (message, details) => {
|
682 | - console.log(
|
|
683 | - `TorConnect: Auto-Bootstrap error => ${message}; ${details}`
|
|
719 | + lazy.logger.error(
|
|
720 | + `Auto-Bootstrap error => ${message}; ${details}`
|
|
684 | 721 | );
|
685 | 722 | };
|
686 | 723 | |
... | ... | @@ -688,6 +725,7 @@ export const TorConnect = (() => { |
688 | 725 | this.on_transition = async nextState => {
|
689 | 726 | if (nextState === TorConnectState.Configuring) {
|
690 | 727 | await tbr.cancel();
|
728 | + await restoreOriginalSettings();
|
|
691 | 729 | }
|
692 | 730 | resolve();
|
693 | 731 | };
|
... | ... | @@ -695,23 +733,20 @@ export const TorConnect = (() => { |
695 | 733 | // begin bootstrap
|
696 | 734 | if (await tbr.bootstrap()) {
|
697 | 735 | // persist the current settings to preferences
|
736 | + TorSettings.setSettings(currentSetting);
|
|
698 | 737 | TorSettings.saveToPrefs();
|
738 | + await TorSettings.applySettings();
|
|
699 | 739 | TorConnect._changeState(TorConnectState.Bootstrapped);
|
700 | 740 | return;
|
701 | 741 | }
|
702 | 742 | }
|
703 | 743 | |
704 | - // bootstrapped failed for all potential settings, so reset daemon to use original
|
|
705 | - TorSettings.setSettings(this.originalSettings);
|
|
706 | - // The original settings should be good, so we save them to
|
|
707 | - // preferences before trying to apply them, as it might fail
|
|
708 | - // if the actual problem is with the connection to the control
|
|
709 | - // port.
|
|
710 | - // FIXME: We should handle this case in a better way.
|
|
711 | - TorSettings.saveToPrefs();
|
|
712 | - await TorSettings.applySettings();
|
|
713 | - |
|
714 | - // only explicitly change state here if something else has not transitioned us
|
|
744 | + // Bootstrap failed for all potential settings, so restore the
|
|
745 | + // original settings the provider.
|
|
746 | + await restoreOriginalSettings();
|
|
747 | + |
|
748 | + // Only explicitly change state here if something else has not
|
|
749 | + // transitioned us.
|
|
715 | 750 | if (!this.transitioning) {
|
716 | 751 | throw_error(
|
717 | 752 | TorStrings.torConnect.autoBootstrappingFailed,
|
... | ... | @@ -720,18 +755,8 @@ export const TorConnect = (() => { |
720 | 755 | }
|
721 | 756 | return;
|
722 | 757 | } catch (err) {
|
723 | - // restore original settings in case of error
|
|
724 | - try {
|
|
725 | - TorSettings.setSettings(this.originalSettings);
|
|
726 | - // As above
|
|
727 | - TorSettings.saveToPrefs();
|
|
728 | - await TorSettings.applySettings();
|
|
729 | - } catch (errRestore) {
|
|
730 | - console.log(
|
|
731 | - `TorConnect: Failed to restore original settings => ${errRestore}`
|
|
732 | - );
|
|
733 | - }
|
|
734 | - // throw to outer catch to transition us
|
|
758 | + await restoreOriginalSettings();
|
|
759 | + // throw to outer catch to transition us.
|
|
735 | 760 | throw err;
|
736 | 761 | }
|
737 | 762 | } catch (err) {
|
... | ... | @@ -748,8 +773,8 @@ export const TorConnect = (() => { |
748 | 773 | true
|
749 | 774 | );
|
750 | 775 | } else {
|
751 | - console.error(
|
|
752 | - "TorConnect: Received AutoBootstrapping error after transitioning",
|
|
776 | + lazy.logger.error(
|
|
777 | + "Received AutoBootstrapping error after transitioning",
|
|
753 | 778 | err
|
754 | 779 | );
|
755 | 780 | }
|
... | ... | @@ -793,8 +818,8 @@ export const TorConnect = (() => { |
793 | 818 | |
794 | 819 | TorConnect._errorMessage = errorMessage;
|
795 | 820 | TorConnect._errorDetails = errorDetails;
|
796 | - console.error(
|
|
797 | - `[TorConnect] Entering error state (${errorMessage}, ${errorDetails})`
|
|
821 | + lazy.logger.error(
|
|
822 | + `Entering error state (${errorMessage}, ${errorDetails})`
|
|
798 | 823 | );
|
799 | 824 | |
800 | 825 | Services.obs.notifyObservers(
|
... | ... | @@ -835,9 +860,7 @@ export const TorConnect = (() => { |
835 | 860 | );
|
836 | 861 | }
|
837 | 862 | |
838 | - console.log(
|
|
839 | - `TorConnect: Try transitioning from ${prevState} to ${newState}`
|
|
840 | - );
|
|
863 | + lazy.logger.trace(`Try transitioning from ${prevState} to ${newState}`);
|
|
841 | 864 | |
842 | 865 | // set our new state first so that state transitions can themselves trigger
|
843 | 866 | // a state transition
|
... | ... | @@ -851,8 +874,8 @@ export const TorConnect = (() => { |
851 | 874 | this._bootstrapProgress = progress;
|
852 | 875 | this._bootstrapStatus = status;
|
853 | 876 | |
854 | - console.log(
|
|
855 | - `TorConnect: Bootstrapping ${this._bootstrapProgress}% complete (${this._bootstrapStatus})`
|
|
877 | + lazy.logger.info(
|
|
878 | + `Bootstrapping ${this._bootstrapProgress}% complete (${this._bootstrapStatus})`
|
|
856 | 879 | );
|
857 | 880 | Services.obs.notifyObservers(
|
858 | 881 | {
|
... | ... | @@ -866,7 +889,7 @@ export const TorConnect = (() => { |
866 | 889 | |
867 | 890 | // init should be called by TorStartupService
|
868 | 891 | init() {
|
869 | - console.log("TorConnect: init()");
|
|
892 | + lazy.logger.debug("TorConnect.init()");
|
|
870 | 893 | this._callback(TorConnectState.Initial).begin();
|
871 | 894 | |
872 | 895 | if (!this.enabled) {
|
... | ... | @@ -875,9 +898,17 @@ export const TorConnect = (() => { |
875 | 898 | } else {
|
876 | 899 | let observeTopic = addTopic => {
|
877 | 900 | Services.obs.addObserver(this, addTopic);
|
878 | - console.log(`TorConnect: Observing topic '${addTopic}'`);
|
|
901 | + lazy.logger.debug(`Observing topic '${addTopic}'`);
|
|
879 | 902 | };
|
880 | 903 | |
904 | + // Wait for TorSettings, as we will need it.
|
|
905 | + // We will wait for a TorProvider only after TorSettings is ready,
|
|
906 | + // because the TorProviderBuilder initialization might not have finished
|
|
907 | + // at this point, and TorSettings initialization is a prerequisite for
|
|
908 | + // having a provider.
|
|
909 | + // So, we prefer initializing TorConnect as soon as possible, so that
|
|
910 | + // the UI will be able to detect it is in the Initializing state and act
|
|
911 | + // consequently.
|
|
881 | 912 | TorSettings.initializedPromise.then(() => this._settingsInitialized());
|
882 | 913 | |
883 | 914 | // register the Tor topics we always care about
|
... | ... | @@ -887,7 +918,7 @@ export const TorConnect = (() => { |
887 | 918 | },
|
888 | 919 | |
889 | 920 | async observe(subject, topic, data) {
|
890 | - console.log(`TorConnect: Observed ${topic}`);
|
|
921 | + lazy.logger.debug(`Observed ${topic}`);
|
|
891 | 922 | |
892 | 923 | switch (topic) {
|
893 | 924 | case TorTopics.LogHasWarnOrErr: {
|
... | ... | @@ -919,19 +950,25 @@ export const TorConnect = (() => { |
919 | 950 | }
|
920 | 951 | },
|
921 | 952 | |
922 | - _settingsInitialized() {
|
|
953 | + async _settingsInitialized() {
|
|
954 | + // TODO: Handle failures here, instead of the prompt to restart the
|
|
955 | + // daemon when it exits (tor-browser#21053, tor-browser#41921).
|
|
956 | + await lazy.TorProviderBuilder.build();
|
|
957 | + |
|
923 | 958 | // tor-browser#41907: This is only a workaround to avoid users being
|
924 | 959 | // bounced back to the initial panel without any explanation.
|
925 | 960 | // Longer term we should disable the clickable elements, or find a UX
|
926 | 961 | // to prevent this from happening (e.g., allow buttons to be clicked,
|
927 | 962 | // but show an intermediate starting state, or a message that tor is
|
928 | 963 | // starting while the butons are disabled, etc...).
|
964 | + // See also tor-browser#41921.
|
|
929 | 965 | if (this.state !== TorConnectState.Initial) {
|
930 | - console.warn(
|
|
931 | - "TorConnect: Seen the torsettings:ready after the state has already changed, ignoring the notification."
|
|
966 | + lazy.logger.warn(
|
|
967 | + "The TorProvider was built after the state had already changed."
|
|
932 | 968 | );
|
933 | 969 | return;
|
934 | 970 | }
|
971 | + lazy.logger.debug("The TorProvider is ready, changing state.");
|
|
935 | 972 | if (this.shouldQuickStart) {
|
936 | 973 | // Quickstart
|
937 | 974 | this._changeState(TorConnectState.Bootstrapping);
|
... | ... | @@ -1074,17 +1111,17 @@ export const TorConnect = (() => { |
1074 | 1111 | */
|
1075 | 1112 | |
1076 | 1113 | beginBootstrap() {
|
1077 | - console.log("TorConnect: beginBootstrap()");
|
|
1114 | + lazy.logger.debug("TorConnect.beginBootstrap()");
|
|
1078 | 1115 | this._changeState(TorConnectState.Bootstrapping);
|
1079 | 1116 | },
|
1080 | 1117 | |
1081 | 1118 | cancelBootstrap() {
|
1082 | - console.log("TorConnect: cancelBootstrap()");
|
|
1119 | + lazy.logger.debug("TorConnect.cancelBootstrap()");
|
|
1083 | 1120 | this._changeState(TorConnectState.Configuring);
|
1084 | 1121 | },
|
1085 | 1122 | |
1086 | 1123 | beginAutoBootstrap(countryCode) {
|
1087 | - console.log("TorConnect: beginAutoBootstrap()");
|
|
1124 | + lazy.logger.debug("TorConnect.beginAutoBootstrap()");
|
|
1088 | 1125 | this._changeState(TorConnectState.AutoBootstrapping, countryCode);
|
1089 | 1126 | },
|
1090 | 1127 | |
... | ... | @@ -1154,7 +1191,10 @@ export const TorConnect = (() => { |
1154 | 1191 | await mrpc.init();
|
1155 | 1192 | this._countryCodes = await mrpc.circumvention_countries();
|
1156 | 1193 | } catch (err) {
|
1157 | - console.log("An error occurred while fetching country codes", err);
|
|
1194 | + lazy.logger.error(
|
|
1195 | + "An error occurred while fetching country codes",
|
|
1196 | + err
|
|
1197 | + );
|
|
1158 | 1198 | } finally {
|
1159 | 1199 | mrpc.uninit();
|
1160 | 1200 | }
|
... | ... | @@ -1187,8 +1227,8 @@ export const TorConnect = (() => { |
1187 | 1227 | uriArray = uriVariant;
|
1188 | 1228 | } else {
|
1189 | 1229 | // about:tor as safe fallback
|
1190 | - console.error(
|
|
1191 | - `TorConnect: received unknown variant '${JSON.stringify(uriVariant)}'`
|
|
1230 | + lazy.logger.error(
|
|
1231 | + `Received unknown variant '${JSON.stringify(uriVariant)}'`
|
|
1192 | 1232 | );
|
1193 | 1233 | uriArray = ["about:tor"];
|
1194 | 1234 | }
|
... | ... | @@ -1209,9 +1249,7 @@ export const TorConnect = (() => { |
1209 | 1249 | // which redirect after bootstrapping
|
1210 | 1250 | getURIsToLoad(uriVariant) {
|
1211 | 1251 | const uris = this.fixupURIs(uriVariant);
|
1212 | - console.log(
|
|
1213 | - `TorConnect: Will load after bootstrap => [${uris.join(", ")}]`
|
|
1214 | - );
|
|
1252 | + lazy.logger.debug(`Will load after bootstrap => [${uris.join(", ")}]`);
|
|
1215 | 1253 | return uris.map(uri => this.getRedirectURL(uri));
|
1216 | 1254 | },
|
1217 | 1255 | };
|
... | ... | @@ -6,10 +6,9 @@ const lazy = {}; |
6 | 6 | |
7 | 7 | ChromeUtils.defineESModuleGetters(lazy, {
|
8 | 8 | TorLauncherUtil: "resource://gre/modules/TorLauncherUtil.sys.mjs",
|
9 | - TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
10 | - TorProviderTopics: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
11 | 9 | Lox: "resource://gre/modules/Lox.sys.mjs",
|
12 | 10 | TorParsers: "resource://gre/modules/TorParsers.sys.mjs",
|
11 | + TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
|
|
13 | 12 | });
|
14 | 13 | |
15 | 14 | ChromeUtils.defineLazyGetter(lazy, "logger", () => {
|
... | ... | @@ -71,20 +70,6 @@ const TorSettingsPrefs = Object.freeze({ |
71 | 70 | },
|
72 | 71 | });
|
73 | 72 | |
74 | -/* Config Keys used to configure tor daemon */
|
|
75 | -const TorConfigKeys = Object.freeze({
|
|
76 | - useBridges: "UseBridges",
|
|
77 | - bridgeList: "Bridge",
|
|
78 | - socks4Proxy: "Socks4Proxy",
|
|
79 | - socks5Proxy: "Socks5Proxy",
|
|
80 | - socks5ProxyUsername: "Socks5ProxyUsername",
|
|
81 | - socks5ProxyPassword: "Socks5ProxyPassword",
|
|
82 | - httpsProxy: "HTTPSProxy",
|
|
83 | - httpsProxyAuthenticator: "HTTPSProxyAuthenticator",
|
|
84 | - reachableAddresses: "ReachableAddresses",
|
|
85 | - clientTransportPlugin: "ClientTransportPlugin",
|
|
86 | -});
|
|
87 | - |
|
88 | 73 | export const TorBridgeSource = Object.freeze({
|
89 | 74 | Invalid: -1,
|
90 | 75 | BuiltIn: 0,
|
... | ... | @@ -322,7 +307,7 @@ class TorSettingsImpl { |
322 | 307 | if (!val) {
|
323 | 308 | return;
|
324 | 309 | }
|
325 | - const bridgeStrings = this.#getBuiltinBridges(val);
|
|
310 | + const bridgeStrings = this.getBuiltinBridges(val);
|
|
326 | 311 | if (bridgeStrings.length) {
|
327 | 312 | this.bridges.bridge_strings = bridgeStrings;
|
328 | 313 | return;
|
... | ... | @@ -659,14 +644,17 @@ class TorSettingsImpl { |
659 | 644 | * @param {string} pt The pluggable transport to return the lines for
|
660 | 645 | * @returns {string[]} The bridge lines in random order
|
661 | 646 | */
|
662 | - #getBuiltinBridges(pt) {
|
|
647 | + getBuiltinBridges(pt) {
|
|
648 | + if (!this.#allowUninitialized) {
|
|
649 | + this.#checkIfInitialized();
|
|
650 | + }
|
|
663 | 651 | // Shuffle so that Tor Browser users do not all try the built-in bridges in
|
664 | 652 | // the same order.
|
665 | 653 | return arrayShuffle(this.#builtinBridges[pt] ?? []);
|
666 | 654 | }
|
667 | 655 | |
668 | 656 | /**
|
669 | - * Load or init our settings, and register observers.
|
|
657 | + * Load or init our settings.
|
|
670 | 658 | */
|
671 | 659 | async init() {
|
672 | 660 | if (this.#initialized) {
|
... | ... | @@ -677,6 +665,7 @@ class TorSettingsImpl { |
677 | 665 | await this.#initInternal();
|
678 | 666 | this.#initialized = true;
|
679 | 667 | this.#initComplete();
|
668 | + Services.obs.notifyObservers(null, TorSettingsTopics.Ready);
|
|
680 | 669 | } catch (e) {
|
681 | 670 | this.#initFailed(e);
|
682 | 671 | throw e;
|
... | ... | @@ -698,45 +687,35 @@ class TorSettingsImpl { |
698 | 687 | lazy.logger.error("Could not load the built-in PT config.", e);
|
699 | 688 | }
|
700 | 689 | |
701 | - // Initialize this before loading from prefs because we need Lox initialized before
|
|
702 | - // any calls to Lox.getBridges()
|
|
690 | + // Initialize this before loading from prefs because we need Lox initialized
|
|
691 | + // before any calls to Lox.getBridges().
|
|
703 | 692 | try {
|
704 | 693 | await lazy.Lox.init();
|
705 | 694 | } catch (e) {
|
706 | 695 | lazy.logger.error("Could not initialize Lox.", e.type);
|
707 | 696 | }
|
708 | 697 | |
709 | - // TODO: We could use a shared promise, and wait for it to be fullfilled
|
|
710 | - // instead of Service.obs.
|
|
711 | - if (lazy.TorLauncherUtil.shouldStartAndOwnTor) {
|
|
712 | - // if the settings branch exists, load settings from prefs
|
|
713 | - if (Services.prefs.getBoolPref(TorSettingsPrefs.enabled, false)) {
|
|
714 | - // Do not want notifications for initially loaded prefs.
|
|
715 | - this.freezeNotifications();
|
|
716 | - try {
|
|
717 | - this.#allowUninitialized = true;
|
|
718 | - this.#loadFromPrefs();
|
|
719 | - } finally {
|
|
720 | - this.#allowUninitialized = false;
|
|
721 | - this.#notificationQueue.clear();
|
|
722 | - this.thawNotifications();
|
|
723 | - }
|
|
724 | - }
|
|
698 | + if (
|
|
699 | + lazy.TorLauncherUtil.shouldStartAndOwnTor &&
|
|
700 | + Services.prefs.getBoolPref(TorSettingsPrefs.enabled, false)
|
|
701 | + ) {
|
|
702 | + // Do not want notifications for initially loaded prefs.
|
|
703 | + this.freezeNotifications();
|
|
725 | 704 | try {
|
726 | - const provider = await lazy.TorProviderBuilder.build();
|
|
727 | - if (provider.isRunning) {
|
|
728 | - this.#handleProcessReady();
|
|
729 | - // No need to add an observer to call this again.
|
|
730 | - return;
|
|
731 | - }
|
|
732 | - } catch {}
|
|
733 | - |
|
734 | - Services.obs.addObserver(this, lazy.TorProviderTopics.ProcessIsReady);
|
|
705 | + this.#allowUninitialized = true;
|
|
706 | + this.#loadFromPrefs();
|
|
707 | + } finally {
|
|
708 | + this.#allowUninitialized = false;
|
|
709 | + this.#notificationQueue.clear();
|
|
710 | + this.thawNotifications();
|
|
711 | + }
|
|
735 | 712 | }
|
713 | + |
|
714 | + lazy.logger.info("Ready");
|
|
736 | 715 | }
|
737 | 716 | |
738 | 717 | /**
|
739 | - * Unload or uninit our settings, and unregister observers.
|
|
718 | + * Unload or uninit our settings.
|
|
740 | 719 | */
|
741 | 720 | async uninit() {
|
742 | 721 | await lazy.Lox.uninit();
|
... | ... | @@ -764,34 +743,6 @@ class TorSettingsImpl { |
764 | 743 | return this.#initialized;
|
765 | 744 | }
|
766 | 745 | |
767 | - /**
|
|
768 | - * Wait for relevant life-cycle events to apply saved settings.
|
|
769 | - */
|
|
770 | - async observe(subject, topic, data) {
|
|
771 | - lazy.logger.debug(`Observed ${topic}`);
|
|
772 | - |
|
773 | - switch (topic) {
|
|
774 | - case lazy.TorProviderTopics.ProcessIsReady:
|
|
775 | - Services.obs.removeObserver(
|
|
776 | - this,
|
|
777 | - lazy.TorProviderTopics.ProcessIsReady
|
|
778 | - );
|
|
779 | - await this.#handleProcessReady();
|
|
780 | - break;
|
|
781 | - }
|
|
782 | - }
|
|
783 | - |
|
784 | - /**
|
|
785 | - * Apply the settings once the tor provider is ready and notify any observer
|
|
786 | - * that the settings can be used.
|
|
787 | - */
|
|
788 | - async #handleProcessReady() {
|
|
789 | - // push down settings to tor
|
|
790 | - await this.#applySettings(true);
|
|
791 | - lazy.logger.info("Ready");
|
|
792 | - Services.obs.notifyObservers(null, TorSettingsTopics.Ready);
|
|
793 | - }
|
|
794 | - |
|
795 | 746 | /**
|
796 | 747 | * Load our settings from prefs.
|
797 | 748 | */
|
... | ... | @@ -972,85 +923,14 @@ class TorSettingsImpl { |
972 | 923 | |
973 | 924 | /**
|
974 | 925 | * Push our settings down to the tor provider.
|
926 | + *
|
|
927 | + * Even though this introduces a circular depdency, it makes the API nicer for
|
|
928 | + * frontend consumers.
|
|
975 | 929 | */
|
976 | 930 | async applySettings() {
|
977 | 931 | this.#checkIfInitialized();
|
978 | - return this.#applySettings(false);
|
|
979 | - }
|
|
980 | - |
|
981 | - /**
|
|
982 | - * Internal implementation of applySettings that does not check if we are
|
|
983 | - * initialized.
|
|
984 | - */
|
|
985 | - async #applySettings(allowUninitialized) {
|
|
986 | - lazy.logger.debug("#applySettings()");
|
|
987 | - |
|
988 | - this.#cleanupSettings();
|
|
989 | - |
|
990 | - const settingsMap = new Map();
|
|
991 | - |
|
992 | - // #applySettings can be called only when #allowUninitialized is false
|
|
993 | - this.#allowUninitialized = allowUninitialized;
|
|
994 | - |
|
995 | - try {
|
|
996 | - /* Bridges */
|
|
997 | - const haveBridges =
|
|
998 | - this.bridges.enabled && !!this.bridges.bridge_strings.length;
|
|
999 | - settingsMap.set(TorConfigKeys.useBridges, haveBridges);
|
|
1000 | - if (haveBridges) {
|
|
1001 | - settingsMap.set(TorConfigKeys.bridgeList, this.bridges.bridge_strings);
|
|
1002 | - } else {
|
|
1003 | - settingsMap.set(TorConfigKeys.bridgeList, null);
|
|
1004 | - }
|
|
1005 | - |
|
1006 | - /* Proxy */
|
|
1007 | - settingsMap.set(TorConfigKeys.socks4Proxy, null);
|
|
1008 | - settingsMap.set(TorConfigKeys.socks5Proxy, null);
|
|
1009 | - settingsMap.set(TorConfigKeys.socks5ProxyUsername, null);
|
|
1010 | - settingsMap.set(TorConfigKeys.socks5ProxyPassword, null);
|
|
1011 | - settingsMap.set(TorConfigKeys.httpsProxy, null);
|
|
1012 | - settingsMap.set(TorConfigKeys.httpsProxyAuthenticator, null);
|
|
1013 | - if (this.proxy.enabled) {
|
|
1014 | - const address = this.proxy.address;
|
|
1015 | - const port = this.proxy.port;
|
|
1016 | - const username = this.proxy.username;
|
|
1017 | - const password = this.proxy.password;
|
|
1018 | - |
|
1019 | - switch (this.proxy.type) {
|
|
1020 | - case TorProxyType.Socks4:
|
|
1021 | - settingsMap.set(TorConfigKeys.socks4Proxy, `${address}:${port}`);
|
|
1022 | - break;
|
|
1023 | - case TorProxyType.Socks5:
|
|
1024 | - settingsMap.set(TorConfigKeys.socks5Proxy, `${address}:${port}`);
|
|
1025 | - settingsMap.set(TorConfigKeys.socks5ProxyUsername, username);
|
|
1026 | - settingsMap.set(TorConfigKeys.socks5ProxyPassword, password);
|
|
1027 | - break;
|
|
1028 | - case TorProxyType.HTTPS:
|
|
1029 | - settingsMap.set(TorConfigKeys.httpsProxy, `${address}:${port}`);
|
|
1030 | - settingsMap.set(
|
|
1031 | - TorConfigKeys.httpsProxyAuthenticator,
|
|
1032 | - `${username}:${password}`
|
|
1033 | - );
|
|
1034 | - break;
|
|
1035 | - }
|
|
1036 | - }
|
|
1037 | - |
|
1038 | - /* Firewall */
|
|
1039 | - if (this.firewall.enabled) {
|
|
1040 | - const reachableAddresses = this.firewall.allowed_ports
|
|
1041 | - .map(port => `*:${port}`)
|
|
1042 | - .join(",");
|
|
1043 | - settingsMap.set(TorConfigKeys.reachableAddresses, reachableAddresses);
|
|
1044 | - } else {
|
|
1045 | - settingsMap.set(TorConfigKeys.reachableAddresses, null);
|
|
1046 | - }
|
|
1047 | - } finally {
|
|
1048 | - this.#allowUninitialized = false;
|
|
1049 | - }
|
|
1050 | - |
|
1051 | - /* Push to Tor */
|
|
1052 | 932 | const provider = await lazy.TorProviderBuilder.build();
|
1053 | - await provider.writeSettings(settingsMap);
|
|
933 | + await provider.writeSettings(this.getSettings());
|
|
1054 | 934 | }
|
1055 | 935 | |
1056 | 936 | /**
|