Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0b1a8b69a | ||
|
|
2d2a5dc860 | ||
|
|
6bf3a30585 | ||
|
|
8cfeb973a4 | ||
|
|
0dc43a0a1f | ||
|
|
24d9677c0f |
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
options {
|
||||
update-ds { 192.168.1.2; };
|
||||
};
|
||||
|
||||
zone "example.net" {
|
||||
type primary;
|
||||
file "example.net.db";
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone "example.net" {
|
||||
type primary;
|
||||
file "example.net.db";
|
||||
update-ds { 192.168.1.1; };
|
||||
update-ds { 192.168.1.1; };
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone "example.net" {
|
||||
type primary;
|
||||
file "example.net.db";
|
||||
update-ds { };
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
zone "." {
|
||||
type mirror;
|
||||
file "root.mirror";
|
||||
update-ds { 192.168.1.1; };
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
parental-agents "com" {
|
||||
192.168.1.2;
|
||||
};
|
||||
|
||||
zone "example.net" {
|
||||
type primary;
|
||||
file "example.net.db";
|
||||
update-ds { "net"; };
|
||||
};
|
||||
@@ -188,6 +188,9 @@ view "fourth" {
|
||||
1.2.3.4;
|
||||
1.2.3.5;
|
||||
};
|
||||
update-ds {
|
||||
"parents";
|
||||
};
|
||||
dnssec-policy "test";
|
||||
parental-source 10.10.10.10 port 53 dscp 55;
|
||||
};
|
||||
@@ -198,6 +201,10 @@ view "fourth" {
|
||||
parental-agents {
|
||||
"parents";
|
||||
};
|
||||
update-ds {
|
||||
1.2.3.4;
|
||||
1.2.3.5;
|
||||
};
|
||||
dnssec-policy "default";
|
||||
};
|
||||
zone "dnssec-inherit" {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
set -e
|
||||
|
||||
rm -f dig.out*
|
||||
rm -f ns*/named.conf ns*/named.memstats ns*/named.run*
|
||||
rm -f ns*/*.jnl ns*/*.jbk
|
||||
rm -f ns*/K*.private ns*/K*.key ns*/K*.state
|
||||
rm -f ns*/dsset-*
|
||||
rm -f ns*/*.db ns*/*.jnl ns*/*.jbk ns*/*.db.signed ns*/*.db.infile
|
||||
rm -f ns*/keygen.out.* ns*/settime.out.* ns*/signer.out.*
|
||||
rm -f ns*/managed-keys.bind*
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
// NS2
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.2;
|
||||
notify-source 10.53.0.2;
|
||||
transfer-source 10.53.0.2;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.2; };
|
||||
listen-on-v6 { none; };
|
||||
allow-transfer { any; };
|
||||
recursion no;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "../../common/root.hint";
|
||||
};
|
||||
|
||||
zone "updateds" {
|
||||
type primary;
|
||||
file "updateds.db";
|
||||
dnssec-policy yes;
|
||||
allow-update { any; };
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. ../../conf.sh
|
||||
|
||||
echo_i "ns2/setup.sh"
|
||||
|
||||
for subdomain in dspublish dswithdraw rollover
|
||||
do
|
||||
cp "../ns9/dsset-$subdomain.updateds." .
|
||||
done
|
||||
|
||||
zone="updateds"
|
||||
infile="updateds.db.infile"
|
||||
zonefile="updateds.db"
|
||||
|
||||
CSK=$($KEYGEN -k default $zone 2> keygen.out.$zone)
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||
$SIGNER -S -g -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone 2>&1
|
||||
@@ -0,0 +1,26 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA secondary.example. hostmaster.example. (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns2
|
||||
ns2 A 10.53.0.2
|
||||
|
||||
dspublish NS ns9.dspublish
|
||||
dswithdraw NS ns9.dswithdraw
|
||||
rollover NS ns9.rollover
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
// NS9
|
||||
|
||||
options {
|
||||
query-source address 10.53.0.9;
|
||||
notify-source 10.53.0.9;
|
||||
transfer-source 10.53.0.9;
|
||||
port @PORT@;
|
||||
pid-file "named.pid";
|
||||
listen-on { 10.53.0.9; };
|
||||
listen-on-v6 { none; };
|
||||
allow-transfer { any; };
|
||||
recursion no;
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm hmac-sha256;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.9 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
||||
parental-agents "ns2" port @PORT@ {
|
||||
10.53.0.2;
|
||||
};
|
||||
|
||||
zone "." {
|
||||
type hint;
|
||||
file "../../common/root.hint";
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone with parental agent configured, time to submit the DS.
|
||||
*/
|
||||
zone "dspublish.updateds" {
|
||||
type primary;
|
||||
file "dspublish.updateds.db";
|
||||
dnssec-policy "default";
|
||||
parental-agents { "ns2"; };
|
||||
update-ds { "ns2"; };
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone with parental agent configured, time to withdraw the DS.
|
||||
*/
|
||||
zone "dswithdraw.updateds" {
|
||||
type primary;
|
||||
file "dswithdraw.updateds.db";
|
||||
dnssec-policy "insecure";
|
||||
parental-agents { "ns2"; };
|
||||
update-ds { "ns2" };
|
||||
};
|
||||
|
||||
/*
|
||||
* Zone with parental agent configured, time to update the DS (rollover).
|
||||
*/
|
||||
zone "rollover.updateds" {
|
||||
type primary;
|
||||
file "rollover.updateds.db";
|
||||
dnssec-policy "default";
|
||||
parental-agents { "ns2"; };
|
||||
update-ds { "ns2" };
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. ../../conf.sh
|
||||
|
||||
echo_i "ns9/setup.sh"
|
||||
|
||||
setup() {
|
||||
zone="$1"
|
||||
echo_i "setting up zone: $zone"
|
||||
zonefile="${zone}.db"
|
||||
infile="${zone}.db.infile"
|
||||
echo "$zone" >> zones
|
||||
}
|
||||
|
||||
# Short environment variable names for key states and times.
|
||||
H="HIDDEN"
|
||||
R="RUMOURED"
|
||||
O="OMNIPRESENT"
|
||||
U="UNRETENTIVE"
|
||||
T="now-30d"
|
||||
Y="now-1y"
|
||||
|
||||
setup "dspublish.updateds"
|
||||
cp template.db.in "$zonefile"
|
||||
keytimes="-P $T -P sync $T -A $T"
|
||||
CSK=$($KEYGEN -k default $keytimes $zone 2> keygen.out.$zone)
|
||||
$SETTIME -s -g $O -k $O $T -r $O $T -z $O $T -d $H $T "$CSK" > settime.out.$zone 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
setup "dswithdraw.updateds"
|
||||
cp template.db.in "$zonefile"
|
||||
keytimes="-P $Y -P sync $Y -A $Y"
|
||||
CSK=$($KEYGEN -k default $keytimes $zone 2> keygen.out.$zone)
|
||||
$SETTIME -s -g $H -k $O $T -r $O $T -z $O $T -d $O $T "$CSK" > settime.out.$zone 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
|
||||
# TODO
|
||||
setup "rollover.updateds"
|
||||
cp template.db.in "$zonefile"
|
||||
keytimes="-P $Y -P sync $Y -A $Y"
|
||||
CSK=$($KEYGEN -k default $keytimes $zone 2> keygen.out.$zone)
|
||||
$SETTIME -s -g $H -k $O $T -r $O $T -z $O $T -d $U $T "$CSK" > settime.out.$zone 2>&1
|
||||
cat template.db.in "${CSK}.key" > "$infile"
|
||||
private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >> "$infile"
|
||||
$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O full -f $zonefile $infile > signer.out.$zone.1 2>&1
|
||||
@@ -0,0 +1,27 @@
|
||||
; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
;
|
||||
; SPDX-License-Identifier: MPL-2.0
|
||||
;
|
||||
; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
; file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
;
|
||||
; See the COPYRIGHT file distributed with this work for additional
|
||||
; information regarding copyright ownership.
|
||||
|
||||
$TTL 300
|
||||
@ IN SOA mname1. . (
|
||||
1 ; serial
|
||||
20 ; refresh (20 seconds)
|
||||
20 ; retry (20 seconds)
|
||||
1814400 ; expire (3 weeks)
|
||||
3600 ; minimum (1 hour)
|
||||
)
|
||||
|
||||
NS ns9
|
||||
ns9 A 10.53.0.9
|
||||
|
||||
a A 10.0.0.1
|
||||
b A 10.0.0.2
|
||||
c A 10.0.0.3
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh -e
|
||||
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
# shellcheck source=conf.sh
|
||||
. ../conf.sh
|
||||
|
||||
set -e
|
||||
|
||||
$SHELL clean.sh
|
||||
|
||||
copy_setports ns2/named.conf.in ns2/named.conf
|
||||
copy_setports ns9/named.conf.in ns9/named.conf
|
||||
|
||||
# Setup zones
|
||||
(
|
||||
cd ns9
|
||||
$SHELL setup.sh
|
||||
)
|
||||
(
|
||||
cd ns2
|
||||
$SHELL setup.sh
|
||||
)
|
||||
Executable
+277
@@ -0,0 +1,277 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
#
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
#
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
#
|
||||
# See the COPYRIGHT file distributed with this work for additional
|
||||
# information regarding copyright ownership.
|
||||
|
||||
import mmap
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
pytest.importorskip("dns", minversion="2.0.0")
|
||||
import dns.exception
|
||||
import dns.message
|
||||
import dns.name
|
||||
import dns.query
|
||||
import dns.rcode
|
||||
import dns.rdataclass
|
||||
import dns.rdatatype
|
||||
import dns.resolver
|
||||
|
||||
|
||||
def has_signed_apex_nsec(zone, response):
|
||||
has_nsec = False
|
||||
has_rrsig = False
|
||||
|
||||
ttl = 300
|
||||
nextname = "a."
|
||||
types = "NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY"
|
||||
match = "{0} {1} IN NSEC {2}{0} {3}".format(zone, ttl, nextname, types)
|
||||
sig = "{0} {1} IN RRSIG NSEC 13 2 300".format(zone, ttl)
|
||||
|
||||
for rr in response.answer:
|
||||
if match in rr.to_text():
|
||||
has_nsec = True
|
||||
if sig in rr.to_text():
|
||||
has_rrsig = True
|
||||
|
||||
if not has_nsec:
|
||||
print("error: missing apex NSEC record in response")
|
||||
if not has_rrsig:
|
||||
print("error: missing NSEC signature in response")
|
||||
|
||||
return has_nsec and has_rrsig
|
||||
|
||||
|
||||
def do_query(server, qname, qtype, tcp=False):
|
||||
query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True)
|
||||
try:
|
||||
if tcp:
|
||||
response = dns.query.tcp(
|
||||
query, server.nameservers[0], timeout=3, port=server.port
|
||||
)
|
||||
else:
|
||||
response = dns.query.udp(
|
||||
query, server.nameservers[0], timeout=3, port=server.port
|
||||
)
|
||||
except dns.exception.Timeout:
|
||||
print(
|
||||
"error: query timeout for query {} {} to {}".format(
|
||||
qname, qtype, server.nameservers[0]
|
||||
)
|
||||
)
|
||||
return None
|
||||
|
||||
return response
|
||||
|
||||
|
||||
def verify_zone(zone, transfer):
|
||||
verify = os.getenv("VERIFY")
|
||||
assert verify is not None
|
||||
|
||||
filename = "{}out".format(zone)
|
||||
with open(filename, "w", encoding="utf-8") as file:
|
||||
for rr in transfer.answer:
|
||||
file.write(rr.to_text())
|
||||
file.write("\n")
|
||||
|
||||
# dnssec-verify command with default arguments.
|
||||
verify_cmd = [verify, "-z", "-o", zone, filename]
|
||||
|
||||
verifier = subprocess.run(verify_cmd, capture_output=True, check=True)
|
||||
|
||||
if verifier.returncode != 0:
|
||||
print("error: dnssec-verify {} failed".format(zone))
|
||||
sys.stderr.buffer.write(verifier.stderr)
|
||||
|
||||
return verifier.returncode == 0
|
||||
|
||||
|
||||
def read_statefile(server, zone):
|
||||
addr = server.nameservers[0]
|
||||
count = 0
|
||||
keyid = 0
|
||||
state = {}
|
||||
|
||||
response = do_query(server, zone, "DS", tcp=True)
|
||||
if not isinstance(response, dns.message.Message):
|
||||
print("error: no response for {} DS from {}".format(zone, addr))
|
||||
return {}
|
||||
|
||||
if response.rcode() == dns.rcode.NOERROR:
|
||||
# fetch key id from response.
|
||||
for rr in response.answer:
|
||||
if rr.match(
|
||||
dns.name.from_text(zone),
|
||||
dns.rdataclass.IN,
|
||||
dns.rdatatype.DS,
|
||||
dns.rdatatype.NONE,
|
||||
):
|
||||
if count == 0:
|
||||
keyid = list(dict(rr.items).items())[0][0].key_tag
|
||||
count += 1
|
||||
|
||||
if count != 1:
|
||||
print(
|
||||
"error: expected a single DS in response for {} from {},"
|
||||
"got {}".format(zone, addr, count)
|
||||
)
|
||||
return {}
|
||||
else:
|
||||
print(
|
||||
"error: {} response for {} DNSKEY from {}".format(
|
||||
dns.rcode.to_text(response.rcode()), zone, addr
|
||||
)
|
||||
)
|
||||
return {}
|
||||
|
||||
filename = "ns9/K{}+013+{:05d}.state".format(zone, keyid)
|
||||
print("read state file {}".format(filename))
|
||||
|
||||
try:
|
||||
with open(filename, "r", encoding="utf-8") as file:
|
||||
for line in file:
|
||||
if line.startswith(";"):
|
||||
continue
|
||||
key, val = line.strip().split(":", 1)
|
||||
state[key.strip()] = val.strip()
|
||||
|
||||
except FileNotFoundError:
|
||||
# file may not be written just yet.
|
||||
return {}
|
||||
|
||||
return state
|
||||
|
||||
|
||||
def zone_check(server, zone):
|
||||
addr = server.nameservers[0]
|
||||
|
||||
# wait until zone is fully signed.
|
||||
signed = False
|
||||
for _ in range(10):
|
||||
response = do_query(server, zone, "NSEC")
|
||||
if not isinstance(response, dns.message.Message):
|
||||
print("error: no response for {} NSEC from {}".format(zone, addr))
|
||||
elif response.rcode() == dns.rcode.NOERROR:
|
||||
signed = has_signed_apex_nsec(zone, response)
|
||||
else:
|
||||
print(
|
||||
"error: {} response for {} NSEC from {}".format(
|
||||
dns.rcode.to_text(response.rcode()), zone, addr
|
||||
)
|
||||
)
|
||||
|
||||
if signed:
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
assert signed
|
||||
|
||||
# check if zone if DNSSEC valid.
|
||||
verified = False
|
||||
transfer = do_query(server, zone, "AXFR", tcp=True)
|
||||
if not isinstance(transfer, dns.message.Message):
|
||||
print("error: no response for {} AXFR from {}".format(zone, addr))
|
||||
elif transfer.rcode() == dns.rcode.NOERROR:
|
||||
verified = verify_zone(zone, transfer)
|
||||
else:
|
||||
print(
|
||||
"error: {} response for {} AXFR from {}".format(
|
||||
dns.rcode.to_text(transfer.rcode()), zone, addr
|
||||
)
|
||||
)
|
||||
|
||||
assert verified
|
||||
|
||||
|
||||
def keystate_check(server, zone, key):
|
||||
val = 0
|
||||
deny = False
|
||||
|
||||
search = key
|
||||
if key.startswith("!"):
|
||||
deny = True
|
||||
search = key[1:]
|
||||
|
||||
for _ in range(10):
|
||||
state = read_statefile(server, zone)
|
||||
try:
|
||||
val = state[search]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
if not deny and val != 0:
|
||||
break
|
||||
if deny and val == 0:
|
||||
break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
if deny:
|
||||
assert val == 0
|
||||
else:
|
||||
assert val != 0
|
||||
|
||||
|
||||
def wait_for_log(filename, log):
|
||||
found = False
|
||||
|
||||
for _ in range(10):
|
||||
print("read log file {}".format(filename))
|
||||
|
||||
try:
|
||||
with open(filename, "r", encoding="utf-8") as file:
|
||||
s = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
|
||||
if s.find(bytes(log, "ascii")) != -1:
|
||||
found = True
|
||||
except FileNotFoundError:
|
||||
print("file not found {}".format(filename))
|
||||
|
||||
if found:
|
||||
break
|
||||
|
||||
print("sleep")
|
||||
time.sleep(1)
|
||||
|
||||
assert found
|
||||
|
||||
|
||||
def test_updateds_publishds(named_port):
|
||||
# Create resolver instances that will be used to send queries.
|
||||
server = dns.resolver.Resolver()
|
||||
server.nameservers = ["10.53.0.9"]
|
||||
server.port = named_port
|
||||
|
||||
parent = dns.resolver.Resolver()
|
||||
parent.nameservers = ["10.53.0.2"]
|
||||
parent.port = named_port
|
||||
|
||||
# DS published in parent.
|
||||
parent_check(parent, "publishds.updateds.")
|
||||
|
||||
def test_updateds_withdrawds(named_port):
|
||||
# We create resolver instances that will be used to send queries.
|
||||
server = dns.resolver.Resolver()
|
||||
server.nameservers = ["10.53.0.9"]
|
||||
server.port = named_port
|
||||
|
||||
parent = dns.resolver.Resolver()
|
||||
parent.nameservers = ["10.53.0.2"]
|
||||
parent.port = named_port
|
||||
|
||||
# DS removed from parent.
|
||||
parent_check(parent, "withdrawds.updateds.")
|
||||
|
||||
# TBD: Key event does not change DS at the parent.
|
||||
@@ -400,7 +400,7 @@ The following blocks are supported:
|
||||
Controls global server configuration options and sets defaults for other statements.
|
||||
|
||||
:any:`parental-agents`
|
||||
Defines a named list of servers for inclusion in primary and secondary zones' :any:`parental-agents` lists.
|
||||
Defines a named list of servers for inclusion in primary and secondary zones' ``parental-agents`` or ``update-ds`` lists.
|
||||
|
||||
:any:`primaries`
|
||||
Defines a named list of servers for inclusion in stub and secondary zones' :any:`primaries` or :any:`also-notify` lists. (Note: this is a synonym for the original keyword ``masters``, which can still be used, but is no longer the preferred terminology.)
|
||||
@@ -7298,6 +7298,12 @@ Zone Options
|
||||
:any:`dnssec-secure-to-insecure`
|
||||
See the description of :any:`dnssec-secure-to-insecure` in :ref:`boolean_options`.
|
||||
|
||||
``update-ds``
|
||||
Defines a named list of servers that will be used to send dynamic
|
||||
updates to. When the zone is configured with a ``dnssec-policy``,
|
||||
BIND will try to update the DS RRset at these servers during a key
|
||||
rollover.
|
||||
|
||||
.. _dynamic_update_policies:
|
||||
|
||||
Dynamic Update Policies
|
||||
|
||||
@@ -720,6 +720,7 @@ zone <string> [ <class> ] {
|
||||
sig\-signing\-type <integer>;
|
||||
sig\-validity\-interval <integer> [ <integer> ];
|
||||
update\-check\-ksk <boolean>;
|
||||
update\-ds [ port <integer> ] [ dscp <integer> ] { ( <remote\-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||
update\-policy ( local | { ( deny | grant ) <string> ( 6to4\-self | external | krb5\-self | krb5\-selfsub | krb5\-subdomain | krb5\-subdomain\-self\-rhs | ms\-self | ms\-selfsub | ms\-subdomain | ms\-subdomain\-self\-rhs | name | self | selfsub | selfwild | subdomain | tcp\-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
||||
zero\-no\-soa\-ttl <boolean>;
|
||||
zone\-statistics ( full | terse | none | <boolean> );
|
||||
@@ -795,6 +796,7 @@ zone <string> [ <class> ] {
|
||||
transfer\-source\-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
||||
try\-tcp\-refresh <boolean>;
|
||||
update\-check\-ksk <boolean>;
|
||||
update\-ds [ port <integer> ] [ dscp <integer> ] { ( <remote\-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||
use\-alt\-transfer\-source <boolean>;
|
||||
zero\-no\-soa\-ttl <boolean>;
|
||||
zone\-statistics ( full | terse | none | <boolean> );
|
||||
|
||||
@@ -56,6 +56,7 @@ zone <string> [ <class> ] {
|
||||
sig-signing-type <integer>;
|
||||
sig-validity-interval <integer> [ <integer> ];
|
||||
update-check-ksk <boolean>;
|
||||
update-ds [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||
update-policy ( local | { ( deny | grant ) <string> ( 6to4-self | external | krb5-self | krb5-selfsub | krb5-subdomain | krb5-subdomain-self-rhs | ms-self | ms-selfsub | ms-subdomain | ms-subdomain-self-rhs | name | self | selfsub | selfwild | subdomain | tcp-self | wildcard | zonesub ) [ <string> ] <rrtypelist>; ... };
|
||||
zero-no-soa-ttl <boolean>;
|
||||
zone-statistics ( full | terse | none | <boolean> );
|
||||
|
||||
@@ -59,6 +59,7 @@ zone <string> [ <class> ] {
|
||||
transfer-source-v6 ( <ipv6_address> | * ) [ port ( <integer> | * ) ] [ dscp <integer> ];
|
||||
try-tcp-refresh <boolean>;
|
||||
update-check-ksk <boolean>;
|
||||
update-ds [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ] [ tls <string> ]; ... };
|
||||
use-alt-transfer-source <boolean>;
|
||||
zero-no-soa-ttl <boolean>;
|
||||
zone-statistics ( full | terse | none | <boolean> );
|
||||
|
||||
+14
-2
@@ -3345,12 +3345,17 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
||||
}
|
||||
|
||||
/*
|
||||
* Primary and secondary zones that have a "parental-agents" field,
|
||||
* must have a corresponding "parental-agents" clause.
|
||||
* Primary and secondary zones that have a "parental-agents" or
|
||||
* "update-ds" field, must have a corresponding "parental-agents"
|
||||
* clause.
|
||||
*/
|
||||
if (ztype == CFG_ZONE_PRIMARY || ztype == CFG_ZONE_SECONDARY) {
|
||||
bool updateds = false;
|
||||
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(zoptions, "parental-agents", &obj);
|
||||
|
||||
check_parentalagents:
|
||||
if (obj != NULL) {
|
||||
uint32_t count;
|
||||
tresult = validate_remotes("parental-agents", obj,
|
||||
@@ -3368,6 +3373,13 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!updateds) {
|
||||
obj = NULL;
|
||||
(void)cfg_map_get(zoptions, "update-ds", &obj);
|
||||
updateds = true;
|
||||
goto check_parentalagents;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -109,6 +109,7 @@ libdns_la_HEADERS = \
|
||||
include/dns/rdatasetiter.h \
|
||||
include/dns/rdataslab.h \
|
||||
include/dns/rdatatype.h \
|
||||
include/dns/remote.h \
|
||||
include/dns/request.h \
|
||||
include/dns/resolver.h \
|
||||
include/dns/result.h \
|
||||
@@ -212,6 +213,7 @@ libdns_la_SOURCES = \
|
||||
rdataset.c \
|
||||
rdatasetiter.c \
|
||||
rdataslab.c \
|
||||
remote.c \
|
||||
request.c \
|
||||
resolver.c \
|
||||
result.c \
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/*! \file dns/remote.h */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <isc/lang.h>
|
||||
#include <isc/mem.h>
|
||||
|
||||
#include <dns/types.h>
|
||||
|
||||
ISC_LANG_BEGINDECLS
|
||||
|
||||
struct dns_remote {
|
||||
isc_mem_t *mctx;
|
||||
isc_sockaddr_t *addresses;
|
||||
isc_dscp_t *dscps;
|
||||
dns_name_t **keynames;
|
||||
dns_name_t **tlsnames;
|
||||
bool *ok;
|
||||
unsigned int addrcnt;
|
||||
unsigned int curraddr;
|
||||
};
|
||||
|
||||
isc_sockaddr_t *
|
||||
dns_remote_addresses(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the addresses of the remote server.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
unsigned int
|
||||
dns_remote_count(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the number of addresses of the remote server.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
dns_name_t **
|
||||
dns_remote_keynames(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the keynames of the remote server.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
dns_name_t **
|
||||
dns_remote_tlsnames(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the tlsnames of the remote server.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_remote_init(dns_remote_t *remote, unsigned int count,
|
||||
const isc_sockaddr_t *addrs, const isc_dscp_t *dscp,
|
||||
dns_name_t **keynames, dns_name_t **tlsnames, bool mark,
|
||||
isc_mem_t *mctx);
|
||||
|
||||
/*%<
|
||||
* Initialize a remote server. Set the provided addresses (addrs),
|
||||
* dscp's (dscp), key names (keynames) and tls names (tlsnames). Use the
|
||||
* provided memory context (mctx) for allocations. If 'mark' is 'true',
|
||||
* set up a list of boolean values to mark the server bad or good.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
* 'mctx' is not NULL.
|
||||
* 'addrs' is not NULL, or 'count' equals zero.
|
||||
* 'keynames' and 'tlsnames' are not NULL, then 'count > 0'.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_remote_clear(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Clear remote server 'remote', free memory.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_remote_equal(dns_remote_t *a, dns_remote_t *b);
|
||||
/*%<
|
||||
* Compare two remote servers 'a' and 'b'. Check if the address
|
||||
* count, the addresses, the dscps, the key names and the tls names are
|
||||
* the same. Return 'true' if so, 'false' otherwise.
|
||||
*
|
||||
* Requires:
|
||||
* 'a' is not NULL and 'b' is not NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_remote_reset(dns_remote_t *remote, bool clear_ok);
|
||||
/*%<
|
||||
* Reset the remote server, set the current address back to the
|
||||
* first. If 'clear_ok' is 'true', clear any servers marked ok.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_remote_next(dns_remote_t *remote, bool skip_good);
|
||||
/*%<
|
||||
* Skip to the next address. If 'skip_good' is 'true', skip over
|
||||
* already addresses already considered good, whatever good means in the
|
||||
* context of this remote server.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
isc_sockaddr_t
|
||||
dns_remote_curraddr(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the currently used address for this remote server.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
'remote->addresses' is not NULL.
|
||||
*/
|
||||
|
||||
isc_sockaddr_t
|
||||
dns_remote_addr(dns_remote_t *remote, unsigned int i);
|
||||
/*%<
|
||||
* Return the address at index 'i'. Returns NULL if we i is equal
|
||||
* or larger than the address count.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
'remote->addresses' is not NULL.
|
||||
*/
|
||||
|
||||
isc_dscp_t
|
||||
dns_remote_dscp(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the current dscp. Returns -1 if we have iterated over all
|
||||
* addresses already, or if dscps are not used.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
dns_name_t *
|
||||
dns_remote_keyname(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the current key name. Returns NULL if we have iterated
|
||||
* over all addresses already, or if keynames are not used.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
dns_name_t *
|
||||
dns_remote_tlsname(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return the current tls name. Returns NULL if we have iterated
|
||||
* over all addresses already, or if tlsnames are not used.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_remote_allgood(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return 'true' if all the addresses are considered good.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_remote_mark(dns_remote_t *remote, bool good);
|
||||
/*%<
|
||||
* Mark the current address 'good' (or not good if 'good' is
|
||||
* 'false').
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
* The current address index is lower than the address count.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_remote_addrok(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return 'true' if the current address is marked good, 'false'
|
||||
* otherwise. Also return 'true' if marking servers is not used.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
* The current address index is lower than the address count.
|
||||
*/
|
||||
|
||||
bool
|
||||
dns_remote_done(dns_remote_t *remote);
|
||||
/*%<
|
||||
* Return 'true' if we iterated over all addresses, 'false' otherwise.
|
||||
*
|
||||
* Requires:
|
||||
* 'remote' is not NULL.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
@@ -128,6 +128,7 @@ typedef struct dns_rdataset dns_rdataset_t;
|
||||
typedef ISC_LIST(dns_rdataset_t) dns_rdatasetlist_t;
|
||||
typedef struct dns_rdatasetiter dns_rdatasetiter_t;
|
||||
typedef uint16_t dns_rdatatype_t;
|
||||
typedef struct dns_remote dns_remote_t;
|
||||
typedef struct dns_request dns_request_t;
|
||||
typedef struct dns_requestmgr dns_requestmgr_t;
|
||||
typedef struct dns_resolver dns_resolver_t;
|
||||
|
||||
@@ -633,7 +633,7 @@ dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
|
||||
dns_zone_setprimaries(dns_zone_t *zone, isc_sockaddr_t *addresses,
|
||||
dns_name_t **keynames, dns_name_t **tlsnames,
|
||||
uint32_t count);
|
||||
/*%<
|
||||
@@ -641,11 +641,11 @@ dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*\li 'primaries' array of isc_sockaddr_t with port set or NULL.
|
||||
*\li 'addresses' array of isc_sockaddr_t with port set or NULL.
|
||||
*\li 'count' the number of primaries.
|
||||
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
|
||||
*
|
||||
*\li If 'primaries' is NULL then 'count' must be zero.
|
||||
*\li If 'addresses' is NULL then 'count' must be zero.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
@@ -654,7 +654,7 @@ dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
|
||||
dns_zone_setparentals(dns_zone_t *zone, isc_sockaddr_t *addresses,
|
||||
dns_name_t **keynames, dns_name_t **tlsnames,
|
||||
uint32_t count);
|
||||
/*%<
|
||||
@@ -662,11 +662,11 @@ dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*\li 'parentals' array of isc_sockaddr_t with port set or NULL.
|
||||
*\li 'addresses' array of isc_sockaddr_t with port set or NULL.
|
||||
*\li 'count' the number of primaries.
|
||||
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
|
||||
*
|
||||
*\li If 'parentals' is NULL then 'count' must be zero.
|
||||
*\li If 'addresses' is NULL then 'count' must be zero.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
@@ -675,29 +675,8 @@ dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
|
||||
dns_name_t **keynames, dns_name_t **tlsnames,
|
||||
uint32_t count);
|
||||
/*%<
|
||||
* Set the list of parental agents for the zone.
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*\li 'parentals' array of isc_sockaddr_t with port set or NULL.
|
||||
*\li 'count' the number of parentals.
|
||||
*\li 'keynames' array of dns_name_t's for tsig keys or NULL.
|
||||
*
|
||||
*\li If 'parentals' is NULL then 'count' must be zero.
|
||||
*
|
||||
* Returns:
|
||||
*\li #ISC_R_SUCCESS
|
||||
*\li #ISC_R_NOMEMORY
|
||||
*\li Any result dns_name_dup() can return, if keynames!=NULL
|
||||
*/
|
||||
|
||||
void
|
||||
dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
|
||||
const isc_dscp_t *dscps, dns_name_t **keynames,
|
||||
dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *addresses,
|
||||
isc_dscp_t *dscps, dns_name_t **keynames,
|
||||
dns_name_t **tlsnames, uint32_t count);
|
||||
/*%<
|
||||
* Set the list of additional servers to be notified when
|
||||
@@ -708,7 +687,7 @@ dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
|
||||
*
|
||||
* Require:
|
||||
*\li 'zone' to be a valid zone.
|
||||
*\li 'notify' to be non-NULL if count != 0.
|
||||
*\li 'addresses' to be non-NULL if count != 0.
|
||||
*\li 'count' to be the number of notifiees.
|
||||
*
|
||||
* Returns:
|
||||
|
||||
@@ -0,0 +1,418 @@
|
||||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/result.h>
|
||||
#include <isc/sockaddr.h>
|
||||
#include <isc/types.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#include <dns/name.h>
|
||||
#include <dns/remote.h>
|
||||
#include <dns/types.h>
|
||||
|
||||
isc_sockaddr_t *
|
||||
dns_remote_addresses(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
return (remote->addresses);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
dns_remote_count(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
return (remote->addrcnt);
|
||||
}
|
||||
|
||||
dns_name_t **
|
||||
dns_remote_keynames(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
return (remote->keynames);
|
||||
}
|
||||
|
||||
dns_name_t **
|
||||
dns_remote_tlsnames(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
return (remote->tlsnames);
|
||||
}
|
||||
|
||||
void
|
||||
dns_remote_init(dns_remote_t *remote, unsigned int count,
|
||||
const isc_sockaddr_t *addrs, const isc_dscp_t *dscp,
|
||||
dns_name_t **keynames, dns_name_t **tlsnames, bool mark,
|
||||
isc_mem_t *mctx) {
|
||||
unsigned int i;
|
||||
|
||||
REQUIRE(remote != NULL);
|
||||
REQUIRE(count == 0 || addrs != NULL);
|
||||
if (keynames != NULL || tlsnames != NULL) {
|
||||
REQUIRE(count != 0);
|
||||
}
|
||||
|
||||
remote->mctx = mctx;
|
||||
|
||||
if (addrs != NULL) {
|
||||
remote->addresses = isc_mem_get(mctx,
|
||||
count * sizeof(isc_sockaddr_t));
|
||||
memmove(remote->addresses, addrs,
|
||||
count * sizeof(isc_sockaddr_t));
|
||||
} else {
|
||||
remote->addresses = NULL;
|
||||
}
|
||||
|
||||
if (dscp != NULL) {
|
||||
remote->dscps = isc_mem_get(mctx, count * sizeof(isc_dscp_t));
|
||||
memmove(remote->dscps, dscp, count * sizeof(isc_dscp_t));
|
||||
} else {
|
||||
remote->dscps = NULL;
|
||||
}
|
||||
|
||||
if (keynames != NULL) {
|
||||
remote->keynames = isc_mem_get(mctx, count * sizeof(keynames));
|
||||
for (i = 0; i < count; i++) {
|
||||
remote->keynames[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (keynames[i] != NULL) {
|
||||
remote->keynames[i] =
|
||||
isc_mem_get(mctx, sizeof(dns_name_t));
|
||||
dns_name_init(remote->keynames[i], NULL);
|
||||
dns_name_dup(keynames[i], mctx,
|
||||
remote->keynames[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
remote->keynames = NULL;
|
||||
}
|
||||
|
||||
if (tlsnames != NULL) {
|
||||
remote->tlsnames = isc_mem_get(mctx, count * sizeof(tlsnames));
|
||||
for (i = 0; i < count; i++) {
|
||||
remote->tlsnames[i] = NULL;
|
||||
}
|
||||
for (i = 0; i < count; i++) {
|
||||
if (tlsnames[i] != NULL) {
|
||||
remote->tlsnames[i] =
|
||||
isc_mem_get(mctx, sizeof(dns_name_t));
|
||||
dns_name_init(remote->tlsnames[i], NULL);
|
||||
dns_name_dup(tlsnames[i], mctx,
|
||||
remote->tlsnames[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
remote->tlsnames = NULL;
|
||||
}
|
||||
|
||||
if (mark) {
|
||||
remote->ok = isc_mem_get(mctx, count * sizeof(bool));
|
||||
for (i = 0; i < count; i++) {
|
||||
remote->ok[i] = false;
|
||||
}
|
||||
} else {
|
||||
remote->ok = NULL;
|
||||
}
|
||||
|
||||
remote->addrcnt = count;
|
||||
remote->curraddr = 0;
|
||||
}
|
||||
|
||||
static bool
|
||||
same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
|
||||
uint32_t count) {
|
||||
unsigned int i;
|
||||
|
||||
if (oldlist == NULL && newlist == NULL) {
|
||||
return (true);
|
||||
}
|
||||
if (oldlist == NULL || newlist == NULL) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
static bool
|
||||
same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist,
|
||||
uint32_t count) {
|
||||
unsigned int i;
|
||||
|
||||
if (oldlist == NULL && newlist == NULL) {
|
||||
return (true);
|
||||
}
|
||||
if (oldlist == NULL || newlist == NULL) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (oldlist[i] == NULL && newlist[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (oldlist[i] == NULL || newlist[i] == NULL ||
|
||||
!dns_name_equal(oldlist[i], newlist[i]))
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
static bool
|
||||
same_dscp(isc_dscp_t *oldlist, isc_dscp_t *newlist, uint32_t count) {
|
||||
unsigned int i;
|
||||
|
||||
if (oldlist == NULL && newlist == NULL) {
|
||||
return (true);
|
||||
}
|
||||
if (oldlist == NULL || newlist == NULL) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (oldlist[i] != newlist[i]) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
void
|
||||
dns_remote_clear(dns_remote_t *remote) {
|
||||
unsigned int count;
|
||||
isc_mem_t *mctx;
|
||||
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
count = remote->addrcnt;
|
||||
mctx = remote->mctx;
|
||||
|
||||
if (mctx == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (remote->ok != NULL) {
|
||||
isc_mem_put(mctx, remote->ok, count * sizeof(bool));
|
||||
remote->ok = NULL;
|
||||
}
|
||||
|
||||
if (remote->addresses != NULL) {
|
||||
isc_mem_put(mctx, remote->addresses,
|
||||
count * sizeof(isc_sockaddr_t));
|
||||
remote->addresses = NULL;
|
||||
}
|
||||
|
||||
if (remote->dscps != NULL) {
|
||||
isc_mem_put(mctx, remote->dscps, count * sizeof(isc_dscp_t));
|
||||
remote->dscps = NULL;
|
||||
}
|
||||
|
||||
if (remote->keynames != NULL) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (remote->keynames[i] != NULL) {
|
||||
dns_name_free(remote->keynames[i], mctx);
|
||||
isc_mem_put(mctx, remote->keynames[i],
|
||||
sizeof(dns_name_t));
|
||||
remote->keynames[i] = NULL;
|
||||
}
|
||||
}
|
||||
isc_mem_put(mctx, remote->keynames,
|
||||
count * sizeof(dns_name_t *));
|
||||
remote->keynames = NULL;
|
||||
}
|
||||
|
||||
if (remote->tlsnames != NULL) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < count; i++) {
|
||||
if (remote->tlsnames[i] != NULL) {
|
||||
dns_name_free(remote->tlsnames[i], mctx);
|
||||
isc_mem_put(mctx, remote->tlsnames[i],
|
||||
sizeof(dns_name_t));
|
||||
remote->tlsnames[i] = NULL;
|
||||
}
|
||||
}
|
||||
isc_mem_put(mctx, remote->tlsnames,
|
||||
count * sizeof(dns_name_t *));
|
||||
remote->tlsnames = NULL;
|
||||
}
|
||||
|
||||
remote->curraddr = 0;
|
||||
remote->addrcnt = 0;
|
||||
remote->mctx = NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
dns_remote_equal(dns_remote_t *a, dns_remote_t *b) {
|
||||
REQUIRE(a != NULL);
|
||||
REQUIRE(b != NULL);
|
||||
|
||||
if (a->addrcnt != b->addrcnt) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (!same_addrs(a->addresses, b->addresses, a->addrcnt)) {
|
||||
return (false);
|
||||
}
|
||||
if (!same_dscp(a->dscps, b->dscps, a->addrcnt)) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
if (!same_names(a->keynames, b->keynames, a->addrcnt)) {
|
||||
return (false);
|
||||
}
|
||||
if (!same_names(a->tlsnames, b->tlsnames, a->addrcnt)) {
|
||||
return (false);
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
void
|
||||
dns_remote_reset(dns_remote_t *remote, bool clear_ok) {
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
remote->curraddr = 0;
|
||||
|
||||
if (clear_ok && remote->ok != NULL) {
|
||||
for (unsigned int i = 0; i < remote->addrcnt; i++) {
|
||||
remote->ok[i] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isc_sockaddr_t
|
||||
dns_remote_curraddr(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
REQUIRE(remote->addresses != NULL);
|
||||
REQUIRE(remote->curraddr < remote->addrcnt);
|
||||
|
||||
return (remote->addresses[remote->curraddr]);
|
||||
}
|
||||
|
||||
isc_sockaddr_t
|
||||
dns_remote_addr(dns_remote_t *remote, unsigned int i) {
|
||||
REQUIRE(remote != NULL);
|
||||
REQUIRE(remote->addresses != NULL);
|
||||
REQUIRE(i < remote->addrcnt);
|
||||
|
||||
return (remote->addresses[i]);
|
||||
}
|
||||
|
||||
isc_dscp_t
|
||||
dns_remote_dscp(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
if (remote->dscps == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (remote->curraddr >= remote->addrcnt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (remote->dscps[remote->curraddr]);
|
||||
}
|
||||
|
||||
dns_name_t *
|
||||
dns_remote_keyname(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
if (remote->keynames == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
if (remote->curraddr >= remote->addrcnt) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (remote->keynames[remote->curraddr]);
|
||||
}
|
||||
|
||||
dns_name_t *
|
||||
dns_remote_tlsname(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
if (remote->tlsnames == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
if (remote->curraddr >= remote->addrcnt) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
return (remote->tlsnames[remote->curraddr]);
|
||||
}
|
||||
|
||||
void
|
||||
dns_remote_next(dns_remote_t *remote, bool skip_good) {
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
skip_to_next:
|
||||
remote->curraddr++;
|
||||
|
||||
if (remote->curraddr >= remote->addrcnt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skip_good && remote->ok != NULL && remote->ok[remote->curraddr]) {
|
||||
goto skip_to_next;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
dns_remote_done(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
return (remote->curraddr >= remote->addrcnt);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_remote_allgood(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
|
||||
if (remote->ok == NULL) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < remote->addrcnt; i++) {
|
||||
if (!remote->ok[i]) {
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
dns_remote_addrok(dns_remote_t *remote) {
|
||||
REQUIRE(remote != NULL);
|
||||
REQUIRE(remote->curraddr < remote->addrcnt);
|
||||
|
||||
if (remote->ok == NULL) {
|
||||
return (true);
|
||||
}
|
||||
|
||||
return (remote->ok[remote->curraddr]);
|
||||
}
|
||||
|
||||
void
|
||||
dns_remote_mark(dns_remote_t *remote, bool good) {
|
||||
REQUIRE(remote != NULL);
|
||||
REQUIRE(remote->curraddr < remote->addrcnt);
|
||||
|
||||
remote->ok[remote->curraddr] = good;
|
||||
}
|
||||
+218
-471
File diff suppressed because it is too large
Load Diff
@@ -2406,6 +2406,8 @@ static cfg_clausedef_t zone_only_clauses[] = {
|
||||
{ "server-addresses", &cfg_type_bracketed_netaddrlist,
|
||||
CFG_ZONE_STATICSTUB },
|
||||
{ "server-names", &cfg_type_namelist, CFG_ZONE_STATICSTUB },
|
||||
{ "update-ds", &cfg_type_namesockaddrkeylist,
|
||||
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY },
|
||||
{ "update-policy", &cfg_type_updatepolicy, CFG_ZONE_PRIMARY },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user