diff --git a/CHANGES b/CHANGES
index bb7b6c4957..67331ad73c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+4794. [func] "dnssec-checkds -s" specifies a file from which
+ to read a DS set rather than querying the parent.
+ [RT #44667]
+
4793. [bug] nsupdate -[46] could overflow the array of server
addresses. [RT #46402]
@@ -317,8 +321,8 @@
4713. [func] Added support for the DNS Response Policy Service
(DNSRPS) API, which allows named to use an external
response policy daemon when built with
- "configure --enable-dnsrps". Thanks to Vernon
- Schryver and Farsight Security. [RT #43376]
+ "configure --enable-dnsrps". Thanks to Farsight
+ Security. [RT #43376]
4712. [bug] "dig +domain" and "dig +search" didn't retain the
search domain when retrying with TCP. [RT #45547]
diff --git a/bin/python/dnssec-checkds.docbook b/bin/python/dnssec-checkds.docbook
index 91716bc69d..069d6e9952 100644
--- a/bin/python/dnssec-checkds.docbook
+++ b/bin/python/dnssec-checkds.docbook
@@ -42,20 +42,13 @@
dnssec-checkds
-
-
+
+
+
zone
-
- dnssec-dsfromkey
-
-
-
-
- zone
-
DESCRIPTION
@@ -92,6 +85,17 @@
+
+ -s file
+
+
+ Specifies a prepared dsset file, such as would be generated
+ by dnssec-signzone, to use as a source for
+ the DS RRset instead of querying the parent.
+
+
+
+
-d dig path
diff --git a/bin/python/isc/checkds.py.in b/bin/python/isc/checkds.py.in
index ce503558a6..a1615543a4 100644
--- a/bin/python/isc/checkds.py.in
+++ b/bin/python/isc/checkds.py.in
@@ -34,7 +34,11 @@ class SECRR:
if not rrtext:
raise Exception
- fields = rrtext.decode('ascii').split()
+ # 'str' does not have decode method in python3
+ if type(rrtext) is not str:
+ fields = rrtext.decode('ascii').split()
+ else:
+ fields = rrtext.split()
if len(fields) < 7:
raise Exception
@@ -89,35 +93,39 @@ class SECRR:
# Generate a set of expected DS/DLV records from the DNSKEY RRset,
# and report on congruency.
############################################################################
-def check(zone, args, masterfile=None, lookaside=None):
+def check(zone, args):
rrlist = []
- cmd = [args.dig, "+noall", "+answer", "-t", "dlv" if lookaside else "ds",
- "-q", zone + "." + lookaside if lookaside else zone]
- fp, _ = Popen(cmd, stdout=PIPE).communicate()
+ if args.dssetfile:
+ fp = open(args.dssetfile).read()
+ else:
+ cmd = [args.dig, "+noall", "+answer", "-t",
+ "dlv" if args.lookaside else "ds", "-q",
+ zone + "." + args.lookaside if args.lookaside else zone]
+ fp, _ = Popen(cmd, stdout=PIPE).communicate()
for line in fp.splitlines():
- rrlist.append(SECRR(line, lookaside))
+ rrlist.append(SECRR(line, args.lookaside))
rrlist = sorted(rrlist, key=lambda rr: (rr.keyid, rr.keyalg, rr.hashalg))
klist = []
- if masterfile:
- cmd = [args.dsfromkey, "-f", masterfile]
- if lookaside:
- cmd += ["-l", lookaside]
+ if args.masterfile:
+ cmd = [args.dsfromkey, "-f", args.masterfile]
+ if args.lookaside:
+ cmd += ["-l", args.lookaside]
cmd.append(zone)
fp, _ = Popen(cmd, stdout=PIPE).communicate()
else:
intods, _ = Popen([args.dig, "+noall", "+answer", "-t", "dnskey",
"-q", zone], stdout=PIPE).communicate()
cmd = [args.dsfromkey, "-f", "-"]
- if lookaside:
- cmd += ["-l", lookaside]
+ if args.lookaside:
+ cmd += ["-l", args.lookaside]
cmd.append(zone)
fp, _ = Popen(cmd, stdin=PIPE, stdout=PIPE).communicate(intods)
for line in fp.splitlines():
- klist.append(SECRR(line, lookaside))
+ klist.append(SECRR(line, args.lookaside))
if len(klist) < 1:
print("No DNSKEY records found in zone apex")
@@ -136,7 +144,8 @@ def check(zone, args, masterfile=None, lookaside=None):
rr.keyid, SECRR.hashalgs[rr.hashalg]))
if not found:
- print("No %s records were found for any DNSKEY" % ("DLV" if lookaside else "DS"))
+ print("No %s records were found for any DNSKEY" %
+ ("DLV" if args.lookaside else "DS"))
return found
@@ -151,10 +160,6 @@ def parse_args():
sbindir = 'bin' if os.name == 'nt' else 'sbin'
parser.add_argument('zone', type=str, help='zone to check')
- parser.add_argument('-f', '--file', dest='masterfile', type=str,
- help='zone master file')
- parser.add_argument('-l', '--lookaside', dest='lookaside', type=str,
- help='DLV lookaside zone')
parser.add_argument('-d', '--dig', dest='dig',
default=os.path.join(prefix(bindir), 'dig'),
type=str, help='path to \'dig\'')
@@ -162,6 +167,12 @@ def parse_args():
default=os.path.join(prefix(sbindir),
'dnssec-dsfromkey'),
type=str, help='path to \'dig\'')
+ parser.add_argument('-f', '--file', dest='masterfile', type=str,
+ help='zone master file')
+ parser.add_argument('-l', '--lookaside', dest='lookaside', type=str,
+ help='DLV lookaside zone')
+ parser.add_argument('-s', '--dsset', dest='dssetfile', type=str,
+ help='prepared DSset file')
parser.add_argument('-v', '--version', action='version',
version=version)
args = parser.parse_args()
@@ -178,5 +189,5 @@ def parse_args():
############################################################################
def main():
args = parse_args()
- found = check(args.zone, args, args.masterfile, args.lookaside)
+ found = check(args.zone, args)
exit(0 if found else 1)
diff --git a/bin/tests/system/checkds/clean.sh b/bin/tests/system/checkds/clean.sh
index 7cffb4c834..542cba305a 100644
--- a/bin/tests/system/checkds/clean.sh
+++ b/bin/tests/system/checkds/clean.sh
@@ -6,7 +6,5 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-# $Id$
-
rm -f checkds.*
rm -f ns*/named.lock
diff --git a/bin/tests/system/checkds/dig.pl b/bin/tests/system/checkds/dig.pl
index c84801d44f..8a021e3b5f 100644
--- a/bin/tests/system/checkds/dig.pl
+++ b/bin/tests/system/checkds/dig.pl
@@ -6,8 +6,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-# $Id$
-
my $arg;
my $ext;
my $file;
diff --git a/bin/tests/system/checkds/dig.sh b/bin/tests/system/checkds/dig.sh
index 1a98b540fb..746f0a1b1b 100755
--- a/bin/tests/system/checkds/dig.sh
+++ b/bin/tests/system/checkds/dig.sh
@@ -6,9 +6,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-# $Id$
-
-
while [ "$#" != 0 ]; do
case $1 in
+*) shift ;;
diff --git a/bin/tests/system/checkds/prep.example.db b/bin/tests/system/checkds/prep.example.db
new file mode 100644
index 0000000000..5ba5987cab
--- /dev/null
+++ b/bin/tests/system/checkds/prep.example.db
@@ -0,0 +1,121 @@
+; File written on Thu Oct 5 23:44:34 2017
+; dnssec_signzone version 9.12.0a1
+prep.example. 300 IN SOA ns1.prep.example. hostmaster.prep.example. (
+ 1 ; serial
+ 2000 ; refresh (33 minutes 20 seconds)
+ 2000 ; retry (33 minutes 20 seconds)
+ 1814400 ; expire (3 weeks)
+ 3600 ; minimum (1 hour)
+ )
+ 300 RRSIG SOA 8 2 300 (
+ 20171105054434 20171006054434 19260 prep.example.
+ 1fX0z7Swu4gMPews/ZE8bzNg+JXNedFBDGIH
+ PTSfVQtVLIvRWpME+PylX7MdVMZE/PST+x4/
+ mWyveyjetEOo7/7aQL236FfI0y6TxQFy7HwC
+ FMieqoQCUluuKOvToxg4vUp4GOdlUGbqC63h
+ DbX5Z37VptJXLkt4niF4Kl2iD+U9/bk7HAEU
+ 4zDiKroYnusGKfVB9xAWddzoHdLxhVuPi7ut
+ 328suPdgX0bfs7uB+y4cikhGzAmPpNMlGHju
+ qYG74NcFGQNutLB7ayx/m87t7mTty7jbNKm3
+ QWJSPf5IR8/kmzAi8HMnapY5vUmm+hX8JOfU
+ UtH7i0iEsUqRbEwu5A== )
+ 300 NS ns1.prep.example.
+ 300 RRSIG NS 8 2 300 (
+ 20171105054434 20171006054434 19260 prep.example.
+ u5sU2cfqNqIyCLw18ZNnFw28/GyRt0EOiPYS
+ dygmpfMDrvDaxjiiai8zWYjnl/E3qzVH9Zku
+ 07lEDORZdVb0uCDe1NynjAyw4AHps85cAwVc
+ 8HTSbzdVZsQTELpunYFJffh24PDr9unw7KOY
+ jzTP6qNedJ1uM54TOr177zfmBh7N2fkAoGyV
+ NjvTKrlgDYGNIn8/YMgHb4sNgyfe54MYY00f
+ kehVxfKnRCgDsbJ0Pk6jhBMCQWvOh8jG8WyV
+ ElAa/eMqlxUC1idF8ydWefjsI/7lPcjSalw9
+ qZw4CDCLHHZy0TOSmCYRRZuIeVXzBfDPJyi4
+ 2A3iLntKFJ4AOLFMJg== )
+ 3600 NSEC ns1.prep.example. NS SOA RRSIG NSEC DNSKEY
+ 3600 RRSIG NSEC 8 2 3600 (
+ 20171105054434 20171006054434 19260 prep.example.
+ Aed99/jdG82YAkKVWjoKOsAGtB3JnyKkCaAq
+ zgMrYkXU41y3KDCAmGzooGPQY7NN+WxX7FJ2
+ 1nXkgljma/azgpsbi9ssneFtv7PPFClVmN+u
+ j+mM4MK/ZR7eJOsMqETg4PAO5VAh6c/GVmyA
+ RD/m6EhJVZEjPfLWbDoC4hVAgem7DP/NMjyI
+ GfztpDjMmyLQyv6tL+UEXSJHGp3ZEa5Z5i7X
+ Nl/bRTUlZs7L4rTgoqHv6LEmsXKAf9rZYq4b
+ eP6GF9I1Ry41MfHLc7lPUmtR38ErEsM5uGzw
+ trCQYEFhuRWUBxZ8OSL2EZK9rUBXZX+cwK/8
+ ZP7mIfDfljkXPQcmow== )
+ 3600 DNSKEY 256 3 8 (
+ AwEAAfMzj6aZIgZDVcpH1pKOtq998E85+nEY
+ YJa0lLS8+QTCC1Efke8GLwsXT0IPTuwnOuXM
+ RjySirab0NuEr69T8KP/43YxcRdmCg89mjjN
+ szoVPPstC9xBKVOc0pRMDF7sfsTrSye3RY7+
+ Z6uZEH5FOAkz2hNbJJHOn4HpNUhLPJGRauhf
+ 0evamwUmQ/mlhkVW5q4WmqPCDMNY3K6XtkEm
+ cvm8n9ZCXC9Z5AX6KpynujzLdKyxpdGqUk6r
+ lavp9ILPpRKoTZDX+2q1pDgP5cDndwtgNSvU
+ DBQZoD0psS2cyB3PHo+dPwwpEyM//ZSKsH9m
+ e85Ti0413TOWFyFd/jUOUA8=
+ ) ; ZSK; alg = RSASHA256 ; key id = 19260
+ 3600 DNSKEY 257 3 8 (
+ AwEAAbV8X06Qvk350aZ6eZ1d7WbT1H/Y0Sv7
+ qAdbk5fbYIKpMvZ8D9xqoTHgD0z0uCgWWIcm
+ /xyKBfmax76oLwMBpR/kdtuJz0irgFITnJCH
+ pEfR9AJ/Mfm7NyMglq+/39I03E1/LXvpXQLG
+ tg+Mo/2CUE5sbG31jmPNK/2J8RMESkIi87fW
+ azZU/oyUEtECE5PGbdyw+4PacAsXNjnwl30T
+ aatL277wX4pt+IUPdE6EIph3t+dxXJ7OpHgW
+ 8g+YSHLlCImLVapdg3oD/cs6ncaBq9z7la5Y
+ dHNw2QAIAvQ11EsonrkonPqO6zNVZAVdT2VB
+ X5YzGAoCFUvbCvlnl2a7SxM=
+ ) ; KSK; alg = RSASHA256 ; key id = 65482
+ 3600 RRSIG DNSKEY 8 2 3600 (
+ 20171105054434 20171006054434 19260 prep.example.
+ pPw81pJ3PeF+tqEswTul9N8Qsl9JKgK4v8SV
+ lPfP0pnlMBMbtMFFkx5ZmhQg3Z3U8SdE64Bt
+ C5St3qItyyKdTQ0Rbm9mfV6twxDB8lVry8F7
+ Pv7gJmmcWzBcbLGcrXIrVNSZhigkemQXTElj
+ P8y1j7kaNFWBWbDMn7KesiZ9BiC6sqvuKa3R
+ wSofjwXTESspWZP0NtXr5ymaBIMR9UtNj5Wh
+ jm1+tg6BxNBKxhCHlSC0ltPS/qq9J1ZUmtJz
+ sj/EAFfPVJVuEveebMvi1oDWPTgajO9+EHl4
+ ELrgnQHCgaybMzbpd/A5+Tr1hQkv48I8Mb0/
+ 8LJ2/6xrvJm64yRteg== )
+ 3600 RRSIG DNSKEY 8 2 3600 (
+ 20171105054434 20171006054434 65482 prep.example.
+ WeIWiC9SnBe2+UocVjpap62O8Rz+iljwJiu9
+ VlGUwct3Vydq4/4FVAKdPklXV5cYbBLhO2MB
+ 3R4toX8RNU/0Ny8DnugQzLKvVfg0xoyU/UAJ
+ k4aWa/vPivSLGouLQPiNp71bdXN4LB/2xmzu
+ cPYXzS9ePpwCOp/9JLoNjBSMQkfjfWAcaNtj
+ 1DKDmHHL1sPMizninxSJLQOAKb+JwUAjAkOM
+ O1JqwkB12/IZuzxN5hly+uNsbFFxPzQkcnJ4
+ 5bhzxuh5D/JRXW0nF5aO4aR+9X+lSUpDJQZ1
+ 5fOt1cybZCn/ag68RA92zrnisdbrggJGS003
+ wn/VKbLVfFj3eQrfNA== )
+ns1.prep.example. 300 IN A 1.1.1.1
+ 300 RRSIG A 8 3 300 (
+ 20171105054434 20171006054434 19260 prep.example.
+ QUyDyJVk3JGEq+VTZtY3firzsRqOA0LUm3Tf
+ /fnemQBeOlMda2ErA7DqYVriIGfM8jph416E
+ YX8SKAZXGEAlsEbC9cWBVyc5TYH6tZ43sV51
+ 55kGTiUY92NnrH10Q+m2SLAEEaKCA/cgBwOR
+ tN2Wb1meHgiLbGYN2LbANfDQzoEk4AYAgT6r
+ wDKVVg/V9Ed7JnCnBQc9MN9+LQ3h4NBGUiEY
+ mr7HX2w+yzqcGFNLI1aFPe2IwFt120QPLyyl
+ cZgc6FUBX4YCnWoCb0aFyyOT76AQkKF5YBRn
+ gAv6S8q1pZ/0B5w4gjaLEGlts3LG0bxZ1GJd
+ gCQMEhgYgyXUchTtZA== )
+ 3600 NSEC prep.example. A RRSIG NSEC
+ 3600 RRSIG NSEC 8 3 3600 (
+ 20171105054434 20171006054434 19260 prep.example.
+ rDWN40u1a3DSzWOrS+4YR2XOxaem0BAQ/glN
+ QkXNDew1WsZo3fe0IHIhDKlJ/5MJAfAHq8Xs
+ A5UGUw2efoNAN/0LuWsI/9IPm4dwQOXiTCly
+ uxugXf5islPYyvn1Z14ay/7/2P3W6HZknXzo
+ lZFpwqfFZQCxz7c/1aH+2ntAMeqx8LHuewSr
+ Rz/sLsSiCcZQ6NMWnZdoC5SGy4CTcIIPPS8z
+ 9dQ6QYTC5iq4MKRfyJUyvODyU9be4e6jbo5b
+ mjRcov4ttbImhD5jrLAZIfjO6DSazGNVFf/x
+ 6rjxjrc8SISPkt2xYwcOlYch9OZuoH86wcZu
+ 3Don6yAnLDYDrZylAA== )
diff --git a/bin/tests/system/checkds/prep.example.ds.db b/bin/tests/system/checkds/prep.example.ds.db
new file mode 100644
index 0000000000..dddcad6468
--- /dev/null
+++ b/bin/tests/system/checkds/prep.example.ds.db
@@ -0,0 +1,2 @@
+prep.example. IN DS 65482 8 1 F3673708FBADDEC3EB55933E2E393ACE85EAC2BB
+prep.example. IN DS 65482 8 2 51A7C97AAC42803DA515D1CAFEE28031A5018F6345F12F4B6C1B6D20 02B59820
diff --git a/bin/tests/system/checkds/tests.sh b/bin/tests/system/checkds/tests.sh
index 53f1dd4d74..b38a713cf0 100644
--- a/bin/tests/system/checkds/tests.sh
+++ b/bin/tests/system/checkds/tests.sh
@@ -171,6 +171,15 @@ n=`expr $n + 1`
if [ $ret != 0 ]; then echo "I:failed"; fi
status=`expr $status + $ret`
+echo "I:checking with prepared dsset file ($n)"
+ret=0
+$CHECKDS -f prep.example.db -s prep.example.ds.db prep.example > checkds.out.$n || ret=1
+grep 'SHA-1.*found' checkds.out.$n > /dev/null 2>&1 || ret=1
+grep 'SHA-256.*found' checkds.out.$n > /dev/null 2>&1 || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
if [ $status = 0 ]; then $SHELL clean.sh; fi
echo "I:exit status: $status"
[ $status -eq 0 ] || exit 1
diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml
index 5f08662a2f..d88018ae4a 100644
--- a/doc/arm/notes.xml
+++ b/doc/arm/notes.xml
@@ -449,6 +449,14 @@
dnssec-settime, etc. [RT #46149]
+
+
+ dnssec-checkds -s specifies a file from
+ which to read a DS set rather than querying the parent zone.
+ This can be used to check zone correctness prior to
+ publication. Thanks to Niall O'Reilly [RT #44667]
+
+