[tor-commits] [tor-browser/tor-browser-91.5.0esr-11.5-1] fixup! Bug 40645: Migrate Moat APIs to Moat.jsm module

gk at torproject.org gk at torproject.org
Mon Jan 17 15:48:21 UTC 2022


commit 286900688251c4e89662d34a42e08ff32de14b29
Author: Richard Pospesel <richard at torproject.org>
Date:   Thu Jan 6 18:27:51 2022 +0100

    fixup! Bug 40645: Migrate Moat APIs to Moat.jsm module
---
 browser/modules/Moat.jsm | 133 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 98 insertions(+), 35 deletions(-)

diff --git a/browser/modules/Moat.jsm b/browser/modules/Moat.jsm
index b26eb32bdfb3..d02075e4412f 100644
--- a/browser/modules/Moat.jsm
+++ b/browser/modules/Moat.jsm
@@ -16,7 +16,7 @@ const { TorProtocolService } = ChromeUtils.import(
   "resource:///modules/TorProtocolService.jsm"
 );
 
-const { TorSettings } = ChromeUtils.import(
+const { TorSettings, TorBridgeSource, TorProxyType } = ChromeUtils.import(
   "resource:///modules/TorSettings.jsm"
 );
 
@@ -489,11 +489,10 @@ class MoatRPC {
     await ch.asyncOpen(listener, ch);
 
     // wait for response
-    const response = await listener.response();
+    const responseJSON = await listener.response();
 
     // parse that JSON
-    const retval = JSON.parse(response);
-    return retval;
+    return JSON.parse(responseJSON);
   }
 
   //
@@ -527,16 +526,16 @@ class MoatRPC {
           },
         ],
       };
-      const retval = await this._makeRequest("fetch", args);
-      if ("errors" in retval) {
-        const code = retval.errors[0].code;
-        const detail = retval.errors[0].detail;
+      const response = await this._makeRequest("fetch", args);
+      if ("errors" in response) {
+        const code = response.errors[0].code;
+        const detail = response.errors[0].detail;
         throw new Error(`MoatRPC: ${detail} (${code})`);
       }
 
-      const transport = retval.data[0].transport;
-      const image = retval.data[0].image;
-      const challenge = retval.data[0].challenge;
+      const transport = response.data[0].transport;
+      const image = response.data[0].image;
+      const challenge = response.data[0].challenge;
 
       return { transport, image, challenge };
     }
@@ -568,10 +567,10 @@ class MoatRPC {
         },
       ],
     };
