1# Copyright (C) Internet Systems Consortium, Inc. ("ISC") 2# 3# SPDX-License-Identifier: MPL-2.0 4# 5# This Source Code Form is subject to the terms of the Mozilla Public 6# License, v. 2.0. If a copy of the MPL was not distributed with this 7# file, you can obtain one at https://mozilla.org/MPL/2.0/. 8# 9# See the COPYRIGHT file distributed with this work for additional 10# information regarding copyright ownership. 11 12import os 13 14import dns.message 15import dns.zone 16 17import isctest 18 19 20def test_masterfile_include_semantics(): 21 """Test master file $INCLUDE semantics""" 22 msg_axfr = dns.message.make_query("include.", "AXFR") 23 res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1") 24 axfr_include_semantics = """;ANSWER 25include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600 26include. 300 IN NS ns.include. 27a.include. 300 IN A 10.0.0.1 28a.include. 300 IN A 10.0.0.99 29a.a.include. 300 IN A 10.0.1.1 30b.foo.a.include. 300 IN A 10.0.2.2 31b.include. 300 IN A 10.0.0.2 32a.b.include. 300 IN A 10.0.1.1 33c.b.include. 300 IN A 10.0.0.3 34b.foo.b.include. 300 IN A 10.0.2.2 35ns.include. 300 IN A 127.0.0.1 36""" 37 expected = dns.message.from_text(axfr_include_semantics) 38 isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True) 39 40 41def test_masterfile_bind_8_compat_semantics(): 42 """Test master file BIND 8 TTL and $TTL semantics compatibility""" 43 msg_axfr = dns.message.make_query("ttl1.", "AXFR") 44 res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1") 45 axfr_ttl_semantics = """;ANSWER 46ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3 47ttl1. 3 IN NS ns.ttl1. 48a.ttl1. 3 IN TXT "soa minttl 3" 49b.ttl1. 2 IN TXT "explicit ttl 2" 50c.ttl1. 3 IN TXT "soa minttl 3" 51d.ttl1. 1 IN TXT "default ttl 1" 52e.ttl1. 4 IN TXT "explicit ttl 4" 53f.ttl1. 1 IN TXT "default ttl 1" 54ns.ttl1. 3 IN A 10.53.0.1 55""" 56 expected = dns.message.from_text(axfr_ttl_semantics) 57 isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True) 58 59 60def test_masterfile_rfc_1035_semantics(): 61 """Test master file RFC1035 TTL and $TTL semantics""" 62 msg_axfr = dns.message.make_query("ttl2.", "AXFR") 63 res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1") 64 axfr_ttl_semantics = """;ANSWER 65ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3 66ttl2. 1 IN NS ns.ttl2. 67a.ttl2. 1 IN TXT "inherited ttl 1" 68b.ttl2. 2 IN TXT "explicit ttl 2" 69c.ttl2. 2 IN TXT "inherited ttl 2" 70d.ttl2. 3 IN TXT "default ttl 3" 71e.ttl2. 2 IN TXT "explicit ttl 2" 72f.ttl2. 3 IN TXT "default ttl 3" 73ns.ttl2. 1 IN A 10.53.0.1 74""" 75 expected = dns.message.from_text(axfr_ttl_semantics) 76 isctest.check.rrsets_equal(res_axfr.answer, expected.answer, compare_ttl=True) 77 78 79def test_masterfile_missing_master_file(): 80 """Test nameserver running with a missing master file""" 81 msg_soa = dns.message.make_query("example.", "SOA") 82 res_soa = isctest.query.tcp(msg_soa, "10.53.0.2") 83 expected_soa_rr = """;ANSWER 84example. 300 IN SOA mname1. . 2010042407 20 20 1814400 3600 85""" 86 expected = dns.message.from_text(expected_soa_rr) 87 isctest.check.rrsets_equal(res_soa.answer, expected.answer, compare_ttl=True) 88 89 90def test_masterfile_missing_master_file_servfail(): 91 """Test nameserver returning SERVFAIL for a missing master file""" 92 msg_soa = dns.message.make_query("missing.", "SOA") 93 res_soa = isctest.query.tcp(msg_soa, "10.53.0.2") 94 isctest.check.servfail(res_soa) 95 96 97def test_masterfile_owner_inheritance(): 98 """Test owner inheritance after $INCLUDE""" 99 checker_output = isctest.run.cmd( 100 [ 101 os.environ["CHECKZONE"], 102 "-D", 103 "-q", 104 "example", 105 "zone/inheritownerafterinclude.db", 106 ] 107 ).stdout.decode("utf-8") 108 owner_inheritance_zone = """ 109example. 0 IN SOA . . 0 0 0 0 0 110example. 0 IN TXT "this should be at the zone apex" 111example. 0 IN NS . 112""" 113 checker_zone = dns.zone.from_text(checker_output, origin="example.") 114 expected = dns.zone.from_text(owner_inheritance_zone, origin="example.") 115 isctest.check.zones_equal(checker_zone, expected, compare_ttl=True) 116