Pier Angelo Vendrame pushed to branch mullvad-browser-128.2.0esr-14.0-1 at The Tor Project / Applications / Mullvad Browser
Commits:
- 
a6251e60
by cypherpunks1 at 2024-08-28T17:41:16+02:00
 - 
09069722
by cypherpunks1 at 2024-08-28T17:41:17+02:00
 
8 changed files:
- browser/components/BrowserGlue.sys.mjs
 - mobile/shared/chrome/geckoview/geckoview.js
 - services/settings/Attachments.sys.mjs
 - services/settings/RemoteSettingsClient.sys.mjs
 - services/settings/dumps/gen_last_modified.py
 - services/settings/remote-settings.sys.mjs
 - toolkit/modules/AppConstants.sys.mjs
 - toolkit/modules/IgnoreLists.sys.mjs
 
Changes:
| ... | ... | @@ -3368,6 +3368,11 @@ BrowserGlue.prototype = { | 
| 3368 | 3368 |          lazy.RemoteSecuritySettings.init();
 | 
| 3369 | 3369 |        },
 | 
| 3370 | 3370 | |
| 3371 | +      function RemoteSettingsPollChanges() {
 | 
|
| 3372 | +        // Support clients that use the "sync" event or "remote-settings:changes-poll-end".
 | 
|
| 3373 | +        lazy.RemoteSettings.pollChanges({ trigger: "timer" });
 | 
|
| 3374 | +      },
 | 
|
| 3375 | +  | 
|
| 3371 | 3376 |        function BrowserUsageTelemetryReportProfileCount() {
 | 
| 3372 | 3377 |          lazy.BrowserUsageTelemetry.reportProfileCount();
 | 
| 3373 | 3378 |        },
 | 
| ... | ... | @@ -21,6 +21,7 @@ ChromeUtils.defineESModuleGetters(this, { | 
| 21 | 21 |    InitializationTracker: "resource://gre/modules/GeckoViewTelemetry.sys.mjs",
 | 
| 22 | 22 |    RemoteSecuritySettings:
 | 
| 23 | 23 |      "resource://gre/modules/psm/RemoteSecuritySettings.sys.mjs",
 | 
| 24 | +  RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
 | 
|
| 24 | 25 |    SafeBrowsing: "resource://gre/modules/SafeBrowsing.sys.mjs",
 | 
| 25 | 26 |  });
 | 
| 26 | 27 | |
| ... | ... | @@ -922,6 +923,10 @@ function startup() { | 
| 922 | 923 |        Blocklist.loadBlocklistAsync();
 | 
| 923 | 924 |      });
 | 
| 924 | 925 | |
| 926 | +    InitLater(() => {
 | 
|
| 927 | +      RemoteSettings.pollChanges({ trigger: "timer" });
 | 
|
| 928 | +    });
 | 
|
| 929 | +  | 
|
| 925 | 930 |      // This should always go last, since the idle tasks (except for the ones with
 | 
| 926 | 931 |      // timeouts) should execute in order. Note that this observer notification is
 | 
| 927 | 932 |      // not guaranteed to fire, since the window could close before we get here.
 | 
| ... | ... | @@ -223,6 +223,10 @@ export class Downloader { | 
| 223 | 223 |        fallbackToDump = false;
 | 
| 224 | 224 |      }
 | 
| 225 | 225 | |
| 226 | +    avoidDownload = true;
 | 
|
| 227 | +    fallbackToCache = true;
 | 
|
| 228 | +    fallbackToDump = true;
 | 
|
| 229 | +  | 
|
| 226 | 230 |      const dumpInfo = new LazyRecordAndBuffer(() =>
 | 
| 227 | 231 |        this._readAttachmentDump(attachmentId)
 | 
| 228 | 232 |      );
 | 
| ... | ... | @@ -444,6 +448,8 @@ export class Downloader { | 
| 444 | 448 |        attachment: { location, hash, size },
 | 
| 445 | 449 |      } = record;
 | 
