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({
|