diff --git a/bin/tests/system/verify/.gitignore b/bin/tests/system/verify/.gitignore deleted file mode 100644 index e1055b0166..0000000000 --- a/bin/tests/system/verify/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -verify.out.* -zones/*.good -zones/*.bad -zones/K* -zones/dsset-* -zones/s.out* diff --git a/bin/tests/system/verify/clean.sh b/bin/tests/system/verify/clean.sh deleted file mode 100644 index 5e801a0215..0000000000 --- a/bin/tests/system/verify/clean.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/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. - -rm -f verify.out* -rm -f zones/*.bad -rm -f zones/*.good -rm -f zones/*.out* -rm -f zones/*.tmp -rm -f zones/K* -rm -f zones/dsset-* -rm -f zones/updated* diff --git a/bin/tests/system/verify/tests.sh b/bin/tests/system/verify/tests.sh deleted file mode 100644 index 3f778b2e09..0000000000 --- a/bin/tests/system/verify/tests.sh +++ /dev/null @@ -1,116 +0,0 @@ -#!/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 - -. ../conf.sh -failed() { - cat verify.out.$n | sed 's/^/D:/' - echo_i "failed" - status=1 -} - -n=0 -status=0 - -for file in zones/*.good; do - n=$((n + 1)) - zone=$(expr "$file" : 'zones/\(.*\).good') - echo_i "checking supposedly good zone: $zone ($n)" - ret=0 - case $zone in - zsk-only.*) only=-z ;; - ksk-only.*) only=-z ;; - *) only= ;; - esac - $VERIFY ${only} -o $zone $file >verify.out.$n 2>&1 || ret=1 - [ $ret = 0 ] || failed -done - -for file in zones/*.bad; do - n=$((n + 1)) - zone=$(expr "$file" : 'zones/\(.*\).bad') - echo_i "checking supposedly bad zone: $zone ($n)" - ret=0 - dumpit=0 - case $zone in - zsk-only.*) only=-z ;; - ksk-only.*) only=-z ;; - *) only= ;; - esac - expect1= expect2= - case $zone in - *.dnskeyonly) - expect1="DNSKEY is not signed" - ;; - *.expired) - expect1="signature has expired" - expect2="No self-signed .*DNSKEY found" - ;; - *.ksk-expired) - expect1="signature has expired" - expect2="No self-signed .*DNSKEY found" - ;; - *.out-of-zone-nsec | *.below-bottom-of-zone-nsec | *.below-dname-nsec) - expect1="unexpected NSEC RRset at" - ;; - *.nsec.broken-chain) - expect1="Bad NSEC record for.*, next name mismatch" - ;; - *.bad-bitmap) - expect1="bit map mismatch" - ;; - *.missing-empty) - expect1="Missing NSEC3 record for" - ;; - unsigned) - expect1="Zone contains no DNSSEC keys" - ;; - *.extra-nsec3) - expect1="Expected and found NSEC3 chains not equal" - ;; - *) - dumpit=1 - ;; - esac - $VERIFY ${only} -o $zone $file >verify.out.$n 2>&1 && ret=1 - grep "${expect1:-.}" verify.out.$n >/dev/null || ret=1 - grep "${expect2:-.}" verify.out.$n >/dev/null || ret=1 - [ $ret = 0 ] || failed - [ $dumpit = 1 ] && cat verify.out.$n -done - -n=$((n + 1)) -echo_i "checking error message when -o is not used and a SOA record not at top of zone is found ($n)" -ret=0 -# When -o is not used, origin is set to zone file name, which should cause an error in this case -$VERIFY zones/ksk+zsk.nsec.good >verify.out.$n 2>&1 && ret=1 -grep "not at top of zone" verify.out.$n >/dev/null || ret=1 -grep "use -o to specify a different zone origin" verify.out.$n >/dev/null || ret=1 -[ $ret = 0 ] || failed - -n=$((n + 1)) -echo_i "checking error message when an invalid -o is specified and a SOA record not at top of zone is found ($n)" -ret=0 -$VERIFY -o invalid.origin zones/ksk+zsk.nsec.good >verify.out.$n 2>&1 && ret=1 -grep "not at top of zone" verify.out.$n >/dev/null || ret=1 -grep "use -o to specify a different zone origin" verify.out.$n >/dev/null && ret=1 -[ $ret = 0 ] || failed - -n=$((n + 1)) -echo_i "checking dnssec-verify -J reads journal file ($n)" -$VERIFY -o updated -J zones/updated.other.jnl zones/updated.other >verify.out.$n 2>&1 || ret=1 -[ $ret = 0 ] || failed - -echo_i "exit status: $status" -[ $status -eq 0 ] || exit 1 diff --git a/bin/tests/system/verify/tests_sh_verify.py b/bin/tests/system/verify/tests_sh_verify.py deleted file mode 100644 index 2fd0c5c203..0000000000 --- a/bin/tests/system/verify/tests_sh_verify.py +++ /dev/null @@ -1,14 +0,0 @@ -# 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. - - -def test_verify(run_tests_sh): - run_tests_sh() diff --git a/bin/tests/system/verify/tests_verify.py b/bin/tests/system/verify/tests_verify.py new file mode 100644 index 0000000000..be5e6ef741 --- /dev/null +++ b/bin/tests/system/verify/tests_verify.py @@ -0,0 +1,175 @@ +# 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 os +import re + +import pytest + +import isctest + +VERIFY = os.environ.get("VERIFY") + + +@pytest.mark.parametrize( + "zone", + [ + "ksk-only.nsec3", + "ksk-only.nsec", + "ksk+zsk.nsec3.apex-dname", + "ksk+zsk.nsec3", + "ksk+zsk.nsec.apex-dname", + "ksk+zsk.nsec", + "ksk+zsk.optout", + "zsk-only.nsec3", + "zsk-only.nsec", + ], +) +def test_verify_good_zone_files(zone): + isctest.run.cmd([VERIFY, "-z", "-o", zone, f"zones/{zone}.good"], log_stdout=True) + + +def test_verify_good_zone_nsec_next_name_case_mismatch(): + isctest.run.cmd( + [ + VERIFY, + "-o", + "nsec-next-name-case-mismatch", + "zones/nsec-next-name-case-mismatch.good", + ], + log_stdout=True, + ) + + +def get_bad_zone_output(zone): + only_opt = ["-z"] if re.match(r"[zk]sk-only", zone) else [] + output = isctest.run.cmd( + [VERIFY, *only_opt, "-o", zone, f"zones/{zone}.bad"], + raise_on_exception=False, + log_stdout=True, + ) + stream = (output.stdout + output.stderr).decode("utf-8").replace("\n", "") + return stream + + +@pytest.mark.parametrize( + "zone", + [ + "ksk-only.dnskeyonly", + "ksk+zsk.dnskeyonly", + "zsk-only.dnskeyonly", + ], +) +def test_verify_bad_zone_files_dnskeyonly(zone): + assert re.match(r".*DNSKEY is not signed.*", get_bad_zone_output(zone)) + + +@pytest.mark.parametrize( + "zone", + [ + "ksk-only.nsec3.expired", + "ksk-only.nsec.expired", + "ksk+zsk.nsec3.expired", + "ksk+zsk.nsec.expired", + "ksk+zsk.nsec.ksk-expired", + "zsk-only.nsec3.expired", + "zsk-only.nsec.expired", + "ksk+zsk.nsec3.ksk-expired", + ], +) +def test_verify_bad_zone_files_expired(zone): + assert re.match( + r".*signature has expired.*|.*No self-signed .*DNSKEY found.*", + get_bad_zone_output(zone), + ) + + +@pytest.mark.parametrize( + "zone", + [ + "ksk+zsk.nsec.out-of-zone-nsec", + "ksk+zsk.nsec.below-bottom-of-zone-nsec", + "ksk+zsk.nsec.below-dname-nsec", + ], +) +def test_verify_bad_zone_files_unexpected_nsec_rrset(zone): + assert re.match(r".*unexpected NSEC RRset at.*", get_bad_zone_output(zone)) + + +def test_verify_bad_zone_files_bad_nsec_record(): + assert re.match( + r".*Bad NSEC record for.*, next name mismatch.*", + get_bad_zone_output("ksk+zsk.nsec.broken-chain"), + ) + + +def test_verify_bad_zone_files_bad_bitmap(): + assert re.match( + r".*bit map mismatch.*", get_bad_zone_output("ksk+zsk.nsec.bad-bitmap") + ) + + +def test_verify_bad_zone_files_missing_nsec3_record(): + assert re.match( + r".*Missing NSEC3 record for.*", + get_bad_zone_output("ksk+zsk.nsec3.missing-empty"), + ) + + +def test_verify_bad_zone_files_no_dnssec_keys(): + assert re.match( + r".*Zone contains no DNSSEC keys.*", get_bad_zone_output("unsigned") + ) + + +def test_verify_bad_zone_files_unequal_nsec3_chains(): + assert re.match( + r".*Expected and found NSEC3 chains not equal.*", + get_bad_zone_output("ksk+zsk.nsec3.extra-nsec3"), + ) + + +# checking error message when -o is not used +# and a SOA record not at top of zone is found +def test_verify_soa_not_at_top_error(): + # when -o is not used, origin is set to zone file name, + # which should cause an error in this case + output = isctest.run.cmd( + [VERIFY, "zones/ksk+zsk.nsec.good"], raise_on_exception=False + ).stderr.decode("utf-8") + assert "not at top of zone" in output + assert "use -o to specify a different zone origin" in output + + +# checking error message when an invalid -o is specified +# and a SOA record not at top of zone is found +def test_verify_invalid_o_option_soa_not_at_top_error(): + output = isctest.run.cmd( + [VERIFY, "-o", "invalid.origin", "zones/ksk+zsk.nsec.good"], + raise_on_exception=False, + ).stderr.decode("utf-8") + assert "not at top of zone" in output + assert "use -o to specify a different zone origin" not in output + + +# checking dnssec-verify -J reads journal file +def test_verify_j_reads_journal_file(): + output = isctest.run.cmd( + [ + VERIFY, + "-o", + "updated", + "-J", + "zones/updated.other.jnl", + "zones/updated.other", + ] + ).stdout.decode("utf-8") + assert "Loading zone 'updated' from file 'zones/updated.other'" in output