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

Commits:

1 changed file:

Changes:

  • toolkit/components/tor-launcher/TorControlPort.sys.mjs
    ... ... @@ -795,7 +795,64 @@ export class TorController {
    795 795
        * @returns {Bridge[]} The configured bridges
    
    796 796
        */
    
    797 797
       async getBridges() {
    
    798
    -    return (await this.#getConf("BRIDGE")).map(TorParsers.parseBridgeLine);
    
    798
    +    let missingId = false;
    
    799
    +    const bridges = (await this.#getConf("BRIDGE")).map(line => {
    
    800
    +      const info = TorParsers.parseBridgeLine(line);
    
    801
    +      if (!info.id) {
    
    802
    +        missingId = true;
    
    803
    +      }
    
    804
    +      return info;
    
    805
    +    });
    
    806
    +
    
    807
    +    // tor-browser#42541: bridge lines are allowed not to have a fingerprint.
    
    808
    +    // If such a bridge is in use, we will fail to associate it to the circuits,
    
    809
    +    // and the circuit display will not be shown.
    
    810
    +    // Tor provides a couple of GETINFO commands we can try to use to get more
    
    811
    +    // data about bridges, in particular GETINFO ns/purpose/bridge.
    
    812
    +    // While it tells us the bridge's IP (as configured by the user, which might
    
    813
    +    // be different from the real one with some PTs such as Snowflake), it does
    
    814
    +    // not tell the pluggable transport.
    
    815
    +    // Therefore, we need to start from the configured bridge lines, and if we
    
    816
    +    // detect that a bridge does not have a fingerprint, we try to associate one
    
    817
    +    // through its IP address and port.
    
    818
    +    // However, users can set them directly, therefore we might end up setting
    
    819
    +    // a fingerprint to the wrong line (e.g., if the IP address is reused).
    
    820
    +    // Also, we are not sure about when the data of ns/purpose/bridge is
    
    821
    +    // populated.
    
    822
    +    // Usually, we are interested only in the data of currently active bridges
    
    823
    +    // for the circuit display. So, as a matter of fact, we expect to have
    
    824
    +    // entries and to expose only the correct and working data in the frontend.
    
    825
    +    if (missingId) {
    
    826
    +      // See https://spec.torproject.org/dir-spec/consensus-formats.html.
    
    827
    +      // r <name> <identity> <digest> <date> <time> <address> <orport> <dirport>
    
    828
    +      const info = (await this.#getInfo("ns/purpose/bridge")).matchAll(
    
    829
    +        /^r\s+\S+\s+(?<identity>\S+)\s+\S+\s+\S+\s+\S+\s+(?<address>\S+)\s+(?<orport>\d+)/gm
    
    830
    +      );
    
    831
    +      const b64ToHex = b64 => {
    
    832
    +        let hex = "";
    
    833
    +        const raw = atob(b64);
    
    834
    +        for (let i = 0; i < raw.length; i++) {
    
    835
    +          hex += raw.charCodeAt(i).toString(16).toUpperCase().padStart(2, "0");
    
    836
    +        }
    
    837
    +        return hex;
    
    838
    +      };
    
    839
    +      const knownBridges = new Map(
    
    840
    +        Array.from(info, m => [
    
    841
    +          `${m.groups.address}:${m.groups.orport}`,
    
    842
    +          b64ToHex(m.groups.identity),
    
    843
    +        ])
    
    844
    +      );
    
    845
    +      for (const b of bridges) {
    
    846
    +        if (!b.id) {
    
    847
    +          // We expect the addresses of these lines to be only IPv4, therefore
    
    848
    +          // we do not check for brackets, even though they might be matched by
    
    849
    +          // our regex.
    
    850
    +          b.id = knownBridges.get(b.addr) ?? "";
    
    851
    +        }
    
    852
    +      }
    
    853
    +    }
    
    854
    +
    
    855
    +    return bridges;
    
    799 856
       }
    
    800 857
     
    
    801 858
       /**