Pier Angelo Vendrame pushed to branch tor-browser-128.6.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
6571ac7b
by Henry Wilkes at 2025-01-21T14:15:40+00:00
-
fa81e56c
by Henry Wilkes at 2025-01-21T14:15:40+00:00
-
093e9483
by Henry Wilkes at 2025-01-21T14:15:41+00:00
-
b50c1c9c
by Henry Wilkes at 2025-01-21T14:15:42+00:00
-
06cbcd5d
by Henry Wilkes at 2025-01-21T14:15:43+00:00
5 changed files:
- browser/components/torpreferences/content/connectionPane.js
- toolkit/components/tor-launcher/TorControlPort.sys.mjs
- toolkit/components/tor-launcher/TorProvider.sys.mjs
- toolkit/modules/TorConnect.sys.mjs
- toolkit/modules/TorSettings.sys.mjs
Changes:
... | ... | @@ -2545,19 +2545,6 @@ const gConnectionPane = (function () { |
2545 | 2545 | |
2546 | 2546 | // populate xul with strings and cache the relevant elements
|
2547 | 2547 | _populateXUL() {
|
2548 | - // saves tor settings to disk when navigate away from about:preferences
|
|
2549 | - window.addEventListener("blur", async () => {
|
|
2550 | - try {
|
|
2551 | - // Build a new provider each time because this might be called also
|
|
2552 | - // when closing the browser (if about:preferences was open), maybe
|
|
2553 | - // when the provider was already uninitialized.
|
|
2554 | - const provider = await TorProviderBuilder.build();
|
|
2555 | - provider.flushSettings();
|
|
2556 | - } catch (e) {
|
|
2557 | - console.warn("Could not save the tor settings.", e);
|
|
2558 | - }
|
|
2559 | - });
|
|
2560 | - |
|
2561 | 2548 | // Quickstart
|
2562 | 2549 | this._enableQuickstartCheckbox = document.getElementById(
|
2563 | 2550 | "torPreferences-quickstart-toggle"
|
... | ... | @@ -364,6 +364,9 @@ export class TorController { |
364 | 364 | /**
|
365 | 365 | * The commands that need to be run or receive a response.
|
366 | 366 | *
|
367 | + * NOTE: This must be in the order with the last requested command at the end
|
|
368 | + * of the queue.
|
|
369 | + *
|
|
367 | 370 | * @type {Command[]}
|
368 | 371 | */
|
369 | 372 | #commandQueue = [];
|
... | ... | @@ -947,6 +950,10 @@ export class TorController { |
947 | 950 | * values will be automatically unrolled.
|
948 | 951 | */
|
949 | 952 | async setConf(values) {
|
953 | + // NOTE: This is an async method. It must ensure that sequential calls to
|
|
954 | + // this method do not race against each other. I.e. the last call to this
|
|
955 | + // method must always be the last in #commandQueue. Otherwise a delayed
|
|
956 | + // earlier call could overwrite the configuration of a later call.
|
|
950 | 957 | const args = values
|
951 | 958 | .flatMap(([key, value]) => {
|
952 | 959 | if (value === undefined || value === null) {
|
... | ... | @@ -70,7 +70,6 @@ const Preferences = Object.freeze({ |
70 | 70 | ControlHost: "extensions.torlauncher.control_host",
|
71 | 71 | ControlPort: "extensions.torlauncher.control_port",
|
72 | 72 | MaxLogEntries: "extensions.torlauncher.max_tor_log_entries",
|
73 | - PromptAtStartup: "extensions.torlauncher.prompt_at_startup",
|
|
74 | 73 | });
|
75 | 74 | |
76 | 75 | /* Config Keys used to configure tor daemon */
|
... | ... | @@ -335,6 +334,15 @@ export class TorProvider { |
335 | 334 | }
|
336 | 335 | |
337 | 336 | logger.debug("Mapped settings object", settings, torSettings);
|
337 | + |
|
338 | + // Send settings to the tor process.
|
|
339 | + // NOTE: Since everything up to this point has been non-async, the order in
|
|
340 | + // which TorProvider.writeSettings is called should match the order in which
|
|
341 | + // the configuration is passed onto setConf. In turn, TorControlPort.setConf
|
|
342 | + // should similarly ensure that the configuration reaches the tor process in
|
|
343 | + // the same order.
|
|
344 | + // In particular, we do not want a race where an earlier call to
|
|
345 | + // TorProvider.writeSettings can be delayed and override a later call.
|
|
338 | 346 | await this.#controller.setConf(Array.from(torSettings));
|
339 | 347 | }
|
340 | 348 | |
... | ... | @@ -962,11 +970,6 @@ export class TorProvider { |
962 | 970 | |
963 | 971 | if (statusObj.PROGRESS === 100) {
|
964 | 972 | this.#isBootstrapDone = true;
|
965 | - try {
|
|
966 | - Services.prefs.setBoolPref(Preferences.PromptAtStartup, false);
|
|
967 | - } catch (e) {
|
|
968 | - logger.warn(`Cannot set ${Preferences.PromptAtStartup}`, e);
|
|
969 | - }
|
|
970 | 973 | return;
|
971 | 974 | }
|
972 | 975 | |
... | ... | @@ -988,11 +991,6 @@ export class TorProvider { |
988 | 991 | * @param {object} statusObj The bootstrap status object with the error
|
989 | 992 | */
|
990 | 993 | #notifyBootstrapError(statusObj) {
|
991 | - try {
|
|
992 | - Services.prefs.setBoolPref(Preferences.PromptAtStartup, true);
|
|
993 | - } catch (e) {
|
|
994 | - logger.warn(`Cannot set ${Preferences.PromptAtStartup}`, e);
|
|
995 | - }
|
|
996 | 994 | logger.error("Tor bootstrap error", statusObj);
|
997 | 995 | |
998 | 996 | if (
|
... | ... | @@ -16,15 +16,12 @@ ChromeUtils.defineESModuleGetters(lazy, { |
16 | 16 | TorSettings: "resource://gre/modules/TorSettings.sys.mjs",
|
17 | 17 | });
|
18 | 18 | |
19 | -/* Relevant prefs used by tor-launcher */
|
|
20 | -const TorLauncherPrefs = Object.freeze({
|
|
21 | - prompt_at_startup: "extensions.torlauncher.prompt_at_startup",
|
|
22 | -});
|
|
23 | - |
|
24 | 19 | const TorConnectPrefs = Object.freeze({
|
25 | 20 | censorship_level: "torbrowser.debug.censorship_level",
|
26 | 21 | allow_internet_test: "torbrowser.bootstrap.allow_internet_test",
|
27 | 22 | log_level: "torbrowser.bootstrap.log_level",
|
23 | + /* prompt_at_startup now controls whether the quickstart can trigger. */
|
|
24 | + prompt_at_startup: "extensions.torlauncher.prompt_at_startup",
|
|
28 | 25 | });
|
29 | 26 | |
30 | 27 | export const TorConnectState = Object.freeze({
|
... | ... | @@ -1050,7 +1047,7 @@ export const TorConnect = { |
1050 | 1047 | lazy.logger.info("Starting again since the tor process exited");
|
1051 | 1048 | // Treat a failure as a possibly broken configuration.
|
1052 | 1049 | // So, prevent quickstart at the next start.
|
1053 | - Services.prefs.setBoolPref(TorLauncherPrefs.prompt_at_startup, true);
|
|
1050 | + Services.prefs.setBoolPref(TorConnectPrefs.prompt_at_startup, true);
|
|
1054 | 1051 | this._makeStageRequest(TorConnectStage.Start, true);
|
1055 | 1052 | break;
|
1056 | 1053 | default:
|
... | ... | @@ -1171,7 +1168,7 @@ export const TorConnect = { |
1171 | 1168 | return (
|
1172 | 1169 | lazy.TorSettings.quickstart.enabled &&
|
1173 | 1170 | // and the previous bootstrap attempt must have succeeded
|
1174 | - !Services.prefs.getBoolPref(TorLauncherPrefs.prompt_at_startup, true)
|
|
1171 | + !Services.prefs.getBoolPref(TorConnectPrefs.prompt_at_startup, true)
|
|
1175 | 1172 | );
|
1176 | 1173 | },
|
1177 | 1174 | |
... | ... | @@ -1451,6 +1448,8 @@ export const TorConnect = { |
1451 | 1448 | this._tryAgain = false;
|
1452 | 1449 | this._potentiallyBlocked = false;
|
1453 | 1450 | this._errorDetails = null;
|
1451 | + // Re-enable quickstart for future sessions.
|
|
1452 | + Services.prefs.setBoolPref(TorConnectPrefs.prompt_at_startup, false);
|
|
1454 | 1453 | |
1455 | 1454 | if (requestedStage) {
|
1456 | 1455 | lazy.logger.warn(
|
... | ... | @@ -1491,6 +1490,8 @@ export const TorConnect = { |
1491 | 1490 | |
1492 | 1491 | this._tryAgain = true;
|
1493 | 1492 | this._potentiallyBlocked = true;
|
1493 | + // Disable quickstart until we have a successful bootstrap.
|
|
1494 | + Services.prefs.setBoolPref(TorConnectPrefs.prompt_at_startup, true);
|
|
1494 | 1495 | |
1495 | 1496 | this._signalError(error);
|
1496 | 1497 |
... | ... | @@ -711,10 +711,15 @@ class TorSettingsImpl { |
711 | 711 | *
|
712 | 712 | * Even though this introduces a circular depdency, it makes the API nicer for
|
713 | 713 | * frontend consumers.
|
714 | + *
|
|
715 | + * @param {boolean} flush - Whether to also flush the settings to disk.
|
|
714 | 716 | */
|
715 | - async #applySettings() {
|
|
717 | + async #applySettings(flush) {
|
|
716 | 718 | const provider = await lazy.TorProviderBuilder.build();
|
717 | 719 | await provider.writeSettings();
|
720 | + if (flush) {
|
|
721 | + provider.flushSettings();
|
|
722 | + }
|
|
718 | 723 | }
|
719 | 724 | |
720 | 725 | /**
|
... | ... | @@ -974,7 +979,7 @@ class TorSettingsImpl { |
974 | 979 | ];
|
975 | 980 | const shouldApply = changes.some(prop => !unreadProps.includes(prop));
|
976 | 981 | if (shouldApply) {
|
977 | - await this.#applySettings();
|
|
982 | + await this.#applySettings(true);
|
|
978 | 983 | }
|
979 | 984 | }
|
980 | 985 | |
... | ... | @@ -1042,7 +1047,8 @@ class TorSettingsImpl { |
1042 | 1047 | |
1043 | 1048 | // After checks are complete, we commit them.
|
1044 | 1049 | this.#temporaryBridgeSettings = bridgeSettings;
|
1045 | - await this.#applySettings();
|
|
1050 | + // Do not flush the temporary bridge settings until they are saved.
|
|
1051 | + await this.#applySettings(false);
|
|
1046 | 1052 | }
|
1047 | 1053 | |
1048 | 1054 | /**
|