tor-browser

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

test_trr_cname_chain.js (5836B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 let trrServer;
      8 
      9 function makeChan(url) {
     10  let chan = NetUtil.newChannel({
     11    uri: url,
     12    loadUsingSystemPrincipal: true,
     13  }).QueryInterface(Ci.nsIHttpChannel);
     14  return chan;
     15 }
     16 
     17 function channelOpenPromise(chan) {
     18  return new Promise(resolve => {
     19    function finish(req, buffer) {
     20      resolve([req, buffer]);
     21    }
     22    chan.asyncOpen(new ChannelListener(finish));
     23  });
     24 }
     25 
     26 add_setup(async function setup() {
     27  trr_test_setup();
     28  registerCleanupFunction(async () => {
     29    trr_clear_prefs();
     30  });
     31 
     32  trrServer = new TRRServer();
     33  registerCleanupFunction(async () => {
     34    await trrServer.stop();
     35  });
     36  await trrServer.start();
     37  dump(`port = ${trrServer.port()}\n`);
     38  let chan = makeChan(`https://localhost:${trrServer.port()}/test?bla=some`);
     39  let [, resp] = await channelOpenPromise(chan);
     40  equal(resp, "<h1> 404 Path not found: /test</h1>");
     41 
     42  Services.dns.clearCache(true);
     43  Services.prefs.setIntPref("network.trr.mode", 3);
     44  Services.prefs.setCharPref(
     45    "network.trr.uri",
     46    `https://foo.example.com:${trrServer.port()}/dns-query`
     47  );
     48 });
     49 
     50 add_task(async function test_follow_cnames_same_response() {
     51  await trrServer.registerDoHAnswers("something.foo", "A", {
     52    answers: [
     53      {
     54        name: "something.foo",
     55        ttl: 55,
     56        type: "CNAME",
     57        flush: false,
     58        data: "other.foo",
     59      },
     60      {
     61        name: "other.foo",
     62        ttl: 55,
     63        type: "CNAME",
     64        flush: false,
     65        data: "bla.foo",
     66      },
     67      {
     68        name: "bla.foo",
     69        ttl: 55,
     70        type: "CNAME",
     71        flush: false,
     72        data: "xyz.foo",
     73      },
     74      {
     75        name: "xyz.foo",
     76        ttl: 55,
     77        type: "A",
     78        flush: false,
     79        data: "1.2.3.4",
     80      },
     81    ],
     82  });
     83  let { inRecord } = await new TRRDNSListener("something.foo", {
     84    expectedAnswer: "1.2.3.4",
     85    flags: Ci.nsIDNSService.RESOLVE_CANONICAL_NAME,
     86  });
     87  equal(inRecord.QueryInterface(Ci.nsIDNSAddrRecord).canonicalName, "xyz.foo");
     88 
     89  await trrServer.registerDoHAnswers("a.foo", "A", {
     90    answers: [
     91      {
     92        name: "a.foo",
     93        ttl: 55,
     94        type: "CNAME",
     95        flush: false,
     96        data: "b.foo",
     97      },
     98    ],
     99  });
    100  await trrServer.registerDoHAnswers("b.foo", "A", {
    101    answers: [
    102      {
    103        name: "b.foo",
    104        ttl: 55,
    105        type: "A",
    106        flush: false,
    107        data: "2.3.4.5",
    108      },
    109    ],
    110  });
    111  await new TRRDNSListener("a.foo", { expectedAnswer: "2.3.4.5" });
    112 });
    113 
    114 add_task(async function test_cname_nodata() {
    115  // Test that we don't needlessly follow cname chains when the RA flag is set
    116  // on the response.
    117 
    118  await trrServer.registerDoHAnswers("first.foo", "A", {
    119    flags: 0x80,
    120    answers: [
    121      {
    122        name: "first.foo",
    123        ttl: 55,
    124        type: "CNAME",
    125        flush: false,
    126        data: "second.foo",
    127      },
    128      {
    129        name: "second.foo",
    130        ttl: 55,
    131        type: "A",
    132        flush: false,
    133        data: "1.2.3.4",
    134      },
    135    ],
    136  });
    137  await trrServer.registerDoHAnswers("first.foo", "AAAA", {
    138    flags: 0x80,
    139    answers: [
    140      {
    141        name: "first.foo",
    142        ttl: 55,
    143        type: "CNAME",
    144        flush: false,
    145        data: "second.foo",
    146      },
    147    ],
    148  });
    149 
    150  await new TRRDNSListener("first.foo", { expectedAnswer: "1.2.3.4" });
    151  equal(await trrServer.requestCount("first.foo", "A"), 1);
    152  equal(await trrServer.requestCount("first.foo", "AAAA"), 1);
    153  equal(await trrServer.requestCount("second.foo", "A"), 0);
    154  equal(await trrServer.requestCount("second.foo", "AAAA"), 0);
    155 
    156  await trrServer.registerDoHAnswers("first.bar", "A", {
    157    answers: [
    158      {
    159        name: "first.bar",
    160        ttl: 55,
    161        type: "CNAME",
    162        flush: false,
    163        data: "second.bar",
    164      },
    165      {
    166        name: "second.bar",
    167        ttl: 55,
    168        type: "A",
    169        flush: false,
    170        data: "1.2.3.4",
    171      },
    172    ],
    173  });
    174  await trrServer.registerDoHAnswers("first.bar", "AAAA", {
    175    answers: [
    176      {
    177        name: "first.bar",
    178        ttl: 55,
    179        type: "CNAME",
    180        flush: false,
    181        data: "second.bar",
    182      },
    183    ],
    184  });
    185 
    186  await new TRRDNSListener("first.bar", { expectedAnswer: "1.2.3.4" });
    187  equal(await trrServer.requestCount("first.bar", "A"), 1);
    188  equal(await trrServer.requestCount("first.bar", "AAAA"), 1);
    189  equal(await trrServer.requestCount("second.bar", "A"), 0); // addr included in first response
    190  equal(await trrServer.requestCount("second.bar", "AAAA"), 1); // will follow cname because no flag is set
    191 
    192  // Check that it also works for HTTPS records
    193 
    194  await trrServer.registerDoHAnswers("first.bar", "HTTPS", {
    195    flags: 0x80,
    196    answers: [
    197      {
    198        name: "second.bar",
    199        ttl: 55,
    200        type: "HTTPS",
    201        flush: false,
    202        data: {
    203          priority: 1,
    204          name: "h3pool",
    205          values: [
    206            { key: "alpn", value: ["h2", "h3"] },
    207            { key: "no-default-alpn" },
    208            { key: "port", value: 8888 },
    209            { key: "ipv4hint", value: "1.2.3.4" },
    210            { key: "echconfig", value: "123..." },
    211            { key: "ipv6hint", value: "::1" },
    212          ],
    213        },
    214      },
    215      {
    216        name: "first.bar",
    217        ttl: 55,
    218        type: "CNAME",
    219        flush: false,
    220        data: "second.bar",
    221      },
    222    ],
    223  });
    224 
    225  let { inStatus } = await new TRRDNSListener("first.bar", {
    226    type: Ci.nsIDNSService.RESOLVE_TYPE_HTTPSSVC,
    227  });
    228  Assert.ok(Components.isSuccessCode(inStatus), `${inStatus} should work`);
    229  equal(await trrServer.requestCount("first.bar", "HTTPS"), 1);
    230  equal(await trrServer.requestCount("second.bar", "HTTPS"), 0);
    231 });