Pier Angelo Vendrame pushed to branch tor-browser-128.6.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
bd7602fe
by Henry Wilkes at 2025-01-20T18:25:01+00:00
-
e43836ca
by Henry Wilkes at 2025-01-20T18:26:14+00:00
-
6864f8ab
by Henry Wilkes at 2025-01-20T18:26:15+00:00
-
d6536e87
by Henry Wilkes at 2025-01-20T18:26:16+00:00
-
3dd18040
by Henry Wilkes at 2025-01-20T18:26:16+00:00
7 changed files:
- browser/components/torpreferences/content/connectionPane.js
- browser/components/torpreferences/content/connectionSettingsDialog.js
- mobile/android/fenix/app/src/main/java/org/mozilla/fenix/tor/TorControllerGV.kt
- mobile/android/geckoview/src/main/java/org/mozilla/geckoview/TorIntegrationAndroid.java
- toolkit/components/torconnect/TorConnectParent.sys.mjs
- toolkit/modules/TorAndroidIntegration.sys.mjs
- toolkit/modules/TorSettings.sys.mjs
Changes:
... | ... | @@ -96,33 +96,6 @@ const Lox = { |
96 | 96 | };
|
97 | 97 | */
|
98 | 98 | |
99 | -/**
|
|
100 | - * Make changes to TorSettings and save them.
|
|
101 | - *
|
|
102 | - * Bulk changes will be frozen together.
|
|
103 | - *
|
|
104 | - * @param {Function} changes - Method to apply changes to TorSettings.
|
|
105 | - */
|
|
106 | -async function setTorSettings(changes) {
|
|
107 | - if (!TorSettings.initialized) {
|
|
108 | - log.warning("Ignoring changes to uninitialized TorSettings");
|
|
109 | - return;
|
|
110 | - }
|
|
111 | - TorSettings.freezeNotifications();
|
|
112 | - try {
|
|
113 | - changes();
|
|
114 | - // This will trigger TorSettings.#cleanupSettings()
|
|
115 | - TorSettings.saveToPrefs();
|
|
116 | - try {
|
|
117 | - await TorSettings.applySettings();
|
|
118 | - } catch (e) {
|
|
119 | - console.error("Failed to apply Tor settings", e);
|
|
120 | - }
|
|
121 | - } finally {
|
|
122 | - TorSettings.thawNotifications();
|
|
123 | - }
|
|
124 | -}
|
|
125 | - |
|
126 | 99 | /**
|
127 | 100 | * Get the ID/fingerprint of the bridge used in the most recent Tor circuit.
|
128 | 101 | *
|
... | ... | @@ -757,6 +730,7 @@ const gBridgeGrid = { |
757 | 730 | });
|
758 | 731 | removeItem.addEventListener("click", () => {
|
759 | 732 | const bridgeLine = row.bridgeLine;
|
733 | + const source = TorSettings.bridges.source;
|
|
760 | 734 | const strings = TorSettings.bridges.bridge_strings;
|
761 | 735 | const index = strings.indexOf(bridgeLine);
|
762 | 736 | if (index === -1) {
|
... | ... | @@ -764,8 +738,8 @@ const gBridgeGrid = { |
764 | 738 | }
|
765 | 739 | strings.splice(index, 1);
|
766 | 740 | |
767 | - setTorSettings(() => {
|
|
768 | - TorSettings.bridges.bridge_strings = strings;
|
|
741 | + TorSettings.changeSettings({
|
|
742 | + bridges: { source, bridge_strings: strings },
|
|
769 | 743 | });
|
770 | 744 | });
|
771 | 745 | },
|
... | ... | @@ -1829,8 +1803,8 @@ const gBridgeSettings = { |
1829 | 1803 | if (!this._haveBridges) {
|
1830 | 1804 | return;
|
1831 | 1805 | }
|
1832 | - setTorSettings(() => {
|
|
1833 | - TorSettings.bridges.enabled = this._toggleButton.pressed;
|
|
1806 | + TorSettings.changeSettings({
|
|
1807 | + bridges: { enabled: this._toggleButton.pressed },
|
|
1834 | 1808 | });
|
1835 | 1809 | });
|
1836 | 1810 | |
... | ... | @@ -2215,10 +2189,10 @@ const gBridgeSettings = { |
2215 | 2189 | return;
|
2216 | 2190 | }
|
2217 | 2191 | |
2218 | - setTorSettings(() => {
|
|
2192 | + TorSettings.changeSettings({
|
|
2219 | 2193 | // This should always have the side effect of disabling bridges as
|
2220 | 2194 | // well.
|
2221 | - TorSettings.bridges.source = TorBridgeSource.Invalid;
|
|
2195 | + bridges: { source: TorBridgeSource.Invalid },
|
|
2222 | 2196 | });
|
2223 | 2197 | });
|
2224 | 2198 | |
... | ... | @@ -2319,10 +2293,12 @@ const gBridgeSettings = { |
2319 | 2293 | if (!result.type) {
|
2320 | 2294 | return null;
|
2321 | 2295 | }
|
2322 | - return setTorSettings(() => {
|
|
2323 | - TorSettings.bridges.enabled = true;
|
|
2324 | - TorSettings.bridges.source = TorBridgeSource.BuiltIn;
|
|
2325 | - TorSettings.bridges.builtin_type = result.type;
|
|
2296 | + return TorSettings.changeSettings({
|
|
2297 | + bridges: {
|
|
2298 | + enabled: true,
|
|
2299 | + source: TorBridgeSource.BuiltIn,
|
|
2300 | + builtin_type: result.type,
|
|
2301 | + },
|
|
2326 | 2302 | });
|
2327 | 2303 | }
|
2328 | 2304 | );
|
... | ... | @@ -2339,10 +2315,12 @@ const gBridgeSettings = { |
2339 | 2315 | if (!result.bridges?.length) {
|
2340 | 2316 | return null;
|
2341 | 2317 | }
|
2342 | - return setTorSettings(() => {
|
|
2343 | - TorSettings.bridges.enabled = true;
|
|
2344 | - TorSettings.bridges.source = TorBridgeSource.BridgeDB;
|
|
2345 | - TorSettings.bridges.bridge_strings = result.bridges.join("\n");
|
|
2318 | + return TorSettings.changeSettings({
|
|
2319 | + bridges: {
|
|
2320 | + enabled: true,
|
|
2321 | + source: TorBridgeSource.BridgeDB,
|
|
2322 | + bridge_strings: result.bridges.join("\n"),
|
|
2323 | + },
|
|
2346 | 2324 | });
|
2347 | 2325 | }
|
2348 | 2326 | );
|
... | ... | @@ -2363,16 +2341,15 @@ const gBridgeSettings = { |
2363 | 2341 | if (!loxId && !result.addresses?.length) {
|
2364 | 2342 | return null;
|
2365 | 2343 | }
|
2366 | - return setTorSettings(() => {
|
|
2367 | - TorSettings.bridges.enabled = true;
|
|
2368 | - if (loxId) {
|
|
2369 | - TorSettings.bridges.source = TorBridgeSource.Lox;
|
|
2370 | - TorSettings.bridges.lox_id = loxId;
|
|
2371 | - } else {
|
|
2372 | - TorSettings.bridges.source = TorBridgeSource.UserProvided;
|
|
2373 | - TorSettings.bridges.bridge_strings = result.addresses;
|
|
2374 | - }
|
|
2375 | - });
|
|
2344 | + const bridges = { enabled: true };
|
|
2345 | + if (loxId) {
|
|
2346 | + bridges.source = TorBridgeSource.Lox;
|
|
2347 | + bridges.lox_id = loxId;
|
|
2348 | + } else {
|
|
2349 | + bridges.source = TorBridgeSource.UserProvided;
|
|
2350 | + bridges.bridge_strings = result.addresses;
|
|
2351 | + }
|
|
2352 | + return TorSettings.changeSettings({ bridges });
|
|
2376 | 2353 | }
|
2377 | 2354 | );
|
2378 | 2355 | },
|
... | ... | @@ -2586,9 +2563,9 @@ const gConnectionPane = (function () { |
2586 | 2563 | "torPreferences-quickstart-toggle"
|
2587 | 2564 | );
|
2588 | 2565 | this._enableQuickstartCheckbox.addEventListener("command", () => {
|
2589 | - const checked = this._enableQuickstartCheckbox.checked;
|
|
2590 | - TorSettings.quickstart.enabled = checked;
|
|
2591 | - TorSettings.saveToPrefs().applySettings();
|
|
2566 | + TorSettings.changeSettings({
|
|
2567 | + quickstart: { enabled: this._enableQuickstartCheckbox.checked },
|
|
2568 | + });
|
|
2592 | 2569 | });
|
2593 | 2570 | this._enableQuickstartCheckbox.checked = TorSettings.quickstart.enabled;
|
2594 | 2571 | Services.obs.addObserver(this, TorSettingsTopics.SettingsChanged);
|
... | ... | @@ -270,33 +270,34 @@ const gConnectionSettingsDialog = { |
270 | 270 | const port = this._proxyPortTextbox.value;
|
271 | 271 | const username = this._proxyUsernameTextbox.value;
|
272 | 272 | const password = this._proxyPasswordTextbox.value;
|
273 | + const settings = { proxy: {}, firewall: {} };
|
|
273 | 274 | switch (type) {
|
274 | 275 | case TorProxyType.Invalid:
|
275 | - TorSettings.proxy.enabled = false;
|
|
276 | + settings.proxy.enabled = false;
|
|
276 | 277 | break;
|
277 | 278 | case TorProxyType.Socks4:
|
278 | - TorSettings.proxy.enabled = true;
|
|
279 | - TorSettings.proxy.type = type;
|
|
280 | - TorSettings.proxy.address = address;
|
|
281 | - TorSettings.proxy.port = port;
|
|
282 | - TorSettings.proxy.username = "";
|
|
283 | - TorSettings.proxy.password = "";
|
|
279 | + settings.proxy.enabled = true;
|
|
280 | + settings.proxy.type = type;
|
|
281 | + settings.proxy.address = address;
|
|
282 | + settings.proxy.port = port;
|
|
283 | + settings.proxy.username = "";
|
|
284 | + settings.proxy.password = "";
|
|
284 | 285 | break;
|
285 | 286 | case TorProxyType.Socks5:
|
286 | - TorSettings.proxy.enabled = true;
|
|
287 | - TorSettings.proxy.type = type;
|
|
288 | - TorSettings.proxy.address = address;
|
|
289 | - TorSettings.proxy.port = port;
|
|
290 | - TorSettings.proxy.username = username;
|
|
291 | - TorSettings.proxy.password = password;
|
|
287 | + settings.proxy.enabled = true;
|
|
288 | + settings.proxy.type = type;
|
|
289 | + settings.proxy.address = address;
|
|
290 | + settings.proxy.port = port;
|
|
291 | + settings.proxy.username = username;
|
|
292 | + settings.proxy.password = password;
|
|
292 | 293 | break;
|
293 | 294 | case TorProxyType.HTTPS:
|
294 | - TorSettings.proxy.enabled = true;
|
|
295 | - TorSettings.proxy.type = type;
|
|
296 | - TorSettings.proxy.address = address;
|
|
297 | - TorSettings.proxy.port = port;
|
|
298 | - TorSettings.proxy.username = username;
|
|
299 | - TorSettings.proxy.password = password;
|
|
295 | + settings.proxy.enabled = true;
|
|
296 | + settings.proxy.type = type;
|
|
297 | + settings.proxy.address = address;
|
|
298 | + settings.proxy.port = port;
|
|
299 | + settings.proxy.username = username;
|
|
300 | + settings.proxy.password = password;
|
|
300 | 301 | break;
|
301 | 302 | }
|
302 | 303 | |
... | ... | @@ -304,16 +305,15 @@ const gConnectionSettingsDialog = { |
304 | 305 | ? this._allowedPortsTextbox.value
|
305 | 306 | : "";
|
306 | 307 | if (portListString) {
|
307 | - TorSettings.firewall.enabled = true;
|
|
308 | - TorSettings.firewall.allowed_ports = portListString;
|
|
308 | + settings.firewall.enabled = true;
|
|
309 | + settings.firewall.allowed_ports = portListString;
|
|
309 | 310 | } else {
|
310 | - TorSettings.firewall.enabled = false;
|
|
311 | + settings.firewall.enabled = false;
|
|
311 | 312 | }
|
312 | 313 | |
313 | - TorSettings.saveToPrefs();
|
|
314 | 314 | // FIXME: What if this fails? Should we prevent the dialog to close and show
|
315 | 315 | // an error?
|
316 | - TorSettings.applySettings();
|
|
316 | + TorSettings.changeSettings(settings);
|
|
317 | 317 | },
|
318 | 318 | };
|
319 | 319 |
... | ... | @@ -80,7 +80,7 @@ class TorControllerGV( |
80 | 80 | set(value) {
|
81 | 81 | getTorSettings()?.let {
|
82 | 82 | it.quickstart = value
|
83 | - getTorIntegration().setSettings(it, true, true)
|
|
83 | + getTorIntegration().setSettings(it)
|
|
84 | 84 | }
|
85 | 85 | }
|
86 | 86 | |
... | ... | @@ -110,7 +110,7 @@ class TorControllerGV( |
110 | 110 | getTorSettings()?.let {
|
111 | 111 | if (!value || it.bridgesSource != BridgeSource.Invalid) {
|
112 | 112 | it.bridgesEnabled = value
|
113 | - getTorIntegration().setSettings(it, true, true)
|
|
113 | + getTorIntegration().setSettings(it)
|
|
114 | 114 | }
|
115 | 115 | }
|
116 | 116 | }
|
... | ... | @@ -150,7 +150,7 @@ class TorControllerGV( |
150 | 150 | }
|
151 | 151 | it.bridgesBuiltinType = bbt
|
152 | 152 | }
|
153 | - getTorIntegration().setSettings(it, true, true)
|
|
153 | + getTorIntegration().setSettings(it)
|
|
154 | 154 | }
|
155 | 155 | }
|
156 | 156 | |
... | ... | @@ -175,7 +175,7 @@ class TorControllerGV( |
175 | 175 | val userProvidedLines: Array<String> = value?.split("\n")?.filter { it.length > 4 }?.toTypedArray() ?: arrayOf<String>()
|
176 | 176 | it.bridgesSource = BridgeSource.UserProvided
|
177 | 177 | it.bridgeBridgeStrings = userProvidedLines
|
178 | - getTorIntegration().setSettings(it, true, true)
|
|
178 | + getTorIntegration().setSettings(it)
|
|
179 | 179 | }
|
180 | 180 | }
|
181 | 181 |
... | ... | @@ -48,8 +48,6 @@ public class TorIntegrationAndroid implements BundleEventListener { |
48 | 48 | // Events we emit
|
49 | 49 | private static final String EVENT_SETTINGS_GET = "GeckoView:Tor:SettingsGet";
|
50 | 50 | private static final String EVENT_SETTINGS_SET = "GeckoView:Tor:SettingsSet";
|
51 | - private static final String EVENT_SETTINGS_APPLY = "GeckoView:Tor:SettingsApply";
|
|
52 | - private static final String EVENT_SETTINGS_SAVE = "GeckoView:Tor:SettingsSave";
|
|
53 | 51 | private static final String EVENT_BOOTSTRAP_BEGIN = "GeckoView:Tor:BootstrapBegin";
|
54 | 52 | private static final String EVENT_BOOTSTRAP_BEGIN_AUTO = "GeckoView:Tor:BootstrapBeginAuto";
|
55 | 53 | private static final String EVENT_BOOTSTRAP_CANCEL = "GeckoView:Tor:BootstrapCancel";
|
... | ... | @@ -194,7 +192,7 @@ public class TorIntegrationAndroid implements BundleEventListener { |
194 | 192 | protected void onPostExecute(TorSettings torSettings) {
|
195 | 193 | mSettings = torSettings;
|
196 | 194 | if (TorLegacyAndroidSettings.unmigrated()) {
|
197 | - setSettings(mSettings, true, true);
|
|
195 | + setSettings(mSettings);
|
|
198 | 196 | TorLegacyAndroidSettings.setMigrated();
|
199 | 197 | }
|
200 | 198 | }
|
... | ... | @@ -657,10 +655,10 @@ public class TorIntegrationAndroid implements BundleEventListener { |
657 | 655 | return mSettings;
|
658 | 656 | }
|
659 | 657 | |
660 | - public void setSettings(final TorSettings settings, boolean save, boolean apply) {
|
|
658 | + public void setSettings(final TorSettings settings) {
|
|
661 | 659 | mSettings = settings;
|
662 | 660 | |
663 | - emitSetSettings(settings, save, apply)
|
|
661 | + emitSetSettings(settings)
|
|
664 | 662 | .then(
|
665 | 663 | new GeckoResult.OnValueListener<Void, Void>() {
|
666 | 664 | public GeckoResult<Void> onValue(Void v) {
|
... | ... | @@ -677,22 +675,12 @@ public class TorIntegrationAndroid implements BundleEventListener { |
677 | 675 | }
|
678 | 676 | |
679 | 677 | private @NonNull GeckoResult<Void> emitSetSettings(
|
680 | - final TorSettings settings, boolean save, boolean apply) {
|
|
681 | - GeckoBundle bundle = new GeckoBundle(3);
|
|
682 | - bundle.putBoolean("save", save);
|
|
683 | - bundle.putBoolean("apply", apply);
|
|
678 | + final TorSettings settings) {
|
|
679 | + GeckoBundle bundle = new GeckoBundle(1);
|
|
684 | 680 | bundle.putBundle("settings", settings.asGeckoBundle());
|
685 | 681 | return EventDispatcher.getInstance().queryVoid(EVENT_SETTINGS_SET, bundle);
|
686 | 682 | }
|
687 | 683 | |
688 | - public @NonNull GeckoResult<Void> applySettings() {
|
|
689 | - return EventDispatcher.getInstance().queryVoid(EVENT_SETTINGS_APPLY);
|
|
690 | - }
|
|
691 | - |
|
692 | - public @NonNull GeckoResult<Void> saveSettings() {
|
|
693 | - return EventDispatcher.getInstance().queryVoid(EVENT_SETTINGS_SAVE);
|
|
694 | - }
|
|
695 | - |
|
696 | 684 | public @NonNull GeckoResult<Void> beginBootstrap() {
|
697 | 685 | return EventDispatcher.getInstance().queryVoid(EVENT_BOOTSTRAP_BEGIN);
|
698 | 686 | }
|
... | ... | @@ -104,8 +104,7 @@ export class TorConnectParent extends JSWindowActorParent { |
104 | 104 | // If there are multiple home pages, just load the first one.
|
105 | 105 | return Promise.resolve(TorConnect.fixupURIs(lazy.HomePage.get())[0]);
|
106 | 106 | case "torconnect:set-quickstart":
|
107 | - TorSettings.quickstart.enabled = message.data;
|
|
108 | - TorSettings.saveToPrefs().applySettings();
|
|
107 | + TorSettings.changeSettings({ quickstart: { enabled: message.data } });
|
|
109 | 108 | break;
|
110 | 109 | case "torconnect:open-tor-preferences":
|
111 | 110 | this.browsingContext.top.embedderElement.ownerGlobal.openPreferences(
|
... | ... | @@ -36,8 +36,6 @@ const ListenedEvents = Object.freeze({ |
36 | 36 | settingsGet: "GeckoView:Tor:SettingsGet",
|
37 | 37 | // The data is passed directly to TorSettings.
|
38 | 38 | settingsSet: "GeckoView:Tor:SettingsSet",
|
39 | - settingsApply: "GeckoView:Tor:SettingsApply",
|
|
40 | - settingsSave: "GeckoView:Tor:SettingsSave",
|
|
41 | 39 | bootstrapBegin: "GeckoView:Tor:BootstrapBegin",
|
42 | 40 | // Optionally takes a countryCode, as data.countryCode.
|
43 | 41 | bootstrapBeginAuto: "GeckoView:Tor:BootstrapBeginAuto",
|
... | ... | @@ -145,20 +143,10 @@ class TorAndroidIntegrationImpl { |
145 | 143 | callback?.onSuccess(lazy.TorSettings.getSettings());
|
146 | 144 | return;
|
147 | 145 | case ListenedEvents.settingsSet:
|
148 | - // This does not throw, so we do not have any way to report the error!
|
|
149 | - lazy.TorSettings.setSettings(data.settings);
|
|
150 | - if (data.save) {
|
|
151 | - lazy.TorSettings.saveToPrefs();
|
|
152 | - }
|
|
153 | - if (data.apply) {
|
|
154 | - await lazy.TorSettings.applySettings();
|
|
155 | - }
|
|
156 | - break;
|
|
157 | - case ListenedEvents.settingsApply:
|
|
158 | - await lazy.TorSettings.applySettings();
|
|
159 | - break;
|
|
160 | - case ListenedEvents.settingsSave:
|
|
161 | - await lazy.TorSettings.saveToPrefs();
|
|
146 | + // TODO: Handle setting throw? This can throw if data.settings is
|
|
147 | + // incorrectly formatted, but more like it can throw when the settings
|
|
148 | + // fail to be passed onto the TorProvider. tor-browser#43405.
|
|
149 | + await lazy.TorSettings.changeSettings(data.settings);
|
|
162 | 150 | break;
|
163 | 151 | case ListenedEvents.bootstrapBegin:
|
164 | 152 | lazy.TorConnect.beginBootstrapping();
|
... | ... | @@ -422,7 +422,7 @@ class TorSettingsImpl { |
422 | 422 | * not contradict each other.
|
423 | 423 | */
|
424 | 424 | #cleanupSettings() {
|
425 | - this.freezeNotifications();
|
|
425 | + this.#freezeNotifications();
|
|
426 | 426 | try {
|
427 | 427 | if (this.bridges.source === TorBridgeSource.Invalid) {
|
428 | 428 | this.bridges.enabled = false;
|
... | ... | @@ -449,7 +449,7 @@ class TorSettingsImpl { |
449 | 449 | this.firewall.allowed_ports = [];
|
450 | 450 | }
|
451 | 451 | } finally {
|
452 | - this.thawNotifications();
|
|
452 | + this.#thawNotifications();
|
|
453 | 453 | }
|
454 | 454 | }
|
455 | 455 | |
... | ... | @@ -488,7 +488,7 @@ class TorSettingsImpl { |
488 | 488 | * changes you make with a `try` block and call thawNotifications in the
|
489 | 489 | * `finally` block.
|
490 | 490 | */
|
491 | - freezeNotifications() {
|
|
491 | + #freezeNotifications() {
|
|
492 | 492 | this.#freezeNotificationsCount++;
|
493 | 493 | }
|
494 | 494 | /**
|
... | ... | @@ -497,7 +497,7 @@ class TorSettingsImpl { |
497 | 497 | * Note, if some other method has also frozen the notifications, this will
|
498 | 498 | * only release them once it has also called this method.
|
499 | 499 | */
|
500 | - thawNotifications() {
|
|
500 | + #thawNotifications() {
|
|
501 | 501 | this.#freezeNotificationsCount--;
|
502 | 502 | this.#tryNotification();
|
503 | 503 | }
|
... | ... | @@ -571,7 +571,7 @@ class TorSettingsImpl { |
571 | 571 | this.#checkIfInitialized();
|
572 | 572 | }
|
573 | 573 | const prevVal = this.#settings[groupname][name];
|
574 | - this.freezeNotifications();
|
|
574 | + this.#freezeNotifications();
|
|
575 | 575 | try {
|
576 | 576 | if (transform) {
|
577 | 577 | val = transform(val, addError);
|
... | ... | @@ -589,7 +589,7 @@ class TorSettingsImpl { |
589 | 589 | } catch (e) {
|
590 | 590 | addError(e.message);
|
591 | 591 | } finally {
|
592 | - this.thawNotifications();
|
|
592 | + this.#thawNotifications();
|
|
593 | 593 | }
|
594 | 594 | },
|
595 | 595 | });
|
... | ... | @@ -717,7 +717,7 @@ class TorSettingsImpl { |
717 | 717 | Services.prefs.getBoolPref(TorSettingsPrefs.enabled, false)
|
718 | 718 | ) {
|
719 | 719 | // Do not want notifications for initially loaded prefs.
|
720 | - this.freezeNotifications();
|
|
720 | + this.#freezeNotifications();
|
|
721 | 721 | try {
|
722 | 722 | this.#allowUninitialized = true;
|
723 | 723 | this.#loadFromPrefs();
|
... | ... | @@ -726,7 +726,7 @@ class TorSettingsImpl { |
726 | 726 | } finally {
|
727 | 727 | this.#allowUninitialized = false;
|
728 | 728 | this.#notificationQueue.clear();
|
729 | - this.thawNotifications();
|
|
729 | + this.#thawNotifications();
|
|
730 | 730 | }
|
731 | 731 | }
|
732 | 732 | |
... | ... | @@ -755,7 +755,7 @@ class TorSettingsImpl { |
755 | 755 | // source. But we do pass on the changes to TorProvider.
|
756 | 756 | // FIXME: This can compete with TorConnect to reach TorProvider.
|
757 | 757 | // tor-browser#42316
|
758 | - this.applySettings();
|
|
758 | + this.#applySettings();
|
|
759 | 759 | }
|
760 | 760 | break;
|
761 | 761 | }
|
... | ... | @@ -876,7 +876,7 @@ class TorSettingsImpl { |
876 | 876 | /**
|
877 | 877 | * Save our settings to prefs.
|
878 | 878 | */
|
879 | - saveToPrefs() {
|
|
879 | + #saveToPrefs() {
|
|
880 | 880 | lazy.logger.debug("saveToPrefs()");
|
881 | 881 | |
882 | 882 | this.#checkIfInitialized();
|
... | ... | @@ -968,8 +968,6 @@ class TorSettingsImpl { |
968 | 968 | |
969 | 969 | // all tor settings now stored in prefs :)
|
970 | 970 | Services.prefs.setBoolPref(TorSettingsPrefs.enabled, true);
|
971 | - |
|
972 | - return this;
|
|
973 | 971 | }
|
974 | 972 | |
975 | 973 | /**
|
... | ... | @@ -978,23 +976,28 @@ class TorSettingsImpl { |
978 | 976 | * Even though this introduces a circular depdency, it makes the API nicer for
|
979 | 977 | * frontend consumers.
|
980 | 978 | */
|
981 | - async applySettings() {
|
|
979 | + async #applySettings() {
|
|
982 | 980 | this.#checkIfInitialized();
|
983 | 981 | const provider = await lazy.TorProviderBuilder.build();
|
984 | 982 | await provider.writeSettings();
|
985 | 983 | }
|
986 | 984 | |
987 | 985 | /**
|
988 | - * Set blocks of settings at once from an object.
|
|
986 | + * Change the Tor settings in use.
|
|
987 | + *
|
|
988 | + * It is possible to set all settings, or only some sections:
|
|
989 | 989 | *
|
990 | - * It is possible to set all settings, or only some sections (e.g., only
|
|
991 | - * bridges), but if a key is present, its settings must make sense (e.g., if
|
|
992 | - * bridges are enabled, a valid source must be provided).
|
|
990 | + * + quickstart.enabled can be set individually.
|
|
991 | + * + bridges.enabled can be set individually.
|
|
992 | + * + bridges.source can be set with a corresponding bridge specification for
|
|
993 | + * the source (bridge_strings, lox_id, builtin_type).
|
|
994 | + * + proxy settings can be set as a group.
|
|
995 | + * + firewall settings can be set a group.
|
|
993 | 996 | *
|
994 | - * @param {object} settings The settings object to set
|
|
997 | + * @param {object} settings - The settings object to set.
|
|
995 | 998 | */
|
996 | - setSettings(settings) {
|
|
997 | - lazy.logger.debug("setSettings()");
|
|
999 | + async changeSettings(settings) {
|
|
1000 | + lazy.logger.debug("changeSettings()", settings);
|
|
998 | 1001 | this.#checkIfInitialized();
|
999 | 1002 | |
1000 | 1003 | const backup = this.getSettings();
|
... | ... | @@ -1003,38 +1006,39 @@ class TorSettingsImpl { |
1003 | 1006 | this.#settingErrors = [];
|
1004 | 1007 | |
1005 | 1008 | // Hold off on lots of notifications until all settings are changed.
|
1006 | - this.freezeNotifications();
|
|
1009 | + this.#freezeNotifications();
|
|
1007 | 1010 | try {
|
1008 | - if ("quickstart" in settings) {
|
|
1011 | + if ("quickstart" in settings && "enabled" in settings.quickstart) {
|
|
1009 | 1012 | this.quickstart.enabled = !!settings.quickstart.enabled;
|
1010 | 1013 | }
|
1011 | 1014 | |
1012 | 1015 | if ("bridges" in settings) {
|
1013 | - this.bridges.enabled = !!settings.bridges.enabled;
|
|
1014 | - // Currently, disabling bridges in the UI does not remove the lines,
|
|
1015 | - // because we call only the `enabled` setter.
|
|
1016 | - // So, if the bridge source is undefined but bridges are disabled,
|
|
1017 | - // do not force Invalid. Instead, keep the current source.
|
|
1018 | - if (this.bridges.enabled || settings.bridges.source !== undefined) {
|
|
1019 | - this.bridges.source = settings.bridges.source;
|
|
1016 | + if ("enabled" in settings.bridges) {
|
|
1017 | + this.bridges.enabled = !!settings.bridges.enabled;
|
|
1020 | 1018 | }
|
1021 | - switch (settings.bridges.source) {
|
|
1022 | - case TorBridgeSource.BridgeDB:
|
|
1023 | - case TorBridgeSource.UserProvided:
|
|
1024 | - this.bridges.bridge_strings = settings.bridges.bridge_strings;
|
|
1025 | - break;
|
|
1026 | - case TorBridgeSource.BuiltIn:
|
|
1027 | - this.bridges.builtin_type = settings.bridges.builtin_type;
|
|
1028 | - break;
|
|
1029 | - case TorBridgeSource.Lox:
|
|
1030 | - this.bridges.lox_id = settings.bridges.lox_id;
|
|
1031 | - break;
|
|
1032 | - case TorBridgeSource.Invalid:
|
|
1033 | - break;
|
|
1019 | + if ("source" in settings.bridges) {
|
|
1020 | + this.bridges.source = settings.bridges.source;
|
|
1021 | + switch (settings.bridges.source) {
|
|
1022 | + case TorBridgeSource.BridgeDB:
|
|
1023 | + case TorBridgeSource.UserProvided:
|
|
1024 | + this.bridges.bridge_strings = settings.bridges.bridge_strings;
|
|
1025 | + break;
|
|
1026 | + case TorBridgeSource.BuiltIn:
|
|
1027 | + this.bridges.builtin_type = settings.bridges.builtin_type;
|
|
1028 | + break;
|
|
1029 | + case TorBridgeSource.Lox:
|
|
1030 | + this.bridges.lox_id = settings.bridges.lox_id;
|
|
1031 | + break;
|
|
1032 | + case TorBridgeSource.Invalid:
|
|
1033 | + break;
|
|
1034 | + case undefined:
|
|
1035 | + break;
|
|
1036 | + }
|
|
1034 | 1037 | }
|
1035 | 1038 | }
|
1036 | 1039 | |
1037 | 1040 | if ("proxy" in settings) {
|
1041 | + // proxy settings have to be set as a group.
|
|
1038 | 1042 | this.proxy.enabled = !!settings.proxy.enabled;
|
1039 | 1043 | if (this.proxy.enabled) {
|
1040 | 1044 | this.proxy.type = settings.proxy.type;
|
... | ... | @@ -1046,6 +1050,7 @@ class TorSettingsImpl { |
1046 | 1050 | }
|
1047 | 1051 | |
1048 | 1052 | if ("firewall" in settings) {
|
1053 | + // firewall settings have to be set as a group.
|
|
1049 | 1054 | this.firewall.enabled = !!settings.firewall.enabled;
|
1050 | 1055 | if (this.firewall.enabled) {
|
1051 | 1056 | this.firewall.allowed_ports = settings.firewall.allowed_ports;
|
... | ... | @@ -1057,27 +1062,33 @@ class TorSettingsImpl { |
1057 | 1062 | if (this.#settingErrors.length) {
|
1058 | 1063 | throw Error(this.#settingErrors.join("; "));
|
1059 | 1064 | }
|
1065 | + this.#saveToPrefs();
|
|
1060 | 1066 | } catch (ex) {
|
1061 | 1067 | // Restore the old settings without any new notifications generated from
|
1062 | 1068 | // the above code.
|
1063 | - // NOTE: Since this code is not async, it should not be possible for
|
|
1064 | - // some other call to TorSettings to change anything whilst we are
|
|
1065 | - // in this context (other than lower down in this call stack), so it is
|
|
1066 | - // safe to discard all changes to settings and notifications.
|
|
1069 | + // NOTE: Since the code that changes #settings is not async, it should not
|
|
1070 | + // be possible for some other call to TorSettings to change anything
|
|
1071 | + // whilst we are in this context (other than lower down in this call
|
|
1072 | + // stack), so it is safe to discard all changes to settings and
|
|
1073 | + // notifications.
|
|
1067 | 1074 | this.#settings = backup;
|
1068 | 1075 | this.#notificationQueue.clear();
|
1069 | 1076 | for (const notification of backupNotifications) {
|
1070 | 1077 | this.#notificationQueue.add(notification);
|
1071 | 1078 | }
|
1072 | 1079 | |
1073 | - lazy.logger.error("setSettings failed", ex);
|
|
1080 | + throw ex;
|
|
1074 | 1081 | } finally {
|
1075 | - this.thawNotifications();
|
|
1082 | + this.#thawNotifications();
|
|
1076 | 1083 | // Stop collecting errors.
|
1077 | 1084 | this.#settingErrors = null;
|
1078 | 1085 | }
|
1079 | 1086 | |
1080 | 1087 | lazy.logger.debug("setSettings result", this.#settings);
|
1088 | + |
|
1089 | + // After we have sent out the notifications for the changed settings and
|
|
1090 | + // saved the preferences we send the new settings to TorProvider.
|
|
1091 | + await this.#applySettings();
|
|
1081 | 1092 | }
|
1082 | 1093 | |
1083 | 1094 | /**
|
... | ... | @@ -1162,7 +1173,7 @@ class TorSettingsImpl { |
1162 | 1173 | |
1163 | 1174 | // After checks are complete, we commit them.
|
1164 | 1175 | this.#temporaryBridgeSettings = bridgeSettings;
|
1165 | - await this.applySettings();
|
|
1176 | + await this.#applySettings();
|
|
1166 | 1177 | }
|
1167 | 1178 | |
1168 | 1179 | /**
|
... | ... | @@ -1174,10 +1185,9 @@ class TorSettingsImpl { |
1174 | 1185 | lazy.logger.warn("No temporary bridges to save");
|
1175 | 1186 | return;
|
1176 | 1187 | }
|
1177 | - this.setSettings({ bridges: this.#temporaryBridgeSettings });
|
|
1188 | + const bridgeSettings = this.#temporaryBridgeSettings;
|
|
1178 | 1189 | this.#temporaryBridgeSettings = null;
|
1179 | - this.saveToPrefs();
|
|
1180 | - await this.applySettings();
|
|
1190 | + await this.changeSettings({ bridges: bridgeSettings });
|
|
1181 | 1191 | }
|
1182 | 1192 | |
1183 | 1193 | /**
|
... | ... | @@ -1190,7 +1200,7 @@ class TorSettingsImpl { |
1190 | 1200 | return;
|
1191 | 1201 | }
|
1192 | 1202 | this.#temporaryBridgeSettings = null;
|
1193 | - await this.applySettings();
|
|
1203 | + await this.#applySettings();
|
|
1194 | 1204 | }
|
1195 | 1205 | }
|
1196 | 1206 |