From 866b54da1a40d4ca62219bdb196e73c10cf883a4 Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Thu, 4 Apr 2019 09:30:44 +0000 Subject: [PATCH] Bug 1540656 - Use dns-packet node module in test_trr.js r=dragana Differential Revision: https://phabricator.services.mozilla.com/D25671 --HG-- extra : moz-landing-system : lando --- netwerk/test/unit/test_trr.js | 52 +++--- testing/xpcshell/moz-http2/moz-http2.js | 220 ++++++++++-------------- 2 files changed, 119 insertions(+), 153 deletions(-) diff --git a/netwerk/test/unit/test_trr.js b/netwerk/test/unit/test_trr.js index 67d198f770f9..2cf90666c234 100644 --- a/netwerk/test/unit/test_trr.js +++ b/netwerk/test/unit/test_trr.js @@ -106,20 +106,20 @@ class DNSListener { add_task(async function test1() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 2); // TRR-first - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=2.2.2.2`); - await new DNSListener("bar.example.com", "127.0.0.1"); + await new DNSListener("bar.example.com", "2.2.2.2"); }); // verify basic A record - without bootstrapping add_task(async function test1b() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=3.3.3.3`); Services.prefs.clearUserPref("network.trr.bootstrapAddress"); Services.prefs.setCharPref("network.dns.localDomains", "foo.example.com"); - await new DNSListener("bar.example.com", "127.0.0.1"); + await new DNSListener("bar.example.com", "3.3.3.3"); }); // verify that the name was put in cache - it works with bad DNS URI @@ -128,24 +128,24 @@ add_task(async function test2() { Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/404`); - await new DNSListener("bar.example.com", "127.0.0.1"); + await new DNSListener("bar.example.com", "3.3.3.3"); }); // verify working credentials in DOH request add_task(async function test3() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-auth`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=4.4.4.4&auth=true`); Services.prefs.setCharPref("network.trr.credentials", "user:password"); - await new DNSListener("bar.example.com", "127.0.0.1"); + await new DNSListener("bar.example.com", "4.4.4.4"); }); // verify failing credentials in DOH request add_task(async function test4() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-auth`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=4.4.4.4&auth=true`); Services.prefs.setCharPref("network.trr.credentials", "evil:person"); let [, , inStatus] = await new DNSListener("wrong.example.com", undefined, false); @@ -156,9 +156,9 @@ add_task(async function test4() { add_task(async function test5() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-push`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=5.5.5.5&push=true`); - await new DNSListener("first.example.com", "127.0.0.1"); + await new DNSListener("first.example.com", "5.5.5.5"); }); add_task(async function test5b() { @@ -175,7 +175,7 @@ add_task(async function test5b() { add_task(async function test6() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-aaaa`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=2020:2020::2020`); await new DNSListener("aaaa.example.com", "2020:2020::2020"); }); @@ -183,7 +183,7 @@ add_task(async function test6() { add_task(async function test7() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-rfc1918`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=192.168.0.1`); let [, , inStatus] = await new DNSListener("rfc1918.example.com", undefined, false); Assert.ok(!Components.isSuccessCode(inStatus), `${inStatus} should be an error code`); }); @@ -192,7 +192,7 @@ add_task(async function test7() { add_task(async function test8() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-rfc1918`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=192.168.0.1`); Services.prefs.setBoolPref("network.trr.allow-rfc1918", true); await new DNSListener("rfc1918.example.com", "192.168.0.1"); }); @@ -202,7 +202,7 @@ add_task(async function test8() { add_task(async function test8b() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-ecs{?dns}`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh{?dns}`); Services.prefs.clearUserPref("network.trr.allow-rfc1918"); Services.prefs.setBoolPref("network.trr.useGET", true); Services.prefs.setBoolPref("network.trr.disable-ECS", true); @@ -213,11 +213,11 @@ add_task(async function test8b() { add_task(async function test9() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-get`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh`); Services.prefs.clearUserPref("network.trr.allow-rfc1918"); Services.prefs.setBoolPref("network.trr.useGET", true); Services.prefs.setBoolPref("network.trr.disable-ECS", false); - await new DNSListener("get.example.com", "1.2.3.4"); + await new DNSListener("get.example.com", "5.5.5.5"); }); // confirmationNS set without confirmed NS yet @@ -362,8 +362,8 @@ add_task(async function test21() { await new DNSListener("test21.example.com", "127.0.0.1"); }); -// verify that basic A record name mismatch gets rejected. Gets the same DOH -// response back as test1 +// verify that basic A record name mismatch gets rejected. +// Gets a response for bar.example.com instead of what it requested add_task(async function test22() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only to avoid native fallback @@ -385,7 +385,7 @@ add_task(async function test24() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 2); // TRR-first Services.prefs.setCharPref("network.trr.excluded-domains", ""); - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-ip`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=192.192.192.192`); await new DNSListener("bar.example.com", "192.192.192.192"); }); @@ -403,15 +403,15 @@ add_task(async function test24c() { await new DNSListener("bar.example.com", "127.0.0.1"); }); -// TRR-only check that localhost doesn't work if not in the excluded-domains list +// TRR-only that resolving localhost with TRR-only mode will use the remote +// resolver if it's not in the excluded domains add_task(async function test25() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only Services.prefs.setCharPref("network.trr.excluded-domains", ""); - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-ip`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=192.192.192.192`); - let [, , inStatus] = await new DNSListener("localhost", "127.0.0.1", false); - Assert.ok(!Components.isSuccessCode(inStatus), `${inStatus} should be an error code`); + await new DNSListener("localhost", "192.192.192.192", true); }); // TRR-only check that localhost goes directly to native lookup when in the excluded-domains @@ -419,7 +419,7 @@ add_task(async function test25b() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only Services.prefs.setCharPref("network.trr.excluded-domains", "localhost"); - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-ip`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=192.192.192.192`); await new DNSListener("localhost", "127.0.0.1"); }); @@ -429,7 +429,7 @@ add_task(async function test25c() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only Services.prefs.setCharPref("network.trr.excluded-domains", "localhost,local"); - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-ip`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=192.192.192.192`); await new DNSListener("test.local", "127.0.0.1"); }); @@ -439,7 +439,7 @@ add_task(async function test25d() { dns.clearCache(true); Services.prefs.setIntPref("network.trr.mode", 3); // TRR-only Services.prefs.setCharPref("network.trr.excluded-domains", "localhost,local,other"); - Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/dns-ip`); + Services.prefs.setCharPref("network.trr.uri", `https://foo.example.com:${h2Port}/doh?responseIP=192.192.192.192`); await new DNSListener("domain.other", "127.0.0.1"); }); diff --git a/testing/xpcshell/moz-http2/moz-http2.js b/testing/xpcshell/moz-http2/moz-http2.js index 2511615ff7b8..9d2f0c33b665 100644 --- a/testing/xpcshell/moz-http2/moz-http2.js +++ b/testing/xpcshell/moz-http2/moz-http2.js @@ -13,6 +13,8 @@ var http2 = require(node_http2_root); var fs = require('fs'); var url = require('url'); var crypto = require('crypto'); +const dnsPacket = require('../dns-packet'); +const ip = require('../node-ip'); // Hook into the decompression code to log the decompressed name-value pairs var compression_module = node_http2_root + "/lib/protocol/compressor"; @@ -550,6 +552,97 @@ function handleRequest(req, res) { return; } + else if (u.pathname == "/doh") { + ns_confirm = 0; // back to first reply for dns-confirm + cname_confirm = 0; // back to first reply for dns-cname + + let params = new url.URL(`http://localhost${req.url}`).searchParams; + let responseIP = params.get("responseIP"); + if (!responseIP) { + responseIP = "5.5.5.5"; + } + + if (params.get("auth")) { + // There's a Set-Cookie: header in the response for "/dns" , which this + // request subsequently would include if the http channel wasn't + // anonymous. Thus, if there's a cookie in this request, we know Firefox + // mishaved. If there's not, we're fine. + if (req.headers['cookie']) { + res.writeHead(403); + res.end("cookie for me, not for you"); + return; + } + if (req.headers['authorization'] != "user:password") { + res.writeHead(401); + res.end("bad boy!"); + return; + } + } + + if (params.get("push")) { + // push.example.com has AAAA entry 2018::2018 + var pcontent= new Buffer("0000010000010001000000000470757368076578616D706C6503636F6D00001C0001C00C001C000100000037001020180000000000000000000000002018", "hex"); + push = res.push({ + hostname: 'foo.example.com:' + serverPort, + port: serverPort, + path: '/dns-pushed-response?dns=AAAAAAABAAAAAAAABHB1c2gHZXhhbXBsZQNjb20AABwAAQ', + method: 'GET', + headers: { + 'accept' : 'application/dns-message' + } + }); + push.writeHead(200, { + 'content-type': 'application/dns-message', + 'pushed' : 'yes', + 'content-length' : pcontent.length, + 'X-Connection-Http2': 'yes' + }); + push.end(pcontent); + } + + let payload = new Buffer(""); + + function emitResponse(response, requestPayload) { + let packet = dnsPacket.decode(requestPayload); + + let buf = dnsPacket.encode({ + type: 'query', + id: packet.id, + flags: dnsPacket.RECURSION_DESIRED, + questions: packet.questions, + answers: [{ + name: packet.questions[0].name, + ttl: 55, + type: ip.isV4Format(responseIP) ? "A" : "AAAA", + flush: false, + data: responseIP, + }], + }); + + response.setHeader('Content-Length', buf.length); + response.setHeader('Set-Cookie', 'trackyou=yes; path=/; max-age=100000;'); + response.setHeader('Content-Type', 'application/dns-message'); + response.writeHead(200); + response.write(buf); + response.end(""); + return; + } + + if (params.get("dns")) { + payload = Buffer.from(params.get("dns"), 'base64'); + emitResponse(res, payload); + return; + } + + req.on('data', function receiveData(chunk) { + payload = Buffer.concat([payload, chunk]); + }); + req.on('end', function finishedData() { + emitResponse(res, payload); + return; + }); + return; + } else if (u.pathname === "/dns-cname-a") { // test23 asks for cname-a.example.com // this responds with a CNAME to here.example.com *and* an A record @@ -603,57 +696,6 @@ function handleRequest(req, res) { res.end(""); return; - } - // for use with test_trr.js, test8b - else if (u.path === "/dns-ecs?dns=AAABAAABAAAAAAABA2VjcwdleGFtcGxlA2NvbQAAAQABAAApEAAAAAAAAAgACAAEAAEAAA") { - // the query string asks for an A entry for ecs.example.com - // ecs.example.com has A entry 5.5.5.5 - var content= new Buffer("00000100000100010000000003656373076578616D706C6503636F6D0000010001C00C0001000100000037000405050505", "hex"); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - res.writeHead(200); - res.write(content); - res.end(""); - return; - } - // for use with test_trr.js - else if (u.path === "/dns-get?dns=AAABAAABAAAAAAAAA2dldAdleGFtcGxlA2NvbQAAAQAB") { - // the query string asks for an A entry for get.example.com - // get.example.com has A entry 1.2.3.4 - var content= new Buffer("00000100000100010000000003676574076578616D706C6503636F6D0000010001C00C0001000100000037000401020304", "hex"); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - res.writeHead(200); - res.write(content); - res.end(""); - ns_confirm = 0; // back to first reply for dns-confirm - cname_confirm = 0; // back to first reply for dns-cname - return; - } - // for use with test_trr.js - else if (u.pathname === "/dns") { - // bar.example.com has A entry 127.0.0.1 - var content= new Buffer("00000100000100010000000003626172076578616D706C6503636F6D0000010001C00C000100010000003700047F000001", "hex"); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - // pass back a cookie here, check it in /dns-auth - res.setHeader('Set-Cookie', 'trackyou=yes; path=/; max-age=100000;'); - res.writeHead(200); - res.write(content); - res.end(""); - return; - } - else if (u.pathname === "/dns-ip") { - // bar.example.com has A entry 192.192.192.192 - var content= new Buffer("00000100000100010000000003626172076578616D706C6503636F6D0000010001C00C00010001000000370004C0C0C0C0", "hex"); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - // pass back a cookie here, check it in /dns-auth - res.setHeader('Set-Cookie', 'trackyou=yes; path=/; max-age=100000;'); - res.writeHead(200); - res.write(content); - res.end(""); - return; } else if (u.pathname === "/dns-ns") { // confirm.example.com has NS entry ns.example.com @@ -694,82 +736,6 @@ function handleRequest(req, res) { res.end(""); return; } - // for use with test_trr.js - else if (u.pathname === "/dns-aaaa") { - // aaaa.example.com has AAAA entry 2020:2020::2020 - var content= new Buffer("0000010000010001000000000461616161076578616D706C6503636F6D00001C0001C00C001C000100000037001020202020000000000000000000002020", "hex"); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - res.writeHead(200); - res.write(content); - res.end(""); - return; - } - else if (u.pathname === "/dns-rfc1918") { - // rfc1918.example.com has A entry 192.168.0.1 - var content= new Buffer("0000010000010001000000000772666331393138076578616D706C6503636F6D0000010001C00C00010001000000370004C0A80001", "hex"); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - res.writeHead(200); - res.write(content); - res.end(""); - return; - } - // for use with test_trr.js - else if (u.pathname === "/dns-push") { - // first.example.com has A entry 127.0.0.1 - var content= new Buffer("000001000001000100000000056669727374076578616D706C6503636F6D0000010001C00C000100010000003700047F000001", "hex"); - // push.example.com has AAAA entry 2018::2018 - var pcontent= new Buffer("0000010000010001000000000470757368076578616D706C6503636F6D00001C0001C00C001C000100000037001020180000000000000000000000002018", "hex"); - push = res.push({ - hostname: 'foo.example.com:' + serverPort, - port: serverPort, - path: '/dns-pushed-response?dns=AAAAAAABAAAAAAAABHB1c2gHZXhhbXBsZQNjb20AABwAAQ', - method: 'GET', - headers: { - 'accept' : 'application/dns-message' - } - }); - push.writeHead(200, { - 'content-type': 'application/dns-message', - 'pushed' : 'yes', - 'content-length' : pcontent.length, - 'X-Connection-Http2': 'yes' - }); - push.end(pcontent); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - res.writeHead(200); - res.write(content); - res.end(""); - return; - } - // for use with test_trr.js - else if (u.pathname === "/dns-auth") { - // There's a Set-Cookie: header in the response for "/dns" , which this - // request subsequently would include if the http channel wasn't - // anonymous. Thus, if there's a cookie in this request, we know Firefox - // mishaved. If there's not, we're fine. - if (req.headers['cookie']) { - res.writeHead(403); - res.end("cookie for me, not for you"); - return; - } - if (req.headers['authorization'] != "user:password") { - res.writeHead(401); - res.end("bad boy!"); - return; - } - // bar.example.com has A entry 127.0.0.1 - var content= new Buffer("00000100000100010000000003626172076578616D706C6503636F6D0000010001C00C000100010000003700047F000001", "hex"); - res.setHeader('Content-Type', 'application/dns-message'); - res.setHeader('Content-Length', content.length); - res.writeHead(200); - res.write(content); - res.end(""); - return; - } - // for use with test_esni_dns_fetch.js else if (u.pathname === "/esni-dns") { content = new Buffer("0000" +