Commit 07116cf4 authored by Pier Angelo Vendrame's avatar Pier Angelo Vendrame 🎃 Committed by Richard Pospesel
Browse files

Bug 41668: Tweaks to the Base Browser updater for Tor Browser

This commit was once part of "Bug 4234: Use the Firefox Update Process
for Tor Browser.".
However, some parts of it were not needed for Base Browser and some
derivative browsers.
Therefore, we extracted from that commit the parts for Tor Browser
legacy, and we add them back to the patch set with this commit.
parent 8aeae779
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ XPCOMUtils.defineLazyGetter(lazy, "gWindowsAlertsService", () => {
});

const FORK_VERSION_PREF =
  "browser.startup.homepage_override.basebrowser.version";
  "browser.startup.homepage_override.torbrowser.version";

// One-time startup homepage override configurations
const ONCE_DOMAINS = ["mozilla.org", "firefox.com"];
+6 −6
Original line number Diff line number Diff line
@@ -25,14 +25,14 @@ MOZ_APP_ID={ec8030f7-c20a-464f-9b0e-13a3a9e97384}
# of values.
# The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t "
if test "$MOZ_UPDATE_CHANNEL" = "alpha"; then
  ACCEPTED_MAR_CHANNEL_IDS=basebrowser-torproject-alpha
  MAR_CHANNEL_ID=basebrowser-torproject-alpha
  ACCEPTED_MAR_CHANNEL_IDS=torbrowser-torproject-alpha
  MAR_CHANNEL_ID=torbrowser-torproject-alpha
elif test "$MOZ_UPDATE_CHANNEL" = "nightly"; then
  ACCEPTED_MAR_CHANNEL_IDS=basebrowser-torproject-nightly
  MAR_CHANNEL_ID=basebrowser-torproject-nightly
  ACCEPTED_MAR_CHANNEL_IDS=torbrowser-torproject-nightly
  MAR_CHANNEL_ID=torbrowser-torproject-nightly
else
  ACCEPTED_MAR_CHANNEL_IDS=basebrowser-torproject-release
  MAR_CHANNEL_ID=basebrowser-torproject-release
  ACCEPTED_MAR_CHANNEL_IDS=torbrowser-torproject-release
  MAR_CHANNEL_ID=torbrowser-torproject-release
fi

# Include the DevTools client, not just the server (which is the default)
+12 −0
Original line number Diff line number Diff line
@@ -10,9 +10,17 @@ import io
import os


# TODO When TOR_BROWSER_DATA_OUTSIDE_APP_DIR is used on all platforms,
# we should remove all lines in this file that contain:
#      TorBrowser/Data

def get_build_entries(root_path):
    """Iterates through the root_path, creating a list for each file and
    directory. Excludes any file paths ending with channel-prefs.js.
    To support Tor Browser updates, excludes:
      TorBrowser/Data/Browser/profiles.ini
      TorBrowser/Data/Browser/profile.default/bookmarks.html
      TorBrowser/Data/Tor/torrc
    """
    rel_file_path_set = set()
    rel_dir_path_set = set()
@@ -24,6 +32,10 @@ def get_build_entries(root_path):
            if not (
                rel_path_file.endswith("channel-prefs.js")
                or rel_path_file.endswith("update-settings.ini")
                or rel_path_file == "TorBrowser/Data/Browser/profiles.ini"
                or rel_path_file
                == "TorBrowser/Data/Browser/profile.default/bookmarks.html"
                or rel_path_file == "TorBrowser/Data/Tor/torrc"
                or rel_path_file.find("distribution/") != -1
            ):
                rel_file_path_set.add(rel_path_file)
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ const PREF_EM_STRICT_COMPATIBILITY = "extensions.strictCompatibility";
const PREF_EM_CHECK_UPDATE_SECURITY = "extensions.checkUpdateSecurity";
const PREF_SYS_ADDON_UPDATE_ENABLED = "extensions.systemAddon.update.enabled";
const PREF_REMOTESETTINGS_DISABLED = "extensions.remoteSettings.disabled";
const PREF_EM_LAST_FORK_VERSION = "extensions.lastBaseBrowserVersion";
const PREF_EM_LAST_FORK_VERSION = "extensions.lastTorBrowserVersion";

const PREF_MIN_WEBEXT_PLATFORM_VERSION =
  "extensions.webExtensionsMinPlatformVersion";
+77 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
  AsyncShutdown: "resource://gre/modules/AsyncShutdown.sys.mjs",
  CertUtils: "resource://gre/modules/CertUtils.sys.mjs",
  DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs",
  TorProviderBuilder: "resource://gre/modules/TorProviderBuilder.sys.mjs",
  UpdateUtils: "resource://gre/modules/UpdateUtils.sys.mjs",
  WindowsRegistry: "resource://gre/modules/WindowsRegistry.sys.mjs",
  ctypes: "resource://gre/modules/ctypes.sys.mjs",