| 446 | 450 | |
| 451 | +    return (await this.#fetchAttachment(record)).buffer;
 | 
|
| 452 | +    // eslint-disable-next-line no-unreachable
 | 
|
| 447 | 453 |      const remoteFileUrl = (await this._baseAttachmentsURL()) + location;
 | 
| 448 | 454 | |
| 449 | 455 |      const { retries = 3, checkHash = true } = options;
 | 
| ... | ... | @@ -424,11 +424,19 @@ export class RemoteSettingsClient extends EventEmitter { | 
| 424 | 424 |        order = "", // not sorted by default.
 | 
| 425 | 425 |        dumpFallback = true,
 | 
| 426 | 426 |        emptyListFallback = true,
 | 
| 427 | -      forceSync = false,
 | 
|
| 428 | 427 |        loadDumpIfNewer = true,
 | 
| 429 | -      syncIfEmpty = true,
 | 
|
| 430 | 428 |      } = options;
 | 
| 431 | -    let { verifySignature = false } = options;
 | 
|
| 429 | +  | 
|
| 430 | +    const hasLocalDump = await lazy.Utils.hasLocalDump(
 | 
|
| 431 | +      this.bucketName,
 | 
|
| 432 | +      this.collectionName
 | 
|
| 433 | +    );
 | 
|
| 434 | +    if (!hasLocalDump) {
 | 
|
| 435 | +      return [];
 | 
|
| 436 | +    }
 | 
|
| 437 | +    const forceSync = false;
 | 
|
| 438 | +    const syncIfEmpty = true;
 | 
|
| 439 | +    let verifySignature = false;
 | 
|
| 432 | 440 | |
| 433 | 441 |      const hasParallelCall = !!this._importingPromise;
 | 
| 434 | 442 |      let data;
 | 
| ... | ... | @@ -598,6 +606,10 @@ export class RemoteSettingsClient extends EventEmitter { | 
| 598 | 606 |     * @param {Object} options See #maybeSync() options.
 | 
| 599 | 607 |     */
 | 
| 600 | 608 |    async sync(options) {
 | 
| 609 | +    if (AppConstants.BASE_BROWSER_VERSION) {
 | 
|
| 610 | +      return;
 | 
|
| 611 | +    }
 | 
|
| 612 | +  | 
|
| 601 | 613 |      if (lazy.Utils.shouldSkipRemoteActivityDueToTests) {
 | 
| 602 | 614 |        return;
 | 
| 603 | 615 |      }
 | 
| ... | ... | @@ -664,7 +676,7 @@ export class RemoteSettingsClient extends EventEmitter { | 
| 664 | 676 |      let thrownError = null;
 | 
| 665 | 677 |      try {
 | 
| 666 | 678 |        // If network is offline, we can't synchronize.
 | 
| 667 | -      if (lazy.Utils.isOffline) {
 | 
|
| 679 | +      if (!AppConstants.BASE_BROWSER_VERSION && lazy.Utils.isOffline) {
 | 
|
| 668 | 680 |          throw new RemoteSettingsClient.NetworkOfflineError();
 | 
| 669 | 681 |        }
 | 
| 670 | 682 | |
| ... | ... | @@ -1046,14 +1058,8 @@ export class RemoteSettingsClient extends EventEmitter { | 
| 1046 | 1058 |      options = {}
 | 
| 1047 | 1059 |    ) {
 | 
| 1048 | 1060 |      const { retry = false } = options;
 | 
| 1049 | -    const since = retry || !localTimestamp ? undefined : `"${localTimestamp}"`;
 | 
|
| 1050 | 1061 | |
| 1051 | -    // Fetch collection metadata and list of changes from server.
 | 
|
| 1052 | -    lazy.console.debug(
 | 
|
| 1053 | -      `${this.identifier} Fetch changes from server (expected=${expectedTimestamp}, since=${since})`
 | 
|
| 1054 | -    );
 | 
|
| 1055 | -    const { metadata, remoteTimestamp, remoteRecords } =
 | 
|
| 1056 | -      await this._fetchChangeset(expectedTimestamp, since);
 | 
|
| 1062 | +    let metadata, remoteTimestamp;
 | 
|
| 1057 | 1063 | |
| 1058 | 1064 |      // We build a sync result, based on remote changes.
 | 
| 1059 | 1065 |      const syncResult = {
 | 
| ... | ... | @@ -1062,24 +1068,20 @@ export class RemoteSettingsClient extends EventEmitter { | 
| 1062 | 1068 |        updated: [],
 | 
| 1063 | 1069 |        deleted: [],
 | 
| 1064 | 1070 |      };
 | 
| 1065 | -    // If data wasn't changed, return empty sync result.
 | 
|
| 1066 | -    // This can happen when we update the signature but not the data.
 | 
|
| 1067 | -    lazy.console.debug(
 | 
|
| 1068 | -      `${this.identifier} local timestamp: ${localTimestamp}, remote: ${remoteTimestamp}`
 | 
|
| 1069 | -    );
 | 
|
| 1070 | -    if (localTimestamp && remoteTimestamp < localTimestamp) {
 | 
|
| 1071 | +  | 
|
| 1072 | +    try {
 | 
|
| 1073 | +      await this._importJSONDump();
 | 
|
| 1074 | +    } catch (e) {
 | 
|
| 1071 | 1075 |        return syncResult;
 | 
| 1072 | 1076 |      }
 | 
| 1073 | 1077 | |
| 1074 | -    await this.db.importChanges(metadata, remoteTimestamp, remoteRecords, {
 | 
|
| 1075 | -      clear: retry,
 | 
|
| 1076 | -    });
 | 
|
| 1077 | -  | 
|
| 1078 | 1078 |      // Read the new local data, after updating.
 | 
| 1079 | 1079 |      const newLocal = await this.db.list();
 | 
| 1080 | 1080 |      const newRecords = newLocal.map(r => this._cleanLocalFields(r));
 | 
| 1081 | 1081 |      // And verify the signature on what is now stored.
 | 
| 1082 | -    if (this.verifySignature) {
 | 
|
| 1082 | +    if (metadata === undefined) {
 | 
|
| 1083 | +      // When working only with dumps, we do not have signatures.
 | 
|
| 1084 | +    } else if (this.verifySignature) {
 | 
|
| 1083 | 1085 |        try {
 | 
| 1084 | 1086 |          await this._validateCollectionSignature(
 | 
| 1085 | 1087 |            newRecords,
 | 
| ... | ... | @@ -63,8 +63,10 @@ def main(output): | 
| 63 | 63 |      dumps_locations = []
 | 
| 64 | 64 |      if buildconfig.substs["MOZ_BUILD_APP"] == "browser":
 | 
| 65 | 65 |          dumps_locations += ["services/settings/dumps/"]
 | 
| 66 | +        dumps_locations += ["services/settings/static-dumps/"]
 | 
|
| 66 | 67 |      elif buildconfig.substs["MOZ_BUILD_APP"] == "mobile/android":
 | 
| 67 | 68 |          dumps_locations += ["services/settings/dumps/"]
 | 
| 69 | +        dumps_locations += ["services/settings/static-dumps/"]
 | 
|
| 68 | 70 |      elif buildconfig.substs["MOZ_BUILD_APP"] == "mobile/ios":
 | 
| 69 | 71 |          dumps_locations += ["services/settings/dumps/"]
 | 
| 70 | 72 |      elif buildconfig.substs["MOZ_BUILD_APP"] == "comm/mail":
 | 
| ... | ... | @@ -91,6 +91,7 @@ export async function jexlFilterFunc(entry, environment) { | 
| 91 | 91 |  function remoteSettingsFunction() {
 | 
| 92 | 92 |    const _clients = new Map();
 | 
| 93 | 93 |    let _invalidatePolling = false;
 | 
| 94 | +  let _initialized = false;
 | 
|
| 94 | 95 | |
| 95 | 96 |    // If not explicitly specified, use the default signer.
 | 
| 96 | 97 |    const defaultOptions = {
 | 
| ... | ... | @@ -194,21 +195,49 @@ function remoteSettingsFunction() { | 
| 194 | 195 |      trigger = "manual",
 | 
| 195 | 196 |      full = false,
 | 
| 196 | 197 |    } = {}) => {
 | 
| 198 | +    if (AppConstants.BASE_BROWSER_VERSION) {
 | 
|
| 199 | +      // Called multiple times on GeckoView due to bug 1730026
 | 
|
| 200 | +      if (_initialized) {
 | 
|
| 201 | +        return;
 | 
|
| 202 | +      }
 | 
|
| 203 | +      _initialized = true;
 | 
|
| 204 | +      let importedFromDump = false;
 | 
|
| 205 | +      for (const client of _clients.values()) {
 | 
|
| 206 | +        const hasLocalDump = await lazy.Utils.hasLocalDump(
 | 
|
| 207 | +          client.bucketName,
 | 
|
| 208 | +          client.collectionName
 | 
|
| 209 | +        );
 | 
|
| 210 | +        if (hasLocalDump) {
 | 
|
| 211 | +          const lastModified = await client.getLastModified();
 | 
|
| 212 | +          const lastModifiedDump = await lazy.Utils.getLocalDumpLastModified(
 | 
|
| 213 | +            client.bucketName,
 | 
|
| 214 | +            client.collectionName
 | 
|
| 215 | +          );
 | 
|
| 216 | +          if (lastModified < lastModifiedDump) {
 | 
|
| 217 | +            await client.maybeSync(lastModifiedDump, {
 | 
|
| 218 | +              loadDump: true,
 | 
|
| 219 | +              trigger,
 | 
|
| 220 | +            });
 | 
|
| 221 | +            importedFromDump = true;
 | 
|
| 222 | +          }
 | 
|
| 223 | +        }
 | 
|
| 224 | +      }
 | 
|
| 225 | +      if (importedFromDump) {
 | 
|
| 226 | +        Services.obs.notifyObservers(null, "remote-settings:changes-poll-end");
 | 
|
| 227 | +      }
 | 
|
| 228 | +      return;
 | 
|
| 229 | +    }
 | 
|
| 230 | +  | 
|
| 197 | 231 |      if (lazy.Utils.shouldSkipRemoteActivityDueToTests) {
 | 
| 198 | 232 |        return;
 | 
| 199 | 233 |      }
 | 
| 200 | 234 |      // When running in full mode, we ignore last polling status.
 | 
| 201 | -    if (full || AppConstants.BASE_BROWSER_VERSION) {
 | 
|
| 235 | +    if (full) {
 | 
|
| 202 | 236 |        lazy.gPrefs.clearUserPref(PREF_SETTINGS_SERVER_BACKOFF);
 | 
| 203 | 237 |        lazy.gPrefs.clearUserPref(PREF_SETTINGS_LAST_UPDATE);
 | 
| 204 | 238 |        lazy.gPrefs.clearUserPref(PREF_SETTINGS_LAST_ETAG);
 | 
| 205 | 239 |      }
 | 
| 206 | 240 | |
| 207 | -    if (AppConstants.BASE_BROWSER_VERSION) {
 | 
|
| 208 | -      // tor-browser#41704: pollChanges is always online, so do not allow it.
 | 
|
| 209 | -      return;
 | 
|
| 210 | -    }
 | 
|
| 211 | -  | 
|
| 212 | 241 |      let pollTelemetryArgs = {
 | 
| 213 | 242 |        source: TELEMETRY_SOURCE_POLL,
 | 
| 214 | 243 |        trigger,
 | 
| ... | ... | @@ -423,11 +423,11 @@ export var AppConstants = Object.freeze({ | 
| 423 | 423 |  #ifdef MOZ_THUNDERBIRD
 | 
| 424 | 424 |      "https://thunderbird-settings.thunderbird.net/v1",
 | 
| 425 | 425 |  #else
 | 
| 426 | -    "https://firefox.settings.services.mozilla.com/v1",
 | 
|
| 426 | +    "",
 | 
|
| 427 | 427 |  #endif
 | 
| 428 | 428 | |
| 429 | 429 |    REMOTE_SETTINGS_VERIFY_SIGNATURE:
 | 
| 430 | -#ifdef MOZ_THUNDERBIRD
 | 
|
| 430 | +#if defined(MOZ_THUNDERBIRD) || defined(BASE_BROWSER_VERSION)
 | 
|
| 431 | 431 |      false,
 | 
| 432 | 432 |  #else
 | 
| 433 | 433 |      true,
 | 
| ... | ... | @@ -5,16 +5,18 @@ | 
| 5 | 5 |  const lazy = {};
 | 
| 6 | 6 | |
| 7 | 7 |  ChromeUtils.defineESModuleGetters(lazy, {
 | 
| 8 | +  RemoteSettings: "resource://services-settings/remote-settings.sys.mjs",
 | 
|
| 8 | 9 |    RemoteSettingsClient:
 | 
| 9 | 10 |      "resource://services-settings/RemoteSettingsClient.sys.mjs",
 | 
| 10 | 11 |  });
 | 
| 11 | 12 | |
| 12 | -class IgnoreListsManager {
 | 
|
| 13 | -  _ignoreListSettings = null;
 | 
|
| 13 | +const SETTINGS_IGNORELIST_KEY = "hijack-blocklists";
 | 
|
| 14 | 14 | |
| 15 | +class IgnoreListsManager {
 | 
|
| 15 | 16 |    async init() {
 | 
| 16 | -    // TODO: Restore the initialization, once we use only the local dumps for
 | 
|
| 17 | -    // the remote settings.
 | 
|
| 17 | +    if (!this._ignoreListSettings) {
 | 
|
| 18 | +      this._ignoreListSettings = lazy.RemoteSettings(SETTINGS_IGNORELIST_KEY);
 | 
|
| 19 | +    }
 | 
|
| 18 | 20 |    }
 | 
| 19 | 21 | |
| 20 | 22 |    async getAndSubscribe(listener) {
 | 
| ... | ... | @@ -24,7 +26,7 @@ class IgnoreListsManager { | 
| 24 | 26 |      const settings = await this._getIgnoreList();
 | 
| 25 | 27 | |
| 26 | 28 |      // Listen for future updates after we first get the values.
 | 
| 27 | -    this._ignoreListSettings?.on("sync", listener);
 | 
|
| 29 | +    this._ignoreListSettings.on("sync", listener);
 | 
|
| 28 | 30 | |
| 29 | 31 |      return settings;
 | 
| 30 | 32 |    }
 | 
| ... | ... | @@ -65,14 +67,6 @@ class IgnoreListsManager { | 
| 65 | 67 |     *   could be obtained.
 | 
| 66 | 68 |     */
 | 
| 67 | 69 |    async _getIgnoreListSettings(firstTime = true) {
 | 
| 68 | -    if (!this._ignoreListSettings) {
 | 
|
| 69 | -      const dump = await fetch(
 | 
|
| 70 | -        "resource:///defaults/settings/main/hijack-blocklists.json"
 | 
|
| 71 | -      );
 | 
|
| 72 | -      const { data } = await dump.json();
 | 
|
| 73 | -      return data;
 | 
|
| 74 | -    }
 | 
|
| 75 | -  | 
|
| 76 | 70 |      let result = [];
 | 
| 77 | 71 |      try {
 | 
| 78 | 72 |        result = await this._ignoreListSettings.get({
 |