[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [Git][tpo/applications/tor-browser][tor-browser-128.4.0esr-14.5-1] 4 commits: fixup! Bug 40933: Add tor-launcher functionality



Title: GitLab

Pier Angelo Vendrame pushed to branch tor-browser-128.4.0esr-14.5-1 at The Tor Project / Applications / Tor Browser

Commits:

  • 82705e37
    by Pier Angelo Vendrame at 2024-11-12T17:32:04+01:00
    fixup! Bug 40933: Add tor-launcher functionality
    
    Make optional members in JSDoc comments more consistent with Firefox's
    codebase.
    
  • 163c91b6
    by Pier Angelo Vendrame at 2024-11-12T17:32:05+01:00
    fixup! Bug 40933: Add tor-launcher functionality
    
    Bug 10439: Ask the the SOCKS port to the tor process.
    
    Allow specifying a negative port as TOR_SOCKS_PORT to let the tor
    process choose one for us.
    
    This does not play too well with DisableNetwork, which we use to start
    and stop the bootstrap, so we have to query the port every time we
    change this setting.
    
    Also, currently we use Firefox's preferences for SOCKS port.
    This prevents us from keeping a negative number saved in them.
    See also tor-browser#42062.
    
  • f7e4e221
    by Pier Angelo Vendrame at 2024-11-12T17:32:06+01:00
    fixup! Bug 40933: Add tor-launcher functionality
    
    Bug 42714: Allow to optionally use a TCP listener on Android.
    
  • bb3cd92e
    by Pier Angelo Vendrame at 2024-11-12T17:32:06+01:00
    fixup! Bug 42247: Android helpers for the TorProvider
    
    Bug 42714: Allow to optionally use a TCP listener on Android.
    

6 changed files:

Changes:

  • mobile/android/geckoview/src/main/java/org/mozilla/geckoview/TorIntegrationAndroid.java
    ... ... @@ -220,12 +220,18 @@ public class TorIntegrationAndroid implements BundleEventListener {
    220 220
         if (previousProcess != null) {
    
    221 221
           Log.w(TAG, "We still have a running process: " + previousProcess.getHandle());
    
    222 222
         }
    
    223
    -    mTorProcess = new TorProcess(handle);
    
    223
    +
    
    224
    +    boolean tcpSocks = message.getBoolean("tcpSocks", false);
    
    225
    +    mTorProcess = new TorProcess(handle, tcpSocks);
    
    224 226
     
    
    225 227
         GeckoBundle bundle = new GeckoBundle(3);
    
    226 228
         bundle.putString("controlPortPath", mIpcDirectory + CONTROL_PORT_FILE);
    
    227
    -    bundle.putString("socksPath", mIpcDirectory + SOCKS_FILE);
    
    228 229
         bundle.putString("cookieFilePath", mIpcDirectory + COOKIE_AUTH_FILE);
    
    230
    +    if (tcpSocks) {
    
    231
    +      bundle.putInt("socksPort", 0);
    
    232
    +    } else {
    
    233
    +      bundle.putString("socksPath", mIpcDirectory + SOCKS_FILE);
    
    234
    +    }
    
    229 235
         callback.sendSuccess(bundle);
    
    230 236
       }
    
    231 237
     
    
    ... ... @@ -254,10 +260,12 @@ public class TorIntegrationAndroid implements BundleEventListener {
    254 260
         private static final String EVENT_TOR_START_FAILED = "GeckoView:Tor:TorStartFailed";
    
    255 261
         private static final String EVENT_TOR_EXITED = "GeckoView:Tor:TorExited";
    
    256 262
         private final String mHandle;
    
    263
    +    private final boolean mTcpSocks;
    
    257 264
         private Process mProcess = null;
    
    258 265
     
    
    259
    -    TorProcess(String handle) {
    
    266
    +    TorProcess(String handle, boolean tcpSocks) {
    
    260 267
           mHandle = handle;
    
    268
    +      mTcpSocks = tcpSocks;
    
    261 269
           setName("tor-process-" + handle);
    
    262 270
           start();
    
    263 271
         }
    
    ... ... @@ -273,8 +281,13 @@ public class TorIntegrationAndroid implements BundleEventListener {
    273 281
           args.add("1");
    
    274 282
           args.add("+__ControlPort");
    
    275 283
           args.add("unix:" + ipcDir + CONTROL_PORT_FILE);
    
    284
    +      final String socksFlags = " IPv6Traffic PreferIPv6 KeepAliveIsolateSOCKSAuth";
    
    276 285
           args.add("+__SocksPort");
    
    277
    -      args.add("unix:" + ipcDir + SOCKS_FILE + " IPv6Traffic PreferIPv6 KeepAliveIsolateSOCKSAuth");
    
    286
    +      args.add("unix:" + ipcDir + SOCKS_FILE + socksFlags);
    
    287
    +      if (mTcpSocks) {
    
    288
    +        args.add("+__SocksPort");
    
    289
    +        args.add("auto " + socksFlags);
    
    290
    +      }
    
    278 291
           args.add("CookieAuthentication");
    
    279 292
           args.add("1");
    
    280 293
           args.add("CookieAuthFile");
    

  • toolkit/components/tor-launcher/TorControlPort.sys.mjs
    ... ... @@ -298,6 +298,12 @@ class AsyncSocket {
    298 298
      * @property {string} [options] Optional options passed to the binary (only for
    
    299 299
      * exec)
    
    300 300
      */
    
    301
    +/**
    
    302
    + * @typedef {object} SocksListener
    
    303
    + * @property {string} [ipcPath] path to a Unix socket to use for an IPC proxy
    
    304
    + * @property {string} [host] The host to connect for a TCP proxy
    
    305
    + * @property {number} [port] The port number to use for a TCP proxy
    
    306
    + */
    
    301 307
     /**
    
    302 308
      * @typedef {object} OnionAuthKeyInfo
    
    303 309
      * @property {string} address The address of the onion service
    
    ... ... @@ -746,6 +752,32 @@ export class TorController {
    746 752
         return this.#getInfo(`ip-to-country/${ip}`);
    
    747 753
       }
    
    748 754
     
    
    755
    +  /**
    
    756
    +   * Ask tor which ports it is listening to for SOCKS connections.
    
    757
    +   *
    
    758
    +   * @returns {Promise<SocksListener[]>} An array of addresses. It might be
    
    759
    +   * empty (e.g., when DisableNetwork is set)
    
    760
    +   */
    
    761
    +  async getSocksListeners() {
    
    762
    +    const listeners = await this.#getInfo("net/listeners/socks");
    
    763
    +    return Array.from(
    
    764
    +      listeners.matchAll(/\s*("(?:[^"\\]|\\.)*"|\S+)\s*/g),
    
    765
    +      m => {
    
    766
    +        const listener = TorParsers.unescapeString(m[1]);
    
    767
    +        if (listener.startsWith("unix:/")) {
    
    768
    +          return { ipcPath: listener.substring(5) };
    
    769
    +        }
    
    770
    +        const idx = listener.lastIndexOf(":");
    
    771
    +        const host = listener.substring(0, idx);
    
    772
    +        const port = parseInt(listener.substring(idx + 1));
    
    773
    +        if (isNaN(port) || port <= 0 || port > 65535 || !host || !port) {
    
    774
    +          throw new Error(`Could not parse the SOCKS listener ${listener}.`);
    
    775
    +        }
    
    776
    +        return { host, port };
    
    777
    +      }
    
    778
    +    );
    
    779
    +  }
    
    780
    +
    
    749 781
       /**
    
    750 782
        * Ask Tor a list of circuits.
    
    751 783
        *
    

  • toolkit/components/tor-launcher/TorLauncherUtil.sys.mjs
    ... ... @@ -449,7 +449,7 @@ export const TorLauncherUtil = Object.freeze({
    449 449
        *   If network.proxy.socks contains a file: URL, a default value of
    
    450 450
        *     "127.0.0.1" is used instead.
    
    451 451
        *   If the network.proxy.socks_port value is not valid (outside the
    
    452
    -   *     (0; 65535] range), a default value of 9150 is used instead.
    
    452
    +   *     (0; 65535] range), we will let the tor daemon choose a port.
    
    453 453
        *
    
    454 454
        * The SOCKS configuration will not influence the launch of a tor daemon and
    
    455 455
        * the configuration of the control port in any way.
    
    ... ... @@ -458,13 +458,6 @@ export const TorLauncherUtil = Object.freeze({
    458 458
        * This also applies to TOR_TRANSPROXY (at least for now): tor will be
    
    459 459
        * launched with its defaults.
    
    460 460
        *
    
    461
    -   * TODO: add a preference to ignore the current configuration, and let tor
    
    462
    -   * listen on any free port. Then, the browser will prompt the daemon the port
    
    463
    -   * to use through the control port (even though this is quite dangerous at the
    
    464
    -   * moment, because with network disabled tor will disable also the SOCKS
    
    465
    -   * listeners, so it means that we will have to check it every time we change
    
    466
    -   * the network status).
    
    467
    -   *
    
    468 461
        * @returns {SocksSettings}
    
    469 462
        */
    
    470 463
       getPreferredSocksConfiguration() {
    
    ... ... @@ -491,7 +484,7 @@ export const TorLauncherUtil = Object.freeze({
    491 484
           }
    
    492 485
           if (Services.env.exists("TOR_SOCKS_PORT")) {
    
    493 486
             const port = parseInt(Services.env.get("TOR_SOCKS_PORT"), 10);
    
    494
    -        if (Number.isInteger(port) && port > 0 && port <= 65535) {
    
    487
    +        if (Number.isInteger(port) && port >= 0 && port <= 65535) {
    
    495 488
               socksPortInfo.port = port;
    
    496 489
               useIPC = false;
    
    497 490
             }
    
    ... ... @@ -522,20 +515,32 @@ export const TorLauncherUtil = Object.freeze({
    522 515
             socksPortInfo.host = socksAddrHasHost ? socksAddr : "127.0.0.1";
    
    523 516
           }
    
    524 517
     
    
    525
    -      if (!socksPortInfo.port) {
    
    518
    +      if (socksPortInfo.port === undefined) {
    
    526 519
             let socksPort = Services.prefs.getIntPref(
    
    527 520
               "network.proxy.socks_port",
    
    528
    -          0
    
    521
    +          9150
    
    529 522
             );
    
    530
    -        // This pref is set as 0 by default in Firefox, use 9150 if we get 0.
    
    531
    -        socksPortInfo.port =
    
    532
    -          socksPort > 0 && socksPort <= 65535 ? socksPort : 9150;
    
    523
    +        if (socksPort > 0 && socksPort <= 65535) {
    
    524
    +          socksPortInfo.port = socksPort;
    
    525
    +        } else {
    
    526
    +          // Automatic port number, we have to query tor over the control port
    
    527
    +          // every time we change DisableNetwork.
    
    528
    +          socksPortInfo.port = 0;
    
    529
    +        }
    
    533 530
           }
    
    534 531
         }
    
    535 532
     
    
    536 533
         return socksPortInfo;
    
    537 534
       },
    
    538 535
     
    
    536
    +  /**
    
    537
    +   * Apply our proxy configuration to the browser.
    
    538
    +   *
    
    539
    +   * Currently, we try to configure the Tor daemon to match the browser's
    
    540
    +   * configuration, but this might change in the future (tor-browser#42062).
    
    541
    +   *
    
    542
    +   * @param {SocksSettings} socksPortInfo The configuration to apply
    
    543
    +   */
    
    539 544
       setProxyConfiguration(socksPortInfo) {
    
    540 545
         if (socksPortInfo.transproxy) {
    
    541 546
           Services.prefs.setBoolPref("network.proxy.socks_remote_dns", false);
    
    ... ... @@ -556,7 +561,7 @@ export const TorLauncherUtil = Object.freeze({
    556 561
           if (socksPortInfo.host) {
    
    557 562
             Services.prefs.setCharPref("network.proxy.socks", socksPortInfo.host);
    
    558 563
           }
    
    559
    -      if (socksPortInfo.port) {
    
    564
    +      if (socksPortInfo.port > 0 && socksPortInfo.port <= 65535) {
    
    560 565
             Services.prefs.setIntPref(
    
    561 566
               "network.proxy.socks_port",
    
    562 567
               socksPortInfo.port
    

  • toolkit/components/tor-launcher/TorProcess.sys.mjs
    ... ... @@ -53,13 +53,16 @@ export class TorProcess {
    53 53
           throw new Error("Unauthenticated control port is not supported");
    
    54 54
         }
    
    55 55
     
    
    56
    -    const checkPort = port =>
    
    56
    +    const checkPort = (port, allowZero) =>
    
    57 57
           port === undefined ||
    
    58
    -      (Number.isInteger(port) && port > 0 && port < 65535);
    
    59
    -    if (!checkPort(controlSettings?.port)) {
    
    58
    +      (Number.isInteger(port) &&
    
    59
    +        port < 65535 &&
    
    60
    +        (port > 0 || (allowZero && port === 0)));
    
    61
    +    if (!checkPort(controlSettings?.port, false)) {
    
    60 62
           throw new Error("Invalid control port");
    
    61 63
         }
    
    62
    -    if (!checkPort(socksSettings.port)) {
    
    64
    +    // Port 0 for SOCKS means automatic port.
    
    65
    +    if (!checkPort(socksSettings.port, true)) {
    
    63 66
           throw new Error("Invalid port specified for the SOCKS port");
    
    64 67
         }
    
    65 68
     
    
    ... ... @@ -296,10 +299,12 @@ export class TorProcess {
    296 299
         let socksPortArg;
    
    297 300
         if (this.#socksSettings.ipcFile) {
    
    298 301
           socksPortArg = this.#socksSettings.ipcFile;
    
    299
    -    } else if (this.#socksSettings.port != 0) {
    
    302
    +    } else if (this.#socksSettings.port > 0) {
    
    300 303
           socksPortArg = this.#socksSettings.host
    
    301 304
             ? `${this.#socksSettings.host}:${this.#socksSettings.port}`
    
    302 305
             : this.#socksSettings.port.toString();
    
    306
    +    } else {
    
    307
    +      socksPortArg = "auto";
    
    303 308
         }
    
    304 309
         if (socksPortArg) {
    
    305 310
           const socksPortFlags = Services.prefs.getCharPref(
    

  • toolkit/components/tor-launcher/TorProcessAndroid.sys.mjs
    ... ... @@ -77,6 +77,10 @@ export class TorProcessAndroid {
    77 77
           config = await lazy.EventDispatcher.instance.sendRequestForResult({
    
    78 78
             type: TorOutgoingEvents.start,
    
    79 79
             handle: this.#processHandle,
    
    80
    +        tcpSocks: Services.prefs.getBoolPref(
    
    81
    +          "extensions.torlauncher.socks_port_use_tcp",
    
    82
    +          false
    
    83
    +        ),
    
    80 84
           });
    
    81 85
           logger.debug("Sent the start event.");
    
    82 86
         } catch (e) {
    

  • toolkit/components/tor-launcher/TorProvider.sys.mjs
    ... ... @@ -27,23 +27,23 @@ const logger = console.createInstance({
    27 27
      * @typedef {object} ControlPortSettings An object with the settings to use for
    
    28 28
      * the control port. All the entries are optional, but an authentication
    
    29 29
      * mechanism and a communication method must be specified.
    
    30
    - * @property {Uint8Array=} password The clear text password as an array of
    
    30
    + * @property {Uint8Array} [password] The clear text password as an array of
    
    31 31
      * bytes. It must always be defined, unless cookieFilePath is
    
    32
    - * @property {string=} cookieFilePath The path to the cookie file to use for
    
    32
    + * @property {string} [cookieFilePath] The path to the cookie file to use for
    
    33 33
      * authentication
    
    34
    - * @property {nsIFile=} ipcFile The nsIFile object with the path to a Unix
    
    34
    + * @property {nsIFile} [ipcFile] The nsIFile object with the path to a Unix
    
    35 35
      * socket to use for control socket
    
    36
    - * @property {string=} host The host to connect for a TCP control port
    
    37
    - * @property {number=} port The port number to use for a TCP control port
    
    36
    + * @property {string} [host] The host to connect for a TCP control port
    
    37
    + * @property {number} [port] The port number to use for a TCP control port
    
    38 38
      */
    
    39 39
     /**
    
    40 40
      * @typedef {object} SocksSettings An object that includes the proxy settings to
    
    41 41
      * be configured in the browser.
    
    42
    - * @property {boolean=} transproxy If true, no proxy is configured
    
    43
    - * @property {nsIFile=} ipcFile The nsIFile object with the path to a Unix
    
    42
    + * @property {boolean} [transproxy] If true, no proxy is configured
    
    43
    + * @property {nsIFile} [ipcFile] The nsIFile object with the path to a Unix
    
    44 44
      * socket to use for an IPC proxy
    
    45
    - * @property {string=} host The host to connect for a TCP proxy
    
    46
    - * @property {number=} port The port number to use for a TCP proxy
    
    45
    + * @property {string} [host] The host to connect for a TCP proxy
    
    46
    + * @property {number} [port] The port number to use for a TCP proxy
    
    47 47
      */
    
    48 48
     /**
    
    49 49
      * @typedef {object} LogEntry An object with a log message
    
    ... ... @@ -345,6 +345,25 @@ export class TorProvider {
    345 345
        */
    
    346 346
       async connect() {
    
    347 347
         await this.#controller.setNetworkEnabled(true);
    
    348
    +    if (this.#socksSettings.port === 0) {
    
    349
    +      // Enablign/disabling network resets also the SOCKS listener.
    
    350
    +      // So, every time we do it, we need to update the browser's configuration
    
    351
    +      // to use the updated port.
    
    352
    +      const settings = structuredClone(this.#socksSettings);
    
    353
    +      for (const listener of await this.#controller.getSocksListeners()) {
    
    354
    +        // When set to automatic port, ignore any IPC listener, as the intention
    
    355
    +        // was to use TCP.
    
    356
    +        if (listener.ipcPath) {
    
    357
    +          continue;
    
    358
    +        }
    
    359
    +        // The tor daemon can have any number of SOCKS listeners (see SocksPort
    
    360
    +        // in man 1 tor). We take for granted that any TCP one will work for us.
    
    361
    +        settings.host = listener.host;
    
    362
    +        settings.port = listener.port;
    
    363
    +        break;
    
    364
    +      }
    
    365
    +      TorLauncherUtil.setProxyConfiguration(settings);
    
    366
    +    }
    
    348 367
         this.#lastWarning = {};
    
    349 368
         this.retrieveBootstrapStatus();
    
    350 369
       }
    
    ... ... @@ -569,14 +588,24 @@ export class TorProvider {
    569 588
         logger.debug("Trying to start the tor process.");
    
    570 589
         const res = await this.#torProcess.start();
    
    571 590
         if (TorLauncherUtil.isAndroid) {
    
    591
    +      logger.debug("Configuration from TorProcessAndriod", res);
    
    572 592
           this.#controlPortSettings = {
    
    573 593
             ipcFile: new lazy.FileUtils.File(res.controlPortPath),
    
    574 594
             cookieFilePath: res.cookieFilePath,
    
    575 595
           };
    
    576 596
           this.#socksSettings = {
    
    577 597
             transproxy: false,
    
    578
    -        ipcFile: new lazy.FileUtils.File(res.socksPath),
    
    579 598
           };
    
    599
    +      if (res.socksPath) {
    
    600
    +        this.#socksSettings.ipcFile = new lazy.FileUtils.File(res.socksPath);
    
    601
    +      } else if (res.socksPort !== undefined) {
    
    602
    +        this.#socksSettings.host = res.socksHost ?? "127.0.0.1";
    
    603
    +        this.#socksSettings.port = res.socksPort;
    
    604
    +      } else {
    
    605
    +        throw new Error(
    
    606
    +          "TorProcessAndroid did not return a valid SOCKS configuration."
    
    607
    +        );
    
    608
    +      }
    
    580 609
         }
    
    581 610
         logger.info("Started a tor process");
    
    582 611
       }
    

  • _______________________________________________
    tor-commits mailing list -- tor-commits@xxxxxxxxxxxxxxxxxxxx
    To unsubscribe send an email to tor-commits-leave@xxxxxxxxxxxxxxxxxxxx