[tor-commits] [tor-browser/tor-browser-78.11.0esr-10.5-1] fixup! Bug 27476: Implement about:torconnect captive portal within Tor Browser

sysrqb at torproject.org sysrqb at torproject.org
Wed Jun 30 19:33:33 UTC 2021


commit fc22d11226d7be2dfd16f10eb8d7b939ae6cccd1
Author: Richard Pospesel <richard at torproject.org>
Date:   Tue Jun 29 14:43:22 2021 +0200

    fixup! Bug 27476: Implement about:torconnect captive portal within Tor Browser
---
 browser/base/content/aboutNetError.js              |  5 +--
 browser/components/BrowserGlue.jsm                 | 22 ++++++----
 browser/components/torconnect/TorConnectParent.jsm | 11 -----
 browser/modules/TorConnect.jsm                     | 47 ++++++++++++++++++++++
 browser/modules/moz.build                          |  1 +
 toolkit/mozapps/update/UpdateService.jsm           | 43 ++++++++++++++++++++
 toolkit/xre/nsAppRunner.cpp                        |  7 +---
 7 files changed, 108 insertions(+), 28 deletions(-)

diff --git a/browser/base/content/aboutNetError.js b/browser/base/content/aboutNetError.js
index b85ba74217cb..6844154e16e3 100644
--- a/browser/base/content/aboutNetError.js
+++ b/browser/base/content/aboutNetError.js
@@ -198,11 +198,8 @@ async function initPage() {
   var err = getErrorCode();
 
   // proxyConnectFailure because no-tor running daemon would return this error
-  // netOffline because we do not want to show the offline page (where users can disable offline-mode)
-  //   when we are 'offline' (offline mode is disabled after successful bootstrapping in
-  //   TorConnectParent)
   if (
-    (err === "proxyConnectFailure" || err === "netOffline") &&
+    (err === "proxyConnectFailure") &&
     (await RPMSendQuery("ShouldShowTorConnect"))
   ) {
     document.location.replace("about:torconnect");
diff --git a/browser/components/BrowserGlue.jsm b/browser/components/BrowserGlue.jsm
index adc8e5edb07a..7c832f62386e 100644
--- a/browser/components/BrowserGlue.jsm
+++ b/browser/components/BrowserGlue.jsm
@@ -17,6 +17,14 @@ const { AppConstants } = ChromeUtils.import(
   "resource://gre/modules/AppConstants.jsm"
 );
 
+const { TorProtocolService } = ChromeUtils.import(
+  "resource:///modules/TorProtocolService.jsm"
+);
+
+const { TorConnect } = ChromeUtils.import(
+  "resource:///modules/TorConnect.jsm"
+);
+
 ChromeUtils.defineModuleGetter(
   this,
   "ActorManagerParent",
@@ -2506,23 +2514,23 @@ BrowserGlue.prototype = {
 
       {
         task: () => {
-          if (Services.io.offline === false) {
+          if (TorProtocolService.isBootstrapDone()) {
             // we will take this path when the user is using the legacy tor launcher
             OnionAliasStore.init();
           } else {
-            // this path is taken when using about:torconnect, we start in offline mode
-            // and only switch to online after bootstrapping completes
-            const topic = "network:offline-status-changed";
-            let offlineStatusChangedObserver = {
+            // this path is taken when using about:torconnect, we wait to init
+            // after we are bootstrapped and connected to tor
+            const topic = "torconnect:bootstrap-complete";
+            let bootstrapObserver = {
               observe(aSubject, aTopic, aData) {
-                if (aTopic === topic && aData === "online") {
+                if (aTopic === topic) {
                   OnionAliasStore.init();
                   // we only need to init once, so remove ourselves as an obvserver
                   Services.obs.removeObserver(this, topic);
                 }
               }
             };
-            Services.obs.addObserver(offlineStatusChangedObserver, topic);
+            Services.obs.addObserver(bootstrapObserver, topic);
           }
         },
       },
diff --git a/browser/components/torconnect/TorConnectParent.jsm b/browser/components/torconnect/TorConnectParent.jsm
index cd574ada4da1..f775507a744f 100644
--- a/browser/components/torconnect/TorConnectParent.jsm
+++ b/browser/components/torconnect/TorConnectParent.jsm
@@ -45,17 +45,6 @@ class TorConnectParent extends JSWindowActorParent {
           obj.handled = true;
         }
         self.sendAsyncMessage(aTopic, obj);
-
-        // we need to tell the IOService that we are not online
-        // setting offline to false will make the io service send out
-        // 'network:offline-status-changed' message to observers
-        // the app updater (among other things) listens for this message
-        // and will attempt to check for updates when receiving this message
-        // to recover from a previously failed attempt
-        if (aTopic === kTorBootstrapStatusTopic &&
-            obj.PROGRESS === 100) {
-          Services.io.offline = false;
-        }
       },
     };
 
diff --git a/browser/modules/TorConnect.jsm b/browser/modules/TorConnect.jsm
new file mode 100644
index 000000000000..2b8cd15e3b62
--- /dev/null
+++ b/browser/modules/TorConnect.jsm
@@ -0,0 +1,47 @@
+"use strict";
+
+var EXPORTED_SYMBOLS = ["TorConnect"];
+
+const { Services } = ChromeUtils.import(
+  "resource://gre/modules/Services.jsm"
+);
+
+const { TorProtocolService } = ChromeUtils.import(
+  "resource:///modules/TorProtocolService.jsm"
+);
+
+// TODO: move the bootstrap state management out of each of the individual
+// about:torconnect pages and stick it here
+var TorConnect = (() => {
+    let retval = {
+        init : function() {
+            let topics = [
+                "TorBootstrapStatus",
+            ];
+
+            for(const topic of topics) {
+                Services.obs.addObserver(this, topic);
+            }
+        },
+
+        observe: function(subject, topic, data) {
+            switch(topic) {
+            case "TorBootstrapStatus":
+                const obj = subject?.wrappedJSObject;
+                if (obj?.PROGRESS === 100) {
+                    Services.obs.notifyObservers(null, "torconnect:bootstrap-complete");
+                }
+                break;
+            default:
+                // ignore
+                break;
+            }
+        },
+
+        shouldShowTorConnect : function() {
+            return TorProtocolService.shouldShowTorConnect();
+        },
+    };
+    retval.init();
+    return retval;
+})(); /* TorConnect */
\ No newline at end of file
diff --git a/browser/modules/moz.build b/browser/modules/moz.build
index f2c9dabdddbe..7f091e0e7711 100644
--- a/browser/modules/moz.build
+++ b/browser/modules/moz.build
@@ -155,6 +155,7 @@ EXTRA_JS_MODULES += [
     'TabUnloader.jsm',
     'ThemeVariableMap.jsm',
     'TopSiteAttribution.jsm',
+    'TorConnect.jsm',
     'TorProcessService.jsm',
     'TorProtocolService.jsm',
     'TorStrings.jsm',
diff --git a/toolkit/mozapps/update/UpdateService.jsm b/toolkit/mozapps/update/UpdateService.jsm
index 1fb397373151..5bd778ce47e2 100644
--- a/toolkit/mozapps/update/UpdateService.jsm
+++ b/toolkit/mozapps/update/UpdateService.jsm
@@ -12,6 +12,11 @@ const { AppConstants } = ChromeUtils.import(
 const { AUSTLMY } = ChromeUtils.import(
   "resource://gre/modules/UpdateTelemetry.jsm"
 );
+
+const { TorProtocolService } = ChromeUtils.import(
+  "resource:///modules/TorProtocolService.jsm"
+);
+
 const {
   Bits,
   BitsRequest,
@@ -201,6 +206,7 @@ const INVALID_UPDATER_STATUS_CODE = 99;
 // 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;
@@ -2220,6 +2226,9 @@ UpdateService.prototype = {
       case "network:offline-status-changed":
         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) {
           gLogEnabled; // Assigning this before it is lazy-loaded is an error.
@@ -2640,6 +2649,35 @@ UpdateService.prototype = {
     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();
+  },
+
   onCheckComplete: function AUS_onCheckComplete(request, updates) {
     this._selectAndInstallUpdate(updates);
   },
@@ -2659,6 +2697,11 @@ UpdateService.prototype = {
         AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_OFFLINE);
       }
       return;
+    } else if (update.errorCode == PROXY_SERVER_CONNECTION_REFUSED &&
+               !TorProtocolService.isBootstrapDone()) {
+      // Register boostrap observer to try again
+      this._registerBootstrapObserver();
+      return;
     }
 
     // Send the error code to telemetry
diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp
index 6c8105939fcb..195b3637ca78 100644
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -2984,7 +2984,7 @@ bool fire_glxtest_process();
 class XREMain {
  public:
   XREMain()
-      : mStartOffline(true),
+      : mStartOffline(false),
         mShuttingDown(false)
 #ifdef MOZ_HAS_REMOTE
         ,
@@ -3588,11 +3588,6 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
   CheckArg("new-instance");
 #endif
 
-  // revert to start online behaviour when using the legacy tor launcher
-  if (EnvHasValue("TOR_USE_LEGACY_LAUNCHER")) {
-    mStartOffline = false;
-  }
-
   ar = CheckArg("offline");
   if (ar || EnvHasValue("XRE_START_OFFLINE")) {
     mStartOffline = true;





More information about the tor-commits mailing list