tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_trr_with_proxy.js (6786B)


      1 /* This test checks that a TRRServiceChannel can connect to the server with
      2   a proxy.
      3   Steps:
      4     - Setup the proxy (PAC, proxy filter, and system proxy settings)
      5     - Test when "network.trr.async_connInfo" is false. In this case, every
      6       TRRServicChannel waits for the proxy info to be resolved.
      7     - Test when "network.trr.async_connInfo" is true. In this case, every
      8       TRRServicChannel uses an already created connection info to connect.
      9     - The test test_trr_uri_change() is about checking if trr connection info
     10       is updated correctly when trr uri changed.
     11 */
     12 
     13 "use strict";
     14 
     15 var { setTimeout } = ChromeUtils.importESModule(
     16  "resource://gre/modules/Timer.sys.mjs"
     17 );
     18 
     19 /* import-globals-from trr_common.js */
     20 /* import-globals-from head_trr.js */
     21 
     22 let filter;
     23 let systemProxySettings;
     24 let trrProxy;
     25 const pps = Cc["@mozilla.org/network/protocol-proxy-service;1"].getService();
     26 
     27 let trrServer;
     28 add_setup(async function setup() {
     29  trr_test_setup();
     30  SetParentalControlEnabled(false);
     31 
     32  trrServer = new TRRServer();
     33  await trrServer.start();
     34  h2Port = trrServer.port();
     35 
     36  registerCleanupFunction(async () => {
     37    trr_clear_prefs();
     38    Services.prefs.clearUserPref("network.proxy.type");
     39    Services.prefs.clearUserPref("network.proxy.autoconfig_url");
     40    Services.prefs.clearUserPref("network.trr.async_connInfo");
     41    if (trrProxy) {
     42      await trrProxy.stop();
     43    }
     44    if (trrServer) {
     45      await trrServer.stop();
     46    }
     47  });
     48 });
     49 
     50 class ProxyFilter {
     51  constructor(type, host, port, flags) {
     52    this._type = type;
     53    this._host = host;
     54    this._port = port;
     55    this._flags = flags;
     56    this.QueryInterface = ChromeUtils.generateQI(["nsIProtocolProxyFilter"]);
     57  }
     58  applyFilter(uri, pi, cb) {
     59    cb.onProxyFilterResult(
     60      pps.newProxyInfo(
     61        this._type,
     62        this._host,
     63        this._port,
     64        "",
     65        "",
     66        this._flags,
     67        1000,
     68        null
     69      )
     70    );
     71  }
     72 }
     73 
     74 async function doTest(proxySetup, delay) {
     75  info("Verifying a basic A record");
     76  Services.dns.clearCache(true);
     77  // Close all previous connections.
     78  Services.obs.notifyObservers(null, "net:cancel-all-connections");
     79  // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
     80  await new Promise(resolve => setTimeout(resolve, 1000));
     81 
     82  setModeAndURI(2, "doh?responseIP=2.2.2.2"); // TRR-first
     83 
     84  trrProxy = new TRRProxy();
     85  await trrProxy.start(h2Port);
     86  info("port=" + trrProxy.port);
     87 
     88  await proxySetup(trrProxy.port);
     89 
     90  if (delay) {
     91    await new Promise(resolve => do_timeout(delay, resolve));
     92  }
     93 
     94  await new TRRDNSListener("bar.example.com", "2.2.2.2");
     95 
     96  // A non-zero request count indicates that TRR requests are being routed
     97  // through the proxy.
     98  Assert.greaterOrEqual(
     99    await trrProxy.request_count(),
    100    1,
    101    `Request count should be at least 1`
    102  );
    103 
    104  // clean up
    105  Services.prefs.clearUserPref("network.proxy.type");
    106  Services.prefs.clearUserPref("network.proxy.autoconfig_url");
    107  if (filter) {
    108    pps.unregisterFilter(filter);
    109    filter = null;
    110  }
    111  if (systemProxySettings) {
    112    MockRegistrar.unregister(systemProxySettings);
    113    systemProxySettings = null;
    114  }
    115 
    116  await trrProxy.stop();
    117  trrProxy = null;
    118 }
    119 
    120 add_task(async function test_trr_proxy() {
    121  async function setupPACWithDataURL(proxyPort) {
    122    var pac = `data:text/plain, function FindProxyForURL(url, host) { return "HTTPS foo.example.com:${proxyPort}";}`;
    123    Services.prefs.setIntPref("network.proxy.type", 2);
    124    Services.prefs.setCharPref("network.proxy.autoconfig_url", pac);
    125  }
    126 
    127  async function setupPACWithHttpURL(proxyPort) {
    128    let httpserv = new HttpServer();
    129    httpserv.registerPathHandler("/", function handler(metadata, response) {
    130      response.setStatusLine(metadata.httpVersion, 200, "OK");
    131      let content = `function FindProxyForURL(url, host) { return "HTTPS foo.example.com:${proxyPort}";}`;
    132      response.setHeader("Content-Length", `${content.length}`);
    133      response.bodyOutputStream.write(content, content.length);
    134    });
    135    httpserv.start(-1);
    136    Services.prefs.setIntPref("network.proxy.type", 2);
    137    let pacUri = `http://127.0.0.1:${httpserv.identity.primaryPort}/`;
    138    Services.prefs.setCharPref("network.proxy.autoconfig_url", pacUri);
    139 
    140    function consoleMessageObserved() {
    141      return new Promise(resolve => {
    142        let listener = {
    143          QueryInterface: ChromeUtils.generateQI(["nsIConsoleListener"]),
    144          observe(msg) {
    145            if (msg == `PAC file installed from ${pacUri}`) {
    146              Services.console.unregisterListener(listener);
    147              resolve();
    148            }
    149          },
    150        };
    151        Services.console.registerListener(listener);
    152      });
    153    }
    154 
    155    await consoleMessageObserved();
    156  }
    157 
    158  async function setupProxyFilter(proxyPort) {
    159    filter = new ProxyFilter("https", "foo.example.com", proxyPort, 0);
    160    pps.registerFilter(filter, 10);
    161  }
    162 
    163  async function setupSystemProxySettings(proxyPort) {
    164    systemProxySettings = {
    165      QueryInterface: ChromeUtils.generateQI(["nsISystemProxySettings"]),
    166      mainThreadOnly: true,
    167      PACURI: null,
    168      getProxyForURI: () => {
    169        return `HTTPS foo.example.com:${proxyPort}`;
    170      },
    171    };
    172 
    173    MockRegistrar.register(
    174      "@mozilla.org/system-proxy-settings;1",
    175      systemProxySettings
    176    );
    177 
    178    Services.prefs.setIntPref(
    179      "network.proxy.type",
    180      Ci.nsIProtocolProxyService.PROXYCONFIG_SYSTEM
    181    );
    182 
    183    // simulate that system proxy setting is changed.
    184    pps.notifyProxyConfigChangedInternal();
    185  }
    186 
    187  Services.prefs.setBoolPref("network.trr.async_connInfo", false);
    188  await doTest(setupPACWithDataURL);
    189  await doTest(setupPACWithDataURL, 1000);
    190  await doTest(setupPACWithHttpURL);
    191  await doTest(setupPACWithHttpURL, 1000);
    192  await doTest(setupProxyFilter);
    193  await doTest(setupProxyFilter, 1000);
    194  await doTest(setupSystemProxySettings);
    195  await doTest(setupSystemProxySettings, 1000);
    196 
    197  Services.prefs.setBoolPref("network.trr.async_connInfo", true);
    198  await doTest(setupPACWithDataURL);
    199  await doTest(setupPACWithDataURL, 1000);
    200  await doTest(setupPACWithHttpURL);
    201  await doTest(setupPACWithHttpURL, 1000);
    202  await doTest(setupProxyFilter);
    203  await doTest(setupProxyFilter, 1000);
    204  await doTest(setupSystemProxySettings);
    205  await doTest(setupSystemProxySettings, 1000);
    206 });
    207 
    208 add_task(async function test_trr_uri_change() {
    209  Services.prefs.setIntPref("network.proxy.type", 0);
    210  Services.prefs.setBoolPref("network.trr.async_connInfo", true);
    211  Services.dns.clearCache(true);
    212  setModeAndURI(2, "doh?responseIP=2.2.2.2", "127.0.0.1");
    213 
    214  await new TRRDNSListener("car.example.com", "127.0.0.1");
    215 
    216  Services.dns.clearCache(true);
    217  setModeAndURI(2, "doh?responseIP=2.2.2.2");
    218  await new TRRDNSListener("car.example.net", "2.2.2.2");
    219 });