Pier Angelo Vendrame pushed to branch tor-browser-128.6.0esr-14.5-1 at The Tor Project / Applications / Tor Browser
Commits:
-
1ad717fe
by Henry Wilkes at 2025-01-21T14:56:40+00:00
-
8ae53510
by Henry Wilkes at 2025-01-21T14:56:41+00:00
-
a0c13700
by Henry Wilkes at 2025-01-21T14:56:41+00:00
-
7a98943f
by Henry Wilkes at 2025-01-21T15:00:22+00:00
4 changed files:
- browser/app/profile/000-tor-browser.js
- browser/components/BrowserGlue.sys.mjs
- toolkit/components/tor-launcher/TorLauncherUtil.sys.mjs
- toolkit/modules/TorSettings.sys.mjs
Changes:
| ... | ... | @@ -61,6 +61,31 @@ pref("browser.startup.homepage", "about:tor"); |
| 61 | 61 | // tor-browser#40701: Add new download warning
|
| 62 | 62 | pref("browser.download.showTorWarning", true);
|
| 63 | 63 | |
| 64 | + |
|
| 65 | +// Tor connection setting preferences.
|
|
| 66 | + |
|
| 67 | +pref("torbrowser.settings.quickstart.enabled", false);
|
|
| 68 | +pref("torbrowser.settings.bridges.enabled", false);
|
|
| 69 | +// TorBridgeSource. Initially TorBridgeSource.Invalid = -1.
|
|
| 70 | +pref("torbrowser.settings.bridges.source", -1);
|
|
| 71 | +pref("torbrowser.settings.bridges.lox_id", "");
|
|
| 72 | +// obfs4|meek-azure|snowflake|etc.
|
|
| 73 | +pref("torbrowser.settings.bridges.builtin_type", "");
|
|
| 74 | +// torbrowser.settings.bridges.bridge_strings.0
|
|
| 75 | +// torbrowser.settings.bridges.bridge_strings.1
|
|
| 76 | +// etc hold the bridge lines.
|
|
| 77 | +pref("torbrowser.settings.proxy.enabled", false);
|
|
| 78 | +// TorProxyType. Initially TorProxyType.Invalid = -1.
|
|
| 79 | +pref("torbrowser.settings.proxy.type", -1);
|
|
| 80 | +pref("torbrowser.settings.proxy.address", "");
|
|
| 81 | +pref("torbrowser.settings.proxy.port", 0);
|
|
| 82 | +pref("torbrowser.settings.proxy.username", "");
|
|
| 83 | +pref("torbrowser.settings.proxy.password", "");
|
|
| 84 | +pref("torbrowser.settings.firewall.enabled", false);
|
|
| 85 | +// comma-delimited list of port numbers.
|
|
| 86 | +pref("torbrowser.settings.firewall.allowed_ports", "");
|
|
| 87 | + |
|
| 88 | + |
|
| 64 | 89 | // This pref specifies an ad-hoc "version" for various pref update hacks we need to do
|
| 65 | 90 | pref("extensions.torbutton.pref_fixup_version", 0);
|
| 66 | 91 |
| ... | ... | @@ -4822,7 +4822,9 @@ BrowserGlue.prototype = { |
| 4822 | 4822 | // YouTube search engines (tor-browser#41835).
|
| 4823 | 4823 | // Version 5: Tor Browser 14.0a5: Clear user preference for CFR settings
|
| 4824 | 4824 | // since we hid the UI (tor-browser#43118).
|
| 4825 | - const TBB_MIGRATION_VERSION = 5;
|
|
| 4825 | + // Version 6: Tor Browser 14.5a3: Clear preference for TorSettings that is
|
|
| 4826 | + // no longer used (tor-browser#41921).
|
|
| 4827 | + const TBB_MIGRATION_VERSION = 6;
|
|
| 4826 | 4828 | const MIGRATION_PREF = "torbrowser.migration.version";
|
| 4827 | 4829 | |
| 4828 | 4830 | // If we decide to force updating users to pass through any version
|
| ... | ... | @@ -4904,6 +4906,10 @@ BrowserGlue.prototype = { |
| 4904 | 4906 | }
|
| 4905 | 4907 | }
|
| 4906 | 4908 | |
| 4909 | + if (currentVersion < 6) {
|
|
| 4910 | + Services.prefs.clearUserPref("torbrowser.settings.enabled");
|
|
| 4911 | + }
|
|
| 4912 | + |
|
| 4907 | 4913 | Services.prefs.setIntPref(MIGRATION_PREF, TBB_MIGRATION_VERSION);
|
| 4908 | 4914 | },
|
| 4909 | 4915 |
| ... | ... | @@ -17,8 +17,6 @@ const kPropBundleURI = "chrome://torbutton/locale/torlauncher.properties"; |
| 17 | 17 | const kPropNamePrefix = "torlauncher.";
|
| 18 | 18 | const kIPCDirPrefName = "extensions.torlauncher.tmp_ipc_dir";
|
| 19 | 19 | |
| 20 | -let gStringBundle = null;
|
|
| 21 | - |
|
| 22 | 20 | /**
|
| 23 | 21 | * This class allows to lookup for the paths of the various files that are
|
| 24 | 22 | * needed or can be used with the tor daemon, such as its configuration, the
|
| ... | ... | @@ -332,7 +330,7 @@ class TorFile { |
| 332 | 330 | }
|
| 333 | 331 | }
|
| 334 | 332 | |
| 335 | -export const TorLauncherUtil = Object.freeze({
|
|
| 333 | +export const TorLauncherUtil = {
|
|
| 336 | 334 | get isAndroid() {
|
| 337 | 335 | return Services.appinfo.OS === "Android";
|
| 338 | 336 | },
|
| ... | ... | @@ -417,6 +415,8 @@ export const TorLauncherUtil = Object.freeze({ |
| 417 | 415 | return this.showConfirm(null, s, defaultBtnLabel, cancelBtnLabel);
|
| 418 | 416 | },
|
| 419 | 417 | |
| 418 | + _stringBundle: null,
|
|
| 419 | + |
|
| 420 | 420 | // Localized Strings
|
| 421 | 421 | // TODO: Switch to fluent also these ones.
|
| 422 | 422 | |
| ... | ... | @@ -425,6 +425,9 @@ export const TorLauncherUtil = Object.freeze({ |
| 425 | 425 | if (!aStringName) {
|
| 426 | 426 | return aStringName;
|
| 427 | 427 | }
|
| 428 | + if (!this._stringBundle) {
|
|
| 429 | + this._stringBundle = Services.strings.createBundle(kPropBundleURI);
|
|
| 430 | + }
|
|
| 428 | 431 | try {
|
| 429 | 432 | const key = kPropNamePrefix + aStringName;
|
| 430 | 433 | return this._stringBundle.GetStringFromName(key);
|
| ... | ... | @@ -587,7 +590,12 @@ export const TorLauncherUtil = Object.freeze({ |
| 587 | 590 | Services.prefs.savePrefFile(null);
|
| 588 | 591 | },
|
| 589 | 592 | |
| 590 | - get shouldStartAndOwnTor() {
|
|
| 593 | + /**
|
|
| 594 | + * Determine the current value for whether we should start and own Tor.
|
|
| 595 | + *
|
|
| 596 | + * @returns {boolean} Whether we should start and own Tor.
|
|
| 597 | + */
|
|
| 598 | + _getShouldStartAndOwnTor() {
|
|
| 591 | 599 | const kPrefStartTor = "extensions.torlauncher.start_tor";
|
| 592 | 600 | try {
|
| 593 | 601 | const kBrowserToolboxPort = "MOZ_BROWSER_TOOLBOX_PORT";
|
| ... | ... | @@ -610,6 +618,29 @@ export const TorLauncherUtil = Object.freeze({ |
| 610 | 618 | return Services.prefs.getBoolPref(kPrefStartTor, true);
|
| 611 | 619 | },
|
| 612 | 620 | |
| 621 | + /**
|
|
| 622 | + * Cached value for shouldStartAndOwnTor, or `null` if not yet initialised.
|
|
| 623 | + *
|
|
| 624 | + * @type {boolean}
|
|
| 625 | + */
|
|
| 626 | + _shouldStartAndOwnTor: null,
|
|
| 627 | + |
|
| 628 | + /**
|
|
| 629 | + * Whether we should start and own Tor.
|
|
| 630 | + *
|
|
| 631 | + * The value should be constant per-session.
|
|
| 632 | + *
|
|
| 633 | + * @type {boolean}
|
|
| 634 | + */
|
|
| 635 | + get shouldStartAndOwnTor() {
|
|
| 636 | + // Do not want this value to change within the same session, so always used
|
|
| 637 | + // the cached valued if it is available.
|
|
| 638 | + if (this._shouldStartAndOwnTor === null) {
|
|
| 639 | + this._shouldStartAndOwnTor = this._getShouldStartAndOwnTor();
|
|
| 640 | + }
|
|
| 641 | + return this._shouldStartAndOwnTor;
|
|
| 642 | + },
|
|
| 643 | + |
|
| 613 | 644 | get shouldShowNetworkSettings() {
|
| 614 | 645 | try {
|
| 615 | 646 | const kEnvForceShowNetConfig = "TOR_FORCE_NET_CONFIG";
|
| ... | ... | @@ -668,11 +699,4 @@ export const TorLauncherUtil = Object.freeze({ |
| 668 | 699 | console.warn("Could not remove the IPC directory", e);
|
| 669 | 700 | }
|
| 670 | 701 | },
|
| 671 | - |
|
| 672 | - get _stringBundle() {
|
|
| 673 | - if (!gStringBundle) {
|
|
| 674 | - gStringBundle = Services.strings.createBundle(kPropBundleURI);
|
|
| 675 | - }
|
|
| 676 | - return gStringBundle;
|
|
| 677 | - },
|
|
| 678 | -}); |
|
| 702 | +}; |
| ... | ... | @@ -27,8 +27,6 @@ export const TorSettingsTopics = Object.freeze({ |
| 27 | 27 | |
| 28 | 28 | /* Prefs used to store settings in TorBrowser prefs */
|
| 29 | 29 | const TorSettingsPrefs = Object.freeze({
|
| 30 | - /* bool: are we pulling tor settings from the preferences */
|
|
| 31 | - enabled: "torbrowser.settings.enabled",
|
|
| 32 | 30 | quickstart: {
|
| 33 | 31 | /* bool: does tor connect automatically on launch */
|
| 34 | 32 | enabled: "torbrowser.settings.quickstart.enabled",
|
| ... | ... | @@ -245,6 +243,13 @@ class TorSettingsImpl { |
| 245 | 243 | */
|
| 246 | 244 | #builtinBridges = {};
|
| 247 | 245 | |
| 246 | + /**
|
|
| 247 | + * A promise that resolves once we are initialized, or throws if there was an
|
|
| 248 | + * initialization error.
|
|
| 249 | + *
|
|
| 250 | + * @type {Promise}
|
|
| 251 | + */
|
|
| 252 | + #initializedPromise;
|
|
| 248 | 253 | /**
|
| 249 | 254 | * Resolve callback of the initializedPromise.
|
| 250 | 255 | */
|
| ... | ... | @@ -261,8 +266,29 @@ class TorSettingsImpl { |
| 261 | 266 | */
|
| 262 | 267 | #initialized = false;
|
| 263 | 268 | |
| 269 | + /**
|
|
| 270 | + * Whether uninit cleanup has been called.
|
|
| 271 | + *
|
|
| 272 | + * @type {boolean}
|
|
| 273 | + */
|
|
| 274 | + #uninitCalled = false;
|
|
| 275 | + |
|
| 276 | + /**
|
|
| 277 | + * Whether Lox was initialized.
|
|
| 278 | + *
|
|
| 279 | + * @type {boolean}
|
|
| 280 | + */
|
|
| 281 | + #initializedLox = false;
|
|
| 282 | + |
|
| 283 | + /**
|
|
| 284 | + * Whether observers were initialized.
|
|
| 285 | + *
|
|
| 286 | + * @type {boolean}
|
|
| 287 | + */
|
|
| 288 | + #initializedObservers = false;
|
|
| 289 | + |
|
| 264 | 290 | constructor() {
|
| 265 | - this.initializedPromise = new Promise((resolve, reject) => {
|
|
| 291 | + this.#initializedPromise = new Promise((resolve, reject) => {
|
|
| 266 | 292 | this.#initComplete = resolve;
|
| 267 | 293 | this.#initFailed = reject;
|
| 268 | 294 | });
|
| ... | ... | @@ -378,12 +404,22 @@ class TorSettingsImpl { |
| 378 | 404 | return this.#builtinBridges[pt] ?? [];
|
| 379 | 405 | }
|
| 380 | 406 | |
| 407 | + /**
|
|
| 408 | + * Whether this module is enabled.
|
|
| 409 | + *
|
|
| 410 | + * @type {boolean}
|
|
| 411 | + */
|
|
| 412 | + get enabled() {
|
|
| 413 | + return lazy.TorLauncherUtil.shouldStartAndOwnTor;
|
|
| 414 | + }
|
|
| 415 | + |
|
| 381 | 416 | /**
|
| 382 | 417 | * Load or init our settings.
|
| 383 | 418 | */
|
| 384 | 419 | async init() {
|
| 385 | 420 | if (this.#initialized) {
|
| 386 | 421 | lazy.logger.warn("Called init twice.");
|
| 422 | + await this.#initializedPromise;
|
|
| 387 | 423 | return;
|
| 388 | 424 | }
|
| 389 | 425 | try {
|
| ... | ... | @@ -402,6 +438,11 @@ class TorSettingsImpl { |
| 402 | 438 | * it easier to update initializatedPromise.
|
| 403 | 439 | */
|
| 404 | 440 | async #initInternal() {
|
| 441 | + if (!this.enabled || this.#uninitCalled) {
|
|
| 442 | + // Nothing to do.
|
|
| 443 | + return;
|
|
| 444 | + }
|
|
| 445 | + |
|
| 405 | 446 | try {
|
| 406 | 447 | const req = await fetch("chrome://global/content/pt_config.json");
|
| 407 | 448 | const config = await req.json();
|
| ... | ... | @@ -419,26 +460,37 @@ class TorSettingsImpl { |
| 419 | 460 | lazy.logger.error("Could not load the built-in PT config.", e);
|
| 420 | 461 | }
|
| 421 | 462 | |
| 463 | + // `uninit` may have been called whilst we awaited pt_config.
|
|
| 464 | + if (this.#uninitCalled) {
|
|
| 465 | + lazy.logger.warn("unint was called before init completed.");
|
|
| 466 | + return;
|
|
| 467 | + }
|
|
| 468 | + |
|
| 422 | 469 | // Initialize this before loading from prefs because we need Lox initialized
|
| 423 | 470 | // before any calls to Lox.getBridges().
|
| 424 | 471 | if (!lazy.TorLauncherUtil.isAndroid) {
|
| 425 | 472 | try {
|
| 473 | + // Set as initialized before calling to ensure it is cleaned up by our
|
|
| 474 | + // `uninit` method.
|
|
| 475 | + this.#initializedLox = true;
|
|
| 426 | 476 | await lazy.Lox.init();
|
| 427 | 477 | } catch (e) {
|
| 428 | 478 | lazy.logger.error("Could not initialize Lox.", e);
|
| 429 | 479 | }
|
| 430 | 480 | }
|
| 431 | 481 | |
| 432 | - if (
|
|
| 433 | - lazy.TorLauncherUtil.shouldStartAndOwnTor &&
|
|
| 434 | - Services.prefs.getBoolPref(TorSettingsPrefs.enabled, false)
|
|
| 435 | - ) {
|
|
| 436 | - this.#loadFromPrefs();
|
|
| 437 | - // We do not pass on the loaded settings to the TorProvider yet. Instead
|
|
| 438 | - // TorProvider will ask for these once it has initialised.
|
|
| 482 | + // `uninit` may have been called whilst we awaited Lox.init.
|
|
| 483 | + if (this.#uninitCalled) {
|
|
| 484 | + lazy.logger.warn("unint was called before init completed.");
|
|
| 485 | + return;
|
|
| 439 | 486 | }
|
| 440 | 487 | |
| 488 | + this.#loadFromPrefs();
|
|
| 489 | + // We do not pass on the loaded settings to the TorProvider yet. Instead
|
|
| 490 | + // TorProvider will ask for these once it has initialised.
|
|
| 491 | + |
|
| 441 | 492 | Services.obs.addObserver(this, lazy.LoxTopics.UpdateBridges);
|
| 493 | + this.#initializedObservers = true;
|
|
| 442 | 494 | |
| 443 | 495 | lazy.logger.info("Ready");
|
| 444 | 496 | }
|
| ... | ... | @@ -447,8 +499,22 @@ class TorSettingsImpl { |
| 447 | 499 | * Unload or uninit our settings.
|
| 448 | 500 | */
|
| 449 | 501 | async uninit() {
|
| 450 | - Services.obs.removeObserver(this, lazy.LoxTopics.UpdateBridges);
|
|
| 451 | - await lazy.Lox.uninit();
|
|
| 502 | + if (this.#uninitCalled) {
|
|
| 503 | + lazy.logger.warn("Called uninit twice");
|
|
| 504 | + return;
|
|
| 505 | + }
|
|
| 506 | + |
|
| 507 | + this.#uninitCalled = true;
|
|
| 508 | + // NOTE: We do not reset #initialized to false because we want it to remain
|
|
| 509 | + // in place for external callers, and we do not want `#initInternal` to be
|
|
| 510 | + // re-entered.
|
|
| 511 | + |
|
| 512 | + if (this.#initializedObservers) {
|
|
| 513 | + Services.obs.removeObserver(this, lazy.LoxTopics.UpdateBridges);
|
|
| 514 | + }
|
|
| 515 | + if (this.#initializedLox) {
|
|
| 516 | + await lazy.Lox.uninit();
|
|
| 517 | + }
|
|
| 452 | 518 | }
|
| 453 | 519 | |
| 454 | 520 | observe(subject, topic) {
|
| ... | ... | @@ -473,10 +539,13 @@ class TorSettingsImpl { |
| 473 | 539 | }
|
| 474 | 540 | |
| 475 | 541 | /**
|
| 476 | - * Check whether the object has been successfully initialized, and throw if
|
|
| 477 | - * it has not.
|
|
| 542 | + * Check whether the module is enabled and successfully initialized, and throw
|
|
| 543 | + * if it is not.
|
|
| 478 | 544 | */
|
| 479 | 545 | #checkIfInitialized() {
|
| 546 | + if (!this.enabled) {
|
|
| 547 | + throw new Error("TorSettings is not enabled");
|
|
| 548 | + }
|
|
| 480 | 549 | if (!this.#initialized) {
|
| 481 | 550 | lazy.logger.trace("Not initialized code path.");
|
| 482 | 551 | throw new Error(
|
| ... | ... | @@ -494,6 +563,16 @@ class TorSettingsImpl { |
| 494 | 563 | return this.#initialized;
|
| 495 | 564 | }
|
| 496 | 565 | |
| 566 | + /**
|
|
| 567 | + * A promise that resolves once we are initialized, or throws if there was an
|
|
| 568 | + * initialization error.
|
|
| 569 | + *
|
|
| 570 | + * @type {Promise}
|
|
| 571 | + */
|
|
| 572 | + get initializedPromise() {
|
|
| 573 | + return this.#initializedPromise;
|
|
| 574 | + }
|
|
| 575 | + |
|
| 497 | 576 | /**
|
| 498 | 577 | * Load our settings from prefs.
|
| 499 | 578 | */
|
| ... | ... | @@ -701,9 +780,6 @@ class TorSettingsImpl { |
| 701 | 780 | } else {
|
| 702 | 781 | Services.prefs.clearUserPref(TorSettingsPrefs.firewall.allowed_ports);
|
| 703 | 782 | }
|
| 704 | - |
|
| 705 | - // all tor settings now stored in prefs :)
|
|
| 706 | - Services.prefs.setBoolPref(TorSettingsPrefs.enabled, true);
|
|
| 707 | 783 | }
|
| 708 | 784 | |
| 709 | 785 | /**
|