-    const retval = await this._makeRequest("check", args);
-    if ("errors" in retval) {
-      const code = retval.errors[0].code;
-      const detail = retval.errors[0].detail;
+    const response = await this._makeRequest("check", args);
+    if ("errors" in response) {
+      const code = response.errors[0].code;
+      const detail = response.errors[0].detail;
       if (code == 419 && detail === "The CAPTCHA solution was incorrect.") {
         return {};
       }
@@ -579,12 +578,74 @@ class MoatRPC {
       throw new Error(`MoatRPC: ${detail} (${code})`);
     }
 
-    const bridges = retval.data[0].bridges;
-    const qrcodeImg = qrcode ? retval.data[0].qrcode : null;
+    const bridges = response.data[0].bridges;
+    const qrcodeImg = qrcode ? response.data[0].qrcode : null;
 
     return { bridges, qrcode: qrcodeImg };
   }
 
+  // Convert received settings object to format used by TorSettings module
+  // In the event of error, just return null
+  _fixupSettings(settings) {
+    try {
+      let retval = TorSettings.defaultSettings()
+      if ("bridges" in settings) {
+        retval.bridges.enabled = true;
+        switch(settings.bridges.source) {
+          case "builtin":
+            retval.bridges.source = TorBridgeSource.BuiltIn;
+            retval.bridges.builtin_type = settings.bridges.type;
+            // Tor Browser will periodically update the built-in bridge strings list using the
+            // circumvention_builtin() function, so we can ignore the bridge strings we have received here;
+            // BridgeDB only returns a subset of the available built-in bridges through the circumvention_settings()
+            // function which is fine for our 3rd parties, but we're better off ignoring them in Tor Browser, otherwise
+            // we get in a weird situation of needing to update our built-in bridges in a piece-meal fashion which
+            // seems over-complicated/error-prone
+            break;
+          case "bridgedb":
+            retval.bridges.source = TorBridgeSource.BridgeDB;
+            if (settings.bridges.bridge_strings) {
+              retval.bridges.bridge_strings = settings.bridges.bridge_strings;
+            } else {
+              throw new Error("MoatRPC::_fixupSettings(): Received no bridge-strings for BridgeDB bridge source");
+            }
+            break;
+          default:
+            throw new Error(`MoatRPC::_fixupSettings(): Unexpected bridge source '${settings.bridges.source}'`);
+        }
+      }
+      if ("proxy" in settings) {
+        // TODO: populate proxy settings
+      }
+      if ("firewall" in settings) {
+        // TODO: populate firewall settings
+      }
+      return retval;
+    } catch(ex) {
+      console.log(ex.message);
+      return null;
+    }
+  }
+
+  // Converts a list of settings objects received from BridgeDB to a list of settings objects
+  // understood by the TorSettings module
+  // In the event of error, returns and empty list
+  _fixupSettingsList(settingsList) {
+    try {
+      let retval = [];
+      for (let settings of settingsList) {
+        settings = this._fixupSettings(settings);
+        if (settings != null) {
+          retval.push(settings);
+        }
+      }
+      return retval;
+    } catch (ex) {
+      console.log(ex.message);
+      return [];
+    }
+  }
+
   // Request tor settings for the user optionally based on their location (derived
   // from their IP), takes the following parameters:
   // - transports: optional, an array of transports available to the client; if empty (or not
@@ -596,16 +657,16 @@ class MoatRPC {
   // object on the TorSettings module.
   // - If the server cannot determine the user's country (and no country code is provided),
   //   then null is returned
-  // - If the country has no associated settings, an empty object is returned
+  // - If the country has no associated settings, an empty array is returned
   async circumvention_settings(transports, country) {
     const args = {
       transports: transports ? transports : [],
       country: country,
     };
-    const retval = await this._makeRequest("circumvention/settings", args);
-    if ("errors" in retval) {
-      const code = retval.errors[0].code;
-      const detail = retval.errors[0].detail;
+    const response = await this._makeRequest("circumvention/settings", args);
+    if ("errors" in response) {
+      const code = response.errors[0].code;
+      const detail = response.errors[0].detail;
       if (code == 406) {
         console.log("MoatRPC::circumvention_settings(): Cannot automatically determine user's country-code");
         // cannot determine user's country
@@ -613,28 +674,30 @@ class MoatRPC {
       }
 
       throw new Error(`MoatRPC: ${detail} (${code})`);
+    } else if ("settings" in response) {
+      return this._fixupSettingsList(response.settings);
     }
 
-    return retval;
+    return [];
   }
 
   // Request a copy of the censorship circumvention map (as if cirumvention_settings were
   // queried for all country codes)
   //
-  // returns a map whose key is an ISO 3166-1 alpha-2 country code and those
+  // returns a map whose key is an ISO 3166-1 alpha-2 country code and whose
   // values are arrays of settings objects
   async circumvention_map() {
     const args = { };
-    const retval = await this._makeRequest("circumvention/map", args);
-    if ("errors" in retval) {
-      const code = retval.errors[0].code;
-      const detail = retval.errors[0].detail;
+    const response = await this._makeRequest("circumvention/map", args);
+    if ("errors" in response) {
+      const code = response.errors[0].code;
+      const detail = response.errors[0].detail;
       throw new Error(`MoatRPC: ${detail} (${code})`);
     }
 
     let map = new Map();
-    for (const [country, config] of Object.entries(retval)) {
-      map.set(country, config);
+    for (const [country, config] of Object.entries(response)) {
+      map.set(country, this._fixupSettingsList(config.settings));
     }
 
     return map;
@@ -650,15 +713,15 @@ class MoatRPC {
     const args = {
       transports: transports ? transports : [],
     };
-    const retval = await this._makeRequest("circumvention/builtin", args);
-    if ("errors" in retval) {
-      const code = retval.errors[0].code;
-      const detail = retval.errors[0].detail;
+    const response = await this._makeRequest("circumvention/builtin", args);
+    if ("errors" in response) {
+      const code = response.errors[0].code;
+      const detail = response.errors[0].detail;
       throw new Error(`MoatRPC: ${detail} (${code})`);
     }
 
     let map = new Map();
-    for (const [transport, bridge_strings] of Object.entries(retval)) {
+    for (const [transport, bridge_strings] of Object.entries(response)) {
       map.set(transport, bridge_strings);
     }
 





More information about the tor-commits mailing list