tor-browser

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

test_ip_address_space_lna_glean.js (7411B)


      1 "use strict";
      2 
      3 const override = Cc["@mozilla.org/network/native-dns-override;1"].getService(
      4  Ci.nsINativeDNSResolverOverride
      5 );
      6 const mockNetwork = Cc[
      7  "@mozilla.org/network/mock-network-controller;1"
      8 ].getService(Ci.nsIMockNetworkLayerController);
      9 const certOverrideService = Cc[
     10  "@mozilla.org/security/certoverride;1"
     11 ].getService(Ci.nsICertOverrideService);
     12 
     13 const { AppConstants } = ChromeUtils.importESModule(
     14  "resource://gre/modules/AppConstants.sys.mjs"
     15 );
     16 
     17 const { NodeHTTPServer, NodeHTTPSServer } = ChromeUtils.importESModule(
     18  "resource://testing-common/NodeServer.sys.mjs"
     19 );
     20 
     21 const DOMAIN = "example.org";
     22 
     23 function makeChan(url, expected) {
     24  let chan = NetUtil.newChannel({
     25    uri: url,
     26    loadUsingSystemPrincipal: true,
     27    contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
     28  }).QueryInterface(Ci.nsIHttpChannel);
     29 
     30  if (
     31    expected.PublicToPrivateHttp !== undefined ||
     32    expected.PublicToLocalHttp !== undefined ||
     33    expected.PublicToPublicHttp !== undefined ||
     34    expected.PublicToPrivateHttps !== undefined ||
     35    expected.PublicToLocalHttps !== undefined ||
     36    expected.PublicToPublicHttp !== undefined
     37  ) {
     38    chan.loadInfo.parentIpAddressSpace = Ci.nsILoadInfo.Public;
     39  } else if (
     40    expected.PrivateToLocalHttp !== undefined ||
     41    expected.PrivateToPrivateHttp !== undefined ||
     42    expected.PrivateToLocalHttps !== undefined ||
     43    expected.PrivateToPrivateHttps !== undefined
     44  ) {
     45    chan.loadInfo.parentIpAddressSpace = Ci.nsILoadInfo.Private;
     46  }
     47  return chan;
     48 }
     49 
     50 function channelOpenPromise(chan, flags) {
     51  return new Promise(resolve => {
     52    function finish(req, buffer) {
     53      resolve([req, buffer]);
     54      certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
     55        false
     56      );
     57    }
     58    certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData(
     59      true
     60    );
     61    chan.asyncOpen(new ChannelListener(finish, null, flags));
     62  });
     63 }
     64 
     65 let server;
     66 
     67 add_setup(async function setup() {
     68  Services.prefs.setBoolPref("network.socket.attach_mock_network_layer", true);
     69 
     70  Services.fog.initializeFOG();
     71 
     72  server = new NodeHTTPServer();
     73  await server.start();
     74  registerCleanupFunction(async () => {
     75    Services.prefs.clearUserPref("network.disable-localhost-when-offline");
     76    Services.prefs.clearUserPref("network.dns.use_override_as_peer_address");
     77    Services.prefs.clearUserPref("dom.security.https_only_mode");
     78    Services.prefs.clearUserPref("dom.security.https_first");
     79    Services.prefs.clearUserPref("dom.security.https_first_schemeless");
     80    Services.prefs.clearUserPref("network.socket.attach_mock_network_layer");
     81    await server.stop();
     82  });
     83 });
     84 
     85 function verifyGleanValues(aDescription, aExpected) {
     86  info(aDescription);
     87 
     88  let privateToLocalHttp = aExpected.PrivateToLocalHttp || null;
     89  let publicToPrivateHttp = aExpected.PublicToPrivateHttp || null;
     90  let publicToLocalHttp = aExpected.PublicToLocalHttp || null;
     91  let privateToLocalHttps = aExpected.PrivateToLocalHttps || null;
     92  let publicToPrivateHttps = aExpected.PublicToPrivateHttps || null;
     93  let publicToLocalHttps = aExpected.PublicToLocalHttps || null;
     94 
     95  let glean = Glean.networking.localNetworkAccess;
     96  Assert.equal(
     97    glean.private_to_local_http.testGetValue(),
     98    privateToLocalHttp,
     99    "verify private_to_local_http"
    100  );
    101  Assert.equal(
    102    glean.public_to_private_http.testGetValue(),
    103    publicToPrivateHttp,
    104    "verify public_to_private_http"
    105  );
    106  Assert.equal(
    107    glean.public_to_local_http.testGetValue(),
    108    publicToLocalHttp,
    109    "verify public_to_local_http"
    110  );
    111  Assert.equal(
    112    glean.private_to_local_https.testGetValue(),
    113    privateToLocalHttps,
    114    "verify private_to_local_http"
    115  );
    116  Assert.equal(
    117    glean.public_to_private_https.testGetValue(),
    118    publicToPrivateHttps,
    119    "verify public_to_private_http"
    120  );
    121  Assert.equal(
    122    glean.public_to_local_https.testGetValue(),
    123    publicToLocalHttps,
    124    "verify public_to_local_http"
    125  );
    126 
    127  Assert.equal(
    128    glean.public_to_local_https.testGetValue(),
    129    publicToLocalHttps,
    130    "verify public_to_local_http"
    131  );
    132 
    133  if (
    134    privateToLocalHttp ||
    135    publicToPrivateHttp ||
    136    publicToLocalHttp ||
    137    privateToLocalHttps ||
    138    publicToPrivateHttps ||
    139    publicToLocalHttps
    140  ) {
    141    Assert.equal(
    142      glean.success.testGetValue(),
    143      1,
    144      "verify local_network_access_success"
    145    );
    146    // XXX (sunil) add test for local_network_access_failure cases
    147  }
    148 }
    149 
    150 async function do_test(ip, expected, srcPort, dstPort) {
    151  Services.fog.testResetFOG();
    152 
    153  override.addIPOverride(DOMAIN, ip);
    154  let fromAddr = mockNetwork.createScriptableNetAddr(ip, srcPort ?? 80);
    155  let toAddr = mockNetwork.createScriptableNetAddr(
    156    fromAddr.family == Ci.nsINetAddr.FAMILY_INET ? "127.0.0.1" : "::1",
    157    dstPort ?? server.port()
    158  );
    159 
    160  mockNetwork.addNetAddrOverride(fromAddr, toAddr);
    161 
    162  info(`do_test ${ip}, ${fromAddr} -> ${toAddr}`);
    163 
    164  let chan = makeChan(`http://${DOMAIN}`, expected);
    165  let [req] = await channelOpenPromise(chan);
    166 
    167  info(
    168    "req.remoteAddress=" +
    169      req.QueryInterface(Ci.nsIHttpChannelInternal).remoteAddress
    170  );
    171 
    172  if (expected.PublicToPrivateHttp) {
    173    Assert.equal(chan.loadInfo.ipAddressSpace, Ci.nsILoadInfo.Private);
    174  } else if (expected.PrivateToLocalHttp || expected.PrivateToLocalHttp) {
    175    Assert.equal(chan.loadInfo.ipAddressSpace, Ci.nsILoadInfo.Local);
    176  }
    177 
    178  verifyGleanValues(`test ip=${ip}`, expected);
    179 
    180  Services.dns.clearCache(false);
    181  override.clearOverrides();
    182  mockNetwork.clearNetAddrOverrides();
    183  Services.obs.notifyObservers(null, "net:prune-all-connections");
    184 }
    185 
    186 add_task(async function test_lna_http() {
    187  Services.prefs.setBoolPref("dom.security.https_only_mode", false);
    188  Services.prefs.setBoolPref("dom.security.https_first", false);
    189  Services.prefs.setBoolPref("dom.security.https_first_schemeless", false);
    190 
    191  await do_test("10.0.0.1", { PublicToPrivateHttp: 1 });
    192 
    193  // NO LNA access do not increment
    194  await do_test("10.0.0.1", { PrivateToPrivateHttp: 0 });
    195  await do_test("2.2.2.2", { PublicToPublicHttp: 0 });
    196 
    197  await do_test("100.64.0.1", { PublicToPrivateHttp: 1 });
    198  await do_test("127.0.0.1", { PublicToLocalHttp: 1 });
    199  await do_test("127.0.0.1", { PrivateToLocalHttp: 1 });
    200  if (AppConstants.platform != "android") {
    201    await do_test("::1", { PrivateToLocalHttp: 1 });
    202  }
    203 });
    204 
    205 add_task(async function test_lna_https() {
    206  Services.prefs.setBoolPref("dom.security.https_only_mode", true);
    207  let httpsServer = new NodeHTTPSServer();
    208  await httpsServer.start();
    209  registerCleanupFunction(async () => {
    210    await httpsServer.stop();
    211  });
    212  await do_test(
    213    "10.0.0.1",
    214    { PublicToPrivateHttps: 1 },
    215    443,
    216    httpsServer.port()
    217  );
    218 
    219  // NO LNA access do not increment
    220  await do_test(
    221    "10.0.0.1",
    222    { PrivateToPrivateHttps: 0 },
    223    443,
    224    httpsServer.port()
    225  );
    226  await do_test(
    227    "2.2.2.2",
    228    { PublicToPublicHttps: 0 },
    229    443,
    230    httpsServer.port(),
    231    true
    232  );
    233 
    234  await do_test(
    235    "100.64.0.1",
    236    { PublicToPrivateHttps: 1 },
    237    443,
    238    httpsServer.port()
    239  );
    240  await do_test(
    241    "127.0.0.1",
    242    { PublicToLocalHttps: 1 },
    243    443,
    244    httpsServer.port()
    245  );
    246  await do_test(
    247    "127.0.0.1",
    248    { PrivateToLocalHttps: 1 },
    249    443,
    250    httpsServer.port()
    251  );
    252  if (AppConstants.platform != "android") {
    253    await do_test("::1", { PrivateToLocalHttps: 1 }, 443, httpsServer.port());
    254  }
    255 });