@@ -245,6 +246,7 @@ const SERVICE_ERRORS = [
// Custom update error codes
const BACKGROUNDCHECK_MULTIPLE_FAILURES = 110;
const NETWORK_ERROR_OFFLINE = 111;
const PROXY_SERVER_CONNECTION_REFUSED = 2152398920;

// Error codes should be < 1000. Errors above 1000 represent http status codes
const HTTP_ERROR_OFFSET = 1000;
@@ -386,6 +388,15 @@ XPCOMUtils.defineLazyGetter(
  }
);

async function _shouldRegisterBootstrapObserver(errorCode) {
  try {
    const provider = await lazy.TorProviderBuilder.build();
    return !provider.isBootstrapDone && provider.ownsTorDaemon;
  } catch {
    return false;
  }
}

/**
 * Changes `nsIApplicationUpdateService.currentState` and causes
 * `nsIApplicationUpdateService.stateTransition` to resolve.
@@ -2758,6 +2769,9 @@ UpdateService.prototype = {
      case "network:offline-status-changed":
        await this._offlineStatusChanged(data);
        break;
      case "torconnect:bootstrap-complete":
        this._bootstrapComplete();
        break;
      case "nsPref:changed":
        if (data == PREF_APP_UPDATE_LOG || data == PREF_APP_UPDATE_LOG_FILE) {
          lazy.gLogEnabled; // Assigning this before it is lazy-loaded is an error.
@@ -3256,6 +3270,35 @@ UpdateService.prototype = {
    await this._attemptResume();
  },

  _registerBootstrapObserver: function AUS__registerBootstrapObserver() {
    if (this._registeredBootstrapObserver) {
      LOG(
        "UpdateService:_registerBootstrapObserver - observer already registered"
      );
      return;
    }

    LOG(
      "UpdateService:_registerBootstrapObserver - waiting for tor bootstrap to " +
        "be complete, then forcing another check"
    );

    Services.obs.addObserver(this, "torconnect:bootstrap-complete");
    this._registeredBootstrapObserver = true;
  },

  _bootstrapComplete: function AUS__bootstrapComplete() {
    Services.obs.removeObserver(this, "torconnect:bootstrap-complete");
    this._registeredBootstrapObserver = false;

    LOG(
      "UpdateService:_bootstrapComplete - bootstrapping complete, forcing " +
        "another background check"
    );

    this._attemptResume();
  },

  /**
   * See nsIUpdateService.idl
   */
@@ -3289,6 +3332,14 @@ UpdateService.prototype = {
        AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_OFFLINE);
      }
      return;
    } else if (
      update.errorCode === PROXY_SERVER_CONNECTION_REFUSED &&
      (await _shouldRegisterBootstrapObserver())
    ) {
      // Register boostrap observer to try again, but only when we own the
      // tor process.
      this._registerBootstrapObserver();
      return;
    }

    // Send the error code to telemetry
@@ -6495,6 +6546,7 @@ Downloader.prototype = {
    var state = this._patch.state;
    var shouldShowPrompt = false;
    var shouldRegisterOnlineObserver = false;
    var shouldRegisterBootstrapObserver = false;
    var shouldRetrySoon = false;
    var deleteActiveUpdate = false;
    let migratedToReadyUpdate = false;
@@ -6625,7 +6677,23 @@ Downloader.prototype = {
      );
      shouldRegisterOnlineObserver = true;
      deleteActiveUpdate = false;

    } else if (
      status === PROXY_SERVER_CONNECTION_REFUSED &&
      (await _shouldRegisterBootstrapObserver())
    ) {
      // Register a bootstrap observer to try again.
      // The bootstrap observer will continue the incremental download by
      // calling downloadUpdate on the active update which continues
      // downloading the file from where it was.
      LOG(
        "Downloader:onStopRequest - not bootstrapped, register bootstrap observer: true"
      );
      AUSTLMY.pingDownloadCode(
        this.isCompleteUpdate,
        AUSTLMY.DWNLD_RETRY_OFFLINE
      );
      shouldRegisterBootstrapObserver = true;
      deleteActiveUpdate = false;
      // Each of NS_ERROR_NET_TIMEOUT, ERROR_CONNECTION_REFUSED,
      // NS_ERROR_NET_RESET and NS_ERROR_DOCUMENT_NOT_CACHED can be returned
      // when disconnecting the internet while a download of a MAR is in
@@ -6748,7 +6816,11 @@ Downloader.prototype = {

    // Only notify listeners about the stopped state if we
    // aren't handling an internal retry.
    if (!shouldRetrySoon && !shouldRegisterOnlineObserver) {
    if (
      !shouldRetrySoon &&
      !shouldRegisterOnlineObserver &&
      !shouldRegisterBootstrapObserver
    ) {
      this.updateService.forEachDownloadListener(listener => {
        listener.onStopRequest(request, status);
      });
@@ -6947,6 +7019,9 @@ Downloader.prototype = {
    if (shouldRegisterOnlineObserver) {
      LOG("Downloader:onStopRequest - Registering online observer");
      this.updateService._registerOnlineObserver();
    } else if (shouldRegisterBootstrapObserver) {
      LOG("Downloader:onStopRequest - Registering bootstrap observer");
      this.updateService._registerBootstrapObserver();
    } else if (shouldRetrySoon) {
      LOG("Downloader:onStopRequest - Retrying soon");
      this.updateService._consecutiveSocketErrors++;
Loading