Version in base suite: 9.20.11-4 Base version: bind9_9.20.11-4 Target version: bind9_9.20.15-1~deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/b/bind9/bind9_9.20.11-4.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/b/bind9/bind9_9.20.15-1~deb13u1.dsc ChangeLog | 4 Makefile.in | 55 NEWS | 4 aclocal.m4 | 484 ar-lib | 14 bin/Makefile.in | 19 bin/check/Makefile.in | 48 bin/check/named-checkconf.c | 8 bin/check/named-checkconf.rst | 8 bin/confgen/Makefile.in | 48 bin/delv/Makefile.in | 40 bin/dig/Makefile.in | 48 bin/dig/dighost.c | 2 bin/dnssec/Makefile.in | 48 bin/dnssec/dnssec-cds.c | 2 bin/dnssec/dnssec-dsfromkey.c | 14 bin/dnssec/dnssec-dsfromkey.rst | 73 bin/dnssec/dnssec-importkey.c | 3 bin/dnssec/dnssec-keyfromlabel.c | 19 bin/dnssec/dnssec-keyfromlabel.rst | 34 bin/dnssec/dnssec-keygen.c | 33 bin/dnssec/dnssec-keygen.rst | 27 bin/dnssec/dnssec-signzone.c | 8 bin/dnssec/dnssec-verify.c | 3 bin/dnssec/dnssectool.c | 5 bin/named/Makefile.in | 40 bin/named/config.c | 3 bin/named/main.c | 6 bin/named/server.c | 152 bin/named/tkeyconf.c | 13 bin/nsupdate/Makefile.in | 40 bin/plugins/Makefile.in | 44 bin/rndc/Makefile.in | 40 bin/rndc/rndc.rst | 9 bin/tests/Makefile.in | 38 bin/tests/system/Makefile.am | 15 bin/tests/system/Makefile.in | 236 bin/tests/system/additional/ns3/named.conf.in | 3 bin/tests/system/addzone/tests_rndc_deadlock.py | 3 bin/tests/system/autosign/tests_sh_autosign.py | 4 bin/tests/system/cacheclean/ns2/named.conf.j2 | 3 bin/tests/system/catz/ns1/named.conf.in | 9 bin/tests/system/catz/ns2/named1.conf.in | 9 bin/tests/system/catz/ns2/named2.conf.in | 6 bin/tests/system/catz/setup.sh | 1 bin/tests/system/chain/ns1/named.conf.in | 3 bin/tests/system/chain/ns7/named.conf.in | 3 bin/tests/system/checkconf-keys/bad-algorithm.conf.j2 | 25 bin/tests/system/checkconf-keys/bad-default-algorithm.conf.j2 | 18 bin/tests/system/checkconf-keys/bad-default-kz.conf.j2 | 18 bin/tests/system/checkconf-keys/bad-keystore.conf.j2 | 33 bin/tests/system/checkconf-keys/bad-length.conf.j2 | 24 bin/tests/system/checkconf-keys/bad-missing-keyfile.conf.j2 | 25 bin/tests/system/checkconf-keys/bad-role.conf.j2 | 25 bin/tests/system/checkconf-keys/bad-superfluous-keyfile.conf.j2 | 25 bin/tests/system/checkconf-keys/bad-tagrange.conf.j2 | 24 bin/tests/system/checkconf-keys/named.conf.j2 | 90 bin/tests/system/checkconf-keys/setup.sh | 85 bin/tests/system/checkconf-keys/template.db.in | 27 bin/tests/system/checkconf-keys/tests_checkconf_keys.py | 162 bin/tests/system/checkconf/good.conf.j2 | 1 bin/tests/system/checkconf/kasp-deprecated-fips.conf | 19 bin/tests/system/checkconf/kasp-deprecated.conf | 20 bin/tests/system/checkconf/tests.sh | 16 bin/tests/system/checkds/tests_checkds.py | 10 bin/tests/system/checknames/ns2/named.conf.j2 | 3 bin/tests/system/checknames/ns3/named.conf.j2 | 3 bin/tests/system/checknames/ns4/named.conf.j2 | 3 bin/tests/system/checknames/ns5/named.conf.j2 | 3 bin/tests/system/checkzone/tests.sh | 101 bin/tests/system/checkzone/zones/warn.deprecated.cds-sha1.db | 44 bin/tests/system/checkzone/zones/warn.deprecated.digest-sha1.db | 51 bin/tests/system/checkzone/zones/warn.deprecated.ds-alg.db | 51 bin/tests/system/checkzone/zones/warn.deprecated.key-alg.db | 53 bin/tests/system/checkzone/zones/warn.deprecated.nsec3rsasha1.db | 71 bin/tests/system/checkzone/zones/warn.deprecated.rsasha1.db | 71 bin/tests/system/cipher-suites/ns1/named.conf.in | 3 bin/tests/system/cipher-suites/ns2/named.conf.in | 3 bin/tests/system/cipher-suites/ns3/named.conf.in | 3 bin/tests/system/cipher-suites/ns4/named.conf.in | 3 bin/tests/system/cipher-suites/ns5/named.conf.in | 3 bin/tests/system/cipher-suites/tests_cipher_suites.py | 2 bin/tests/system/conftest.py | 50 bin/tests/system/cookie/ns1/named.conf.j2 | 3 bin/tests/system/cookie/ns3/named.conf.j2 | 3 bin/tests/system/cookie/ns4/named.conf.j2 | 3 bin/tests/system/cookie/ns5/named.conf.j2 | 3 bin/tests/system/cookie/ns6/named.conf.j2 | 3 bin/tests/system/cookie/ns8/named.conf.j2 | 3 bin/tests/system/database/ns1/named.conf.j2 | 3 bin/tests/system/database/tests_database.py | 12 bin/tests/system/dialup/tests_dialup_zone_transfer.py | 3 bin/tests/system/digdelv/tests.sh | 9 bin/tests/system/dispatch/ans3/ans.py | 114 bin/tests/system/dlzexternal/driver/Makefile.in | 37 bin/tests/system/dns64/ns1/named.conf1.in | 4 bin/tests/system/dns64/ns1/named.conf2.in | 4 bin/tests/system/dns64/ns1/named.conf3.in | 4 bin/tests/system/dns64/ns2/named.conf.in | 3 bin/tests/system/dns64/ns3/named.conf.in | 3 bin/tests/system/dns64/ns4/named.conf.in | 3 bin/tests/system/dnssec/ns3/badalg.secure.example.db.in | 22 bin/tests/system/dnssec/ns3/named.conf.in | 12 bin/tests/system/dnssec/ns3/secure.example.db.in | 7 bin/tests/system/dnssec/ns3/sign.sh | 27 bin/tests/system/dnssec/ns3/zonecut.ent.secure.example.db.in | 22 bin/tests/system/dnssec/ns4/named1.conf.in | 2 bin/tests/system/dnssec/ns4/named2.conf.in | 2 bin/tests/system/dnssec/ns4/named3.conf.in | 2 bin/tests/system/dnssec/ns4/named4.conf.in | 2 bin/tests/system/dnssec/tests.sh | 112 bin/tests/system/dnssec/tests_sh_dnssec.py | 5 bin/tests/system/dnstap/ns1/named.conf.j2 | 3 bin/tests/system/dnstap/ns2/named.conf.j2 | 3 bin/tests/system/dnstap/ns3/named.conf.j2 | 3 bin/tests/system/dnstap/ns4/named.conf.j2 | 3 bin/tests/system/dnstap/tests_dnstap.py | 5 bin/tests/system/dnstap/tests_sh_dnstap.py | 1 bin/tests/system/doth/example.axfr.good | 3 bin/tests/system/doth/example8.axfr.good | 3 bin/tests/system/doth/ns1/named.conf.in | 3 bin/tests/system/doth/ns2/named.conf.in | 3 bin/tests/system/doth/ns3/named.conf.in | 3 bin/tests/system/doth/ns4/named.conf.in | 3 bin/tests/system/doth/ns5/named.conf.in | 3 bin/tests/system/doth/tests_gnutls.py | 5 bin/tests/system/dsdigest/tests_dsdigest.py | 8 bin/tests/system/dyndb/driver/Makefile.in | 37 bin/tests/system/ecdsa/tests_ecdsa.py | 6 bin/tests/system/emptyzones/tests_emptyzones.py | 13 bin/tests/system/enginepkcs11/tests_sh_enginepkcs11.py | 4 bin/tests/system/fetchlimit/ans4/ans.pl | 90 bin/tests/system/fetchlimit/ans4/ans.py | 48 bin/tests/system/fetchlimit/ns3/named1.conf.in | 3 bin/tests/system/fetchlimit/ns3/named2.conf.in | 3 bin/tests/system/fetchlimit/ns3/named3.conf.in | 3 bin/tests/system/fetchlimit/ns5/named1.conf.in | 3 bin/tests/system/fetchlimit/ns5/named2.conf.in | 3 bin/tests/system/fetchlimit/ns5/named3.conf.in | 3 bin/tests/system/fetchlimit/tests.sh | 23 bin/tests/system/fetchlimit/tests_sh_fetchlimit.py | 4 bin/tests/system/filter-aaaa/conf/bad1.conf | 17 bin/tests/system/filter-aaaa/conf/bad2.conf | 26 bin/tests/system/filter-aaaa/conf/bad3.conf | 19 bin/tests/system/filter-aaaa/conf/bad4.conf | 19 bin/tests/system/filter-aaaa/conf/bad5.conf | 21 bin/tests/system/filter-aaaa/conf/good1.conf | 16 bin/tests/system/filter-aaaa/conf/good2.conf | 16 bin/tests/system/filter-aaaa/conf/good3.conf | 17 bin/tests/system/filter-aaaa/conf/good4.conf | 17 bin/tests/system/filter-aaaa/conf/good5.conf | 19 bin/tests/system/filter-aaaa/ns1/named1.conf.in | 49 bin/tests/system/filter-aaaa/ns1/named2.conf.in | 46 bin/tests/system/filter-aaaa/ns1/root.db | 25 bin/tests/system/filter-aaaa/ns1/sign.sh | 34 bin/tests/system/filter-aaaa/ns1/signed.db.in | 25 bin/tests/system/filter-aaaa/ns1/unsigned.db | 25 bin/tests/system/filter-aaaa/ns2/hints | 16 bin/tests/system/filter-aaaa/ns2/named1.conf.in | 44 bin/tests/system/filter-aaaa/ns2/named2.conf.in | 44 bin/tests/system/filter-aaaa/ns3/hints | 16 bin/tests/system/filter-aaaa/ns3/named1.conf.in | 44 bin/tests/system/filter-aaaa/ns3/named2.conf.in | 44 bin/tests/system/filter-aaaa/ns4/named1.conf.in | 44 bin/tests/system/filter-aaaa/ns4/named2.conf.in | 44 bin/tests/system/filter-aaaa/ns4/root.db | 24 bin/tests/system/filter-aaaa/ns4/sign.sh | 27 bin/tests/system/filter-aaaa/ns4/signed.db.in | 25 bin/tests/system/filter-aaaa/ns4/unsigned.db | 25 bin/tests/system/filter-aaaa/ns5/hints | 16 bin/tests/system/filter-aaaa/ns5/named.conf.in | 49 bin/tests/system/filter-aaaa/setup.sh | 23 bin/tests/system/filter-aaaa/tests.sh | 1405 -- bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py | 31 bin/tests/system/filters/common.py | 231 bin/tests/system/filters/conf/bad1.conf.j2 | 17 bin/tests/system/filters/conf/bad2.conf.j2 | 26 bin/tests/system/filters/conf/bad3.conf.j2 | 19 bin/tests/system/filters/conf/bad4.conf.j2 | 19 bin/tests/system/filters/conf/bad5.conf.j2 | 21 bin/tests/system/filters/conf/good1.conf.j2 | 16 bin/tests/system/filters/conf/good2.conf.j2 | 16 bin/tests/system/filters/conf/good3.conf.j2 | 17 bin/tests/system/filters/conf/good4.conf.j2 | 17 bin/tests/system/filters/conf/good5.conf.j2 | 19 bin/tests/system/filters/ns1/named.conf.j2 | 57 bin/tests/system/filters/ns1/root.db | 25 bin/tests/system/filters/ns1/sign.sh | 34 bin/tests/system/filters/ns1/signed.db.in | 25 bin/tests/system/filters/ns1/unsigned.db | 25 bin/tests/system/filters/ns2/hints | 16 bin/tests/system/filters/ns2/named.conf.j2 | 55 bin/tests/system/filters/ns3/hints | 16 bin/tests/system/filters/ns3/named.conf.j2 | 55 bin/tests/system/filters/ns4/named.conf.j2 | 54 bin/tests/system/filters/ns4/root.db | 24 bin/tests/system/filters/ns4/sign.sh | 27 bin/tests/system/filters/ns4/signed.db.in | 25 bin/tests/system/filters/ns4/unsigned.db | 25 bin/tests/system/filters/ns5/hints | 16 bin/tests/system/filters/ns5/named.conf.j2 | 49 bin/tests/system/filters/setup.sh | 17 bin/tests/system/filters/tests_filter_a_v4.py | 60 bin/tests/system/filters/tests_filter_a_v6.py | 80 bin/tests/system/filters/tests_filter_aaaa_v4.py | 61 bin/tests/system/filters/tests_filter_aaaa_v6.py | 81 bin/tests/system/filters/tests_filter_checkconf.py | 32 bin/tests/system/filters/tests_filter_dns64.py | 28 bin/tests/system/forward/ns3/named1.conf.in | 3 bin/tests/system/forward/ns4/named.conf.in | 3 bin/tests/system/forward/ns5/named.conf.in | 3 bin/tests/system/forward/ns7/named.conf.in | 3 bin/tests/system/forward/ns8/named.conf.in | 3 bin/tests/system/genzone.sh | 11 bin/tests/system/glue/tests_glue.py | 5 bin/tests/system/hooks/driver/Makefile.in | 37 bin/tests/system/hooks/ns1/named.conf.j2 | 3 bin/tests/system/hooks/tests_async_plugin.py | 6 bin/tests/system/ifconfig.sh.in | 2 bin/tests/system/include-multiplecfg/tests_include_multiplecfg.py | 6 bin/tests/system/isctest/__init__.py | 1 bin/tests/system/isctest/asyncserver.py | 260 bin/tests/system/isctest/check.py | 60 bin/tests/system/isctest/hypothesis/strategies.py | 16 bin/tests/system/isctest/instance.py | 67 bin/tests/system/isctest/kasp.py | 300 bin/tests/system/isctest/log/watchlog.py | 496 bin/tests/system/isctest/mark.py | 32 bin/tests/system/isctest/name.py | 192 bin/tests/system/isctest/query.py | 20 bin/tests/system/isctest/vars/basic.py | 6 bin/tests/system/isctest/vars/dirs.py | 1 bin/tests/system/kasp/ns3/named-fips.conf.in | 9 bin/tests/system/kasp/ns3/policies/autosign.conf.in | 16 bin/tests/system/kasp/ns3/setup.sh | 13 bin/tests/system/kasp/tests_kasp.py | 414 bin/tests/system/keepalive/tests_keepalive.py | 6 bin/tests/system/keyfromlabel/tests_keyfromlabel.py | 1 bin/tests/system/ksr/tests_ksr.py | 44 bin/tests/system/legacy/ns1/named1.conf.in | 3 bin/tests/system/limits/tests_limits.py | 7 bin/tests/system/makejournal.c | 2 bin/tests/system/masterfile/ns2/named.conf.j2 | 3 bin/tests/system/masterfile/tests_masterfile.py | 10 bin/tests/system/migrate2kasp/ns3/kasp.conf.j2 | 104 bin/tests/system/migrate2kasp/ns3/named.conf.j2 | 111 bin/tests/system/migrate2kasp/ns3/setup.sh | 161 bin/tests/system/migrate2kasp/ns3/template.db.in | 26 bin/tests/system/migrate2kasp/ns4/named.conf.j2 | 92 bin/tests/system/migrate2kasp/ns4/setup.sh | 46 bin/tests/system/migrate2kasp/ns4/template.ext.db.in | 28 bin/tests/system/migrate2kasp/ns4/template.int.db.in | 28 bin/tests/system/migrate2kasp/setup.sh | 27 bin/tests/system/migrate2kasp/tests_migrate2kasp.py | 358 bin/tests/system/mirror-root-zone/tests_mirror_root_zone.py | 5 bin/tests/system/mkeys/ns1/named1.conf.in | 3 bin/tests/system/mkeys/ns1/named2.conf.in | 3 bin/tests/system/mkeys/ns1/named3.conf.in | 3 bin/tests/system/mkeys/tests_sh_mkeys.py | 4 bin/tests/system/names/tests_names.py | 4 bin/tests/system/nsec3-answer/ns1/named.conf.j2 | 31 bin/tests/system/nsec3-answer/ns1/root.db.in | 51 bin/tests/system/nsec3-answer/ns1/sign.sh | 34 bin/tests/system/nsec3-answer/ns2/named.conf.j2 | 39 bin/tests/system/nsec3-answer/setup.sh | 22 bin/tests/system/nsec3-answer/tests_nsec3.py | 410 bin/tests/system/nsupdate/ns3/named.conf.in | 3 bin/tests/system/nsupdate/tests_sh_nsupdate.py | 4 bin/tests/system/nzd2nzf/tests_nzd2nzf.py | 18 bin/tests/system/pipelined/ns2/named.conf.j2 | 3 bin/tests/system/pipelined/ns3/named.conf.j2 | 3 bin/tests/system/pipelined/ns4/named.conf.j2 | 3 bin/tests/system/proxy/ns1/named.conf.in | 3 bin/tests/system/proxy/ns3/named.conf.in | 3 bin/tests/system/qmin/tests_sh_qmin.py | 4 bin/tests/system/query-source/tests_querysource_none.py | 7 bin/tests/system/reclimit/ns3/named1.conf.in | 3 bin/tests/system/reclimit/ns3/named2.conf.in | 3 bin/tests/system/reclimit/ns3/named3.conf.in | 3 bin/tests/system/reclimit/ns3/named4.conf.in | 3 bin/tests/system/reclimit/ns3/named5.conf.in | 3 bin/tests/system/reclimit/ns3/named6.conf.in | 3 bin/tests/system/reclimit/tests_sh_reclimit.py | 4 bin/tests/system/redirect/ns1/named.conf.in | 3 bin/tests/system/redirect/ns2/named.conf.in | 3 bin/tests/system/redirect/ns3/named.conf.in | 3 bin/tests/system/redirect/ns4/named.conf.in | 3 bin/tests/system/resolver/ns1/named.conf.in | 3 bin/tests/system/resolver/ns1/named.conf.j2 | 48 bin/tests/system/resolver/ns7/named1.conf.in | 3 bin/tests/system/resolver/ns7/named2.conf.in | 3 bin/tests/system/resolver/ns9/named.conf.in | 3 bin/tests/system/resolver/tests_resolver.py | 39 bin/tests/system/resolver/tests_sh_resolver.py | 1 bin/tests/system/rfc5011/tests_rfc5011.py | 6 bin/tests/system/rndc/ns4/named.conf.in | 3 bin/tests/system/rndc/tests.sh | 6 bin/tests/system/rndc/tests_cve-2023-3341.py | 5 bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 | 50 bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 | 50 bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 | 35 bin/tests/system/rollover-algo-csk/ns6/named.conf.j2 | 59 bin/tests/system/rollover-algo-csk/ns6/template.db.in | 27 bin/tests/system/rollover-algo-csk/setup.sh | 152 bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py | 48 bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py | 334 bin/tests/system/rollover-algo-ksk-zsk/ns6/kasp.conf.j2 | 92 bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 | 35 bin/tests/system/rollover-algo-ksk-zsk/ns6/named.conf.j2 | 60 bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in | 27 bin/tests/system/rollover-algo-ksk-zsk/setup.sh | 201 bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py | 50 bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py | 356 bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 | 58 bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2 | 61 bin/tests/system/rollover-csk-roll1/ns3/template.db.in | 27 bin/tests/system/rollover-csk-roll1/setup.sh | 314 bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py | 434 bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 | 58 bin/tests/system/rollover-csk-roll2/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover-csk-roll2/ns3/named.conf.j2 | 56 bin/tests/system/rollover-csk-roll2/ns3/template.db.in | 27 bin/tests/system/rollover-csk-roll2/setup.sh | 301 bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py | 409 bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db | 27 bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 | 35 bin/tests/system/rollover-dynamic2inline/ns6/named.conf.j2 | 21 bin/tests/system/rollover-dynamic2inline/ns6/template.db.in | 27 bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py | 46 bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 | 52 bin/tests/system/rollover-enable-dnssec/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover-enable-dnssec/ns3/named.conf.j2 | 41 bin/tests/system/rollover-enable-dnssec/ns3/template.db.in | 27 bin/tests/system/rollover-enable-dnssec/setup.sh | 102 bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py | 210 bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 | 21 bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 | 35 bin/tests/system/rollover-going-insecure/ns6/named.conf.j2 | 49 bin/tests/system/rollover-going-insecure/ns6/template.db.in | 27 bin/tests/system/rollover-going-insecure/setup.sh | 71 bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py | 50 bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py | 99 bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 | 60 bin/tests/system/rollover-ksk-3crowd/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover-ksk-3crowd/ns3/named.conf.j2 | 23 bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in | 27 bin/tests/system/rollover-ksk-3crowd/setup.sh | 82 bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py | 95 bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 | 60 bin/tests/system/rollover-ksk-doubleksk/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover-ksk-doubleksk/ns3/named.conf.j2 | 50 bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in | 27 bin/tests/system/rollover-ksk-doubleksk/setup.sh | 243 bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py | 348 bin/tests/system/rollover-lifetime/ns6/kasp.conf.j2 | 29 bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db | 27 bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db | 27 bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 | 35 bin/tests/system/rollover-lifetime/ns6/named.conf.j2 | 45 bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db | 27 bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db | 27 bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py | 50 bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py | 65 bin/tests/system/rollover-multisigner/ns3/kasp.conf.j2 | 22 bin/tests/system/rollover-multisigner/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover-multisigner/ns3/named.conf.j2 | 34 bin/tests/system/rollover-multisigner/ns3/template.db.in | 27 bin/tests/system/rollover-multisigner/setup.sh | 67 bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py | 176 bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 | 21 bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 | 35 bin/tests/system/rollover-straight2none/ns6/named.conf.j2 | 31 bin/tests/system/rollover-straight2none/ns6/template.db.in | 27 bin/tests/system/rollover-straight2none/setup.sh | 53 bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py | 48 bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py | 57 bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 | 52 bin/tests/system/rollover-zsk-prepub/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover-zsk-prepub/ns3/named.conf.j2 | 50 bin/tests/system/rollover-zsk-prepub/ns3/template.db.in | 27 bin/tests/system/rollover-zsk-prepub/setup.sh | 218 bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py | 353 bin/tests/system/rollover/common.py | 139 bin/tests/system/rollover/ns3/kasp.conf.j2 | 115 bin/tests/system/rollover/ns3/named.common.conf.j2 | 39 bin/tests/system/rollover/ns3/named.conf.j2 | 233 bin/tests/system/rollover/ns3/setup.sh | 1091 - bin/tests/system/rollover/ns6/csk1.conf.j2 | 30 bin/tests/system/rollover/ns6/csk2.conf.j2 | 30 bin/tests/system/rollover/ns6/kasp.conf.j2 | 97 bin/tests/system/rollover/ns6/named.conf.j2 | 120 bin/tests/system/rollover/ns6/named2.conf.j2 | 198 bin/tests/system/rollover/ns6/setup.sh | 390 bin/tests/system/rollover/ns6/template.db.in | 27 bin/tests/system/rollover/setup.sh | 37 bin/tests/system/rollover/tests_rollover.py | 1815 --- bin/tests/system/rollover/tests_rollover_manual.py | 155 bin/tests/system/rpz/ns3/evil-cname.db.in | 21 bin/tests/system/rpz/ns3/named.conf.in | 23 bin/tests/system/rpz/ns3/slow-rpz.db.in | 16 bin/tests/system/rpz/ns3/wild-cname.db.in | 21 bin/tests/system/rpz/ns4/tld4.db | 2 bin/tests/system/rpz/ns8/named.conf.in | 3 bin/tests/system/rpz/ns9/named.conf.in | 3 bin/tests/system/rpz/setup.sh | 6 bin/tests/system/rpz/test2 | 4 bin/tests/system/rpz/testlib/Makefile.in | 37 bin/tests/system/rpz/tests.sh | 35 bin/tests/system/rpz/tests_sh_rpz.py | 3 bin/tests/system/rpz/tests_sh_rpz_dnsrps.py | 3 bin/tests/system/rpzextra/tests_rpzextra.py | 15 bin/tests/system/rpzrecurse/ns2/named.clientip.conf | 1 bin/tests/system/rpzrecurse/ns2/named.clientip2.conf | 1 bin/tests/system/rpzrecurse/ns2/named.conf.header.in | 3 bin/tests/system/rpzrecurse/ns2/named.default.conf | 1 bin/tests/system/rpzrecurse/ns2/named.log.conf | 1 bin/tests/system/rpzrecurse/ns2/named.max.conf | 1 bin/tests/system/rpzrecurse/ns2/named.wildcard1.conf | 1 bin/tests/system/rpzrecurse/ns2/named.wildcard2.conf | 1 bin/tests/system/rpzrecurse/ns2/named.wildcard3.conf | 1 bin/tests/system/rpzrecurse/ns2/named.wildcard4.conf | 1 bin/tests/system/rpzrecurse/ns3/named1.conf.in | 3 bin/tests/system/rpzrecurse/ns3/named2.conf.in | 3 bin/tests/system/rpzrecurse/ns3/named3.conf.in | 3 bin/tests/system/rrchecker/tests_rrchecker.py | 3 bin/tests/system/rrl/ns1/named.conf.j2 | 3 bin/tests/system/rrl/ns2/named.conf.j2 | 3 bin/tests/system/rrl/ns3/named.conf.j2 | 3 bin/tests/system/rrl/ns4/named.conf.j2 | 3 bin/tests/system/rrl/tests_sh_rrl.py | 4 bin/tests/system/rrsetorder/ns3/named.conf.j2 | 3 bin/tests/system/rrsetorder/ns4/named.conf.j2 | 3 bin/tests/system/rrsetorder/ns5/named.conf.j2 | 3 bin/tests/system/selftest/tests_zone_analyzer.py | 228 bin/tests/system/serve-stale/ans2/ans.pl | 9 bin/tests/system/serve-stale/ns1/stale.test.db | 8 bin/tests/system/serve-stale/ns3/serve.stale.db | 1 bin/tests/system/serve-stale/tests.sh | 99 bin/tests/system/serve-stale/tests_sh_serve_stale.py | 1 bin/tests/system/shutdown/tests_shutdown.py | 2 bin/tests/system/spf/tests_spf_zones.py | 6 bin/tests/system/statistics/ns2/named.conf.in | 3 bin/tests/system/statistics/ns3/named.conf.in | 3 bin/tests/system/statschannel/tests_json.py | 2 bin/tests/system/statschannel/tests_xml.py | 2 bin/tests/system/stress/ns3/named.conf.in | 3 bin/tests/system/stress/ns4/named.conf.in | 3 bin/tests/system/stub/tests_stub.py | 18 bin/tests/system/synthfromdnssec/ns1/named.conf.in | 5 bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in | 28 bin/tests/system/synthfromdnssec/ns1/root.db.in | 2 bin/tests/system/synthfromdnssec/ns1/sign.sh | 11 bin/tests/system/synthfromdnssec/tests.sh | 35 bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py | 3 bin/tests/system/timeouts/tests_tcp_timeouts.py | 9 bin/tests/system/tools/tests.sh | 24 bin/tests/system/tools/tests_sh_tools.py | 18 bin/tests/system/tools/tests_tools_nsec3hash.py | 54 bin/tests/system/transport-acl/ns1/named.conf.in | 3 bin/tests/system/transport-change/ns1/named-http-plain-proxy.conf.in | 3 bin/tests/system/transport-change/ns1/named-http-plain.conf.in | 3 bin/tests/system/transport-change/ns1/named-https-proxy-encrypted.conf.in | 3 bin/tests/system/transport-change/ns1/named-https-proxy-plain.conf.in | 3 bin/tests/system/transport-change/ns1/named-https.conf.in | 3 bin/tests/system/transport-change/ns1/named-proxy.conf.in | 3 bin/tests/system/transport-change/ns1/named-tls-proxy-encrypted.conf.in | 3 bin/tests/system/transport-change/ns1/named-tls-proxy-plain.conf.in | 3 bin/tests/system/transport-change/ns1/named-tls.conf.in | 3 bin/tests/system/transport-change/ns1/named.conf.in | 3 bin/tests/system/tsig/ans2/ans.pl | 52 bin/tests/system/tsig/ans2/ans.py | 49 bin/tests/system/tsig/tests_sh_tsig.py | 3 bin/tests/system/tsig/tests_tsig_hypothesis.py | 3 bin/tests/system/tsiggss/tests_isc_spnego_flaws.py | 2 bin/tests/system/ttl/tests_cache_ttl.py | 5 bin/tests/system/wildcard/tests_wildcard.py | 10 bin/tests/system/xfer/dig1.good | 3 bin/tests/system/xfer/dig2.good | 3 bin/tests/system/xferquota/tests_xferquota.py | 15 bin/tests/system/zero/ans5/ans.pl | 81 bin/tests/system/zero/ans5/ans.py | 62 bin/tests/system/zero/ns3/named.conf.in | 3 bin/tests/system/zero/ns4/named.conf.in | 3 bin/tests/system/zonechecks/ns1/named.conf.in | 3 bin/tests/system/zonechecks/ns2/named.conf.in | 3 bin/tools/Makefile.in | 40 compile | 11 config.guess | 111 config.h.in | 181 config.sub | 942 + configure | 5787 ++++++---- configure.ac | 6 debian/changelog | 11 debian/gbp.conf | 2 depcomp | 15 doc/Makefile.in | 19 doc/arm/Makefile.in | 23 doc/arm/advanced.inc.rst | 9 doc/arm/changelog.rst | 4 doc/arm/conf.py | 2 doc/arm/index.rst | 6 doc/arm/notes.rst | 4 doc/arm/platforms.inc.rst | 4 doc/arm/reference.rst | 127 doc/changelog/changelog-9.20.12.rst | 140 doc/changelog/changelog-9.20.13.rst | 139 doc/changelog/changelog-9.20.14.rst | 18 doc/changelog/changelog-9.20.15.rst | 133 doc/man/Makefile.in | 32 doc/man/dnssec-dsfromkey.1in | 73 doc/man/dnssec-keyfromlabel.1in | 32 doc/man/dnssec-keygen.1in | 25 doc/man/named-checkconf.1in | 9 doc/man/named.conf.5in | 9 doc/man/rndc.8in | 9 doc/misc/Makefile.in | 40 doc/misc/options | 9 doc/notes/notes-9.20.12.rst | 98 doc/notes/notes-9.20.13.rst | 82 doc/notes/notes-9.20.14.rst | 18 doc/notes/notes-9.20.15.rst | 108 fuzz/Makefile.in | 108 install-sh | 14 lib/Makefile.in | 23 lib/dns/Makefile.am | 3 lib/dns/Makefile.in | 51 lib/dns/acl.c | 3 lib/dns/adb.c | 240 lib/dns/dnssec.c | 2 lib/dns/dst_api.c | 104 lib/dns/dst_internal.h | 23 lib/dns/dst_parse.c | 46 lib/dns/include/dns/db.h | 13 lib/dns/include/dns/ds.h | 2 lib/dns/include/dns/dsync.h | 27 lib/dns/include/dns/kasp.h | 39 lib/dns/include/dns/keymgr.h | 28 lib/dns/include/dns/message.h | 8 lib/dns/include/dns/qp.h | 7 lib/dns/include/dns/rdataset.h | 23 lib/dns/include/dns/rpz.h | 12 lib/dns/include/dns/tkey.h | 1 lib/dns/include/dns/types.h | 1 lib/dns/include/dns/zone.h | 14 lib/dns/include/dst/dst.h | 102 lib/dns/kasp.c | 31 lib/dns/keymgr.c | 265 lib/dns/message.c | 31 lib/dns/qp.c | 177 lib/dns/qp_p.h | 32 lib/dns/qpcache.c | 67 lib/dns/rbtdb.c | 59 lib/dns/rcode.c | 43 lib/dns/rdata/any_255/tsig_250.c | 4 lib/dns/rdata/ch_3/a_1.c | 4 lib/dns/rdata/generic/afsdb_18.c | 4 lib/dns/rdata/generic/amtrelay_260.c | 4 lib/dns/rdata/generic/avc_258.c | 4 lib/dns/rdata/generic/brid_68.c | 213 lib/dns/rdata/generic/brid_68.h | 21 lib/dns/rdata/generic/caa_257.c | 4 lib/dns/rdata/generic/cdnskey_60.c | 4 lib/dns/rdata/generic/cds_59.c | 4 lib/dns/rdata/generic/cert_37.c | 4 lib/dns/rdata/generic/cname_5.c | 4 lib/dns/rdata/generic/csync_62.c | 4 lib/dns/rdata/generic/dlv_32769.c | 4 lib/dns/rdata/generic/dname_39.c | 4 lib/dns/rdata/generic/dnskey_48.c | 4 lib/dns/rdata/generic/doa_259.c | 4 lib/dns/rdata/generic/ds_43.c | 4 lib/dns/rdata/generic/dsync_66.c | 359 lib/dns/rdata/generic/dsync_66.h | 24 lib/dns/rdata/generic/eui48_108.c | 4 lib/dns/rdata/generic/eui64_109.c | 4 lib/dns/rdata/generic/gpos_27.c | 4 lib/dns/rdata/generic/hhit_67.c | 213 lib/dns/rdata/generic/hhit_67.h | 21 lib/dns/rdata/generic/hinfo_13.c | 4 lib/dns/rdata/generic/hip_55.c | 4 lib/dns/rdata/generic/ipseckey_45.c | 4 lib/dns/rdata/generic/isdn_20.c | 4 lib/dns/rdata/generic/key_25.c | 4 lib/dns/rdata/generic/keydata_65533.c | 4 lib/dns/rdata/generic/l32_105.c | 4 lib/dns/rdata/generic/l64_106.c | 4 lib/dns/rdata/generic/loc_29.c | 4 lib/dns/rdata/generic/lp_107.c | 4 lib/dns/rdata/generic/mb_7.c | 4 lib/dns/rdata/generic/md_3.c | 4 lib/dns/rdata/generic/mf_4.c | 4 lib/dns/rdata/generic/mg_8.c | 4 lib/dns/rdata/generic/minfo_14.c | 4 lib/dns/rdata/generic/mr_9.c | 4 lib/dns/rdata/generic/mx_15.c | 4 lib/dns/rdata/generic/naptr_35.c | 4 lib/dns/rdata/generic/nid_104.c | 4 lib/dns/rdata/generic/ninfo_56.c | 4 lib/dns/rdata/generic/ns_2.c | 4 lib/dns/rdata/generic/nsec3_50.c | 4 lib/dns/rdata/generic/nsec3param_51.c | 4 lib/dns/rdata/generic/nsec_47.c | 4 lib/dns/rdata/generic/null_10.c | 4 lib/dns/rdata/generic/nxt_30.c | 4 lib/dns/rdata/generic/openpgpkey_61.c | 4 lib/dns/rdata/generic/opt_41.c | 4 lib/dns/rdata/generic/ptr_12.c | 4 lib/dns/rdata/generic/resinfo_261.c | 4 lib/dns/rdata/generic/rkey_57.c | 4 lib/dns/rdata/generic/rp_17.c | 4 lib/dns/rdata/generic/rrsig_46.c | 4 lib/dns/rdata/generic/rt_21.c | 4 lib/dns/rdata/generic/sig_24.c | 4 lib/dns/rdata/generic/sink_40.c | 4 lib/dns/rdata/generic/smimea_53.c | 4 lib/dns/rdata/generic/soa_6.c | 4 lib/dns/rdata/generic/spf_99.c | 4 lib/dns/rdata/generic/sshfp_44.c | 4 lib/dns/rdata/generic/ta_32768.c | 4 lib/dns/rdata/generic/talink_58.c | 4 lib/dns/rdata/generic/tkey_249.c | 4 lib/dns/rdata/generic/tlsa_52.c | 4 lib/dns/rdata/generic/txt_16.c | 4 lib/dns/rdata/generic/uri_256.c | 4 lib/dns/rdata/generic/wallet_262.c | 4 lib/dns/rdata/generic/x25_19.c | 4 lib/dns/rdata/generic/zonemd_63.c | 4 lib/dns/rdata/hs_4/a_1.c | 4 lib/dns/rdata/in_1/a6_38.c | 4 lib/dns/rdata/in_1/a_1.c | 4 lib/dns/rdata/in_1/aaaa_28.c | 4 lib/dns/rdata/in_1/apl_42.c | 4 lib/dns/rdata/in_1/atma_34.c | 4 lib/dns/rdata/in_1/dhcid_49.c | 4 lib/dns/rdata/in_1/eid_31.c | 4 lib/dns/rdata/in_1/kx_36.c | 4 lib/dns/rdata/in_1/nimloc_32.c | 4 lib/dns/rdata/in_1/nsap-ptr_23.c | 4 lib/dns/rdata/in_1/nsap_22.c | 4 lib/dns/rdata/in_1/px_26.c | 4 lib/dns/rdata/in_1/srv_33.c | 4 lib/dns/rdata/in_1/svcb_64.c | 4 lib/dns/rdata/in_1/wks_11.c | 4 lib/dns/rdataset.c | 15 lib/dns/rdataslab.c | 19 lib/dns/request.c | 2 lib/dns/resolver.c | 337 lib/dns/rpz.c | 49 lib/dns/tkey.c | 21 lib/dns/validator.c | 105 lib/dns/zone.c | 288 lib/isc/Makefile.am | 3 lib/isc/Makefile.in | 175 lib/isc/entropy.c | 24 lib/isc/hash.c | 3 lib/isc/hashmap.c | 1 lib/isc/httpd.c | 6 lib/isc/include/isc/attributes.h | 6 lib/isc/include/isc/entropy.h | 35 lib/isc/include/isc/nonce.h | 7 lib/isc/include/isc/random.h | 36 lib/isc/include/isc/util.h | 2 lib/isc/mem.c | 2 lib/isc/nonce.c | 20 lib/isc/os.c | 6 lib/isc/picohttpparser.c | 2 lib/isc/random.c | 125 lib/isc/uv.c | 15 lib/isccc/Makefile.in | 44 lib/isccfg/Makefile.in | 44 lib/isccfg/check.c | 249 lib/isccfg/include/isccfg/check.h | 5 lib/isccfg/include/isccfg/kaspconf.h | 42 lib/isccfg/kaspconf.c | 434 lib/isccfg/namedconf.c | 9 lib/ns/Makefile.in | 44 lib/ns/client.c | 4 lib/ns/hooks.c | 3 lib/ns/include/ns/query.h | 2 lib/ns/include/ns/server.h | 1 lib/ns/query.c | 291 ltmain.sh | 749 - m4/libtool.m4 | 448 m4/ltoptions.m4 | 106 m4/ltsugar.m4 | 2 m4/ltversion.m4 | 12 m4/lt~obsolete.m4 | 2 missing | 75 srcid | 2 test-driver | 15 tests/Makefile.in | 32 tests/bench/Makefile.in | 46 tests/dns/Makefile.in | 100 tests/dns/diff_test.c | 5 tests/dns/qpmulti_test.c | 14 tests/dns/rdata_test.c | 143 tests/isc/Makefile.in | 100 tests/isc/random_test.c | 4 tests/isccfg/Makefile.in | 100 tests/libtest/Makefile.in | 99 tests/libtest/qp.c | 11 tests/ns/Makefile.in | 100 util/check-make-install.in | 61 util/check-make-install.sh.in | 61 705 files changed, 26196 insertions(+), 13579 deletions(-) diff -Nru bind9-9.20.11/ChangeLog bind9-9.20.15/ChangeLog --- bind9-9.20.11/ChangeLog 2025-07-04 09:42:08.300327360 +0000 +++ bind9-9.20.15/ChangeLog 2025-10-18 10:16:12.531731809 +0000 @@ -18,6 +18,10 @@ development. Regular users should refer to :ref:`Release Notes ` for changes relevant to them. +.. include:: ../changelog/changelog-9.20.15.rst +.. include:: ../changelog/changelog-9.20.14.rst +.. include:: ../changelog/changelog-9.20.13.rst +.. include:: ../changelog/changelog-9.20.12.rst .. include:: ../changelog/changelog-9.20.11.rst .. include:: ../changelog/changelog-9.20.10.rst .. include:: ../changelog/changelog-9.20.9.rst diff -Nru bind9-9.20.11/Makefile.in bind9-9.20.15/Makefile.in --- bind9-9.20.11/Makefile.in 2025-07-04 09:43:10.661798693 +0000 +++ bind9-9.20.15/Makefile.in 2025-10-18 10:17:03.875492286 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -72,6 +72,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -129,7 +131,7 @@ bin/tests/system/isctest/vars/.ac_vars/NC \ bin/tests/system/isctest/vars/.ac_vars/XSLTPROC \ bin/tests/system/isctest/vars/.ac_vars/PYTEST \ - util/check-make-install + util/check-make-install.sh CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -200,7 +202,7 @@ $(top_srcdir)/bin/tests/system/isctest/vars/.ac_vars/TOP_SRCDIR.in \ $(top_srcdir)/bin/tests/system/isctest/vars/.ac_vars/XSLTPROC.in \ $(top_srcdir)/doc/doxygen/doxygen-input-filter.in \ - $(top_srcdir)/util/check-make-install.in AUTHORS COPYING \ + $(top_srcdir)/util/check-make-install.sh.in AUTHORS COPYING \ ChangeLog NEWS README.md ar-lib compile config.guess \ config.sub install-sh ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -208,8 +210,8 @@ top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ - find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ - && rm -rf "$(distdir)" \ + find "$(distdir)" -type d ! -perm -700 -exec chmod u+rwx {} ';' \ + ; rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) @@ -238,7 +240,7 @@ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" -GZIP_ENV = --best +GZIP_ENV = -9 DIST_ARCHIVES = $(distdir).tar.xz DIST_TARGETS = dist-xz # Exists only to be overridden by the user if desired. @@ -246,7 +248,9 @@ distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' -distcleancheck_listfiles = find . -type f -print +distcleancheck_listfiles = \ + find . \( -type f -a \! \ + \( -name .nfs* -o -name .smb* -o -name .__afs* \) \) -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ @@ -405,8 +409,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -566,12 +572,12 @@ @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status config.h + $(AM_V_at)rm -f stamp-h1 + $(AM_V_GEN)cd $(top_builddir) && $(SHELL) ./config.status config.h $(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ + $(AM_V_GEN)($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + $(AM_V_at)rm -f stamp-h1 + $(AM_V_at)touch $@ distclean-hdr: -rm -f config.h stamp-h1 @@ -597,7 +603,7 @@ cd $(top_builddir) && $(SHELL) ./config.status $@ bin/tests/system/isctest/vars/.ac_vars/PYTEST: $(top_builddir)/config.status $(top_srcdir)/bin/tests/system/isctest/vars/.ac_vars/PYTEST.in cd $(top_builddir) && $(SHELL) ./config.status $@ -util/check-make-install: $(top_builddir)/config.status $(top_srcdir)/util/check-make-install.in +util/check-make-install.sh: $(top_builddir)/config.status $(top_srcdir)/util/check-make-install.sh.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: @@ -722,7 +728,7 @@ distdir-am: $(DISTFILES) $(am__remove_distdir) - test -d "$(distdir)" || mkdir "$(distdir)" + $(AM_V_at)$(MKDIR_P) "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ @@ -835,7 +841,7 @@ distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -845,7 +851,7 @@ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ *.tar.zst*) \ @@ -946,16 +952,16 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am @@ -1074,3 +1080,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/NEWS bind9-9.20.15/NEWS --- bind9-9.20.11/NEWS 2025-07-04 09:42:08.300327360 +0000 +++ bind9-9.20.15/NEWS 2025-10-18 10:16:12.531731809 +0000 @@ -18,6 +18,10 @@ development. Regular users should refer to :ref:`Release Notes ` for changes relevant to them. +.. include:: ../changelog/changelog-9.20.15.rst +.. include:: ../changelog/changelog-9.20.14.rst +.. include:: ../changelog/changelog-9.20.13.rst +.. include:: ../changelog/changelog-9.20.12.rst .. include:: ../changelog/changelog-9.20.11.rst .. include:: ../changelog/changelog-9.20.10.rst .. include:: ../changelog/changelog-9.20.9.rst diff -Nru bind9-9.20.11/aclocal.m4 bind9-9.20.15/aclocal.m4 --- bind9-9.20.11/aclocal.m4 2025-07-04 09:43:09.302767023 +0000 +++ bind9-9.20.15/aclocal.m4 2025-10-18 10:17:02.521473439 +0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.5 -*- Autoconf -*- +# generated automatically by aclocal 1.17 -*- Autoconf -*- -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,8 +14,8 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl -m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, -[m4_warning([this file was generated for autoconf 2.71. +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.72],, +[m4_warning([this file was generated for autoconf 2.72. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) @@ -364,7 +364,7 @@ [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])]) ])dnl PKG_HAVE_DEFINE_WITH_MODULES -# Copyright (C) 2002-2021 Free Software Foundation, Inc. +# Copyright (C) 2002-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -376,10 +376,10 @@ # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.16' +[am__api_version='1.17' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.16.5], [], +m4_if([$1], [1.17], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -395,12 +395,12 @@ # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.16.5])dnl +[AM_AUTOMAKE_VERSION([1.17])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) -# Copyright (C) 2011-2021 Free Software Foundation, Inc. +# Copyright (C) 2011-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -414,16 +414,18 @@ AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl +AC_BEFORE([$0], [AC_PROG_AR])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} +: ${ARFLAGS=cr} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], - [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' + [am_ar_try='$AR $ARFLAGS libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar @@ -462,7 +464,7 @@ # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -514,7 +516,7 @@ # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# Copyright (C) 1997-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -545,7 +547,7 @@ Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -677,7 +679,7 @@ # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: + # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported @@ -736,7 +738,7 @@ # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -804,7 +806,7 @@ # AM_EXTRA_RECURSIVE_TARGETS -*- Autoconf -*- -# Copyright (C) 2012-2021 Free Software Foundation, Inc. +# Copyright (C) 2012-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -821,7 +823,7 @@ # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -955,7 +957,7 @@ fi AC_SUBST([CSCOPE]) -AC_REQUIRE([AM_SILENT_RULES])dnl +AC_REQUIRE([_AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. @@ -963,47 +965,9 @@ [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. +AC_REQUIRE([_AM_PROG_RM_F]) +AC_REQUIRE([_AM_PROG_XARGS_N]) -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) - fi -fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. @@ -1036,7 +1000,7 @@ done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1057,7 +1021,7 @@ fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2021 Free Software Foundation, Inc. +# Copyright (C) 2003-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1079,7 +1043,7 @@ # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1114,7 +1078,7 @@ # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1157,7 +1121,7 @@ # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2021 Free Software Foundation, Inc. +# Copyright (C) 1997-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1191,7 +1155,7 @@ # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1220,7 +1184,7 @@ AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1267,7 +1231,7 @@ # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1301,10 +1265,12 @@ dnl Find a Python interpreter. Python versions prior to 2.0 are not dnl supported. (2.0 was released on October 16, 2000). m4_define_default([_AM_PYTHON_INTERPRETER_LIST], -[python python2 python3 dnl - python3.11 python3.10 dnl +[python python3 dnl + python3.20 python3.19 python3.18 python3.17 python3.16 dnl + python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 dnl python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 dnl python3.2 python3.1 python3.0 dnl + python2 dnl python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 dnl python2.0]) @@ -1499,15 +1465,29 @@ if python_implementation() == 'CPython' and sys.version[[:3]] == '2.7': can_use_sysconfig = 0 except ImportError: - pass" + pass" # end of am_python_setup_sysconfig + + # More repeated code, for figuring out the installation scheme to use. + am_python_setup_scheme="if hasattr(sysconfig, 'get_default_scheme'): + scheme = sysconfig.get_default_scheme() + else: + scheme = sysconfig._get_default_scheme() + if scheme == 'posix_local': + if '$am_py_prefix' == '/usr': + scheme = 'deb_system' # should only happen during Debian package builds + else: + # Debian's default scheme installs to /usr/local/ but we want to + # follow the prefix, as we always have. + # See bugs#54412, #64837, et al. + scheme = 'posix_prefix'" # end of am_python_setup_scheme dnl emacs-page Set up 4 directories: dnl 1. pythondir: where to install python scripts. This is the dnl site-packages directory, not the python standard library - dnl directory like in previous automake betas. This behavior + dnl directory as in early automake betas. This behavior dnl is more consistent with lispdir.m4 for example. - dnl Query distutils for this directory. + dnl Query sysconfig or distutils (per above) for this directory. dnl AC_CACHE_CHECK([for $am_display_PYTHON script directory (pythondir)], [am_cv_python_pythondir], @@ -1519,14 +1499,11 @@ am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: - if hasattr(sysconfig, 'get_default_scheme'): - scheme = sysconfig.get_default_scheme() - else: - scheme = sysconfig._get_default_scheme() - if scheme == 'posix_local': - # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ - scheme = 'posix_prefix' - sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) + try: + $am_python_setup_scheme + sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) + except: + sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') @@ -1556,7 +1533,8 @@ dnl 3. pyexecdir: directory for installing python extension modules dnl (shared libraries). - dnl Query distutils for this directory. + dnl Query sysconfig or distutils for this directory. + dnl Much of this is the same as for prefix setup above. dnl AC_CACHE_CHECK([for $am_display_PYTHON extension module directory (pyexecdir)], [am_cv_python_pyexecdir], @@ -1568,14 +1546,11 @@ am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: - if hasattr(sysconfig, 'get_default_scheme'): - scheme = sysconfig.get_default_scheme() - else: - scheme = sysconfig._get_default_scheme() - if scheme == 'posix_local': - # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ - scheme = 'posix_prefix' - sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) + try: + $am_python_setup_scheme + sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) + except: + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix') @@ -1626,7 +1601,23 @@ sys.exit(sys.hexversion < minverhex)" AS_IF([AM_RUN_LOG([$1 -c "$prog"])], [$3], [$4])]) -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# Copyright (C) 2022-2024 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_RM_F +# --------------- +# Check whether 'rm -f' without any arguments works. +# https://bugs.gnu.org/10828 +AC_DEFUN([_AM_PROG_RM_F], +[am__rm_f_notfound= +AS_IF([(rm -f && rm -fr && rm -rf) 2>/dev/null], [], [am__rm_f_notfound='""']) +AC_SUBST(am__rm_f_notfound) +]) + +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1645,16 +1636,169 @@ # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2021 Free Software Foundation, Inc. +# Copyright (C) 1996-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. +# _AM_SLEEP_FRACTIONAL_SECONDS +# ---------------------------- +AC_DEFUN([_AM_SLEEP_FRACTIONAL_SECONDS], [dnl +AC_CACHE_CHECK([whether sleep supports fractional seconds], + am_cv_sleep_fractional_seconds, [dnl +AS_IF([sleep 0.001 2>/dev/null], [am_cv_sleep_fractional_seconds=yes], + [am_cv_sleep_fractional_seconds=no]) +])]) + +# _AM_FILESYSTEM_TIMESTAMP_RESOLUTION +# ----------------------------------- +# Determine the filesystem's resolution for file modification +# timestamps. The coarsest we know of is FAT, with a resolution +# of only two seconds, even with the most recent "exFAT" extensions. +# The finest (e.g. ext4 with large inodes, XFS, ZFS) is one +# nanosecond, matching clock_gettime. However, it is probably not +# possible to delay execution of a shell script for less than one +# millisecond, due to process creation overhead and scheduling +# granularity, so we don't check for anything finer than that. (See below.) +AC_DEFUN([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION], [dnl +AC_REQUIRE([_AM_SLEEP_FRACTIONAL_SECONDS]) +AC_CACHE_CHECK([filesystem timestamp resolution], + am_cv_filesystem_timestamp_resolution, [dnl +# Default to the worst case. +am_cv_filesystem_timestamp_resolution=2 + +# Only try to go finer than 1 sec if sleep can do it. +# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work, +# - 1 sec is not much of a win compared to 2 sec, and +# - it takes 2 seconds to perform the test whether 1 sec works. +# +# Instead, just use the default 2s on platforms that have 1s resolution, +# accept the extra 1s delay when using $sleep in the Automake tests, in +# exchange for not incurring the 2s delay for running the test for all +# packages. +# +am_try_resolutions= +if test "$am_cv_sleep_fractional_seconds" = yes; then + # Even a millisecond often causes a bunch of false positives, + # so just try a hundredth of a second. The time saved between .001 and + # .01 is not terribly consequential. + am_try_resolutions="0.01 0.1 $am_try_resolutions" +fi + +# In order to catch current-generation FAT out, we must *modify* files +# that already exist; the *creation* timestamp is finer. Use names +# that make ls -t sort them differently when they have equal +# timestamps than when they have distinct timestamps, keeping +# in mind that ls -t prints the *newest* file first. +rm -f conftest.ts? +: > conftest.ts1 +: > conftest.ts2 +: > conftest.ts3 + +# Make sure ls -t actually works. Do 'set' in a subshell so we don't +# clobber the current shell's arguments. (Outer-level square brackets +# are removed by m4; they're present so that m4 does not expand +# ; be careful, easy to get confused.) +if ( + set X `[ls -t conftest.ts[12]]` && + { + test "$[]*" != "X conftest.ts1 conftest.ts2" || + test "$[]*" != "X conftest.ts2 conftest.ts1"; + } +); then :; else + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + _AS_ECHO_UNQUOTED( + ["Bad output from ls -t: \"`[ls -t conftest.ts[12]]`\""], + [AS_MESSAGE_LOG_FD]) + AC_MSG_FAILURE([ls -t produces unexpected output. +Make sure there is not a broken ls alias in your environment.]) +fi + +for am_try_res in $am_try_resolutions; do + # Any one fine-grained sleep might happen to cross the boundary + # between two values of a coarser actual resolution, but if we do + # two fine-grained sleeps in a row, at least one of them will fall + # entirely within a coarse interval. + echo alpha > conftest.ts1 + sleep $am_try_res + echo beta > conftest.ts2 + sleep $am_try_res + echo gamma > conftest.ts3 + + # We assume that 'ls -t' will make use of high-resolution + # timestamps if the operating system supports them at all. + if (set X `ls -t conftest.ts?` && + test "$[]2" = conftest.ts3 && + test "$[]3" = conftest.ts2 && + test "$[]4" = conftest.ts1); then + # + # Ok, ls -t worked. If we're at a resolution of 1 second, we're done, + # because we don't need to test make. + make_ok=true + if test $am_try_res != 1; then + # But if we've succeeded so far with a subsecond resolution, we + # have one more thing to check: make. It can happen that + # everything else supports the subsecond mtimes, but make doesn't; + # notably on macOS, which ships make 3.81 from 2006 (the last one + # released under GPLv2). https://bugs.gnu.org/68808 + # + # We test $MAKE if it is defined in the environment, else "make". + # It might get overridden later, but our hope is that in practice + # it does not matter: it is the system "make" which is (by far) + # the most likely to be broken, whereas if the user overrides it, + # probably they did so with a better, or at least not worse, make. + # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html + # + # Create a Makefile (real tab character here): + rm -f conftest.mk + echo 'conftest.ts1: conftest.ts2' >conftest.mk + echo ' touch conftest.ts2' >>conftest.mk + # + # Now, running + # touch conftest.ts1; touch conftest.ts2; make + # should touch ts1 because ts2 is newer. This could happen by luck, + # but most often, it will fail if make's support is insufficient. So + # test for several consecutive successes. + # + # (We reuse conftest.ts[12] because we still want to modify existing + # files, not create new ones, per above.) + n=0 + make=${MAKE-make} + until test $n -eq 3; do + echo one > conftest.ts1 + sleep $am_try_res + echo two > conftest.ts2 # ts2 should now be newer than ts1 + if $make -f conftest.mk | grep 'up to date' >/dev/null; then + make_ok=false + break # out of $n loop + fi + n=`expr $n + 1` + done + fi + # + if $make_ok; then + # Everything we know to check worked out, so call this resolution good. + am_cv_filesystem_timestamp_resolution=$am_try_res + break # out of $am_try_res loop + fi + # Otherwise, we'll go on to check the next resolution. + fi +done +rm -f conftest.ts? +# (end _am_filesystem_timestamp_resolution) +])]) + # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) +[AC_REQUIRE([_AM_FILESYSTEM_TIMESTAMP_RESOLUTION]) +# This check should not be cached, as it may vary across builds of +# different projects. +AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' @@ -1673,49 +1817,40 @@ # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$[*]" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$[*]" != "X $srcdir/configure conftest.file" \ - && test "$[*]" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken - alias in your environment]) - fi - if test "$[2]" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$[2]" = conftest.file - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! +am_build_env_is_sane=no +am_has_slept=no +rm -f conftest.file +for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[]*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + test "$[]2" = conftest.file + ); then + am_build_env_is_sane=yes + break + fi + # Just in case. + sleep "$am_cv_filesystem_timestamp_resolution" + am_has_slept=yes +done + +AC_MSG_RESULT([$am_build_env_is_sane]) +if test "$am_build_env_is_sane" = no; then + AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi -AC_MSG_RESULT([yes]) + # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & +AS_IF([test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1],, [dnl + ( sleep "$am_cv_filesystem_timestamp_resolution" ) & am_sleep_pid=$! -fi +]) AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then @@ -1726,18 +1861,18 @@ rm -f conftest.file ]) -# Copyright (C) 2009-2021 Free Software Foundation, Inc. +# Copyright (C) 2009-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. -# AM_SILENT_RULES([DEFAULT]) -# -------------------------- -# Enable less verbose build rules; with the default set to DEFAULT -# ("yes" being less verbose, "no" or empty being verbose). -AC_DEFUN([AM_SILENT_RULES], -[AC_ARG_ENABLE([silent-rules], [dnl +# _AM_SILENT_RULES +# ---------------- +# Enable less verbose build rules support. +AC_DEFUN([_AM_SILENT_RULES], +[AM_DEFAULT_VERBOSITY=1 +AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) @@ -1745,11 +1880,6 @@ [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) -case $enable_silent_rules in @%:@ ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; -esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. @@ -1768,14 +1898,6 @@ else am_cv_make_support_nested_variables=no fi]) -if test $am_cv_make_support_nested_variables = yes; then - dnl Using '$V' instead of '$(V)' breaks IRIX make. - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl @@ -1784,9 +1906,33 @@ AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +dnl Delay evaluation of AM_DEFAULT_VERBOSITY to the end to allow multiple calls +dnl to AM_SILENT_RULES to change the default value. +AC_CONFIG_COMMANDS_PRE([dnl +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; +esac +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +])dnl ]) -# Copyright (C) 2001-2021 Free Software Foundation, Inc. +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Set the default verbosity level to DEFAULT ("yes" being less verbose, "no" or +# empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_REQUIRE([_AM_SILENT_RULES]) +AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1])]) + +# Copyright (C) 2001-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1814,7 +1960,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2021 Free Software Foundation, Inc. +# Copyright (C) 2006-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1833,7 +1979,7 @@ # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2021 Free Software Foundation, Inc. +# Copyright (C) 2004-2024 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1879,15 +2025,19 @@ am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) - if test $am_uid -le $am_max_uid; then - AC_MSG_RESULT([yes]) + if test x$am_uid = xunknown; then + AC_MSG_WARN([ancient id detected; assuming current UID is ok, but dist-ustar might not work]) + elif test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) else - AC_MSG_RESULT([no]) - _am_tools=none + AC_MSG_RESULT([no]) + _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) - if test $am_gid -le $am_max_gid; then - AC_MSG_RESULT([yes]) + if test x$gm_gid = xunknown; then + AC_MSG_WARN([ancient id detected; assuming current GID is ok, but dist-ustar might not work]) + elif test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none @@ -1964,6 +2114,26 @@ AC_SUBST([am__untar]) ]) # _AM_PROG_TAR +# Copyright (C) 2022-2024 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_XARGS_N +# ---------------- +# Check whether 'xargs -n' works. It should work everywhere, so the fallback +# is not optimized at all as we never expect to use it. +AC_DEFUN([_AM_PROG_XARGS_N], +[AC_CACHE_CHECK([xargs -n works], am_cv_xargs_n_works, [dnl +AS_IF([test "`echo 1 2 3 | xargs -n2 echo`" = "1 2 +3"], [am_cv_xargs_n_works=yes], [am_cv_xargs_n_works=no])]) +AS_IF([test "$am_cv_xargs_n_works" = yes], [am__xargs_n='xargs -n'], [dnl + am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "$@" "$am__xargs_n_arg"; done; }' +])dnl +AC_SUBST(am__xargs_n) +]) + m4_include([m4/ax_check_compile_flag.m4]) m4_include([m4/ax_check_link_flag.m4]) m4_include([m4/ax_check_openssl.m4]) diff -Nru bind9-9.20.11/ar-lib bind9-9.20.15/ar-lib --- bind9-9.20.11/ar-lib 2025-07-04 09:43:10.564796432 +0000 +++ bind9-9.20.15/ar-lib 2025-10-18 10:17:03.744490279 +0000 @@ -2,9 +2,9 @@ # Wrapper for Microsoft lib.exe me=ar-lib -scriptversion=2019-07-04.01; # UTC +scriptversion=2024-06-19.01; # UTC -# Copyright (C) 2010-2021 Free Software Foundation, Inc. +# Copyright (C) 2010-2024 Free Software Foundation, Inc. # Written by Peter Rosin . # # This program is free software; you can redistribute it and/or modify @@ -105,11 +105,15 @@ Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...] Members may be specified in a file named with @FILE. + +Report bugs to . +GNU Automake home page: . +General help using GNU software: . EOF exit $? ;; -v | --v*) - echo "$me, version $scriptversion" + echo "$me (GNU Automake) $scriptversion" exit $? ;; esac @@ -135,6 +139,10 @@ AR="$AR $1" shift ;; + -nologo | -NOLOGO) + # We always invoke AR with -nologo, so don't need to add it again. + shift + ;; *) action=$1 shift diff -Nru bind9-9.20.11/bin/Makefile.in bind9-9.20.15/bin/Makefile.in --- bind9-9.20.11/bin/Makefile.in 2025-07-04 09:43:10.675799019 +0000 +++ bind9-9.20.15/bin/Makefile.in 2025-10-18 10:17:03.890492515 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -69,6 +69,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -351,8 +353,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -631,8 +635,8 @@ clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -737,3 +741,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/check/Makefile.in bind9-9.20.15/bin/check/Makefile.in --- bind9-9.20.11/bin/check/Makefile.in 2025-07-04 09:43:10.703799671 +0000 +++ bind9-9.20.15/bin/check/Makefile.in 2025-10-18 10:17:03.918492944 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -74,6 +74,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -370,8 +372,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -552,27 +556,20 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(bin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libcheck-tool.la: $(libcheck_tool_la_OBJECTS) $(libcheck_tool_la_DEPENDENCIES) $(EXTRA_libcheck_tool_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libcheck_tool_la_OBJECTS) $(libcheck_tool_la_LIBADD) $(LIBS) @@ -597,7 +594,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -750,23 +747,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/check-tool.Plo + -rm -f ./$(DEPDIR)/check-tool.Plo -rm -f ./$(DEPDIR)/named-checkconf.Po -rm -f ./$(DEPDIR)/named-checkzone.Po -rm -f Makefile @@ -819,7 +816,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/check-tool.Plo + -rm -f ./$(DEPDIR)/check-tool.Plo -rm -f ./$(DEPDIR)/named-checkconf.Po -rm -f ./$(DEPDIR)/named-checkzone.Po -rm -f Makefile @@ -882,3 +879,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/check/named-checkconf.c bind9-9.20.15/bin/check/named-checkconf.c --- bind9-9.20.11/bin/check/named-checkconf.c 2025-07-04 09:42:08.032321084 +0000 +++ bind9-9.20.15/bin/check/named-checkconf.c 2025-10-18 10:16:12.247727392 +0000 @@ -60,7 +60,7 @@ static void usage(void) { fprintf(stderr, - "usage: %s [-achijlvz] [-p [-x]] [-t directory] " + "usage: %s [-achijklvz] [-p [-x]] [-t directory] " "[named.conf]\n", program); exit(EXIT_SUCCESS); @@ -606,7 +606,7 @@ /* * Process memory debugging argument first. */ -#define CMDLINE_FLAGS "acdhijlm:t:pvxz" +#define CMDLINE_FLAGS "acdhijklm:t:pvxz" while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (c) { case 'm': @@ -653,6 +653,10 @@ nomerge = false; break; + case 'k': + checkflags |= BIND_CHECK_KEYS; + break; + case 'l': list_zones = true; break; diff -Nru bind9-9.20.11/bin/check/named-checkconf.rst bind9-9.20.15/bin/check/named-checkconf.rst --- bind9-9.20.11/bin/check/named-checkconf.rst 2025-07-04 09:42:08.032321084 +0000 +++ bind9-9.20.15/bin/check/named-checkconf.rst 2025-10-18 10:16:12.247727392 +0000 @@ -21,7 +21,7 @@ Synopsis ~~~~~~~~ -:program:`named-checkconf` [**-achjlvz**] [**-p** [**-x** ]] [**-t** directory] {filename} +:program:`named-checkconf` [**-achjklvz**] [**-p** [**-x** ]] [**-t** directory] {filename} Description ~~~~~~~~~~~ @@ -56,6 +56,12 @@ When loading a zonefile, this option instructs :iscman:`named` to read the journal if it exists. +.. option:: -k + + Check the `dnssec-policy`'s DNSSEC keys against the key files in + the `key-directory`. This is useful when checking a `named.conf` + to ensure a DNSSEC policy matches the existing keys. + .. option:: -l This option lists all the configured zones. Each line of output contains the zone diff -Nru bind9-9.20.11/bin/confgen/Makefile.in bind9-9.20.15/bin/confgen/Makefile.in --- bind9-9.20.11/bin/confgen/Makefile.in 2025-07-04 09:43:10.728800254 +0000 +++ bind9-9.20.15/bin/confgen/Makefile.in 2025-10-18 10:17:03.944493342 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -74,6 +74,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -369,8 +371,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -553,27 +557,20 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(sbindir)" && rm -f $$files + cd "$(DESTDIR)$(sbindir)" && $(am__rm_f) $$files clean-sbinPROGRAMS: - @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(sbin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(sbin_PROGRAMS:$(EXEEXT)=) clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libconfgen.la: $(libconfgen_la_OBJECTS) $(libconfgen_la_DEPENDENCIES) $(EXTRA_libconfgen_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libconfgen_la_OBJECTS) $(libconfgen_la_LIBADD) $(LIBS) @@ -600,7 +597,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -753,23 +750,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-sbinPROGRAMS mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/keygen.Plo + -rm -f ./$(DEPDIR)/keygen.Plo -rm -f ./$(DEPDIR)/os.Plo -rm -f ./$(DEPDIR)/rndc-confgen.Po -rm -f ./$(DEPDIR)/tsig-keygen.Po @@ -824,7 +821,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/keygen.Plo + -rm -f ./$(DEPDIR)/keygen.Plo -rm -f ./$(DEPDIR)/os.Plo -rm -f ./$(DEPDIR)/rndc-confgen.Po -rm -f ./$(DEPDIR)/tsig-keygen.Po @@ -889,3 +886,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/delv/Makefile.in bind9-9.20.15/bin/delv/Makefile.in --- bind9-9.20.11/bin/delv/Makefile.in 2025-07-04 09:43:10.751800790 +0000 +++ bind9-9.20.15/bin/delv/Makefile.in 2025-10-18 10:17:03.968493710 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -356,8 +358,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -541,16 +545,11 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(bin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) delv$(EXEEXT): $(delv_OBJECTS) $(delv_DEPENDENCIES) $(EXTRA_delv_DEPENDENCIES) @rm -f delv$(EXEEXT) @@ -566,7 +565,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -719,22 +718,22 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/delv.Po + -rm -f ./$(DEPDIR)/delv.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -784,7 +783,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/delv.Po + -rm -f ./$(DEPDIR)/delv.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -834,3 +833,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/dig/Makefile.in bind9-9.20.15/bin/dig/Makefile.in --- bind9-9.20.11/bin/dig/Makefile.in 2025-07-04 09:43:10.778801419 +0000 +++ bind9-9.20.15/bin/dig/Makefile.in 2025-10-18 10:17:03.996494139 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -74,6 +74,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -380,8 +382,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -564,27 +568,20 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(bin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libdighost.la: $(libdighost_la_OBJECTS) $(libdighost_la_DEPENDENCIES) $(EXTRA_libdighost_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdighost_la_OBJECTS) $(libdighost_la_LIBADD) $(LIBS) @@ -614,7 +611,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -781,23 +778,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/dig.Po + -rm -f ./$(DEPDIR)/dig.Po -rm -f ./$(DEPDIR)/dighost.Plo -rm -f ./$(DEPDIR)/host.Po -rm -f ./$(DEPDIR)/nslookup-nslookup.Po @@ -850,7 +847,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/dig.Po + -rm -f ./$(DEPDIR)/dig.Po -rm -f ./$(DEPDIR)/dighost.Plo -rm -f ./$(DEPDIR)/host.Po -rm -f ./$(DEPDIR)/nslookup-nslookup.Po @@ -904,3 +901,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/dig/dighost.c bind9-9.20.15/bin/dig/dighost.c --- bind9-9.20.11/bin/dig/dighost.c 2025-07-04 09:42:08.036321177 +0000 +++ bind9-9.20.15/bin/dig/dighost.c 2025-10-18 10:16:12.251727455 +0000 @@ -2754,6 +2754,7 @@ } query_detach(&query); lookup_detach(&l); + check_if_done(); return; } else if (eresult != ISC_R_SUCCESS) { debug("send failed: %s", isc_result_totext(eresult)); @@ -3027,7 +3028,6 @@ if (keep != NULL && isc_sockaddr_equal(&keepaddr, &query->sockaddr)) { query->handle = keep; launch_next_query(query); - query_detach(&query); return; } else if (keep != NULL) { isc_nmhandle_detach(&keep); diff -Nru bind9-9.20.11/bin/dnssec/Makefile.in bind9-9.20.15/bin/dnssec/Makefile.in --- bind9-9.20.11/bin/dnssec/Makefile.in 2025-07-04 09:43:10.811802188 +0000 +++ bind9-9.20.15/bin/dnssec/Makefile.in 2025-10-18 10:17:04.031494675 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -74,6 +74,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -426,8 +428,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -623,27 +627,20 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(bin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libdnssectool.la: $(libdnssectool_la_OBJECTS) $(libdnssectool_la_DEPENDENCIES) $(EXTRA_libdnssectool_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libdnssectool_la_OBJECTS) $(libdnssectool_la_LIBADD) $(LIBS) @@ -708,7 +705,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -889,23 +886,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool \ clean-noinstLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/dnssec-cds.Po + -rm -f ./$(DEPDIR)/dnssec-cds.Po -rm -f ./$(DEPDIR)/dnssec-dsfromkey.Po -rm -f ./$(DEPDIR)/dnssec-importkey.Po -rm -f ./$(DEPDIR)/dnssec-keyfromlabel.Po @@ -965,7 +962,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/dnssec-cds.Po + -rm -f ./$(DEPDIR)/dnssec-cds.Po -rm -f ./$(DEPDIR)/dnssec-dsfromkey.Po -rm -f ./$(DEPDIR)/dnssec-importkey.Po -rm -f ./$(DEPDIR)/dnssec-keyfromlabel.Po @@ -1026,3 +1023,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/dnssec/dnssec-cds.c bind9-9.20.15/bin/dnssec/dnssec-cds.c --- bind9-9.20.11/bin/dnssec/dnssec-cds.c 2025-07-04 09:42:08.037321201 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-cds.c 2025-10-18 10:16:12.252727470 +0000 @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -1083,6 +1084,7 @@ } isc_mem_destroy(&mctx); } + rcu_barrier(); } int diff -Nru bind9-9.20.11/bin/dnssec/dnssec-dsfromkey.c bind9-9.20.15/bin/dnssec/dnssec-dsfromkey.c --- bind9-9.20.11/bin/dnssec/dnssec-dsfromkey.c 2025-07-04 09:42:08.037321201 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-dsfromkey.c 2025-10-18 10:16:12.252727470 +0000 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -318,6 +319,11 @@ n = sizeof(dtype) / sizeof(dtype[0]); for (i = 0; i < n; i++) { + if (dtype[i] == DNS_DSDIGEST_SHA1) { + fprintf(stderr, + "WARNING: DS digest type %u is deprecated\n", + i); + } if (dtype[i] != 0) { emit(dtype[i], showall, cds, rdata); } @@ -336,10 +342,10 @@ fprintf(stderr, " %s [-h|-V]\n\n", program); fprintf(stderr, "Version: %s\n", PACKAGE_VERSION); fprintf(stderr, "Options:\n" - " -1: digest algorithm SHA-1\n" + " -1: digest algorithm SHA-1 (deprecated)\n" " -2: digest algorithm SHA-256\n" - " -a algorithm: digest algorithm (SHA-1, SHA-256 or " - "SHA-384)\n" + " -a algorithm: digest algorithm (SHA-1 " + "(deprecated), SHA-256 or SHA-384)\n" " -A: include all keys in DS set, not just KSKs (-f " "only)\n" " -c class: rdata class for DS set (default IN) (-f " @@ -555,6 +561,8 @@ } isc_mem_destroy(&mctx); + rcu_barrier(); + fflush(stdout); if (ferror(stdout)) { fprintf(stderr, "write error\n"); diff -Nru bind9-9.20.11/bin/dnssec/dnssec-dsfromkey.rst bind9-9.20.15/bin/dnssec/dnssec-dsfromkey.rst --- bind9-9.20.11/bin/dnssec/dnssec-dsfromkey.rst 2025-07-04 09:42:08.037321201 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-dsfromkey.rst 2025-10-18 10:16:12.252727470 +0000 @@ -32,30 +32,34 @@ Description ~~~~~~~~~~~ -The :program:`dnssec-dsfromkey` command outputs DS (Delegation Signer) resource records -(RRs), or CDS (Child DS) RRs with the :option:`-C` option. +The :program:`dnssec-dsfromkey` command outputs DS (Delegation +Signer) resource records (RRs), or CDS (Child DS) RRs with the +:option:`-C` option. By default, only KSKs are converted (keys with flags = 257). The -:option:`-A` option includes ZSKs (flags = 256). Revoked keys are never -included. +:option:`-A` option includes ZSKs (flags = 256). Revoked keys are +never included. The input keys can be specified in a number of ways: -By default, :program:`dnssec-dsfromkey` reads a key file named in the format -``Knnnn.+aaa+iiiii.key``, as generated by :iscman:`dnssec-keygen`. +By default, :program:`dnssec-dsfromkey` reads a key file named in +the format ``Knnnn.+aaa+iiiii.key``, as generated by +:iscman:`dnssec-keygen`. + +With the :option:`-f file <-f>` option, :program:`dnssec-dsfromkey` +reads keys from a zone file or partial zone file (which can contain +just the DNSKEY records). -With the :option:`-f file <-f>` option, :program:`dnssec-dsfromkey` reads keys from a zone -file or partial zone file (which can contain just the DNSKEY records). - -With the :option:`-s` option, :program:`dnssec-dsfromkey` reads a ``keyset-`` file, -as generated by :iscman:`dnssec-keygen` :option:`-C`. +With the :option:`-s` option, :program:`dnssec-dsfromkey` reads a +``keyset-`` file, as generated by :iscman:`dnssec-keygen` :option:`-C`. Options ~~~~~~~ .. option:: -1 - This option is an abbreviation for :option:`-a SHA1 <-a>`. + This option is an abbreviation for :option:`-a SHA1 <-a>`. This + digest is deprecated. .. option:: -2 @@ -63,24 +67,26 @@ .. option:: -a algorithm - This option specifies a digest algorithm to use when converting DNSKEY records to - DS records. This option can be repeated, so that multiple DS records - are created for each DNSKEY record. - - The algorithm must be one of SHA-1, SHA-256, or SHA-384. These values - are case-insensitive, and the hyphen may be omitted. If no algorithm - is specified, the default is SHA-256. + This option specifies a digest algorithm to use when converting + DNSKEY records to DS records. This option can be repeated, so + that multiple DS records are created for each DNSKEY record. + + The algorithm must be one of SHA-1 (deprecated), SHA-256, or + SHA-384. These values are case-insensitive, and the hyphen may + be omitted. If no algorithm is specified, the default is SHA-256. .. option:: -A - This option indicates that ZSKs are to be included when generating DS records. Without this option, only - keys which have the KSK flag set are converted to DS records and - printed. This option is only useful in :option:`-f` zone file mode. + This option indicates that ZSKs are to be included when generating + DS records. Without this option, only keys which have the KSK + flag set are converted to DS records and printed. This option + is only useful in :option:`-f` zone file mode. .. option:: -c class - This option specifies the DNS class; the default is IN. This option is only useful in :option:`-s` keyset - or :option:`-f` zone file mode. + This option specifies the DNS class; the default is IN. This + option is only useful in :option:`-s` keyset or :option:`-f` + zone file mode. .. option:: -C @@ -88,10 +94,10 @@ .. option:: -f file - This option sets zone file mode, in which the final dnsname argument of :program:`dnssec-dsfromkey` is the - DNS domain name of a zone whose master file can be read from - ``file``. If the zone name is the same as ``file``, then it may be - omitted. + This option sets zone file mode, in which the final dnsname + argument of :program:`dnssec-dsfromkey` is the DNS domain name + of a zone whose master file can be read from ``file``. If the + zone name is the same as ``file``, then it may be omitted. If ``file`` is ``-``, then the zone data is read from the standard input. This makes it possible to use the output of the :iscman:`dig` @@ -105,16 +111,19 @@ .. option:: -K directory - This option tells BIND 9 to look for key files or ``keyset-`` files in ``directory``. + This option tells BIND 9 to look for key files or ``keyset-`` + files in ``directory``. .. option:: -s - This option enables keyset mode, in which the final dnsname argument from :program:`dnssec-dsfromkey` is the DNS - domain name used to locate a ``keyset-`` file. + This option enables keyset mode, in which the final dnsname + argument from :program:`dnssec-dsfromkey` is the DNS domain name + used to locate a ``keyset-`` file. .. option:: -T TTL - This option specifies the TTL of the DS records. By default the TTL is omitted. + This option specifies the TTL of the DS records. By default the + TTL is omitted. .. option:: -v level diff -Nru bind9-9.20.11/bin/dnssec/dnssec-importkey.c bind9-9.20.15/bin/dnssec/dnssec-importkey.c --- bind9-9.20.11/bin/dnssec/dnssec-importkey.c 2025-07-04 09:42:08.037321201 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-importkey.c 2025-10-18 10:16:12.252727470 +0000 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -465,6 +466,8 @@ } isc_mem_destroy(&mctx); + rcu_barrier(); + fflush(stdout); if (ferror(stdout)) { fprintf(stderr, "write error\n"); diff -Nru bind9-9.20.11/bin/dnssec/dnssec-keyfromlabel.c bind9-9.20.15/bin/dnssec/dnssec-keyfromlabel.c --- bind9-9.20.11/bin/dnssec/dnssec-keyfromlabel.c 2025-07-04 09:42:08.038321224 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-keyfromlabel.c 2025-10-18 10:16:12.253727485 +0000 @@ -58,8 +58,8 @@ fprintf(stderr, " name: owner of the key\n"); fprintf(stderr, "Other options:\n"); fprintf(stderr, " -a algorithm: \n" - " RSASHA1 |\n" - " NSEC3RSASHA1 |\n" + " RSASHA1 (deprecated) |\n" + " NSEC3RSASHA1 (deprecated) |\n" " RSASHA256 | RSASHA512 |\n" " ECDSAP256SHA256 | ECDSAP384SHA384 |\n" " ED25519 | ED448\n"); @@ -582,6 +582,21 @@ fatal("invalid DNSKEY nametype %s", nametype); } + switch (alg) { + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: { + char algstr[DNS_SECALG_FORMATSIZE]; + dns_secalg_format(alg, algstr, sizeof(algstr)); + fprintf(stderr, + "WARNING: DNSKEY algorithm '%s' is deprecated. Please " + "migrate to another algorithm\n", + algstr); + break; + } + default: + break; + } + rdclass = strtoclass(classname); if (directory == NULL) { diff -Nru bind9-9.20.11/bin/dnssec/dnssec-keyfromlabel.rst bind9-9.20.15/bin/dnssec/dnssec-keyfromlabel.rst --- bind9-9.20.11/bin/dnssec/dnssec-keyfromlabel.rst 2025-07-04 09:42:08.038321224 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-keyfromlabel.rst 2025-10-18 10:16:12.253727485 +0000 @@ -41,27 +41,31 @@ .. option:: -a algorithm - This option selects the cryptographic algorithm. The value of ``algorithm`` must - be one of RSASHA1, NSEC3RSASHA1, RSASHA256, RSASHA512, - ECDSAP256SHA256, ECDSAP384SHA384, ED25519, or ED448. - - These values are case-insensitive. In some cases, abbreviations are - supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 for - ECDSAP384SHA384. If RSASHA1 is specified along with the :option:`-3` - option, then NSEC3RSASHA1 is used instead. + This option selects the cryptographic algorithm. The value of + ``algorithm`` must be one of RSASHA1 (deprecated), NSEC3RSASHA1 + (deprecated), RSASHA256, RSASHA512, ECDSAP256SHA256, ECDSAP384SHA384, + ED25519, or ED448. + + These values are case-insensitive. In some cases, abbreviations + are supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 + for ECDSAP384SHA384. If RSASHA1 (deprecated) is specified along + with the :option:`-3` option, then NSEC3RSASHA1 (deprecated) is + used instead. - This option is mandatory except when using the - :option:`-S` option, which copies the algorithm from the predecessory key. + This option is mandatory except when using the :option:`-S` + option, which copies the algorithm from the predecessory key. .. versionchanged:: 9.12.0 - The default value RSASHA1 for newly generated keys was removed. + The default value RSASHA1 (deprecated) for newly generated + keys was removed. .. option:: -3 - This option uses an NSEC3-capable algorithm to generate a DNSSEC key. If this - option is used with an algorithm that has both NSEC and NSEC3 - versions, then the NSEC3 version is used; for example, - ``dnssec-keygen -3a RSASHA1`` specifies the NSEC3RSASHA1 algorithm. + This option uses an NSEC3-capable algorithm to generate a DNSSEC + key. If this option is used with an algorithm that has both NSEC + and NSEC3 versions, then the NSEC3 version is used; for example, + ``dnssec-keygen -3a RSASHA1`` specifies the NSEC3RSASHA1 + (deprecated) algorithm. .. option:: -E engine diff -Nru bind9-9.20.11/bin/dnssec/dnssec-keygen.c bind9-9.20.15/bin/dnssec/dnssec-keygen.c --- bind9-9.20.11/bin/dnssec/dnssec-keygen.c 2025-07-04 09:42:08.038321224 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-keygen.c 2025-10-18 10:16:12.253727485 +0000 @@ -152,7 +152,8 @@ "statement\n"); fprintf(stderr, " -a :\n"); if (!isc_fips_mode()) { - fprintf(stderr, " RSASHA1 | NSEC3RSASHA1 |\n"); + fprintf(stderr, " RSASHA1 (deprecated) | NSEC3RSASHA1 " + "(deprecated) |\n"); } fprintf(stderr, " RSASHA256 | RSASHA512 |\n"); fprintf(stderr, " ECDSAP256SHA256 | ECDSAP384SHA384 |\n"); @@ -160,10 +161,11 @@ fprintf(stderr, " -3: use NSEC3-capable algorithm\n"); fprintf(stderr, " -b :\n"); if (!isc_fips_mode()) { - fprintf(stderr, " RSASHA1:\t[%d..%d]\n", min_rsa, - MAX_RSA); - fprintf(stderr, " NSEC3RSASHA1:\t[%d..%d]\n", min_rsa, - MAX_RSA); + fprintf(stderr, " RSASHA1 (deprecated) :\t[%d..%d]\n", + min_rsa, MAX_RSA); + fprintf(stderr, + " NSEC3RSASHA1 (deprecated) :\t[%d..%d]\n", + min_rsa, MAX_RSA); } fprintf(stderr, " RSASHA256:\t[%d..%d]\n", min_rsa, MAX_RSA); fprintf(stderr, " RSASHA512:\t[%d..%d]\n", min_rsa, MAX_RSA); @@ -502,14 +504,27 @@ } switch (ctx->alg) { - case DNS_KEYALG_RSASHA1: - case DNS_KEYALG_NSEC3RSASHA1: + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + dns_secalg_format(ctx->alg, algstr, sizeof(algstr)); + fprintf(stderr, + "WARNING: DNSKEY algorithm '%s' is deprecated. Please " + "migrate to another algorithm\n", + algstr); + break; + default: + break; + } + + switch (ctx->alg) { + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: if (isc_fips_mode()) { fatal("SHA1 based keys not supported in FIPS mode"); } FALLTHROUGH; - case DNS_KEYALG_RSASHA256: - case DNS_KEYALG_RSASHA512: + case DST_ALG_RSASHA256: + case DST_ALG_RSASHA512: if (ctx->size != 0 && (ctx->size < min_rsa || ctx->size > MAX_RSA)) { diff -Nru bind9-9.20.11/bin/dnssec/dnssec-keygen.rst bind9-9.20.15/bin/dnssec/dnssec-keygen.rst --- bind9-9.20.11/bin/dnssec/dnssec-keygen.rst 2025-07-04 09:42:08.038321224 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-keygen.rst 2025-10-18 10:16:12.253727485 +0000 @@ -38,21 +38,24 @@ .. option:: -3 - This option uses an NSEC3-capable algorithm to generate a DNSSEC key. If this - option is used with an algorithm that has both NSEC and NSEC3 - versions, then the NSEC3 version is selected; for example, - ``dnssec-keygen -3 -a RSASHA1`` specifies the NSEC3RSASHA1 algorithm. + This option uses an NSEC3-capable algorithm to generate a DNSSEC + key. If this option is used with an algorithm that has both NSEC + and NSEC3 versions, then the NSEC3 version is selected; for + example, ``dnssec-keygen -3 -a RSASHA1`` specifies the NSEC3RSASHA1 + (deprecated) algorithm. .. option:: -a algorithm - This option selects the cryptographic algorithm. For DNSSEC keys, the value of - ``algorithm`` must be one of RSASHA1, NSEC3RSASHA1, RSASHA256, - RSASHA512, ECDSAP256SHA256, ECDSAP384SHA384, ED25519, or ED448. - - These values are case-insensitive. In some cases, abbreviations are - supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 for - ECDSAP384SHA384. If RSASHA1 is specified along with the :option:`-3` - option, NSEC3RSASHA1 is used instead. + This option selects the cryptographic algorithm. For DNSSEC keys, + the value of ``algorithm`` must be one of RSASHA1 (deprecated), + NSEC3RSASHA1 (deprecated), RSASHA256, RSASHA512, ECDSAP256SHA256, + ECDSAP384SHA384, ED25519, or ED448. + + These values are case-insensitive. In some cases, abbreviations + are supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 + for ECDSAP384SHA384. If RSASHA1 (deprecated) is specified along + with the :option:`-3` option, NSEC3RSASHA1 (deprecated) is used + instead. This parameter *must* be specified except when using the :option:`-S` option, which copies the algorithm from the predecessor key. diff -Nru bind9-9.20.11/bin/dnssec/dnssec-signzone.c bind9-9.20.15/bin/dnssec/dnssec-signzone.c --- bind9-9.20.11/bin/dnssec/dnssec-signzone.c 2025-07-04 09:42:08.039321248 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-signzone.c 2025-10-18 10:16:12.254727501 +0000 @@ -60,6 +60,7 @@ #include #include #include +#include #include #include @@ -3204,6 +3205,8 @@ } static void +print_time(FILE *fp) ISC_ATTR_NONNULL(1); +static void print_time(FILE *fp) { time_t currenttime = time(NULL); struct tm t, *tm = localtime_r(¤ttime, &t); @@ -3220,6 +3223,8 @@ } static void +print_version(FILE *fp) ISC_ATTR_NONNULL(1); +static void print_version(FILE *fp) { if (outputformat != dns_masterformat_text) { return; @@ -4057,6 +4062,7 @@ fatal("failed to open temporary output file: %s", isc_result_totext(result)); } + INSIST(outfp != NULL); removefile = true; setfatalcallback(&removetempfile); } @@ -4175,5 +4181,7 @@ } isc_mutex_destroy(&namelock); + rcu_barrier(); + return vresult == ISC_R_SUCCESS ? 0 : 1; } diff -Nru bind9-9.20.11/bin/dnssec/dnssec-verify.c bind9-9.20.15/bin/dnssec/dnssec-verify.c --- bind9-9.20.11/bin/dnssec/dnssec-verify.c 2025-07-04 09:42:08.040321271 +0000 +++ bind9-9.20.15/bin/dnssec/dnssec-verify.c 2025-10-18 10:16:12.255727517 +0000 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -342,5 +343,7 @@ } isc_mem_destroy(&mctx); + rcu_barrier(); + return result == ISC_R_SUCCESS ? 0 : 1; } diff -Nru bind9-9.20.11/bin/dnssec/dnssectool.c bind9-9.20.15/bin/dnssec/dnssectool.c --- bind9-9.20.11/bin/dnssec/dnssectool.c 2025-07-04 09:42:08.040321271 +0000 +++ bind9-9.20.15/bin/dnssec/dnssectool.c 2025-10-18 10:16:12.255727517 +0000 @@ -628,6 +628,9 @@ const cfg_obj_t *keystores = NULL; dns_keystore_t *ks = NULL, *ks_next; dns_keystorelist_t kslist; + unsigned int options = (ISCCFG_KASPCONF_CHECK_ALGORITHMS | + ISCCFG_KASPCONF_CHECK_KEYLIST | + ISCCFG_KASPCONF_LOG_ERRORS); ISC_LIST_INIT(kasplist); ISC_LIST_INIT(kslist); @@ -668,7 +671,7 @@ continue; } - result = cfg_kasp_fromconfig(kconfig, NULL, true, mctx, lctx, + result = cfg_kasp_fromconfig(kconfig, NULL, options, mctx, lctx, &kslist, &kasplist, &kasp); if (result != ISC_R_SUCCESS) { fatal("failed to configure dnssec-policy '%s': %s", diff -Nru bind9-9.20.11/bin/named/Makefile.in bind9-9.20.15/bin/named/Makefile.in --- bind9-9.20.11/bin/named/Makefile.in 2025-07-04 09:43:10.838802817 +0000 +++ bind9-9.20.15/bin/named/Makefile.in 2025-10-18 10:17:04.058495088 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -416,8 +418,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -616,16 +620,11 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(sbindir)" && rm -f $$files + cd "$(DESTDIR)$(sbindir)" && $(am__rm_f) $$files clean-sbinPROGRAMS: - @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(sbin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(sbin_PROGRAMS:$(EXEEXT)=) named$(EXEEXT): $(named_OBJECTS) $(named_DEPENDENCIES) $(EXTRA_named_DEPENDENCIES) @rm -f named$(EXEEXT) @@ -658,7 +657,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -811,23 +810,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/builtin.Po + -rm -f ./$(DEPDIR)/builtin.Po -rm -f ./$(DEPDIR)/config.Po -rm -f ./$(DEPDIR)/control.Po -rm -f ./$(DEPDIR)/controlconf.Po @@ -894,7 +893,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/builtin.Po + -rm -f ./$(DEPDIR)/builtin.Po -rm -f ./$(DEPDIR)/config.Po -rm -f ./$(DEPDIR)/control.Po -rm -f ./$(DEPDIR)/controlconf.Po @@ -969,3 +968,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/named/config.c bind9-9.20.15/bin/named/config.c --- bind9-9.20.11/bin/named/config.c 2025-07-04 09:42:08.041321294 +0000 +++ bind9-9.20.15/bin/named/config.c 2025-10-18 10:16:12.256727532 +0000 @@ -123,7 +123,6 @@ tcp-listen-queue 10;\n\ tcp-receive-buffer 0;\n\ tcp-send-buffer 0;\n\ -# tkey-domain \n\ # tkey-gssapi-credential \n\ transfer-message-size 20480;\n\ transfers-in 10;\n\ @@ -306,6 +305,7 @@ cds-digest-types { 2; };\n\ dnskey-ttl " DNS_KASP_KEY_TTL ";\n\ inline-signing yes;\n\ + manual-mode no;\n\ offline-ksk no;\n\ publish-safety " DNS_KASP_PUBLISH_SAFETY "; \n\ retire-safety " DNS_KASP_RETIRE_SAFETY "; \n\ @@ -324,6 +324,7 @@ max-zone-ttl 0; \n\ keys { };\n\ inline-signing yes;\n\ + manual-mode no;\n\ };\n\ \n\ " diff -Nru bind9-9.20.11/bin/named/main.c bind9-9.20.15/bin/named/main.c --- bind9-9.20.11/bin/named/main.c 2025-07-04 09:42:08.044321365 +0000 +++ bind9-9.20.15/bin/named/main.c 2025-10-18 10:16:12.259727579 +0000 @@ -142,6 +142,7 @@ static bool nonearest = false; static bool nosoa = false; static bool notcp = false; +static bool rpzslow = false; static bool sigvalinsecs = false; static bool transferinsecs = false; static bool transferslowly = false; @@ -789,6 +790,8 @@ if (dns_zone_mkey_month < dns_zone_mkey_day) { named_main_earlyfatal("bad mkeytimer"); } + } else if (!strcmp(option, "rpzslow")) { + rpzslow = true; } else if (!strcmp(option, "sigvalinsecs")) { sigvalinsecs = true; } else if (!strcmp(option, "transferinsecs")) { @@ -1368,6 +1371,9 @@ if (notcp) { ns_server_setoption(sctx, NS_SERVER_NOTCP, true); } + if (rpzslow) { + ns_server_setoption(sctx, NS_SERVER_RPZSLOW, true); + } if (sigvalinsecs) { ns_server_setoption(sctx, NS_SERVER_SIGVALINSECS, true); } diff -Nru bind9-9.20.11/bin/named/server.c bind9-9.20.15/bin/named/server.c --- bind9-9.20.11/bin/named/server.c 2025-07-04 09:42:08.046321412 +0000 +++ bind9-9.20.15/bin/named/server.c 2025-10-18 10:16:12.261727610 +0000 @@ -427,10 +427,11 @@ "255.255.255.255.IN-ADDR.ARPA", /* BROADCAST */ /* Local IPv6 Unicast Addresses */ - "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6." - "ARPA", - "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6." - "ARPA", + /* clang-format off */ + "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", + "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA", + /* clang-format on */ + /* LOCALLY ASSIGNED LOCAL ADDRESS SCOPE */ "D.F.IP6.ARPA", "8.E.F.IP6.ARPA", /* LINK LOCAL */ "9.E.F.IP6.ARPA", /* LINK LOCAL */ @@ -2459,7 +2460,7 @@ static isc_result_t configure_rpz(dns_view_t *view, dns_view_t *pview, const cfg_obj_t **maps, - const cfg_obj_t *rpz_obj, bool *old_rpz_okp) { + const cfg_obj_t *rpz_obj, bool *old_rpz_okp, bool first_time) { bool dnsrps_enabled; const cfg_listelt_t *zone_element; char *rps_cstr; @@ -2544,7 +2545,7 @@ #endif /* ifndef USE_DNSRPS */ result = dns_rpz_new_zones(view, named_g_loopmgr, rps_cstr, - rps_cstr_size, &view->rpzs); + rps_cstr_size, &view->rpzs, first_time); if (result != ISC_R_SUCCESS) { return result; } @@ -2553,6 +2554,8 @@ zones->p.nsip_on = nsip_on; zones->p.nsdname_on = nsdname_on; + zones->p.slow_mode = ns_server_getoption(named_g_server->sctx, + NS_SERVER_RPZSLOW); sub_obj = cfg_tuple_get(rpz_obj, "recursive-only"); if (!cfg_obj_isvoid(sub_obj) && !cfg_obj_asboolean(sub_obj)) { @@ -2617,6 +2620,20 @@ zones->p.nsip_wait_recurse = false; } + sub_obj = cfg_tuple_get(rpz_obj, "servfail-until-ready"); + if (!cfg_obj_isvoid(sub_obj) && cfg_obj_asboolean(sub_obj)) { + zones->p.servfail_until_ready = true; + } else { + zones->p.servfail_until_ready = false; + } + + if (dnsrps_enabled && zones->p.servfail_until_ready) { + zones->p.servfail_until_ready = false; + cfg_obj_log(rpz_obj, named_g_lctx, ISC_LOG_WARNING, + "\"servfail-until-ready yes\" has no effect when " + "used with \"dnsrps-enable yes\""); + } + if (pview != NULL) { old = pview->rpzs; } else { @@ -2680,11 +2697,24 @@ } if (*old_rpz_okp) { + INSIST(pview->rpzs != NULL); + + /* Discard the newly created rpzs. */ dns_rpz_zones_shutdown(view->rpzs); dns_rpz_zones_detach(&view->rpzs); + + /* + * We are reusing the old rpzs, so it can no longer be its + * first time. + */ + pview->rpzs->first_time = false; + + /* Reuse rpzs from the old view. */ dns_rpz_zones_attach(pview->rpzs, &view->rpzs); dns_rpz_zones_detach(&pview->rpzs); } else if (old != NULL && pview != NULL) { + INSIST(pview->rpzs != NULL); + ++pview->rpzs->rpz_ver; view->rpzs->rpz_ver = pview->rpzs->rpz_ver; cfg_obj_log(rpz_obj, named_g_lctx, DNS_RPZ_DEBUG_LEVEL1, @@ -3161,9 +3191,11 @@ const char *str; isc_result_t result; dns_name_t origin; + dns_ipkeylist_t ipkl; dns_catz_options_t *opts; dns_name_init(&origin, NULL); + dns_ipkeylist_init(&ipkl); catz_obj = cfg_listelt_value(element); str = cfg_obj_asstring(cfg_tuple_get(catz_obj, "zone name")); @@ -3180,6 +3212,22 @@ goto cleanup; } + obj = cfg_tuple_get(catz_obj, "default-masters"); + if (obj == NULL || !cfg_obj_istuple(obj)) { + obj = cfg_tuple_get(catz_obj, "default-primaries"); + } + if (obj != NULL && cfg_obj_istuple(obj)) { + result = named_config_getipandkeylist(config, obj, view->mctx, + &ipkl); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(catz_obj, named_g_lctx, + DNS_CATZ_ERROR_LEVEL, + "catz: default-primaries parse error: %s", + isc_result_totext(result)); + goto cleanup; + } + } + result = dns_catz_zone_add(view->catzs, &origin, &zone); if (result == ISC_R_EXISTS) { catz_reconfig_data_t data = { @@ -3197,18 +3245,24 @@ view); dns_catz_zone_for_each_entry2(zone, catz_reconfigure, view, &data); + + result = ISC_R_SUCCESS; + } else if (result != ISC_R_SUCCESS) { + cfg_obj_log(catz_obj, named_g_lctx, DNS_CATZ_ERROR_LEVEL, + "catz: dns_catz_zone_add failed: %s", + isc_result_totext(result)); + goto cleanup; } dns_catz_zone_resetdefoptions(zone); opts = dns_catz_zone_getdefoptions(zone); - - obj = cfg_tuple_get(catz_obj, "default-masters"); - if (obj == NULL || !cfg_obj_istuple(obj)) { - obj = cfg_tuple_get(catz_obj, "default-primaries"); - } - if (obj != NULL && cfg_obj_istuple(obj)) { - result = named_config_getipandkeylist(config, obj, view->mctx, - &opts->masters); + if (ipkl.count != 0) { + /* + * Transfer the ownership of the pointers inside 'ipkl' and + * set its count to 0 in order to not cleanup it later below. + */ + opts->masters = ipkl; + ipkl.count = 0; } obj = cfg_tuple_get(catz_obj, "in-memory"); @@ -3237,6 +3291,9 @@ cleanup: dns_name_free(&origin, view->mctx); + if (ipkl.count != 0) { + dns_ipkeylist_clear(view->mctx, &ipkl); + } return result; } @@ -4141,7 +4198,8 @@ cfg_obj_t *vconfig, named_cachelist_t *cachelist, named_cachelist_t *oldcachelist, dns_kasplist_t *kasplist, dns_keystorelist_t *keystores, const cfg_obj_t *bindkeys, - isc_mem_t *mctx, cfg_aclconfctx_t *actx, bool need_hints) { + isc_mem_t *mctx, cfg_aclconfctx_t *actx, bool need_hints, + bool first_time) { const cfg_obj_t *maps[4]; const cfg_obj_t *cfgmaps[3]; const cfg_obj_t *optionmaps[3]; @@ -4248,7 +4306,8 @@ if (view->rdclass == dns_rdataclass_in && need_hints && named_config_get(maps, "response-policy", &obj) == ISC_R_SUCCESS) { - CHECK(configure_rpz(view, NULL, maps, obj, &old_rpz_ok)); + CHECK(configure_rpz(view, NULL, maps, obj, &old_rpz_ok, + first_time)); rpz_configured = true; } @@ -4780,13 +4839,15 @@ dns_cache_getname(nsc->cache)); nsc = NULL; } else { + shared_cache = true; + dns_cache_attach(nsc->cache, &cache); if (oldcache) { - ISC_LIST_UNLINK(*oldcachelist, nsc, link); - ISC_LIST_APPEND(*cachelist, nsc, link); - nsc->primaryview = view; + /* + * We need to re-use the cache, but we don't + * want to mutate the old production list. + */ + nsc = NULL; } - dns_cache_attach(nsc->cache, &cache); - shared_cache = true; } } else if (strcmp(cachename, view->name) == 0) { result = dns_viewlist_find(&named_g_server->viewlist, cachename, @@ -6169,7 +6230,8 @@ * done previously in the "correct" order. */ result2 = configure_rpz(pview, view, maps, obj, - &old_rpz_ok); + &old_rpz_ok, + first_time); if (result2 != ISC_R_SUCCESS) { isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, @@ -7063,7 +7125,7 @@ * Ensure that zone keys are reloaded on reconfig */ if ((dns_zone_getkeyopts(zone) & DNS_ZONEKEY_MAINTAIN) != 0) { - dns_zone_rekey(zone, fullsign); + dns_zone_rekey(zone, fullsign, false); } cleanup: @@ -8380,6 +8442,9 @@ dns_kasp_t *kasp_next = NULL; dns_kasp_t *default_kasp = NULL; dns_kasplist_t tmpkasplist, kasplist; + unsigned int kaspopts = (ISCCFG_KASPCONF_CHECK_ALGORITHMS | + ISCCFG_KASPCONF_CHECK_KEYLIST | + ISCCFG_KASPCONF_LOG_ERRORS); dns_keystore_t *keystore = NULL; dns_keystore_t *keystore_next = NULL; dns_keystorelist_t tmpkeystorelist, keystorelist; @@ -9213,7 +9278,7 @@ cfg_obj_t *kconfig = cfg_listelt_value(element); kasp = NULL; - result = cfg_kasp_fromconfig(kconfig, default_kasp, true, + result = cfg_kasp_fromconfig(kconfig, default_kasp, kaspopts, named_g_mctx, named_g_lctx, &keystorelist, &kasplist, &kasp); if (result != ISC_R_SUCCESS) { @@ -9242,7 +9307,7 @@ { cfg_obj_t *kconfig = cfg_listelt_value(element); kasp = NULL; - result = cfg_kasp_fromconfig(kconfig, default_kasp, true, + result = cfg_kasp_fromconfig(kconfig, default_kasp, kaspopts, named_g_mctx, named_g_lctx, &keystorelist, &kasplist, &kasp); if (result != ISC_R_SUCCESS) { @@ -9363,11 +9428,11 @@ goto cleanup_cachelist; } - result = configure_view(view, &viewlist, config, vconfig, - &cachelist, &server->cachelist, - &server->kasplist, - &server->keystorelist, bindkeys, - named_g_mctx, named_g_aclconfctx, true); + result = configure_view( + view, &viewlist, config, vconfig, &cachelist, + &server->cachelist, &server->kasplist, + &server->keystorelist, bindkeys, named_g_mctx, + named_g_aclconfctx, true, first_time); if (result != ISC_R_SUCCESS) { dns_view_detach(&view); goto cleanup_cachelist; @@ -9386,11 +9451,11 @@ if (result != ISC_R_SUCCESS) { goto cleanup_cachelist; } - result = configure_view(view, &viewlist, config, NULL, - &cachelist, &server->cachelist, - &server->kasplist, - &server->keystorelist, bindkeys, - named_g_mctx, named_g_aclconfctx, true); + result = configure_view( + view, &viewlist, config, NULL, &cachelist, + &server->cachelist, &server->kasplist, + &server->keystorelist, bindkeys, named_g_mctx, + named_g_aclconfctx, true, first_time); if (result != ISC_R_SUCCESS) { dns_view_detach(&view); goto cleanup_cachelist; @@ -9420,7 +9485,7 @@ view, &viewlist, config, vconfig, &cachelist, &server->cachelist, &server->kasplist, &server->keystorelist, bindkeys, named_g_mctx, - named_g_aclconfctx, false); + named_g_aclconfctx, false, first_time); if (result != ISC_R_SUCCESS) { dns_view_detach(&view); goto cleanup_cachelist; @@ -12828,7 +12893,7 @@ } else if ((keyopts & DNS_ZONEKEY_MAINTAIN) == 0 && !fullsign) { result = ISC_R_NOPERM; } else { - dns_zone_rekey(zone, fullsign); + dns_zone_rekey(zone, fullsign, false); } dns_zone_detach(&zone); @@ -15174,6 +15239,8 @@ dns_dnsseckey_t *key; char *ptr, *zonetext = NULL; const char *msg = NULL; + /* variables for -step */ + bool forcestep = false; /* variables for -checkds */ bool checkds = false, dspublish = false; /* variables for -rollover */ @@ -15217,6 +15284,8 @@ rollover = true; } else if (strcasecmp(ptr, "-checkds") == 0) { checkds = true; + } else if (strcasecmp(ptr, "-step") == 0) { + forcestep = true; } else { CHECK(DNS_R_SYNTAX); } @@ -15373,7 +15442,7 @@ * Rekey after checkds command because the next key * event may have changed. */ - dns_zone_rekey(zone, false); + dns_zone_rekey(zone, false, false); if (use_keyid) { char tagbuf[6]; @@ -15423,7 +15492,7 @@ * Rekey after rollover command because the next key * event may have changed. */ - dns_zone_rekey(zone, false); + dns_zone_rekey(zone, false, false); if (use_keyid) { char tagbuf[6]; @@ -15447,7 +15516,10 @@ CHECK(putstr(text, isc_result_totext(ret))); break; } + } else if (forcestep) { + dns_zone_rekey(zone, false, true); } + CHECK(putnull(text)); cleanup: @@ -16919,7 +16991,7 @@ CHECK(putnull(text)); } else { /* Schedule a rekey */ - dns_zone_rekey(zone, false); + dns_zone_rekey(zone, false, false); } cleanup: diff -Nru bind9-9.20.11/bin/named/tkeyconf.c bind9-9.20.15/bin/named/tkeyconf.c --- bind9-9.20.11/bin/named/tkeyconf.c 2025-07-04 09:42:08.046321412 +0000 +++ bind9-9.20.15/bin/named/tkeyconf.c 2025-10-18 10:16:12.261727610 +0000 @@ -59,19 +59,6 @@ } obj = NULL; - result = cfg_map_get(options, "tkey-domain", &obj); - if (result == ISC_R_SUCCESS) { - s = cfg_obj_asstring(obj); - isc_buffer_constinit(&b, s, strlen(s)); - isc_buffer_add(&b, strlen(s)); - name = dns_fixedname_initname(&fname); - RETERR(dns_name_fromtext(name, &b, dns_rootname, 0, NULL)); - tctx->domain = isc_mem_get(mctx, sizeof(dns_name_t)); - dns_name_init(tctx->domain, NULL); - dns_name_dup(name, mctx, tctx->domain); - } - - obj = NULL; result = cfg_map_get(options, "tkey-gssapi-credential", &obj); if (result == ISC_R_SUCCESS) { s = cfg_obj_asstring(obj); diff -Nru bind9-9.20.11/bin/nsupdate/Makefile.in bind9-9.20.15/bin/nsupdate/Makefile.in --- bind9-9.20.11/bin/nsupdate/Makefile.in 2025-07-04 09:43:10.862803377 +0000 +++ bind9-9.20.15/bin/nsupdate/Makefile.in 2025-10-18 10:17:04.083495471 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -362,8 +364,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -544,16 +548,11 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(bin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) nsupdate$(EXEEXT): $(nsupdate_OBJECTS) $(nsupdate_DEPENDENCIES) $(EXTRA_nsupdate_DEPENDENCIES) @rm -f nsupdate$(EXEEXT) @@ -569,7 +568,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -722,22 +721,22 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/nsupdate.Po + -rm -f ./$(DEPDIR)/nsupdate.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -787,7 +786,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/nsupdate.Po + -rm -f ./$(DEPDIR)/nsupdate.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -837,3 +836,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/plugins/Makefile.in bind9-9.20.15/bin/plugins/Makefile.in --- bind9-9.20.11/bin/plugins/Makefile.in 2025-07-04 09:43:10.886803936 +0000 +++ bind9-9.20.15/bin/plugins/Makefile.in 2025-10-18 10:17:04.107495839 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -140,10 +142,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(pkglibdir)" LTLIBRARIES = $(pkglib_LTLIBRARIES) @@ -387,8 +388,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -554,15 +557,13 @@ done clean-pkglibLTLIBRARIES: - -test -z "$(pkglib_LTLIBRARIES)" || rm -f $(pkglib_LTLIBRARIES) + -$(am__rm_f) $(pkglib_LTLIBRARIES) @list='$(pkglib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} filter-a.la: $(filter_a_la_OBJECTS) $(filter_a_la_DEPENDENCIES) $(EXTRA_filter_a_la_DEPENDENCIES) $(AM_V_CCLD)$(filter_a_la_LINK) -rpath $(pkglibdir) $(filter_a_la_OBJECTS) $(filter_a_la_LIBADD) $(LIBS) @@ -581,7 +582,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -734,23 +735,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-pkglibLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/filter-a.Plo + -rm -f ./$(DEPDIR)/filter-a.Plo -rm -f ./$(DEPDIR)/filter-aaaa.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -801,7 +802,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/filter-a.Plo + -rm -f ./$(DEPDIR)/filter-a.Plo -rm -f ./$(DEPDIR)/filter-aaaa.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -853,3 +854,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/rndc/Makefile.in bind9-9.20.15/bin/rndc/Makefile.in --- bind9-9.20.11/bin/rndc/Makefile.in 2025-07-04 09:43:10.910804495 +0000 +++ bind9-9.20.15/bin/rndc/Makefile.in 2025-10-18 10:17:04.131496206 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -356,8 +358,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -544,16 +548,11 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(sbindir)" && rm -f $$files + cd "$(DESTDIR)$(sbindir)" && $(am__rm_f) $$files clean-sbinPROGRAMS: - @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(sbin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(sbin_PROGRAMS:$(EXEEXT)=) rndc$(EXEEXT): $(rndc_OBJECTS) $(rndc_DEPENDENCIES) $(EXTRA_rndc_DEPENDENCIES) @rm -f rndc$(EXEEXT) @@ -570,7 +569,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -723,23 +722,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/rndc.Po + -rm -f ./$(DEPDIR)/rndc.Po -rm -f ./$(DEPDIR)/util.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -790,7 +789,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/rndc.Po + -rm -f ./$(DEPDIR)/rndc.Po -rm -f ./$(DEPDIR)/util.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -841,3 +840,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/rndc/rndc.rst bind9-9.20.15/bin/rndc/rndc.rst --- bind9-9.20.11/bin/rndc/rndc.rst 2025-07-04 09:42:08.049321482 +0000 +++ bind9-9.20.15/bin/rndc/rndc.rst 2025-10-18 10:16:12.264727657 +0000 @@ -171,7 +171,7 @@ See also :option:`rndc addzone` and :option:`rndc modzone`. -.. option:: dnssec (-status | -rollover -key id [-alg algorithm] [-when time] | -checkds [-key id [-alg algorithm]] [-when time] published | withdrawn)) zone [class [view]] +.. option:: dnssec (-status | -step | -rollover -key id [-alg algorithm] [-when time] | -checkds [-key id [-alg algorithm]] [-when time] published | withdrawn)) zone [class [view]] This command allows you to interact with the "dnssec-policy" of a given zone. @@ -179,6 +179,13 @@ ``rndc dnssec -status`` show the DNSSEC signing state for the specified zone. + ``rndc dnssec -step`` sends a signal to an instance of :iscman:`named` for a + zone configured with ``dnssec-policy`` in manual mode, telling it to + continue with the operations that had previously been blocked but logged. + This gives the human operator a chance to review the log messages, + understand what will happen next and then, using ``rndc dnssec -step``, to + inform :iscman:`named` to proceed to the next stage. + ``rndc dnssec -rollover`` allows you to schedule key rollover for a specific key (overriding the original key lifetime). diff -Nru bind9-9.20.11/bin/tests/Makefile.in bind9-9.20.15/bin/tests/Makefile.in --- bind9-9.20.11/bin/tests/Makefile.in 2025-07-04 09:43:10.938805148 +0000 +++ bind9-9.20.15/bin/tests/Makefile.in 2025-10-18 10:17:04.160496650 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -405,8 +407,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -570,13 +574,8 @@ $(am__aclocal_m4_deps): clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(noinst_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=) test_client$(EXEEXT): $(test_client_OBJECTS) $(test_client_DEPENDENCIES) $(EXTRA_test_client_DEPENDENCIES) @rm -f test_client$(EXEEXT) @@ -602,7 +601,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -867,23 +866,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-recursive - -rm -f ./$(DEPDIR)/test_client-test_client.Po + -rm -f ./$(DEPDIR)/test_client-test_client.Po -rm -f ./$(DEPDIR)/test_server-test_server.Po -rm -f ./$(DEPDIR)/wire_test-wire_test.Po -rm -f Makefile @@ -935,7 +934,7 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -f ./$(DEPDIR)/test_client-test_client.Po + -rm -f ./$(DEPDIR)/test_client-test_client.Po -rm -f ./$(DEPDIR)/test_server-test_server.Po -rm -f ./$(DEPDIR)/wire_test-wire_test.Po -rm -f Makefile @@ -989,3 +988,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/tests/system/Makefile.am bind9-9.20.15/bin/tests/system/Makefile.am --- bind9-9.20.11/bin/tests/system/Makefile.am 2025-07-04 09:42:08.050321505 +0000 +++ bind9-9.20.15/bin/tests/system/Makefile.am 2025-10-18 10:16:12.265727672 +0000 @@ -113,7 +113,7 @@ ednscompliance \ emptyzones \ enginepkcs11 \ - filter-aaaa \ + filters \ fetchlimit \ formerr \ forward \ @@ -157,6 +157,19 @@ resolver \ rndc \ rollover \ + rollover-algo-csk \ + rollover-algo-ksk-zsk \ + rollover-csk-roll1 \ + rollover-csk-roll2 \ + rollover-dynamic2inline \ + rollover-enable-dnssec \ + rollover-going-insecure \ + rollover-ksk-3crowd \ + rollover-ksk-doubleksk \ + rollover-lifetime \ + rollover-multisigner \ + rollover-straight2none \ + rollover-zsk-prepub \ rootkeysentinel \ rpzextra \ rrchecker \ diff -Nru bind9-9.20.11/bin/tests/system/Makefile.in bind9-9.20.15/bin/tests/system/Makefile.in --- bind9-9.20.11/bin/tests/system/Makefile.in 2025-07-04 09:43:10.999806569 +0000 +++ bind9-9.20.15/bin/tests/system/Makefile.in 2025-10-18 10:17:04.222497600 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -285,10 +287,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* @@ -376,6 +377,7 @@ # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ + $$am__collect_skipped_logs \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the @@ -400,6 +402,11 @@ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ +if test -n '$(IGNORE_SKIPPED_LOGS)'; then \ + am__collect_skipped_logs='--collect-skipped-logs no'; \ +else \ + am__collect_skipped_logs=''; \ +fi; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ @@ -634,8 +641,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -816,7 +825,7 @@ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ ednscompliance \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ emptyzones \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ enginepkcs11 \ -@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ filter-aaaa \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ filters \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ fetchlimit \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ formerr \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ forward \ @@ -860,6 +869,19 @@ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ resolver \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rndc \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-algo-csk \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-algo-ksk-zsk \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-csk-roll1 \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-csk-roll2 \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-dynamic2inline \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-enable-dnssec \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-going-insecure \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-ksk-3crowd \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-ksk-doubleksk \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-lifetime \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-multisigner \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-straight2none \ +@HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rollover-zsk-prepub \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rootkeysentinel \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rpzextra \ @HAVE_PERL_TRUE@@HAVE_PYTEST_TRUE@@HAVE_PYTHON_TRUE@ rrchecker \ @@ -943,13 +965,8 @@ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(noinst_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=) feature-test$(EXEEXT): $(feature_test_OBJECTS) $(feature_test_DEPENDENCIES) $(EXTRA_feature_test_DEPENDENCIES) @rm -f feature-test$(EXEEXT) @@ -960,10 +977,10 @@ $(AM_V_CCLD)$(LINK) $(makejournal_OBJECTS) $(makejournal_LDADD) $(LIBS) pipelined/$(am__dirstamp): @$(MKDIR_P) pipelined - @: > pipelined/$(am__dirstamp) + @: >>pipelined/$(am__dirstamp) pipelined/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) pipelined/$(DEPDIR) - @: > pipelined/$(DEPDIR)/$(am__dirstamp) + @: >>pipelined/$(DEPDIR)/$(am__dirstamp) pipelined/pipequeries-pipequeries.$(OBJEXT): \ pipelined/$(am__dirstamp) pipelined/$(DEPDIR)/$(am__dirstamp) @@ -972,10 +989,10 @@ $(AM_V_CCLD)$(LINK) $(pipelined_pipequeries_OBJECTS) $(pipelined_pipequeries_LDADD) $(LIBS) rndc/$(am__dirstamp): @$(MKDIR_P) rndc - @: > rndc/$(am__dirstamp) + @: >>rndc/$(am__dirstamp) rndc/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) rndc/$(DEPDIR) - @: > rndc/$(DEPDIR)/$(am__dirstamp) + @: >>rndc/$(DEPDIR)/$(am__dirstamp) rndc/gencheck.$(OBJEXT): rndc/$(am__dirstamp) \ rndc/$(DEPDIR)/$(am__dirstamp) @@ -984,10 +1001,10 @@ $(AM_V_CCLD)$(LINK) $(rndc_gencheck_OBJECTS) $(rndc_gencheck_LDADD) $(LIBS) rpz/$(am__dirstamp): @$(MKDIR_P) rpz - @: > rpz/$(am__dirstamp) + @: >>rpz/$(am__dirstamp) rpz/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) rpz/$(DEPDIR) - @: > rpz/$(DEPDIR)/$(am__dirstamp) + @: >>rpz/$(DEPDIR)/$(am__dirstamp) rpz/dnsrps-dnsrps.$(OBJEXT): rpz/$(am__dirstamp) \ rpz/$(DEPDIR)/$(am__dirstamp) @@ -1012,7 +1029,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -1220,7 +1237,6 @@ am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: - $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ @@ -1296,10 +1312,37 @@ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ + output_system_information () \ + { \ + echo; \ + { uname -a | $(AWK) '{ \ + printf "System information (uname -a):"; \ + for (i = 1; i < NF; ++i) \ + { \ + if (i != 2) \ + printf " %s", $$i; \ + } \ + printf "\n"; \ +}'; } 2>&1; \ + if test -r /etc/os-release; then \ + echo "Distribution information (/etc/os-release):"; \ + sed 8q /etc/os-release; \ + elif test -r /etc/issue; then \ + echo "Distribution information (/etc/issue):"; \ + cat /etc/issue; \ + fi; \ + }; \ + please_report () \ + { \ +echo "Some test(s) failed. Please report this to $(PACKAGE_BUGREPORT),"; \ +echo "together with the test-suite.log file (gzipped) and your system"; \ +echo "information. Thanks."; \ + }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ + output_system_information; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ @@ -1319,26 +1362,25 @@ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG) for debugging.$${std}";\ if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @$(am__rm_f) $(RECHECK_LOGS) + @$(am__rm_f) $(RECHECK_LOGS:.log=.trs) + @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ @@ -1628,9 +1670,9 @@ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) -filter-aaaa.log: filter-aaaa - @p='filter-aaaa'; \ - b='filter-aaaa'; \ +filters.log: filters + @p='filters'; \ + b='filters'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ @@ -1936,6 +1978,97 @@ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-algo-csk.log: rollover-algo-csk + @p='rollover-algo-csk'; \ + b='rollover-algo-csk'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-algo-ksk-zsk.log: rollover-algo-ksk-zsk + @p='rollover-algo-ksk-zsk'; \ + b='rollover-algo-ksk-zsk'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-csk-roll1.log: rollover-csk-roll1 + @p='rollover-csk-roll1'; \ + b='rollover-csk-roll1'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-csk-roll2.log: rollover-csk-roll2 + @p='rollover-csk-roll2'; \ + b='rollover-csk-roll2'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-dynamic2inline.log: rollover-dynamic2inline + @p='rollover-dynamic2inline'; \ + b='rollover-dynamic2inline'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-enable-dnssec.log: rollover-enable-dnssec + @p='rollover-enable-dnssec'; \ + b='rollover-enable-dnssec'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-going-insecure.log: rollover-going-insecure + @p='rollover-going-insecure'; \ + b='rollover-going-insecure'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-ksk-3crowd.log: rollover-ksk-3crowd + @p='rollover-ksk-3crowd'; \ + b='rollover-ksk-3crowd'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-ksk-doubleksk.log: rollover-ksk-doubleksk + @p='rollover-ksk-doubleksk'; \ + b='rollover-ksk-doubleksk'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-lifetime.log: rollover-lifetime + @p='rollover-lifetime'; \ + b='rollover-lifetime'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-multisigner.log: rollover-multisigner + @p='rollover-multisigner'; \ + b='rollover-multisigner'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-straight2none.log: rollover-straight2none + @p='rollover-straight2none'; \ + b='rollover-straight2none'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +rollover-zsk-prepub.log: rollover-zsk-prepub + @p='rollover-zsk-prepub'; \ + b='rollover-zsk-prepub'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) rootkeysentinel.log: rootkeysentinel @p='rootkeysentinel'; \ b='rootkeysentinel'; \ @@ -2264,34 +2397,34 @@ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + -$(am__rm_f) $(TEST_LOGS) + -$(am__rm_f) $(TEST_LOGS:.log=.trs) + -$(am__rm_f) $(TEST_SUITE_LOG) clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f pipelined/$(DEPDIR)/$(am__dirstamp) - -rm -f pipelined/$(am__dirstamp) - -rm -f rndc/$(DEPDIR)/$(am__dirstamp) - -rm -f rndc/$(am__dirstamp) - -rm -f rpz/$(DEPDIR)/$(am__dirstamp) - -rm -f rpz/$(am__dirstamp) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) pipelined/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) pipelined/$(am__dirstamp) + -$(am__rm_f) rndc/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) rndc/$(am__dirstamp) + -$(am__rm_f) rpz/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) rpz/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-libtool clean-local clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-recursive - -rm -f ./$(DEPDIR)/feature_test-feature-test.Po + -rm -f ./$(DEPDIR)/feature_test-feature-test.Po -rm -f ./$(DEPDIR)/makejournal-makejournal.Po -rm -f pipelined/$(DEPDIR)/pipequeries-pipequeries.Po -rm -f rndc/$(DEPDIR)/gencheck.Po @@ -2345,7 +2478,7 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -f ./$(DEPDIR)/feature_test-feature-test.Po + -rm -f ./$(DEPDIR)/feature_test-feature-test.Po -rm -f ./$(DEPDIR)/makejournal-makejournal.Po -rm -f pipelined/$(DEPDIR)/pipequeries-pipequeries.Po -rm -f rndc/$(DEPDIR)/gencheck.Po @@ -2423,3 +2556,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/tests/system/additional/ns3/named.conf.in bind9-9.20.15/bin/tests/system/additional/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/additional/ns3/named.conf.in 2025-07-04 09:42:08.053321575 +0000 +++ bind9-9.20.15/bin/tests/system/additional/ns3/named.conf.in 2025-10-18 10:16:12.269727735 +0000 @@ -22,11 +22,10 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; minimal-responses no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/addzone/tests_rndc_deadlock.py bind9-9.20.15/bin/tests/system/addzone/tests_rndc_deadlock.py --- bind9-9.20.11/bin/tests/system/addzone/tests_rndc_deadlock.py 2025-07-04 09:42:08.056321646 +0000 +++ bind9-9.20.15/bin/tests/system/addzone/tests_rndc_deadlock.py 2025-10-18 10:16:12.271727766 +0000 @@ -59,13 +59,12 @@ return False -def test_rndc_deadlock(servers): +def test_rndc_deadlock(ns3): """ Test whether running "rndc addzone", "rndc modzone", and "rndc delzone" commands concurrently does not trigger a deadlock """ test_state = {"finished": False} - ns3 = servers["ns3"] # Create 4 worker threads running "rndc" commands in a loop. with concurrent.futures.ThreadPoolExecutor() as executor: diff -Nru bind9-9.20.11/bin/tests/system/autosign/tests_sh_autosign.py bind9-9.20.15/bin/tests/system/autosign/tests_sh_autosign.py --- bind9-9.20.11/bin/tests/system/autosign/tests_sh_autosign.py 2025-07-04 09:42:08.064321833 +0000 +++ bind9-9.20.15/bin/tests/system/autosign/tests_sh_autosign.py 2025-10-18 10:16:12.280727905 +0000 @@ -11,8 +11,6 @@ import pytest -import isctest.mark - pytestmark = pytest.mark.extra_artifacts( [ "active.key", @@ -151,6 +149,6 @@ ) -@isctest.mark.flaky(max_runs=2) +@pytest.mark.flaky(max_runs=2) def test_autosign(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/cacheclean/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/cacheclean/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/cacheclean/ns2/named.conf.j2 2025-07-04 09:42:08.066321880 +0000 +++ bind9-9.20.15/bin/tests/system/cacheclean/ns2/named.conf.j2 2025-10-18 10:16:12.282727936 +0000 @@ -22,10 +22,9 @@ notify yes; disable-empty-zone 127.IN-ADDR.ARPA; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/catz/ns1/named.conf.in bind9-9.20.15/bin/tests/system/catz/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/catz/ns1/named.conf.in 2025-07-04 09:42:08.069321950 +0000 +++ bind9-9.20.15/bin/tests/system/catz/ns1/named.conf.in 2025-10-18 10:16:12.285727983 +0000 @@ -38,6 +38,15 @@ view "default" { + zone "catalog0.example" { + type primary; + file "catalog0.example.db"; + allow-transfer { any; }; + allow-update { any; }; + also-notify { 10.53.0.2; }; + notify explicit; + }; + zone "catalog1.example" { type primary; file "catalog1.example.db"; diff -Nru bind9-9.20.11/bin/tests/system/catz/ns2/named1.conf.in bind9-9.20.15/bin/tests/system/catz/ns2/named1.conf.in --- bind9-9.20.11/bin/tests/system/catz/ns2/named1.conf.in 2025-07-04 09:42:08.069321950 +0000 +++ bind9-9.20.15/bin/tests/system/catz/ns2/named1.conf.in 2025-10-18 10:16:12.285727983 +0000 @@ -43,6 +43,9 @@ view "default" { catalog-zones { + zone "catalog0.example" + /* unset default-primaries, see GL#5494 */ + in-memory yes; zone "catalog1.example" default-masters { 10.53.0.1; } min-update-interval 1s @@ -108,6 +111,12 @@ forwarders { }; }; + zone "catalog0.example" { + type secondary; + file "catalog0.example.db"; + primaries { 10.53.0.1; }; + }; + zone "catalog1.example" { type secondary; file "catalog1.example.db"; diff -Nru bind9-9.20.11/bin/tests/system/catz/ns2/named2.conf.in bind9-9.20.15/bin/tests/system/catz/ns2/named2.conf.in --- bind9-9.20.11/bin/tests/system/catz/ns2/named2.conf.in 2025-07-04 09:42:08.069321950 +0000 +++ bind9-9.20.15/bin/tests/system/catz/ns2/named2.conf.in 2025-10-18 10:16:12.285727983 +0000 @@ -55,6 +55,12 @@ forwarders { }; }; + zone "catalog0.example" { + type secondary; + file "catalog0.example.db"; + primaries { 10.53.0.1; }; + }; + zone "catalog1.example" { type secondary; file "catalog1.example.db"; diff -Nru bind9-9.20.11/bin/tests/system/catz/setup.sh bind9-9.20.15/bin/tests/system/catz/setup.sh --- bind9-9.20.11/bin/tests/system/catz/setup.sh 2025-07-04 09:42:08.070321974 +0000 +++ bind9-9.20.15/bin/tests/system/catz/setup.sh 2025-10-18 10:16:12.286727999 +0000 @@ -18,6 +18,7 @@ copy_setports ns3/named.conf.in ns3/named.conf copy_setports ns4/named.conf.in ns4/named.conf +cp -f ns1/catalog.example.db.in ns1/catalog0.example.db cp -f ns1/catalog.example.db.in ns1/catalog1.example.db cp -f ns3/catalog.example.db.in ns3/catalog2.example.db cp -f ns1/catalog.example.db.in ns1/catalog3.example.db diff -Nru bind9-9.20.11/bin/tests/system/chain/ns1/named.conf.in bind9-9.20.15/bin/tests/system/chain/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/chain/ns1/named.conf.in 2025-07-04 09:42:08.072322021 +0000 +++ bind9-9.20.15/bin/tests/system/chain/ns1/named.conf.in 2025-10-18 10:16:12.287728014 +0000 @@ -20,10 +20,9 @@ listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion no; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; zone "." { type primary; file "root.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/chain/ns7/named.conf.in bind9-9.20.15/bin/tests/system/chain/ns7/named.conf.in --- bind9-9.20.11/bin/tests/system/chain/ns7/named.conf.in 2025-07-04 09:42:08.072322021 +0000 +++ bind9-9.20.15/bin/tests/system/chain/ns7/named.conf.in 2025-10-18 10:16:12.288728030 +0000 @@ -22,7 +22,7 @@ listen-on-v6 { fd92:7065:b8e:ffff::7; }; recursion yes; allow-recursion { any; }; - dnssec-validation yes; + dnssec-validation no; deny-answer-aliases { "example"; } except-from { @@ -31,7 +31,6 @@ qname-minimization disabled; // Regression test for GL #4652 }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/checkconf/good.conf.j2 bind9-9.20.15/bin/tests/system/checkconf/good.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf/good.conf.j2 2025-07-04 09:42:08.097322606 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf/good.conf.j2 2025-10-18 10:16:12.315728450 +0000 @@ -27,6 +27,7 @@ zsk lifetime P30D algorithm 13; csk key-store "hsm" lifetime P30D algorithm 8 2048; }; + manual-mode no; max-zone-ttl 86400; nsec3param ; parent-ds-ttl 7200; diff -Nru bind9-9.20.11/bin/tests/system/checkconf/kasp-deprecated-fips.conf bind9-9.20.15/bin/tests/system/checkconf/kasp-deprecated-fips.conf --- bind9-9.20.11/bin/tests/system/checkconf/kasp-deprecated-fips.conf 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf/kasp-deprecated-fips.conf 2025-10-18 10:16:12.316728465 +0000 @@ -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. + */ + +dnssec-policy deprecated { + cds-digest-types { sha1; }; + keys { + csk lifetime unlimited algorithm ecdsa256; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf/kasp-deprecated.conf bind9-9.20.15/bin/tests/system/checkconf/kasp-deprecated.conf --- bind9-9.20.11/bin/tests/system/checkconf/kasp-deprecated.conf 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf/kasp-deprecated.conf 2025-10-18 10:16:12.316728465 +0000 @@ -0,0 +1,20 @@ +/* + * 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. + */ + +dnssec-policy deprecated { + cds-digest-types { sha1; }; + keys { + csk lifetime unlimited algorithm rsasha1; + csk lifetime unlimited algorithm nsec3rsasha1; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf/tests.sh bind9-9.20.15/bin/tests/system/checkconf/tests.sh --- bind9-9.20.11/bin/tests/system/checkconf/tests.sh 2025-07-04 09:42:08.100322676 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf/tests.sh 2025-10-18 10:16:12.317728481 +0000 @@ -647,7 +647,7 @@ expect=2 else conf=kasp-bad-nsec3-iter.conf - expect=3 + expect=5 fi $CHECKCONF $conf >checkconf.out$n 2>&1 && ret=1 grep "dnssec-policy: nsec3 iterations value 1 not allowed, must be zero" /dev/null || ret=1 @@ -726,6 +726,20 @@ if [ $ret -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) +n=$((n + 1)) +echo_i "checking named-checkconf kasp deprecated algorithms and digests ($n)" +ret=0 +if [ $RSASHA1_SUPPORTED = 0 ]; then + $CHECKCONF kasp-deprecated-fips.conf >checkconf.out$n 2>&1 || ret=1 +else + $CHECKCONF kasp-deprecated.conf >checkconf.out$n 2>&1 || ret=1 + grep "dnssec-policy: DNSSEC algorithm rsasha1 is deprecated" checkconf.out$n >/dev/null || ret=1 + grep "dnssec-policy: DNSSEC algorithm nsec3rsasha1 is deprecated" checkconf.out$n >/dev/null || ret=1 +fi +grep "dnssec-policy: deprecated CDS digest-type sha1" checkconf.out$n >/dev/null || ret=1 +if [ $ret -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + n=$((n + 1)) echo_i "check that a good 'kasp' configuration is accepted ($n)" ret=0 diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-algorithm.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-algorithm.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-algorithm.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-algorithm.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -0,0 +1,25 @@ +/* + * 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. + */ + +dnssec-policy "alternative-kz" { + keys { + ksk key-directory lifetime unlimited algorithm RSASHA256; + zsk key-directory lifetime unlimited algorithm RSASHA256; + }; +}; + +zone "bad-algorithm.kz.example" { + type primary; + file "bad-algorithm.kz.example.db"; + dnssec-policy "alternative-kz"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-default-algorithm.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-default-algorithm.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-default-algorithm.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-default-algorithm.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -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 "bad-default-algorithm.example" { + type primary; + file "bad-default-algorithm.example.db"; + dnssec-policy "default"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-default-kz.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-default-kz.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-default-kz.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-default-kz.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -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 "bad-default-kz.example" { + type primary; + file "bad-default-kz.example.db"; + dnssec-policy "default"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-keystore.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-keystore.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-keystore.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-keystore.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -0,0 +1,33 @@ +/* + * 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. + */ + +key-store "ksk" { + directory "ksk"; +}; + +key-store "zsk" { + directory "zsk"; +}; + +dnssec-policy "keystores-kz" { + keys { + ksk key-store "ksk" lifetime unlimited algorithm ECDSAP256SHA256; + zsk key-store "zsk" lifetime unlimited algorithm ECDSAP256SHA256; + }; +}; + +zone "bad-keystores.kz.example" { + type primary; + file "bad-keystores.kz.example.db"; + dnssec-policy "keystores-kz"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-length.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-length.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-length.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-length.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -0,0 +1,24 @@ +/* + * 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. + */ + +dnssec-policy "alternative-csk" { + keys { + csk key-directory lifetime unlimited algorithm RSASHA256 2048; + }; +}; + +zone "bad-length.csk.example" { + type primary; + file "bad-length.csk.example.db"; + dnssec-policy "alternative-csk"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-missing-keyfile.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-missing-keyfile.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-missing-keyfile.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-missing-keyfile.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -0,0 +1,25 @@ +/* + * 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. + */ + +dnssec-policy "default-kz" { + keys { + ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + }; +}; + +zone "missing-keyfile.kz.example" { + type primary; + file "missing-keyfile.kz.example.db"; + dnssec-policy "default-kz"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-role.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-role.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-role.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-role.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -0,0 +1,25 @@ +/* + * 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. + */ + +dnssec-policy "default-kz" { + keys { + ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + }; +}; + +zone "bad-role.kz.example" { + type primary; + file "bad-role.kz.example.db"; + dnssec-policy "default-kz"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-superfluous-keyfile.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-superfluous-keyfile.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-superfluous-keyfile.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-superfluous-keyfile.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -0,0 +1,25 @@ +/* + * 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. + */ + +dnssec-policy "default-kz" { + keys { + ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + }; +}; + +zone "superfluous-keyfile.kz.example" { + type primary; + file "superfluous-keyfile.kz.example.db"; + dnssec-policy "default-kz"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/bad-tagrange.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/bad-tagrange.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/bad-tagrange.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/bad-tagrange.conf.j2 2025-10-18 10:16:12.289728045 +0000 @@ -0,0 +1,24 @@ +/* + * 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. + */ + +dnssec-policy "tagrange-csk" { + keys { + csk key-directory lifetime unlimited algorithm ECDSAP256SHA256 tag-range 0 32767; + }; +}; + +zone "bad-tagrange.csk.example" { + type primary; + file "bad-tagrange.csk.example.db"; + dnssec-policy "tagrange-csk"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/named.conf.j2 bind9-9.20.15/bin/tests/system/checkconf-keys/named.conf.j2 --- bind9-9.20.11/bin/tests/system/checkconf-keys/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/named.conf.j2 2025-10-18 10:16:12.290728061 +0000 @@ -0,0 +1,90 @@ +/* + * 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. + */ + +key-store "ksk" { + directory "ksk"; +}; + +key-store "zsk" { + directory "zsk"; +}; + +dnssec-policy "alternative-kz" { + keys { + ksk key-directory lifetime unlimited algorithm RSASHA256 2048; + zsk key-directory lifetime unlimited algorithm RSASHA256 2048; + }; +}; + +dnssec-policy "alternative-csk" { + keys { + csk key-directory lifetime unlimited algorithm RSASHA256 2048; + }; +}; + +dnssec-policy "default-kz" { + keys { + ksk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + zsk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + }; +}; + +dnssec-policy "default-csk" { + keys { + csk key-directory lifetime unlimited algorithm ECDSAP256SHA256; + }; +}; + + +dnssec-policy "keystores-kz" { + keys { + ksk key-store "ksk" lifetime unlimited algorithm ECDSAP256SHA256; + zsk key-store "zsk" lifetime unlimited algorithm ECDSAP256SHA256; + }; +}; + +zone "default.example" { + type primary; + file "default.example.db"; + dnssec-policy "default"; +}; + +zone "alternative.kz.example" { + type primary; + file "alternative.kz.example.db"; + dnssec-policy "alternative-kz"; +}; + +zone "alternative.csk.example" { + type primary; + file "alternative.csk.example.db"; + dnssec-policy "alternative-csk"; +}; + +zone "default.kz.example" { + type primary; + file "default.kz.example.db"; + dnssec-policy "default-kz"; +}; + +zone "default.csk.example" { + type primary; + file "default.csk.example.db"; + dnssec-policy "default-csk"; +}; + +zone "keystores.kz.example" { + type primary; + file "keystores.kz.example.db"; + dnssec-policy "keystores-kz"; +}; diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/setup.sh bind9-9.20.15/bin/tests/system/checkconf-keys/setup.sh --- bind9-9.20.11/bin/tests/system/checkconf-keys/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/setup.sh 2025-10-18 10:16:12.290728061 +0000 @@ -0,0 +1,85 @@ +#!/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 + +mkdir ksk +mkdir zsk + +zone="default.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.1 + +zone="bad-default-kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.1 +$KEYGEN -a 13 $zone 2>keygen.out.$zone.2 + +zone="bad-default-algorithm.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 8 -fK $zone 2>keygen.out.$zone.1 + +zone="alternative.kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a RSASHA256 -b 2048 $zone 2>keygen.out.$zone.1 +$KEYGEN -a RSASHA256 -b 2048 -fK $zone 2>keygen.out.$zone.2 + +zone="alternative.csk.example" +cp template.db.in "${zone}.db" +$KEYGEN -a RSASHA256 -b 2048 -fK $zone 2>keygen.out.$zone.2 + +zone="default.kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 $zone 2>keygen.out.$zone.1 +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2 + +zone="default.csk.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2 + +zone="keystores.kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 -fK -K ksk $zone 2>keygen.out.$zone.2 +$KEYGEN -a 13 -K zsk $zone 2>keygen.out.$zone.2 + +zone="superfluous-keyfile.kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 $zone 2>keygen.out.$zone.1 +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2 +$KEYGEN -a 13 $zone 2>keygen.out.$zone.3 # superfluous + +zone="missing-keyfile.kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 $zone 2>keygen.out.$zone.1 +# no ksk + +zone="bad-algorithm.kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 $zone 2>keygen.out.$zone.1 +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2 + +zone="bad-length.csk.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 8 -b 4096 -fK $zone 2>keygen.out.$zone.2 + +zone="bad-tagrange.csk.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 -M 32768:65535 -fK $zone 2>keygen.out.$zone.2 + +zone="bad-role.kz.example" +cp template.db.in "${zone}.db" +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.1 +$KEYGEN -a 13 -fK $zone 2>keygen.out.$zone.2 diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/template.db.in bind9-9.20.15/bin/tests/system/checkconf-keys/template.db.in --- bind9-9.20.11/bin/tests/system/checkconf-keys/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/template.db.in 2025-10-18 10:16:12.290728061 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/checkconf-keys/tests_checkconf_keys.py bind9-9.20.15/bin/tests/system/checkconf-keys/tests_checkconf_keys.py --- bind9-9.20.11/bin/tests/system/checkconf-keys/tests_checkconf_keys.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkconf-keys/tests_checkconf_keys.py 2025-10-18 10:16:12.290728061 +0000 @@ -0,0 +1,162 @@ +# 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 pytest + +import isctest + +pytestmark = pytest.mark.extra_artifacts( + [ + "bad-*.conf", + "K*.key", + "K*.private", + "K*.state", + "keygen.out.*", + "named.conf", + "*.db", + "ksk/", + "zsk/", + ] +) + +CHECKCONF = os.environ["CHECKCONF"] + + +def test_dnssecpolicy_keystore(): + # Good configuration. + isctest.run.cmd([CHECKCONF, "-k", "named.conf"]) + + # Superfluous key file. + zone = "superfluous-keyfile.kz.example" + out = isctest.run.cmd( + [CHECKCONF, "-k", "bad-superfluous-keyfile.conf"], raise_on_exception=False + ) + err = out.stdout.decode("utf-8") + assert f"zone '{zone}': wrong number of key files (3, expected 2)" in err + + # Missing key file. + zone = "missing-keyfile.kz.example" + out = isctest.run.cmd( + [CHECKCONF, "-k", "bad-missing-keyfile.conf"], raise_on_exception=False + ) + err = out.stdout.decode("utf-8") + assert f"zone '{zone}': wrong number of key files (1, expected 2)" in err + + # Mismatch algorithm. + zone = "bad-algorithm.kz.example" + out = isctest.run.cmd( + [CHECKCONF, "-k", "bad-algorithm.conf"], raise_on_exception=False + ) + err = out.stdout.decode("utf-8") + keys = isctest.kasp.keydir_to_keylist(zone) + assert len(keys) == 2 + assert ( + f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[0].tag}' does not match dnssec-policy alternative-kz" + in err + ) + assert ( + f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[1].tag}' does not match dnssec-policy alternative-kz" + in err + ) + assert ( + f"zone '{zone}': no key file found matching dnssec-policy alternative-kz key:'ksk algorithm:RSASHA256 length:2048 tag-range:0-65535'" + in err + ) + assert ( + f"zone '{zone}': no key file found matching dnssec-policy alternative-kz key:'zsk algorithm:RSASHA256 length:2048 tag-range:0-65535'" + in err + ) + + # Mismatch length + zone = "bad-length.csk.example" + out = isctest.run.cmd( + [CHECKCONF, "-k", "bad-length.conf"], raise_on_exception=False + ) + err = out.stdout.decode("utf-8") + keys = isctest.kasp.keydir_to_keylist(zone) + assert len(keys) == 1 + assert ( + f"zone '{zone}': key file '{zone}/RSASHA256/{keys[0].tag}' does not match dnssec-policy alternative-csk" + in err + ) + assert ( + f"zone '{zone}': no key file found matching dnssec-policy alternative-csk key:'csk algorithm:RSASHA256 length:2048 tag-range:0-65535'" + in err + ) + + # Mismatch tag range + zone = "bad-tagrange.csk.example" + out = isctest.run.cmd( + [CHECKCONF, "-k", "bad-tagrange.conf"], raise_on_exception=False + ) + err = out.stdout.decode("utf-8") + keys = isctest.kasp.keydir_to_keylist(zone) + assert len(keys) == 1 + assert ( + f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[0].tag}' does not match dnssec-policy tagrange-csk" + in err + ) + assert ( + f"zone '{zone}': no key file found matching dnssec-policy tagrange-csk key:'csk algorithm:ECDSAP256SHA256 length:256 tag-range:0-32767'" + in err + ) + + # Mismatch role + zone = "bad-role.kz.example" + out = isctest.run.cmd([CHECKCONF, "-k", "bad-role.conf"], raise_on_exception=False) + err = out.stdout.decode("utf-8") + keys = isctest.kasp.keydir_to_keylist(zone) + assert len(keys) == 2 + assert ( + f"zone '{zone}': no key file found matching dnssec-policy default-kz key:'zsk algorithm:ECDSAP256SHA256 length:256 tag-range:0-65535'" + in err + ) + + # Mismatch algorithm (default policy) + zone = "bad-default-algorithm.example" + out = isctest.run.cmd( + [CHECKCONF, "-k", "bad-default-algorithm.conf"], raise_on_exception=False + ) + err = out.stdout.decode("utf-8") + keys = isctest.kasp.keydir_to_keylist(zone) + assert len(keys) == 1 + assert ( + f"zone '{zone}': key file '{zone}/RSASHA256/{keys[0].tag}' does not match dnssec-policy default" + in err + ) + assert ( + f"zone '{zone}': no key file found matching dnssec-policy default key:'csk algorithm:ECDSAP256SHA256 length:256 tag-range:0-65535'" + in err + ) + + # Mismatch role (default policy) + zone = "bad-default-kz.example" + out = isctest.run.cmd( + [CHECKCONF, "-k", "bad-default-kz.conf"], raise_on_exception=False + ) + err = out.stdout.decode("utf-8") + keys = isctest.kasp.keydir_to_keylist(zone) + assert len(keys) == 2 + assert ( + f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[0].tag}' does not match dnssec-policy default" + in err + ) + assert ( + f"zone '{zone}': key file '{zone}/ECDSAP256SHA256/{keys[1].tag}' does not match dnssec-policy default" + in err + ) + assert ( + f"zone '{zone}': no key file found matching dnssec-policy default key:'csk algorithm:ECDSAP256SHA256 length:256 tag-range:0-65535'" + in err + ) + assert f"zone '{zone}': wrong number of key files (2, expected 1)" in err diff -Nru bind9-9.20.11/bin/tests/system/checkds/tests_checkds.py bind9-9.20.15/bin/tests/system/checkds/tests_checkds.py --- bind9-9.20.11/bin/tests/system/checkds/tests_checkds.py 2025-07-04 09:42:08.103322746 +0000 +++ bind9-9.20.15/bin/tests/system/checkds/tests_checkds.py 2025-10-18 10:16:12.321728543 +0000 @@ -81,7 +81,7 @@ def do_query(server, qname, qtype, tcp=False): - msg = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True) + msg = isctest.query.create(qname, qtype) query_func = isctest.query.tcp if tcp else isctest.query.udp response = query_func(msg, server.ip, expected_rcode=dns.rcode.NOERROR) return response @@ -462,16 +462,16 @@ @pytest.mark.parametrize("params", checkds_tests, ids=lambda t: t.zone) -def test_checkds(servers, params): +def test_checkds(ns2, ns9, params): # Wait until the provided zone is signed and then verify its DNSSEC data. - zone_check(servers["ns9"], params.zone) + zone_check(ns9, params.zone) # Wait up to 10 seconds until all the expected log lines are found in the # log file for the provided server. Rekey every second if necessary. time_remaining = 10 for log_string in params.logs_to_wait_for: line = f"zone {params.zone}/IN (signed): checkds: {log_string}" - while line not in servers["ns9"].log: + while line not in ns9.log: rekey(params.zone) time_remaining -= 1 assert time_remaining, f'Timed out waiting for "{log_string}" to be logged' @@ -479,4 +479,4 @@ # Check whether key states on the parent server provided match # expectations. - keystate_check(servers["ns2"], params.zone, params.expected_parent_state) + keystate_check(ns2, params.zone, params.expected_parent_state) diff -Nru bind9-9.20.11/bin/tests/system/checknames/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/checknames/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/checknames/ns2/named.conf.j2 2025-07-04 09:42:08.104322770 +0000 +++ bind9-9.20.15/bin/tests/system/checknames/ns2/named.conf.j2 2025-10-18 10:16:12.322728559 +0000 @@ -20,12 +20,11 @@ listen-on { 10.53.0.2; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; check-names response warn; notify yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/checknames/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/checknames/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/checknames/ns3/named.conf.j2 2025-07-04 09:42:08.104322770 +0000 +++ bind9-9.20.15/bin/tests/system/checknames/ns3/named.conf.j2 2025-10-18 10:16:12.322728559 +0000 @@ -20,12 +20,11 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; check-names response fail; notify yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/checknames/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/checknames/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/checknames/ns4/named.conf.j2 2025-07-04 09:42:08.105322793 +0000 +++ bind9-9.20.15/bin/tests/system/checknames/ns4/named.conf.j2 2025-10-18 10:16:12.322728559 +0000 @@ -21,13 +21,12 @@ listen-on-v6 { none; }; allow-transfer { any; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; check-names primary ignore; check-names secondary ignore; notify yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/checknames/ns5/named.conf.j2 bind9-9.20.15/bin/tests/system/checknames/ns5/named.conf.j2 --- bind9-9.20.11/bin/tests/system/checknames/ns5/named.conf.j2 2025-07-04 09:42:08.105322793 +0000 +++ bind9-9.20.15/bin/tests/system/checknames/ns5/named.conf.j2 2025-10-18 10:16:12.323728574 +0000 @@ -21,13 +21,12 @@ listen-on-v6 { none; }; allow-transfer { any; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; check-names master ignore; check-names slave ignore; notify yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/checkzone/tests.sh bind9-9.20.15/bin/tests/system/checkzone/tests.sh --- bind9-9.20.11/bin/tests/system/checkzone/tests.sh 2025-07-04 09:42:08.105322793 +0000 +++ bind9-9.20.15/bin/tests/system/checkzone/tests.sh 2025-10-18 10:16:12.323728574 +0000 @@ -139,28 +139,28 @@ echo_i "checking that expirations that loop using serial arithmetic are handled ($n)" ret=0 q=-q -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 -test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 +test $ret -eq 1 || $CHECKZONE $q dyn.example.net zones/crashzone.db >test.out.$n 2>&1 || ret=1 n=$((n + 1)) if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) @@ -207,10 +207,65 @@ echo_i "checking integer overflow is prevented in \$GENERATE ($n)" $CHECKZONE -D example.com zones/generate-overflow.db >test.out.$n 2>&1 || ret=1 lines=$(grep -c CNAME test.out.$n) -echo $lines [ "$lines" -eq 1 ] || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) +echo_i "Checking for RSASHA1 deprecated warning ($n)" +ret=0 +$CHECKZONE example zones/warn.deprecated.rsasha1.db >test.out.$n || ret=1 +grep "deprecated DNSKEY algorithm found: 5 (RSASHA1)" test.out.$n >/dev/null || ret=1 +grep "all DNSKEY algorithms found are deprecated" test.out.$n >/dev/null || ret=1 +grep "loaded serial 0 (DNSSEC signed)" test.out.$n >/dev/null || ret=1 +n=$((n + 1)) +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "Checking for NSECRSASHA1 deprected warning ($n)" +ret=0 +$CHECKZONE example zones/warn.deprecated.nsec3rsasha1.db >test.out.$n || ret=1 +grep "deprecated DNSKEY algorithm found: 7 (NSEC3RSASHA1)" test.out.$n >/dev/null || ret=1 +grep "all DNSKEY algorithms found are deprecated" test.out.$n >/dev/null || ret=1 +grep "loaded serial 0 (DNSSEC signed)" test.out.$n >/dev/null || ret=1 +n=$((n + 1)) +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "Checking for SHA1 CDS digest warning ($n)" +ret=0 +$CHECKZONE example zones/warn.deprecated.cds-sha1.db >test.out.$n || ret=1 +grep "zone example/IN: deprecated CDS digest type 1 (SHA-1)" test.out.$n >/dev/null || ret=1 +grep "loaded serial 0 (DNSSEC signed)" test.out.$n >/dev/null || ret=1 +n=$((n + 1)) +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "Checking for SHA1 DS digest warning ($n)" +ret=0 +$CHECKZONE example zones/warn.deprecated.digest-sha1.db >test.out.$n || ret=1 +grep "zone example/IN: child.example/DS deprecated digest type 1 (SHA-1)" test.out.$n >/dev/null || ret=1 +grep "loaded serial 0 (DNSSEC signed)" test.out.$n >/dev/null || ret=1 +n=$((n + 1)) +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "Checking for RSASHA1 DS algorithm warning ($n)" +ret=0 +$CHECKZONE example zones/warn.deprecated.ds-alg.db >test.out.$n || ret=1 +grep "zone example/IN: child.example/DS deprecated algorithm 5 (RSASHA1)" test.out.$n >/dev/null || ret=1 +grep "loaded serial 0 (DNSSEC signed)" test.out.$n >/dev/null || ret=1 +n=$((n + 1)) +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "Checking for RSASHA1 KEY algorithm warning ($n)" +ret=0 +$CHECKZONE example zones/warn.deprecated.key-alg.db >test.out.$n || ret=1 +grep "zone example/IN: example/KEY deprecated algorithm 5 (RSASHA1)" test.out.$n >/dev/null || ret=1 +grep "loaded serial 0 (DNSSEC signed)" test.out.$n >/dev/null || ret=1 +n=$((n + 1)) +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff -Nru bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.cds-sha1.db bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.cds-sha1.db --- bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.cds-sha1.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.cds-sha1.db 2025-10-18 10:16:12.333728730 +0000 @@ -0,0 +1,44 @@ +; File written on Wed Jul 2 14:27:34 2025 +; dnssec-signzone version 9.21.3-dev +example. 3600 IN SOA . . ( + 0 ; serial + 0 ; refresh (0 seconds) + 0 ; retry (0 seconds) + 0 ; expire (0 seconds) + 3600 ; minimum (1 hour) + ) + 3600 RRSIG SOA 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + iC+sFesZi+uurPGRfP7faPfmQcHlQcz4oGKP + 4Fqq6/ePy9s+FYpL6LILjnB9iPxc0w3BBvsd + PArExFsuaKcWgQ== ) + 3600 NS . + 3600 RRSIG NS 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + q2qPtVYQsku7j5xqLyIleldPLnhJjvbjMkcb + XtnV2djkM1swGkZp67u4l7GHr9/b9lcM848w + t+AfDiT2Mak9Lg== ) + 3600 NSEC example. NS SOA RRSIG NSEC DNSKEY CDS + 3600 RRSIG NSEC 13 1 3600 ( + 20901231235959 20250702032734 46204 example. + aPkaoO9OMYZwldpUPJeqFZoGCc8XQcmQHig2 + zJmp2Qv2QGRH1faoWosYy5jwQskxtpoyE0Eh + yxEoUhHZNCKogQ== ) + 3600 DNSKEY 256 3 13 ( + Il3F88buwuAwswJl70b4xh8werV/2a2cDo6x + joU5+1H2dRXE/XRt4CEipBdt8Ss4fr8s6jBE + 5CT4INCzzeTuZQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 46204 + 3600 RRSIG DNSKEY 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + KQWGucJalgX/cANLv0/g0LNweGdeE7gs8rrx + 9yOiZqciu7wCfyRgk5ED1pNXOXsTqtIA0OGa + OmTOsXrBWly7ng== ) + 3600 CDS 46204 13 1 ( + 712DD9926EDF2A5E81E76D3BC5F5637BEA06 + 2E67 ) + 3600 RRSIG CDS 13 1 3600 ( + 20901231235959 20250702032734 46204 example. + nS9qKdj0dfWNe6U0ttuKSMiKMhxLq4Yo6WPT + 9j/cmjbaOdKO1DBoDxzZ7G4M34msvBcKq31L + mn8qUlrzSOfD9A== ) diff -Nru bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.digest-sha1.db bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.digest-sha1.db --- bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.digest-sha1.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.digest-sha1.db 2025-10-18 10:16:12.333728730 +0000 @@ -0,0 +1,51 @@ +; File written on Mon Jun 30 15:20:51 2025 +; dnssec-signzone version 9.21.3-dev +example. 3600 IN SOA . . ( + 0 ; serial + 0 ; refresh (0 seconds) + 0 ; retry (0 seconds) + 0 ; expire (0 seconds) + 3600 ; minimum (1 hour) + ) + 3600 RRSIG SOA 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + iC+sFesZi+uurPGRfP7faPfmQcHlQcz4oGKP + 4Fqq6/ePy9s+FYpL6LILjnB9iPxc0w3BBvsd + PArExFsuaKcWgQ== ) + 3600 NS . + 3600 RRSIG NS 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + q2qPtVYQsku7j5xqLyIleldPLnhJjvbjMkcb + XtnV2djkM1swGkZp67u4l7GHr9/b9lcM848w + t+AfDiT2Mak9Lg== ) + 3600 NSEC child.example. NS SOA RRSIG NSEC DNSKEY + 3600 RRSIG NSEC 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + jgKjQOGLqw7JY1qsyjWZGxL/47mc9dMeZ7yB + KtrRfFCsT7mCe/lMV3u7FOwM2r9/ta8U9/j2 + YRVJGECc6/rdcg== ) + 3600 DNSKEY 256 3 13 ( + Il3F88buwuAwswJl70b4xh8werV/2a2cDo6x + joU5+1H2dRXE/XRt4CEipBdt8Ss4fr8s6jBE + 5CT4INCzzeTuZQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 46204 + 3600 RRSIG DNSKEY 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + KQWGucJalgX/cANLv0/g0LNweGdeE7gs8rrx + 9yOiZqciu7wCfyRgk5ED1pNXOXsTqtIA0OGa + OmTOsXrBWly7ng== ) +child.example. 3600 IN NS . + 3600 DS 30914 13 1 ( + 3FFB809FC091FDC931815B50E5DA9C00B5C1 + 454F ) + 3600 RRSIG DS 13 2 3600 ( + 20901231235959 20250630042051 46204 example. + 5Y/jx0eePoUztptSLwE9DeY2GlVNVHSr3lF4 + R8IajnK7zXs2QtoRIdmKwWZ1um1JICh59Xk7 + R/BXFAbO6FMaPA== ) + 3600 NSEC example. NS DS RRSIG NSEC + 3600 RRSIG NSEC 13 2 3600 ( + 20901231235959 20250630042051 46204 example. + A662/raRKle9b45C5douUufAne7iRtKw0u7C + gcnf3tSrJS+plT3e/jHOE5ZRttkloHSDVhYT + 7+Wv86G8MGt+3Q== ) diff -Nru bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.ds-alg.db bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.ds-alg.db --- bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.ds-alg.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.ds-alg.db 2025-10-18 10:16:12.333728730 +0000 @@ -0,0 +1,51 @@ +; File written on Wed Jul 2 12:22:09 2025 +; dnssec-signzone version 9.21.3-dev +example. 3600 IN SOA . . ( + 0 ; serial + 0 ; refresh (0 seconds) + 0 ; retry (0 seconds) + 0 ; expire (0 seconds) + 3600 ; minimum (1 hour) + ) + 3600 RRSIG SOA 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + iC+sFesZi+uurPGRfP7faPfmQcHlQcz4oGKP + 4Fqq6/ePy9s+FYpL6LILjnB9iPxc0w3BBvsd + PArExFsuaKcWgQ== ) + 3600 NS . + 3600 RRSIG NS 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + q2qPtVYQsku7j5xqLyIleldPLnhJjvbjMkcb + XtnV2djkM1swGkZp67u4l7GHr9/b9lcM848w + t+AfDiT2Mak9Lg== ) + 3600 NSEC child.example. NS SOA RRSIG NSEC DNSKEY + 3600 RRSIG NSEC 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + jgKjQOGLqw7JY1qsyjWZGxL/47mc9dMeZ7yB + KtrRfFCsT7mCe/lMV3u7FOwM2r9/ta8U9/j2 + YRVJGECc6/rdcg== ) + 3600 DNSKEY 256 3 13 ( + Il3F88buwuAwswJl70b4xh8werV/2a2cDo6x + joU5+1H2dRXE/XRt4CEipBdt8Ss4fr8s6jBE + 5CT4INCzzeTuZQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 46204 + 3600 RRSIG DNSKEY 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + KQWGucJalgX/cANLv0/g0LNweGdeE7gs8rrx + 9yOiZqciu7wCfyRgk5ED1pNXOXsTqtIA0OGa + OmTOsXrBWly7ng== ) +child.example. 3600 IN NS . + 3600 DS 58246 5 2 ( + 641AFA5ACB8099E4E571585B7B9A416078FF + 79D40D1C2E85F9179E28BF08D61D ) + 3600 RRSIG DS 13 2 3600 ( + 20901231235959 20250702012209 46204 example. + g17c5sfC0OAucFLA0n9C5EfPActxuPMpHN6G + spGmkkDUaU5UosWkdcapd20Yb29NaEKvJO3Q + Qn6K53MKtWt7zQ== ) + 3600 NSEC example. NS DS RRSIG NSEC + 3600 RRSIG NSEC 13 2 3600 ( + 20901231235959 20250630042051 46204 example. + A662/raRKle9b45C5douUufAne7iRtKw0u7C + gcnf3tSrJS+plT3e/jHOE5ZRttkloHSDVhYT + 7+Wv86G8MGt+3Q== ) diff -Nru bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.key-alg.db bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.key-alg.db --- bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.key-alg.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.key-alg.db 2025-10-18 10:16:12.334728745 +0000 @@ -0,0 +1,53 @@ +; File written on Wed Jul 2 16:48:02 2025 +; dnssec-signzone version 9.21.3-dev +example. 3600 IN SOA . . ( + 0 ; serial + 0 ; refresh (0 seconds) + 0 ; retry (0 seconds) + 0 ; expire (0 seconds) + 3600 ; minimum (1 hour) + ) + 3600 RRSIG SOA 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + iC+sFesZi+uurPGRfP7faPfmQcHlQcz4oGKP + 4Fqq6/ePy9s+FYpL6LILjnB9iPxc0w3BBvsd + PArExFsuaKcWgQ== ) + 3600 NS . + 3600 RRSIG NS 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + q2qPtVYQsku7j5xqLyIleldPLnhJjvbjMkcb + XtnV2djkM1swGkZp67u4l7GHr9/b9lcM848w + t+AfDiT2Mak9Lg== ) + 3600 KEY 512 3 5 ( + AwEAAZwLHbB7cjvlEt0evebAMsJtuNYXgiyt + qe3lu0RO/ChFdddyHv+O9M1zLrCnWMBSLHad + YHSXfG3BMyMAnBh7om+1pgrHCShlmMaxZ5cC + sug5buS3E8eVRVAf7Qje63owxm2iF3G9kKWY + FgfE+Ml5Uv7etHkmxqAmFb3jYuXzYWfMz1qY + rICsJnw7qcKzNphl71tDvJUYD5pDA7izhzs3 + 8tdDH8qMQgK/yNU3Q/RAOg2VRvYuwYOteCAx + 6RB/z+rtNTKNbphrPrzSsekOurLo1B+AvDct + o/orbilbQ8qdq0cknKlqdMKuYcqQ1BbBMrdV + w1fBTLDwiFwiRBjYazPqPiE= + ); alg = RSASHA1 ; key id = 13684 + 3600 RRSIG KEY 13 1 3600 ( + 20901231235959 20250702054802 46204 example. + GvfNtx1F8crebI/QrPb2meHplhSpAsIDqJ48 + iMg6aT22mGBagR698GS+9ehg0ExMumfIDPSO + k/1wtwRKYqrKow== ) + 3600 NSEC example. NS SOA KEY RRSIG NSEC DNSKEY + 3600 RRSIG NSEC 13 1 3600 ( + 20901231235959 20250702054802 46204 example. + Nah5tUuwQiiDKWpdgtqPp7LppMOoDUJkyTZB + pAzmbT8UA7kNJN2K5kfkLJgPqWAt4h2P0Ys1 + 9lkLcXqYUH0x5g== ) + 3600 DNSKEY 256 3 13 ( + Il3F88buwuAwswJl70b4xh8werV/2a2cDo6x + joU5+1H2dRXE/XRt4CEipBdt8Ss4fr8s6jBE + 5CT4INCzzeTuZQ== + ) ; ZSK; alg = ECDSAP256SHA256 ; key id = 46204 + 3600 RRSIG DNSKEY 13 1 3600 ( + 20901231235959 20250630042051 46204 example. + KQWGucJalgX/cANLv0/g0LNweGdeE7gs8rrx + 9yOiZqciu7wCfyRgk5ED1pNXOXsTqtIA0OGa + OmTOsXrBWly7ng== ) diff -Nru bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.nsec3rsasha1.db bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.nsec3rsasha1.db --- bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.nsec3rsasha1.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.nsec3rsasha1.db 2025-10-18 10:16:12.334728745 +0000 @@ -0,0 +1,71 @@ +; File written on Mon Jun 30 14:55:37 2025 +; dnssec-signzone version 9.21.3-dev +example. 3600 IN SOA . . ( + 0 ; serial + 0 ; refresh (0 seconds) + 0 ; retry (0 seconds) + 0 ; expire (0 seconds) + 3600 ; minimum (1 hour) + ) + 3600 RRSIG SOA 7 1 3600 ( + 20901231235959 20250630035537 41424 example. + oqX2MaQSaMj2YPYWA/8echxn7QHBerVEs426 + z8IJ88lv8Ih3Rrsldur6hXCieYI46wK3xOft + p0VMAw9iIK5T49PXnaf7+hdaIJFDTAvuhzco + e1IcdfmS26a6rRZHG8QKNjVjn/Du3J2gbdoB + ubyio+7BY45Mk1S0sb0QzkmfTRZodULfvlW7 + BkmC9k0ixU1f1R+k26I0TJHYwH6Tw3O/0nPG + SkUKnIcgqjzXsnUN1XGR+gD9TVF8Hp+JYWCz + 5fFTR733OiScIK+Xlon+ydg1GixW1rOR2MOP + lowGJIHeE8nDYEgncKv91wFCp1IRHjgN/6zg + c6JBClYMhe0RS66I6A== ) + 3600 NS . + 3600 RRSIG NS 7 1 3600 ( + 20901231235959 20250630035411 41424 example. + pQUeJTZvpEPBZOdatA79eUE+qunKTasFyjgT + xB+hpvXujxFqf6FDs/TdfE9jGo5T8Rwb3Gu0 + 7+uo5ATwKuQL0TywDVm7DMj07iWoXpCGWge9 + q+iZ9sVXTzGKbb+1f8w9b/E9qW/s9Uir/tZq + pPWhEgy61ip/pjkcyoIi3wQtffBMckApBgao + Nk6YPi0TSl3W+cQUDkT2BeCoZDHuhuvS+Z3x + URTu5FnqT3YPKJ5xb4N3mr4um4oI9sy+TJIj + yuSW/ie0Bzy8x8ha1capfhlbPsZI6SKe0ldR + vC9dr0gertISQzAnl9GqxFne6Ya5DyYHKye+ + khVrRKAu2YIFRWYrOg== ) + 3600 NSEC example. NS SOA RRSIG NSEC DNSKEY + 3600 RRSIG NSEC 7 1 3600 ( + 20901231235959 20250630035537 41424 example. + IMgNRFY4qWHDFz/gWiXn6jrCSW4Az/5sE7ML + dyJgY8OHtM2Kq+ThRsgZn7gN47T7QJv8Dvc3 + oYNRH7R6sjGJBZmfoqfdZmJOrR1bdKhHjhHR + 0b3NuXlVAG7eqMu4eJvsKZCUTKxa3+iFStw/ + pTsHWEVT9ozMaAfQdzM86Pq6x8VVQCRwuw9g + JWkjt0/4VGA/tTj713o0/7Ju0055wSVnFNvH + XaAW2PG9nRDyFvoOq1lFSFEPm9gXDFfDmTZn + 40v+qIer/vPGMkHyizZAbZ0qnM7lwNAhDukz + catwpgsbpMWHrBUgnDCbxpzfl24n7wmHyCUa + ArewJH9UphjytrxHjw== ) + 3600 DNSKEY 256 3 7 ( + AwEAAakdlaNNa6UNEKTh7g0TPBLuEecXezJ2 + mz7kaBxIEx7t3IPxWymt5XezCtR7NilHW+zo + d42hzKrtqFilt5SBrsjnWr5ipczEySEYCtOz + Jx0P9xLj8MjCf5D6+elSY4zm9gtqlIo6ryhf + SuCJQ9XZOIFD10/8efr0HYxkc0N4msZhVcuB + yJ650Pjc0EFWEe2yseM+uXZCIc/0Q4OayMJA + 5GEJwvq/POH/POU7HlQR5RKzT0babm4Jvmpx + F1jf7gSRL44LgVLl/m4fKjseK1w0shOxhrwc + gAXI5ZMpspN9Mnhy+HNemkw9xyw3XkAtcTuN + yUHvCLEyaklh6latwxFQTLM= + ) ; ZSK; alg = NSEC3RSASHA1 ; key id = 41424 + 3600 RRSIG DNSKEY 7 1 3600 ( + 20901231235959 20250630035411 41424 example. + G2lr1Q+xjDnefyPbxLTy0yZ8wUg1+GcaBb9H + 7YX0FzZroRLTNr8SN2VYge4CbNZkTIC98dmV + TRwoBp4HbrWY5jDGT2oQS1zDc92dz0TuD0Ys + JMI2/IEVpA9wBcqsRssmAwzSuh4dMLqfMkrm + KzWk7CRNxqC1JXJ1MgbRCRuES22HGO3O7ZXZ + HjsFANBQt+7PebgdmAtS61RvztyJE+o6LyaA + qA9qawqYDBi7Lcar/U+arrfg77kQ8BmC+ZZV + toLkus9VsM9GShmMo2/KMu+PYWHKWUuHwRas + v9hSvLh/+b7mymssp/WtmX79a3WXlHovNP2v + Sh2S4RjDq4lFsyqTAA== ) diff -Nru bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.rsasha1.db bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.rsasha1.db --- bind9-9.20.11/bin/tests/system/checkzone/zones/warn.deprecated.rsasha1.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/checkzone/zones/warn.deprecated.rsasha1.db 2025-10-18 10:16:12.334728745 +0000 @@ -0,0 +1,71 @@ +; File written on Mon Jun 30 14:57:52 2025 +; dnssec-signzone version 9.21.3-dev +example. 3600 IN SOA . . ( + 0 ; serial + 0 ; refresh (0 seconds) + 0 ; retry (0 seconds) + 0 ; expire (0 seconds) + 3600 ; minimum (1 hour) + ) + 3600 RRSIG SOA 5 1 3600 ( + 20901231235959 20250630035752 3495 example. + gq16Xp8iCErMp/R6jdzvws3MMvWAMowfYOa5 + K3Dwo3MXUruWhsDa4XjH3CJIk4LtSRDWcVSj + /STy/R4CEvz83/2VMjQ7L73hFZZNVrMHKrLi + SfRhnUueOHiYrv8sLM2ZHy0EYM/gULmcX51j + j0XJlSf9DfkT/nh3ZwqS+lD/RA+1Gg73xVkS + tRh5AZMWAGrjyBMOC0iW9qexqINmM0nR40K7 + 5L+17OL2Ay/Fp7zliN+g9bAEfgITQlFRO32Y + sZrPRguzavP5xad4m3GOCAQoTQJpnci7id2u + DhIwkh6+7Do3zjZOQy74IvbuPVUS5nVRiEd8 + XqF3Z7hHMYWWCEdslw== ) + 3600 NS . + 3600 RRSIG NS 5 1 3600 ( + 20901231235959 20250630034615 3495 example. + FrY8Bi8StW34PADKfVn2uPDIgDzbhyinoQDw + HjklP8PFXvl2VLhroGZy5EfoGQlC+eOL7Ffb + ZlKMvSOtGHpIIdqWg6GmGBWqCYoC3EoaFVXh + A2SBxOPdcbGbwzVk6MWnrpFRsxwMqX+7vjJg + eB7XVh1tZf90N6Yfswfy/UFf5Qbaj69gE7/7 + Eu3lkNNsFr5UVLPU4K4/dzNalllZjZ++w68T + 5Y97UmIJH+aXpNndibJU9c25F1/ou5NJLQQN + LxyWXIi1CRaF88sjQwXemO8xutnh2b3ULKI0 + pelDtKThLWWYAMhgMnhr5HktL69++cMZiZ4z + 3heBavJIPY2QTYOLZw== ) + 3600 NSEC example. NS SOA RRSIG NSEC DNSKEY + 3600 RRSIG NSEC 5 1 3600 ( + 20901231235959 20250630035752 3495 example. + N5mNbNXTSbLOya8baU6SaGao8bPquA4rO2hb + 5mkYjM+wzAJRNKSrViA5Ev7iFJolXKM+NCV3 + fpKtT+5v8mqhGZf80H1Z7inmAMX+Gz9B0YfO + yhmSTD7qnIgoxw+W/dFAeBx18XyCRDBRlGyj + 2FEqZa46AVuDaYgQoUJLfM4SkOhbsDdDfQV1 + uQinjRnhvOQEOd0wYRbqR7S8BMqppnahwyai + lH5tx8qsBVFTR7P8D5UlTfHCBM+d0VI5jXjt + 45eCwzqQBTl4ot4Tbc/nGaUvPU5ffkW8fmsk + BygQeKd97xPnzK0tt1KJaYGTiqc3UgUId929 + XniHMB6YmxkpIb2qrg== ) + 3600 DNSKEY 256 3 5 ( + AwEAAZmABvQsJBvsRu2fMlU1CtN58u7+yO5x + ioxkg8O2mH29NDFoMKtxZKlk74+hT8m0aAKV + hqEywM9S2NaWEXctv2lF6t/f8E8YJkY+cnLb + iZmxuJmScxce8u32KlX0MiKN2JQHIokDTz7m + 2AqUaLTnERyIXNUHJfHx1nzvhhz4G7TV41Pk + U1MSX3gCrgsSQ7IUzLOsyy6iQn4wFml+eXlO + qmypFvjRDhmjXAHms3nSOgDmDu6kF+9R0ccL + Lh4YAEYZlx2UoDigcEtRfMeYQwb76tC7xAkx + EEJAUo+oRkaw2in8kVjpwuXSWF5WlX+Cpie9 + o3r+4EpI/IV6z63QO9zqMEE= + ) ; ZSK; alg = RSASHA1 ; key id = 3495 + 3600 RRSIG DNSKEY 5 1 3600 ( + 20901231235959 20250630034615 3495 example. + gpKH6gf+47UNqMlTdtylpSW/yRNEyPtpj7Tu + Y939pwRPgQcPBscIwcZzezV0r4y2O5xMTKQ1 + fQZTidfCwvessYTxYJYSjE1i+pChblLmqY/j + JNjwUv0nH9rs8ZSXRSFiqPsC7tl4jBQsD1N+ + UdV3a/rEFCON1C+KirQlrdSq+/bAic0A4afZ + g746kgnLsNCu/FnVucfoOBGaAk6na9dYIt0+ + l7IKI+4dg+tHsaGdRVv2h2JXO6g1I2LtCiIB + FlKxFDCrMFV9+xduLFNnNxVsvnK7RtlAAPo5 + n4WBinbW5CpGJnc7n/0BknnecqZb63qkQgia + 50FJvVZCJ4WTZ+Hh0g== ) diff -Nru bind9-9.20.11/bin/tests/system/cipher-suites/ns1/named.conf.in bind9-9.20.15/bin/tests/system/cipher-suites/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/cipher-suites/ns1/named.conf.in 2025-07-04 09:42:08.115323028 +0000 +++ bind9-9.20.15/bin/tests/system/cipher-suites/ns1/named.conf.in 2025-10-18 10:16:12.334728745 +0000 @@ -63,13 +63,12 @@ notify explicit; also-notify { 10.53.0.2 port @PORT@; }; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; transfers-in 100; transfers-out 100; }; -trust-anchors { }; zone "." { type primary; diff -Nru bind9-9.20.11/bin/tests/system/cipher-suites/ns2/named.conf.in bind9-9.20.15/bin/tests/system/cipher-suites/ns2/named.conf.in --- bind9-9.20.11/bin/tests/system/cipher-suites/ns2/named.conf.in 2025-07-04 09:42:08.116323051 +0000 +++ bind9-9.20.15/bin/tests/system/cipher-suites/ns2/named.conf.in 2025-10-18 10:16:12.334728745 +0000 @@ -36,10 +36,9 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cipher-suites/ns3/named.conf.in bind9-9.20.15/bin/tests/system/cipher-suites/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/cipher-suites/ns3/named.conf.in 2025-07-04 09:42:08.116323051 +0000 +++ bind9-9.20.15/bin/tests/system/cipher-suites/ns3/named.conf.in 2025-10-18 10:16:12.334728745 +0000 @@ -36,10 +36,9 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cipher-suites/ns4/named.conf.in bind9-9.20.15/bin/tests/system/cipher-suites/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/cipher-suites/ns4/named.conf.in 2025-07-04 09:42:08.116323051 +0000 +++ bind9-9.20.15/bin/tests/system/cipher-suites/ns4/named.conf.in 2025-10-18 10:16:12.335728761 +0000 @@ -36,10 +36,9 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cipher-suites/ns5/named.conf.in bind9-9.20.15/bin/tests/system/cipher-suites/ns5/named.conf.in --- bind9-9.20.11/bin/tests/system/cipher-suites/ns5/named.conf.in 2025-07-04 09:42:08.116323051 +0000 +++ bind9-9.20.15/bin/tests/system/cipher-suites/ns5/named.conf.in 2025-10-18 10:16:12.335728761 +0000 @@ -36,10 +36,9 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cipher-suites/tests_cipher_suites.py bind9-9.20.15/bin/tests/system/cipher-suites/tests_cipher_suites.py --- bind9-9.20.11/bin/tests/system/cipher-suites/tests_cipher_suites.py 2025-07-04 09:42:08.116323051 +0000 +++ bind9-9.20.15/bin/tests/system/cipher-suites/tests_cipher_suites.py 2025-10-18 10:16:12.335728761 +0000 @@ -84,7 +84,7 @@ ) # pylint: disable=redefined-outer-name,unused-argument def test_cipher_suites_tls_xfer(qname, ns, rcode, transfers_complete): - msg = dns.message.make_query(qname, "AXFR") + msg = isctest.query.create(qname, "AXFR") ans = isctest.query.tls(msg, f"10.53.0.{ns}") assert ans.rcode() == rcode if rcode == dns.rcode.NOERROR: diff -Nru bind9-9.20.11/bin/tests/system/conftest.py bind9-9.20.15/bin/tests/system/conftest.py --- bind9-9.20.11/bin/tests/system/conftest.py 2025-07-04 09:42:08.117323074 +0000 +++ bind9-9.20.15/bin/tests/system/conftest.py 2025-10-18 10:16:12.335728761 +0000 @@ -634,3 +634,53 @@ except ValueError: continue return instances + + +@pytest.fixture(scope="module") +def ns1(servers): + return servers["ns1"] + + +@pytest.fixture(scope="module") +def ns2(servers): + return servers["ns2"] + + +@pytest.fixture(scope="module") +def ns3(servers): + return servers["ns3"] + + +@pytest.fixture(scope="module") +def ns4(servers): + return servers["ns4"] + + +@pytest.fixture(scope="module") +def ns5(servers): + return servers["ns5"] + + +@pytest.fixture(scope="module") +def ns6(servers): + return servers["ns6"] + + +@pytest.fixture(scope="module") +def ns7(servers): + return servers["ns7"] + + +@pytest.fixture(scope="module") +def ns8(servers): + return servers["ns8"] + + +@pytest.fixture(scope="module") +def ns9(servers): + return servers["ns9"] + + +@pytest.fixture(scope="module") +def ns10(servers): + return servers["ns10"] diff -Nru bind9-9.20.11/bin/tests/system/cookie/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/cookie/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/cookie/ns1/named.conf.j2 2025-07-04 09:42:08.117323074 +0000 +++ bind9-9.20.15/bin/tests/system/cookie/ns1/named.conf.j2 2025-10-18 10:16:12.336728776 +0000 @@ -38,7 +38,7 @@ listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; } except-from { "example.org"; }; deny-answer-aliases { "example.org"; } @@ -49,7 +49,6 @@ nocookie-udp-size 512; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cookie/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/cookie/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/cookie/ns3/named.conf.j2 2025-07-04 09:42:08.118323098 +0000 +++ bind9-9.20.15/bin/tests/system/cookie/ns3/named.conf.j2 2025-10-18 10:16:12.336728776 +0000 @@ -29,7 +29,7 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; } except-from { "example.org"; }; deny-answer-aliases { "example.org"; } @@ -41,7 +41,6 @@ require-server-cookie yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cookie/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/cookie/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/cookie/ns4/named.conf.j2 2025-07-04 09:42:08.118323098 +0000 +++ bind9-9.20.15/bin/tests/system/cookie/ns4/named.conf.j2 2025-10-18 10:16:12.337728792 +0000 @@ -29,13 +29,12 @@ listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; cookie-algorithm siphash24; cookie-secret "569d36a6cc27d6bf55502183302ba352"; require-server-cookie yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cookie/ns5/named.conf.j2 bind9-9.20.15/bin/tests/system/cookie/ns5/named.conf.j2 --- bind9-9.20.11/bin/tests/system/cookie/ns5/named.conf.j2 2025-07-04 09:42:08.118323098 +0000 +++ bind9-9.20.15/bin/tests/system/cookie/ns5/named.conf.j2 2025-10-18 10:16:12.337728792 +0000 @@ -29,14 +29,13 @@ listen-on { 10.53.0.5; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; cookie-algorithm siphash24; cookie-secret "569d36a6cc27d6bf55502183302ba352"; cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; require-server-cookie yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cookie/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/cookie/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/cookie/ns6/named.conf.j2 2025-07-04 09:42:08.118323098 +0000 +++ bind9-9.20.15/bin/tests/system/cookie/ns6/named.conf.j2 2025-10-18 10:16:12.337728792 +0000 @@ -29,13 +29,12 @@ listen-on { 10.53.0.6; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; cookie-algorithm siphash24; cookie-secret "6b300e27a0db46d4b046e4189790fa7d"; require-server-cookie yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/cookie/ns8/named.conf.j2 bind9-9.20.15/bin/tests/system/cookie/ns8/named.conf.j2 --- bind9-9.20.11/bin/tests/system/cookie/ns8/named.conf.j2 2025-07-04 09:42:08.119323121 +0000 +++ bind9-9.20.15/bin/tests/system/cookie/ns8/named.conf.j2 2025-10-18 10:16:12.337728792 +0000 @@ -28,12 +28,11 @@ pid-file "named.pid"; listen-on { 10.53.0.8; }; listen-on-v6 { none; }; - dnssec-validation yes; + dnssec-validation no; rate-limit {}; require-server-cookie yes; }; -trust-anchors { }; server 10.53.0.7 { require-cookie yes; }; diff -Nru bind9-9.20.11/bin/tests/system/database/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/database/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/database/ns1/named.conf.j2 2025-07-04 09:42:08.120323145 +0000 +++ bind9-9.20.15/bin/tests/system/database/ns1/named.conf.j2 2025-10-18 10:16:12.338728807 +0000 @@ -32,10 +32,9 @@ listen-on-v6 { none; }; recursion no; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "database" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/database/tests_database.py bind9-9.20.15/bin/tests/system/database/tests_database.py --- bind9-9.20.11/bin/tests/system/database/tests_database.py 2025-07-04 09:42:08.120323145 +0000 +++ bind9-9.20.15/bin/tests/system/database/tests_database.py 2025-10-18 10:16:12.338728807 +0000 @@ -9,13 +9,13 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -import isctest +import dns -import dns.message +import isctest -def test_database(servers, templates): - msg = dns.message.make_query("database.", "SOA") +def test_database(ns1, templates): + msg = isctest.query.create("database.", "SOA") # checking pre reload zone res = isctest.query.tcp(msg, "10.53.0.1") @@ -28,8 +28,8 @@ ) templates.render("ns1/named.conf", {"rname": "marka.isc.org."}) - with servers["ns1"].watch_log_from_here() as watcher: - servers["ns1"].rndc("reload") + with ns1.watch_log_from_here() as watcher: + ns1.rndc("reload") watcher.wait_for_line("all zones loaded") # checking post reload zone diff -Nru bind9-9.20.11/bin/tests/system/dialup/tests_dialup_zone_transfer.py bind9-9.20.15/bin/tests/system/dialup/tests_dialup_zone_transfer.py --- bind9-9.20.11/bin/tests/system/dialup/tests_dialup_zone_transfer.py 2025-07-04 09:42:08.121323168 +0000 +++ bind9-9.20.15/bin/tests/system/dialup/tests_dialup_zone_transfer.py 2025-10-18 10:16:12.339728823 +0000 @@ -28,10 +28,9 @@ # Drop the RD flag from the query msg.flags &= ~dns.flags.RD ns1response = isctest.query.tcp(msg, "10.53.0.1") - with servers[f"ns{ns}"].watch_log_from_start() as watcher: + with servers[f"ns{ns}"].watch_log_from_start(timeout=90) as watcher: watcher.wait_for_line( f"transfer of 'example/IN' from 10.53.0.{ns-1}#{named_port}: Transfer status: success", - timeout=90, ) response = isctest.query.tcp(msg, f"10.53.0.{ns}") if response.rcode() != dns.rcode.SERVFAIL: diff -Nru bind9-9.20.11/bin/tests/system/digdelv/tests.sh bind9-9.20.15/bin/tests/system/digdelv/tests.sh --- bind9-9.20.11/bin/tests/system/digdelv/tests.sh 2025-07-04 09:42:08.122323192 +0000 +++ bind9-9.20.15/bin/tests/system/digdelv/tests.sh 2025-10-18 10:16:12.341728854 +0000 @@ -1760,15 +1760,6 @@ if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null; then n=$((n + 1)) - echo_i "checking delv +ns uses both address families ($n)" - ret=0 - delv_with_opts -a ns1/anchor.dnskey +root +ns +hint=root.hint a a.example >delv.out.test$n || ret=1 - grep -qF 'sending packet to 10.53' delv.out.test$n >/dev/null || ret=1 - grep -qF 'sending packet to fd92:7065' delv.out.test$n >/dev/null || ret=1 - if [ $ret -ne 0 ]; then echo_i "failed"; fi - status=$((status + ret)) - - n=$((n + 1)) echo_i "checking delv -4 +ns uses only IPv4 ($n)" ret=0 delv_with_opts -a ns1/anchor.dnskey +root -4 +ns +hint=root.hint a a.example >delv.out.test$n || ret=1 diff -Nru bind9-9.20.11/bin/tests/system/dispatch/ans3/ans.py bind9-9.20.15/bin/tests/system/dispatch/ans3/ans.py --- bind9-9.20.11/bin/tests/system/dispatch/ans3/ans.py 2025-07-04 09:42:08.123323215 +0000 +++ bind9-9.20.15/bin/tests/system/dispatch/ans3/ans.py 2025-10-18 10:16:12.341728854 +0000 @@ -9,91 +9,37 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -import os -import select -import signal -import socket -import sys -import time +from typing import AsyncGenerator -import dns.flags -import dns.message +import dns +from isctest.asyncserver import ( + AsyncDnsServer, + ConnectionReset, + DnsProtocol, + DnsResponseSend, + QueryContext, + ResponseAction, + ResponseHandler, +) + + +class TruncateOnUdpHandler(ResponseHandler): + async def get_responses( + self, qctx: QueryContext + ) -> AsyncGenerator[ResponseAction, None]: + assert qctx.protocol == DnsProtocol.UDP, "This server only supports UDP" + qctx.response.set_rcode(dns.rcode.NOERROR) + qctx.response.flags |= dns.flags.TC + yield DnsResponseSend(qctx.response) + + +def main() -> None: + server = AsyncDnsServer() + server.install_connection_handler(ConnectionReset(delay=1.0)) + server.install_response_handler(TruncateOnUdpHandler()) + server.run() -def port(): - env_port = os.getenv("PORT") - if env_port is None: - env_port = 5300 - else: - env_port = int(env_port) - return env_port - - -def udp_listen(port): - udp = socket.socket(type=socket.SOCK_DGRAM) - udp.bind(("10.53.0.3", port)) - - return udp - - -def tcp_listen(port): - tcp = socket.socket(type=socket.SOCK_STREAM) - tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - tcp.bind(("10.53.0.3", port)) - tcp.listen(100) - - return tcp - - -def udp_tc_once(udp): - qrybytes, clientaddr = udp.recvfrom(65535) - qry = dns.message.from_wire(qrybytes) - answ = dns.message.make_response(qry) - answ.flags |= dns.flags.TC - answbytes = answ.to_wire() - udp.sendto(answbytes, clientaddr) - - -def tcp_once(tcp): - csock, _clientaddr = tcp.accept() - time.sleep(5) - csock.close() - - -def sigterm(signum, frame): - os.remove("ans.pid") - sys.exit(0) - - -def write_pid(): - with open("ans.pid", "w") as f: - pid = os.getpid() - f.write("{}".format(pid)) - - -signal.signal(signal.SIGTERM, sigterm) -write_pid() - -udp = udp_listen(port()) -tcp = tcp_listen(port()) - -input = [udp, tcp] - -while True: - try: - inputready, outputready, exceptready = select.select(input, [], []) - except select.error: - break - except socket.error: - break - except KeyboardInterrupt: - break - - for s in inputready: - if s == udp: - udp_tc_once(udp) - if s == tcp: - tcp_once(tcp) - -sigterm(signal.SIGTERM, 0) +if __name__ == "__main__": + main() diff -Nru bind9-9.20.11/bin/tests/system/dlzexternal/driver/Makefile.in bind9-9.20.15/bin/tests/system/dlzexternal/driver/Makefile.in --- bind9-9.20.11/bin/tests/system/dlzexternal/driver/Makefile.in 2025-07-04 09:43:11.026807198 +0000 +++ bind9-9.20.15/bin/tests/system/dlzexternal/driver/Makefile.in 2025-10-18 10:17:04.246497967 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -352,8 +354,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -495,15 +499,13 @@ $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} dlzexternal.la: $(dlzexternal_la_OBJECTS) $(dlzexternal_la_DEPENDENCIES) $(EXTRA_dlzexternal_la_DEPENDENCIES) $(AM_V_CCLD)$(dlzexternal_la_LINK) $(dlzexternal_la_OBJECTS) $(dlzexternal_la_LIBADD) $(LIBS) @@ -518,7 +520,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -668,23 +670,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/driver.Plo + -rm -f ./$(DEPDIR)/driver.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -734,7 +736,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/driver.Plo + -rm -f ./$(DEPDIR)/driver.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -784,3 +786,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/tests/system/dns64/ns1/named.conf1.in bind9-9.20.15/bin/tests/system/dns64/ns1/named.conf1.in --- bind9-9.20.11/bin/tests/system/dns64/ns1/named.conf1.in 2025-07-04 09:42:08.126323285 +0000 +++ bind9-9.20.15/bin/tests/system/dns64/ns1/named.conf1.in 2025-10-18 10:16:12.345728916 +0000 @@ -31,7 +31,7 @@ listen-on-v6 { none; }; allow-recursion { 10.53.0.1; }; notify yes; - dnssec-validation yes; + dnssec-validation no; dns64 2001:bbbb::/96 { clients { any; }; @@ -42,8 +42,6 @@ }; }; -trust-anchors { }; - zone "." { type primary; file "root.db"; diff -Nru bind9-9.20.11/bin/tests/system/dns64/ns1/named.conf2.in bind9-9.20.15/bin/tests/system/dns64/ns1/named.conf2.in --- bind9-9.20.11/bin/tests/system/dns64/ns1/named.conf2.in 2025-07-04 09:42:08.126323285 +0000 +++ bind9-9.20.15/bin/tests/system/dns64/ns1/named.conf2.in 2025-10-18 10:16:12.345728916 +0000 @@ -31,7 +31,7 @@ listen-on-v6 { none; }; allow-recursion { 10.53.0.1; }; notify yes; - dnssec-validation yes; + dnssec-validation no; dns64 2001:bbbb::/96 { clients { any; }; @@ -45,8 +45,6 @@ }; }; -trust-anchors { }; - zone "." { type primary; file "root.db"; diff -Nru bind9-9.20.11/bin/tests/system/dns64/ns1/named.conf3.in bind9-9.20.15/bin/tests/system/dns64/ns1/named.conf3.in --- bind9-9.20.11/bin/tests/system/dns64/ns1/named.conf3.in 2025-07-04 09:42:08.126323285 +0000 +++ bind9-9.20.15/bin/tests/system/dns64/ns1/named.conf3.in 2025-10-18 10:16:12.345728916 +0000 @@ -31,11 +31,9 @@ listen-on-v6 { none; }; allow-recursion { 10.53.0.1; }; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; - zone "." { type primary; file "root.db"; diff -Nru bind9-9.20.11/bin/tests/system/dns64/ns2/named.conf.in bind9-9.20.15/bin/tests/system/dns64/ns2/named.conf.in --- bind9-9.20.11/bin/tests/system/dns64/ns2/named.conf.in 2025-07-04 09:42:08.127323309 +0000 +++ bind9-9.20.15/bin/tests/system/dns64/ns2/named.conf.in 2025-10-18 10:16:12.345728916 +0000 @@ -25,7 +25,7 @@ listen-on-v6 { none; }; recursion yes; notify yes; - dnssec-validation yes; + dnssec-validation no; dns64 2001:aaaa::/96 { clients { 10.53.0.2; }; @@ -60,7 +60,6 @@ response-policy { zone "rpz"; }; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/dns64/ns3/named.conf.in bind9-9.20.15/bin/tests/system/dns64/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/dns64/ns3/named.conf.in 2025-07-04 09:42:08.127323309 +0000 +++ bind9-9.20.15/bin/tests/system/dns64/ns3/named.conf.in 2025-10-18 10:16:12.346728932 +0000 @@ -29,7 +29,7 @@ listen-on { 10.53.0.3; }; listen-on-v6 { fd92:7065:b8e:ffff::3; }; notify yes; - dnssec-validation yes; + dnssec-validation no; allow-recursion { any; }; resolver-use-dns64 yes; @@ -40,7 +40,6 @@ }; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/dns64/ns4/named.conf.in bind9-9.20.15/bin/tests/system/dns64/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/dns64/ns4/named.conf.in 2025-07-04 09:42:08.127323309 +0000 +++ bind9-9.20.15/bin/tests/system/dns64/ns4/named.conf.in 2025-10-18 10:16:12.346728932 +0000 @@ -26,11 +26,10 @@ listen-on port @PORT@ { 10.53.0.4; }; // for start.pl listen-on-v6 { fd92:7065:b8e:fffe::10.53.0.4; }; notify yes; - dnssec-validation yes; + dnssec-validation no; recursion no; }; -trust-anchors { }; zone "." { type master; diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns3/badalg.secure.example.db.in bind9-9.20.15/bin/tests/system/dnssec/ns3/badalg.secure.example.db.in --- bind9-9.20.11/bin/tests/system/dnssec/ns3/badalg.secure.example.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns3/badalg.secure.example.db.in 2025-10-18 10:16:12.350728994 +0000 @@ -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. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 2000042407 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns3 + A 10.53.0.4 +ns3 A 10.53.0.3 diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns3/named.conf.in bind9-9.20.15/bin/tests/system/dnssec/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/dnssec/ns3/named.conf.in 2025-07-04 09:42:08.132323426 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns3/named.conf.in 2025-10-18 10:16:12.351729010 +0000 @@ -91,6 +91,18 @@ allow-update { any; }; }; +zone "badalg.secure.example" { + type primary; + file "badalg.secure.example.db.signed"; + allow-update { any; }; +}; + +zone "zonecut.ent.secure.example" { + type primary; + file "zonecut.ent.secure.example.db.signed"; + allow-update { any; }; +}; + zone "bogus.example" { type primary; file "bogus.example.db.signed"; diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns3/secure.example.db.in bind9-9.20.15/bin/tests/system/dnssec/ns3/secure.example.db.in --- bind9-9.20.11/bin/tests/system/dnssec/ns3/secure.example.db.in 2025-07-04 09:42:08.134323473 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns3/secure.example.db.in 2025-10-18 10:16:12.353729041 +0000 @@ -30,7 +30,12 @@ z A 10.0.0.26 a.a.a.a.a.a.a.a.a.a.e A 10.0.0.27 x CNAME a -badalg A 10.53.0.4 + +badalg NS ns3.badalg +ns3.badalg A 10.53.0.3 + +zonecut.ent NS ns3.zonecut.ent +ns3.zonecut.ent A 10.53.0.3 private NS ns.private ns.private A 10.53.0.2 diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns3/sign.sh bind9-9.20.15/bin/tests/system/dnssec/ns3/sign.sh --- bind9-9.20.11/bin/tests/system/dnssec/ns3/sign.sh 2025-07-04 09:42:08.134323473 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns3/sign.sh 2025-10-18 10:16:12.353729041 +0000 @@ -77,6 +77,31 @@ echo_i "ns3/sign.sh: example zones" +# A zone that will be treated as insecure as the DEFAULT_ALGORITHM is +# disabled for it. +zone=badalg.secure.example. +infile=badalg.secure.example.db.in +zonefile=badalg.secure.example.db + +keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone") + +cat "$infile" "$keyname.key" >"$zonefile" + +"$SIGNER" -z -o "$zone" "$zonefile" >/dev/null + +# A zone that will be treated as insecure as the DEFAULT_ALGORITHM is +# disabled for ent.secure.example. +zone=zonecut.ent.secure.example. +infile=zonecut.ent.secure.example.db.in +zonefile=zonecut.ent.secure.example.db + +keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone") + +cat "$infile" "$keyname.key" >"$zonefile" + +"$SIGNER" -z -o "$zone" "$zonefile" >/dev/null + +# zone=secure.example. infile=secure.example.db.in zonefile=secure.example.db @@ -85,7 +110,7 @@ dnameandkey=$("$KEYGEN" -T KEY -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n host "dnameandkey.$zone") keyname=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone") -cat "$infile" "$cnameandkey.key" "$dnameandkey.key" "$keyname.key" >"$zonefile" +cat "$infile" dsset-badalg.secure.example. "$cnameandkey.key" "$dnameandkey.key" "$keyname.key" >"$zonefile" "$SIGNER" -z -D -o "$zone" "$zonefile" >/dev/null cat "$zonefile" "$zonefile".signed >"$zonefile".tmp diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns3/zonecut.ent.secure.example.db.in bind9-9.20.15/bin/tests/system/dnssec/ns3/zonecut.ent.secure.example.db.in --- bind9-9.20.11/bin/tests/system/dnssec/ns3/zonecut.ent.secure.example.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns3/zonecut.ent.secure.example.db.in 2025-10-18 10:16:12.354729056 +0000 @@ -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. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 2000042407 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns3 + A 10.53.0.4 +ns3 A 10.53.0.3 diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns4/named1.conf.in bind9-9.20.15/bin/tests/system/dnssec/ns4/named1.conf.in --- bind9-9.20.11/bin/tests/system/dnssec/ns4/named1.conf.in 2025-07-04 09:42:08.135323496 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns4/named1.conf.in 2025-10-18 10:16:12.354729056 +0000 @@ -34,6 +34,8 @@ disable-ds-digests "digest-alg-unsupported.example." { "SHA384"; "SHA-384"; }; disable-ds-digests "ds-unsupported.example." {"SHA256"; "SHA-256"; "SHA384"; "SHA-384"; }; disable-algorithms "badalg.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "z.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "ent.secure.example." { ECDSAP256SHA256; }; # Note: We only reference the bind.keys file here to confirm that it # is *not* being used. It contains the real root key, and we're diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns4/named2.conf.in bind9-9.20.15/bin/tests/system/dnssec/ns4/named2.conf.in --- bind9-9.20.11/bin/tests/system/dnssec/ns4/named2.conf.in 2025-07-04 09:42:08.135323496 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns4/named2.conf.in 2025-10-18 10:16:12.355729072 +0000 @@ -29,6 +29,8 @@ disable-ds-digests "digest-alg-unsupported.example." { "SHA384"; "SHA-384"; }; disable-ds-digests "ds-unsupported.example." { "SHA256"; "SHA-256"; "SHA384"; "SHA-384"; }; disable-algorithms "badalg.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "z.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "ent.secure.example." { ECDSAP256SHA256; }; }; key rndc_key { diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns4/named3.conf.in bind9-9.20.15/bin/tests/system/dnssec/ns4/named3.conf.in --- bind9-9.20.11/bin/tests/system/dnssec/ns4/named3.conf.in 2025-07-04 09:42:08.135323496 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns4/named3.conf.in 2025-10-18 10:16:12.355729072 +0000 @@ -32,6 +32,8 @@ disable-ds-digests "digest-alg-unsupported.example." { "SHA384"; "SHA-384";}; disable-ds-digests "ds-unsupported.example." { "SHA256"; "SHA-256"; "SHA384"; "SHA-384"; }; disable-algorithms "badalg.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "z.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "ent.secure.example." { ECDSAP256SHA256; }; }; key rndc_key { diff -Nru bind9-9.20.11/bin/tests/system/dnssec/ns4/named4.conf.in bind9-9.20.15/bin/tests/system/dnssec/ns4/named4.conf.in --- bind9-9.20.11/bin/tests/system/dnssec/ns4/named4.conf.in 2025-07-04 09:42:08.135323496 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/ns4/named4.conf.in 2025-10-18 10:16:12.355729072 +0000 @@ -25,6 +25,8 @@ disable-ds-digests "digest-alg-unsupported.example." { "SHA384"; "SHA-384"; }; disable-ds-digests "ds-unsupported.example." { "SHA256"; "SHA-256"; "SHA384"; "SHA-384"; }; disable-algorithms "badalg.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "z.secure.example." { ECDSAP256SHA256; }; + disable-algorithms "ent.secure.example." { ECDSAP256SHA256; }; }; key rndc_key { diff -Nru bind9-9.20.11/bin/tests/system/dnssec/tests.sh bind9-9.20.15/bin/tests/system/dnssec/tests.sh --- bind9-9.20.11/bin/tests/system/dnssec/tests.sh 2025-07-04 09:42:08.139323590 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/tests.sh 2025-10-18 10:16:12.359729134 +0000 @@ -2851,7 +2851,7 @@ grep "SERVFAIL" dig.out.ns4.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 grep "expired.example/.*: RRSIG has expired" ns4/named.run >/dev/null || ret=1 -grep "; EDE: 7 (Signature Expired): (expired.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "; EDE: 7 (Signature Expired)" dig.out.ns4.test$n >/dev/null || ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" status=$((status + ret)) @@ -2863,7 +2863,7 @@ grep "SERVFAIL" dig.out.ns4.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 grep "future.example/.*: RRSIG validity period has not begun" ns4/named.run >/dev/null || ret=1 -grep "; EDE: 8 (Signature Not Yet Valid): (future.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "; EDE: 8 (Signature Not Yet Valid)" dig.out.ns4.test$n >/dev/null || ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" status=$((status + ret)) @@ -3742,7 +3742,7 @@ dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-unsupported.example A >dig.out.ns4.test$n grep "status: NOERROR," dig.out.ns3.test$n >/dev/null || ret=1 grep "status: NOERROR," dig.out.ns4.test$n >/dev/null || ret=1 -grep "; EDE: 1 (Unsupported DNSKEY Algorithm): (255 dnskey-unsupported.example/SOA)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "; EDE: 1 (Unsupported DNSKEY Algorithm)" dig.out.ns4.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" @@ -3751,16 +3751,48 @@ echo_i "checking EDE code 2 for unsupported DS digest ($n)" ret=0 dig_with_opts @10.53.0.4 a.ds-unsupported.example >dig.out.ns4.test$n || ret=1 -grep "; EDE: 2 (Unsupported DS Digest Type): (SHA-256 ds-unsupported.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "; EDE: 2 (Unsupported DS Digest Type)" dig.out.ns4.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" status=$((status + ret)) +echo_i "check that zone contents are still secure despite disable-algorithms on query name (name below zone name) ($n)" +ret=0 +dig_with_opts @10.53.0.4 z.secure.example >dig.out.ns4.test$n || ret=1 +grep "ANSWER: 2," dig.out.ns4.test$n >/dev/null || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status + ret)) + +echo_i "check that zone contents are treated as insecure when disable-algorithms name is above zone name ($n)" +ret=0 +dig_with_opts @10.53.0.4 zonecut.ent.secure.example >dig.out.ns4.test$n || ret=1 +grep "ANSWER: 2," dig.out.ns4.test$n >/dev/null || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 +grep "; EDE: 1 (Unsupported DNSKEY Algorithm)" dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status + ret)) + +echo_i "check that DS records are still treated as secure at the disable-algorithm name ($n)" +ret=0 +dig_with_opts @10.53.0.4 badalg.secure.example DS >dig.out.ns4.test$n || ret=1 +grep "ANSWER: 2," dig.out.ns4.test$n >/dev/null || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +test "$ret" -eq 0 || echo_i "failed" +status=$((status + ret)) + echo_i "checking EDE code 1 for bad alg mnemonic ($n)" ret=0 dig_with_opts @10.53.0.4 badalg.secure.example >dig.out.ns4.test$n || ret=1 -grep "; EDE: 1 (Unsupported DNSKEY Algorithm): (ECDSAP256SHA256 badalg.secure.example/A)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "; EDE: 1 (Unsupported DNSKEY Algorithm)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" @@ -3769,8 +3801,8 @@ echo_i "checking both EDE code 1 and 2 for unsupported digest on one DNSKEY and alg on the other ($n)" ret=0 dig_with_opts @10.53.0.4 a.digest-alg-unsupported.example >dig.out.ns4.test$n || ret=1 -grep "; EDE: 1 (Unsupported DNSKEY Algorithm): (ECDSAP384SHA384 digest-alg-unsupported.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1 -grep "; EDE: 2 (Unsupported DS Digest Type): (SHA-384 digest-alg-unsupported.example/DNSKEY)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "; EDE: 1 (Unsupported DNSKEY Algorithm)" dig.out.ns4.test$n >/dev/null || ret=1 +grep "; EDE: 2 (Unsupported DS Digest Type)" dig.out.ns4.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null && ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" @@ -4095,7 +4127,7 @@ dig_with_opts @10.53.0.8 a.unsupported.trusted A >dig.out.ns8.test$n grep "status: NOERROR," dig.out.ns3.test$n >/dev/null || ret=1 grep "status: NOERROR," dig.out.ns8.test$n >/dev/null || ret=1 -grep "; EDE: 1 (Unsupported DNSKEY Algorithm): (255 ns3.unsupported.trusted (cached))" dig.out.ns8.test$n >/dev/null || ret=1 +grep "; EDE: 1 (Unsupported DNSKEY Algorithm)" dig.out.ns8.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n >/dev/null && ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" @@ -4107,7 +4139,7 @@ dig_with_opts @10.53.0.8 a.unsupported.managed A >dig.out.ns8.test$n grep "status: NOERROR," dig.out.ns3.test$n >/dev/null || ret=1 grep "status: NOERROR," dig.out.ns8.test$n >/dev/null || ret=1 -grep "; EDE: 1 (Unsupported DNSKEY Algorithm): (255 ns3.unsupported.managed (cached))" dig.out.ns8.test$n >/dev/null || ret=1 +grep "; EDE: 1 (Unsupported DNSKEY Algorithm)" dig.out.ns8.test$n >/dev/null || ret=1 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n >/dev/null && ret=1 n=$((n + 1)) test "$ret" -eq 0 || echo_i "failed" @@ -4612,6 +4644,57 @@ if [ "$ret" -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) +echo_i "checking NSEC3 nxdomain response closest encloser with 0 ENT ($n)" +ret=0 +dig_with_opts @10.53.0.4 b.b.b.b.b.a.nsec3.example. >dig.out.ns4.test$n +grep "status: NXDOMAIN" dig.out.ns4.test$n >/dev/null || ret=1 +# closest encloser (a.nsec3.example) +pat1="^6OVDUHTN094ML2PV8AN90U0DPU823GH2\.nsec3\.example\..*NSEC3 1 0 0 - 7AT0S0RIDCJRFF2M5H5AAV22CSFJBUL4 A RRSIG\$" +grep "$pat1" dig.out.ns4.test$n >/dev/null || ret=1 +# no QNAME proof (b.a.nsec3.example / DSPF4R9UKOEPJ9O34E1H4539LSOTL14E) +pat2="^CG2DVCNE20EKU1PDRLMI2L4DGC2FO1H3\.nsec3\.example\..*NSEC3 1 0 0 - EF2S05SGK1IR2K5SKMFIRERGQCLMR18M A RRSIG\$" +grep "$pat2" dig.out.ns4.test$n >/dev/null || ret=1 +# no WILDCARD proof (*.a.nsec3.example / TFGQ60S97BS31IT1EBEDO63ETM0T5JFA) +pat3="^R8EVDMNIGNOKME4LH2H90OSP2PRSNJ1Q\.nsec3\.example\..*NSEC3 1 0 0 - VH656EQUD4J02OFVSO4GKOK5D02MS1TL NS DS RRSIG\$" +grep "$pat3" dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +if [ "$ret" -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "checking NSEC3 nxdomain response closest encloser with 1 ENTs ($n)" +ret=0 +dig_with_opts @10.53.0.4 b.b.b.b.b.a.a.nsec3.example. >dig.out.ns4.test$n +grep "status: NXDOMAIN" dig.out.ns4.test$n >/dev/null || ret=1 +# closest encloser (a.a.nsec3.example) +pat1="^NGCJFSOLJUUE27PFNQNJIME4TQ0OU2DH\.nsec3\.example\..*NSEC3 1 0 0 - R8EVDMNIGNOKME4LH2H90OSP2PRSNJ1Q\$" +grep "$pat1" dig.out.ns4.test$n >/dev/null || ret=1 +# no QNAME proof (b.a.a.nsec3.example / V8I8SAIIVC3HOVMOVENSDRA6ATDCEMJI) +pat2="^R8EVDMNIGNOKME4LH2H90OSP2PRSNJ1Q\.nsec3\.example\..*NSEC3 1 0 0 - VH656EQUD4J02OFVSO4GKOK5D02MS1TL NS DS RRSIG\$" +grep "$pat2" dig.out.ns4.test$n >/dev/null || ret=1 +# no WILDCARD proof (*.a.a.nsec3.example / V7JNNDJ4NLRIU195FRB7DLUCSLU4LLFM) +pat3="^R8EVDMNIGNOKME4LH2H90OSP2PRSNJ1Q\.nsec3\.example\..*NSEC3 1 0 0 - VH656EQUD4J02OFVSO4GKOK5D02MS1TL NS DS RRSIG\$" +grep "$pat3" dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +if [ "$ret" -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +echo_i "checking NSEC3 nxdomain response closest encloser with 2 ENTs ($n)" +ret=0 +dig_with_opts @10.53.0.4 b.b.b.b.b.a.a.a.nsec3.example. >dig.out.ns4.test$n +grep "status: NXDOMAIN" dig.out.ns4.test$n >/dev/null || ret=1 +# closest encloser (a.a.a.nsec3.example) +pat1="^H7RHPDCHSVVRAND332F878C8AB6IBJQV\.nsec3\.example\..*NSEC3 1 0 0 - K8IG76R2UPQ13IKFO49L7IB9JRVB6QJI\$" +grep "$pat1" dig.out.ns4.test$n >/dev/null || ret=1 +# no QNAME proof (b.a.a.a.nsec3.example / 18Q8D89RM8GGRSSOPFRB05QS6VEGB1P4) +pat2="^VH656EQUD4J02OFVSO4GKOK5D02MS1TL\.nsec3\.example\..*NSEC3 1 0 0 - 1HARMGSKJH0EBU2EI2OJIKTDPIQA6KBI NS DS RRSIG\$" +grep "$pat2" dig.out.ns4.test$n >/dev/null || ret=1 +# no WILDCARD proof (*.a.a.a.nsec3.example / 8113LDMSEFPUAG4VGFF1C8KLOUT4Q6PH) +pat3="^7AT0S0RIDCJRFF2M5H5AAV22CSFJBUL4\.nsec3\.example\..*NSEC3 1 0 0 - BEJ5GMQA872JF4DAGQ0R3O5Q7A2O5S9L A RRSIG\$" +grep "$pat3" dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +if [ "$ret" -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + echo_i "checking that records other than DNSKEY are not signed by a revoked key by dnssec-signzone ($n)" ret=0 ( @@ -4702,6 +4785,17 @@ n=$((n + 1)) if [ "$ret" -ne 0 ]; then echo_i "failed"; fi status=$((status + ret)) + +echo_i "test that RRSIGS are returned for glue name with CD=1 ($n)" +ret=0 +dig_with_opts @10.53.0.4 ns3.secure.example A +cd >dig.out.ns4.test$n +grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 +grep "ANSWER: 2," dig.out.ns4.test$n >/dev/null || ret=1 +grep "ns3\.secure\.example\..[0-9]*.IN.A.10\.53\.0.3" dig.out.ns4.test$n >/dev/null || ret=1 +grep "ns3\.secure\.example\..[0-9]*.IN.RRSIG.A " dig.out.ns4.test$n >/dev/null || ret=1 +n=$((n + 1)) +if [ "$ret" -ne 0 ]; then echo_i "failed"; fi +status=$((status + ret)) echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff -Nru bind9-9.20.11/bin/tests/system/dnssec/tests_sh_dnssec.py bind9-9.20.15/bin/tests/system/dnssec/tests_sh_dnssec.py --- bind9-9.20.11/bin/tests/system/dnssec/tests_sh_dnssec.py 2025-07-04 09:42:08.140323613 +0000 +++ bind9-9.20.15/bin/tests/system/dnssec/tests_sh_dnssec.py 2025-10-18 10:16:12.359729134 +0000 @@ -13,6 +13,7 @@ pytestmark = pytest.mark.extra_artifacts( [ + ".hypothesis/examples/*", "K*", "canonical*", "delv.out*", @@ -78,6 +79,7 @@ "ns3/NSEC3", "ns3/auto-nsec.example.db", "ns3/auto-nsec3.example.db", + "ns3/badalg.secure.example.db", "ns3/badds.example.db", "ns3/bogus.example.db", "ns3/disabled.managed.db", @@ -90,6 +92,7 @@ "ns3/dnskey-unsupported-2.example.db", "ns3/dnskey-unsupported.example.db", "ns3/dnskey-unsupported.example.db.tmp", + "ns3/ds-unsupported.example.db", "ns3/dynamic.example.db", "ns3/digest-alg-unsupported.example.db", "ns3/enabled.managed.db", @@ -140,7 +143,7 @@ "ns3/update-nsec3.example.db.signed", "ns3/upper.example.db", "ns3/upper.example.db.lower", - "ns3/ds-unsupported.example.db", + "ns3/zonecut.ent.secure.example.db", "ns4/managed.conf", "ns4/managed-keys.bind", "ns4/named.secroots", diff -Nru bind9-9.20.11/bin/tests/system/dnstap/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/dnstap/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/dnstap/ns1/named.conf.j2 2025-07-04 09:42:08.142323660 +0000 +++ bind9-9.20.15/bin/tests/system/dnstap/ns1/named.conf.j2 2025-10-18 10:16:12.361729165 +0000 @@ -28,11 +28,10 @@ dnstap { all; }; send-cookie no; require-server-cookie no; - dnssec-validation yes; + dnssec-validation no; qname-minimization disabled; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/dnstap/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/dnstap/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/dnstap/ns2/named.conf.j2 2025-07-04 09:42:08.142323660 +0000 +++ bind9-9.20.15/bin/tests/system/dnstap/ns2/named.conf.j2 2025-10-18 10:16:12.362729181 +0000 @@ -28,11 +28,10 @@ dnstap { all; }; send-cookie no; require-server-cookie no; - dnssec-validation yes; + dnssec-validation no; qname-minimization disabled; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/dnstap/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/dnstap/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/dnstap/ns3/named.conf.j2 2025-07-04 09:42:08.142323660 +0000 +++ bind9-9.20.15/bin/tests/system/dnstap/ns3/named.conf.j2 2025-10-18 10:16:12.362729181 +0000 @@ -29,11 +29,10 @@ send-cookie no; require-server-cookie no; minimal-responses no; - dnssec-validation yes; + dnssec-validation no; qname-minimization disabled; }; -trust-anchors { }; server 10.53.0.1 { tcp-only yes; }; diff -Nru bind9-9.20.11/bin/tests/system/dnstap/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/dnstap/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/dnstap/ns4/named.conf.j2 2025-07-04 09:42:08.142323660 +0000 +++ bind9-9.20.15/bin/tests/system/dnstap/ns4/named.conf.j2 2025-10-18 10:16:12.362729181 +0000 @@ -28,11 +28,10 @@ dnstap { all; }; send-cookie no; require-server-cookie no; - dnssec-validation yes; + dnssec-validation no; qname-minimization disabled; }; -trust-anchors { }; server 10.53.0.1 { tcp-only yes; }; diff -Nru bind9-9.20.11/bin/tests/system/dnstap/tests_dnstap.py bind9-9.20.15/bin/tests/system/dnstap/tests_dnstap.py --- bind9-9.20.11/bin/tests/system/dnstap/tests_dnstap.py 2025-07-04 09:42:08.143323683 +0000 +++ bind9-9.20.15/bin/tests/system/dnstap/tests_dnstap.py 2025-10-18 10:16:12.362729181 +0000 @@ -18,9 +18,8 @@ import isctest.mark import pytest -import dns.message - pytest.importorskip("dns", minversion="2.0.0") +import dns.rrset pytestmark = [ isctest.mark.with_dnstap, @@ -49,7 +48,7 @@ def test_dnstap_dispatch_socket_addresses(): # Send some query to ns3 so that it records something in its dnstap file. - msg = dns.message.make_query("mail.example.", "A") + msg = isctest.query.create("mail.example.", "A") res = isctest.query.tcp(msg, "10.53.0.2", expected_rcode=dns.rcode.NOERROR) assert res.answer == [ dns.rrset.from_text("mail.example.", 300, "IN", "A", "10.0.0.2") diff -Nru bind9-9.20.11/bin/tests/system/dnstap/tests_sh_dnstap.py bind9-9.20.15/bin/tests/system/dnstap/tests_sh_dnstap.py --- bind9-9.20.11/bin/tests/system/dnstap/tests_sh_dnstap.py 2025-07-04 09:42:08.143323683 +0000 +++ bind9-9.20.15/bin/tests/system/dnstap/tests_sh_dnstap.py 2025-10-18 10:16:12.362729181 +0000 @@ -31,5 +31,6 @@ ] +@pytest.mark.flaky(max_runs=2, rerun_filter=isctest.mark.is_host_freebsd_13) def test_dnstap(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/doth/example.axfr.good bind9-9.20.15/bin/tests/system/doth/example.axfr.good --- bind9-9.20.11/bin/tests/system/doth/example.axfr.good 2025-07-04 09:42:08.146323754 +0000 +++ bind9-9.20.15/bin/tests/system/doth/example.axfr.good 2025-10-18 10:16:12.366729243 +0000 @@ -2524,6 +2524,7 @@ biganswer.example. 3600 IN A 10.10.50.48 biganswer.example. 3600 IN A 10.10.50.49 biganswer.example. 3600 IN A 10.10.50.50 +brid.example. 3600 IN BRID abcd caa01.example. 3600 IN CAA 0 issue "ca.example.net; policy=ev" caa02.example. 3600 IN CAA 128 tbs "Unknown" caa03.example. 3600 IN CAA 128 tbs "" @@ -2548,12 +2549,14 @@ ds01.example. 3600 IN DS 12892 5 2 26584835CA80C81C91999F31CFAF2A0E89D4FF1C8FAFD0DDB31A85C7 19277C13 ds02.example. 3600 IN NS ns43.example. ds02.example. 3600 IN DS 12892 5 1 7AA4A3F416C2F2391FB7AB0D434F762CD62D1390 +dsync01.example. 3600 IN DSYNC CDS NOTIFY 53 . eid01.example. 3600 IN EID 1289AB eui48.example. 3600 IN EUI48 01-23-45-67-89-ab eui64.example. 3600 IN EUI64 01-23-45-67-89-ab-cd-ef gid01.example. 3600 IN GID \# 1 03 gpos01.example. 3600 IN GPOS "-22.6882" "116.8652" "250.0" gpos02.example. 3600 IN GPOS "" "" "" +hhit.example. 3600 IN HHIT abcd hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4" hinfo02.example. 3600 IN HINFO "PC" "NetBSD" hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D diff -Nru bind9-9.20.11/bin/tests/system/doth/example8.axfr.good bind9-9.20.15/bin/tests/system/doth/example8.axfr.good --- bind9-9.20.11/bin/tests/system/doth/example8.axfr.good 2025-07-04 09:42:08.147323777 +0000 +++ bind9-9.20.15/bin/tests/system/doth/example8.axfr.good 2025-10-18 10:16:12.366729243 +0000 @@ -2524,6 +2524,7 @@ biganswer.example8. 3600 IN A 10.10.50.48 biganswer.example8. 3600 IN A 10.10.50.49 biganswer.example8. 3600 IN A 10.10.50.50 +brid.example8. 3600 IN BRID abcd caa01.example8. 3600 IN CAA 0 issue "ca.example.net; policy=ev" caa02.example8. 3600 IN CAA 128 tbs "Unknown" caa03.example8. 3600 IN CAA 128 tbs "" @@ -2548,12 +2549,14 @@ ds01.example8. 3600 IN NS ns42.example8. ds02.example8. 3600 IN DS 12892 5 1 7AA4A3F416C2F2391FB7AB0D434F762CD62D1390 ds02.example8. 3600 IN NS ns43.example8. +dsync01.example8. 3600 IN DSYNC CDS NOTIFY 53 . eid01.example8. 3600 IN EID 1289AB eui48.example8. 3600 IN EUI48 01-23-45-67-89-ab eui64.example8. 3600 IN EUI64 01-23-45-67-89-ab-cd-ef gid01.example8. 3600 IN GID \# 1 03 gpos01.example8. 3600 IN GPOS "-22.6882" "116.8652" "250.0" gpos02.example8. 3600 IN GPOS "" "" "" +hhit.example8. 3600 IN HHIT abcd hinfo01.example8. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4" hinfo02.example8. 3600 IN HINFO "PC" "NetBSD" hip1.example8. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D diff -Nru bind9-9.20.11/bin/tests/system/doth/ns1/named.conf.in bind9-9.20.15/bin/tests/system/doth/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/doth/ns1/named.conf.in 2025-07-04 09:42:08.147323777 +0000 +++ bind9-9.20.15/bin/tests/system/doth/ns1/named.conf.in 2025-10-18 10:16:12.366729243 +0000 @@ -94,14 +94,13 @@ notify explicit; also-notify { 10.53.0.2 port @PORT@; }; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; transfers-in 100; transfers-out 100; max-records-per-type 0; }; -trust-anchors { }; zone "." { type primary; diff -Nru bind9-9.20.11/bin/tests/system/doth/ns2/named.conf.in bind9-9.20.15/bin/tests/system/doth/ns2/named.conf.in --- bind9-9.20.11/bin/tests/system/doth/ns2/named.conf.in 2025-07-04 09:42:08.148323801 +0000 +++ bind9-9.20.15/bin/tests/system/doth/ns2/named.conf.in 2025-10-18 10:16:12.367729258 +0000 @@ -51,13 +51,12 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; max-records-per-type 0; transfers-in 100; transfers-out 100; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/doth/ns3/named.conf.in bind9-9.20.15/bin/tests/system/doth/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/doth/ns3/named.conf.in 2025-07-04 09:42:08.148323801 +0000 +++ bind9-9.20.15/bin/tests/system/doth/ns3/named.conf.in 2025-10-18 10:16:12.367729258 +0000 @@ -43,11 +43,10 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; max-records-per-type 0; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/doth/ns4/named.conf.in bind9-9.20.15/bin/tests/system/doth/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/doth/ns4/named.conf.in 2025-07-04 09:42:08.148323801 +0000 +++ bind9-9.20.15/bin/tests/system/doth/ns4/named.conf.in 2025-10-18 10:16:12.367729258 +0000 @@ -51,11 +51,10 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; max-records-per-type 0; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/doth/ns5/named.conf.in bind9-9.20.15/bin/tests/system/doth/ns5/named.conf.in --- bind9-9.20.11/bin/tests/system/doth/ns5/named.conf.in 2025-07-04 09:42:08.148323801 +0000 +++ bind9-9.20.15/bin/tests/system/doth/ns5/named.conf.in 2025-10-18 10:16:12.368729274 +0000 @@ -39,11 +39,10 @@ notify no; ixfr-from-differences yes; check-integrity no; - dnssec-validation yes; + dnssec-validation no; max-records-per-type 0; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/doth/tests_gnutls.py bind9-9.20.15/bin/tests/system/doth/tests_gnutls.py --- bind9-9.20.11/bin/tests/system/doth/tests_gnutls.py 2025-07-04 09:42:08.149323824 +0000 +++ bind9-9.20.15/bin/tests/system/doth/tests_gnutls.py 2025-10-18 10:16:12.368729274 +0000 @@ -20,11 +20,12 @@ pytest.importorskip("dns") import dns.exception -import dns.message import dns.name import dns.rdataclass import dns.rdatatype +import isctest + pytestmark = pytest.mark.extra_artifacts( [ "gnutls-cli.*", @@ -35,7 +36,7 @@ def test_gnutls_cli_query(gnutls_cli_executable, named_tlsport): # Prepare the example/SOA query which will be sent over TLS. - query = dns.message.make_query("example.", dns.rdatatype.SOA) + query = isctest.query.create("example.", dns.rdatatype.SOA) query_wire = query.to_wire() query_with_length = struct.pack(">H", len(query_wire)) + query_wire diff -Nru bind9-9.20.11/bin/tests/system/dsdigest/tests_dsdigest.py bind9-9.20.15/bin/tests/system/dsdigest/tests_dsdigest.py --- bind9-9.20.11/bin/tests/system/dsdigest/tests_dsdigest.py 2025-07-04 09:42:08.150323847 +0000 +++ bind9-9.20.15/bin/tests/system/dsdigest/tests_dsdigest.py 2025-10-18 10:16:12.369729289 +0000 @@ -9,7 +9,7 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -import dns.message +import dns.flags import pytest import isctest @@ -29,7 +29,7 @@ def test_dsdigest_good(): """Check that validation with enabled digest types works""" - msg = dns.message.make_query("a.good.", "A", want_dnssec=True) + msg = isctest.query.create("a.good.", "A") res = isctest.query.tcp( msg, "10.53.0.3", @@ -51,7 +51,7 @@ def test_dsdigest_insecure(): """Check that validation with not supported digest algorithms is insecure""" - msg_ds = dns.message.make_query("bad.", "DS", want_dnssec=True) + msg_ds = isctest.query.create("bad.", "DS") res_ds = isctest.query.tcp( msg_ds, "10.53.0.4", @@ -59,7 +59,7 @@ isctest.check.noerror(res_ds) assert res_ds.flags & dns.flags.AD - msg_a = dns.message.make_query("a.bad.", "A", want_dnssec=True) + msg_a = isctest.query.create("a.bad.", "A") res_a = isctest.query.tcp( msg_a, "10.53.0.4", diff -Nru bind9-9.20.11/bin/tests/system/dyndb/driver/Makefile.in bind9-9.20.15/bin/tests/system/dyndb/driver/Makefile.in --- bind9-9.20.11/bin/tests/system/dyndb/driver/Makefile.in 2025-07-04 09:43:11.052807804 +0000 +++ bind9-9.20.15/bin/tests/system/dyndb/driver/Makefile.in 2025-10-18 10:17:04.270498335 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -354,8 +356,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -507,15 +511,13 @@ $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} sample.la: $(sample_la_OBJECTS) $(sample_la_DEPENDENCIES) $(EXTRA_sample_la_DEPENDENCIES) $(AM_V_CCLD)$(sample_la_LINK) $(sample_la_OBJECTS) $(sample_la_LIBADD) $(LIBS) @@ -535,7 +537,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -685,23 +687,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/db.Plo + -rm -f ./$(DEPDIR)/db.Plo -rm -f ./$(DEPDIR)/driver.Plo -rm -f ./$(DEPDIR)/instance.Plo -rm -f ./$(DEPDIR)/log.Plo @@ -756,7 +758,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/db.Plo + -rm -f ./$(DEPDIR)/db.Plo -rm -f ./$(DEPDIR)/driver.Plo -rm -f ./$(DEPDIR)/instance.Plo -rm -f ./$(DEPDIR)/log.Plo @@ -811,3 +813,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/tests/system/ecdsa/tests_ecdsa.py bind9-9.20.15/bin/tests/system/ecdsa/tests_ecdsa.py --- bind9-9.20.11/bin/tests/system/ecdsa/tests_ecdsa.py 2025-07-04 09:42:08.153323917 +0000 +++ bind9-9.20.15/bin/tests/system/ecdsa/tests_ecdsa.py 2025-10-18 10:16:12.372729336 +0000 @@ -12,7 +12,8 @@ import os import pytest -import dns.message +import dns.flags + import isctest @@ -29,8 +30,7 @@ def check_server_soa(resolver): - msg = dns.message.make_query(".", "SOA") - msg.flags += dns.flags.AD + msg = isctest.query.create(".", "SOA") res1 = isctest.query.tcp(msg, "10.53.0.1") res2 = isctest.query.tcp(msg, resolver) isctest.check.rrsets_equal(res1.answer, res2.answer) diff -Nru bind9-9.20.11/bin/tests/system/emptyzones/tests_emptyzones.py bind9-9.20.15/bin/tests/system/emptyzones/tests_emptyzones.py --- bind9-9.20.11/bin/tests/system/emptyzones/tests_emptyzones.py 2025-07-04 09:42:08.155323964 +0000 +++ bind9-9.20.15/bin/tests/system/emptyzones/tests_emptyzones.py 2025-10-18 10:16:12.374729367 +0000 @@ -9,22 +9,21 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -import dns.message - import isctest -def test_emptyzones(servers, templates): +def test_emptyzones(ns1, templates): # check that switching to automatic empty zones works - ns1 = servers["ns1"] - ns1.rndc("reload") + with ns1.watch_log_from_here() as watcher: + ns1.rndc("reload") + watcher.wait_for_line("all zones loaded") templates.render("ns1/named.conf", {"automatic_empty_zones": True}) ns1.rndc("reload") - msg = dns.message.make_query("version.bind", "TXT", "CH") + msg = isctest.query.create("version.bind", "TXT", "CH") res = isctest.query.tcp(msg, "10.53.0.1") isctest.check.noerror(res) # check that allow-transfer { none; } works - msg = dns.message.make_query("10.in-addr.arpa", "AXFR") + msg = isctest.query.create("10.in-addr.arpa", "AXFR") res = isctest.query.tcp(msg, "10.53.0.1") isctest.check.refused(res) diff -Nru bind9-9.20.11/bin/tests/system/enginepkcs11/tests_sh_enginepkcs11.py bind9-9.20.15/bin/tests/system/enginepkcs11/tests_sh_enginepkcs11.py --- bind9-9.20.11/bin/tests/system/enginepkcs11/tests_sh_enginepkcs11.py 2025-07-04 09:42:08.156323988 +0000 +++ bind9-9.20.15/bin/tests/system/enginepkcs11/tests_sh_enginepkcs11.py 2025-10-18 10:16:12.375729383 +0000 @@ -11,8 +11,6 @@ import pytest -import isctest.mark - pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", @@ -53,6 +51,6 @@ ) -@isctest.mark.flaky(max_runs=3) # GL#4605 +@pytest.mark.flaky(max_runs=5) # GL#4605 def test_enginepkcs11(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ans4/ans.pl bind9-9.20.15/bin/tests/system/fetchlimit/ans4/ans.pl --- bind9-9.20.11/bin/tests/system/fetchlimit/ans4/ans.pl 2025-07-04 09:42:08.156323988 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ans4/ans.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -#!/usr/bin/perl -w - -# 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. - -# -# Don't respond if the "norespond" file exists; otherwise respond to -# any A or AAAA query. -# - -use IO::File; -use IO::Socket; -use Net::DNS; -use Net::DNS::Packet; - -my $localport = int($ENV{'PORT'}); -if (!$localport) { $localport = 5300; } - -my $sock = IO::Socket::INET->new(LocalAddr => "10.53.0.4", - LocalPort => $localport, Proto => "udp") or die "$!"; - -my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!"; -print $pidf "$$\n" or die "cannot write pid file: $!"; -$pidf->close or die "cannot close pid file: $!"; -sub rmpid { unlink "ans.pid"; exit 1; }; - -$SIG{INT} = \&rmpid; -$SIG{TERM} = \&rmpid; - -for (;;) { - $sock->recv($buf, 512); - - print "**** request from " , $sock->peerhost, " port ", $sock->peerport, "\n"; - - my $packet; - - if ($Net::DNS::VERSION > 0.68) { - $packet = new Net::DNS::Packet(\$buf, 0); - $@ and die $@; - } else { - my $err; - ($packet, $err) = new Net::DNS::Packet(\$buf, 0); - $err and die $err; - } - - print "REQUEST:\n"; - $packet->print; - - $packet->header->qr(1); - - my @questions = $packet->question; - my $qname = $questions[0]->qname; - my $qtype = $questions[0]->qtype; - - my $donotrespond = 0; - - if (-e 'norespond') { - $donotrespond = 1; - } else { - $packet->header->aa(1); - if ($qtype eq "A") { - $packet->push("answer", - new Net::DNS::RR($qname . - " 300 A 192.0.2.1")); - } elsif ($qtype eq "AAAA") { - $packet->push("answer", - new Net::DNS::RR($qname . - " 300 AAAA 2001:db8:beef::1")); - } - } - - if ($donotrespond == 0) { - if (index($qname, "latency") == 0) { - # 50ms latency - select(undef, undef, undef, 0.05); - } - $sock->send($packet->data); - print "RESPONSE:\n"; - $packet->print; - print "\n"; - } -} diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ans4/ans.py bind9-9.20.15/bin/tests/system/fetchlimit/ans4/ans.py --- bind9-9.20.11/bin/tests/system/fetchlimit/ans4/ans.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ans4/ans.py 2025-10-18 10:16:12.375729383 +0000 @@ -0,0 +1,48 @@ +""" +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. +""" + +from typing import AsyncGenerator + +import dns + +from isctest.asyncserver import ( + ControllableAsyncDnsServer, + DnsResponseSend, + QueryContext, + ResponseHandler, + ToggleResponsesCommand, +) + + +class MaybeDelayedAddressAnswerHandler(ResponseHandler): + async def get_responses( + self, qctx: QueryContext + ) -> AsyncGenerator[DnsResponseSend, None]: + if qctx.qtype in (dns.rdatatype.A, dns.rdatatype.AAAA): + addr = "192.0.2.1" if qctx.qtype == dns.rdatatype.A else "2001:db8:beef::1" + rrset = dns.rrset.from_text(qctx.qname, 300, qctx.qclass, qctx.qtype, addr) + qctx.response.answer.append(rrset) + + qctx.response.set_rcode(dns.rcode.NOERROR) + delay = 0.05 if qctx.qname.labels[0].startswith(b"latency") else 0.00 + yield DnsResponseSend(qctx.response, delay=delay, authoritative=True) + + +def main() -> None: + server = ControllableAsyncDnsServer([ToggleResponsesCommand]) + server.install_response_handler(MaybeDelayedAddressAnswerHandler()) + server.run() + + +if __name__ == "__main__": + main() diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ns3/named1.conf.in bind9-9.20.15/bin/tests/system/fetchlimit/ns3/named1.conf.in --- bind9-9.20.11/bin/tests/system/fetchlimit/ns3/named1.conf.in 2025-07-04 09:42:08.156323988 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ns3/named1.conf.in 2025-10-18 10:16:12.376729398 +0000 @@ -23,12 +23,11 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; fetches-per-server 400; }; -trust-anchors { }; server 10.53.0.4 { edns no; diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ns3/named2.conf.in bind9-9.20.15/bin/tests/system/fetchlimit/ns3/named2.conf.in --- bind9-9.20.11/bin/tests/system/fetchlimit/ns3/named2.conf.in 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ns3/named2.conf.in 2025-10-18 10:16:12.376729398 +0000 @@ -21,12 +21,11 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; fetches-per-zone 40; }; -trust-anchors { }; server 10.53.0.4 { edns no; diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ns3/named3.conf.in bind9-9.20.15/bin/tests/system/fetchlimit/ns3/named3.conf.in --- bind9-9.20.11/bin/tests/system/fetchlimit/ns3/named3.conf.in 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ns3/named3.conf.in 2025-10-18 10:16:12.376729398 +0000 @@ -21,12 +21,11 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; recursive-clients 400; }; -trust-anchors { }; server 10.53.0.4 { edns no; diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ns5/named1.conf.in bind9-9.20.15/bin/tests/system/fetchlimit/ns5/named1.conf.in --- bind9-9.20.11/bin/tests/system/fetchlimit/ns5/named1.conf.in 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ns5/named1.conf.in 2025-10-18 10:16:12.377729414 +0000 @@ -21,13 +21,12 @@ listen-on { 10.53.0.5; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; clients-per-query 5; max-clients-per-query 10; }; -trust-anchors { }; server 10.53.0.4 { edns no; diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ns5/named2.conf.in bind9-9.20.15/bin/tests/system/fetchlimit/ns5/named2.conf.in --- bind9-9.20.11/bin/tests/system/fetchlimit/ns5/named2.conf.in 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ns5/named2.conf.in 2025-10-18 10:16:12.377729414 +0000 @@ -21,7 +21,7 @@ listen-on { 10.53.0.5; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; stale-answer-enable yes; stale-cache-enable yes; @@ -30,7 +30,6 @@ max-clients-per-query 10; }; -trust-anchors { }; server 10.53.0.4 { edns no; diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/ns5/named3.conf.in bind9-9.20.15/bin/tests/system/fetchlimit/ns5/named3.conf.in --- bind9-9.20.11/bin/tests/system/fetchlimit/ns5/named3.conf.in 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/ns5/named3.conf.in 2025-10-18 10:16:12.377729414 +0000 @@ -21,7 +21,7 @@ listen-on { 10.53.0.5; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; stale-answer-enable yes; stale-cache-enable yes; @@ -31,7 +31,6 @@ max-clients-per-query 5; }; -trust-anchors { }; server 10.53.0.4 { edns no; diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/tests.sh bind9-9.20.15/bin/tests/system/fetchlimit/tests.sh --- bind9-9.20.11/bin/tests/system/fetchlimit/tests.sh 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/tests.sh 2025-10-18 10:16:12.377729414 +0000 @@ -21,6 +21,17 @@ "$RNDC" -c ../_common/rndc.conf -p "${CONTROLPORT}" -s "$@" ) +dig_with_opts() ( + "$DIG" -p "$PORT" "$@" +) + +sendcmd() ( + SERVER="${1}" + COMMAND="${2}" + COMMAND_ARGS="${3}" + dig_with_opts "@${SERVER}" "${COMMAND_ARGS}.${COMMAND}._control." TXT +time=5 +tries=1 +tcp >/dev/null 2>&1 +) + burst() { server=${1} num=${4:-20} @@ -66,7 +77,7 @@ ret=0 # make the server lame and restart rndccmd 10.53.0.3 flush -touch ans4/norespond +sendcmd 10.53.0.4 send-responses "disable" for try in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do burst 10.53.0.3 a $try # fetches-per-server is at 400, but at 20qps against a lame server, @@ -111,7 +122,7 @@ n=$((n + 1)) echo_i "checking lame server recovery ($n)" ret=0 -test -f ans4/norespond && rm -f ans4/norespond +sendcmd 10.53.0.4 send-responses "enable" for try in 1 2 3 4 5; do burst 10.53.0.3 b $try stat 10.53.0.3 0 200 || ret=1 @@ -163,7 +174,7 @@ ret=0 fail=0 success=0 -touch ans4/norespond +sendcmd 10.53.0.4 send-responses "disable" for try in 1 2 3 4 5; do burst 10.53.0.3 d $try 300 $DIGCMD a ${try}.example >dig.out.ns3.$n.$try @@ -207,7 +218,7 @@ fail=0 exceeded=0 success=0 -touch ans4/norespond +sendcmd 10.53.0.4 send-responses "disable" for try in 1 2 3 4 5; do burst 10.53.0.3 b $try 400 $DIGCMD +time=2 a ${try}.example >dig.out.ns3.$n.$try @@ -253,7 +264,7 @@ n=$((n + 1)) echo_i "checking clients are dropped at the clients-per-query limit ($n)" ret=0 -test -f ans4/norespond && rm -f ans4/norespond +sendcmd 10.53.0.4 send-responses "enable" for try in 1 2 3 4 5; do burst 10.53.0.5 latency $try 20 "dup" sleep 1 @@ -296,7 +307,7 @@ n=$((n + 1)) echo_i "checking clients are dropped at the clients-per-query limit with stale-answer-client-timeout ($n)" ret=0 -test -f ans4/norespond && rm -f ans4/norespond +sendcmd 10.53.0.4 send-responses "enable" for try in 1 2 3 4 5; do burst 10.53.0.5 latency $try 20 "dup" sleep 1 diff -Nru bind9-9.20.11/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py bind9-9.20.15/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py --- bind9-9.20.11/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/fetchlimit/tests_sh_fetchlimit.py 2025-10-18 10:16:12.377729414 +0000 @@ -22,9 +22,7 @@ ] ) -import isctest.mark - -@isctest.mark.flaky(max_runs=2) +@pytest.mark.flaky(max_runs=3) def test_fetchlimit(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad1.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad1.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad1.conf 2025-07-04 09:42:08.157324011 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad1.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +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. - */ - -plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; - filter-aaaa { none; }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad2.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad2.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad2.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad2.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +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. - */ - -plugin query "../../../plugins/.libs/filter-aaaa.so" { - /* - * While this matches the defaults, it is not a good configuration - * to have in named.conf as the two options contradict each other - * indicating a error on behalf of the operator. - * - * The default is to have filter-aaaa-on-v4 off, but if it is turned - * on then it applies to all IPv4 queries. This results in - * contradictory defaults. - */ - filter-aaaa-on-v4 no; - filter-aaaa { any; }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad3.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad3.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad3.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad3.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +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. - */ - -view myview { - plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 no; - filter-aaaa { any; }; - }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad4.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad4.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad4.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad4.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +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. - */ - -view myview { - plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; - filter-aaaa { none; }; - }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad5.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad5.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/bad5.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/bad5.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +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. - */ - -plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; - filter-aaaa { 1.0.0.0/8; }; -}; - -view myview { - match-clients { any; }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good1.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good1.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good1.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good1.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +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. - */ - -plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good2.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good2.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good2.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good2.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +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. - */ - -plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 break-dnssec; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good3.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good3.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good3.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good3.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +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. - */ - -plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 break-dnssec; - filter-aaaa { 1.0.0.0/8; }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good4.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good4.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good4.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good4.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,17 +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. - */ - -plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; - filter-aaaa { 1.0.0.0/8; }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good5.conf bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good5.conf --- bind9-9.20.11/bin/tests/system/filter-aaaa/conf/good5.conf 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/conf/good5.conf 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +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. - */ - -view myview { - plugin query "../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; - filter-aaaa { 1.0.0.0/8; }; - }; -}; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/named1.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/named1.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/named1.conf.in 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/named1.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +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. - */ - -options { - query-source address 10.53.0.1; - notify-source 10.53.0.1; - transfer-source 10.53.0.1; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.1; }; - listen-on-v6 { fd92:7065:b8e:ffff::1; }; - recursion no; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -trust-anchors { }; - -acl filterees { 10.53.0.1; }; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; - filter-aaaa { filterees; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - - -zone "." { type primary; file "root.db"; }; -zone "signed" { type primary; file "signed.db.signed"; }; -zone "unsigned" { type primary; file "unsigned.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/named2.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/named2.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/named2.conf.in 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/named2.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +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. - */ - -options { - query-source address 10.53.0.1; - notify-source 10.53.0.1; - transfer-source 10.53.0.1; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.1; }; - listen-on-v6 { fd92:7065:b8e:ffff::1; }; - recursion no; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -trust-anchors { }; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v6 yes; - filter-aaaa { fd92:7065:b8e:ffff::1; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type primary; file "root.db"; }; -zone "signed" { type primary; file "signed.db.signed"; }; -zone "unsigned" { type primary; file "unsigned.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/root.db bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/root.db --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/root.db 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/root.db 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +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. - -$TTL 120 -@ SOA ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 ) -@ NS ns.utld -ns.utld A 10.53.0.1 -ns.utld AAAA fd92:7065:b8e:ffff::1 -; - -signed NS ns.signed -ns.signed A 10.53.0.1 -ns.signed AAAA fd92:7065:b8e:ffff::1 - -unsigned NS ns.unsigned -ns.unsigned A 10.53.0.1 -ns.unsigned AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/sign.sh bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/sign.sh --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/sign.sh 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/sign.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,34 +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. - -. ../../conf.sh - -SYSTESTDIR=filter-aaaa - -zone=signed. -infile=signed.db.in -zonefile=signed.db.signed -outfile=signed.db.signed - -$KEYGEN -a $DEFAULT_ALGORITHM $zone 2>&1 >/dev/null | cat_i -$KEYGEN -f KSK -a $DEFAULT_ALGORITHM $zone 2>&1 >keygen.out | cat_i -keyname=$(cat keygen.out) -rm -f keygen.out - -keyfile_to_static_ds $keyname >trusted.conf -cp trusted.conf ../ns2/trusted.conf -cp trusted.conf ../ns3/trusted.conf -cp trusted.conf ../ns5/trusted.conf - -$SIGNER -S -o $zone -f $outfile $infile >/dev/null 2>signer.err || cat signer.err -echo_i "signed zone '$zone'" diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/signed.db.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/signed.db.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/signed.db.in 2025-07-04 09:42:08.158324035 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/signed.db.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +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. - -$TTL 120 -@ SOA ns.signed. hostmaster.ns.signed. ( 1 3600 1200 604800 60 ) -@ NS ns -@ MX 10 mx - -ns A 10.53.0.1 - AAAA fd92:7065:b8e:ffff::1 - -a-only NS 1.0.0.1 -aaaa-only AAAA 2001:db8::2 -dual A 1.0.0.3 -dual AAAA 2001:db8::3 -mx A 1.0.0.3 -mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/unsigned.db bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/unsigned.db --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns1/unsigned.db 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns1/unsigned.db 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +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. - -$TTL 120 -@ SOA ns.unsigned. hostmaster.ns.unsigned. ( 1 3600 1200 604800 60 ) -@ NS ns -@ MX 10 mx - -ns A 10.53.0.1 - AAAA fd92:7065:b8e:ffff::1 - -a-only NS 1.0.0.4 -aaaa-only AAAA 2001:db8::5 -dual A 1.0.0.6 -dual AAAA 2001:db8::6 -mx A 1.0.0.3 -mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns2/hints bind9-9.20.15/bin/tests/system/filter-aaaa/ns2/hints --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns2/hints 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns2/hints 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +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. - -$TTL 120 - -. NS ns.utld. -ns.utld. A 10.53.0.1 -ns.utld. AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns2/named1.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns2/named1.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns2/named1.conf.in 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns2/named1.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +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. - */ - -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 { fd92:7065:b8e:ffff::2; }; - recursion yes; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 yes; - filter-aaaa { 10.53.0.2; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type hint; file "hints"; }; - -include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns2/named2.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns2/named2.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns2/named2.conf.in 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns2/named2.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +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. - */ - -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 { fd92:7065:b8e:ffff::2; }; - recursion yes; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v6 yes; - filter-aaaa { fd92:7065:b8e:ffff::2; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type hint; file "hints"; }; - -include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns3/hints bind9-9.20.15/bin/tests/system/filter-aaaa/ns3/hints --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns3/hints 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns3/hints 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +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. - -$TTL 120 - -. NS ns.utld. -ns.utld. A 10.53.0.1 -ns.utld. AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns3/named1.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns3/named1.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns3/named1.conf.in 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns3/named1.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +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. - */ - -options { - query-source address 10.53.0.3; - notify-source 10.53.0.3; - transfer-source 10.53.0.3; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.3; }; - listen-on-v6 { fd92:7065:b8e:ffff::3; }; - recursion yes; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 break-dnssec; - filter-aaaa { 10.53.0.3; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type hint; file "hints"; }; - -include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns3/named2.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns3/named2.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns3/named2.conf.in 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns3/named2.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +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. - */ - -options { - query-source address 10.53.0.3; - notify-source 10.53.0.3; - transfer-source 10.53.0.3; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.3; }; - listen-on-v6 { fd92:7065:b8e:ffff::3; }; - recursion yes; - dnssec-validation yes; - notify yes; - minimal-responses no; -}; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v6 break-dnssec; - filter-aaaa { fd92:7065:b8e:ffff::3; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type hint; file "hints"; }; - -include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/named1.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/named1.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/named1.conf.in 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/named1.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +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. - */ - -options { - query-source address 10.53.0.4; - notify-source 10.53.0.4; - transfer-source 10.53.0.4; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.4; }; - listen-on-v6 { fd92:7065:b8e:ffff::4; }; - recursion no; - dnssec-validation no; - notify yes; - minimal-responses no; -}; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 break-dnssec; - filter-aaaa { 10.53.0.4; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type primary; file "root.db"; }; -zone "signed" { type primary; file "signed.db.signed"; }; -zone "unsigned" { type primary; file "unsigned.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/named2.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/named2.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/named2.conf.in 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/named2.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,44 +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. - */ - -options { - query-source address 10.53.0.4; - notify-source 10.53.0.4; - transfer-source 10.53.0.4; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.4; }; - listen-on-v6 { fd92:7065:b8e:ffff::4; }; - recursion no; - dnssec-validation no; - notify yes; - minimal-responses no; -}; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v6 break-dnssec; - filter-aaaa { fd92:7065:b8e:ffff::4; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type primary; file "root.db"; }; -zone "signed" { type primary; file "signed.db.signed"; }; -zone "unsigned" { type primary; file "unsigned.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/root.db bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/root.db --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/root.db 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/root.db 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +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. - -@ SOA ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 ) -@ NS ns.utld -ns.utld A 10.53.0.4 -ns.utld AAAA fd92:7065:b8e:ffff::4 -; - -signed NS ns.signed -ns.signed A 10.53.0.4 -ns.signed AAAA fd92:7065:b8e:ffff::4 - -unsigned NS ns.unsigned -ns.unsigned A 10.53.0.4 -ns.unsigned AAAA fd92:7065:b8e:ffff::4 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/sign.sh bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/sign.sh --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/sign.sh 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/sign.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - -. ../../conf.sh - -SYSTESTDIR=filter-aaaa - -zone=signed. -infile=signed.db.in -zonefile=signed.db.signed -outfile=signed.db.signed - -$KEYGEN -a $DEFAULT_ALGORITHM $zone 2>&1 >/dev/null | cat_i -$KEYGEN -f KSK -a $DEFAULT_ALGORITHM $zone 2>&1 >/dev/null | cat_i - -$SIGNER -S -o $zone -f $outfile $infile >/dev/null 2>signer.err || cat signer.err -echo_i "signed zone '$zone'" diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/signed.db.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/signed.db.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/signed.db.in 2025-07-04 09:42:08.159324058 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/signed.db.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +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. - -$TTL 120 -@ SOA ns.signed. hostmaster.ns.signed. ( 1 3600 1200 604800 60 ) -@ NS ns -@ MX 10 mx - -ns A 10.53.0.4 - AAAA fd92:7065:b8e:ffff::4 - -a-only NS 1.0.0.1 -aaaa-only AAAA 2001:db8::2 -dual A 1.0.0.3 -dual AAAA 2001:db8::3 -mx A 1.0.0.3 -mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/unsigned.db bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/unsigned.db --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns4/unsigned.db 2025-07-04 09:42:08.160324081 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns4/unsigned.db 1970-01-01 00:00:00.000000000 +0000 @@ -1,25 +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. - -$TTL 120 -@ SOA ns.unsigned. hostmaster.ns.unsigned. ( 1 3600 1200 604800 60 ) -@ NS ns -@ MX 10 mx - -ns A 10.53.0.4 - AAAA fd92:7065:b8e:ffff::4 - -a-only NS 1.0.0.4 -aaaa-only AAAA 2001:db8::5 -dual A 1.0.0.6 -dual AAAA 2001:db8::6 -mx A 1.0.0.3 -mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns5/hints bind9-9.20.15/bin/tests/system/filter-aaaa/ns5/hints --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns5/hints 2025-07-04 09:42:08.160324081 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns5/hints 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +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. - -$TTL 120 - -. NS ns.utld. -ns.utld. A 10.53.0.1 -ns.utld. AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/ns5/named.conf.in bind9-9.20.15/bin/tests/system/filter-aaaa/ns5/named.conf.in --- bind9-9.20.11/bin/tests/system/filter-aaaa/ns5/named.conf.in 2025-07-04 09:42:08.160324081 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/ns5/named.conf.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,49 +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. - */ - -options { - query-source address 10.53.0.5; - notify-source 10.53.0.5; - transfer-source 10.53.0.5; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.5; }; - listen-on-v6 { fd92:7065:b8e:ffff::5; }; - recursion yes; - dnssec-validation no; - notify yes; - dns64 64:ff9b::/96 { - clients { any; }; - exclude { any; }; - mapped { any; }; - }; - minimal-responses no; -}; - -plugin query "../../../../plugins/.libs/filter-aaaa.so" { - filter-aaaa-on-v4 break-dnssec; - filter-aaaa { any; }; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.5 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { type hint; file "hints"; }; - -include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/setup.sh bind9-9.20.15/bin/tests/system/filter-aaaa/setup.sh --- bind9-9.20.11/bin/tests/system/filter-aaaa/setup.sh 2025-07-04 09:42:08.160324081 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/setup.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,23 +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. - -. ../conf.sh - -copy_setports ns1/named1.conf.in ns1/named.conf -copy_setports ns2/named1.conf.in ns2/named.conf -copy_setports ns3/named1.conf.in ns3/named.conf -copy_setports ns4/named1.conf.in ns4/named.conf -copy_setports ns5/named.conf.in ns5/named.conf - -(cd ns1 && $SHELL -e sign.sh) -(cd ns4 && $SHELL -e sign.sh) diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/tests.sh bind9-9.20.15/bin/tests/system/filter-aaaa/tests.sh --- bind9-9.20.11/bin/tests/system/filter-aaaa/tests.sh 2025-07-04 09:42:08.160324081 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/tests.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,1405 +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 - -status=0 -n=0 - -rm -f dig.out.* - -DIGOPTS="+tcp +noadd +nosea +nostat +nocmd -p ${PORT}" -RNDCCMD="$RNDC -c ../_common/rndc.conf -p ${CONTROLPORT} -s" - -for conf in conf/good*.conf; do - n=$((n + 1)) - echo_i "checking that $conf is accepted ($n)" - ret=0 - $CHECKCONF "$conf" || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -done - -for conf in conf/bad*.conf; do - n=$((n + 1)) - echo_i "checking that $conf is rejected ($n)" - ret=0 - $CHECKCONF "$conf" >/dev/null && ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -done - -# -# Authoritative tests against: -# filter-aaaa-on-v4 yes; -# filter-aaaa { 10.53.0.1; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::5 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "AUTHORITY: 2," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0," dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 2," dig.out.ns1.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.2 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6 ($n)" -if testsock6 fd92:7065:b8e:ffff::1; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 - grep 2001:db8::6 dig.out.ns1.test$n >/dev/null || ret=1 - grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep AAAA dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -grep "ANSWER: 1," dig.out.ns1.test$n >/dev/null || ret=1 -grep "ADDITIONAL: 2" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -grep "AUTHORITY: 2," dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv6 ($n)" -if testsock6 fd92:7065:b8e:ffff::1; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 - grep "AUTHORITY: 1," dig.out.ns1.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -# -# Authoritative tests against: -# filter-aaaa-on-v4 break-dnssec; -# filter-aaaa { 10.53.0.4; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns4.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "AUTHORITY: 1," dig.out.ns4.test$n >/dev/null || ret=1 -grep ::5 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "AUTHORITY: 0," dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.2 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6 with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::4; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 - grep 2001:db8::6 dig.out.ns4.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep AAAA dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv6, with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::4; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -# -# Recursive tests against: -# filter-aaaa-on-v4 yes; -# filter-aaaa { 10.53.0.2; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep ::5 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.1 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6, recursive ($n)" -if testsock6 fd92:7065:b8e:ffff::2; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 - grep 2001:db8::6 dig.out.ns2.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep AAAA dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed, recursive ($n)" -ret=0 -# we need to prime the cache with addresses for the MX, since additional -# section data won't be included unless it's validated, and that doesn't -# necessarily happen otherwise. -$DIG $DIGOPTS +dnssec mx.signed @10.53.0.2 >/dev/null -$DIG $DIGOPTS +dnssec mx.signed aaaa @10.53.0.2 >/dev/null -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, recursive, over IPv6 ($n)" -if testsock6 fd92:7065:b8e:ffff::2; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -# -# Recursive tests against: -# filter-aaaa-on-v4 break-dnssec; -# filter-aaaa { 10.53.0.3; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep ::5 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b 10.53.0.1 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv6, recursive with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::3; then - ret=0 - $DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 - grep 2001:db8::6 dig.out.ns3.test$n >/dev/null || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add ns unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep AAAA dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv6, recursive with break-dnssec ($n)" -if testsock6 fd92:7065:b8e:ffff::3; then - ret=0 - $DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 - grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 - if [ $ret != 0 ]; then echo_i "failed"; fi - status=$((status + ret)) -else - echo_i "skipped." -fi - -if ! testsock6 fd92:7065:b8e:ffff::1; then - echo_i "IPv6 address not configured; skipping IPv6 query tests" - echo_i "exit status: $status" - exit $status -fi - -# Reconfiguring for IPv6 tests -echo_i "reconfiguring servers" -copy_setports ns1/named2.conf.in ns1/named.conf -rndc_reconfig ns1 10.53.0.1 -copy_setports ns2/named2.conf.in ns2/named.conf -rndc_reconfig ns2 10.53.0.2 -copy_setports ns3/named2.conf.in ns3/named.conf -rndc_reconfig ns3 10.53.0.3 -copy_setports ns4/named2.conf.in ns4/named.conf -rndc_reconfig ns4 10.53.0.4 - -# BEGIN IPv6 TESTS - -# -# Authoritative tests against: -# filter-aaaa-on-v6 yes; -# filter-aaaa { fd92:7065:b8e:ffff::1; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep ::2 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep ::5 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns1.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns1.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns1.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "status: NOERROR" dig.out.ns1.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns1.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4 ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep 2001:db8::6 dig.out.ns1.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep AAAA dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::1 >dig.out.ns1.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4 ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.1 @10.53.0.1 >dig.out.ns1.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns1.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# -# Authoritative tests against: -# filter-aaaa-on-v6 break-dnssec; -# filter-aaaa { fd92:7065:b8e:ffff::4; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep ::2 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep ::5 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns4.test$n >/dev/null || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns4.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns4.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns4.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns4.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4 with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep 2001:db8::6 dig.out.ns4.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep AAAA dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::4 @fd92:7065:b8e:ffff::4 >dig.out.ns4.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4, with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.4 @10.53.0.4 >dig.out.ns4.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns4.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# -# Recursive tests against: -# filter-aaaa-on-v6 yes; -# filter-aaaa { fd92:7065:b8e:ffff::2; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep ::5 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist, signed and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, signed, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns2.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns2.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "status: NOERROR" dig.out.ns2.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns2.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4, recursive ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep 2001:db8::6 dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep AAAA dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, signed ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::2 @fd92:7065:b8e:ffff::2 >dig.out.ns2.test$n || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns2.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4 ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.2 @10.53.0.2 >dig.out.ns2.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns2.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# -# Recursive tests against: -# filter-aaaa-on-v6 yes; -# filter-aaaa { fd92:7065:b8e:ffff::3; }; -# -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::2 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when only AAAA record exists, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep ::5 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, signed and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.signed +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that NODATA/NOERROR is returned when both AAAA and A records exist, unsigned and DO set, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "ANSWER: 0" dig.out.ns3.test$n >/dev/null || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null && ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A records exist and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::3" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned and qtype=ANY with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, signed, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.signed +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.3" dig.out.ns3.test$n >/dev/null || ret=1 -grep ::3 dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that A and not AAAA is returned when both AAAA and A records exist, unsigned, qtype=ANY and DO is set with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned +dnssec -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep "1.0.0.6" dig.out.ns3.test$n >/dev/null || ret=1 -grep "::6" dig.out.ns3.test$n >/dev/null && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that both A and AAAA are returned when both AAAA and A records exist, qtype=ANY and query source does not match acl, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS any dual.unsigned -b fd92:7065:b8e:ffff::1 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "status: NOERROR" dig.out.ns3.test$n >/dev/null || ret=1 -grep 1.0.0.6 dig.out.ns3.test$n >/dev/null || ret=1 -grep ::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is returned when both AAAA and A record exists, unsigned over IPv4, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS aaaa dual.unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep 2001:db8::6 dig.out.ns3.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=NS, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec ns unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep AAAA dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -grep "ADDITIONAL: 2" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, unsigned, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is omitted from additional section, qtype=MX, signed, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx signed -b fd92:7065:b8e:ffff::3 @fd92:7065:b8e:ffff::3 >dig.out.ns3.test$n || ret=1 -grep "flags:.*ad.*QUERY" dig.out.ns3.test$n >/dev/null || ret=1 -grep "^mx.signed.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 && ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -n=$((n + 1)) -echo_i "checking that AAAA is included in additional section, qtype=MX, unsigned, over IPv4, recursive with break-dnssec ($n)" -ret=0 -$DIG $DIGOPTS +add +dnssec mx unsigned -b 10.53.0.3 @10.53.0.3 >dig.out.ns3.test$n || ret=1 -grep "^mx.unsigned.*AAAA" dig.out.ns3.test$n >/dev/null 2>&1 || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -# We don't check for the AAAA record here as configuration in ns5 does -# not make sense. The AAAA record is wanted by filter-aaaa but discarded -# by the dns64 configuration. We just want to ensure the server stays -# running. -n=$((n + 1)) -echo_i "checking filter-aaaa with dns64 ($n)" -ret=0 -$DIG $DIGOPTS aaaa aaaa-only.unsigned @10.53.0.5 >dig.out.ns5.test$n || ret=1 -grep "status: NOERROR" dig.out.ns5.test$n >/dev/null || ret=1 -if [ $ret != 0 ]; then echo_i "failed"; fi -status=$((status + ret)) - -echo_i "exit status: $status" -[ $status -eq 0 ] || exit 1 diff -Nru bind9-9.20.11/bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py bind9-9.20.15/bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py --- bind9-9.20.11/bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py 2025-07-04 09:42:08.160324081 +0000 +++ bind9-9.20.15/bin/tests/system/filter-aaaa/tests_sh_filter_aaaa.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +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. - -import pytest - -pytestmark = pytest.mark.extra_artifacts( - [ - "dig.out.*", - "ns*/trusted.conf", - "ns1/K*", - "ns1/dsset-*", - "ns1/*.signed", - "ns1/signer.err", - "ns4/K*", - "ns4/dsset-*", - "ns4/*.signed", - "ns4/signer.err", - ] -) - - -def test_filter_aaaa(run_tests_sh): - run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/filters/common.py bind9-9.20.15/bin/tests/system/filters/common.py --- bind9-9.20.11/bin/tests/system/filters/common.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/common.py 2025-10-18 10:16:12.377729414 +0000 @@ -0,0 +1,231 @@ +# 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 dns +from dns import rdataclass, rdatatype + +import isctest + + +ARTIFACTS = [ + "conf/*.conf", + "ns*/trusted.conf", + "ns*/*.signed", + "ns*/K*", + "ns*/dsset-*", + "ns*/signer.err", +] + + +def reconfigure_servers(ftype, family, servers, templates): + for server_id in ["ns1", "ns2", "ns3", "ns4"]: + templates.render( + f"{server_id}/named.conf", {"family": family, "filtertype": ftype} + ) + servers[server_id].reconfigure(log=False) + + +def check_filtertype_only(dest, source, qname, ftype, expected, adflag): + qname = dns.name.from_text(qname) + + msg = isctest.query.create(qname, ftype) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + + if adflag: + isctest.check.adflag(res) + else: + isctest.check.noadflag(res) + a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) + aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) + if ftype == "aaaa": + assert not a_record + if expected: + assert ( + aaaa_record and aaaa_record[0].address == expected + ), f"expected AAAA {expected} in ANSWER: {res}" + else: + assert not aaaa_record + if expected: + assert ( + a_record and a_record[0].address == expected + ), f"expected A {expected} in ANSWER: {res}" + + +def check_any(dest, source, qname, expected4, expected6, do): + qname = dns.name.from_text(qname) + msg = isctest.query.create(qname, "any", dnssec=do) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + a_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.A) + if expected4: + assert ( + a_record and a_record[0].address == expected4 + ), f"expected A {expected4} in ANSWER: {res}" + else: + assert not a_record + aaaa_record = res.get_rrset(res.answer, qname, rdataclass.IN, rdatatype.AAAA) + if expected6: + assert ( + aaaa_record and aaaa_record[0].address == expected6 + ), f"expected AAAA {expected6} in ANSWER: {res}" + else: + assert not aaaa_record + + +def check_nodata(dest, source, qname, qtype, do, adflag): + msg = isctest.query.create(qname, qtype, dnssec=do) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + isctest.check.empty_answer(res) + if adflag: + isctest.check.adflag(res) + else: + isctest.check.noadflag(res) + + +def check_additional(dest, source, qname, qtype, ftype, expected, adcount): + msg = isctest.query.create(qname, qtype) + res = isctest.query.tcp(msg, dest, source=source) + isctest.check.noerror(res) + isctest.check.rr_count_eq(res.additional, adcount) + t = rdatatype.A if ftype == "a" else rdatatype.AAAA + if expected: + assert [a for a in res.additional if a.rdtype == t] + else: + assert not [a for a in res.additional if a.rdtype == t] + + +def prime_cache(addr): + isctest.log.debug("prime cache for recursive testing:") + # (when testing recursive, we need to prime the cache first with + # the MX addresses, since additional section data isn't included + # unless it's been validated.) + for name in ["mx", "ns"]: + for zone in ["signed", "unsigned"]: + for qtype in ["a", "aaaa"]: + isctest.log.debug(f"{addr}: {name}.{zone}/{qtype}") + isctest.query.tcp(isctest.query.create(f"{name}.{zone}", qtype), addr) + + +def check_filter(addr, altaddr, ftype, break_dnssec, recursive): + qtype = ftype.upper() + isctest.log.debug( + f"check that {qtype} is returned when only {qtype} record exists, signed" + ) + expected = "1.0.0.2" if ftype == "a" else "2001:db8::2" + check_filtertype_only( + addr, addr, f"{ftype}-only.signed", ftype, expected, recursive + ) + + isctest.log.debug( + f"check that {qtype} is returned when only {qtype} record exists, unsigned" + ) + expected = "1.0.0.5" if ftype == "a" else "2001:db8::5" + check_filtertype_only(addr, addr, f"{ftype}-only.unsigned", ftype, expected, False) + + isctest.log.debug( + "check that NODATA/NOERROR is returned when both AAAA and A exist, signed, DO=0" + ) + check_nodata(addr, addr, "dual.signed", ftype, False, False) + + isctest.log.debug( + "check that NODATA/NOERROR is returned when both AAAA and A exist, unsigned, DO=0" + ) + check_nodata(addr, addr, "dual.unsigned", ftype, False, False) + + isctest.log.debug( + f"check that {qtype} is returned when both AAAA and A exist, signed, DO=1, unless break-dnssec is enabled" + ) + if break_dnssec: + check_nodata(addr, addr, "dual.signed", ftype, False, False) + else: + expected = "1.0.0.3" if ftype == "a" else "2001:db8::3" + check_filtertype_only(addr, addr, "dual.signed", ftype, expected, recursive) + + isctest.log.debug( + "check that NODATA/NOERROR is returned when both AAAA and A exist, unsigned, DO=1" + ) + check_nodata(addr, addr, "dual.unsigned", ftype, recursive, False) + + isctest.log.debug( + f"check that {qtype} is returned if both AAAA and A exist and the query source doesn't match the ACL" + ) + + expected = "1.0.0.6" if ftype == "a" else "2001:db8::6" + check_filtertype_only(addr, altaddr, "dual.unsigned", ftype, expected, False) + + isctest.log.debug( + f"check that A/AAAA (and not {qtype}) is returned if both AAAA and A exist, signed, qtype=ANY, DO=0" + ) + expected4 = "1.0.0.3" if ftype == "aaaa" else None + expected6 = "2001:db8::3" if ftype == "a" else None + check_any(addr, addr, "dual.signed", expected4, expected6, False) + + isctest.log.debug( + "check that both A and AAAA are returned if both AAAA and A exist, signed, qtype=ANY, DO=1, unless break-dnssec is enabled" + ) + if break_dnssec: + if ftype == "a": + expected4 = None + else: + expected6 = None + check_any(addr, addr, "dual.signed", expected4, expected6, True) + else: + check_any(addr, addr, "dual.signed", "1.0.0.3", "2001:db8::3", True) + + expected4 = "1.0.0.6" if ftype == "aaaa" else None + expected6 = "2001:db8::6" if ftype == "a" else None + + isctest.log.debug( + f"check that A/AAAA (and not {qtype}) is returned if both AAAA and A exist, unsigned, qtype=ANY, DO=0" + ) + check_any(addr, addr, "dual.unsigned", expected4, expected6, False) + + isctest.log.debug( + f"check that A/AAAA (and not {qtype}) is returned if both AAAA and A exist, unsigned, qtype=ANY, DO=1" + ) + check_any(addr, addr, "dual.unsigned", expected4, expected6, True) + + isctest.log.debug( + "check that both A and AAAA are returned if both AAAA and A exist, signed, qtype=ANY, query source does not match ACL" + ) + check_any(addr, altaddr, "dual.unsigned", "1.0.0.6", "2001:db8::6", True) + + isctest.log.debug( + f"check that {qtype} is omitted from additional section, qtype=NS, unsigned" + ) + check_additional(addr, addr, "unsigned", "ns", ftype, False, 1) + + isctest.log.debug( + f"check that {qtype} is omitted from additional section, qtype=MX, unsigned" + ) + check_additional(addr, addr, "unsigned", "mx", ftype, False, 2) + + isctest.log.debug( + f"check that {qtype} is included in additional section, qtype=MX, signed, unless break-dnssec is enabled" + ) + if break_dnssec: + check_additional(addr, addr, "signed", "mx", ftype, False, 4) + else: + check_additional(addr, addr, "signed", "mx", ftype, True, 8) + + +def check_filter_other_family(addr, ftype): + isctest.log.debug( + "check that the filtered type is returned when both AAAA and A record exists, unsigned, over other family" + ) + check_filtertype_only(addr, addr, "dual.unsigned", ftype, None, False) + + isctest.log.debug( + "check that the filtered type is included in additional section, qtype=MX, unsigned, over other family" + ) + check_additional(addr, addr, "unsigned", "mx", ftype, True, 4) diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/bad1.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/bad1.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/bad1.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/bad1.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -0,0 +1,17 @@ +/* + * 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. + */ + +plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 yes; + filter-aaaa { none; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/bad2.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/bad2.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/bad2.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/bad2.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -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. + */ + +plugin query "../../../plugins/.libs/filter-aaaa.so" { + /* + * While this matches the defaults, it is not a good configuration + * to have in named.conf as the two options contradict each other + * indicating a error on behalf of the operator. + * + * The default is to have filter-aaaa-on-v4 off, but if it is turned + * on then it applies to all IPv4 queries. This results in + * contradictory defaults. + */ + filter-aaaa-on-v4 no; + filter-aaaa { any; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/bad3.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/bad3.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/bad3.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/bad3.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -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. + */ + +view myview { + plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 no; + filter-aaaa { any; }; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/bad4.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/bad4.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/bad4.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/bad4.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -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. + */ + +view myview { + plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 yes; + filter-aaaa { none; }; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/bad5.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/bad5.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/bad5.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/bad5.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -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. + */ + +plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 yes; + filter-aaaa { 1.0.0.0/8; }; +}; + +view myview { + match-clients { any; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/good1.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/good1.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/good1.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/good1.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -0,0 +1,16 @@ +/* + * 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. + */ + +plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 yes; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/good2.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/good2.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/good2.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/good2.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -0,0 +1,16 @@ +/* + * 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. + */ + +plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 break-dnssec; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/good3.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/good3.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/good3.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/good3.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -0,0 +1,17 @@ +/* + * 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. + */ + +plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 break-dnssec; + filter-aaaa { 1.0.0.0/8; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/good4.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/good4.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/good4.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/good4.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -0,0 +1,17 @@ +/* + * 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. + */ + +plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 yes; + filter-aaaa { 1.0.0.0/8; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/conf/good5.conf.j2 bind9-9.20.15/bin/tests/system/filters/conf/good5.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/conf/good5.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/conf/good5.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -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. + */ + +view myview { + plugin query "../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 yes; + filter-aaaa { 1.0.0.0/8; }; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/filters/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/filters/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/ns1/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns1/named.conf.j2 2025-10-18 10:16:12.378729429 +0000 @@ -0,0 +1,57 @@ +/* + * 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 filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { fd92:7065:b8e:ffff::1; }; + recursion no; + dnssec-validation no; + notify yes; + minimal-responses no; +}; + +{% if family == "v6" %} + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v6 yes; + filter-@filtertype@ { fd92:7065:b8e:ffff::1; }; + }; +{% else %} + acl filterees { 10.53.0.1; }; + + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v4 yes; + filter-@filtertype@ { filterees; }; + }; +{% endif %} + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + + +zone "." { type primary; file "root.db"; }; +zone "signed" { type primary; file "signed.db.signed"; }; +zone "unsigned" { type primary; file "unsigned.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/filters/ns1/root.db bind9-9.20.15/bin/tests/system/filters/ns1/root.db --- bind9-9.20.11/bin/tests/system/filters/ns1/root.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns1/root.db 2025-10-18 10:16:12.378729429 +0000 @@ -0,0 +1,25 @@ +; 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 120 +@ SOA ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 ) +@ NS ns.utld +ns.utld A 10.53.0.1 +ns.utld AAAA fd92:7065:b8e:ffff::1 +; + +signed NS ns.signed +ns.signed A 10.53.0.1 +ns.signed AAAA fd92:7065:b8e:ffff::1 + +unsigned NS ns.unsigned +ns.unsigned A 10.53.0.1 +ns.unsigned AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns1/sign.sh bind9-9.20.15/bin/tests/system/filters/ns1/sign.sh --- bind9-9.20.11/bin/tests/system/filters/ns1/sign.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns1/sign.sh 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,34 @@ +#!/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. + +. ../../conf.sh + +SYSTESTDIR=filter-aaaa + +zone=signed. +infile=signed.db.in +zonefile=signed.db.signed +outfile=signed.db.signed + +$KEYGEN -a $DEFAULT_ALGORITHM $zone 2>&1 >/dev/null | cat_i +$KEYGEN -f KSK -a $DEFAULT_ALGORITHM $zone 2>&1 >keygen.out | cat_i +keyname=$(cat keygen.out) +rm -f keygen.out + +keyfile_to_static_ds $keyname >trusted.conf +cp trusted.conf ../ns2/trusted.conf +cp trusted.conf ../ns3/trusted.conf +cp trusted.conf ../ns5/trusted.conf + +$SIGNER -S -o $zone -f $outfile $infile >/dev/null 2>signer.err || cat signer.err +echo_i "signed zone '$zone'" diff -Nru bind9-9.20.11/bin/tests/system/filters/ns1/signed.db.in bind9-9.20.15/bin/tests/system/filters/ns1/signed.db.in --- bind9-9.20.11/bin/tests/system/filters/ns1/signed.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns1/signed.db.in 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,25 @@ +; 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 120 +@ SOA ns.signed. hostmaster.ns.signed. ( 1 3600 1200 604800 60 ) +@ NS ns +@ MX 10 mx + +ns A 10.53.0.1 + AAAA fd92:7065:b8e:ffff::1 + +a-only A 1.0.0.2 +aaaa-only AAAA 2001:db8::2 +dual A 1.0.0.3 +dual AAAA 2001:db8::3 +mx A 1.0.0.3 +mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns1/unsigned.db bind9-9.20.15/bin/tests/system/filters/ns1/unsigned.db --- bind9-9.20.11/bin/tests/system/filters/ns1/unsigned.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns1/unsigned.db 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,25 @@ +; 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 120 +@ SOA ns.unsigned. hostmaster.ns.unsigned. ( 1 3600 1200 604800 60 ) +@ NS ns +@ MX 10 mx + +ns A 10.53.0.1 + AAAA fd92:7065:b8e:ffff::1 + +a-only A 1.0.0.5 +aaaa-only AAAA 2001:db8::5 +dual A 1.0.0.6 +dual AAAA 2001:db8::6 +mx A 1.0.0.3 +mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns2/hints bind9-9.20.15/bin/tests/system/filters/ns2/hints --- bind9-9.20.11/bin/tests/system/filters/ns2/hints 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns2/hints 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,16 @@ +; 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 120 + +. NS ns.utld. +ns.utld. A 10.53.0.1 +ns.utld. AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/filters/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/ns2/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns2/named.conf.j2 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,55 @@ +/* + * 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 filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + +options { + query-source address 10.53.0.2; + query-source-v6 address fd92:7065:b8e:ffff::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 { fd92:7065:b8e:ffff::2; }; + recursion yes; + dnssec-validation yes; + notify yes; + minimal-responses no; +}; + +{% if family == "v6" %} + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v6 yes; + filter-@filtertype@ { fd92:7065:b8e:ffff::2; }; + }; +{% else %} + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v4 yes; + filter-@filtertype@{ 10.53.0.2; }; + }; +{% endif %} + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filters/ns3/hints bind9-9.20.15/bin/tests/system/filters/ns3/hints --- bind9-9.20.11/bin/tests/system/filters/ns3/hints 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns3/hints 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,16 @@ +; 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 120 + +. NS ns.utld. +ns.utld. A 10.53.0.1 +ns.utld. AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/filters/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns3/named.conf.j2 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,55 @@ +/* + * 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 filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + +options { + query-source address 10.53.0.3; + query-source-v6 address fd92:7065:b8e:ffff::3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { fd92:7065:b8e:ffff::3; }; + recursion yes; + dnssec-validation yes; + notify yes; + minimal-responses no; +}; + +{% if family == "v6" %} + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v6 break-dnssec; + filter-@filtertype@ { fd92:7065:b8e:ffff::3; }; + }; +{% else %} + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v4 break-dnssec; + filter-@filtertype@ { 10.53.0.3; }; + }; +{% endif %} + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filters/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/filters/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/ns4/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns4/named.conf.j2 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,54 @@ +/* + * 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 filtertype = filtertype | default("aaaa") %} +{% set family = family | default("v4") %} + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { fd92:7065:b8e:ffff::4; }; + recursion no; + dnssec-validation no; + notify yes; + minimal-responses no; +}; + +{% if family == "v6" %} + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v6 break-dnssec; + filter-@filtertype@ { fd92:7065:b8e:ffff::4; }; + }; +{% else %} + plugin query "../../../../plugins/.libs/filter-@filtertype@.so" { + filter-@filtertype@-on-v4 break-dnssec; + filter-@filtertype@ { 10.53.0.4; }; + }; +{% endif %} + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { type primary; file "root.db"; }; +zone "signed" { type primary; file "signed.db.signed"; }; +zone "unsigned" { type primary; file "unsigned.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/filters/ns4/root.db bind9-9.20.15/bin/tests/system/filters/ns4/root.db --- bind9-9.20.11/bin/tests/system/filters/ns4/root.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns4/root.db 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,24 @@ +; 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. + +@ SOA ns.utld hostmaster.ns.utld ( 1 3600 1200 604800 60 ) +@ NS ns.utld +ns.utld A 10.53.0.4 +ns.utld AAAA fd92:7065:b8e:ffff::4 +; + +signed NS ns.signed +ns.signed A 10.53.0.4 +ns.signed AAAA fd92:7065:b8e:ffff::4 + +unsigned NS ns.unsigned +ns.unsigned A 10.53.0.4 +ns.unsigned AAAA fd92:7065:b8e:ffff::4 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns4/sign.sh bind9-9.20.15/bin/tests/system/filters/ns4/sign.sh --- bind9-9.20.11/bin/tests/system/filters/ns4/sign.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns4/sign.sh 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,27 @@ +#!/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. + +. ../../conf.sh + +SYSTESTDIR=filter-aaaa + +zone=signed. +infile=signed.db.in +zonefile=signed.db.signed +outfile=signed.db.signed + +$KEYGEN -a $DEFAULT_ALGORITHM $zone 2>&1 >/dev/null | cat_i +$KEYGEN -f KSK -a $DEFAULT_ALGORITHM $zone 2>&1 >/dev/null | cat_i + +$SIGNER -S -o $zone -f $outfile $infile >/dev/null 2>signer.err || cat signer.err +echo_i "signed zone '$zone'" diff -Nru bind9-9.20.11/bin/tests/system/filters/ns4/signed.db.in bind9-9.20.15/bin/tests/system/filters/ns4/signed.db.in --- bind9-9.20.11/bin/tests/system/filters/ns4/signed.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns4/signed.db.in 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,25 @@ +; 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 120 +@ SOA ns.signed. hostmaster.ns.signed. ( 1 3600 1200 604800 60 ) +@ NS ns +@ MX 10 mx + +ns A 10.53.0.4 + AAAA fd92:7065:b8e:ffff::4 + +a-only A 1.0.0.2 +aaaa-only AAAA 2001:db8::2 +dual A 1.0.0.3 +dual AAAA 2001:db8::3 +mx A 1.0.0.3 +mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns4/unsigned.db bind9-9.20.15/bin/tests/system/filters/ns4/unsigned.db --- bind9-9.20.11/bin/tests/system/filters/ns4/unsigned.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns4/unsigned.db 2025-10-18 10:16:12.379729445 +0000 @@ -0,0 +1,25 @@ +; 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 120 +@ SOA ns.unsigned. hostmaster.ns.unsigned. ( 1 3600 1200 604800 60 ) +@ NS ns +@ MX 10 mx + +ns A 10.53.0.4 + AAAA fd92:7065:b8e:ffff::4 + +a-only A 1.0.0.5 +aaaa-only AAAA 2001:db8::5 +dual A 1.0.0.6 +dual AAAA 2001:db8::6 +mx A 1.0.0.3 +mx AAAA 2001:db8::3 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns5/hints bind9-9.20.15/bin/tests/system/filters/ns5/hints --- bind9-9.20.11/bin/tests/system/filters/ns5/hints 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns5/hints 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,16 @@ +; 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 120 + +. NS ns.utld. +ns.utld. A 10.53.0.1 +ns.utld. AAAA fd92:7065:b8e:ffff::1 diff -Nru bind9-9.20.11/bin/tests/system/filters/ns5/named.conf.j2 bind9-9.20.15/bin/tests/system/filters/ns5/named.conf.j2 --- bind9-9.20.11/bin/tests/system/filters/ns5/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/ns5/named.conf.j2 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,49 @@ +/* + * 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 { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on-v6 { fd92:7065:b8e:ffff::5; }; + recursion yes; + dnssec-validation no; + notify yes; + dns64 64:ff9b::/96 { + clients { any; }; + exclude { any; }; + mapped { any; }; + }; + minimal-responses no; +}; + +plugin query "../../../../plugins/.libs/filter-aaaa.so" { + filter-aaaa-on-v4 break-dnssec; + filter-aaaa { any; }; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.5 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { type hint; file "hints"; }; + +include "trusted.conf"; diff -Nru bind9-9.20.11/bin/tests/system/filters/setup.sh bind9-9.20.15/bin/tests/system/filters/setup.sh --- bind9-9.20.11/bin/tests/system/filters/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/setup.sh 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,17 @@ +#!/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. + +. ../conf.sh + +(cd ns1 && $SHELL -e sign.sh) +(cd ns4 && $SHELL -e sign.sh) diff -Nru bind9-9.20.11/bin/tests/system/filters/tests_filter_a_v4.py bind9-9.20.15/bin/tests/system/filters/tests_filter_a_v4.py --- bind9-9.20.11/bin/tests/system/filters/tests_filter_a_v4.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/tests_filter_a_v4.py 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,60 @@ +# 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 pytest + +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter A on V4") + reconfigure_servers("a", "v4", servers, templates) + prime_cache("10.53.0.2") + prime_cache("10.53.0.3") + + +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param("10.53.0.1", "10.53.0.2", False, False, id="auth"), + pytest.param("10.53.0.4", "10.53.0.2", True, False, id="auth-break-dnssec"), + pytest.param("10.53.0.2", "10.53.0.1", False, True, id="recurs"), + pytest.param("10.53.0.3", "10.53.0.1", True, True, id="recurs-break-dnssec"), + ], +) +def test_filter_a_on_v4(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "a", break_dnssec, recursive) + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr", + [ + pytest.param("fd92:7065:b8e:ffff::1", id="auth"), + pytest.param("fd92:7065:b8e:ffff::4", id="auth-break-dnssec"), + pytest.param("fd92:7065:b8e:ffff::2", id="recurs"), + pytest.param("fd92:7065:b8e:ffff::3", id="recurs-break-dnssec"), + ], +) +def test_filter_a_on_v4_via_v6(addr): + check_filter_other_family(addr, "a") diff -Nru bind9-9.20.11/bin/tests/system/filters/tests_filter_a_v6.py bind9-9.20.15/bin/tests/system/filters/tests_filter_a_v6.py --- bind9-9.20.11/bin/tests/system/filters/tests_filter_a_v6.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/tests_filter_a_v6.py 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,80 @@ +# 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 pytest + +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter A on V6") + reconfigure_servers("a", "v6", servers, templates) + prime_cache("fd92:7065:b8e:ffff::2") + prime_cache("fd92:7065:b8e:ffff::3") + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param( + "fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", False, False, id="auth" + ), + pytest.param( + "fd92:7065:b8e:ffff::4", + "fd92:7065:b8e:ffff::2", + True, + False, + id="auth-break-dnssec", + ), + pytest.param( + "fd92:7065:b8e:ffff::2", + "fd92:7065:b8e:ffff::1", + False, + True, + id="recurs", + ), + pytest.param( + "fd92:7065:b8e:ffff::3", + "fd92:7065:b8e:ffff::1", + True, + True, + id="recurs-break-dnssec", + ), + ], +) +def test_filter_a_on_v6(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "a", break_dnssec, recursive) + + +@pytest.mark.parametrize( + "addr", + [ + pytest.param("10.53.0.1", id="auth"), + pytest.param("10.53.0.4", id="auth-break-dnssec"), + pytest.param("10.53.0.2", id="recurs"), + pytest.param("10.53.0.3", id="recurs-break-dnssec"), + ], +) +def test_filter_a_on_v6_via_v4(addr): + check_filter_other_family(addr, "a") diff -Nru bind9-9.20.11/bin/tests/system/filters/tests_filter_aaaa_v4.py bind9-9.20.15/bin/tests/system/filters/tests_filter_aaaa_v4.py --- bind9-9.20.11/bin/tests/system/filters/tests_filter_aaaa_v4.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/tests_filter_aaaa_v4.py 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,61 @@ +# 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 pytest + +import isctest +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter AAAA on V4") + reconfigure_servers("aaaa", "v4", servers, templates) + prime_cache("10.53.0.2") + prime_cache("10.53.0.3") + + +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param("10.53.0.1", "10.53.0.2", False, False, id="auth"), + pytest.param("10.53.0.4", "10.53.0.2", True, False, id="auth-break-dnssec"), + pytest.param("10.53.0.2", "10.53.0.1", False, True, id="recurs"), + pytest.param("10.53.0.3", "10.53.0.1", True, True, id="recurs-break-dnssec"), + ], +) +def test_filter_aaaa_on_v4(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "aaaa", break_dnssec, recursive) + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr", + [ + pytest.param("fd92:7065:b8e:ffff::1", id="auth"), + pytest.param("fd92:7065:b8e:ffff::4", id="auth-break-dnssec"), + pytest.param("fd92:7065:b8e:ffff::2", id="recurs"), + pytest.param("fd92:7065:b8e:ffff::3", id="recurs-break-dnssec"), + ], +) +def test_filter_aaaa_on_v4_via_v6(addr): + check_filter_other_family(addr, "aaaa") diff -Nru bind9-9.20.11/bin/tests/system/filters/tests_filter_aaaa_v6.py bind9-9.20.15/bin/tests/system/filters/tests_filter_aaaa_v6.py --- bind9-9.20.11/bin/tests/system/filters/tests_filter_aaaa_v6.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/tests_filter_aaaa_v6.py 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,81 @@ +# 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 pytest + +import isctest.mark + +from filters.common import ( + ARTIFACTS, + check_filter, + check_filter_other_family, + prime_cache, + reconfigure_servers, +) + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +@pytest.fixture(scope="module", autouse=True) +def setup_filters(servers, templates): + isctest.log.info("configuring server to filter AAAA on V6") + reconfigure_servers("aaaa", "v6", servers, templates) + prime_cache("fd92:7065:b8e:ffff::2") + prime_cache("fd92:7065:b8e:ffff::3") + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr, altaddr, break_dnssec, recursive", + [ + pytest.param( + "fd92:7065:b8e:ffff::1", "fd92:7065:b8e:ffff::2", False, False, id="auth" + ), + pytest.param( + "fd92:7065:b8e:ffff::4", + "fd92:7065:b8e:ffff::2", + True, + False, + id="auth-break-dnssec", + ), + pytest.param( + "fd92:7065:b8e:ffff::2", + "fd92:7065:b8e:ffff::1", + False, + True, + id="recurs", + ), + pytest.param( + "fd92:7065:b8e:ffff::3", + "fd92:7065:b8e:ffff::1", + True, + True, + id="recurs-break-dnssec", + ), + ], +) +def test_filter_aaaa_on_v6(addr, altaddr, break_dnssec, recursive): + check_filter(addr, altaddr, "aaaa", break_dnssec, recursive) + + +@isctest.mark.with_ipv6 +@pytest.mark.parametrize( + "addr", + [ + pytest.param("10.53.0.1", id="auth"), + pytest.param("10.53.0.4", id="auth-break-dnssec"), + pytest.param("10.53.0.2", id="recurs"), + pytest.param("10.53.0.3", id="recurs-break-dnssec"), + ], +) +def test_filter_aaaa_on_v6_via_v4(addr): + check_filter_other_family(addr, "aaaa") diff -Nru bind9-9.20.11/bin/tests/system/filters/tests_filter_checkconf.py bind9-9.20.15/bin/tests/system/filters/tests_filter_checkconf.py --- bind9-9.20.11/bin/tests/system/filters/tests_filter_checkconf.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/tests_filter_checkconf.py 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,32 @@ +# 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 glob +import os +import subprocess + +import pytest + +import isctest + +from filters.common import ARTIFACTS + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +# FUTURE: move this to checkconf test - it doesn't need nsX servers +def test_filters_checkconf(): + for filename in glob.glob("conf/good*.conf"): + isctest.run.cmd([os.environ["CHECKCONF"], filename]) + for filename in glob.glob("conf/bad*.conf"): + with pytest.raises(subprocess.CalledProcessError): + isctest.run.cmd([os.environ["CHECKCONF"], filename]) diff -Nru bind9-9.20.11/bin/tests/system/filters/tests_filter_dns64.py bind9-9.20.15/bin/tests/system/filters/tests_filter_dns64.py --- bind9-9.20.11/bin/tests/system/filters/tests_filter_dns64.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/filters/tests_filter_dns64.py 2025-10-18 10:16:12.380729460 +0000 @@ -0,0 +1,28 @@ +# 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 pytest + +import isctest + +from filters.common import ARTIFACTS + + +pytestmark = pytest.mark.extra_artifacts(ARTIFACTS) + + +def test_filter_dns64(): + # This configuration doesn't make sense. The AAAA is wanted by + # filter-aaaa, but discarded by the dns64 configuration. We just + # need to ensure that the server keeps running. + msg = isctest.query.create("aaaa-only.unsigned", "aaaa") + res = isctest.query.tcp(msg, "10.53.0.5") + isctest.check.noerror(res) diff -Nru bind9-9.20.11/bin/tests/system/forward/ns3/named1.conf.in bind9-9.20.15/bin/tests/system/forward/ns3/named1.conf.in --- bind9-9.20.11/bin/tests/system/forward/ns3/named1.conf.in 2025-07-04 09:42:08.165324199 +0000 +++ bind9-9.20.15/bin/tests/system/forward/ns3/named1.conf.in 2025-10-18 10:16:12.385729538 +0000 @@ -24,10 +24,9 @@ listen-on-v6 { fd92:7065:b8e:ffff::3; }; forwarders { fd92:7065:b8e:ffff::2; }; forward first; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/forward/ns4/named.conf.in bind9-9.20.15/bin/tests/system/forward/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/forward/ns4/named.conf.in 2025-07-04 09:42:08.166324222 +0000 +++ bind9-9.20.15/bin/tests/system/forward/ns4/named.conf.in 2025-10-18 10:16:12.386729554 +0000 @@ -23,11 +23,10 @@ listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; minimal-responses yes; }; -trust-anchors { }; statistics-channels { inet 10.53.0.4 port @EXTRAPORT1@ allow { localhost; }; }; diff -Nru bind9-9.20.11/bin/tests/system/forward/ns5/named.conf.in bind9-9.20.15/bin/tests/system/forward/ns5/named.conf.in --- bind9-9.20.11/bin/tests/system/forward/ns5/named.conf.in 2025-07-04 09:42:08.166324222 +0000 +++ bind9-9.20.15/bin/tests/system/forward/ns5/named.conf.in 2025-10-18 10:16:12.386729554 +0000 @@ -22,10 +22,9 @@ forward only; forwarders { 10.53.0.4; }; deny-answer-aliases { "rebind"; }; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/forward/ns7/named.conf.in bind9-9.20.15/bin/tests/system/forward/ns7/named.conf.in --- bind9-9.20.11/bin/tests/system/forward/ns7/named.conf.in 2025-07-04 09:42:08.166324222 +0000 +++ bind9-9.20.15/bin/tests/system/forward/ns7/named.conf.in 2025-10-18 10:16:12.387729569 +0000 @@ -21,10 +21,9 @@ listen-on-v6 { none; }; forwarders { 10.53.0.4; }; forward first; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/forward/ns8/named.conf.in bind9-9.20.15/bin/tests/system/forward/ns8/named.conf.in --- bind9-9.20.11/bin/tests/system/forward/ns8/named.conf.in 2025-07-04 09:42:08.166324222 +0000 +++ bind9-9.20.15/bin/tests/system/forward/ns8/named.conf.in 2025-10-18 10:16:12.387729569 +0000 @@ -21,10 +21,9 @@ listen-on-v6 { none; }; forwarders { 10.53.0.2; }; // returns referrals forward first; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/genzone.sh bind9-9.20.15/bin/tests/system/genzone.sh --- bind9-9.20.11/bin/tests/system/genzone.sh 2025-07-04 09:42:08.168324269 +0000 +++ bind9-9.20.15/bin/tests/system/genzone.sh 2025-10-18 10:16:12.388729585 +0000 @@ -389,7 +389,16 @@ https0 HTTPS 0 example.net. https1 HTTPS 1 . port=60 -; type 66 -- 98 (unassigned) +; type 66 +dsync01 DSYNC CDS NOTIFY 53 . + +; type 67 +hhit HHIT abcd + +; type 68 +brid BRID abcd + +; type 69 -- 98 (unassigned) ; type 99 spf01 SPF "v=spf1 -all" diff -Nru bind9-9.20.11/bin/tests/system/glue/tests_glue.py bind9-9.20.15/bin/tests/system/glue/tests_glue.py --- bind9-9.20.11/bin/tests/system/glue/tests_glue.py 2025-07-04 09:42:08.172324363 +0000 +++ bind9-9.20.15/bin/tests/system/glue/tests_glue.py 2025-10-18 10:16:12.392729647 +0000 @@ -10,6 +10,7 @@ # information regarding copyright ownership. +import dns.flags import dns.message import pytest @@ -29,7 +30,7 @@ def test_glue_full_glue_set(): """test that a ccTLD referral gets a full glue set from the root zone""" - msg = dns.message.make_query("foo.bar.fi", "A") + msg = isctest.query.create("foo.bar.fi", "A") msg.flags &= ~dns.flags.RD res = isctest.query.udp(msg, "10.53.0.1") @@ -60,7 +61,7 @@ def test_glue_no_glue_set(): """test that out-of-zone glue is not found""" - msg = dns.message.make_query("example.net.", "A") + msg = isctest.query.create("example.net.", "A") msg.flags &= ~dns.flags.RD res = isctest.query.udp(msg, "10.53.0.1") diff -Nru bind9-9.20.11/bin/tests/system/hooks/driver/Makefile.in bind9-9.20.15/bin/tests/system/hooks/driver/Makefile.in --- bind9-9.20.11/bin/tests/system/hooks/driver/Makefile.in 2025-07-04 09:43:11.077808387 +0000 +++ bind9-9.20.15/bin/tests/system/hooks/driver/Makefile.in 2025-10-18 10:17:04.294498703 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -351,8 +353,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -492,15 +496,13 @@ $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} test-async.la: $(test_async_la_OBJECTS) $(test_async_la_DEPENDENCIES) $(EXTRA_test_async_la_DEPENDENCIES) $(AM_V_CCLD)$(test_async_la_LINK) $(test_async_la_OBJECTS) $(test_async_la_LIBADD) $(LIBS) @@ -515,7 +517,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -665,23 +667,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/test-async.Plo + -rm -f ./$(DEPDIR)/test-async.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -731,7 +733,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/test-async.Plo + -rm -f ./$(DEPDIR)/test-async.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -781,3 +783,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/tests/system/hooks/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/hooks/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/hooks/ns1/named.conf.j2 2025-07-04 09:42:08.172324363 +0000 +++ bind9-9.20.15/bin/tests/system/hooks/ns1/named.conf.j2 2025-10-18 10:16:12.392729647 +0000 @@ -19,12 +19,11 @@ pid-file "named.pid"; listen-on { 10.53.0.1; }; recursion no; - dnssec-validation yes; + dnssec-validation no; notify yes; minimal-responses no; }; -trust-anchors { }; plugin query "../driver/.libs/test-async.so"; diff -Nru bind9-9.20.11/bin/tests/system/hooks/tests_async_plugin.py bind9-9.20.15/bin/tests/system/hooks/tests_async_plugin.py --- bind9-9.20.11/bin/tests/system/hooks/tests_async_plugin.py 2025-07-04 09:42:08.172324363 +0000 +++ bind9-9.20.15/bin/tests/system/hooks/tests_async_plugin.py 2025-10-18 10:16:12.392729647 +0000 @@ -9,15 +9,11 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -import pytest import isctest -pytest.importorskip("dns") -import dns.message - def test_async_hook(): - msg = dns.message.make_query("example.com.", "A") + msg = isctest.query.create("example.com.", "A") res = isctest.query.udp(msg, "10.53.0.1") # the test-async plugin changes the status of any positive answer to NOTIMP isctest.check.notimp(res) diff -Nru bind9-9.20.11/bin/tests/system/ifconfig.sh.in bind9-9.20.15/bin/tests/system/ifconfig.sh.in --- bind9-9.20.11/bin/tests/system/ifconfig.sh.in 2025-07-04 09:42:08.173324386 +0000 +++ bind9-9.20.15/bin/tests/system/ifconfig.sh.in 2025-10-18 10:16:12.394729678 +0000 @@ -86,7 +86,7 @@ [ "$aaaa" ] && ip address add $aaaa/64 dev lo ip link set dev lo:$int mtu 1500 else - ifconfig lo:$int $a up netmask 255.255.255.0 mtu 1500 + [ "$a" ] && ifconfig lo:$int $a up netmask 255.255.255.0 mtu 1500 [ "$aaaa" ] && ifconfig lo inet6 add $aaaa/64 fi ;; diff -Nru bind9-9.20.11/bin/tests/system/include-multiplecfg/tests_include_multiplecfg.py bind9-9.20.15/bin/tests/system/include-multiplecfg/tests_include_multiplecfg.py --- bind9-9.20.11/bin/tests/system/include-multiplecfg/tests_include_multiplecfg.py 2025-07-04 09:42:08.174324409 +0000 +++ bind9-9.20.15/bin/tests/system/include-multiplecfg/tests_include_multiplecfg.py 2025-10-18 10:16:12.394729678 +0000 @@ -11,10 +11,10 @@ import os -import isctest +import dns.rrset import pytest -import dns.message +import isctest @pytest.mark.parametrize( @@ -26,7 +26,7 @@ ], ) def test_include_multiplecfg(qname): - msg = dns.message.make_query(qname, "A") + msg = isctest.query.create(qname, "A") res = isctest.query.tcp(msg, "10.53.0.2") isctest.check.noerror(res) diff -Nru bind9-9.20.11/bin/tests/system/isctest/__init__.py bind9-9.20.15/bin/tests/system/isctest/__init__.py --- bind9-9.20.11/bin/tests/system/isctest/__init__.py 2025-07-04 09:42:08.177324480 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/__init__.py 2025-10-18 10:16:12.398729740 +0000 @@ -13,7 +13,6 @@ from . import instance from . import query from . import kasp -from . import name from . import rndc from . import run from . import template diff -Nru bind9-9.20.11/bin/tests/system/isctest/asyncserver.py bind9-9.20.15/bin/tests/system/isctest/asyncserver.py --- bind9-9.20.11/bin/tests/system/isctest/asyncserver.py 2025-07-04 09:42:08.178324503 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/asyncserver.py 2025-10-18 10:16:12.398729740 +0000 @@ -28,6 +28,7 @@ import abc import asyncio +import contextlib import enum import functools import logging @@ -46,6 +47,8 @@ import dns.rdataclass import dns.rdatatype import dns.rrset +import dns.tsig +import dns.version import dns.zone try: @@ -370,6 +373,118 @@ return None +class _ConnectionTeardownRequested(Exception): + pass + + +@dataclass +class ResponseDropAndCloseConnection(ResponseAction): + """ + Action which makes the server close the connection after the DNS query is + received by the server (TCP only). + + The connection may be closed with a delay if requested. + """ + + delay: float = 0.0 + + async def perform(self) -> Optional[Union[dns.message.Message, bytes]]: + if self.delay > 0: + logging.info("Waiting %.1fs before closing TCP connection", self.delay) + await asyncio.sleep(self.delay) + raise _ConnectionTeardownRequested + + +class ConnectionHandler(abc.ABC): + """ + Base class for TCP connection handlers. + + An installed connection handler is called when a new TCP connection is + established. It may be used to perform arbitrary actions before + AsyncDnsServer processes DNS queries. + """ + + @abc.abstractmethod + async def handle( + self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, peer: Peer + ) -> None: + """ + Handle the connection with the provided reader and writer. + """ + raise NotImplementedError + + +@dataclass +class ConnectionReset(ConnectionHandler): + """ + A connection handler that makes the server close the connection without + reading anything from the client socket. + + The connection may be closed with a delay if requested. + + The sole purpose of this handler is to trigger a connection reset, i.e. to + make the server send an RST segment; this happens when the server closes a + client's socket while there is still unread data in that socket's buffer. + If closing the connection _after_ the query is read by the server is enough + for a given use case, the ResponseDropAndCloseConnection response handler + should be used instead. + """ + + delay: float = 0.0 + + async def handle( + self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, peer: Peer + ) -> None: + try: + # Python >= 3.7 + loop = asyncio.get_running_loop() + except AttributeError: + # Python < 3.7 + loop = asyncio.get_event_loop() + + logging.info("Blocking reads from %s", peer) + + # This is MichaÅ‚'s submission for the Ugliest Hack of the Year contest. + # (The alternative was implementing an asyncio transport from scratch.) + # + # In order to prevent the client socket from being read from, simply + # not calling `reader.read()` is not enough, because asyncio buffers + # incoming data itself on the transport level. However, `StreamReader` + # does not expose the underlying transport as a property. Therefore, + # cheat by extracting it from `StreamWriter` as it is the same + # bidirectional transport as for the read side (a `Transport`, which is + # a subclass of both `ReadTransport` and `WriteTransport`) and call + # `ReadTransport.pause_reading()` to remove the underlying socket from + # the set of descriptors monitored by the selector, thereby preventing + # any reads from happening on the client socket. However... + loop.call_soon(writer.transport.pause_reading) # type: ignore + + # ...due to `AsyncDnsServer._handle_tcp()` being a coroutine, by the + # time it gets executed, asyncio transport code will already have added + # the client socket to the set of descriptors monitored by the + # selector. Therefore, if the client starts sending data immediately, + # a read from the socket will have already been scheduled by the time + # this handler gets executed. There is no way to prevent that from + # happening, so work around it by abusing the fact that the transport + # at hand is specifically an instance of `_SelectorSocketTransport` + # (from asyncio.selector_events) and set the size of its read buffer to + # just a single byte. This does give asyncio enough time to read that + # single byte from the client socket's buffer before that socket is + # removed from the set of monitored descriptors, but prevents the + # one-off read from emptying the client socket buffer _entirely_, which + # is enough to trigger sending an RST segment when the connection is + # closed shortly afterwards. + writer.transport.max_size = 1 # type: ignore + + if self.delay > 0: + logging.info( + "Waiting %.1fs before closing TCP connection from %s", self.delay, peer + ) + await asyncio.sleep(self.delay) + + raise _ConnectionTeardownRequested + + class ResponseHandler(abc.ABC): """ Base class for generic response handlers. @@ -517,6 +632,67 @@ return node.zone if node != self._root else None +class _DnsMessageWithTsigDisabled(dns.message.Message): + """ + A wrapper for `dns.message.Message` that works around a dnspython bug + causing exceptions to be raised when `make_response()` or `to_wire()` are + called for a message created using `dns.message.from_wire(keyring=False)`. + + See https://github.com/rthalley/dnspython/issues/1205 for more details. + """ + + class _DisableTsigHandling(contextlib.ContextDecorator): + def __init__(self, message: Optional[dns.message.Message] = None) -> None: + self.original_tsig_sign = dns.tsig.sign + self.original_tsig_validate = dns.tsig.validate + if message: + self.tsig = message.tsig + + def __enter__(self) -> None: + """ + Override the `dns.tsig.sign` and `dns.tsig.validate` functions to prevent them + from failing on messages initialized with `dns.message.from_wire(keyring=False)`. + """ + + def sign(*_: Any, **__: Any) -> Tuple[dns.rdata.Rdata, None]: + assert self.tsig + return self.tsig[0], None + + def validate(*_: Any, **__: Any) -> None: + return None + + dns.tsig.sign = sign + dns.tsig.validate = validate + + def __exit__(self, *_: Any, **__: Any) -> None: + dns.tsig.sign = self.original_tsig_sign + dns.tsig.validate = self.original_tsig_validate + + @classmethod + def from_wire(cls, wire: bytes) -> "_DnsMessageWithTsigDisabled": + with cls._DisableTsigHandling(): + message = dns.message.from_wire(wire, keyring=False) + message.__class__ = _DnsMessageWithTsigDisabled + + return cast(_DnsMessageWithTsigDisabled, message) + + @property + def had_tsig(self) -> bool: + """ + Override the `had_tsig()` method to always return False, to prevent + `make_response()` from crashing. + """ + return False + + def to_wire(self, *args: Any, **kwargs: Any) -> bytes: + """ + Override the `to_wire()` method to prevent it from trying to sign + the message with TSIG. + """ + with self._DisableTsigHandling(self): + return super().to_wire(*args, **kwargs) + + class AsyncDnsServer(AsyncServer): """ DNS server which responds to queries based on zone data and/or custom @@ -533,12 +709,18 @@ response from scratch, without using zone data at all. """ - def __init__(self, acknowledge_manual_dname_handling: bool = False) -> None: + def __init__( + self, + acknowledge_manual_dname_handling: bool = False, + acknowledge_tsig_dnspython_hacks: bool = False, + ) -> None: super().__init__(self._handle_udp, self._handle_tcp, "ans.pid") self._zone_tree: _ZoneTree = _ZoneTree() + self._connection_handler: Optional[ConnectionHandler] = None self._response_handlers: List[ResponseHandler] = [] self._acknowledge_manual_dname_handling = acknowledge_manual_dname_handling + self._acknowledge_tsig_dnspython_hacks = acknowledge_tsig_dnspython_hacks self._load_zones() @@ -568,6 +750,15 @@ logging.info("Uninstalling response handler: %s", handler) self._response_handlers.remove(handler) + def install_connection_handler(self, handler: ConnectionHandler) -> None: + """ + Install a connection handler that will be called when a new TCP + connection is established. + """ + if self._connection_handler: + raise RuntimeError("Only one connection handler can be installed") + self._connection_handler = handler + def _load_zones(self) -> None: for entry in os.scandir(): entry_path = pathlib.Path(entry.path) @@ -577,13 +768,36 @@ self._zone_tree.add(zone) def _load_zone(self, zone_file_path: pathlib.Path) -> dns.zone.Zone: - origin = dns.name.from_text(zone_file_path.stem) logging.info("Loading zone file %s", zone_file_path) - with open(zone_file_path, encoding="utf-8") as zone_file: - zone = dns.zone.from_file(zone_file, origin, relativize=False) + zone = self._load_zone_file(zone_file_path) self._abort_if_dname_found_unless_acknowledged(zone) return zone + def _load_zone_file(self, zone_file_path: pathlib.Path) -> dns.zone.Zone: + try: + zone = self._load_zone_file_with_origin(zone_file_path) + except dns.zone.UnknownOrigin: + zone = self._load_zone_file_without_origin(zone_file_path) + + return zone + + def _load_zone_file_with_origin( + self, zone_file_path: pathlib.Path + ) -> dns.zone.Zone: + zone = dns.zone.from_file(str(zone_file_path), origin=None, relativize=False) + if zone.origin != dns.name.root: + error = "only the root zone may use $ORIGIN in the zone file; " + error += "for every other zone, its origin is determined by " + error += "the name of the file it is loaded from" + raise ValueError(error) + return zone + + def _load_zone_file_without_origin( + self, zone_file_path: pathlib.Path + ) -> dns.zone.Zone: + origin = dns.name.from_text(zone_file_path.stem) + return dns.zone.from_file(str(zone_file_path), origin=origin, relativize=False) + def _abort_if_dname_found_unless_acknowledged(self, zone: dns.zone.Zone) -> None: if self._acknowledge_manual_dname_handling: return @@ -615,15 +829,19 @@ peer = Peer(peer_info[0], peer_info[1]) logging.debug("Accepted TCP connection from %s", peer) - while True: - try: + try: + if self._connection_handler: + await self._connection_handler.handle(reader, writer, peer) + while True: wire = await self._read_tcp_query(reader, peer) if not wire: break await self._send_tcp_response(writer, peer, wire) - except ConnectionResetError: - logging.error("TCP connection from %s reset by peer", peer) - return + except _ConnectionTeardownRequested: + pass + except ConnectionResetError: + logging.error("TCP connection from %s reset by peer", peer) + return logging.debug("Closing TCP connection from %s", peer) writer.close() @@ -778,6 +996,10 @@ """ try: query = dns.message.from_wire(wire) + except dns.message.UnknownTSIGKey: + self._abort_if_on_dnspython_version_less_than_2_0_0() + self._abort_if_tsig_signed_query_received_unless_acknowledged() + query = _DnsMessageWithTsigDisabled.from_wire(wire) except dns.exception.DNSException as exc: logging.error("Invalid query from %s (%s): %s", peer, wire.hex(), exc) return @@ -796,6 +1018,26 @@ response_length = struct.pack("!H", len(response)) yield response_length + response + def _abort_if_on_dnspython_version_less_than_2_0_0(self) -> None: + if dns.version.MAJOR < 2: + error = "Receiving TSIG signed queries requires dnspython >= 2.0.0; " + error += 'add `pytest.importorskip("dns", minversion="2.0.0")` ' + error += "to the test module to skip this test." + raise RuntimeError(error) + + def _abort_if_tsig_signed_query_received_unless_acknowledged(self) -> None: + if self._acknowledge_tsig_dnspython_hacks: + return + + error = "TSIG-signed query received; " + error += "due to a bug in dnspython, this requires some hacking around; " + error += "you may experience unexpected behavior when dealing with TSIG; " + error += "TSIG validation is disabled, so any TSIG handling must be done " + error += "manually; pass `acknowledge_tsig_dnspython_hacks=True` to the " + error += "AsyncDnsServer constructor to acknowledge this and continue." + + raise ValueError(error) + async def _prepare_responses( self, qctx: QueryContext ) -> AsyncGenerator[Optional[Union[dns.message.Message, bytes]], None]: diff -Nru bind9-9.20.11/bin/tests/system/isctest/check.py bind9-9.20.15/bin/tests/system/isctest/check.py --- bind9-9.20.11/bin/tests/system/isctest/check.py 2025-07-04 09:42:08.178324503 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/check.py 2025-10-18 10:16:12.398729740 +0000 @@ -13,8 +13,9 @@ import shutil from typing import Optional -import dns.rcode +import dns.flags import dns.message +import dns.rcode import dns.zone import isctest.log @@ -41,6 +42,55 @@ rcode(message, dns_rcode.SERVFAIL) +def adflag(message: dns.message.Message) -> None: + assert (message.flags & dns.flags.AD) != 0, str(message) + + +def noadflag(message: dns.message.Message) -> None: + assert (message.flags & dns.flags.AD) == 0, str(message) + + +def rdflag(message: dns.message.Message) -> None: + assert (message.flags & dns.flags.RD) != 0, str(message) + + +def nordflag(message: dns.message.Message) -> None: + assert (message.flags & dns.flags.RD) == 0, str(message) + + +def raflag(message: dns.message.Message) -> None: + assert (message.flags & dns.flags.RA) != 0, str(message) + + +def noraflag(message: dns.message.Message) -> None: + assert (message.flags & dns.flags.RA) == 0, str(message) + + +def section_equal(first_section: list, second_section: list) -> None: + for rrset in first_section: + assert ( + rrset in second_section + ), f"No corresponding RRset found in second section: {rrset}" + for rrset in second_section: + assert ( + rrset in first_section + ), f"No corresponding RRset found in first section: {rrset}" + + +def same_data(res1: dns.message.Message, res2: dns.message.Message): + section_equal(res1.question, res2.question) + section_equal(res1.answer, res2.answer) + section_equal(res1.authority, res2.authority) + section_equal(res1.additional, res2.additional) + assert res1.rcode() == res2.rcode() + + +def same_answer(res1: dns.message.Message, res2: dns.message.Message): + section_equal(res1.question, res2.question) + section_equal(res1.answer, res2.answer) + assert res1.rcode() == res2.rcode() + + def rrsets_equal( first_rrset: dns.rrset.RRset, second_rrset: dns.rrset.RRset, @@ -105,7 +155,7 @@ def named_alive(named_proc, resolver_ip): assert named_proc.poll() is None, "named isn't running" - msg = dns.message.make_query("version.bind", "TXT", "CH") + msg = isctest.query.create("version.bind", "TXT", "CH") isctest.query.tcp(msg, resolver_ip, expected_rcode=dns_rcode.NOERROR) @@ -125,6 +175,12 @@ assert not message.answer, str(message) +def rr_count_eq(section: list, expected: int): + # NOTE: OPT and TSIG records aren't included in the count for ADDITIONAL section + count = sum(len(rrset) for rrset in section) + assert count == expected, str(section) + + def is_response_to(response: dns.message.Message, query: dns.message.Message) -> None: single_question(response) single_question(query) diff -Nru bind9-9.20.11/bin/tests/system/isctest/hypothesis/strategies.py bind9-9.20.15/bin/tests/system/isctest/hypothesis/strategies.py --- bind9-9.20.11/bin/tests/system/isctest/hypothesis/strategies.py 2025-07-04 09:42:08.178324503 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/hypothesis/strategies.py 2025-10-18 10:16:12.399729756 +0000 @@ -11,7 +11,8 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -from typing import List +import collections.abc +from typing import List, Union from warnings import warn from hypothesis.strategies import ( @@ -22,6 +23,7 @@ just, nothing, permutations, + sampled_from, ) import dns.name @@ -37,7 +39,9 @@ draw, *, prefix: dns.name.Name = dns.name.empty, - suffix: dns.name.Name = dns.name.root, + suffix: Union[ + dns.name.Name, collections.abc.Iterable[dns.name.Name] + ] = dns.name.root, min_labels: int = 1, max_labels: int = 128, ) -> dns.name.Name: @@ -71,6 +75,14 @@ """ prefix = prefix.relativize(dns.name.root) + # Python str is iterable, but that's most probably not what user actually wanted + if isinstance(suffix, str): + raise NotImplementedError( + "ambiguous API use, convert suffix to Name or list to express intent" + ) + if isinstance(suffix, collections.abc.Iterable): + suffix = draw(sampled_from(sorted(suffix))) + assert isinstance(suffix, dns.name.Name) suffix = suffix.derelativize(dns.name.root) try: diff -Nru bind9-9.20.11/bin/tests/system/isctest/instance.py bind9-9.20.15/bin/tests/system/isctest/instance.py --- bind9-9.20.11/bin/tests/system/isctest/instance.py 2025-07-04 09:42:08.178324503 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/instance.py 2025-10-18 10:16:12.399729756 +0000 @@ -118,35 +118,28 @@ The RNDC command will be logged to `rndc.log` (along with the server's response) unless `log` is set to `False`. - >>> # Instances of the `NamedInstance` class are expected to be passed - >>> # to pytest tests as fixtures; here, some instances are created - >>> # directly (with a fake RNDC executor) so that doctest can work. - >>> import unittest.mock - >>> mock_rndc_executor = unittest.mock.Mock() - >>> ns1 = NamedInstance("ns1", rndc_executor=mock_rndc_executor) - >>> ns2 = NamedInstance("ns2", rndc_executor=mock_rndc_executor) - >>> ns3 = NamedInstance("ns3", rndc_executor=mock_rndc_executor) - >>> ns4 = NamedInstance("ns4", rndc_executor=mock_rndc_executor) - - >>> # Send the "status" command to ns1. An `RNDCException` will be - >>> # raised if the RNDC command fails. This command will be logged. - >>> response = ns1.rndc("status") - - >>> # Send the "thaw foo" command to ns2. No exception will be raised - >>> # in case the RNDC command fails. This command will be logged - >>> # (even if it fails). - >>> response = ns2.rndc("thaw foo", ignore_errors=True) - - >>> # Send the "stop" command to ns3. An `RNDCException` will be - >>> # raised if the RNDC command fails, but this command will not be - >>> # logged (the server's response will still be returned to the - >>> # caller, though). - >>> response = ns3.rndc("stop", log=False) - - >>> # Send the "halt" command to ns4 in "fire & forget mode": no - >>> # exceptions will be raised and no logging will take place (the - >>> # server's response will still be returned to the caller, though). - >>> response = ns4.rndc("stop", ignore_errors=True, log=False) + ```python + def test_foo(servers): + # Send the "status" command to ns1. An `RNDCException` will be + # raised if the RNDC command fails. This command will be logged. + response = servers["ns1"].rndc("status") + + # Send the "thaw foo" command to ns2. No exception will be raised + # in case the RNDC command fails. This command will be logged + # (even if it fails). + response = servers["ns2"].rndc("thaw foo", ignore_errors=True) + + # Send the "stop" command to ns3. An `RNDCException` will be + # raised if the RNDC command fails, but this command will not be + # logged (the server's response will still be returned to the + # caller, though). + response = servers["ns3"].rndc("stop", log=False) + + # Send the "halt" command to ns4 in "fire & forget mode": no + # exceptions will be raised and no logging will take place (the + # server's response will still be returned to the caller, though). + response = servers["ns4"].rndc("stop", ignore_errors=True, log=False) + ``` """ try: response = self._rndc_executor.call(self.ip, self.ports.rndc, command) @@ -183,27 +176,31 @@ debug(f"update of zone {zone} to server {self.ip} successful") return response - def watch_log_from_start(self) -> WatchLogFromStart: + def watch_log_from_start( + self, timeout: float = WatchLogFromStart.DEFAULT_TIMEOUT + ) -> WatchLogFromStart: """ Return an instance of the `WatchLogFromStart` context manager for this `named` instance's log file. """ - return WatchLogFromStart(self.log.path) + return WatchLogFromStart(self.log.path, timeout) - def watch_log_from_here(self) -> WatchLogFromHere: + def watch_log_from_here( + self, timeout: float = WatchLogFromHere.DEFAULT_TIMEOUT + ) -> WatchLogFromHere: """ Return an instance of the `WatchLogFromHere` context manager for this `named` instance's log file. """ - return WatchLogFromHere(self.log.path) + return WatchLogFromHere(self.log.path, timeout) - def reconfigure(self) -> None: + def reconfigure(self, **kwargs) -> None: """ Reconfigure this named `instance` and wait until reconfiguration is finished. Raise an `RNDCException` if reconfiguration fails. """ with self.watch_log_from_here() as watcher: - self.rndc("reconfig") + self.rndc("reconfig", **kwargs) watcher.wait_for_line("any newly configured zones are now loaded") def _rndc_log(self, command: str, response: str) -> None: diff -Nru bind9-9.20.11/bin/tests/system/isctest/kasp.py bind9-9.20.15/bin/tests/system/isctest/kasp.py --- bind9-9.20.11/bin/tests/system/isctest/kasp.py 2025-07-04 09:42:08.178324503 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/kasp.py 2025-10-18 10:16:12.399729756 +0000 @@ -9,6 +9,7 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. +from datetime import datetime, timedelta, timezone from functools import total_ordering import glob import os @@ -18,13 +19,13 @@ import time from typing import Dict, List, Optional, Tuple, Union -from datetime import datetime, timedelta, timezone - import dns import dns.tsig + import isctest.log import isctest.query import isctest.util +from isctest.instance import NamedInstance from isctest.vars.algorithms import Algorithm, ALL_ALGORITHMS_BY_NUM DEFAULT_TTL = 300 @@ -33,7 +34,7 @@ def _query(server, qname, qtype, tsig=None): - query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True) + query = isctest.query.create(qname, qtype) if tsig is not None: tsigkey = tsig.split(":") @@ -49,6 +50,56 @@ return response +def Ipub(config): + return ( + config["dnskey-ttl"] + + config["zone-propagation-delay"] + + config["publish-safety"] + ) + + +def IpubC(config, rollover=True): + ttl1 = config["dnskey-ttl"] + config["publish-safety"] + ttl2 = timedelta(0) + + if not rollover: + # If this is the first key, we also need to wait until the zone + # signatures are omnipresent. Use max-zone-ttl instead of + # dnskey-ttl, and no publish-safety (because we are looking at + # signatures here, not the public key). + ttl2 = config["max-zone-ttl"] + + return config["zone-propagation-delay"] + max(ttl1, ttl2) + + +def Iret(config, zsk=True, ksk=False, rollover=True, smooth=True): + sign_delay = timedelta(0) + safety_interval = timedelta(0) + if rollover: + if smooth: + sign_delay = config["signatures-validity"] - config["signatures-refresh"] + safety_interval = config["retire-safety"] + + iretKSK = timedelta(0) + if ksk: + # KSK: Double-KSK Method: Iret = DprpP + TTLds + iretKSK = ( + config["parent-propagation-delay"] + config["ds-ttl"] + safety_interval + ) + + iretZSK = timedelta(0) + if zsk: + # ZSK: Pre-Publication Method: Iret = Dsgn + Dprp + TTLsig + iretZSK = ( + sign_delay + + config["zone-propagation-delay"] + + config["max-zone-ttl"] + + safety_interval + ) + + return max(iretKSK, iretZSK) + + @total_ordering class KeyTimingMetadata: """ @@ -174,12 +225,7 @@ ipub = timedelta(0) if self.key.get_metadata("Predecessor", must_exist=False) != "undefined": - # Ipub = Dprp + TTLkey - ipub = ( - config["dnskey-ttl"] - + config["zone-propagation-delay"] - + config["publish-safety"] - ) + ipub = Ipub(config) self.timing["Active"] = self.timing["Published"] + ipub @@ -187,52 +233,28 @@ if not self.key.is_ksk(): return - ttl1 = config["dnskey-ttl"] + config["publish-safety"] - ttl2 = timedelta(0) - - if self.key.get_metadata("Predecessor", must_exist=False) == "undefined": - # If this is the first key, we also need to wait until the zone - # signatures are omnipresent. Use max-zone-ttl instead of - # dnskey-ttl, and no publish-safety (because we are looking at - # signatures here, not the public key). - ttl2 = config["max-zone-ttl"] - - # IpubC = DprpC + TTLkey - ipubc = config["zone-propagation-delay"] + max(ttl1, ttl2) + rollover = self.key.get_metadata("Predecessor", must_exist=False) != "undefined" + ipubc = IpubC(config, rollover) self.timing["PublishCDS"] = self.timing["Published"] + ipubc - if self.metadata["Lifetime"] != 0: + if "Lifetime" in self.metadata and self.metadata["Lifetime"] != 0: self.timing["DeleteCDS"] = ( self.timing["PublishCDS"] + self.metadata["Lifetime"] ) def Iret(self, config): - if self.metadata["Lifetime"] == 0: + if "Lifetime" not in self.metadata or self.metadata["Lifetime"] == 0: return - sign_delay = config["signatures-validity"] - config["signatures-refresh"] - safety_interval = config["retire-safety"] - - iretKSK = timedelta(0) - iretZSK = timedelta(0) - if self.key.is_ksk(): - # Iret = DprpP + TTLds - iretKSK = ( - config["parent-propagation-delay"] + config["ds-ttl"] + safety_interval - ) - if self.key.is_zsk(): - # Iret = Dsgn + Dprp + TTLsig - iretZSK = ( - sign_delay - + config["zone-propagation-delay"] - + config["max-zone-ttl"] - + safety_interval - ) + sigdel = self.key.get_timing("SigRemoved", must_exist=False) + smooth = sigdel is None + iret = Iret(config, zsk=self.key.is_zsk(), ksk=self.key.is_ksk(), smooth=smooth) + self.timing["Removed"] = self.timing["Retired"] + iret - self.timing["Removed"] = self.timing["Retired"] + max(iretKSK, iretZSK) - - def set_expected_keytimes(self, config, offset=None, pregenerated=False): + def set_expected_keytimes( + self, config, offset=None, pregenerated=False, migrate=False + ): if self.key is None: raise ValueError("KeyProperties must be attached to a Key") @@ -243,18 +265,24 @@ offset = self.properties["offset"] self.timing["Generated"] = self.key.get_timing("Created") - - self.timing["Published"] = self.timing["Generated"] + self.timing["Published"] = self.key.get_timing("Created") if pregenerated: self.timing["Published"] = self.key.get_timing("Publish") - self.timing["Published"] = self.timing["Published"] + offset - self.Ipub(config) + + if migrate: + self.timing["Published"] = self.key.get_timing("Publish") + if self.key.is_ksk(): + self.timing["PublishCDS"] = self.key.get_timing("SyncPublish") + self.timing["Active"] = self.key.get_timing("Activate") + else: + self.timing["Published"] = self.timing["Published"] + offset + self.Ipub(config) + self.IpubC(config) # Set Retired timing metadata if key has lifetime. - if self.metadata["Lifetime"] != 0: + if "Lifetime" in self.metadata and self.metadata["Lifetime"] != 0: self.timing["Retired"] = self.timing["Active"] + self.metadata["Lifetime"] - self.IpubC(config) self.Iret(config) # Key state change times must exist, but since we cannot reliably tell @@ -796,7 +824,13 @@ def _check_signatures( - signatures, covers, fqdn, keys, offline_ksk=False, zsk_missing=False, smooth=False + signatures, + covers, + fqdn, + keys, + offline_ksk=False, + zsk_missing=False, + smooth=False, ): numsigs = 0 zrrsig = True @@ -884,7 +918,7 @@ assert numsigs == len(signatures) -def _check_dnskeys(dnskeys, keys, cdnskey=False): +def _check_dnskeys(dnskeys, keys, cdnskey=False, manual_mode=False): now = KeyTimingMetadata.now() numkeys = 0 @@ -895,10 +929,21 @@ delete_md = f"Sync{delete_md}" for key in keys: - publish = key.get_timing(publish_md, must_exist=False) - delete = key.get_timing(delete_md, must_exist=False) - published = publish is not None and now >= publish - removed = delete is not None and delete <= now + if manual_mode: + # State transitions may be blocked, preset key timings may not + # be accurate. Use the state values to determine whether the + # CDS must be published or not. + if cdnskey: + md = key.get_metadata("DSState") + else: + md = key.get_metadata("DNSKEYState") + published = md in ["omnipresent", "rumoured"] + removed = not published + else: + publish = key.get_timing(publish_md, must_exist=False) + delete = key.get_timing(delete_md, must_exist=False) + published = publish is not None and now >= publish + removed = delete is not None and delete <= now if not published or removed: for dnskey in dnskeys: @@ -921,7 +966,7 @@ return numkeys -def check_dnskeys(rrset, ksks, zsks, cdnskey=False): +def check_dnskeys(rrset, ksks, zsks, cdnskey=False, manual_mode=False): # Check if the correct DNSKEY records are published. If the current time # is between the timing metadata 'publish' and 'delete', the key must have # a DNSKEY record published. If 'cdnskey' is True, check against CDNSKEY @@ -936,14 +981,14 @@ dnskey = f"{rr.name} {rr.ttl} {rdclass} {rdtype} {rdata}" dnskeys.append(dnskey) - numkeys += _check_dnskeys(dnskeys, ksks, cdnskey=cdnskey) + numkeys += _check_dnskeys(dnskeys, ksks, cdnskey=cdnskey, manual_mode=manual_mode) if not cdnskey: - numkeys += _check_dnskeys(dnskeys, zsks) + numkeys += _check_dnskeys(dnskeys, zsks, manual_mode=manual_mode) assert numkeys == len(dnskeys) -def check_cds(cdss, keys, alg): +def check_cds(cdss, keys, alg, manual_mode=False): # Check if the correct CDS records are published. If the current time # is between the timing metadata 'publish' and 'delete', the key must have # a CDS record published. @@ -953,10 +998,19 @@ for key in keys: assert key.is_ksk() - publish = key.get_timing("SyncPublish") - delete = key.get_timing("SyncDelete", must_exist=False) - published = now >= publish - removed = delete is not None and delete <= now + if manual_mode: + # State transitions may be blocked, preset key timings may not + # be accurate. Use the state values to determine whether the + # CDS must be published or not. + md = key.get_metadata("DSState") + published = md in ["omnipresent", "rumoured"] + removed = not published + else: + publish = key.get_timing("SyncPublish") + delete = key.get_timing("SyncDelete", must_exist=False) + published = now >= publish + removed = delete is not None and delete <= now + if not published or removed: for cds in cdss: assert not key.cds_equals(cds, alg) @@ -1036,6 +1090,7 @@ zsks, cdss=None, cds_delete=False, + manual_mode=False, offline_ksk=False, zsk_missing=False, tsig=None, @@ -1049,7 +1104,7 @@ # test dnskey query dnskeys, rrsigs = _query_rrset(server, fqdn, dns.rdatatype.DNSKEY, tsig=tsig) - check_dnskeys(dnskeys, ksks, zsks) + check_dnskeys(dnskeys, ksks, zsks, manual_mode=manual_mode) check_signatures( rrsigs, dns.rdatatype.DNSKEY, fqdn, ksks, zsks, offline_ksk=offline_ksk ) @@ -1075,7 +1130,7 @@ check_cdsdelete(cdnskeys, "0 3 0 AA==") else: if "CDNSKEY" in cdss: - check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True) + check_dnskeys(cdnskeys, ksks, zsks, cdnskey=True, manual_mode=manual_mode) else: assert len(cdnskeys) == 0 @@ -1103,7 +1158,7 @@ for alg in ["SHA-256", "SHA-384"]: if f"CDS ({alg})" in cdss: - numcds += check_cds(cdsrrs, ksks, alg) + numcds += check_cds(cdsrrs, ksks, alg, manual_mode=manual_mode) else: check_cds_prohibit(cdsrrs, ksks, alg) @@ -1141,6 +1196,100 @@ ) +def check_rollover_step(server, config, policy, step): + zone = step["zone"] + keyprops = step["keyprops"] + nextev = step.get("nextev", None) + cdss = step.get("cdss", None) + keyrelationships = step.get("keyrelationships", None) + smooth = step.get("smooth", False) + ds_swap = step.get("ds-swap", True) + cds_delete = step.get("cds-delete", False) + check_keytimes_flag = step.get("check-keytimes", True) + zone_signed = step.get("zone-signed", True) + manual_mode = step.get("manual-mode", False) + + isctest.log.info(f"check rollover step {zone}") + + if zone_signed: + check_dnssec_verify(server, zone) + + ttl = int(config["dnskey-ttl"].total_seconds()) + expected = policy_to_properties(ttl, keyprops) + keys = keydir_to_keylist(zone, server.identifier) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + check_keys(zone, keys, expected) + + for kp in expected: + key = kp.key + + # Set expected key timing metadata. + kp.set_expected_keytimes(config) + + # Set rollover relationships. + if keyrelationships is not None: + prd = keyrelationships[0] + suc = keyrelationships[1] + expected[prd].metadata["Successor"] = expected[suc].key.tag + expected[suc].metadata["Predecessor"] = expected[prd].key.tag + check_keyrelationships(keys, expected) + + # Policy changes may retire keys, set expected timing metadata. + if kp.metadata["GoalState"] == "hidden" and "Retired" not in kp.timing: + retired = kp.key.get_timing("Inactive") + kp.timing["Retired"] = retired + kp.timing["Removed"] = retired + Iret( + config, zsk=key.is_zsk(), ksk=key.is_ksk() + ) + + # Check that CDS publication/withdrawal is logged. + if "KSK" not in kp.metadata: + continue + if kp.metadata["KSK"] == "no": + continue + + if ds_swap and kp.metadata["DSState"] == "rumoured": + assert cdss is not None + for algstr in ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"]: + if algstr in cdss: + check_cdslog(server, zone, key, algstr) + else: + check_cdslog_prohibit(server, zone, key, algstr) + + # The DS can be introduced. We ignore any parent registration delay, + # so set the DS publish time to now. + server.rndc(f"dnssec -checkds -key {key.tag} published {zone}") + + if ds_swap and kp.metadata["DSState"] == "unretentive": + # The DS can be withdrawn. We ignore any parent registration + # delay, so set the DS withdraw time to now. + server.rndc(f"dnssec -checkds -key {key.tag} withdrawn {zone}") + + if check_keytimes_flag: + check_keytimes(keys, expected) + + check_dnssecstatus(server, zone, keys, policy=policy) + check_apex( + server, + zone, + ksks, + zsks, + cdss=cdss, + cds_delete=cds_delete, + manual_mode=manual_mode, + ) + check_subdomain(server, zone, ksks, zsks, smooth=smooth) + + def check_next_key_event(): + return next_key_event_equals(server, zone, nextev) + + if nextev is not None: + isctest.run.retry_with_timeout(check_next_key_event, timeout=5) + + return expected + + def verify_update_is_signed(server, fqdn, qname, qtype, rdata, ksks, zsks, tsig=None): """ Test an RRset below the apex and verify it is updated and signed correctly. @@ -1385,8 +1534,9 @@ keyprop.properties["dnskey_ttl"] = ttl keyprop.metadata["Algorithm"] = line[2] keyprop.metadata["Length"] = line[3] - keyprop.metadata["Lifetime"] = 0 - if line[1] != "unlimited": + if line[1] == "unlimited": + keyprop.metadata["Lifetime"] = 0 + elif line[1] != "-": keyprop.metadata["Lifetime"] = int(line[1]) for i in range(4, len(line)): @@ -1421,3 +1571,15 @@ proplist.append(keyprop) return proplist + + +def wait_keymgr_done(server: NamedInstance, zone: str, reconfig: bool = False) -> None: + """ + Block and wait until the keymgr is done processing zone. + """ + messages = [] + if reconfig: + messages.append("received control channel command 'reconfig'") + messages.append(f"keymgr: {zone} done") + with server.watch_log_from_start() as watcher: + watcher.wait_for_sequence(messages) diff -Nru bind9-9.20.11/bin/tests/system/isctest/log/watchlog.py bind9-9.20.15/bin/tests/system/isctest/log/watchlog.py --- bind9-9.20.11/bin/tests/system/isctest/log/watchlog.py 2025-07-04 09:42:08.179324526 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/log/watchlog.py 2025-10-18 10:16:12.399729756 +0000 @@ -9,17 +9,27 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -from typing import Iterator, Optional, TextIO, Dict, Any, Union, Pattern +from typing import Any, Iterator, List, Match, Optional, Pattern, TextIO, TypeVar, Union import abc import os +import re import time +FlexPattern = Union[str, Pattern] +T = TypeVar("T") +OneOrMore = Union[T, List[T]] + + class WatchLogException(Exception): pass +class WatchLogTimeout(WatchLogException): + pass + + class LogFile: """ Log file wrapper with a path and means to find a string in its contents. @@ -54,6 +64,94 @@ assert False, f"forbidden message appeared in log {self.path}: {msg}" +class LineReader: + """ + >>> import io + + >>> file = io.StringIO("complete line\\n") + >>> line_reader = LineReader(file) + >>> for line in line_reader.readlines(): + ... print(line.strip()) + complete line + + >>> file = io.StringIO("complete line\\nand then incomplete line") + >>> line_reader = LineReader(file) + >>> for line in line_reader.readlines(): + ... print(line.strip()) + complete line + + >>> file = io.StringIO("complete line\\nand then another complete line\\n") + >>> line_reader = LineReader(file) + >>> for line in line_reader.readlines(): + ... print(line.strip()) + complete line + and then another complete line + + >>> file = io.StringIO() + >>> line_reader = LineReader(file) + >>> for chunk in ( + ... "first line\\nsecond line\\nthi", + ... "rd ", + ... "line\\nfour", + ... "th line\\n\\nfifth line\\n" + ... ): + ... print("=== OUTER ITERATION ===") + ... pos = file.tell() + ... print(chunk, end="", file=file) + ... _ = file.seek(pos) + ... for line in line_reader.readlines(): + ... print("--- inner iteration ---") + ... print(line.strip() or "") + === OUTER ITERATION === + --- inner iteration --- + first line + --- inner iteration --- + second line + === OUTER ITERATION === + === OUTER ITERATION === + --- inner iteration --- + third line + === OUTER ITERATION === + --- inner iteration --- + fourth line + --- inner iteration --- + + --- inner iteration --- + fifth line + """ + + def __init__(self, stream: TextIO): + self._stream = stream + self._linebuf = "" + + def readline(self) -> Optional[str]: + """ + Wrapper around io.readline() function to handle unfinished lines. + + If a line ends with newline character, it's returned immediately. + If a line doesn't end with a newline character, the read contents are + buffered until the next call of this function and None is returned + instead. + """ + read = self._stream.readline() + if not read.endswith("\n"): + self._linebuf += read + return None + read = self._linebuf + read + self._linebuf = "" + return read + + def readlines(self) -> Iterator[str]: + """ + Wrapper around io.readline() which only returns finished lines. + """ + while True: + line = self.readline() + if line is None: + return + yield line + + class WatchLog(abc.ABC): """ Wait for a log message to appear in a text file. @@ -65,44 +163,95 @@ by the `NamedInstance` class (see below for recommended usage patterns). """ - def __init__(self, path: str) -> None: + DEFAULT_TIMEOUT = 10.0 + + def __init__(self, path: str, timeout: float = DEFAULT_TIMEOUT) -> None: """ `path` is the path to the log file to watch. + `timeout` is the number of seconds (float) to wait for each wait call. Every instance of this class must call one of the `wait_for_*()` - methods exactly once or else an `Exception` is thrown. + methods at least once or else an `Exception` is thrown. >>> with WatchLogFromStart("/dev/null") as watcher: ... print("Just print something without waiting for a log line") Traceback (most recent call last): ... - Exception: wait_for_*() was not called + isctest.log.watchlog.WatchLogException: wait_for_*() was not called - >>> with WatchLogFromHere("/dev/null") as watcher: - ... try: - ... watcher.wait_for_line("foo", timeout=0) - ... except TimeoutError: - ... pass - ... try: - ... watcher.wait_for_lines({"bar": 42}, timeout=0) - ... except TimeoutError: - ... pass + >>> with WatchLogFromHere("/dev/null", timeout=0.0) as watcher: + ... watcher.wait_for_line("foo") Traceback (most recent call last): ... - Exception: wait_for_*() was already called + isctest.log.watchlog.WatchLogException: timeout must be greater than 0 """ - self._fd = None # type: Optional[TextIO] + self._fd: Optional[TextIO] = None + self._reader: Optional[LineReader] = None self._path = path self._wait_function_called = False + if timeout <= 0.0: + raise WatchLogException("timeout must be greater than 0") + self._timeout = timeout + self._deadline = 0.0 - def wait_for_line(self, string: str, timeout: int = 10) -> None: + def _setup_wait(self, patterns: OneOrMore[FlexPattern]) -> List[Pattern]: + self._wait_function_called = True + self._deadline = time.monotonic() + self._timeout + return self._prepare_patterns(patterns) + + def _prepare_patterns(self, strings: OneOrMore[FlexPattern]) -> List[Pattern]: + """ + Convert a mix of string(s) and/or pattern(s) into a list of patterns. + + Any strings are converted into regular expression patterns that match + the string verbatim. + """ + patterns = [] + if not isinstance(strings, list): + strings = [strings] + for string in strings: + if isinstance(string, Pattern): + patterns.append(string) + elif isinstance(string, str): + pattern = re.compile(re.escape(string)) + patterns.append(pattern) + else: + raise WatchLogException( + "only string and re.Pattern allowed for matching" + ) + return patterns + + def _wait_for_match(self, regexes: List[Pattern]) -> Match: + if not self._reader: + raise WatchLogException( + "use WatchLog as context manager before calling wait_for_*() functions" + ) + while time.monotonic() < self._deadline: + for line in self._reader.readlines(): + for regex in regexes: + match = regex.search(line) + if match: + return match + time.sleep(0.1) + raise WatchLogTimeout( + f"Timeout reached watching {self._path} for " + f"{' | '.join([regex.pattern for regex in regexes])}" + ) + + def wait_for_line(self, patterns: OneOrMore[FlexPattern]) -> Match: """ - Block execution until a line containing the provided `string` appears - in the log file. Return `None` once the line is found or raise a - `TimeoutError` after `timeout` seconds (default: 10) if `string` does - not appear in the log file (strings and regular expressions are - supported). (Catching this exception is discouraged as it indicates - that the test code did not behave as expected.) + Block execution until any line of interest appears in the log file. + + `patterns` accepts one value or a list of values, with each value being + either a regular expression pattern, or a string which should be + matched verbatim (without interpreting it as a regular expression). + + If any of the patterns is found anywhere within a line in the log file, + return the match, allowing access to the matched line, the regex + groups, and the regex which matched. See re.Match for more. + + A `WatchLogTimeout` is raised if the function fails to find any of the + `patterns` in the allotted time. Recommended use: @@ -110,13 +259,27 @@ import isctest def test_foo(servers): + with servers["ns1"].watch_log_from_start() as watcher: + watcher.wait_for_line("all zones loaded") + + pattern = re.compile(r"next key event in ([0-9]+) seconds") with servers["ns1"].watch_log_from_here() as watcher: # ... do stuff here ... - watcher.wait_for_line("foo bar") + match = watcher.wait_for_line(pattern) + seconds = int(match.groups(1)) + + strings = [ + "freezing zone", + "thawing zone", + ] + with servers["ns1"].watch_log_from_here() as watcher: + # ... do stuff here ... + match = watcher.wait_for_line(strings) + line = match.string ``` - One of `wait_for_line()` or `wait_for_lines()` must be called exactly - once for every `WatchLogFrom*` instance. + `wait_for_line()` must be called exactly once for every `WatchLog` + instance. >>> # For `WatchLogFromStart`, `wait_for_line()` returns without >>> # raising an exception as soon as the line being looked for appears @@ -124,135 +287,205 @@ >>> # after the `with` statement is reached. >>> import tempfile >>> with tempfile.NamedTemporaryFile("w") as file: - ... print("foo", file=file, flush=True) + ... print("foo bar baz", file=file, flush=True) ... with WatchLogFromStart(file.name) as watcher: - ... retval = watcher.wait_for_line("foo", timeout=1) - >>> print(retval) - None + ... match = watcher.wait_for_line("bar") + >>> print(match.string.strip()) + foo bar baz >>> with tempfile.NamedTemporaryFile("w") as file: ... with WatchLogFromStart(file.name) as watcher: - ... print("foo", file=file, flush=True) - ... retval = watcher.wait_for_line("foo", timeout=1) - >>> print(retval) - None + ... print("foo bar baz", file=file, flush=True) + ... match = watcher.wait_for_line("bar") + >>> print(match.group(0)) + bar >>> # For `WatchLogFromHere`, `wait_for_line()` only returns without >>> # raising an exception if the string being looked for appears in >>> # the log file after the `with` statement is reached. >>> import tempfile >>> with tempfile.NamedTemporaryFile("w") as file: - ... print("foo", file=file, flush=True) - ... with WatchLogFromHere(file.name) as watcher: - ... watcher.wait_for_line("foo", timeout=1) #doctest: +ELLIPSIS + ... print("foo bar baz", file=file, flush=True) + ... with WatchLogFromHere(file.name, timeout=0.1) as watcher: + ... watcher.wait_for_line("bar") #doctest: +ELLIPSIS Traceback (most recent call last): ... - TimeoutError: Timeout reached watching ... + isctest.log.watchlog.WatchLogTimeout: ... >>> with tempfile.NamedTemporaryFile("w") as file: - ... print("foo", file=file, flush=True) + ... print("foo bar baz", file=file, flush=True) ... with WatchLogFromHere(file.name) as watcher: - ... print("foo", file=file, flush=True) - ... retval = watcher.wait_for_line("foo", timeout=1) - >>> print(retval) - None - """ - return self._wait_for({string: None}, timeout) - - def wait_for_lines( - self, strings: Dict[Union[str, Pattern], Any], timeout: int = 10 - ) -> None: - """ - Block execution until a line of interest appears in the log file. This - function is a "multi-match" variant of `wait_for_line()` which is - useful when some action may cause several different (mutually - exclusive) messages to appear in the log file. - - `strings` is a `dict` associating each string to look for with the - value this function should return when that string is found in the log - file (strings and regular expressions are supported). If none of the - `strings` being looked for appear in the log file after `timeout` - seconds, a `TimeoutError` is raised. (Catching this exception is - discouraged as it indicates that the test code did not behave as - expected.) - - Since `strings` is a `dict` and preserves key order (in CPython 3.6 as - implementation detail, since 3.7 by language design), each line is - checked against each key in order until the first match. Values provided - in the `strings` dictionary (i.e. values which this function is expected - to return upon a successful match) can be of any type. + ... print("bar qux", file=file, flush=True) + ... match = watcher.wait_for_line("bar") + >>> print(match.string.strip()) + bar qux - Recommended use: + >>> # Different values must be returned depending on which line is + >>> # found in the log file. + >>> import tempfile + >>> patterns = [re.compile(r"bar ([0-9])"), "qux"] + >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("foo bar 3", file=file, flush=True) + ... with WatchLogFromStart(file.name) as watcher: + ... match1 = watcher.wait_for_line(patterns) + ... with WatchLogFromHere(file.name) as watcher: + ... print("baz qux", file=file, flush=True) + ... match2 = watcher.wait_for_line(patterns) + >>> print(match1.group(1)) + 3 + >>> print(match2.group(0)) + qux + """ + regexes = self._setup_wait(patterns) - ```python - import isctest + return self._wait_for_match(regexes) - def test_foo(servers): - triggers = { - "message A": "value returned when message A is found", - "message B": "value returned when message B is found", - } - with servers["ns1"].watch_log_from_here() as watcher: - # ... do stuff here ... - retval = watcher.wait_for_lines(triggers) - ``` + def wait_for_sequence(self, patterns: List[FlexPattern]) -> List[Match]: + """ + Block execution until the specified pattern sequence is found in the + log file. - One of `wait_for_line()` or `wait_for_lines()` must be called exactly - once for every `WatchLogFromHere` instance. + `patterns` is a list of values, with each value being either a regular + expression pattern, or a string which should be matched verbatim + (without interpreting it as a regular expression). Order of patterns is + important, as each pattern is looked for only after all the previous + patterns have matched. + + All the matches are returned as a list. + + A `WatchLogTimeout` is raised if the function fails to find all of the + `patterns` in the given order in the allotted time. + + >>> import tempfile + >>> seq = ['a', 'b', 'c'] + >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("b", file=file, flush=True) + ... print("a", file=file, flush=True) + ... print("b", file=file, flush=True) + ... print("z", file=file, flush=True) + ... print("c", file=file, flush=True) + ... with WatchLogFromStart(file.name) as watcher: + ... ret = watcher.wait_for_sequence(seq) + >>> assert ret[0].group(0) == "a" + >>> assert ret[1].group(0) == "b" + >>> assert ret[2].group(0) == "c" + + >>> import tempfile + >>> seq = ['a', 'b', 'c'] + >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("b", file=file, flush=True) + ... print("a", file=file, flush=True) + ... print("c", file=file, flush=True) + ... with WatchLogFromStart(file.name, timeout=0.1) as watcher: + ... ret = watcher.wait_for_sequence(seq) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + isctest.log.watchlog.WatchLogTimeout: ... - >>> # Different values must be returned depending on which line is - >>> # found in the log file. >>> import tempfile - >>> triggers = {"foo": 42, "bar": 1337} + >>> seq = ['a', 'b', 'c'] >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("b", file=file, flush=True) + ... print("a", file=file, flush=True) + ... print("b", file=file, flush=True) + ... with WatchLogFromStart(file.name, timeout=0.1) as watcher: + ... ret = watcher.wait_for_sequence(seq) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + isctest.log.watchlog.WatchLogTimeout: ... + + >>> import tempfile + >>> seq = ['a', 'b', 'c'] + >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("b", file=file, flush=True) + ... print("a", file=file, flush=True) + ... print("c", file=file, flush=True) + ... print("b", file=file, flush=True) + ... with WatchLogFromStart(file.name, timeout=0.1) as watcher: + ... ret = watcher.wait_for_sequence(seq) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + isctest.log.watchlog.WatchLogTimeout: ... + """ + regexes = self._setup_wait(patterns) + matches = [] + + for regex in regexes: + match = self._wait_for_match([regex]) + matches.append(match) + + return matches + + def wait_for_all(self, patterns: List[FlexPattern]) -> List[Match]: + """ + Block execution until all the specified patterns are found in the + log file in any order. + + `patterns` is a list of values, with each value being either a regular + expression pattern, or a string which should be matched verbatim + (without interpreting it as a regular expression). Order of patterns is + irrelevant and they may appear in any order. + + All the matches are returned as a list. The matches are listed in the + order of appearance. Pattern may match more than once, and all the + matches are included. To pair matches with the patterns, re.Match.re + may be used. + + A `WatchLogTimeout` is raised if the function fails to find all of the + `patterns` in the allotted time. + + >>> import tempfile + >>> patterns = ['foo', 'bar'] + >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("bar", file=file, flush=True) ... print("foo", file=file, flush=True) ... with WatchLogFromStart(file.name) as watcher: - ... retval1 = watcher.wait_for_lines(triggers, timeout=1) - ... with WatchLogFromHere(file.name) as watcher: - ... print("bar", file=file, flush=True) - ... retval2 = watcher.wait_for_lines(triggers, timeout=1) - >>> print(retval1) - 42 - >>> print(retval2) - 1337 - """ - return self._wait_for(strings, timeout) - - def _wait_for(self, patterns: Dict[Union[str, Pattern], Any], timeout: int) -> Any: - """ - Block execution until one of the `strings` being looked for appears in - the log file. Raise a `TimeoutError` if none of the `strings` being - looked for are found in the log file for `timeout` seconds. + ... ret = watcher.wait_for_all(patterns) + >>> assert ret[0].group(0) == "bar" + >>> assert ret[1].group(0) == "foo" + + >>> import tempfile + >>> bar_pattern = re.compile('bar') + >>> patterns = ['foo', bar_pattern] + >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("bar", file=file, flush=True) + ... print("baz", file=file, flush=True) + ... print("bar", file=file, flush=True) + ... print("foo", file=file, flush=True) + ... with WatchLogFromStart(file.name) as watcher: + ... ret = watcher.wait_for_all(patterns) + >>> assert len(ret) == 3 + >>> assert ret[0].group(0) == "bar" + >>> assert ret[1].group(0) == "bar" + >>> assert ret[2].group(0) == "foo" + >>> assert ret[0].re == bar_pattern + >>> assert ret[1].re == bar_pattern + >>> assert ret[2].re.pattern == "foo" + + >>> import tempfile + >>> patterns = ['foo', 'bar'] + >>> with tempfile.NamedTemporaryFile("w") as file: + ... print("foo", file=file, flush=True) + ... print("quux", file=file, flush=True) + ... with WatchLogFromStart(file.name, timeout=0.1) as watcher: + ... ret = watcher.wait_for_all(patterns) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + isctest.log.watchlog.WatchLogTimeout: ... """ - if self._wait_function_called: - raise WatchLogException("wait_for_*() was already called") - self._wait_function_called = True - if not self._fd: - raise WatchLogException("No file to watch") - leftover = "" - assert timeout, "Do not use this class unless you want to WAIT for something." - deadline = time.monotonic() + timeout - while time.monotonic() < deadline: - for line in self._fd.readlines(): - if line[-1] != "\n": - # Line is not completely written yet, buffer and keep on waiting - leftover += line - else: - line = leftover + line - leftover = "" - for string, retval in patterns.items(): - if isinstance(string, Pattern) and string.search(line): - return retval - if isinstance(string, str) and string in line: - return retval - time.sleep(0.1) - raise TimeoutError( - "Timeout reached watching {} for {}".format( - self._path, list(patterns.keys()) - ) - ) + regexes = self._setup_wait(patterns) + unmatched_regexes = set(regexes) + matches = [] + + while unmatched_regexes: + match = self._wait_for_match(regexes) + matches.append(match) + unmatched_regexes.discard(match.re) + + return matches def __enter__(self) -> Any: self._fd = open(self._path, encoding="utf-8") self._seek_on_enter() + self._reader = LineReader(self._fd) return self @abc.abstractmethod @@ -269,8 +502,9 @@ def __exit__(self, *_: Any) -> None: if not self._wait_function_called: raise WatchLogException("wait_for_*() was not called") - if self._fd: - self._fd.close() + self._reader = None + assert self._fd + self._fd.close() class WatchLogFromStart(WatchLog): @@ -291,5 +525,5 @@ """ def _seek_on_enter(self) -> None: - if self._fd: - self._fd.seek(0, os.SEEK_END) + assert self._fd + self._fd.seek(0, os.SEEK_END) diff -Nru bind9-9.20.11/bin/tests/system/isctest/mark.py bind9-9.20.15/bin/tests/system/isctest/mark.py --- bind9-9.20.11/bin/tests/system/isctest/mark.py 2025-07-04 09:42:08.179324526 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/mark.py 2025-10-18 10:16:12.399729756 +0000 @@ -13,12 +13,13 @@ import os from pathlib import Path +import platform +import socket import shutil import subprocess import pytest - long_test = pytest.mark.skipif( not os.environ.get("CI_ENABLE_LONG_TESTS"), reason="CI_ENABLE_LONG_TESTS not set" ) @@ -30,7 +31,9 @@ def feature_test(feature): - feature_test_bin = os.environ["FEATURETEST"] + feature_test_bin = os.environ.get("FEATURETEST") + if not feature_test_bin: # this can be the case when running doctest + return False try: subprocess.run([feature_test_bin, feature], check=True) except subprocess.CalledProcessError as exc: @@ -53,8 +56,8 @@ return True -def with_tsan(*args): # pylint: disable=unused-argument - return feature_test("--tsan") +def is_host_freebsd_13(*_): + return platform.system() == "FreeBSD" and platform.release().startswith("13") def with_algorithm(name: str): @@ -99,19 +102,14 @@ reason="SOFTHSM2_CONF and SOFTHSM2_MODULE environmental variables must be set and pkcs11-tool and softhsm2-util tools present", ) -try: - import flaky as flaky_pkg # type: ignore -except ModuleNotFoundError: - # In case the flaky package is not installed, run the tests as usual - # without any attempts to re-run them. - # pylint: disable=unused-argument - def flaky(*args, **kwargs): - """Mock decorator that doesn't do anything special, just returns the function.""" - def wrapper(wrapped_obj): - return wrapped_obj +def have_ipv6(): + sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) + try: + sock.bind(("fd92:7065:b8e:ffff::1", 0)) + except OSError: + return False + return True - return wrapper -else: - flaky = flaky_pkg.flaky +with_ipv6 = pytest.mark.skipif(not have_ipv6(), reason="IPv6 not available") diff -Nru bind9-9.20.11/bin/tests/system/isctest/name.py bind9-9.20.15/bin/tests/system/isctest/name.py --- bind9-9.20.11/bin/tests/system/isctest/name.py 2025-07-04 09:42:08.179324526 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/name.py 2025-10-18 10:16:12.399729756 +0000 @@ -9,12 +9,196 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -import dns.name +from typing import Container, Iterable, FrozenSet +import pytest -def prepend_label(label: str, name: dns.name.Name) -> dns.name.Name: - return dns.name.Name((label,) + name.labels) +pytest.importorskip("dns", minversion="2.3.0") # NameRelation +from dns.name import Name, NameRelation +import dns.zone +import dns.rdatatype -def len_wire_uncompressed(name: dns.name.Name) -> int: +def prepend_label(label: str, name: Name) -> Name: + return Name((label,) + name.labels) + + +def len_wire_uncompressed(name: Name) -> int: return len(name) + sum(map(len, name.labels)) + + +def get_wildcard_names(names: Iterable[Name]) -> FrozenSet[Name]: + return frozenset(name for name in names if name.is_wild()) + + +class ZoneAnalyzer: + """ + Categorize names in zone and provide list of ENTs: + + - delegations - names with NS RR + - dnames - names with DNAME RR + - wildcards - names with leftmost label '*' + - reachable - non-empty authoritative nodes in zone + - have at least one auth RR set and are not occluded + - ents - reachable empty non-terminals + - occluded - names under a parent node which has DNAME or a non-apex NS + - reachable_delegations + - have NS RR on it, are not zone's apex, and are not occluded + - reachable_dnames - have DNAME RR on it and are not occluded + - reachable_wildcards - have leftmost label '*' and are not occluded + - reachable_wildcard_parents - reachable_wildcards with leftmost '*' stripped + + Warnings: + - Quadratic complexity ahead! Use only on small test zones. + - Zone must be constant. + """ + + @classmethod + def read_path(cls, zpath, origin): + with open(zpath, encoding="ascii") as zf: + zonedb = dns.zone.from_file(zf, origin, relativize=False) + return cls(zonedb) + + def __init__(self, zone: dns.zone.Zone): + self.zone = zone + assert self.zone.origin # mypy hack + # based on individual nodes but not relationship between nodes + self.delegations = self.get_names_with_type(dns.rdatatype.NS) - { + self.zone.origin + } + self.dnames = self.get_names_with_type(dns.rdatatype.DNAME) + self.wildcards = get_wildcard_names(self.zone) + + # takes relationship between nodes into account + self._categorize_names() + self.ents = self.generate_ents() + self.reachable_dnames = self.dnames.intersection(self.reachable) + self.reachable_wildcards = self.wildcards.intersection(self.reachable) + self.reachable_wildcard_parents = { + Name(wname[1:]) for wname in self.reachable_wildcards + } + + # (except for wildcard expansions) all names in zone which result in NOERROR answers + self.all_existing_names = ( + self.reachable.union(self.ents) + .union(self.reachable_delegations) + .union(self.reachable_dnames) + ) + + def get_names_with_type(self, rdtype) -> FrozenSet[Name]: + return frozenset( + name for name in self.zone if self.zone.get_rdataset(name, rdtype) + ) + + def _categorize_names( + self, + ) -> None: + """ + Split names defined in a zone into three sets: + Generally reachable, reachable delegations, and occluded. + + Delegations are set aside because they are a weird hybrid with different + rules for different RR types (NS, DS, NSEC, everything else). + """ + assert self.zone.origin # mypy workaround + reachable = set(self.zone) + # assume everything is reachable until proven otherwise + reachable_delegations = set(self.delegations) + occluded = set() + + def _mark_occluded(name: Name) -> None: + occluded.add(name) + if name in reachable: + reachable.remove(name) + if name in reachable_delegations: + reachable_delegations.remove(name) + + # sanity check, should be impossible with dnspython 2.7.0 zone reader + for name in reachable: + relation, _, _ = name.fullcompare(self.zone.origin) + if relation in ( + NameRelation.NONE, # out of zone? + NameRelation.SUPERDOMAIN, # parent of apex?! + ): + raise NotImplementedError + + for maybe_occluded in reachable.copy(): + for cut in self.delegations: + rel, _, _ = maybe_occluded.fullcompare(cut) + if rel == NameRelation.EQUAL: + # data _on_ a parent-side of a zone cut are in limbo: + # - are not really authoritative (except for DS) + # - but NS is not really 'occluded' + # We remove them from 'reachable' but do not add them to 'occluded' set, + # i.e. leave them in 'reachable_delegations'. + if maybe_occluded in reachable: + reachable.remove(maybe_occluded) + + if rel == NameRelation.SUBDOMAIN: + _mark_occluded(maybe_occluded) + # do not break cycle - handle also nested NS and DNAME + + # DNAME itself is authoritative but nothing under it is reachable + for dname in self.dnames: + rel, _, _ = maybe_occluded.fullcompare(dname) + if rel == NameRelation.SUBDOMAIN: + _mark_occluded(maybe_occluded) + # do not break cycle - handle also nested NS and DNAME + + self.reachable = frozenset(reachable) + self.reachable_delegations = frozenset(reachable_delegations) + self.occluded = frozenset(occluded) + + def generate_ents(self) -> FrozenSet[Name]: + """ + Generate reachable names of empty nodes "between" all reachable + names with a RR and the origin. + """ + assert self.zone.origin + all_reachable_names = self.reachable.union(self.reachable_delegations) + ents = set() + for name in all_reachable_names: + _, super_name = name.split(len(name) - 1) + while len(super_name) > len(self.zone.origin): + if super_name not in all_reachable_names: + ents.add(super_name) + _, super_name = super_name.split(len(super_name) - 1) + + return frozenset(ents) + + def closest_encloser(self, qname: Name): + """ + Get (closest encloser, next closer name) for given qname. + """ + ce = None # Closest encloser, RFC 4592 + nce = None # Next closer name, RFC 5155 + for zname in self.all_existing_names: + relation, _, common_labels = qname.fullcompare(zname) + if relation == NameRelation.SUBDOMAIN: + if not ce or common_labels > len(ce): + # longest match so far + ce = zname + _, nce = qname.split(len(ce) + 1) + assert ce is not None + assert nce is not None + return ce, nce + + def source_of_synthesis(self, qname: Name) -> Name: + """ + Return source of synthesis according to RFC 4592 section 3.3.1. + Name is not guaranteed to exist or be reachable. + """ + ce, _ = self.closest_encloser(qname) + return Name("*") + ce + + +def is_related_to_any( + test_name: Name, + acceptable_relations: Container[NameRelation], + candidates: Iterable[Name], +) -> bool: + for maybe_parent in candidates: + relation, _, _ = test_name.fullcompare(maybe_parent) + if relation in acceptable_relations: + return True + return False diff -Nru bind9-9.20.11/bin/tests/system/isctest/query.py bind9-9.20.15/bin/tests/system/isctest/query.py --- bind9-9.20.11/bin/tests/system/isctest/query.py 2025-07-04 09:42:08.179324526 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/query.py 2025-10-18 10:16:12.400729772 +0000 @@ -99,3 +99,23 @@ raise RuntimeError( "dnspython 2.5.0 or newer is required for isctest.query.tls()" ) from e + + +def create( + qname, + qtype, + qclass=dns.rdataclass.IN, + dnssec: bool = True, + cd: bool = False, + ad: bool = True, +) -> dns.message.Message: + """Create DNS query with defaults suitable for our tests.""" + msg = dns.message.make_query( + qname, qtype, qclass, use_edns=True, want_dnssec=dnssec + ) + msg.flags = dns.flags.RD + if ad: + msg.flags |= dns.flags.AD + if cd: + msg.flags |= dns.flags.CD + return msg diff -Nru bind9-9.20.11/bin/tests/system/isctest/vars/basic.py bind9-9.20.15/bin/tests/system/isctest/vars/basic.py --- bind9-9.20.11/bin/tests/system/isctest/vars/basic.py 2025-07-04 09:42:08.180324550 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/vars/basic.py 2025-10-18 10:16:12.401729787 +0000 @@ -23,6 +23,7 @@ "CHECKCONF": f"{AC_VARS['TOP_BUILDDIR']}/bin/check/named-checkconf", "CHECKZONE": f"{AC_VARS['TOP_BUILDDIR']}/bin/check/named-checkzone", "DIG": f"{AC_VARS['TOP_BUILDDIR']}/bin/dig/dig", + "DELV": f"{AC_VARS['TOP_BUILDDIR']}/bin/delv/delv", "DNSTAPREAD": f"{AC_VARS['TOP_BUILDDIR']}/bin/tools/dnstap-read", "DSFROMKEY": f"{AC_VARS['TOP_BUILDDIR']}/bin/dnssec/dnssec-dsfromkey", "FEATURETEST": f"{AC_VARS['TOP_BUILDDIR']}/bin/tests/system/feature-test", @@ -54,11 +55,6 @@ "TMPDIR": os.getenv("TMPDIR", "/tmp"), "KRB5_CONFIG": "/dev/null", # we don't want a KRB5_CONFIG setting breaking the tests "KRB5_KTNAME": "dns.keytab", # use local keytab instead of default /etc/krb5.keytab - "DELV": ( - f"{AC_VARS['TOP_BUILDDIR']}/bin/delv/delv" - if not os.getenv("TSAN_OPTIONS", "") - else ":" # workaround for GL#4119 - ), "LC_ALL": "C", "ANS_LOG_LEVEL": "debug", } diff -Nru bind9-9.20.11/bin/tests/system/isctest/vars/dirs.py bind9-9.20.15/bin/tests/system/isctest/vars/dirs.py --- bind9-9.20.11/bin/tests/system/isctest/vars/dirs.py 2025-07-04 09:42:08.180324550 +0000 +++ bind9-9.20.15/bin/tests/system/isctest/vars/dirs.py 2025-10-18 10:16:12.401729787 +0000 @@ -22,6 +22,7 @@ DIR_VARS = { "builddir": f"{AC_VARS['TOP_BUILDDIR']}/{SYSTEM_TEST_DIR_GIT_PATH}", "srcdir": f"{AC_VARS['TOP_SRCDIR']}/{SYSTEM_TEST_DIR_GIT_PATH}", + "HYPOTHESIS_STORAGE_DIRECTORY": f"{AC_VARS['TOP_BUILDDIR']}/{SYSTEM_TEST_DIR_GIT_PATH}/.hypothesis", "SYSTESTDIR": None, } diff -Nru bind9-9.20.11/bin/tests/system/kasp/ns3/named-fips.conf.in bind9-9.20.15/bin/tests/system/kasp/ns3/named-fips.conf.in --- bind9-9.20.11/bin/tests/system/kasp/ns3/named-fips.conf.in 2025-07-04 09:42:08.184324644 +0000 +++ bind9-9.20.15/bin/tests/system/kasp/ns3/named-fips.conf.in 2025-10-18 10:16:12.405729849 +0000 @@ -287,6 +287,15 @@ }; /* + * Zone that has missing key files, manual-mode. + */ +zone "keyfiles-missing.manual" { + type primary; + file "keyfiles-missing.manual.db"; + dnssec-policy "manual"; +}; + +/* * Zone that has missing private KSK. */ zone "ksk-missing.autosign" { diff -Nru bind9-9.20.11/bin/tests/system/kasp/ns3/policies/autosign.conf.in bind9-9.20.15/bin/tests/system/kasp/ns3/policies/autosign.conf.in --- bind9-9.20.11/bin/tests/system/kasp/ns3/policies/autosign.conf.in 2025-07-04 09:42:08.185324667 +0000 +++ bind9-9.20.15/bin/tests/system/kasp/ns3/policies/autosign.conf.in 2025-10-18 10:16:12.405729849 +0000 @@ -24,3 +24,19 @@ zsk key-directory lifetime P1Y algorithm @DEFAULT_ALGORITHM@; }; }; + +dnssec-policy "manual" { + + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 300; + + keys { + ksk key-directory lifetime P2Y algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime P2M algorithm @DEFAULT_ALGORITHM@; + }; + + manual-mode yes; +}; diff -Nru bind9-9.20.11/bin/tests/system/kasp/ns3/setup.sh bind9-9.20.15/bin/tests/system/kasp/ns3/setup.sh --- bind9-9.20.11/bin/tests/system/kasp/ns3/setup.sh 2025-07-04 09:42:08.185324667 +0000 +++ bind9-9.20.15/bin/tests/system/kasp/ns3/setup.sh 2025-10-18 10:16:12.405729849 +0000 @@ -261,6 +261,19 @@ cp $infile $zonefile $SIGNER -S -x -s now-1w -e now+1w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +# These signatures are still good, but the key files will be removed +# before a second run of reconfiguring keys, now in manual-mode. +setup keyfiles-missing.manual +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $keytimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $keytimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -s now-1w -e now+1w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + # These signatures are already expired, and the private ZSK is retired. setup zsk-retired.autosign zsktimes="$keytimes -I now" diff -Nru bind9-9.20.11/bin/tests/system/kasp/tests_kasp.py bind9-9.20.15/bin/tests/system/kasp/tests_kasp.py --- bind9-9.20.11/bin/tests/system/kasp/tests_kasp.py 2025-07-04 09:42:08.187324714 +0000 +++ bind9-9.20.15/bin/tests/system/kasp/tests_kasp.py 2025-10-18 10:16:12.408729896 +0000 @@ -118,6 +118,7 @@ "P1Y": int(timedelta(days=365).total_seconds()), "P30D": int(timedelta(days=30).total_seconds()), "P6M": int(timedelta(days=31 * 6).total_seconds()), + "P2M": int(timedelta(days=31 * 2).total_seconds()), } KASP_INHERIT_TSIG_SECRET = { @@ -157,10 +158,18 @@ ] -def check_all(server, zone, policy, ksks, zsks, zsk_missing=False, tsig=None): +def check_all( + server, zone, policy, ksks, zsks, manual_mode=False, zsk_missing=False, tsig=None +): isctest.kasp.check_dnssecstatus(server, zone, ksks + zsks, policy=policy) isctest.kasp.check_apex( - server, zone, ksks, zsks, zsk_missing=zsk_missing, tsig=tsig + server, + zone, + ksks, + zsks, + manual_mode=manual_mode, + zsk_missing=zsk_missing, + tsig=tsig, ) isctest.kasp.check_subdomain(server, zone, ksks, zsks, tsig=tsig) @@ -203,7 +212,7 @@ ) for update in expected_updates: - isctest.run.retry_with_timeout(update_is_signed, timeout=5) + isctest.run.retry_with_timeout(update_is_signed, timeout=10) def cb_rrsig_refresh(params, ksks=None, zsks=None): @@ -586,6 +595,9 @@ ], }, id="secondary.kasp", + marks=pytest.mark.flaky( + max_runs=2, rerun_filter=isctest.mark.is_host_freebsd_13 + ), ), pytest.param( { @@ -630,16 +642,17 @@ ), ], ) -def test_kasp_case(servers, params): +def test_kasp_case(servers, ns3, params): # Test many different configurations and expected keys and states after # initial startup. - server = servers["ns3"] - keydir = server.identifier + keydir = ns3.identifier # Get test parameters. zone = params["zone"] policy = params["policy"] + isctest.kasp.wait_keymgr_done(ns3, zone) + params["config"]["key-directory"] = params["config"]["key-directory"].replace( "{keydir}", keydir ) @@ -657,7 +670,7 @@ isctest.log.info(f"check test case zone {zone} policy {policy}") # First make sure the zone is signed. - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) # Key properties. expected = isctest.kasp.policy_to_properties(ttl=ttl, keys=params["key-properties"]) @@ -675,7 +688,7 @@ ksks = [k for k in keys if k.is_ksk()] zsks = [k for k in keys if not k.is_ksk()] - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) offset = params["offset"] if "offset" in params else None @@ -688,7 +701,7 @@ if "rumoured" not in params: isctest.kasp.check_keytimes(keys, expected) - check_all(server, zone, policy, ksks, zsks, zsk_missing=zsk_missing) + check_all(ns3, zone, policy, ksks, zsks, zsk_missing=zsk_missing) if "additional-tests" in params: params["servers"] = servers @@ -751,6 +764,8 @@ else None ) + isctest.kasp.wait_keymgr_done(server, zone) + key1 = KeyProperties.default() key1.metadata["Algorithm"] = alg.number key1.metadata["Length"] = alg.bits @@ -771,26 +786,27 @@ param("3", "no", "yes", "view2"), ], ) -def test_kasp_inherit_view(number, dynamic, inline_signing, txt_rdata, servers): +def test_kasp_inherit_view(number, dynamic, inline_signing, txt_rdata, ns4): zone = "example.net" policy = "test" - server = servers["ns4"] view = f"example{number}" tsig = f"{os.environ['DEFAULT_HMAC']}:keyforview{number}:{KASP_INHERIT_TSIG_SECRET[f'view{number}']}" + isctest.kasp.wait_keymgr_done(ns4, zone) + key1 = KeyProperties.default() key1.metadata["Algorithm"] = ECDSAP384SHA384.number key1.metadata["Length"] = ECDSAP384SHA384.bits - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) + keys = isctest.kasp.keydir_to_keylist(zone, ns4.identifier) - isctest.kasp.check_dnssec_verify(server, zone, tsig=tsig) + isctest.kasp.check_dnssec_verify(ns4, zone, tsig=tsig) isctest.kasp.check_keys(zone, keys, [key1]) set_keytimes_default_policy(key1) isctest.kasp.check_keytimes(keys, [key1]) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy, view=view) - isctest.kasp.check_apex(server, zone, keys, [], tsig=tsig) + isctest.kasp.check_dnssecstatus(ns4, zone, keys, policy=policy, view=view) + isctest.kasp.check_apex(ns4, zone, keys, [], tsig=tsig) # check zonestatus - response = server.rndc(f"zonestatus {zone} in {view}", log=False) + response = ns4.rndc(f"zonestatus {zone} in {view}", log=False) assert f"dynamic: {dynamic}" in response assert f"inline signing: {inline_signing}" in response # check subdomain @@ -798,14 +814,14 @@ qname = f"view.{zone}." qtype = dns.rdatatype.TXT rdata = txt_rdata - query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True) + query = isctest.query.create(qname, qtype) tsigkey = tsig.split(":") keyring = dns.tsig.Key(tsigkey[1], tsigkey[2], tsigkey[0]) query.use_tsig(keyring) try: - response = isctest.query.tcp(query, server.ip, server.ports.dns, timeout=3) + response = isctest.query.tcp(query, ns4.ip, ns4.ports.dns, timeout=3) except dns.exception.Timeout: - isctest.log.debug(f"query timeout for query {qname} {qtype} to {server.ip}") + isctest.log.debug(f"query timeout for query {qname} {qtype} to {ns4.ip}") response = None assert response.rcode() == dns.rcode.NOERROR match = f'{qname} 300 IN TXT "{rdata}"' @@ -821,14 +837,14 @@ isctest.kasp.check_signatures(rrsigs, qtype, fqdn, keys, []) -def test_kasp_default(servers): - server = servers["ns3"] - +def test_kasp_default(ns3): # check the zone with default kasp policy has loaded and is signed. isctest.log.info("check a zone with the default policy is signed") zone = "default.kasp" policy = "default" + isctest.kasp.wait_keymgr_done(ns3, zone) + # Key properties. # DNSKEY, RRSIG (ksk), RRSIG (zsk) are published. DS needs to wait. keyprops = [ @@ -836,11 +852,11 @@ ] expected = isctest.kasp.policy_to_properties(ttl=3600, keys=keyprops) keys = isctest.kasp.keydir_to_keylist(zone, "ns3") - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) set_keytimes_default_policy(expected[0]) isctest.kasp.check_keytimes(keys, expected) - check_all(server, zone, policy, keys, []) + check_all(ns3, zone, policy, keys, []) # Trigger a keymgr run. Make sure the key files are not touched if there # are no modifications to the key metadata. @@ -852,8 +868,8 @@ pubkey_stat = os.stat(key.keyfile) state_stat = os.stat(key.statefile) - with server.watch_log_from_here() as watcher: - server.rndc(f"loadkeys {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"loadkeys {zone}", log=False) watcher.wait_for_line(f"keymgr: {zone} done") assert privkey_stat.st_mtime == os.stat(key.privatefile).st_mtime @@ -861,8 +877,8 @@ assert state_stat.st_mtime == os.stat(key.statefile).st_mtime # again - with server.watch_log_from_here() as watcher: - server.rndc(f"loadkeys {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"loadkeys {zone}", log=False) watcher.wait_for_line(f"keymgr: {zone} done") assert privkey_stat.st_mtime == os.stat(key.privatefile).st_mtime @@ -872,7 +888,7 @@ # modify unsigned zone file and check that new record is signed. isctest.log.info("check that an updated zone signs the new record") shutil.copyfile("ns3/template2.db.in", f"ns3/{zone}.db") - server.rndc(f"reload {zone}", log=False) + ns3.rndc(f"reload {zone}", log=False) def update_is_signed(): parts = update.split() @@ -880,7 +896,7 @@ qtype = dns.rdatatype.from_text(parts[1]) rdata = parts[2] return isctest.kasp.verify_update_is_signed( - server, zone, qname, qtype, rdata, keys, [] + ns3, zone, qname, qtype, rdata, keys, [] ) expected_updates = [f"a.{zone}. A 10.0.0.11", f"d.{zone}. A 10.0.0.44"] @@ -892,48 +908,51 @@ isctest.log.info("check that missing private key doesn't trigger rollover") shutil.move(f"{key.privatefile}", f"{key.path}.offline") expectmsg = "zone_rekey:zone_verifykeys failed: some key files are missing" - with server.watch_log_from_here() as watcher: - server.rndc(f"loadkeys {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"loadkeys {zone}", log=False) watcher.wait_for_line(f"zone {zone}/IN (signed): {expectmsg}") # Nothing has changed. expected[0].properties["private"] = False - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) isctest.kasp.check_keytimes(keys, expected) - check_all(server, zone, policy, keys, []) + check_all(ns3, zone, policy, keys, []) # A zone that uses inline-signing. isctest.log.info("check an inline-signed zone with the default policy is signed") zone = "inline-signing.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + # Key properties. key1 = KeyProperties.default() keys = isctest.kasp.keydir_to_keylist(zone, "ns3") expected = [key1] - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) set_keytimes_default_policy(key1) isctest.kasp.check_keytimes(keys, expected) - check_all(server, zone, policy, keys, []) - + check_all(ns3, zone, policy, keys, []) -def test_kasp_dynamic(servers): - # Dynamic update test cases. - server = servers["ns3"] +def test_kasp_dynamic(ns3): # Standard dynamic zone. isctest.log.info("check dynamic zone is updated and signed after update") zone = "dynamic.kasp" policy = "default" + + isctest.kasp.wait_keymgr_done(ns3, zone) + # Key properties. key1 = KeyProperties.default() expected = [key1] keys = isctest.kasp.keydir_to_keylist(zone, "ns3") - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) set_keytimes_default_policy(key1) expected = [key1] isctest.kasp.check_keytimes(keys, expected) - check_all(server, zone, policy, keys, []) + check_all(ns3, zone, policy, keys, []) def update_is_signed(): parts = update.split() @@ -941,14 +960,14 @@ qtype = dns.rdatatype.from_text(parts[1]) rdata = parts[2] return isctest.kasp.verify_update_is_signed( - server, zone, qname, qtype, rdata, keys, [] + ns3, zone, qname, qtype, rdata, keys, [] ) update_msg = dns.update.UpdateMessage(zone) update_msg.delete(f"a.{zone}.", "A", "10.0.0.1") update_msg.add(f"a.{zone}.", 300, "A", "10.0.0.101") update_msg.add(f"d.{zone}.", 300, "A", "10.0.0.4") - server.nsupdate(update_msg) + ns3.nsupdate(update_msg) expected_updates = [f"a.{zone}. A 10.0.0.101", f"d.{zone}. A 10.0.0.4"] for update in expected_updates: @@ -959,15 +978,15 @@ update_msg.add(f"a.{zone}.", 300, "A", "10.0.0.1") update_msg.delete(f"a.{zone}.", "A", "10.0.0.101") update_msg.delete(f"d.{zone}.", "A", "10.0.0.4") - server.nsupdate(update_msg) + ns3.nsupdate(update_msg) update = f"a.{zone}. A 10.0.0.1" isctest.run.retry_with_timeout(update_is_signed, timeout=5) # Update zone with freeze/thaw. isctest.log.info("check dynamic zone is updated and signed after freeze and thaw") - with server.watch_log_from_here() as watcher: - server.rndc(f"freeze {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"freeze {zone}", log=False) watcher.wait_for_line(f"freezing zone '{zone}/IN': success") time.sleep(1) @@ -975,8 +994,8 @@ zonefile.write(f"d.{zone}. 300 A 10.0.0.44\n") time.sleep(1) - with server.watch_log_from_here() as watcher: - server.rndc(f"thaw {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"thaw {zone}", log=False) watcher.wait_for_line(f"thawing zone '{zone}/IN': success") expected_updates = [f"a.{zone}. A 10.0.0.1", f"d.{zone}. A 10.0.0.44"] @@ -986,31 +1005,34 @@ # Dynamic, and inline-signing. zone = "dynamic-inline-signing.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + # Key properties. key1 = KeyProperties.default() expected = [key1] keys = isctest.kasp.keydir_to_keylist(zone, "ns3") - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) set_keytimes_default_policy(key1) expected = [key1] isctest.kasp.check_keytimes(keys, expected) - check_all(server, zone, policy, keys, []) + check_all(ns3, zone, policy, keys, []) # Update zone with freeze/thaw. isctest.log.info( "check dynamic inline-signed zone is updated and signed after freeze and thaw" ) - with server.watch_log_from_here() as watcher: - server.rndc(f"freeze {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"freeze {zone}", log=False) watcher.wait_for_line(f"freezing zone '{zone}/IN': success") time.sleep(1) shutil.copyfile("ns3/template2.db.in", f"ns3/{zone}.db") time.sleep(1) - with server.watch_log_from_here() as watcher: - server.rndc(f"thaw {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"thaw {zone}", log=False) watcher.wait_for_line(f"thawing zone '{zone}/IN': success") expected_updates = [f"a.{zone}. A 10.0.0.11", f"d.{zone}. A 10.0.0.44"] @@ -1020,6 +1042,9 @@ # Dynamic, signed, and inline-signing. isctest.log.info("check dynamic signed, and inline-signed zone") zone = "dynamic-signed-inline-signing.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + # Key properties. key1 = KeyProperties.default() # The ns3/setup.sh script sets all states to omnipresent. @@ -1029,16 +1054,14 @@ key1.metadata["DSState"] = "omnipresent" expected = [key1] keys = isctest.kasp.keydir_to_keylist(zone, "ns3/keys") - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) - check_all(server, zone, policy, keys, []) + check_all(ns3, zone, policy, keys, []) # Ensure no zone_resigninc for the unsigned version of the zone is triggered. assert f"zone_resigninc: zone {zone}/IN (unsigned): enter" not in "ns3/named.run" -def test_kasp_checkds(servers): - server = servers["ns3"] - +def test_kasp_checkds(ns3): def wait_for_metadata(): return isctest.util.file_contents_contain(ksk.statefile, metadata) @@ -1051,19 +1074,22 @@ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured", ] + + isctest.kasp.wait_keymgr_done(ns3, zone) + expected = isctest.kasp.policy_to_properties(ttl=303, keys=policy_keys) keys = isctest.kasp.keydir_to_keylist(zone, "ns3") ksks = [k for k in keys if k.is_ksk()] zsks = [k for k in keys if k.is_zsk()] - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) - check_all(server, zone, policy, ksks, zsks) + check_all(ns3, zone, policy, ksks, zsks) now = KeyTimingMetadata.now() ksk = ksks[0] isctest.log.info("check if checkds -publish correctly sets DSPublish") - server.rndc(f"dnssec -checkds -when {now} published {zone}", log=False) + ns3.rndc(f"dnssec -checkds -when {now} published {zone}", log=False) metadata = f"DSPublish: {now}" isctest.run.retry_with_timeout(wait_for_metadata, timeout=3) expected[0].metadata["DSState"] = "rumoured" @@ -1071,7 +1097,7 @@ isctest.kasp.check_keys(zone, keys, expected) isctest.log.info("check if checkds -withdrawn correctly sets DSRemoved") - server.rndc(f"dnssec -checkds -when {now} withdrawn {zone}", log=False) + ns3.rndc(f"dnssec -checkds -when {now} withdrawn {zone}", log=False) metadata = f"DSRemoved: {now}" isctest.run.retry_with_timeout(wait_for_metadata, timeout=3) expected[0].metadata["DSState"] = "unretentive" @@ -1079,9 +1105,7 @@ isctest.kasp.check_keys(zone, keys, expected) -def test_kasp_checkds_doubleksk(servers): - server = servers["ns3"] - +def test_kasp_checkds_doubleksk(ns3): def wait_for_metadata(): return isctest.util.file_contents_contain(ksk.statefile, metadata) @@ -1095,13 +1119,16 @@ f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured", ] + + isctest.kasp.wait_keymgr_done(ns3, zone) + expected = isctest.kasp.policy_to_properties(ttl=303, keys=policy_keys) keys = isctest.kasp.keydir_to_keylist(zone, "ns3") ksks = [k for k in keys if k.is_ksk()] zsks = [k for k in keys if k.is_zsk()] - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) - check_all(server, zone, policy, ksks, zsks) + check_all(ns3, zone, policy, ksks, zsks) now = KeyTimingMetadata.now() ksk = ksks[0] @@ -1110,7 +1137,7 @@ isctest.log.info("check invalid checkds commands") def check_error(): - response = server.rndc(test["command"], log=False) + response = ns3.rndc(test["command"], log=False) assert test["error"] in response test_cases = [ @@ -1135,9 +1162,7 @@ check_error() isctest.log.info("check if checkds -publish -key correctly sets DSPublish") - server.rndc( - f"dnssec -checkds -when {now} -key {ksk.tag} published {zone}", log=False - ) + ns3.rndc(f"dnssec -checkds -when {now} -key {ksk.tag} published {zone}", log=False) metadata = f"DSPublish: {now}" isctest.run.retry_with_timeout(wait_for_metadata, timeout=3) expected[0].metadata["DSState"] = "rumoured" @@ -1146,9 +1171,7 @@ isctest.log.info("check if checkds -withdrawn -key correctly sets DSRemoved") ksk = ksks[1] - server.rndc( - f"dnssec -checkds -when {now} -key {ksk.tag} withdrawn {zone}", log=False - ) + ns3.rndc(f"dnssec -checkds -when {now} -key {ksk.tag} withdrawn {zone}", log=False) metadata = f"DSRemoved: {now}" isctest.run.retry_with_timeout(wait_for_metadata, timeout=3) expected[1].metadata["DSState"] = "unretentive" @@ -1156,9 +1179,7 @@ isctest.kasp.check_keys(zone, keys, expected) -def test_kasp_checkds_csk(servers): - server = servers["ns3"] - +def test_kasp_checkds_csk(ns3): def wait_for_metadata(): return isctest.util.file_contents_contain(ksk.statefile, metadata) @@ -1170,17 +1191,20 @@ policy_keys = [ f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", ] + + isctest.kasp.wait_keymgr_done(ns3, zone) + expected = isctest.kasp.policy_to_properties(ttl=303, keys=policy_keys) keys = isctest.kasp.keydir_to_keylist(zone, "ns3") - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) - check_all(server, zone, policy, keys, []) + check_all(ns3, zone, policy, keys, []) now = KeyTimingMetadata.now() ksk = keys[0] isctest.log.info("check if checkds -publish csk correctly sets DSPublish") - server.rndc(f"dnssec -checkds -when {now} published {zone}", log=False) + ns3.rndc(f"dnssec -checkds -when {now} published {zone}", log=False) metadata = f"DSPublish: {now}" isctest.run.retry_with_timeout(wait_for_metadata, timeout=3) expected[0].metadata["DSState"] = "rumoured" @@ -1188,7 +1212,7 @@ isctest.kasp.check_keys(zone, keys, expected) isctest.log.info("check if checkds -withdrawn csk correctly sets DSRemoved") - server.rndc(f"dnssec -checkds -when {now} withdrawn {zone}", log=False) + ns3.rndc(f"dnssec -checkds -when {now} withdrawn {zone}", log=False) metadata = f"DSRemoved: {now}" isctest.run.retry_with_timeout(wait_for_metadata, timeout=3) expected[0].metadata["DSState"] = "unretentive" @@ -1196,50 +1220,49 @@ isctest.kasp.check_keys(zone, keys, expected) -def test_kasp_special_characters(servers): - server = servers["ns3"] - +def test_kasp_special_characters(ns3): # A zone with special characters. isctest.log.info("check special characters") - zone = r'i-am.":\;?&[]\@!\$*+,|=\.\(\)special.kasp' + zone = r"i-am.\":\;?&[]\@!\$*+,|=\.\(\)special.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + # It is non-trivial to adapt the tests to deal with all possible different # escaping characters, so we will just try to verify the zone. - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) -def test_kasp_insecure(servers): - server = servers["ns3"] - +def test_kasp_insecure(ns3): # Insecure zones. isctest.log.info("check insecure zones") zone = "insecure.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + expected = [] keys = isctest.kasp.keydir_to_keylist(zone, "ns3") isctest.kasp.check_keys(zone, keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy="insecure") - isctest.kasp.check_apex(server, zone, keys, []) - isctest.kasp.check_subdomain(server, zone, keys, []) + isctest.kasp.check_dnssecstatus(ns3, zone, keys, policy="insecure") + isctest.kasp.check_apex(ns3, zone, keys, []) + isctest.kasp.check_subdomain(ns3, zone, keys, []) zone = "unsigned.kasp" expected = [] keys = isctest.kasp.keydir_to_keylist(zone, "ns3") isctest.kasp.check_keys(zone, keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=None) - isctest.kasp.check_apex(server, zone, keys, []) - isctest.kasp.check_subdomain(server, zone, keys, []) + isctest.kasp.check_dnssecstatus(ns3, zone, keys, policy=None) + isctest.kasp.check_apex(ns3, zone, keys, []) + isctest.kasp.check_subdomain(ns3, zone, keys, []) # Make sure the zone file is untouched. isctest.check.file_contents_equal(f"ns3/{zone}.db.infile", f"ns3/{zone}.db") -def test_kasp_bad_maxzonettl(servers): - server = servers["ns3"] - - # check that max-zone-ttl rejects zones with too high TTL. +def test_kasp_bad_maxzonettl(ns3): isctest.log.info("check max-zone-ttl rejects zones with too high TTL") zone = "max-zone-ttl.kasp" - assert f"loading from master file {zone}.db failed: out of range" in server.log + assert f"loading from master file {zone}.db failed: out of range" in ns3.log def test_kasp_dnssec_keygen(): @@ -1260,7 +1283,10 @@ return isctest.run.cmd(keygen_command).stdout.decode("utf-8") - # check that 'dnssec-keygen -k' (configured policy) creates valid files. + isctest.log.info( + "check that 'dnssec-keygen -k' (configured policy) created valid files" + ) + keyprops = [ f"csk {lifetime['P1Y']} 13 256", f"ksk {lifetime['P1Y']} 8 2048", @@ -1273,14 +1299,20 @@ expected = isctest.kasp.policy_to_properties(ttl=200, keys=keyprops) isctest.kasp.check_keys("kasp", keys, expected) - # check that 'dnssec-keygen -k' (default policy) creates valid files. + isctest.log.info( + "check that 'dnssec-keygen -k' (default policy) created valid files" + ) + keyprops = ["csk 0 13 256"] out = keygen("kasp", "default") keys = isctest.kasp.keystr_to_keylist(out) expected = isctest.kasp.policy_to_properties(ttl=3600, keys=keyprops) isctest.kasp.check_keys("kasp", keys, expected) - # check that 'dnssec-settime' by default does not edit key state file. + isctest.log.info( + "check that 'dnssec-settime' by default does not edit key state file" + ) + key = keys[0] shutil.copyfile(key.privatefile, f"{key.privatefile}.backup") shutil.copyfile(key.keyfile, f"{key.keyfile}.backup") @@ -1300,8 +1332,10 @@ assert key.get_metadata("Publish", file=key.privatefile) == str(publish) assert key.get_metadata("Publish", file=key.keyfile, comment=True) == str(publish) - # check that 'dnssec-settime -s' also sets publish time metadata and - # states in key state file. + isctest.log.info( + "check that 'dnssec-settime -s' also sets publish time metadata and states in key state file" + ) + now = KeyTimingMetadata.now() goal = "omnipresent" dnskey = "rumoured" @@ -1347,8 +1381,10 @@ isctest.kasp.check_keys("kasp", keys, expected) isctest.kasp.check_keytimes(keys, expected) - # check that 'dnssec-settime -s' also unsets publish time metadata and - # states in key state file. + isctest.log.info( + "check that 'dnssec-settime -s' also unsets publish time metadata and states in key state file" + ) + now = KeyTimingMetadata.now() keyprops = ["csk 0 13 256"] expected = isctest.kasp.policy_to_properties(ttl=3600, keys=keyprops) @@ -1382,7 +1418,10 @@ isctest.kasp.check_keys("kasp", keys, expected) isctest.kasp.check_keytimes(keys, expected) - # check that 'dnssec-settime -s' also sets active time metadata and states in key state file (uppercase) + isctest.log.info( + "check that 'dnssec-settime -s' also sets active time metadata and states in key state file (uppercase)" + ) + soon = now + timedelta(hours=2) goal = "hidden" dnskey = "unretentive" @@ -1428,9 +1467,7 @@ isctest.kasp.check_keytimes(keys, expected) -def test_kasp_zsk_retired(servers): - server = servers["ns3"] - +def test_kasp_zsk_retired(ns3): config = { "dnskey-ttl": timedelta(seconds=300), "ds-ttl": timedelta(days=1), @@ -1454,11 +1491,14 @@ # zsk successor f"zsk 31536000 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden", ] + + isctest.kasp.wait_keymgr_done(ns3, zone) + expected = isctest.kasp.policy_to_properties(300, key_properties) keys = isctest.kasp.keydir_to_keylist(zone, "ns3") ksks = [k for k in keys if k.is_ksk()] zsks = [k for k in keys if not k.is_ksk()] - isctest.kasp.check_dnssec_verify(server, zone) + isctest.kasp.check_dnssec_verify(ns3, zone) isctest.kasp.check_keys(zone, keys, expected) offset = -timedelta(days=30 * 6) @@ -1526,7 +1566,7 @@ expected[2].timing["ZRRSIGChange"] = None isctest.kasp.check_keytimes(keys, expected) - check_all(server, zone, policy, ksks, zsks) + check_all(ns3, zone, policy, ksks, zsks) queries = [ f"{zone} DNSKEY", @@ -1548,25 +1588,23 @@ qname = parts[0] qtype = dns.rdatatype.from_text(parts[1]) return isctest.kasp.verify_rrsig_is_refreshed( - server, zone, f"ns3/{zone}.db.signed", qname, qtype, ksks, zsks + ns3, zone, f"ns3/{zone}.db.signed", qname, qtype, ksks, zsks ) for query in queries: isctest.run.retry_with_timeout(rrsig_is_refreshed, timeout=5) # Load again, make sure the purged key is not an issue when verifying keys. - with server.watch_log_from_here() as watcher: - server.rndc(f"loadkeys {zone}", log=False) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"loadkeys {zone}", log=False) watcher.wait_for_line(f"keymgr: {zone} done") msg = f"zone {zone}/IN (signed): zone_rekey:zone_verifykeys failed: some key files are missing" - server.log.prohibit(msg) + ns3.log.prohibit(msg) -def test_kasp_purge_keys(servers): +def test_kasp_purge_keys(ns4): zone = "purgekeys.kasp" - server = servers["ns4"] - tsig1 = ( f"{os.environ['DEFAULT_HMAC']}:keyforview1:{KASP_INHERIT_TSIG_SECRET['view1']}" ) @@ -1574,34 +1612,35 @@ f"{os.environ['DEFAULT_HMAC']}:keyforview2:{KASP_INHERIT_TSIG_SECRET['view2']}" ) - isctest.kasp.check_dnssec_verify(server, zone, tsig=tsig1) - isctest.kasp.check_dnssec_verify(server, zone, tsig=tsig2) + isctest.kasp.wait_keymgr_done(ns4, zone) + + isctest.kasp.check_dnssec_verify(ns4, zone, tsig=tsig1) + isctest.kasp.check_dnssec_verify(ns4, zone, tsig=tsig2) # Reconfig, make sure the purged key is not an issue when verifying keys. shutil.copyfile("ns4/purgekeys2.conf", "ns4/purgekeys.conf") - with server.watch_log_from_here() as watcher: - server.rndc("reconfig", log=False) + with ns4.watch_log_from_here() as watcher: + ns4.rndc("reconfig", log=False) watcher.wait_for_line(f"keymgr: {zone} done") msg = f"zone {zone}/IN/example1 (signed): zone_rekey:zone_verifykeys failed: some key files are missing" - server.log.prohibit(msg) + ns4.log.prohibit(msg) msg = f"zone {zone}/IN/example2 (signed): zone_rekey:zone_verifykeys failed: some key files are missing" - server.log.prohibit(msg) + ns4.log.prohibit(msg) -def test_kasp_reload_restart(servers): - server = servers["ns6"] +def test_kasp_reload_restart(ns6): zone = "example" def query_soa(qname): fqdn = dns.name.from_text(qname) qtype = dns.rdatatype.SOA - query = dns.message.make_query(fqdn, qtype, use_edns=True, want_dnssec=True) + query = isctest.query.create(fqdn, qtype) try: - response = isctest.query.tcp(query, server.ip, server.ports.dns, timeout=3) + response = isctest.query.tcp(query, ns6.ip, ns6.ports.dns, timeout=3) except dns.exception.Timeout: - isctest.log.debug(f"query timeout for query {qname} SOA to {server.ip}") + isctest.log.debug(f"query timeout for query {qname} SOA to {ns6.ip}") return 0, 0 assert response.rcode() == dns.rcode.NOERROR @@ -1626,8 +1665,8 @@ assert ttl1 == 300 shutil.copyfile(f"ns6/{zone}2.db.in", f"ns6/{zone}.db") - with server.watch_log_from_here() as watcher: - server.rndc("reload", log=False) + with ns6.watch_log_from_here() as watcher: + ns6.rndc("reload", log=False) watcher.wait_for_line("all zones loaded") newttl = 300 @@ -1638,12 +1677,111 @@ soa1, ttl1 = query_soa(zone) assert ttl1 == 300 - server.stop() + ns6.stop() shutil.copyfile(f"ns6/{zone}3.db.in", f"ns6/{zone}.db") os.unlink(f"ns6/{zone}.db.jnl") - with server.watch_log_from_here() as watcher: - server.start(["--noclean", "--restart", "--port", os.environ["PORT"]]) + with ns6.watch_log_from_here() as watcher: + ns6.start(["--noclean", "--restart", "--port", os.environ["PORT"]]) watcher.wait_for_line("all zones loaded") newttl = 400 isctest.run.retry_with_timeout(check_soa_ttl, timeout=10) + + +def test_kasp_manual_mode(ns3): + + keydir = ns3.identifier + zone = "keyfiles-missing.manual" + policy = "manual" + ttl = int(autosign_config["dnskey-ttl"].total_seconds()) + offset = -timedelta(days=30 * 6) + alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] + size = os.environ["DEFAULT_BITS"] + keyprops = [ + f"ksk {lifetime['P2Y']} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + f"zsk {lifetime['P2M']} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent", + ] + + isctest.kasp.wait_keymgr_done(ns3, zone) + + isctest.log.info(f"check test case zone {zone} policy {policy}") + + # First make sure the zone is signed. + isctest.kasp.check_dnssec_verify(ns3, zone) + + # Key properties. + expected = isctest.kasp.policy_to_properties(ttl=ttl, keys=keyprops) + + # Key files. + keys = isctest.kasp.keydir_to_keylist(zone, keydir) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + isctest.kasp.check_dnssec_verify(ns3, zone) + isctest.kasp.check_keys(zone, keys, expected) + + for kp in expected: + kp.set_expected_keytimes(autosign_config, offset=offset) + + isctest.kasp.check_keytimes(keys, expected) + + check_all(ns3, zone, policy, ksks, zsks, manual_mode=True) + + # Key rollover should have been be blocked. + tag = expected[1].key.tag + blockmsg = f"keymgr-manual-mode: block ZSK rollover for key {zone}/ECDSAP256SHA256/{tag} (policy {policy})" + ns3.log.expect(blockmsg) + + # Remove files. + for key in ksks + zsks: + shutil.copyfile(key.privatefile, f"{key.privatefile}.backup") + shutil.copyfile(key.keyfile, f"{key.keyfile}.backup") + shutil.copyfile(key.statefile, f"{key.statefile}.backup") + + os.remove(key.keyfile) + os.remove(key.privatefile) + os.remove(key.statefile) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}", log=False) + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey:zone_verifykeys failed: some key files are missing" + ) + + # Restore key files. + for key in ksks + zsks: + shutil.copyfile(f"{key.privatefile}.backup", key.privatefile) + shutil.copyfile(f"{key.keyfile}.backup", key.keyfile) + shutil.copyfile(f"{key.statefile}.backup", key.statefile) + + # Load keys. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"loadkeys {zone}", log=False) + watcher.wait_for_line(blockmsg) + + # Check keys again, make sure no new keys are created. + isctest.kasp.check_keys(zone, keys, expected) + isctest.kasp.check_keytimes(keys, expected) + check_all(ns3, zone, policy, ksks, zsks, manual_mode=True) + isctest.kasp.check_dnssec_verify(ns3, zone) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}", log=False) + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + # Check keys again, make sure the rollover has started. + keyprops = [ + f"ksk {lifetime['P2Y']} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + f"zsk {lifetime['P2M']} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent", + f"zsk {lifetime['P2M']} {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden", + ] + expected = isctest.kasp.policy_to_properties(ttl=ttl, keys=keyprops) + keys = isctest.kasp.keydir_to_keylist(zone, keydir) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + isctest.kasp.check_keys(zone, keys, expected) + check_all(ns3, zone, policy, ksks, zsks, manual_mode=True) + isctest.kasp.check_dnssec_verify(ns3, zone) diff -Nru bind9-9.20.11/bin/tests/system/keepalive/tests_keepalive.py bind9-9.20.15/bin/tests/system/keepalive/tests_keepalive.py --- bind9-9.20.11/bin/tests/system/keepalive/tests_keepalive.py 2025-07-04 09:42:08.187324714 +0000 +++ bind9-9.20.15/bin/tests/system/keepalive/tests_keepalive.py 2025-10-18 10:16:12.408729896 +0000 @@ -18,9 +18,9 @@ ) -def test_dig_tcp_keepalive_handling(named_port, servers): +def test_dig_tcp_keepalive_handling(named_port, ns2): def get_keepalive_options_received(): - servers["ns2"].rndc("stats", log=False) + ns2.rndc("stats", log=False) options_received = 0 with open("ns2/named.stats", "r", encoding="utf-8") as ns2_stats_file: for line in ns2_stats_file: @@ -53,7 +53,7 @@ ) isctest.log.info("check a re-configured keepalive value") - response = servers["ns2"].rndc("tcp-timeouts 300 300 300 200", log=False) + response = ns2.rndc("tcp-timeouts 300 300 300 200", log=False) assert "tcp-initial-timeout=300" in response assert "tcp-idle-timeout=300" in response assert "tcp-keepalive-timeout=300" in response diff -Nru bind9-9.20.11/bin/tests/system/keyfromlabel/tests_keyfromlabel.py bind9-9.20.15/bin/tests/system/keyfromlabel/tests_keyfromlabel.py --- bind9-9.20.11/bin/tests/system/keyfromlabel/tests_keyfromlabel.py 2025-07-04 09:42:08.188324737 +0000 +++ bind9-9.20.15/bin/tests/system/keyfromlabel/tests_keyfromlabel.py 2025-10-18 10:16:12.408729896 +0000 @@ -86,7 +86,6 @@ raise_on_exception=False, ).stdout.decode("utf-8") assert re.search("Found token (.*) with matching token label", output) - assert re.search("The token (.*) has been deleted", output) # pylint: disable-msg=too-many-locals diff -Nru bind9-9.20.11/bin/tests/system/ksr/tests_ksr.py bind9-9.20.15/bin/tests/system/ksr/tests_ksr.py --- bind9-9.20.11/bin/tests/system/ksr/tests_ksr.py 2025-07-04 09:42:08.188324737 +0000 +++ bind9-9.20.15/bin/tests/system/ksr/tests_ksr.py 2025-10-18 10:16:12.409729911 +0000 @@ -11,6 +11,7 @@ from datetime import timedelta import os +import re import shutil import time @@ -564,7 +565,7 @@ assert "dnssec-ksr: fatal: 'sign' requires a KSR file" in err -def test_ksr_common(servers): +def test_ksr_common(ns1): # common test cases (1) zone = "common.test" policy = "common" @@ -651,17 +652,10 @@ overlapping_zsks = isctest.kasp.keystr_to_keylist(out, zskdir) assert len(overlapping_zsks) == 4 - verbose = err.split() - selected = 0 - generated = 0 - for output in verbose: - if "Selecting" in output: - selected += 1 - if "Generating" in output: - generated += 1 - # Subtract if there was a key collision. - if "collide" in output: - generated -= 1 + selected = len(re.findall("Selecting key pair", err)) + generated = len(re.findall("Generating key pair", err)) - len( + re.findall("collide", err) + ) assert selected == 2 assert generated == 2 @@ -738,7 +732,6 @@ ) # add zone - ns1 = servers["ns1"] ns1.rndc( f"addzone {zone} " + "{ type primary; file " @@ -764,7 +757,7 @@ isctest.kasp.check_subdomain(ns1, zone, ksks, overlapping_zsks, offline_ksk=True) -def test_ksr_lastbundle(servers): +def test_ksr_lastbundle(ns1): zone = "last-bundle.test" policy = "common" n = 1 @@ -811,7 +804,6 @@ check_signedkeyresponse(out, zone, ksks, zsks, then, until, refresh) # add zone - ns1 = servers["ns1"] ns1.rndc( f"addzone {zone} " + "{ type primary; file " @@ -841,7 +833,7 @@ assert f"zone {zone}/IN (signed): zone_rekey: {warning}" in ns1.log -def test_ksr_inthemiddle(servers): +def test_ksr_inthemiddle(ns1): zone = "in-the-middle.test" policy = "common" n = 1 @@ -889,7 +881,6 @@ check_signedkeyresponse(out, zone, ksks, zsks, then, until, refresh) # add zone - ns1 = servers["ns1"] ns1.rndc( f"addzone {zone} " + "{ type primary; file " @@ -982,18 +973,14 @@ assert line in server.log -def test_ksr_rekey_logs_error(servers): +def test_ksr_rekey_logs_error(ns1): # check that an SKR that is too old logs error - check_ksr_rekey_logs_error( - servers["ns1"], "past.test", "common", -63072000, -31536000 - ) + check_ksr_rekey_logs_error(ns1, "past.test", "common", -63072000, -31536000) # check that an SKR that is too new logs error - check_ksr_rekey_logs_error( - servers["ns1"], "future.test", "common", 2592000, 31536000 - ) + check_ksr_rekey_logs_error(ns1, "future.test", "common", 2592000, 31536000) -def test_ksr_unlimited(servers): +def test_ksr_unlimited(ns1): zone = "unlimited.test" policy = "unlimited" n = 1 @@ -1082,7 +1069,6 @@ check_signedkeyresponse(out, zone, ksks, zsks, now, until, refresh) # add zone - ns1 = servers["ns1"] ns1.rndc( f"addzone {zone} " + "{ type primary; file " @@ -1108,7 +1094,7 @@ isctest.kasp.check_subdomain(ns1, zone, ksks, zsks, offline_ksk=True) -def test_ksr_twotone(servers): +def test_ksr_twotone(ns1): zone = "two-tone.test" policy = "two-tone" n = 1 @@ -1192,7 +1178,6 @@ check_signedkeyresponse(out, zone, ksks, zsks, now, until, refresh) # add zone - ns1 = servers["ns1"] ns1.rndc( f"addzone {zone} " + "{ type primary; file " @@ -1224,7 +1209,7 @@ isctest.kasp.check_subdomain(ns1, zone, ksks, zsks, offline_ksk=True) -def test_ksr_kskroll(servers): +def test_ksr_kskroll(ns1): zone = "ksk-roll.test" policy = "ksk-roll" n = 1 @@ -1270,7 +1255,6 @@ check_signedkeyresponse(out, zone, ksks, zsks, now, until, refresh) # add zone - ns1 = servers["ns1"] ns1.rndc( f"addzone {zone} " + "{ type primary; file " diff -Nru bind9-9.20.11/bin/tests/system/legacy/ns1/named1.conf.in bind9-9.20.15/bin/tests/system/legacy/ns1/named1.conf.in --- bind9-9.20.11/bin/tests/system/legacy/ns1/named1.conf.in 2025-07-04 09:42:08.188324737 +0000 +++ bind9-9.20.15/bin/tests/system/legacy/ns1/named1.conf.in 2025-10-18 10:16:12.409729911 +0000 @@ -20,10 +20,9 @@ listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/limits/tests_limits.py bind9-9.20.15/bin/tests/system/limits/tests_limits.py --- bind9-9.20.11/bin/tests/system/limits/tests_limits.py 2025-07-04 09:42:08.192324831 +0000 +++ bind9-9.20.15/bin/tests/system/limits/tests_limits.py 2025-10-18 10:16:12.413729974 +0000 @@ -14,11 +14,10 @@ import isctest import pytest -import dns.message - # Everything from getting a big answer to creating an RR set with thousands # of records takes minutes of CPU and real time with dnspython < 2.0.0. pytest.importorskip("dns", minversion="2.0.0") +import dns.rrset @pytest.mark.parametrize( @@ -32,7 +31,7 @@ ], ) def test_limits(name, limit): - msg_query = dns.message.make_query(f"{name}.example.", "A") + msg_query = isctest.query.create(f"{name}.example.", "A") res = isctest.query.tcp(msg_query, "10.53.0.1", log_response=False) iplist = [ @@ -46,7 +45,7 @@ def test_limit_exceeded(): - msg_query = dns.message.make_query("5000.example.", "A") + msg_query = isctest.query.create("5000.example.", "A") res = isctest.query.tcp(msg_query, "10.53.0.1", log_response=False) assert res.flags & dns.flags.TC, "TC flag was not set" diff -Nru bind9-9.20.11/bin/tests/system/makejournal.c bind9-9.20.15/bin/tests/system/makejournal.c --- bind9-9.20.11/bin/tests/system/makejournal.c 2025-07-04 09:42:08.194324878 +0000 +++ bind9-9.20.15/bin/tests/system/makejournal.c 2025-10-18 10:16:12.415730005 +0000 @@ -156,5 +156,7 @@ isc_mem_destroy(&mctx); } + rcu_barrier(); + return result != ISC_R_SUCCESS ? 1 : 0; } diff -Nru bind9-9.20.11/bin/tests/system/masterfile/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/masterfile/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/masterfile/ns2/named.conf.j2 2025-07-04 09:42:08.194324878 +0000 +++ bind9-9.20.15/bin/tests/system/masterfile/ns2/named.conf.j2 2025-10-18 10:16:12.415730005 +0000 @@ -24,10 +24,9 @@ allow-transfer { any; }; recursion no; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/masterfile/tests_masterfile.py bind9-9.20.15/bin/tests/system/masterfile/tests_masterfile.py --- bind9-9.20.11/bin/tests/system/masterfile/tests_masterfile.py 2025-07-04 09:42:08.194324878 +0000 +++ bind9-9.20.15/bin/tests/system/masterfile/tests_masterfile.py 2025-10-18 10:16:12.415730005 +0000 @@ -19,7 +19,7 @@ def test_masterfile_include_semantics(): """Test master file $INCLUDE semantics""" - msg_axfr = dns.message.make_query("include.", "AXFR") + msg_axfr = isctest.query.create("include.", "AXFR") res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1") axfr_include_semantics = """;ANSWER include. 300 IN SOA ns.include. hostmaster.include. 1 3600 1800 1814400 3600 @@ -40,7 +40,7 @@ def test_masterfile_bind_8_compat_semantics(): """Test master file BIND 8 TTL and $TTL semantics compatibility""" - msg_axfr = dns.message.make_query("ttl1.", "AXFR") + msg_axfr = isctest.query.create("ttl1.", "AXFR") res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1") axfr_ttl_semantics = """;ANSWER ttl1. 3 IN SOA ns.ttl1. hostmaster.ttl1. 1 3600 1800 1814400 3 @@ -59,7 +59,7 @@ def test_masterfile_rfc_1035_semantics(): """Test master file RFC1035 TTL and $TTL semantics""" - msg_axfr = dns.message.make_query("ttl2.", "AXFR") + msg_axfr = isctest.query.create("ttl2.", "AXFR") res_axfr = isctest.query.tcp(msg_axfr, "10.53.0.1") axfr_ttl_semantics = """;ANSWER ttl2. 1 IN SOA ns.ttl2. hostmaster.ttl2. 1 3600 1800 1814400 3 @@ -78,7 +78,7 @@ def test_masterfile_missing_master_file(): """Test nameserver running with a missing master file""" - msg_soa = dns.message.make_query("example.", "SOA") + msg_soa = isctest.query.create("example.", "SOA") res_soa = isctest.query.tcp(msg_soa, "10.53.0.2") expected_soa_rr = """;ANSWER example. 300 IN SOA mname1. . 2010042407 20 20 1814400 3600 @@ -89,7 +89,7 @@ def test_masterfile_missing_master_file_servfail(): """Test nameserver returning SERVFAIL for a missing master file""" - msg_soa = dns.message.make_query("missing.", "SOA") + msg_soa = isctest.query.create("missing.", "SOA") res_soa = isctest.query.tcp(msg_soa, "10.53.0.2") isctest.check.servfail(res_soa) diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/kasp.conf.j2 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,104 @@ +/* + * 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. + */ + +dnssec-policy "migrate" { + dnskey-ttl 7200; + + keys { + ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + }; +}; + +dnssec-policy "timing-metadata" { + dnskey-ttl 300; + + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + keys { + ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + }; + + // Together 12h + zone-propagation-delay 3600; + max-zone-ttl 11h; + + // Together 3h + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +/* + * This policy tests migration from existing keys with 1024 bits RSASHA1 keys + * to ECDSAP256SHA256 keys. + */ +dnssec-policy "migrate-nomatch-algnum" { + dnskey-ttl 300; + + keys { + ksk key-directory lifetime unlimited algorithm ecdsa256; + zsk key-directory lifetime P60D algorithm ecdsa256; + }; + + // Together 12h + zone-propagation-delay 3600; + max-zone-ttl 11h; + + // Together 3h + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +/* + * This policy tests migration from existing keys with 2048 bits RSASHA256 keys + * to 3072 bits RSASHA256 keys. + */ +dnssec-policy "migrate-nomatch-alglen" { + dnskey-ttl 300; + + keys { + ksk key-directory lifetime unlimited algorithm rsasha256 3072; + zsk key-directory lifetime P60D algorithm rsasha256 3072; + }; + + // Together 12h + zone-propagation-delay 3600; + max-zone-ttl 11h; + + // Together 3h + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +/* + * This policy tests migration from existing KSK and ZSK to CSK. + * The keys clause matches the default policy. + */ +dnssec-policy "migrate-nomatch-kzc" { + dnskey-ttl 300; + + keys { + csk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; + + // Together 12h + zone-propagation-delay 3600; + max-zone-ttl 11h; + + // Together 3h + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/named.conf.j2 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,111 @@ +/* + * 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. + */ + +// NS3 + +include "kasp.conf"; + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +/* These are zones that migrate to dnssec-policy. */ +zone "migrate.kasp" { + type primary; + file "migrate.kasp.db"; + dnssec-policy "migrate"; + inline-signing no; + allow-update { any; }; +}; + +zone "csk.kasp" { + type primary; + file "csk.kasp.db"; + dnssec-policy "default"; + inline-signing no; + allow-update { any; }; +}; + +zone "csk-nosep.kasp" { + type primary; + file "csk-nosep.kasp.db"; + dnssec-policy "default"; + inline-signing no; + allow-update { any; }; +}; + +zone "rumoured.kasp" { + type primary; + file "rumoured.kasp.db"; + dnssec-policy "timing-metadata"; + inline-signing no; + allow-update { any; }; +}; + +zone "omnipresent.kasp" { + type primary; + file "omnipresent.kasp.db"; + dnssec-policy "timing-metadata"; + inline-signing no; + allow-update { any; }; +}; + +zone "no-syncpublish.kasp" { + type primary; + file "no-syncpublish.kasp.db"; + dnssec-policy "timing-metadata"; + inline-signing no; + allow-update { any; }; +}; + +zone "migrate-nomatch-algnum.kasp" { + type primary; + file "migrate-nomatch-algnum.kasp.db"; + dnssec-policy "migrate-nomatch-algnum"; + inline-signing no; + allow-update { any; }; +}; + +zone "migrate-nomatch-alglen.kasp" { + type primary; + file "migrate-nomatch-alglen.kasp.db"; + dnssec-policy "migrate-nomatch-alglen"; + inline-signing no; + allow-update { any; }; +}; + +zone "migrate-nomatch-kzc.kasp" { + type primary; + file "migrate-nomatch-kzc.kasp.db"; + dnssec-policy "migrate-nomatch-kzc"; + inline-signing no; + allow-update { any; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/setup.sh bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/setup.sh --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/setup.sh 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,161 @@ +#!/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 "ns3/setup.sh" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# Set up a zone with auto-dnssec maintain to migrate to dnssec-policy. +setup migrate.kasp +echo "$zone" >>zones +ksktimes="-P now -A now -P sync now" +zsktimes="-P now -A now" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.2) +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" +$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 + +# Set up Single-Type Signing Scheme zones with auto-dnssec maintain to +# migrate to dnssec-policy. This is a zone that has 'update-check-ksk no;' +# configured, meaning the zone is signed with a single CSK. +setup csk.kasp +echo "$zone" >>zones +csktimes="-P now -A now -P sync now" +CSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $csktimes $zone 2>keygen.out.$zone.1) +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" +$SIGNER -S -z -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 + +setup csk-nosep.kasp +echo "$zone" >>zones +csktimes="-P now -A now -P sync now" +CSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $csktimes $zone 2>keygen.out.$zone.1) +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" +$SIGNER -S -z -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 + +# Set up a zone with auto-dnssec maintain to migrate to dnssec-policy, but this +# time the existing keys do not match the policy. The existing keys are +# RSASHA256 keys, and will be migrated to a dnssec-policy that dictates +# ECDSAP256SHA256 keys. +setup migrate-nomatch-algnum.kasp +echo "$zone" >>zones +Tds="now-3h" # Time according to dnssec-policy that DS will be OMNIPRESENT +Tkey="now-3900s" # DNSKEY TTL + propagation delay +Tsig="now-12h" # Zone's maximum TTL + propagation delay +ksktimes="-P ${Tkey} -A ${Tkey} -P sync ${Tds}" +zsktimes="-P ${Tkey} -A ${Tsig}" +KSK=$($KEYGEN -a RSASHA256 -b 2048 -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a RSASHA256 -b 2048 -L 300 $zsktimes $zone 2>keygen.out.$zone.2) +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone 5 "$KSK" >>"$infile" +private_type_record $zone 5 "$ZSK" >>"$infile" +$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 + +# Set up a zone with auto-dnssec maintain to migrate to dnssec-policy, but this +# time the existing keys do not match the policy. The existing keys are +# 2048 bits RSASHA256 keys, and will be migrated to a dnssec-policy that +# dictates 3072 bits RSASHA256 keys. +setup migrate-nomatch-alglen.kasp +echo "$zone" >>zones +Tds="now-3h" # Time according to dnssec-policy that DS will be OMNIPRESENT +Tkey="now-3900s" # DNSKEY TTL + propagation delay +Tsig="now-12h" # Zone's maximum TTL + propagation delay +ksktimes="-P ${Tkey} -A ${Tkey} -P sync ${Tds}" +zsktimes="-P ${Tkey} -A ${Tsig}" +KSK=$($KEYGEN -a RSASHA256 -b 2048 -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a RSASHA256 -b 2048 -L 300 $zsktimes $zone 2>keygen.out.$zone.2) +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone 5 "$KSK" >>"$infile" +private_type_record $zone 5 "$ZSK" >>"$infile" +$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 + +# Set up a zone with auto-dnssec maintain to migrate to default dnssec-policy. +# The zone is signed with KSK/ZSK split, but the dnssec-policy uses CSK. +setup migrate-nomatch-kzc.kasp +echo "$zone" >>zones +Tds="now-3h" # Time according to dnssec-policy that DS will be OMNIPRESENT +Tkey="now-3900s" # DNSKEY TTL + propagation delay +Tsig="now-12h" # Zone's maximum TTL + propagation delay +ksktimes="-P ${Tkey} -A ${Tkey} -P sync ${Tds}" +zsktimes="-P ${Tkey} -A ${Tsig}" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2) +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +cp $infile $zonefile +private_type_record $zone 5 "$KSK" >>"$infile" +private_type_record $zone 5 "$ZSK" >>"$infile" +$SIGNER -PS -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +# +# Set up zones to test time metadata correctly sets state. +# + +# Key states expected to be rumoured after migration. +setup rumoured.kasp +echo "$zone" >>zones +Tds="now-2h" +Tkey="now-300s" +Tsig="now-11h" +ksktimes="-P ${Tkey} -A ${Tkey} -P sync ${Tds}" +zsktimes="-P ${Tkey} -A ${Tsig}" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2) +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" +$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 + +# Key states expected to be omnipresent after migration. +setup omnipresent.kasp +echo "$zone" >>zones +Tds="now-3h" # Time according to dnssec-policy that DS will be OMNIPRESENT +Tkey="now-3900s" # DNSKEY TTL + propagation delay +Tsig="now-12h" # Zone's maximum TTL + propagation delay +ksktimes="-P ${Tkey} -A ${Tkey} -P sync ${Tds}" +zsktimes="-P ${Tkey} -A ${Tsig}" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2) +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" +$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 + +# Key states expected to be omnipresent after migration, except DS because -P sync is missing. +setup no-syncpublish.kasp +echo "$zone" >>zones +Tsig="now-12h" # Zone's maximum TTL + propagation delay +ksktimes="-P ${Tsig} -A ${Tsig}" +zsktimes="-P ${Tsig} -A ${Tsig}" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 300 $zsktimes $zone 2>keygen.out.$zone.2) +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" +$SIGNER -S -x -s now-1h -e now+2w -o $zone -O full -f $zonefile $infile >signer.out.$zone.1 2>&1 diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/template.db.in bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns3/template.db.in 2025-10-18 10:16:12.418730052 +0000 @@ -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 mname1. . ( + 1 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + + NS ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/named.conf.j2 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,92 @@ +/* + * 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. + */ + +// NS4 + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +dnssec-policy "rsasha256" { + keys { + zsk key-directory lifetime P3M algorithm 8 2048; + ksk key-directory lifetime P1Y algorithm 8 2048; + }; + + dnskey-ttl 300; + publish-safety 1h; + retire-safety 1h; + + signatures-refresh 5d; + signatures-validity 14d; + signatures-validity-dnskey 14d; + + max-zone-ttl 1d; + zone-propagation-delay 300; + + parent-ds-ttl 86400; + parent-propagation-delay 3h; +}; + +key "external" { + algorithm @DEFAULT_HMAC@; + secret "YPfMoAk6h+3iN8MDRQC004iSNHY="; +}; + +key "internal" { + algorithm @DEFAULT_HMAC@; + secret "4xILSZQnuO1UKubXHkYUsvBRPu8="; +}; + +view "ext" { + match-clients { key "external"; }; + + zone "view-rsasha256.kasp" { + type primary; + file "view-rsasha256.kasp.ext.db"; + dnssec-policy "rsasha256"; + inline-signing no; + allow-update { any; }; + }; +}; + +view "int" { + match-clients { key "internal"; }; + + zone "view-rsasha256.kasp" { + type primary; + file "view-rsasha256.kasp.int.db"; + dnssec-policy "rsasha256"; + inline-signing no; + allow-update { any; }; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/setup.sh bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/setup.sh --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/setup.sh 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,46 @@ +#!/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 "ns4/setup.sh" + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +zone="view-rsasha256.kasp" +algo="RSASHA256" +num="8" +echo "$zone" >>zones + +# Set up zones in views with auto-dnssec maintain to migrate to dnssec-policy. +# The keys for these zones are in use long enough that they should start a +# rollover for the ZSK (P3M), but not long enough to initiate a KSK rollover (P1Y). +ksktimes="-P -93d -A -93d -P sync -93d" +zsktimes="-P -93d -A -93d" +KSK=$($KEYGEN -a $algo -L 300 -b 2048 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $algo -L 300 -b 2048 $zsktimes $zone 2>keygen.out.$zone.2) + +echo_i "setting up zone $zone (external)" +view="ext" +zonefile="${zone}.${view}.db" +cat template.$view.db.in "${KSK}.key" "${ZSK}.key" >"$zonefile" + +echo_i "setting up zone $zone (internal)" +view="int" +zonefile="${zone}.${view}.db" +cat template.$view.db.in "${KSK}.key" "${ZSK}.key" >"$zonefile" diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/template.ext.db.in bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/template.ext.db.in --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/template.ext.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/template.ext.db.in 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,28 @@ +; 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 ns4 +ns4 A 10.53.0.4 + +view TXT "external" + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/template.int.db.in bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/template.int.db.in --- bind9-9.20.11/bin/tests/system/migrate2kasp/ns4/template.int.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/ns4/template.int.db.in 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,28 @@ +; 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 ns4 +ns4 A 10.53.0.4 + +view TXT "internal" + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/setup.sh bind9-9.20.15/bin/tests/system/migrate2kasp/setup.sh --- bind9-9.20.11/bin/tests/system/migrate2kasp/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/setup.sh 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,27 @@ +#!/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 + +# Setup zones +( + cd ns3 + $SHELL setup.sh +) +( + cd ns4 + $SHELL setup.sh +) diff -Nru bind9-9.20.11/bin/tests/system/migrate2kasp/tests_migrate2kasp.py bind9-9.20.15/bin/tests/system/migrate2kasp/tests_migrate2kasp.py --- bind9-9.20.11/bin/tests/system/migrate2kasp/tests_migrate2kasp.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/migrate2kasp/tests_migrate2kasp.py 2025-10-18 10:16:12.418730052 +0000 @@ -0,0 +1,358 @@ +# 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 + +from datetime import timedelta + +import pytest + +pytest.importorskip("dns", minversion="2.0.0") +import isctest +import isctest.mark + +pytestmark = pytest.mark.extra_artifacts( + [ + "*.axfr", + "*.created", + "created.key-*", + "dig.out*", + "ns*/*.mkeys*", + "ns*/dsset-*", + "ns*/K*.key", + "ns*/K*.private", + "ns*/K*.state", + "ns*/kasp.conf", + "ns*/keygen.out*", + "ns*/managed-keys.bind*", + "ns*/named.conf", + "ns*/named.memstats", + "ns*/named.run", + "ns*/signer.out*", + "ns*/zones", + "ns*/*.db", + "ns*/*.db.infile", + "ns*/*.db.jbk", + "ns*/*.db.jnl", + "ns*/*.db.signed*", + "python.out.*", + "retired.*", + "rndc.dnssec.*", + "unused.key*", + "verify.out.*", + ] +) + +default_config = { + "dnskey-ttl": timedelta(hours=1), + "ds-ttl": timedelta(days=1), + "key-directory": "{keydir}", + "max-zone-ttl": timedelta(days=1), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(minutes=5), +} + +standard_config = { + "dnskey-ttl": timedelta(seconds=7200), + "ds-ttl": timedelta(days=1), + "key-directory": "{keydir}", + "max-zone-ttl": timedelta(days=1), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(minutes=5), +} + +timing_config = { + "dnskey-ttl": timedelta(seconds=300), + "ds-ttl": timedelta(seconds=7200), + "key-directory": "{keydir}", + "max-zone-ttl": timedelta(hours=11), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(seconds=3600), +} + +migrate_config = { + "dnskey-ttl": timedelta(seconds=300), + "ds-ttl": timedelta(seconds=7200), + "key-directory": "{keydir}", + "max-zone-ttl": timedelta(hours=11), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(seconds=3600), +} + +view_config = { + "dnskey-ttl": timedelta(seconds=300), + "ds-ttl": timedelta(seconds=86400), + "key-directory": "{keydir}", + "max-zone-ttl": timedelta(days=1), + "parent-propagation-delay": timedelta(hours=3), + "publish-safety": timedelta(hours=1), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(seconds=300), +} + +lifetime = { + "P60D": int(timedelta(days=60).total_seconds()), + "P3M": int(timedelta(days=31 * 3).total_seconds()), + "P1Y": int(timedelta(days=365).total_seconds()), +} + + +@pytest.mark.parametrize( + "params", + [ + # Testing good migration (KSK/ZSK). + pytest.param( + { + "zone": "migrate.kasp", + "policy": "migrate", + "server": "ns3", + "config": standard_config, + "offset": 0, + "key-properties": [ + f"ksk 0 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:rumoured", + f"zsk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured zrrsig:rumoured", + ], + }, + id="migrate.kasp", + ), + # Testing a good migration (CSK). + pytest.param( + { + "zone": "csk.kasp", + "policy": "default", + "server": "ns3", + "config": default_config, + "offset": 0, + "key-properties": [ + f"csk 0 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:rumoured", + ], + }, + id="csk.kasp", + ), + # Testing a good migration (CSK, no SEP). + pytest.param( + { + "zone": "csk-nosep.kasp", + "policy": "default", + "server": "ns3", + "config": default_config, + "offset": 0, + "key-properties": [ + f"csk 0 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:rumoured", + ], + }, + id="csk-nosep.kasp", + ), + # Testing key states derived from timing metadata: rumoured. + pytest.param( + { + "zone": "rumoured.kasp", + "policy": "timing-metadata", + "server": "ns3", + "config": timing_config, + "offset": -timedelta(seconds=300), + "key-properties": [ + f"ksk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:rumoured", + f"zsk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured zrrsig:rumoured", + ], + }, + id="rumoured.kasp", + ), + # Testing key states derived from timing metadata: omnipresent. + pytest.param( + { + "zone": "omnipresent.kasp", + "policy": "timing-metadata", + "server": "ns3", + "config": timing_config, + "offset": -timedelta(seconds=3900), + "key-properties": [ + f"ksk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + f"zsk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent", + ], + }, + id="omnipresent.kasp", + ), + # Testing key states derived from timing metadata: no SyncPublish. + pytest.param( + { + "zone": "no-syncpublish.kasp", + "policy": "timing-metadata", + "server": "ns3", + "config": timing_config, + "offset": -timedelta(hours=12), + "key-properties": [ + f"ksk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured", + f"zsk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent", + ], + }, + id="no-syncpublish.kasp", + ), + # Test migration to dnssec-policy, existing keys do not match key algorithm. + pytest.param( + { + "zone": "migrate-nomatch-algnum.kasp", + "policy": "migrate-nomatch-algnum", + "server": "ns3", + "config": migrate_config, + "offset": -timedelta(seconds=3900), + "key-properties": [ + "ksk - 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + "zsk - 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent", + f"ksk 0 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", + f"zsk {lifetime['P60D']} {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured zrrsig:rumoured", + ], + }, + id="migrate-nomatch-algnum.kasp", + ), + # Test migration to dnssec-policy, existing keys do not match key length. + pytest.param( + { + "zone": "migrate-nomatch-alglen.kasp", + "policy": "migrate-nomatch-alglen", + "server": "ns3", + "config": migrate_config, + "offset": -timedelta(seconds=3900), + "key-properties": [ + "ksk - 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + "zsk - 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent", + "ksk 0 8 3072 goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", + # This key is considered to be prepublished, so it is not yet signing. + f"zsk {lifetime['P60D']} 8 3072 goal:omnipresent dnskey:rumoured zrrsig:hidden", + ], + }, + id="migrate-nomatch-alglen.kasp", + ), + # Test migration to dnssec-policy, existing keys do not match role (KSK/ZSK -> CSK). + pytest.param( + { + "zone": "migrate-nomatch-kzc.kasp", + "policy": "migrate-nomatch-kzc", + "server": "ns3", + "config": migrate_config, + "offset": -timedelta(seconds=3900), + "key-properties": [ + f"ksk - {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + f"zsk - {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:hidden dnskey:omnipresent zrrsig:omnipresent", + # This key is considered to be prepublished, so it is not yet signing, nor is the DS introduced. + f"csk 0 {os.environ['DEFAULT_ALGORITHM_NUMBER']} {os.environ['DEFAULT_BITS']} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:hidden ds:hidden", + ], + }, + id="migrate-nomatch-kzc.kasp", + ), + # Test good migration with views. + pytest.param( + { + "zone": "view-rsasha256.kasp", + "policy": "rsasha256", + "server": "ns4", + "config": view_config, + "offset": -timedelta(days=31 * 3), + "key-properties": [ + f"zsk {lifetime['P3M']} 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent", + f"zsk {lifetime['P3M']} 8 2048 goal:omnipresent dnskey:rumoured zrrsig:hidden", + f"ksk {lifetime['P1Y']} 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + ], + "view": "ext", + "tsig": "external:YPfMoAk6h+3iN8MDRQC004iSNHY=", + }, + id="view-rsasha256.kasp (external)", + ), + pytest.param( + { + "zone": "view-rsasha256.kasp", + "policy": "rsasha256", + "server": "ns4", + "config": view_config, + "offset": -timedelta(days=31 * 3), + "key-properties": [ + f"zsk {lifetime['P3M']} 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent", + f"zsk {lifetime['P3M']} 8 2048 goal:omnipresent dnskey:rumoured zrrsig:hidden", + f"ksk {lifetime['P1Y']} 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + ], + "view": "int", + "tsig": "internal:4xILSZQnuO1UKubXHkYUsvBRPu8=", + }, + id="view-rsasha256.kasp (internal)", + ), + ], +) +def test_migrate2kasp_case(servers, params): + # Get test parameters. + zone = params["zone"] + policy = params["policy"] + server = servers[params["server"]] + keydir = server.identifier + view = params.get("view", None) + tsig = None + if "tsig" in params: + secret = params["tsig"] + tsig = f"{os.environ['DEFAULT_HMAC']}:{secret}" + + isctest.kasp.wait_keymgr_done(server, zone) + + params["config"]["key-directory"] = params["config"]["key-directory"].replace( + "{keydir}", keydir + ) + ttl = int(params["config"]["dnskey-ttl"].total_seconds()) + + # Test case. + isctest.log.info(f"check test case zone {zone} policy {policy}") + + # First make sure the zone is signed. + isctest.kasp.check_dnssec_verify(server, zone, tsig=tsig) + + # Key properties. + expected = isctest.kasp.policy_to_properties(ttl=ttl, keys=params["key-properties"]) + + # Special case: CSK without SEP bit set. + if zone == "csk-nosep.kasp": + expected[0].properties["role_full"] = "zone-signing" + expected[0].properties["flags"] = 256 + + # Key files. + keys = isctest.kasp.keydir_to_keylist(zone, params["config"]["key-directory"]) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + isctest.kasp.check_keys(zone, keys, expected) + + offset = params["offset"] if "offset" in params else None + + for expect in expected: + expect.set_expected_keytimes(params["config"], offset=offset, migrate=True) + + isctest.kasp.check_dnssecstatus(server, zone, ksks + zsks, policy=policy, view=view) + isctest.kasp.check_apex(server, zone, ksks, zsks, tsig=tsig) + isctest.kasp.check_subdomain(server, zone, ksks, zsks, tsig=tsig) + + if "additional-tests" in params: + for additional_test in params["additional-tests"]: + callback = additional_test["callback"] + arguments = additional_test["arguments"] + callback(*arguments, params=params, ksks=ksks, zsks=zsks) diff -Nru bind9-9.20.11/bin/tests/system/mirror-root-zone/tests_mirror_root_zone.py bind9-9.20.15/bin/tests/system/mirror-root-zone/tests_mirror_root_zone.py --- bind9-9.20.11/bin/tests/system/mirror-root-zone/tests_mirror_root_zone.py 2025-07-04 09:42:08.197324948 +0000 +++ bind9-9.20.15/bin/tests/system/mirror-root-zone/tests_mirror_root_zone.py 2025-10-18 10:16:12.418730052 +0000 @@ -9,19 +9,16 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -from typing import Dict - from isctest.instance import NamedInstance from isctest.mark import live_internet_test @live_internet_test -def test_mirror_root_zone(servers: Dict[str, NamedInstance]): +def test_mirror_root_zone(ns1: NamedInstance): """ This test pulls the root zone from the Internet, so let's only run it when CI_ENABLE_LIVE_INTERNET_TESTS is set. """ - ns1 = servers["ns1"] with ns1.watch_log_from_start() as watch_log: # TimeoutError is raised if the line is not found and the test will fail. watch_log.wait_for_line("Transfer status: success") diff -Nru bind9-9.20.11/bin/tests/system/mkeys/ns1/named1.conf.in bind9-9.20.15/bin/tests/system/mkeys/ns1/named1.conf.in --- bind9-9.20.11/bin/tests/system/mkeys/ns1/named1.conf.in 2025-07-04 09:42:08.198324972 +0000 +++ bind9-9.20.15/bin/tests/system/mkeys/ns1/named1.conf.in 2025-10-18 10:16:12.420730083 +0000 @@ -28,11 +28,10 @@ listen-on-v6 { none; }; recursion no; notify no; - dnssec-validation yes; + dnssec-validation no; allow-query { allowed; }; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/mkeys/ns1/named2.conf.in bind9-9.20.15/bin/tests/system/mkeys/ns1/named2.conf.in --- bind9-9.20.11/bin/tests/system/mkeys/ns1/named2.conf.in 2025-07-04 09:42:08.198324972 +0000 +++ bind9-9.20.15/bin/tests/system/mkeys/ns1/named2.conf.in 2025-10-18 10:16:12.420730083 +0000 @@ -28,11 +28,10 @@ listen-on-v6 { none; }; recursion no; notify no; - dnssec-validation yes; + dnssec-validation no; allow-query { allowed; }; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/mkeys/ns1/named3.conf.in bind9-9.20.15/bin/tests/system/mkeys/ns1/named3.conf.in --- bind9-9.20.11/bin/tests/system/mkeys/ns1/named3.conf.in 2025-07-04 09:42:08.198324972 +0000 +++ bind9-9.20.15/bin/tests/system/mkeys/ns1/named3.conf.in 2025-10-18 10:16:12.420730083 +0000 @@ -23,10 +23,9 @@ listen-on-v6 { none; }; recursion no; notify no; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/mkeys/tests_sh_mkeys.py bind9-9.20.15/bin/tests/system/mkeys/tests_sh_mkeys.py --- bind9-9.20.11/bin/tests/system/mkeys/tests_sh_mkeys.py 2025-07-04 09:42:08.200325018 +0000 +++ bind9-9.20.15/bin/tests/system/mkeys/tests_sh_mkeys.py 2025-10-18 10:16:12.422730114 +0000 @@ -11,8 +11,6 @@ import pytest -import isctest.mark - pytestmark = [ pytest.mark.algorithm_set("ecc_default"), pytest.mark.extra_artifacts( @@ -52,6 +50,6 @@ ] -@isctest.mark.flaky(max_runs=2) # GL#3098 +@pytest.mark.flaky(max_runs=2) # GL#3098 def test_mkeys(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/names/tests_names.py bind9-9.20.15/bin/tests/system/names/tests_names.py --- bind9-9.20.11/bin/tests/system/names/tests_names.py 2025-07-04 09:42:08.202325065 +0000 +++ bind9-9.20.15/bin/tests/system/names/tests_names.py 2025-10-18 10:16:12.424730145 +0000 @@ -13,8 +13,6 @@ pytest.importorskip("dns", minversion="2.7.0") - -import dns.message import isctest @@ -22,7 +20,7 @@ # about twice as large as the answer with compression enabled, while # maintaining identical content. def test_names(): - msg = dns.message.make_query("example.", "MX") + msg = isctest.query.create("example.", "MX") # Getting message size with compression enabled res_enabled = isctest.query.tcp(msg, ip="10.53.0.1", source="10.53.0.1") # Getting message size with compression disabled diff -Nru bind9-9.20.11/bin/tests/system/nsec3-answer/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/nsec3-answer/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/nsec3-answer/ns1/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/nsec3-answer/ns1/named.conf.j2 2025-10-18 10:16:12.427730191 +0000 @@ -0,0 +1,31 @@ +/* + * 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. + */ + +// NS1 + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; + dnssec-validation no; +}; + +zone "." { + type primary; + file "root.db.signed"; +}; diff -Nru bind9-9.20.11/bin/tests/system/nsec3-answer/ns1/root.db.in bind9-9.20.15/bin/tests/system/nsec3-answer/ns1/root.db.in --- bind9-9.20.11/bin/tests/system/nsec3-answer/ns1/root.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/nsec3-answer/ns1/root.db.in 2025-10-18 10:16:12.427730191 +0000 @@ -0,0 +1,51 @@ +; 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 . . ( + 2025063000 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. + +02hc3em7bdd011a0gms3hkkjt2if5vp8. A 10.0.0.0 +a. A 10.0.0.1 +*.a.a. A 10.0.0.6 +a.a.a.a. A 10.0.0.3 +b. A 10.0.0.2 +b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b.b. A 10.0.0.2 +cname. CNAME does-not-exist. +cname.cname. CNAME cname. +cname.ent.cname. CNAME cname.cname. +d. A 10.0.0.4 +dname-to-nowhere. DNAME does-not-exist. +; DNAME owner longer than target to avoid YXDOMAIN dependent on QNAME +insecure. NS a.root-servers.nil. +ns.insecure. A 10.53.0.3 +a.root-servers.nil. A 10.53.0.1 +secure. NS a.root-servers.nil. +secure. DS 11111 13 255 00 +occluded.secure. A 0.0.0.0 +*.wild. A 10.0.0.6 +explicit.wild. A 192.0.2.66 +z. A 10.0.0.26 + +; randomly generated subtree to excercise unknown corner cases +; intentionally small, to not blow up algorithms with quadratic complexity in ZoneAnalyzer and name generator +a.a.a.b.a.a.a.b.a.a.b.b.a.random. TXT "r" +b.b.a.a.b.b.a.a.a.b.b.a.b.a.a.a.a.a.b.a.a.b.a.b.a.b.b.b.b.b.a.a.a.a.b.a.a.a.b.a.a.b.b.a.random. TXT "r" +a.a.a.b.b.a.b.b.a.b.a.b.a.b.a.b.b.b.a.random. TXT "r" +b.b.a.b.a.b.a.a.a.b.a.a.b.a.a.a.a.b.b.a.b.b.a.b.a.b.a.b.a.b.b.b.a.random. TXT "r" +a.b.a.a.b.a.b.a.b.a.a.b.a.b.a.a.a.b.b.a.b.b.a.a.b.b.a.a.b.a.b.a.b.b.b.b.a.a.a.a.a.a.a.a.b.a.b.a.b.b.a.b.a.b.a.a.a.b.a.a.b.a.a.a.a.b.b.a.b.b.a.b.a.b.a.b.a.b.b.b.a.random. TXT "r" +a.a.a.a.a.b.b.a.a.a.a.a.b.b.a.a.b.a.a.b.a.a.b.b.a.a.a.b.a.a.a.b.b.b.b.b.a.a.a.b.b.b.b.b.b.a.b.b.b.a.a.b.b.b.b.a.a.a.a.b.a.b.b.a.b.a.a.b.b.b.b.b.b.b.a.b.b.a.b.a.b.a.a.a.b.b.a.a.b.b.a.b.a.b.b.a.b.b.b.a.b.b.b.b.b.a.a.b.a.a.a.b.b.a.a.a.b.b.b.b.b.a.random. TXT "r" diff -Nru bind9-9.20.11/bin/tests/system/nsec3-answer/ns1/sign.sh bind9-9.20.15/bin/tests/system/nsec3-answer/ns1/sign.sh --- bind9-9.20.11/bin/tests/system/nsec3-answer/ns1/sign.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/nsec3-answer/ns1/sign.sh 2025-10-18 10:16:12.427730191 +0000 @@ -0,0 +1,34 @@ +#!/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 + +zone=. +infile=root.db.in +zonefile=root.db + +echo_i "ns1/sign.sh" + +ksk=$("$KEYGEN" -q -fk -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone") +zsk=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" "$zone") + +cat "$infile" "$ksk.key" "$zsk.key" >"$zonefile" + +SALT="$(printf "%04x" "$(($(date +%s) / 3600 % 65536))")" +echo_ic "NSEC3 salt for this hour: $SALT" +"$SIGNER" -3 "$SALT" -o "$zone" "$zonefile" 2>&1 >"$zonefile.sign.log" + +keyfile_to_initial_ds "$ksk" >managed-keys.conf diff -Nru bind9-9.20.11/bin/tests/system/nsec3-answer/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/nsec3-answer/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/nsec3-answer/ns2/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/nsec3-answer/ns2/named.conf.j2 2025-10-18 10:16:12.427730191 +0000 @@ -0,0 +1,39 @@ +/* + * 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. + */ + +// validating resolver + +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; }; + recursion yes; + dnssec-validation yes; +}; + +controls { + inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +include "../../_common/rndc.key"; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + +include "../ns1/managed-keys.conf"; diff -Nru bind9-9.20.11/bin/tests/system/nsec3-answer/setup.sh bind9-9.20.15/bin/tests/system/nsec3-answer/setup.sh --- bind9-9.20.11/bin/tests/system/nsec3-answer/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/nsec3-answer/setup.sh 2025-10-18 10:16:12.427730191 +0000 @@ -0,0 +1,22 @@ +#!/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 + +( + cd ns1 + $SHELL sign.sh +) diff -Nru bind9-9.20.11/bin/tests/system/nsec3-answer/tests_nsec3.py bind9-9.20.15/bin/tests/system/nsec3-answer/tests_nsec3.py --- bind9-9.20.11/bin/tests/system/nsec3-answer/tests_nsec3.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/nsec3-answer/tests_nsec3.py 2025-10-18 10:16:12.428730207 +0000 @@ -0,0 +1,410 @@ +#!/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. + +from dataclasses import dataclass +import os +from pathlib import Path +from typing import Optional, Set, Tuple + +import pytest + +pytest.importorskip("dns", minversion="2.5.0") +import dns.dnssec +import dns.message +import dns.name +import dns.query +import dns.rcode +import dns.rdataclass +import dns.rdatatype +import dns.rdtypes.ANY.RRSIG +import dns.rdtypes.ANY.NSEC3 +import dns.rrset + +from isctest.hypothesis.strategies import dns_names, sampled_from +import isctest +import isctest.name + +from hypothesis import assume, given + +SUFFIX = dns.name.from_text(".") +AUTH = "10.53.0.1" +RESOLVER = "10.53.0.2" +TIMEOUT = 5 +ZONE = isctest.name.ZoneAnalyzer.read_path( + Path(os.environ["srcdir"]) / "nsec3-answer/ns1/root.db.in", origin=SUFFIX +) + + +def do_test_query( + qname: dns.name.Name, qtype: dns.rdatatype.RdataType, server: str, named_port: int +) -> Tuple[dns.message.QueryMessage, "NSEC3Checker"]: + query = dns.message.make_query(qname, qtype, use_edns=True, want_dnssec=True) + response = isctest.query.tcp(query, server, named_port, timeout=TIMEOUT) + isctest.check.is_response_to(response, query) + assert response.rcode() in (dns.rcode.NOERROR, dns.rcode.NXDOMAIN) + return response, NSEC3Checker(response) + + +@pytest.mark.parametrize( + "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")] +) +@given( + qname=sampled_from( + sorted(ZONE.reachable - ZONE.get_names_with_type(dns.rdatatype.CNAME)) + ) +) +def test_nodata(server: str, qname: dns.name.Name, named_port: int) -> None: + """An existing name, no wildcards, but a query type for RRset which does not exist""" + _, nsec3check = do_test_query(qname, dns.rdatatype.HINFO, server, named_port) + check_nodata(qname, nsec3check) + + +@pytest.mark.parametrize("server", [pytest.param(AUTH, id="ns1")]) +@given( + qname=dns_names( + suffix=(ZONE.delegations - ZONE.get_names_with_type(dns.rdatatype.DS)) + ) +) +def test_nodata_ds(server: str, qname: dns.name.Name, named_port: int) -> None: + """Auth sends proof of nonexistance with referral without DS RR. Opt-out is not supported.""" + response, nsec3check = do_test_query(qname, dns.rdatatype.HINFO, server, named_port) + + nsrr = None + for rrset in response.authority: + if rrset.rdtype == dns.rdatatype.NS: + nsrr = rrset + break + assert nsrr is not None, "NS RRset missing in delegation answer" + + # DS RR does not exist so we must prove it by having NSEC3 with QNAME + check_nodata(nsrr.name, nsec3check) + + +def check_nodata(name: dns.name.Name, nsec3check: "NSEC3Checker") -> None: + assert nsec3check.response.rcode() is dns.rcode.NOERROR + + nsec3check.prove_name_exists(name) + nsec3check.check_extraneous_rrs() + + +def assume_nx_and_no_delegation(qname: dns.name.Name) -> None: + assume(qname not in ZONE.all_existing_names) + + # name must not be under a delegation or DNAME: + # it would not work with resolver ns2 + assume( + not isctest.name.is_related_to_any( + qname, + (dns.name.NameRelation.EQUAL, dns.name.NameRelation.SUBDOMAIN), + ZONE.reachable_delegations.union(ZONE.reachable_dnames), + ) + ) + + +@pytest.mark.parametrize( + "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")] +) +@given(qname=dns_names(suffix=SUFFIX)) +def test_nxdomain(server: str, qname: dns.name.Name, named_port: int) -> None: + """A real NXDOMAIN, no wildcards involved""" + assume_nx_and_no_delegation(qname) + wname = ZONE.source_of_synthesis(qname) + assume(wname not in ZONE.reachable_wildcards) + + _, nsec3check = do_test_query(qname, dns.rdatatype.A, server, named_port) + check_nxdomain(qname, nsec3check) + + +@pytest.mark.parametrize( + "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")] +) +@given(qname=sampled_from(sorted(ZONE.get_names_with_type(dns.rdatatype.CNAME)))) +def test_cname_nxdomain(server: str, qname: dns.name.Name, named_port: int) -> None: + """CNAME which terminates by NXDOMAIN, no wildcards involved""" + response, nsec3check = do_test_query(qname, dns.rdatatype.A, server, named_port) + chain = response.resolve_chaining() + assume_nx_and_no_delegation(chain.canonical_name) + + wname = ZONE.source_of_synthesis(chain.canonical_name) + assume(wname not in ZONE.reachable_wildcards) + + check_nxdomain(chain.canonical_name, nsec3check) + + +@pytest.mark.parametrize( + "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")] +) +@given(qname=dns_names(suffix=ZONE.get_names_with_type(dns.rdatatype.DNAME))) +def test_dname_nxdomain(server: str, qname: dns.name.Name, named_port: int) -> None: + """DNAME which terminates by NXDOMAIN, no wildcards involved""" + assume(qname not in ZONE.reachable) + + response, nsec3check = do_test_query(qname, dns.rdatatype.A, server, named_port) + chain = response.resolve_chaining() + assume_nx_and_no_delegation(chain.canonical_name) + + wname = ZONE.source_of_synthesis(chain.canonical_name) + assume(wname not in ZONE.reachable_wildcards) + + check_nxdomain(chain.canonical_name, nsec3check) + + +@pytest.mark.parametrize( + "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")] +) +@given(qname=dns_names(suffix=ZONE.ents)) +def test_ents(server: str, qname: dns.name.Name, named_port: int) -> None: + """ENT can have a wildcard under it""" + assume_nx_and_no_delegation(qname) + + _, nsec3check = do_test_query(qname, dns.rdatatype.A, server, named_port) + + wname = ZONE.source_of_synthesis(qname) + # does qname match a wildcard under ENT? + if wname in ZONE.reachable_wildcards: + check_wildcard_synthesis(qname, nsec3check) + else: + check_nxdomain(qname, nsec3check) + + +@pytest.mark.parametrize( + "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")] +) +@given(qname=dns_names(suffix=ZONE.reachable_wildcard_parents)) +def test_wildcard_synthesis(server: str, qname: dns.name.Name, named_port: int) -> None: + assume(qname not in ZONE.all_existing_names) + + wname = ZONE.source_of_synthesis(qname) + assume(wname in ZONE.reachable_wildcards) + + _, nsec3check = do_test_query(qname, dns.rdatatype.A, server, named_port) + check_wildcard_synthesis(qname, nsec3check) + + +@pytest.mark.parametrize( + "server", [pytest.param(AUTH, id="ns1"), pytest.param(RESOLVER, id="ns2")] +) +@given(qname=dns_names(suffix=ZONE.reachable_wildcard_parents)) +def test_wildcard_nodata(server: str, qname: dns.name.Name, named_port: int) -> None: + assume(qname not in ZONE.all_existing_names) + + wname = ZONE.source_of_synthesis(qname) + assume(wname in ZONE.reachable_wildcards) + + _, nsec3check = do_test_query(qname, dns.rdatatype.AAAA, server, named_port) + check_wildcard_nodata(qname, nsec3check) + + +def check_wildcard_nodata(qname: dns.name.Name, nsec3check: "NSEC3Checker") -> None: + assert nsec3check.response.rcode() is dns.rcode.NOERROR + + ce, nce = ZONE.closest_encloser(qname) + nsec3check.prove_name_exists(ce) + nsec3check.prove_name_does_not_exist(nce) + + wname = ZONE.source_of_synthesis(qname) + # expecting proof that wildcard owner does not have rdatatype requested + nsec3check.prove_name_exists(wname) + nsec3check.check_extraneous_rrs() + + +def check_nxdomain(qname: dns.name.Name, nsec3check: "NSEC3Checker") -> None: + assert nsec3check.response.rcode() is dns.rcode.NXDOMAIN + + ce, nce = ZONE.closest_encloser(qname) + nsec3check.prove_name_exists(ce) + nsec3check.prove_name_does_not_exist(nce) + + wname = ZONE.source_of_synthesis(qname) + nsec3check.prove_name_does_not_exist(wname) + nsec3check.check_extraneous_rrs() + + +def check_wildcard_synthesis(qname: dns.name.Name, nsec3check: "NSEC3Checker") -> None: + """Expect wildcard response with a signed A RRset""" + assert nsec3check.response.rcode() is dns.rcode.NOERROR + + answer_sig = nsec3check.response.get_rrset( + section="ANSWER", + name=qname, + rdclass=dns.rdataclass.IN, + rdtype=dns.rdatatype.RRSIG, + covers=dns.rdatatype.A, + ) + assert answer_sig is not None + assert len(answer_sig) == 1 + rrsig = answer_sig[0] + assert isinstance(rrsig, dns.rdtypes.ANY.RRSIG.RRSIG) + # RRSIG labels field RFC 4034 section 3.1.3 does not count: + # - root label + # - leftmost * label + wildcard_parent_labels = rrsig.labels + 1 # add root but not leftmost * + assert wildcard_parent_labels < len(qname) + + # 1. We have RRSIG from the wildcard '*.something', which proves the node + # 'something' exists (by definition - it has a child, so it exists, but + # maybe it is an ENT). Thus we expect closest encloser = 'something' + # 2. If wildcard synthesis is legitimate, QNAME itself and no nodes between + # QNAME and the closest encloser can exist. Because of DNS node existence + # rules it's sufficient to prove non-existence of next-closer name, i.e. + # ., to deny existence of the whole + # subtree down to QNAME. + + ce, nce = ZONE.closest_encloser(qname) + assert ce == qname.split(wildcard_parent_labels)[1] + # ce is proven to exist by the RRSIG + assert nce == qname.split(wildcard_parent_labels + 1)[1] + nsec3check.prove_name_does_not_exist(nce) + nsec3check.check_extraneous_rrs() + + +@dataclass(frozen=True) +class NSEC3Params: + """Common values from a single DNS response""" + + algorithm: int + flags: int + iterations: int + salt: Optional[bytes] + + +class NSEC3Checker: + def __init__(self, response: dns.message.Message): + for rrset in response.answer: + assert not rrset.match( + dns.rdataclass.IN, dns.rdatatype.NSEC3, dns.rdatatype.NONE + ), f"unexpected NSEC3 RR in ANSWER section:\n{response}" + for rrset in response.additional: + assert not rrset.match( + dns.rdataclass.IN, dns.rdatatype.NSEC3, dns.rdatatype.NONE + ), f"unexpected NSEC3 RR in ADDITIONAL section:\n{response}" + + attrs_seen = { + "algorithm": None, + "flags": None, + "iterations": None, + "salt": None, + } + first = True + owners_seen = set() + self.rrsets = [] + for rrset in response.authority: + if not rrset.match( + dns.rdataclass.IN, dns.rdatatype.NSEC3, dns.rdatatype.NONE + ): + continue + assert ( + rrset.name not in owners_seen + ), f"duplicate NSEC3 owner {rrset.name}:\n{response}" + owners_seen.add(rrset.name) + + assert len(rrset) == 1 + rr = rrset[0] + assert isinstance(rr, dns.rdtypes.ANY.NSEC3.NSEC3) + + assert ( + "NSEC3" + not in dns.rdtypes.ANY.NSEC3.Bitmap(rr.windows).to_text().split() + ), f"NSEC3 RRset with NSEC3 in type bitmap:\n{response}" + + # NSEC3 parameters MUST be consistent across all NSEC3 RRs: + # RFC 5155 section 7.2, last paragraph + for attr_name, value_seen in attrs_seen.items(): + current = getattr(rr, attr_name) + if first: + attrs_seen[attr_name] = current + else: + assert ( + current == value_seen + ), f"inconsistent {attr_name}\n{response}" + first = False + self.rrsets.append(rrset) + + assert attrs_seen["algorithm"] is not None, f"no NSEC3 found\n{response}" + self.params: NSEC3Params = NSEC3Params(**attrs_seen) + self.response: dns.message.Message = response + self.owners_present: Set[dns.name.Name] = owners_seen + self.owners_used: Set[dns.name.Name] = set() + + @staticmethod + def nsec3_covers(rrset: dns.rrset.RRset, hashed_name: dns.name.Name) -> bool: + """ + Test if 'hashed_name' is covered by an NSEC3 record in 'rrset', i.e. the name does not exist. + """ + prev_name = rrset.name + + assert len(rrset) == 1 + nsec3 = rrset[0] + assert isinstance(nsec3, dns.rdtypes.ANY.NSEC3.NSEC3) + assert nsec3.flags == 0, "opt-out not supported by test logic" + next_name = nsec3.next_name(SUFFIX) + + # Single name case. + if prev_name == next_name: + return prev_name != hashed_name + + # Standard case. + if prev_name < next_name: + if prev_name < hashed_name < next_name: + return True + + # The cover wraps. + if next_name < prev_name: + # Case 1: The covered name is at the end of the chain. + if hashed_name > prev_name: + return True + # Case 2: The covered name is at the start of the chain. + if hashed_name < next_name: + return True + return False + + def hash_name(self, name: dns.name.Name) -> dns.name.Name: + nhash = dns.dnssec.nsec3_hash( + name, + salt=self.params.salt, + iterations=self.params.iterations, + algorithm=self.params.algorithm, + ) + return dns.name.from_text(nhash, SUFFIX) + + def prove_name_does_not_exist(self, name: dns.name.Name) -> dns.rrset.RRset: + """Hash of a given name must fall between an NSEC3 owner and 'next' name""" + hashed_name = self.hash_name(name) + for rrset in self.rrsets: + name_is_covered = self.nsec3_covers(rrset, hashed_name) + if name_is_covered: + self.owners_used.add(rrset.name) + return rrset + + assert ( + False + ), f"Expected covering NSEC3 for {name} (hash={hashed_name}) not found:\n{self.response}" + + def prove_name_exists(self, owner: dns.name.Name) -> dns.rrset.RRset: + """Check response has NSEC3 RR matching given owner name, i.e. the name exists.""" + nsec3_owner = self.hash_name(owner) + for rrset in self.rrsets: + if rrset.match( + nsec3_owner, dns.rdataclass.IN, dns.rdatatype.NSEC3, dns.rdatatype.NONE + ): + self.owners_used.add(rrset.name) + return rrset + assert ( + False + ), f"Expected matching NSEC3 for {owner} (hash={nsec3_owner}) not found:\n{self.response}" + + def check_extraneous_rrs(self) -> None: + """Check that all NSEC3 RRs present in the message were actually needed for proofs""" + assert ( + self.owners_used == self.owners_present + ), f"extraneous NSEC3 RRs detected\n{self.response}" diff -Nru bind9-9.20.11/bin/tests/system/nsupdate/ns3/named.conf.in bind9-9.20.15/bin/tests/system/nsupdate/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/nsupdate/ns3/named.conf.in 2025-07-04 09:42:08.212325299 +0000 +++ bind9-9.20.15/bin/tests/system/nsupdate/ns3/named.conf.in 2025-10-18 10:16:12.434730300 +0000 @@ -23,10 +23,9 @@ listen-on-v6 { none; }; recursion no; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/nsupdate/tests_sh_nsupdate.py bind9-9.20.15/bin/tests/system/nsupdate/tests_sh_nsupdate.py --- bind9-9.20.11/bin/tests/system/nsupdate/tests_sh_nsupdate.py 2025-07-04 09:42:08.215325370 +0000 +++ bind9-9.20.15/bin/tests/system/nsupdate/tests_sh_nsupdate.py 2025-10-18 10:16:12.437730347 +0000 @@ -13,8 +13,6 @@ import pytest -import isctest.mark - pytestmark = pytest.mark.extra_artifacts( [ "Kxxx*", @@ -80,6 +78,6 @@ MAX_RUNS = 2 if platform.system() == "FreeBSD" else 1 # GL#3846 -@isctest.mark.flaky(max_runs=MAX_RUNS) +@pytest.mark.flaky(max_runs=MAX_RUNS) def test_nsupdate(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/nzd2nzf/tests_nzd2nzf.py bind9-9.20.15/bin/tests/system/nzd2nzf/tests_nzd2nzf.py --- bind9-9.20.11/bin/tests/system/nzd2nzf/tests_nzd2nzf.py 2025-07-04 09:42:08.215325370 +0000 +++ bind9-9.20.15/bin/tests/system/nzd2nzf/tests_nzd2nzf.py 2025-10-18 10:16:12.437730347 +0000 @@ -17,8 +17,6 @@ import isctest.mark import isctest.run -import dns.message - pytestmark = [ isctest.mark.with_lmdb, pytest.mark.extra_artifacts( @@ -27,22 +25,22 @@ ] -def test_nzd2nzf(servers): +def test_nzd2nzf(ns1): zone_data = '"added.example" { type primary; file "added.db"; };' - msg = dns.message.make_query("a.added.example.", "A") + msg = isctest.query.create("a.added.example.", "A") # query for non-existing zone data - res = isctest.query.tcp(msg, servers["ns1"].ip) + res = isctest.query.tcp(msg, ns1.ip) isctest.check.refused(res) # add new zone into the default NZD using "rndc addzone" - servers["ns1"].rndc(f"addzone {zone_data}", log=False) + ns1.rndc(f"addzone {zone_data}", log=False) # query for existing zone data - res = isctest.query.tcp(msg, servers["ns1"].ip) + res = isctest.query.tcp(msg, ns1.ip) isctest.check.noerror(res) - servers["ns1"].stop() + ns1.stop() # dump "_default.nzd" to "_default.nzf" and check that it contains the expected content cfg_dir = "ns1" @@ -59,8 +57,8 @@ os.remove(nzd_filename) # start ns1 again, it should migrate "_default.nzf" to "_default.nzd" - servers["ns1"].start(["--noclean", "--restart", "--port", os.environ["PORT"]]) + ns1.start(["--noclean", "--restart", "--port", os.environ["PORT"]]) # query for zone data from the migrated zone config - res = isctest.query.tcp(msg, servers["ns1"].ip) + res = isctest.query.tcp(msg, ns1.ip) isctest.check.noerror(res) diff -Nru bind9-9.20.11/bin/tests/system/pipelined/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/pipelined/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/pipelined/ns2/named.conf.j2 2025-07-04 09:42:08.218325440 +0000 +++ bind9-9.20.15/bin/tests/system/pipelined/ns2/named.conf.j2 2025-10-18 10:16:12.440730393 +0000 @@ -20,11 +20,10 @@ listen-on { 10.53.0.2; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/pipelined/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/pipelined/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/pipelined/ns3/named.conf.j2 2025-07-04 09:42:08.219325463 +0000 +++ bind9-9.20.15/bin/tests/system/pipelined/ns3/named.conf.j2 2025-10-18 10:16:12.441730409 +0000 @@ -20,11 +20,10 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/pipelined/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/pipelined/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/pipelined/ns4/named.conf.j2 2025-07-04 09:42:08.219325463 +0000 +++ bind9-9.20.15/bin/tests/system/pipelined/ns4/named.conf.j2 2025-10-18 10:16:12.441730409 +0000 @@ -21,11 +21,10 @@ listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/proxy/ns1/named.conf.in bind9-9.20.15/bin/tests/system/proxy/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/proxy/ns1/named.conf.in 2025-07-04 09:42:08.219325463 +0000 +++ bind9-9.20.15/bin/tests/system/proxy/ns1/named.conf.in 2025-10-18 10:16:12.441730409 +0000 @@ -50,11 +50,10 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; }; -trust-anchors { }; zone "example0" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/proxy/ns3/named.conf.in bind9-9.20.15/bin/tests/system/proxy/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/proxy/ns3/named.conf.in 2025-07-04 09:42:08.219325463 +0000 +++ bind9-9.20.15/bin/tests/system/proxy/ns3/named.conf.in 2025-10-18 10:16:12.441730409 +0000 @@ -45,11 +45,10 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/qmin/tests_sh_qmin.py bind9-9.20.15/bin/tests/system/qmin/tests_sh_qmin.py --- bind9-9.20.11/bin/tests/system/qmin/tests_sh_qmin.py 2025-07-04 09:42:08.222325534 +0000 +++ bind9-9.20.15/bin/tests/system/qmin/tests_sh_qmin.py 2025-10-18 10:16:12.444730456 +0000 @@ -11,8 +11,6 @@ import pytest -import isctest.mark - pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", @@ -25,6 +23,6 @@ # The qmin test is inherently unstable, see GL #904 for details. -@isctest.mark.flaky(max_runs=3) +@pytest.mark.flaky(max_runs=3) def test_qmin(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/query-source/tests_querysource_none.py bind9-9.20.15/bin/tests/system/query-source/tests_querysource_none.py --- bind9-9.20.11/bin/tests/system/query-source/tests_querysource_none.py 2025-07-04 09:42:08.223325557 +0000 +++ bind9-9.20.15/bin/tests/system/query-source/tests_querysource_none.py 2025-10-18 10:16:12.445730471 +0000 @@ -12,10 +12,9 @@ # information regarding copyright ownership. import pytest + import isctest -pytest.importorskip("dns") -import dns.message pytestmark = pytest.mark.extra_artifacts( [ @@ -26,7 +25,7 @@ def test_querysource_none(): - msg = dns.message.make_query("example.", "A", want_dnssec=False) + msg = isctest.query.create("example.", "A", dnssec=False) res = isctest.query.udp(msg, "10.53.0.2") isctest.check.noerror(res) @@ -43,7 +42,7 @@ # using a different name below to make sure we don't use the # resolver cache - msg = dns.message.make_query("exampletwo.", "A", want_dnssec=False) + msg = isctest.query.create("exampletwo.", "A", dnssec=False) res = isctest.query.udp(msg, "fd92:7065:b8e:ffff::2") isctest.check.noerror(res) diff -Nru bind9-9.20.11/bin/tests/system/reclimit/ns3/named1.conf.in bind9-9.20.15/bin/tests/system/reclimit/ns3/named1.conf.in --- bind9-9.20.11/bin/tests/system/reclimit/ns3/named1.conf.in 2025-07-04 09:42:08.224325580 +0000 +++ bind9-9.20.15/bin/tests/system/reclimit/ns3/named1.conf.in 2025-10-18 10:16:12.447730502 +0000 @@ -25,10 +25,9 @@ max-recursion-queries 50; max-recursion-depth 12; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/reclimit/ns3/named2.conf.in bind9-9.20.15/bin/tests/system/reclimit/ns3/named2.conf.in --- bind9-9.20.11/bin/tests/system/reclimit/ns3/named2.conf.in 2025-07-04 09:42:08.224325580 +0000 +++ bind9-9.20.15/bin/tests/system/reclimit/ns3/named2.conf.in 2025-10-18 10:16:12.447730502 +0000 @@ -24,10 +24,9 @@ qname-minimization disabled; max-recursion-depth 5; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/reclimit/ns3/named3.conf.in bind9-9.20.15/bin/tests/system/reclimit/ns3/named3.conf.in --- bind9-9.20.11/bin/tests/system/reclimit/ns3/named3.conf.in 2025-07-04 09:42:08.225325604 +0000 +++ bind9-9.20.15/bin/tests/system/reclimit/ns3/named3.conf.in 2025-10-18 10:16:12.447730502 +0000 @@ -25,10 +25,9 @@ max-recursion-depth 100; max-recursion-queries 50; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/reclimit/ns3/named4.conf.in bind9-9.20.15/bin/tests/system/reclimit/ns3/named4.conf.in --- bind9-9.20.11/bin/tests/system/reclimit/ns3/named4.conf.in 2025-07-04 09:42:08.225325604 +0000 +++ bind9-9.20.15/bin/tests/system/reclimit/ns3/named4.conf.in 2025-10-18 10:16:12.447730502 +0000 @@ -25,10 +25,9 @@ max-recursion-depth 100; max-recursion-queries 40; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/reclimit/ns3/named5.conf.in bind9-9.20.15/bin/tests/system/reclimit/ns3/named5.conf.in --- bind9-9.20.11/bin/tests/system/reclimit/ns3/named5.conf.in 2025-07-04 09:42:08.225325604 +0000 +++ bind9-9.20.15/bin/tests/system/reclimit/ns3/named5.conf.in 2025-10-18 10:16:12.447730502 +0000 @@ -24,12 +24,11 @@ qname-minimization disabled; max-recursion-depth 12; recursion yes; - dnssec-validation yes; + dnssec-validation no; max-records-per-type 0; max-types-per-name 10; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/reclimit/ns3/named6.conf.in bind9-9.20.15/bin/tests/system/reclimit/ns3/named6.conf.in --- bind9-9.20.11/bin/tests/system/reclimit/ns3/named6.conf.in 2025-07-04 09:42:08.225325604 +0000 +++ bind9-9.20.15/bin/tests/system/reclimit/ns3/named6.conf.in 2025-10-18 10:16:12.447730502 +0000 @@ -24,12 +24,11 @@ qname-minimization disabled; max-recursion-depth 12; recursion yes; - dnssec-validation yes; + dnssec-validation no; max-records-per-type 0; max-types-per-name 0; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/reclimit/tests_sh_reclimit.py bind9-9.20.15/bin/tests/system/reclimit/tests_sh_reclimit.py --- bind9-9.20.11/bin/tests/system/reclimit/tests_sh_reclimit.py 2025-07-04 09:42:08.225325604 +0000 +++ bind9-9.20.15/bin/tests/system/reclimit/tests_sh_reclimit.py 2025-10-18 10:16:12.448730518 +0000 @@ -11,8 +11,6 @@ import pytest -import isctest.mark - pytestmark = pytest.mark.extra_artifacts( [ "dig.out.*", @@ -27,6 +25,6 @@ # The reclimit is known to be quite unstable. GL #1587 -@isctest.mark.flaky(max_runs=2) +@pytest.mark.flaky(max_runs=2) def test_reclimit(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/redirect/ns1/named.conf.in bind9-9.20.15/bin/tests/system/redirect/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/redirect/ns1/named.conf.in 2025-07-04 09:42:08.226325627 +0000 +++ bind9-9.20.15/bin/tests/system/redirect/ns1/named.conf.in 2025-10-18 10:16:12.448730518 +0000 @@ -25,10 +25,9 @@ listen-on-v6 { none; }; allow-recursion { 10.53.0.1; }; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type primary; diff -Nru bind9-9.20.11/bin/tests/system/redirect/ns2/named.conf.in bind9-9.20.15/bin/tests/system/redirect/ns2/named.conf.in --- bind9-9.20.11/bin/tests/system/redirect/ns2/named.conf.in 2025-07-04 09:42:08.226325627 +0000 +++ bind9-9.20.15/bin/tests/system/redirect/ns2/named.conf.in 2025-10-18 10:16:12.449730534 +0000 @@ -27,11 +27,10 @@ listen-on-v6 { none; }; recursion yes; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/redirect/ns3/named.conf.in bind9-9.20.15/bin/tests/system/redirect/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/redirect/ns3/named.conf.in 2025-07-04 09:42:08.226325627 +0000 +++ bind9-9.20.15/bin/tests/system/redirect/ns3/named.conf.in 2025-10-18 10:16:12.449730534 +0000 @@ -23,10 +23,9 @@ listen-on-v6 { none; }; allow-recursion { 10.53.0.3; }; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." { type primary; diff -Nru bind9-9.20.11/bin/tests/system/redirect/ns4/named.conf.in bind9-9.20.15/bin/tests/system/redirect/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/redirect/ns4/named.conf.in 2025-07-04 09:42:08.227325651 +0000 +++ bind9-9.20.15/bin/tests/system/redirect/ns4/named.conf.in 2025-10-18 10:16:12.450730549 +0000 @@ -27,11 +27,10 @@ listen-on-v6 { none; }; recursion yes; notify yes; - dnssec-validation yes; + dnssec-validation no; nxdomain-redirect "redirect"; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/resolver/ns1/named.conf.in bind9-9.20.15/bin/tests/system/resolver/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/resolver/ns1/named.conf.in 2025-07-04 09:42:08.229325697 +0000 +++ bind9-9.20.15/bin/tests/system/resolver/ns1/named.conf.in 2025-10-18 10:16:12.452730580 +0000 @@ -20,7 +20,7 @@ listen-on { 10.53.0.1; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; deny-answer-addresses { 192.0.2.0/24; 2001:db8:beef::/48; } except-from { "example.org"; }; deny-answer-aliases { "example.org"; } @@ -33,7 +33,6 @@ max-recursion-queries 100; }; -trust-anchors { }; server 10.53.0.3 { tcp-only yes; diff -Nru bind9-9.20.11/bin/tests/system/resolver/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/resolver/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/resolver/ns1/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/resolver/ns1/named.conf.j2 2025-10-18 10:16:12.452730580 +0000 @@ -0,0 +1,48 @@ +/* + * 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 wrongoption = wrongoption | default(False) %} + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion yes; + dnssec-validation no; + attach-cache "globalcache"; + max-zone-ttl unlimited; + resolver-query-timeout 5000; # 5 seconds + max-recursion-queries 100; +}; + +view "default" { + zone "." { + type hint; + file "root.hint"; + }; +{% if wrongoption %} + forwarders port 9999999 { 127.0.0.1; }; +{% endif %} +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/resolver/ns7/named1.conf.in bind9-9.20.15/bin/tests/system/resolver/ns7/named1.conf.in --- bind9-9.20.11/bin/tests/system/resolver/ns7/named1.conf.in 2025-07-04 09:42:08.231325744 +0000 +++ bind9-9.20.15/bin/tests/system/resolver/ns7/named1.conf.in 2025-10-18 10:16:12.454730611 +0000 @@ -22,7 +22,7 @@ listen-on { 10.53.0.7; }; listen-on-v6 { fd92:7065:b8e:ffff::7; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; empty-zones-enable yes; disable-empty-zone 20.172.in-addr.arpa; /* @@ -34,7 +34,6 @@ edns-udp-size 4096; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/resolver/ns7/named2.conf.in bind9-9.20.15/bin/tests/system/resolver/ns7/named2.conf.in --- bind9-9.20.11/bin/tests/system/resolver/ns7/named2.conf.in 2025-07-04 09:42:08.231325744 +0000 +++ bind9-9.20.15/bin/tests/system/resolver/ns7/named2.conf.in 2025-10-18 10:16:12.454730611 +0000 @@ -22,7 +22,7 @@ listen-on { 10.53.0.7; }; listen-on-v6 { fd92:7065:b8e:ffff::7; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; empty-zones-enable yes; disable-empty-zone 20.172.in-addr.arpa; /* @@ -34,7 +34,6 @@ edns-udp-size 4096; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/resolver/ns9/named.conf.in bind9-9.20.15/bin/tests/system/resolver/ns9/named.conf.in --- bind9-9.20.11/bin/tests/system/resolver/ns9/named.conf.in 2025-07-04 09:42:08.231325744 +0000 +++ bind9-9.20.15/bin/tests/system/resolver/ns9/named.conf.in 2025-10-18 10:16:12.455730627 +0000 @@ -20,12 +20,11 @@ listen-on-v6 { fd92:7065:b8e:ffff::9; }; recursion yes; recursive-clients 0; // regression test for [GL #4987] - dnssec-validation yes; + dnssec-validation no; dual-stack-servers { fd92:7065:b8e:ffff::7; }; qname-minimization off; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/resolver/tests_resolver.py bind9-9.20.15/bin/tests/system/resolver/tests_resolver.py --- bind9-9.20.11/bin/tests/system/resolver/tests_resolver.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/resolver/tests_resolver.py 2025-10-18 10:16:12.455730627 +0000 @@ -0,0 +1,39 @@ +# 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 time + + +import isctest + + +def test_resolver_cache_reloadfails(ns1, templates): + ns1.rndc("flush") + msg = isctest.query.create("www.example.org.", "A") + res = isctest.query.udp(msg, "10.53.0.1") + isctest.check.noerror(res) + assert res.answer[0].ttl == 300 + templates.render("ns1/named.conf", {"wrongoption": True}) + try: + # The first reload fails, and the old cache list will be preserved + ns1.rndc("reload") + except isctest.rndc.RNDCException: + templates.render("ns1/named.conf", {"wrongoption": False}) + # The second reload succeed, and the cache is still there, as preserved + # from the old cache list + ns1.rndc("reload") + time.sleep(3) + msg = isctest.query.create("www.example.org.", "A") + res = isctest.query.udp(msg, "10.53.0.1") + isctest.check.noerror(res) + # The ttl being lower than 300 (provided by fake authoritative) proves + # the cache is still in use + assert res.answer[0].ttl < 300 diff -Nru bind9-9.20.11/bin/tests/system/resolver/tests_sh_resolver.py bind9-9.20.15/bin/tests/system/resolver/tests_sh_resolver.py --- bind9-9.20.11/bin/tests/system/resolver/tests_sh_resolver.py 2025-07-04 09:42:08.232325768 +0000 +++ bind9-9.20.15/bin/tests/system/resolver/tests_sh_resolver.py 2025-10-18 10:16:12.455730627 +0000 @@ -11,6 +11,7 @@ import pytest + pytestmark = pytest.mark.extra_artifacts( [ ".digrc", diff -Nru bind9-9.20.11/bin/tests/system/rfc5011/tests_rfc5011.py bind9-9.20.15/bin/tests/system/rfc5011/tests_rfc5011.py --- bind9-9.20.11/bin/tests/system/rfc5011/tests_rfc5011.py 2025-07-04 09:42:08.232325768 +0000 +++ bind9-9.20.15/bin/tests/system/rfc5011/tests_rfc5011.py 2025-10-18 10:16:12.456730642 +0000 @@ -20,13 +20,13 @@ @live_internet_test -def test_rfc5011_rootdnskeyrefresh(servers): - with servers["ns1"].watch_log_from_start() as watcher: +def test_rfc5011_rootdnskeyrefresh(ns1): + with ns1.watch_log_from_start() as watcher: watcher.wait_for_line( "managed-keys-zone: Initializing automatic trust anchor management for zone '.'; DNSKEY ID 20326 is now trusted, waiving the normal 30-day waiting period" ) - with servers["ns1"].watch_log_from_start() as watcher: + with ns1.watch_log_from_start() as watcher: watcher.wait_for_line( "managed-keys-zone: Initializing automatic trust anchor management for zone '.'; DNSKEY ID 38696 is now trusted, waiving the normal 30-day waiting period" ) diff -Nru bind9-9.20.11/bin/tests/system/rndc/ns4/named.conf.in bind9-9.20.15/bin/tests/system/rndc/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/rndc/ns4/named.conf.in 2025-07-04 09:42:08.233325791 +0000 +++ bind9-9.20.15/bin/tests/system/rndc/ns4/named.conf.in 2025-10-18 10:16:12.456730642 +0000 @@ -17,10 +17,9 @@ listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; view normal { match-clients { any; }; diff -Nru bind9-9.20.11/bin/tests/system/rndc/tests.sh bind9-9.20.15/bin/tests/system/rndc/tests.sh --- bind9-9.20.11/bin/tests/system/rndc/tests.sh 2025-07-04 09:42:08.234325815 +0000 +++ bind9-9.20.15/bin/tests/system/rndc/tests.sh 2025-10-18 10:16:12.457730658 +0000 @@ -562,8 +562,9 @@ n=$((n + 1)) echo_i "test 'rndc reconfig' with a broken config ($n)" ret=0 +nextpart ns4/named.run >/dev/null $RNDC -s 10.53.0.4 -p ${EXTRAPORT6} -c ns4/key6.conf reconfig >/dev/null || ret=1 -sleep 1 +wait_for_log 3 "running" ns4/named.run mv ns4/named.conf ns4/named.conf.save echo "error error error" >>ns4/named.conf $RNDC -s 10.53.0.4 -p ${EXTRAPORT6} -c ns4/key6.conf reconfig >rndc.out.1.test$n 2>&1 && ret=1 @@ -582,10 +583,11 @@ n=$((n + 1)) echo_i "restore working config ($n)" ret=0 +nextpart ns4/named.run >/dev/null mv ns4/named.conf.save ns4/named.conf sleep 1 $RNDC -s 10.53.0.4 -p ${EXTRAPORT6} -c ns4/key6.conf reconfig >/dev/null || ret=1 -sleep 1 +wait_for_log 3 "running" ns4/named.run if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) diff -Nru bind9-9.20.11/bin/tests/system/rndc/tests_cve-2023-3341.py bind9-9.20.15/bin/tests/system/rndc/tests_cve-2023-3341.py --- bind9-9.20.11/bin/tests/system/rndc/tests_cve-2023-3341.py 2025-07-04 09:42:08.234325815 +0000 +++ bind9-9.20.15/bin/tests/system/rndc/tests_cve-2023-3341.py 2025-10-18 10:16:12.457730658 +0000 @@ -15,10 +15,9 @@ import time import pytest + import isctest -pytest.importorskip("dns") -import dns.message pytestmark = pytest.mark.extra_artifacts( [ @@ -66,6 +65,6 @@ # Wait for named to (possibly) crash time.sleep(10) - msg = dns.message.make_query("version.bind", "TXT", "CH") + msg = isctest.query.create("version.bind", "TXT", "CH") res = isctest.query.udp(msg, "10.53.0.2") isctest.check.noerror(res) diff -Nru bind9-9.20.11/bin/tests/system/rollover/common.py bind9-9.20.15/bin/tests/system/rollover/common.py --- bind9-9.20.11/bin/tests/system/rollover/common.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/common.py 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,139 @@ +# 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. + +from datetime import timedelta +import os + +import pytest + +from isctest.kasp import Ipub, IpubC, Iret + +pytestmark = pytest.mark.extra_artifacts( + [ + "*.axfr*", + "dig.out*", + "K*.key*", + "K*.private*", + "ns*/*.db", + "ns*/*.db.infile", + "ns*/*.db.jnl", + "ns*/*.db.jbk", + "ns*/*.db.signed", + "ns*/*.db.signed.jnl", + "ns*/*.conf", + "ns*/dsset-*", + "ns*/K*.key", + "ns*/K*.private", + "ns*/K*.state", + "ns*/keygen.out.*", + "ns*/settime.out.*", + "ns*/signer.out.*", + "ns*/zones", + ] +) + + +TIMEDELTA = { + 0: timedelta(seconds=0), + "PT5M": timedelta(minutes=5), + "PT20M": timedelta(minutes=20), + "PT1H": timedelta(hours=1), + "PT2H": timedelta(hours=2), + "PT6H": timedelta(hours=6), + "PT12H": timedelta(hours=12), + "P1D": timedelta(days=1), + "P2D": timedelta(days=2), + "P5D": timedelta(days=5), + "P7D": timedelta(days=7), + "P10D": timedelta(days=10), + "P14D": timedelta(days=14), + "P30D": timedelta(days=30), + "P60D": timedelta(days=60), + "P90D": timedelta(days=90), + "P6M": timedelta(days=31 * 6), + "P1Y": timedelta(days=365), +} +DURATION = {isoname: int(delta.total_seconds()) for isoname, delta in TIMEDELTA.items()} +CDSS = ["CDNSKEY", "CDS (SHA-256)"] +DEFAULT_CONFIG = { + "dnskey-ttl": TIMEDELTA["PT1H"], + "ds-ttl": TIMEDELTA["P1D"], + "max-zone-ttl": TIMEDELTA["P1D"], + "parent-propagation-delay": TIMEDELTA["PT1H"], + "publish-safety": TIMEDELTA["PT1H"], + "purge-keys": TIMEDELTA["P90D"], + "retire-safety": TIMEDELTA["PT1H"], + "signatures-refresh": TIMEDELTA["P5D"], + "signatures-validity": TIMEDELTA["P14D"], + "zone-propagation-delay": TIMEDELTA["PT5M"], +} +UNSIGNING_CONFIG = DEFAULT_CONFIG.copy() +UNSIGNING_CONFIG["dnskey-ttl"] = TIMEDELTA["PT2H"] +ALGOROLL_CONFIG = { + "dnskey-ttl": TIMEDELTA["PT1H"], + "ds-ttl": TIMEDELTA["PT2H"], + "max-zone-ttl": TIMEDELTA["PT6H"], + "parent-propagation-delay": TIMEDELTA["PT1H"], + "publish-safety": TIMEDELTA["PT1H"], + "purge-keys": TIMEDELTA["P90D"], + "retire-safety": TIMEDELTA["PT2H"], + "signatures-refresh": TIMEDELTA["P5D"], + "signatures-validity": TIMEDELTA["P30D"], + "zone-propagation-delay": TIMEDELTA["PT1H"], +} +ALGOROLL_IPUB = Ipub(ALGOROLL_CONFIG) +ALGOROLL_IPUBC = IpubC(ALGOROLL_CONFIG, rollover=False) +ALGOROLL_IRET = Iret(ALGOROLL_CONFIG, rollover=False) +ALGOROLL_IRETKSK = Iret(ALGOROLL_CONFIG, zsk=False, ksk=True, rollover=False) +ALGOROLL_KEYTTLPROP = ( + ALGOROLL_CONFIG["dnskey-ttl"] + ALGOROLL_CONFIG["zone-propagation-delay"] +) +ALGOROLL_OFFSETS = {} +ALGOROLL_OFFSETS["step2"] = -int(ALGOROLL_IPUB.total_seconds()) +ALGOROLL_OFFSETS["step3"] = -int(ALGOROLL_IRET.total_seconds()) +ALGOROLL_OFFSETS["step4"] = ALGOROLL_OFFSETS["step3"] - int( + ALGOROLL_IRETKSK.total_seconds() +) +ALGOROLL_OFFSETS["step5"] = ALGOROLL_OFFSETS["step4"] - int( + ALGOROLL_KEYTTLPROP.total_seconds() +) +ALGOROLL_OFFSETS["step6"] = ALGOROLL_OFFSETS["step5"] - int( + ALGOROLL_IRET.total_seconds() +) +ALGOROLL_OFFVAL = -DURATION["P7D"] +KSK_CONFIG = { + "dnskey-ttl": TIMEDELTA["PT2H"], + "ds-ttl": TIMEDELTA["PT1H"], + "max-zone-ttl": TIMEDELTA["P1D"], + "parent-propagation-delay": TIMEDELTA["PT1H"], + "publish-safety": TIMEDELTA["P1D"], + "purge-keys": TIMEDELTA["PT1H"], + "retire-safety": TIMEDELTA["P2D"], + "signatures-refresh": TIMEDELTA["P7D"], + "signatures-validity": TIMEDELTA["P14D"], + "zone-propagation-delay": TIMEDELTA["PT1H"], +} +KSK_LIFETIME = TIMEDELTA["P60D"] +KSK_LIFETIME_POLICY = int(KSK_LIFETIME.total_seconds()) +KSK_IPUB = Ipub(KSK_CONFIG) +KSK_IPUBC = IpubC(KSK_CONFIG) +KSK_IRET = Iret(KSK_CONFIG, zsk=False, ksk=True) +KSK_KEYTTLPROP = KSK_CONFIG["dnskey-ttl"] + KSK_CONFIG["zone-propagation-delay"] + + +@pytest.fixture +def alg(): + return os.environ["DEFAULT_ALGORITHM_NUMBER"] + + +@pytest.fixture +def size(): + return os.environ["DEFAULT_BITS"] diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns3/kasp.conf.j2 2025-07-04 09:42:08.234325815 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns3/kasp.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -19,118 +19,3 @@ zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; }; }; - -dnssec-policy "multisigner-model2" { - dnskey-ttl 3600; - inline-signing no; - - keys { - ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535; - zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535; - }; -}; - -dnssec-policy "enable-dnssec" { - signatures-refresh P1W; - signatures-validity P2W; - signatures-validity-dnskey P2W; - - dnskey-ttl 300; - max-zone-ttl PT12H; - zone-propagation-delay PT5M; - retire-safety PT20M; - publish-safety PT5M; - - parent-propagation-delay 1h; - parent-ds-ttl 2h; - - keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@; - }; -}; - -dnssec-policy "zsk-prepub" { - signatures-refresh P1W; - signatures-validity P2W; - signatures-validity-dnskey P2W; - - dnskey-ttl 3600; - publish-safety P1D; - retire-safety P2D; - purge-keys PT1H; - - keys { - ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - zsk key-directory lifetime P30D algorithm @DEFAULT_ALGORITHM@; - }; - - zone-propagation-delay PT1H; - max-zone-ttl 1d; -}; - -dnssec-policy "ksk-doubleksk" { - signatures-refresh P1W; - signatures-validity P2W; - signatures-validity-dnskey P2W; - - dnskey-ttl 2h; - publish-safety P1D; - retire-safety P2D; - purge-keys PT1H; - - cdnskey no; - keys { - ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; - zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - }; - - zone-propagation-delay PT1H; - max-zone-ttl 1d; - - parent-ds-ttl 3600; - parent-propagation-delay PT1H; -}; - -dnssec-policy "csk-roll1" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - purge-keys PT1H; - - cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes - keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; - }; - - zone-propagation-delay 1h; - max-zone-ttl P1D; - - parent-ds-ttl 1h; - parent-propagation-delay 1h; -}; - -dnssec-policy "csk-roll2" { - signatures-refresh 12h; - signatures-validity P1D; - signatures-validity-dnskey P1D; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 1h; - purge-keys 0; - - cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes - keys { - csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; - }; - - zone-propagation-delay PT1H; - max-zone-ttl 1d; - - parent-ds-ttl PT1H; - parent-propagation-delay P1W; -}; diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns3/named.conf.j2 2025-07-04 09:42:08.234325815 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns3/named.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -11,242 +11,11 @@ * information regarding copyright ownership. */ -// NS3 - include "kasp.conf"; +include "named.common.conf"; -options { - query-source address 10.53.0.3; - notify-source 10.53.0.3; - transfer-source 10.53.0.3; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.3; }; - listen-on-v6 { none; }; - allow-transfer { any; }; - recursion no; - dnssec-validation no; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { - type hint; - file "../../_common/root.hint.blackhole"; -}; - -/* Manual rollover. */ zone "manual-rollover.kasp" { type primary; file "manual-rollover.kasp.db"; dnssec-policy "manual-rollover"; }; - -/* RFC 8901 Multi-signer Model 2. */ -zone "multisigner-model2.kasp" { - type primary; - file "multisigner-model2.kasp.db"; - dnssec-policy "multisigner-model2"; - allow-update { any; }; -}; - -/* - * A zone that starts with keys that have tags that are - * outside of the desired multi-signer key tag range. - */ -zone "single-to-multisigner.kasp" { - type primary; - file "single-to-multisigner.kasp.db"; - dnssec-policy "multisigner-model2"; - allow-update { any; }; -}; - -/* - * Zones for testing enabling DNSSEC. - */ -zone "step1.enable-dnssec.autosign" { - type primary; - file "step1.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; -zone "step2.enable-dnssec.autosign" { - type primary; - file "step2.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; -zone "step3.enable-dnssec.autosign" { - type primary; - file "step3.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; -zone "step4.enable-dnssec.autosign" { - type primary; - file "step4.enable-dnssec.autosign.db"; - dnssec-policy "enable-dnssec"; -}; - -/* - * Zones for testing ZSK Pre-Publication steps. - */ -zone "step1.zsk-prepub.autosign" { - type primary; - file "step1.zsk-prepub.autosign.db"; - dnssec-policy "zsk-prepub"; -}; -zone "step2.zsk-prepub.autosign" { - type primary; - file "step2.zsk-prepub.autosign.db"; - dnssec-policy "zsk-prepub"; -}; -zone "step3.zsk-prepub.autosign" { - type primary; - file "step3.zsk-prepub.autosign.db"; - dnssec-policy "zsk-prepub"; -}; -zone "step4.zsk-prepub.autosign" { - type primary; - file "step4.zsk-prepub.autosign.db"; - dnssec-policy "zsk-prepub"; -}; -zone "step5.zsk-prepub.autosign" { - type primary; - file "step5.zsk-prepub.autosign.db"; - dnssec-policy "zsk-prepub"; -}; -zone "step6.zsk-prepub.autosign" { - type primary; - file "step6.zsk-prepub.autosign.db"; - dnssec-policy "zsk-prepub"; -}; - -/* - * Zones for testing KSK Double-KSK steps. - */ -zone "step1.ksk-doubleksk.autosign" { - type primary; - file "step1.ksk-doubleksk.autosign.db"; - dnssec-policy "ksk-doubleksk"; -}; -zone "step2.ksk-doubleksk.autosign" { - type primary; - file "step2.ksk-doubleksk.autosign.db"; - dnssec-policy "ksk-doubleksk"; -}; -zone "step3.ksk-doubleksk.autosign" { - type primary; - file "step3.ksk-doubleksk.autosign.db"; - dnssec-policy "ksk-doubleksk"; -}; -zone "step4.ksk-doubleksk.autosign" { - type primary; - file "step4.ksk-doubleksk.autosign.db"; - dnssec-policy "ksk-doubleksk"; -}; -zone "step5.ksk-doubleksk.autosign" { - type primary; - file "step5.ksk-doubleksk.autosign.db"; - dnssec-policy "ksk-doubleksk"; -}; -zone "step6.ksk-doubleksk.autosign" { - type primary; - file "step6.ksk-doubleksk.autosign.db"; - dnssec-policy "ksk-doubleksk"; -}; - -/* - * Zone for testing GL #2375: Three is a crowd. - */ -zone "three-is-a-crowd.kasp" { - type primary; - file "three-is-a-crowd.kasp.db"; - inline-signing yes; - /* Use same policy as KSK rollover test zones. */ - dnssec-policy "ksk-doubleksk"; -}; - -/* - * Zones for testing CSK rollover steps. - */ -zone "step1.csk-roll1.autosign" { - type primary; - file "step1.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; -zone "step2.csk-roll1.autosign" { - type primary; - file "step2.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; -zone "step3.csk-roll1.autosign" { - type primary; - file "step3.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; -zone "step4.csk-roll1.autosign" { - type primary; - file "step4.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; -zone "step5.csk-roll1.autosign" { - type primary; - file "step5.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; -zone "step6.csk-roll1.autosign" { - type primary; - file "step6.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; -zone "step7.csk-roll1.autosign" { - type primary; - file "step7.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; -zone "step8.csk-roll1.autosign" { - type primary; - file "step8.csk-roll1.autosign.db"; - dnssec-policy "csk-roll1"; -}; - -zone "step1.csk-roll2.autosign" { - type primary; - file "step1.csk-roll2.autosign.db"; - dnssec-policy "csk-roll2"; -}; -zone "step2.csk-roll2.autosign" { - type primary; - file "step2.csk-roll2.autosign.db"; - dnssec-policy "csk-roll2"; -}; -zone "step3.csk-roll2.autosign" { - type primary; - file "step3.csk-roll2.autosign.db"; - dnssec-policy "csk-roll2"; -}; -zone "step4.csk-roll2.autosign" { - type primary; - file "step4.csk-roll2.autosign.db"; - dnssec-policy "csk-roll2"; -}; -zone "step5.csk-roll2.autosign" { - type primary; - file "step5.csk-roll2.autosign.db"; - dnssec-policy "csk-roll2"; -}; -zone "step6.csk-roll2.autosign" { - type primary; - file "step6.csk-roll2.autosign.db"; - dnssec-policy "csk-roll2"; -}; -zone "step7.csk-roll2.autosign" { - type primary; - file "step7.csk-roll2.autosign.db"; - dnssec-policy "csk-roll2"; -}; diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns3/setup.sh bind9-9.20.15/bin/tests/system/rollover/ns3/setup.sh --- bind9-9.20.11/bin/tests/system/rollover/ns3/setup.sh 2025-07-04 09:42:08.234325815 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns3/setup.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,1091 +0,0 @@ -#!/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 "ns3/setup.sh" - -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" - echo "$zone" >>zones -} - -# Set in the key state files the Predecessor/Successor fields. -# Key $1 is the predecessor of key $2. -key_successor() { - id1=$(keyfile_to_key_id "$1") - id2=$(keyfile_to_key_id "$2") - echo "Predecessor: ${id1}" >>"${2}.state" - echo "Successor: ${id2}" >>"${1}.state" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -# Zone to test manual rollover. -setup manual-rollover.kasp -T="now-7d" -keytimes="-P $T -A $T" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 -cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Multi-signer zones. -setup "multisigner-model2.kasp" -cp template.db.in "$zonefile" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2) -cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db" -cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db" -# Import a ZSK of another provider into the DNSKEY RRset. -ZSK1=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.3) -cat "../${ZSK1}.key" | grep -v ";.*" >>"${zone}.db" - -# We are changing an existing single-signed zone to multi-signed -# zone where the key tags do not match the dnssec-policy key tag range -setup single-to-multisigner.kasp -T="now-7d" -S="now-8635mi" # T - 1d5m -keytimes="-P $T -A $T" -cdstimes="-P sync $S" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 -cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" -$SIGNER -PS -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}" $infile >signer.out.$zone.1 2>&1 -echo "Lifetime: 0" >>"${KSK}".state -echo "Lifetime: 0" >>"${ZSK}".state - -# -# The zones at enable-dnssec.autosign represent the various steps of the -# initial signing of a zone. -# - -# Step 1: -# This is an unsigned zone and named should perform the initial steps of -# introducing the DNSSEC records in the right order. -setup step1.enable-dnssec.autosign -cp template.db.in $zonefile - -# Step 2: -# The DNSKEY has been published long enough to become OMNIPRESENT. -setup step2.enable-dnssec.autosign -# DNSKEY TTL: 300 seconds -# zone-propagation-delay: 5 minutes (300 seconds) -# publish-safety: 5 minutes (300 seconds) -# Total: 900 seconds -TpubN="now-900s" -keytimes="-P ${TpubN} -A ${TpubN}" -CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# The zone signatures have been published long enough to become OMNIPRESENT. -setup step3.enable-dnssec.autosign -# Passed time since publication: -# max-zone-ttl: 12 hours (43200 seconds) -# zone-propagation-delay: 5 minutes (300 seconds) -TpubN="now-43500s" -# We can submit the DS now. -keytimes="-P ${TpubN} -A ${TpubN}" -CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TpubN -r $O $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# The DS has been submitted long enough ago to become OMNIPRESENT. -setup step4.enable-dnssec.autosign -# DS TTL: 2 hour (7200 seconds) -# parent-propagation-delay: 1 hour (3600 seconds) -# Total aditional time: 10800 seconds -# 43500 + 10800 = 54300 -TpubN="now-54300s" -TsbmN="now-10800s" -keytimes="-P ${TpubN} -A ${TpubN} -P sync ${TsbmN}" -CSK=$($KEYGEN -k enable-dnssec -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -P ds $TsbmN -k $O $TpubN -r $O $TpubN -d $R $TpubN -z $O $TsbmN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# -# The zones at zsk-prepub.autosign represent the various steps of a ZSK -# Pre-Publication rollover. -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.zsk-prepub.autosign -TactN="now-7d" -keytimes="-P ${TactN} -A ${TactN}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 -cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 2: -# It is time to pre-publish the successor ZSK. -setup step2.zsk-prepub.autosign -# According to RFC 7583: -# Tact(N) = now + Ipub - Lzsk = now + 26h - 30d -# = now + 26h - 30d = now − 694h -TactN="now-694h" -keytimes="-P ${TactN} -A ${TactN}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 -cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# After the publication interval has passed the DNSKEY of the successor ZSK -# is OMNIPRESENT and the zone can thus be signed with the successor ZSK. -setup step3.zsk-prepub.autosign -# According to RFC 7583: -# Tpub(N+1) <= Tact(N) + Lzsk - Ipub -# Tact(N+1) = Tact(N) + Lzsk -# -# Tact(N) = now - Lzsk = now - 30d -# Tpub(N+1) = now - Ipub = now - 26h -# Tact(N+1) = now -# Tret(N) = now -# Trem(N) = now + Iret = now + Dsign + Dprp + TTLsig + retire-safety = 8d1h = now + 241h -TactN="now-30d" -TpubN1="now-26h" -TactN1="now" -TremN="now+241h" -keytimes="-P ${TactN} -A ${TactN}" -oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" -newtimes="-P ${TpubN1} -A ${TactN1}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -z $H $TpubN1 "$ZSK2" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $ZSK1 $ZSK2 -# Sign zone. -cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# After the retire interval has passed the predecessor DNSKEY can be -# removed from the zone. -setup step4.zsk-prepub.autosign -# Lzsk: 30d -# Ipub: 26h -# Dsgn: 1w -# Dprp: 1h -# TTLsig: 1d -# retire-safety: 2d -# -# According to RFC 7583: -# Iret = Dsgn + Dprp + TTLsig (+retire-safety) -# Iret = 1w + 1h + 1d + 2d = 10d1h = 241h -# -# Tact(N) = now - Iret - Lzsk -# = now - 241h - 30d = now - 241h - 720h -# = now - 961h -# Tpub(N+1) = now - Iret - Ipub -# = now - 241h - 26h -# = now - 267h -# Tact(N+1) = now - Iret = now - 241h -TactN="now-961h" -TpubN1="now-267h" -TactN1="now-241h" -TremN="now" -keytimes="-P ${TactN} -A ${TactN}" -oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" -newtimes="-P ${TpubN1} -A ${TactN1}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $O $TactN -z $U $TactN1 "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -z $R $TactN1 "$ZSK2" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $ZSK1 $ZSK2 -# Sign zone. -cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" -cp $infile $zonefile -$SIGNER -PS -x -s now-2w -e now-1mi -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 5: -# The predecessor DNSKEY is removed long enough that is has become HIDDEN. -setup step5.zsk-prepub.autosign -# Subtract DNSKEY TTL + zone-propagation-delay from all the times (2h). -# Tact(N) = now - 961h - 2h = now - 963h -# Tpub(N+1) = now - 267h - 2h = now - 269h -# Tact(N+1) = now - 241h - 2h = now - 243h -# Trem(N) = Tact(N+1) + Iret = now -2h -TactN="now-963h" -TremN="now-2h" -TpubN1="now-269h" -TactN1="now-243h" -TremN="now-2h" -keytimes="-P ${TactN} -A ${TactN}" -oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" -newtimes="-P ${TpubN1} -A ${TactN1}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $U $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $ZSK1 $ZSK2 -# Sign zone. -cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 6: -# The predecessor DNSKEY can be purged. -setup step6.zsk-prepub.autosign -# Subtract purge-keys interval from all the times (1h). -TactN="now-964h" -TremN="now-3h" -TpubN1="now-270h" -TactN1="now-244h" -TremN="now-3h" -keytimes="-P ${TactN} -A ${TactN}" -oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" -newtimes="-P ${TpubN1} -A ${TactN1}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $H $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $ZSK1 $ZSK2 -# Sign zone. -cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# -# The zones at ksk-doubleksk.autosign represent the various steps of a KSK -# Double-KSK rollover. -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.ksk-doubleksk.autosign -TactN="now-7d" -keytimes="-P ${TactN} -A ${TactN}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 -cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 2: -# It is time to submit the introduce the new KSK. -setup step2.ksk-doubleksk.autosign -# Lksk: 60d -# Dreg: n/a -# DprpC: 1h -# TTLds: 1d -# TTLkey: 2h -# publish-safety: 1d -# retire-safety: 2d -# -# According to RFC 7583: -# Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC -# IpubC = DprpC + TTLkey (+publish-safety) -# -# IpubC = 27h -# Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h -# = now - 1440h + 27h = now - 1413h -TactN="now-1413h" -keytimes="-P ${TactN} -A ${TactN}" -KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 -cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# It is time to submit the DS. -setup step3.ksk-doubleksk.autosign -# According to RFC 7583: -# Iret = DprpP + TTLds (+retire-safety) -# -# Iret = 50h -# Tpub(N) = now - Lksk = now - 60d = now - 60d -# Tact(N) = now - 1413h -# Tret(N) = now -# Trem(N) = now + Iret = now + 50h -# Tpub(N+1) = now - IpubC = now - 27h -# Tact(N+1) = now -# Tret(N+1) = now + Lksk = now + 60d -# Trem(N+1) = now + Lksk + Iret = now + 60d + 50h -# = now + 1440h + 50h = 1490h -TpubN="now-60d" -TactN="now-1413h" -TretN="now" -TremN="now+50h" -TpubN1="now-27h" -TactN1="now" -TretN1="now+60d" -TremN1="now+1490h" -ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" -zsktimes="-P ${TpubN} -A ${TpubN}" -KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $H -k $O $TpubN -r $O $TpubN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TpubN -z $O $TpubN "$ZSK" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $KSK1 $KSK2 -# Sign zone. -cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# The DS should be swapped now. -setup step4.ksk-doubleksk.autosign -# Tpub(N) = now - Lksk - Iret = now - 60d - 50h -# = now - 1440h - 50h = now - 1490h -# Tact(N) = now - 1490h + 27h = now - 1463h -# Tret(N) = now - Iret = now - 50h -# Trem(N) = now -# Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h -# = now - 77h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h -# Trem(N+1) = now + Lksk = now + 60d -TpubN="now-1490h" -TactN="now-1463h" -TretN="now-50h" -TremN="now" -TpubN1="now-77h" -TactN1="${TretN}" -TretN1="now+1390h" -TremN1="now+60d" -ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" -zsktimes="-P ${TpubN} -A ${TpubN}" -KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TretN -D ds $TretN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -P ds $TactN1 "$KSK2" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $KSK1 $KSK2 -# Sign zone. -cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 5: -# The predecessor DNSKEY is removed long enough that is has become HIDDEN. -setup step5.ksk-doubleksk.autosign -# Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h). -# Tpub(N) = now - 1490h - 3h = now - 1493h -# Tact(N) = now - 1463h - 3h = now - 1466h -# Tret(N) = now - 50h - 3h = now - 53h -# Trem(N) = now - 3h -# Tpub(N+1) = now - 77h - 3h = now - 80h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now + 1390h - 3h = now + 1387h -# Trem(N+1) = now + 60d - 3h = now + 1441h -TpubN="now-1493h" -TactN="now-1466h" -TretN="now-53h" -TremN="now-3h" -TpubN1="now-80h" -TactN1="${TretN}" -TretN1="now+1387h" -TremN1="now+1441h" -ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" -zsktimes="-P ${TpubN} -A ${TpubN}" -KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $H -k $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $KSK1 $KSK2 -# Sign zone. -cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 6: -# The predecessor DNSKEY can be purged. -setup step6.ksk-doubleksk.autosign -# Subtract purge-keys interval from all the times (1h). -TpubN="now-1494h" -TactN="now-1467h" -TretN="now-54h" -TremN="now-4h" -TpubN1="now-81h" -TactN1="${TretN}" -TretN1="now+1386h" -TremN1="now+1440h" -ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" -zsktimes="-P ${TpubN} -A ${TpubN}" -KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $H -k $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $KSK1 $KSK2 -# Sign zone. -cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Test #2375, the "three is a crowd" bug, where a new key is introduced but the -# previous rollover has not finished yet. In other words, we have a key KEY2 -# that is the successor of key KEY1, and we introduce a new key KEY3 that is -# the successor of key KEY2: -# -# KEY1 < KEY2 < KEY3. -# -# The expected behavior is that all three keys remain in the zone, and not -# the bug behavior where KEY2 is removed and immediately replaced with KEY3. -# -# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2) -# published as well. -setup three-is-a-crowd.kasp -# These times are the same as step3.ksk-doubleksk.autosign. -TpubN="now-60d" -TactN="now-1413h" -TretN="now" -TremN="now+50h" -TpubN1="now-27h" -TsbmN1="now" -TactN1="${TretN}" -TretN1="now+60d" -TremN1="now+1490h" -ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}" -zsktimes="-P ${TpubN} -A ${TpubN}" -KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) -ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 -# Set key rollover relationship. -key_successor $KSK1 $KSK2 -# Sign zone. -cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# -# The zones at csk-roll1.autosign represent the various steps of a CSK rollover -# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.csk-roll1.autosign -TactN="now-7d" -keytimes="-P ${TactN} -A ${TactN}" -CSK=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 2: -# It is time to introduce the new CSK. -setup step2.csk-roll1.autosign -# According to RFC 7583: -# KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC -# ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub -# IpubC = DprpC + TTLkey (+publish-safety) -# Ipub = IpubC -# Lcsk = Lksk = Lzsk -# -# Lcsk: 6mo (186d, 4464h) -# Dreg: N/A -# DprpC: 1h -# TTLkey: 1h -# publish-safety: 1h -# Ipub: 3h -# -# Tact(N) = now - Lcsk + Ipub = now - 186d + 3h -# = now - 4464h + 3h = now - 4461h -TactN="now-4461h" -keytimes="-P ${TactN} -A ${TactN}" -CSK=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# It is time to submit the DS and to roll signatures. -setup step3.csk-roll1.autosign -# According to RFC 7583: -# -# Tsbm(N+1) >= Trdy(N+1) -# KSK: Tact(N+1) = Tsbm(N+1) -# ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) -# KSK: Iret = DprpP + TTLds (+retire-safety) -# ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) -# -# Lcsk: 186d -# Dprp: 1h -# DprpP: 1h -# Dreg: N/A -# Dsgn: 25d -# TTLds: 1h -# TTLsig: 1d -# retire-safety: 2h -# Iret: 4h -# IretZ: 26d3h -# Ipub: 3h -# -# Tpub(N) = now - Lcsk = now - 186d -# Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h -# Tret(N) = now -# Trem(N) = now + IretZ = now + 26d3h = now + 627h -# Tpub(N+1) = now - Ipub = now - 3h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now + Lcsk = now + 186d = now + 186d -# Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h = -# = now + 5091h -TpubN="now-186d" -TactN="now-4439h" -TretN="now" -TremN="now+627h" -TpubN1="now-3h" -TactN1="${TretN}" -TretN1="now+186d" -TremN1="now+5091h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# Some time later all the ZRRSIG records should be from the new CSK, and the -# DS should be swapped. The ZRRSIG records are all replaced after IretZ -# (which is 26d3h). The DS is swapped after Iret (which is 4h). -# In other words, the DS is swapped before all zone signatures are replaced. -setup step4.csk-roll1.autosign -# According to RFC 7583: -# Trem(N) = Tret(N) - Iret + IretZ -# now = Tsbm(N+1) + Iret -# -# Lcsk: 186d -# Iret: 4h -# IretZ: 26d3h -# -# Tpub(N) = now - Iret - Lcsk = now - 4h - 186d = now - 4468h -# Tret(N) = now - Iret = now - 4h = now - 4h -# Trem(N) = now - Iret + IretZ = now - 4h + 26d3h -# = now + 623h -# Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h -# Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h -# = now + 5087h -TpubN="now-4468h" -TactN="now-4443h" -TretN="now-4h" -TremN="now+623h" -TpubN1="now-7h" -TactN1="${TretN}" -TretN1="now+4460h" -TremN1="now+5087h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TactN1 -z $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -z $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 5: -# After the DS is swapped in step 4, also the KRRSIG records can be removed. -# At this time these have all become hidden. -setup step5.csk-roll1.autosign -# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h). -TpubN="now-4470h" -TactN="now-4445h" -TretN="now-6h" -TremN="now+621h" -TpubN1="now-9h" -TactN1="${TretN}" -TretN1="now+4458h" -TremN1="now+5085h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $U now-2h -d $H now-2h -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O now-2h -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 6: -# After the retire interval has passed the predecessor DNSKEY can be -# removed from the zone. -setup step6.csk-roll1.autosign -# According to RFC 7583: -# Trem(N) = Tret(N) + IretZ -# Tret(N) = Tact(N) + Lcsk -# -# Lcsk: 186d -# Iret: 4h -# IretZ: 26d3h -# -# Tpub(N) = now - IretZ - Lcsk = now - 627h - 186d -# = now - 627h - 4464h = now - 5091h -# Tact(N) = now - 627h - 186d -# Tret(N) = now - IretZ = now - 627h -# Trem(N) = now -# Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h -# Trem(N+1) = now + Lcsk = now + 186d -TpubN="now-5091h" -TactN="now-5066h" -TretN="now-627h" -TremN="now" -TpubN1="now-630h" -TactN1="${TretN}" -TretN1="now+3837h" -TremN1="now+186d" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $H $TremN -d $H $TremN -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 7: -# Some time later the predecessor DNSKEY enters the HIDDEN state. -setup step7.csk-roll1.autosign -# Subtract DNSKEY TTL plus zone propagation delay from all the times (2h). -TpubN="now-5093h" -TactN="now-5068h" -TretN="now-629h" -TremN="now-2h" -TpubN1="now-632h" -TactN1="${TretN}" -TretN1="now+3835h" -TremN1="now+4462h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $U $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 8: -# The predecessor DNSKEY can be purged. -setup step8.csk-roll1.autosign -TpubN="now-5094h" -TactN="now-5069h" -TretN="now-630h" -TremN="now-3h" -TpubN1="now-633h" -TactN1="${TretN}" -TretN1="now+3834h" -TremN1="now+4461h" -# Subtract purge-keys interval from all the times (1h). -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll1 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll1 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $H $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# -# The zones at csk-roll2.autosign represent the various steps of a CSK rollover -# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). -# This scenario differs from the above one because the zone signatures (ZRRSIG) -# are replaced with the new key sooner than the DS is swapped. -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.csk-roll2.autosign -TactN="now-7d" -keytimes="-P ${TactN} -A ${TactN}" -CSK=$($KEYGEN -k csk-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 2: -# It is time to introduce the new CSK. -setup step2.csk-roll2.autosign -# According to RFC 7583: -# KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC -# ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub -# IpubC = DprpC + TTLkey (+publish-safety) -# Ipub = IpubC -# Lcsk = Lksk = Lzsk -# -# Lcsk: 6mo (186d, 4464h) -# Dreg: N/A -# DprpC: 1h -# TTLkey: 1h -# publish-safety: 1h -# Ipub: 3h -# -# Tact(N) = now - Lcsk + Ipub = now - 186d + 3h -# = now - 4464h + 3h = now - 4461h -TactN="now-4461h" -keytimes="-P ${TactN} -A ${TactN}" -CSK=$($KEYGEN -k csk-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# It is time to submit the DS and to roll signatures. -setup step3.csk-roll2.autosign -# According to RFC 7583: -# -# Tsbm(N+1) >= Trdy(N+1) -# KSK: Tact(N+1) = Tsbm(N+1) -# ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) -# KSK: Iret = DprpP + TTLds (+retire-safety) -# ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) -# -# Lcsk: 186d -# Dprp: 1h -# DprpP: 1w -# Dreg: N/A -# Dsgn: 12h -# TTLds: 1h -# TTLsig: 1d -# retire-safety: 1h -# Iret: 170h -# IretZ: 38h -# Ipub: 3h -# -# Tpub(N) = now - Lcsk = now - 186d -# Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h -# Tret(N) = now -# Trem(N) = now + Iret = now + 170h -# Tpub(N+1) = now - Ipub = now - 3h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now + Lcsk = now + 186d -# Trem(N+1) = now + Lcsk + Iret = now + 186d + 170h = -# = now + 4464h + 170h = now + 4634h -TpubN="now-186d" -TactN="now-4439h" -TretN="now" -TremN="now+170h" -TpubN1="now-3h" -TactN1="${TretN}" -TretN1="now+186d" -TremN1="now+4634h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# Some time later all the ZRRSIG records should be from the new CSK, and the -# DS should be swapped. The ZRRSIG records are all replaced after IretZ (38h). -# The DS is swapped after Dreg + Iret (1w3h). In other words, the zone -# signatures are replaced before the DS is swapped. -setup step4.csk-roll2.autosign -# According to RFC 7583: -# Trem(N) = Tret(N) + IretZ -# -# Lcsk: 186d -# Dreg: N/A -# Iret: 170h -# IretZ: 38h -# -# Tpub(N) = now - IretZ - Lcsk = now - 38h - 186d -# = now - 38h - 4464h = now - 4502h -# Tact(N) = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h -# Tret(N) = now - IretZ = now - 38h -# Trem(N) = now - IretZ + Iret = now - 38h + 170h = now + 132h -# Tpub(N+1) = now - IretZ - IpubC = now - 38h - 3h = now - 41h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now - IretZ + Lcsk = now - 38h + 186d -# = now + 4426h -# Trem(N+1) = now - IretZ + Lcsk + Iret -# = now + 4426h + 3h = now + 4429h -TpubN="now-4502h" -TactN="now-4477h" -TretN="now-38h" -TremN="now+132h" -TpubN1="now-41h" -TactN1="${TretN}" -TretN1="now+4426h" -TremN1="now+4429h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $U $TretN -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $R $TactN1 -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 5: -# Some time later the DS can be swapped and the old DNSKEY can be removed from -# the zone. -setup step5.csk-roll2.autosign -# Subtract Iret (170h) - IretZ (38h) = 132h. -# -# Tpub(N) = now - 4502h - 132h = now - 4634h -# Tact(N) = now - 4477h - 132h = now - 4609h -# Tret(N) = now - 38h - 132h = now - 170h -# Trem(N) = now + 132h - 132h = now -# Tpub(N+1) = now - 41h - 132h = now - 173h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now + 4426h - 132h = now + 4294h -# Trem(N+1) = now + 4492h - 132h = now + 4360h -TpubN="now-4634h" -TactN="now-4609h" -TretN="now-170h" -TremN="now" -TpubN1="now-173h" -TactN1="${TretN}" -TretN1="now+4294h" -TremN1="now+4360h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $H now-133h -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O now-133h -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 6: -# Some time later the predecessor DNSKEY enters the HIDDEN state. -setup step6.csk-roll2.autosign -# Subtract DNSKEY TTL plus zone propagation delay (2h). -# -# Tpub(N) = now - 4634h - 2h = now - 4636h -# Tact(N) = now - 4609h - 2h = now - 4611h -# Tret(N) = now - 170h - 2h = now - 172h -# Trem(N) = now - 2h -# Tpub(N+1) = now - 173h - 2h = now - 175h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now + 4294h - 2h = now + 4292h -# Trem(N+1) = now + 4360h - 2h = now + 4358h -TpubN="now-4636h" -TactN="now-4611h" -TretN="now-172h" -TremN="now-2h" -TpubN1="now-175h" -TactN1="${TretN}" -TretN1="now+4292h" -TremN1="now+4358h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 7: -# The predecessor DNSKEY can be purged, but purge-keys is disabled. -setup step7.csk-roll2.autosign -# Subtract 90 days (default, 2160h) from all the times. -# -# Tpub(N) = now - 4636h - 2160h = now - 6796h -# Tact(N) = now - 4611h - 2160h = now - 6771h -# Tret(N) = now - 172h - 2160h = now - 2332h -# Trem(N) = now - 2h - 2160h = now - 2162h -# Tpub(N+1) = now - 175h - 2160h = now - 2335h -# Tact(N+1) = Tret(N) -# Tret(N+1) = now + 4292h - 2160h = now + 2132h -# Trem(N+1) = now + 4358h - 2160h = now + 2198h -TpubN="now-6796h" -TactN="now-6771h" -TretN="now-2332h" -TremN="now-2162h" -TpubN1="now-2335h" -TactN1="${TretN}" -TretN1="now+2132h" -TremN1="now+2198h" -keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" -newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" -CSK1=$($KEYGEN -k csk-roll2 -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-roll2 -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 -# Set key rollover relationship. -key_successor $CSK1 $CSK2 -# Sign zone. -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns6/csk1.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns6/csk1.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns6/csk1.conf.j2 2025-07-04 09:42:08.234325815 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns6/csk1.conf.j2 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +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. - */ - -dnssec-policy "csk-algoroll" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - keys { - csk lifetime unlimited algorithm rsasha256; - }; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - zone-propagation-delay 3600; - max-zone-ttl 6h; - parent-propagation-delay pt1h; - parent-ds-ttl 7200; -}; diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns6/csk2.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns6/csk2.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns6/csk2.conf.j2 2025-07-04 09:42:08.234325815 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns6/csk2.conf.j2 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +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. - */ - -dnssec-policy "csk-algoroll" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - }; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - zone-propagation-delay 3600; - max-zone-ttl 6h; - parent-propagation-delay pt1h; - parent-ds-ttl 7200; -}; diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns6/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns6/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns6/kasp.conf.j2 2025-07-04 09:42:08.235325838 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns6/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +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. - */ - -dnssec-policy "unlimited-lifetime" { - keys { - csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - }; -}; -dnssec-policy "short-lifetime" { - keys { - csk lifetime P6M algorithm @DEFAULT_ALGORITHM@; - }; -}; - -dnssec-policy "long-lifetime" { - keys { - csk lifetime P1Y algorithm @DEFAULT_ALGORITHM@; - }; -}; - -dnssec-policy "unsigning" { - dnskey-ttl 7200; - - keys { - ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; - zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; - }; -}; - -dnssec-policy "rsasha256" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - keys { - ksk lifetime unlimited algorithm rsasha256; - zsk lifetime unlimited algorithm rsasha256; - }; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - zone-propagation-delay 3600; - max-zone-ttl 6h; - parent-propagation-delay pt1h; - parent-ds-ttl 7200; -}; - -dnssec-policy "ecdsa256" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - keys { - ksk lifetime unlimited algorithm ecdsa256; - zsk lifetime unlimited algorithm ecdsa256; - }; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - zone-propagation-delay 3600; - max-zone-ttl 6h; - parent-propagation-delay pt1h; - parent-ds-ttl 7200; -}; - -{% if RSASHA1_SUPPORTED == "1" %} -dnssec-policy "rsasha1" { - signatures-refresh P5D; - signatures-validity 30d; - signatures-validity-dnskey 30d; - - keys { - ksk lifetime unlimited algorithm rsasha1; - zsk lifetime unlimited algorithm rsasha1; - }; - - dnskey-ttl 1h; - publish-safety PT1H; - retire-safety 2h; - zone-propagation-delay 3600; - max-zone-ttl 6h; - parent-propagation-delay pt1h; - parent-ds-ttl 7200; -}; -{% endif %} diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns6/named.conf.j2 2025-07-04 09:42:08.235325838 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns6/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +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. - */ - -// NS6 - -include "kasp.conf"; -include "csk1.conf"; - -options { - query-source address 10.53.0.6; - notify-source 10.53.0.6; - transfer-source 10.53.0.6; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.6; }; - listen-on-v6 { none; }; - allow-transfer { any; }; - recursion no; - key-directory "."; - dnssec-validation no; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { - type hint; - file "../../_common/root.hint.blackhole"; -}; - -/* This zone switch from dynamic to inline-signing. */ -zone "dynamic2inline.kasp" { - type primary; - file "dynamic2inline.kasp.db"; - allow-update { any; }; - dnssec-policy "default"; -}; - -/* Lifetime changes. */ -zone longer-lifetime { - type primary; - file "longer-lifetime.db"; - dnssec-policy short-lifetime; -}; - -zone shorter-lifetime { - type primary; - file "shorter-lifetime.db"; - dnssec-policy long-lifetime; -}; - -zone limit-lifetime { - type primary; - file "limit-lifetime.db"; - dnssec-policy unlimited-lifetime; -}; - -zone unlimit-lifetime { - type primary; - file "unlimit-lifetime.db"; - dnssec-policy short-lifetime; -}; - -/* These zones are going insecure. */ -zone "step1.going-insecure.kasp" { - type primary; - file "step1.going-insecure.kasp.db"; - dnssec-policy "unsigning"; -}; - -zone "step1.going-insecure-dynamic.kasp" { - type primary; - file "step1.going-insecure-dynamic.kasp.db"; - dnssec-policy "unsigning"; - inline-signing no; - allow-update { any; }; -}; - -zone "step1.going-straight-to-none.kasp" { - type primary; - file "step1.going-straight-to-none.kasp.db"; - dnssec-policy "default"; -}; - -zone "step1.going-straight-to-none-dynamic.kasp" { - type primary; - file "step1.going-straight-to-none-dynamic.kasp.db.signed"; - inline-signing no; - dnssec-policy "default"; - allow-update { any; }; -}; - -/* These are alorithm rollover test zones. */ -zone "step1.algorithm-roll.kasp" { - type primary; - file "step1.algorithm-roll.kasp.db"; - dnssec-policy "rsasha256"; -}; - -zone "step1.csk-algorithm-roll.kasp" { - type primary; - file "step1.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns6/named2.conf.j2 bind9-9.20.15/bin/tests/system/rollover/ns6/named2.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover/ns6/named2.conf.j2 2025-07-04 09:42:08.235325838 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns6/named2.conf.j2 1970-01-01 00:00:00.000000000 +0000 @@ -1,198 +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. - */ - -// NS6 - -include "kasp.conf"; -include "csk2.conf"; - -options { - query-source address 10.53.0.6; - notify-source 10.53.0.6; - transfer-source 10.53.0.6; - port @PORT@; - pid-file "named.pid"; - listen-on { 10.53.0.6; }; - listen-on-v6 { none; }; - allow-transfer { any; }; - recursion no; - dnssec-validation no; -}; - -key rndc_key { - secret "1234abcd8765"; - algorithm @DEFAULT_HMAC@; -}; - -controls { - inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; -}; - -zone "." { - type hint; - file "../../_common/root.hint.blackhole"; -}; - -/* This zone switch from dynamic to inline-signing. */ -zone "dynamic2inline.kasp" { - type primary; - file "dynamic2inline.kasp.db"; - allow-update { any; }; - dnssec-policy "default"; -}; - -/* Lifetime changes. */ -zone longer-lifetime { - type primary; - file "longer-lifetime.db"; - dnssec-policy long-lifetime; -}; - -zone shorter-lifetime { - type primary; - file "shorter-lifetime.db"; - dnssec-policy short-lifetime; -}; - -zone limit-lifetime { - type primary; - file "limit-lifetime.db"; - dnssec-policy short-lifetime; -}; - -zone unlimit-lifetime { - type primary; - file "unlimit-lifetime.db"; - dnssec-policy unlimited-lifetime; -}; - -/* Zones for testing going insecure. */ -zone "step1.going-insecure.kasp" { - type primary; - file "step1.going-insecure.kasp.db"; - dnssec-policy "insecure"; -}; - -zone "step2.going-insecure.kasp" { - type primary; - file "step2.going-insecure.kasp.db"; - dnssec-policy "insecure"; -}; - -zone "step1.going-insecure-dynamic.kasp" { - type primary; - file "step1.going-insecure-dynamic.kasp.db"; - inline-signing no; - dnssec-policy "insecure"; - allow-update { any; }; -}; - -zone "step2.going-insecure-dynamic.kasp" { - type primary; - file "step2.going-insecure-dynamic.kasp.db"; - inline-signing no; - dnssec-policy "insecure"; - allow-update { any; }; -}; - -zone "step1.going-straight-to-none.kasp" { - type primary; - file "step1.going-straight-to-none.kasp.db"; - dnssec-policy "none"; -}; - -zone "step1.going-straight-to-none-dynamic.kasp" { - type primary; - file "step1.going-straight-to-none-dynamic.kasp.db.signed"; - inline-signing no; - dnssec-policy "none"; - allow-update { any; }; -}; - -/* - * Zones for testing KSK/ZSK algorithm roll. - */ -zone "step1.algorithm-roll.kasp" { - type primary; - file "step1.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step2.algorithm-roll.kasp" { - type primary; - file "step2.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step3.algorithm-roll.kasp" { - type primary; - file "step3.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step4.algorithm-roll.kasp" { - type primary; - file "step4.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step5.algorithm-roll.kasp" { - type primary; - file "step5.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -zone "step6.algorithm-roll.kasp" { - type primary; - file "step6.algorithm-roll.kasp.db"; - dnssec-policy "ecdsa256"; -}; - -/* - * Zones for testing CSK algorithm roll. - */ -zone "step1.csk-algorithm-roll.kasp" { - type primary; - file "step1.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step2.csk-algorithm-roll.kasp" { - type primary; - file "step2.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step3.csk-algorithm-roll.kasp" { - type primary; - file "step3.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step4.csk-algorithm-roll.kasp" { - type primary; - file "step4.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step5.csk-algorithm-roll.kasp" { - type primary; - file "step5.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; - -zone "step6.csk-algorithm-roll.kasp" { - type primary; - file "step6.csk-algorithm-roll.kasp.db"; - dnssec-policy "csk-algoroll"; -}; diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns6/setup.sh bind9-9.20.15/bin/tests/system/rollover/ns6/setup.sh --- bind9-9.20.11/bin/tests/system/rollover/ns6/setup.sh 2025-07-04 09:42:08.235325838 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns6/setup.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,390 +0,0 @@ -#!/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 "ns6/setup.sh" - -setup() { - zone="$1" - echo_i "setting up zone: $zone" - zonefile="${zone}.db" - infile="${zone}.db.infile" -} - -# Make lines shorter by storing key states in environment variables. -H="HIDDEN" -R="RUMOURED" -O="OMNIPRESENT" -U="UNRETENTIVE" - -for zn in dynamic2inline.kasp shorter-lifetime longer-lifetime limit-lifetime \ - unlimit-lifetime; do - setup $zn - cp template.db.in $zonefile -done - -# The child zones (step1, step2) beneath these zones represent the various -# steps of unsigning a zone. -for zn in going-insecure.kasp going-insecure-dynamic.kasp; do - # Step 1: - # Set up a zone with dnssec-policy that is going insecure. - setup step1.$zn - echo "$zone" >>zones - T="now-10d" - S="now-12955mi" - keytimes="-P $T -A $T" - cdstimes="-P sync $S" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) - cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - - # Step 2: - # Set up a zone with dnssec-policy that is going insecure. Don't add - # this zone to the zones file, because this zone is no longer expected - # to be fully signed. - setup step2.$zn - # The DS was withdrawn from the parent zone 26 hours ago. - D="now-26h" - keytimes="-P $T -A $T -I $D -D now" - cdstimes="-P sync $S -D sync $D" - KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) - ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) - $SETTIME -s -g $H -k $O $T -r $O $T -d $U $D -D ds $D "$KSK" >settime.out.$zone.1 2>&1 - $SETTIME -s -g $H -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 - # Fake lifetime of old algorithm keys. - echo "Lifetime: 0" >>"${KSK}.state" - echo "Lifetime: 5184000" >>"${ZSK}.state" - cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" - private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" - cp $infile $zonefile - $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 -done - -# These zones are going straight to "none" policy. This is undefined behavior. -T="now-10d" -S="now-12955mi" -csktimes="-P $T -A $T -P sync $S" - -setup step1.going-straight-to-none.kasp -echo "$zone" >>zones -CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -setup step1.going-straight-to-none-dynamic.kasp -echo "$zone" >>zones -CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O full -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# -# The zones at algorithm-roll.kasp represent the various steps of a ZSK/KSK -# algorithm rollover. -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.algorithm-roll.kasp -echo "$zone" >>zones -TactN="now-7d" -TsbmN="now-161h" -ksktimes="-P ${TactN} -A ${TactN}" -zsktimes="-P ${TactN} -A ${TactN}" -KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) -ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 -cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" -private_type_record $zone 8 "$KSK" >>"$infile" -private_type_record $zone 8 "$ZSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 2: -# After the publication interval has passed the DNSKEY is OMNIPRESENT. -setup step2.algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 3 hours. -TpubN1="now-3h" -# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h -TsbmN1="now+4h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# The zone signatures are also OMNIPRESENT. -setup step3.algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 7 hours. -TpubN1="now-7h" -TsbmN1="now" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# The DS is swapped and can become OMNIPRESENT. -setup step4.algorithm-roll.kasp -# The time passed since the DS has been swapped is 3 hours. -TpubN1="now-10h" -TsbmN1="now-3h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 5: -# The DNSKEY is removed long enough to be HIDDEN. -setup step5.algorithm-roll.kasp -# The time passed since the DNSKEY has been removed is 2 hours. -TpubN1="now-12h" -TsbmN1="now-5h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 6: -# The RRSIGs have been removed long enough to be HIDDEN. -setup step6.algorithm-roll.kasp -# Additional time passed: 7h. -TpubN1="now-19h" -TsbmN1="now-12h" -ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" -ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -zsk2times="-P ${TpubN1} -A ${TpubN1}" -KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) -ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) -KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) -ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) -$SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${KSK1}.state" -echo "Lifetime: 0" >>"${ZSK1}.state" -cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" -private_type_record $zone 8 "$KSK1" >>"$infile" -private_type_record $zone 8 "$ZSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# -# The zones at csk-algorithm-roll.kasp represent the various steps of a CSK -# algorithm rollover. -# - -# Step 1: -# Introduce the first key. This will immediately be active. -setup step1.csk-algorithm-roll.kasp -echo "$zone" >>zones -TactN="now-7d" -TsbmN="now-161h" -csktimes="-P ${TactN} -A ${TactN}" -CSK=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -$SETTIME -s -g $O -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 -cat template.db.in "${CSK}.key" >"$infile" -private_type_record $zone 5 "$CSK" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 2: -# After the publication interval has passed the DNSKEY is OMNIPRESENT. -setup step2.csk-algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 3 hours. -TpubN1="now-3h" -# Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h -TsbmN1="now+4h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I now" -newtimes="-P ${TpubN1} -A ${TpubN1}" -CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 3: -# The zone signatures are also OMNIPRESENT. -setup step3.csk-algorithm-roll.kasp -# The time passed since the new algorithm keys have been introduced is 7 hours. -TpubN1="now-7h" -TsbmN1="now" -ckstimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 4: -# The DS is swapped and can become OMNIPRESENT. -setup step4.csk-algorithm-roll.kasp -# The time passed since the DS has been swapped is 3 hours. -TpubN1="now-10h" -TsbmN1="now-3h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TsbmN1 -d $U $TsbmN1 -D ds $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $R $TsbmN1 -P ds $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 5: -# The DNSKEY is removed long enough to be HIDDEN. -setup step5.csk-algorithm-roll.kasp -# The time passed since the DNSKEY has been removed is 2 hours. -TpubN1="now-12h" -TsbmN1="now-5h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $U $TactN -r $U $TactN -z $U $TsbmN1 -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 - -# Step 6: -# The RRSIGs have been removed long enough to be HIDDEN. -setup step6.csk-algorithm-roll.kasp -# Additional time passed: 7h. -TpubN1="now-19h" -TsbmN1="now-12h" -csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" -newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" -CSK1=$($KEYGEN -k csk-algoroll -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) -CSK2=$($KEYGEN -k csk-algoroll -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) -$SETTIME -s -g $H -k $H $TactN -r $U $TactN -z $U $TactN -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 -$SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O $TsubN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 -# Fake lifetime of old algorithm keys. -echo "Lifetime: 0" >>"${CSK1}.state" -cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" -private_type_record $zone 5 "$CSK1" >>"$infile" -private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" -cp $infile $zonefile -$SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff -Nru bind9-9.20.11/bin/tests/system/rollover/ns6/template.db.in bind9-9.20.15/bin/tests/system/rollover/ns6/template.db.in --- bind9-9.20.11/bin/tests/system/rollover/ns6/template.db.in 2025-07-04 09:42:08.235325838 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/ns6/template.db.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +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. - -$TTL 300 -@ IN SOA mname1. . ( - 1 ; serial - 20 ; refresh (20 seconds) - 20 ; retry (20 seconds) - 1814400 ; expire (3 weeks) - 3600 ; minimum (1 hour) - ) - - NS ns6 -ns6 A 10.53.0.6 - -a A 10.0.0.1 -b A 10.0.0.2 -c A 10.0.0.3 - diff -Nru bind9-9.20.11/bin/tests/system/rollover/setup.sh bind9-9.20.15/bin/tests/system/rollover/setup.sh --- bind9-9.20.11/bin/tests/system/rollover/setup.sh 2025-07-04 09:42:08.235325838 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/setup.sh 2025-10-18 10:16:12.464730767 +0000 @@ -14,13 +14,32 @@ # shellcheck source=conf.sh . ../conf.sh -set -e +cd "ns3" -( - cd ns3 - $SHELL setup.sh -) -( - cd ns6 - $SHELL setup.sh -) +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# Zone to test manual rollover. +setup manual-rollover.kasp +T="now-7d" +keytimes="-P $T -A $T" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" +cp $infile $zonefile +$SIGNER -PS -x -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff -Nru bind9-9.20.11/bin/tests/system/rollover/tests_rollover.py bind9-9.20.15/bin/tests/system/rollover/tests_rollover.py --- bind9-9.20.11/bin/tests/system/rollover/tests_rollover.py 2025-07-04 09:42:08.235325838 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/tests_rollover.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,1815 +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. - -import os -import shutil - -from datetime import timedelta - -import pytest - -pytest.importorskip("dns", minversion="2.0.0") -import dns.update - -import isctest -from isctest.kasp import KeyTimingMetadata - -pytestmark = pytest.mark.extra_artifacts( - [ - "*.axfr*", - "dig.out*", - "K*.key*", - "K*.private*", - "ns*/*.db", - "ns*/*.db.infile", - "ns*/*.db.jnl", - "ns*/*.db.jbk", - "ns*/*.db.signed", - "ns*/*.db.signed.jnl", - "ns*/*.conf", - "ns*/dsset-*", - "ns*/K*.key", - "ns*/K*.private", - "ns*/K*.state", - "ns*/keygen.out.*", - "ns*/settime.out.*", - "ns*/signer.out.*", - "ns*/zones", - ] -) - - -def Ipub(config): - return ( - config["dnskey-ttl"] - + config["zone-propagation-delay"] - + config["publish-safety"] - ) - - -def IpubC(config, rollover=True): - if rollover: - ttl = config["dnskey-ttl"] - safety_interval = config["publish-safety"] - else: - ttl = config["max-zone-ttl"] - safety_interval = timedelta(0) - - return ttl + config["zone-propagation-delay"] + safety_interval - - -def Iret(config, zsk=True, ksk=False, rollover=True): - sign_delay = timedelta(0) - safety_interval = timedelta(0) - if rollover: - sign_delay = config["signatures-validity"] - config["signatures-refresh"] - safety_interval = config["retire-safety"] - - iretKSK = timedelta(0) - if ksk: - # KSK: Double-KSK Method: Iret = DprpP + TTLds - iretKSK = ( - config["parent-propagation-delay"] + config["ds-ttl"] + safety_interval - ) - - iretZSK = timedelta(0) - if zsk: - # ZSK: Pre-Publication Method: Iret = Dsgn + Dprp + TTLsig - iretZSK = ( - sign_delay - + config["zone-propagation-delay"] - + config["max-zone-ttl"] - + safety_interval - ) - - return max(iretKSK, iretZSK) - - -def test_rollover_manual(servers): - server = servers["ns3"] - policy = "manual-rollover" - config = { - "dnskey-ttl": timedelta(hours=1), - "ds-ttl": timedelta(days=1), - "max-zone-ttl": timedelta(days=1), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(hours=1), - "retire-safety": timedelta(hours=1), - "signatures-refresh": timedelta(days=7), - "signatures-validity": timedelta(days=14), - "zone-propagation-delay": timedelta(minutes=5), - } - ttl = int(config["dnskey-ttl"].total_seconds()) - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - zone = "manual-rollover.kasp" - - with server.watch_log_from_start() as watcher: - watcher.wait_for_line(f"keymgr: {zone} done") - - isctest.kasp.check_dnssec_verify(server, zone) - - key_properties = [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent", - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent", - ] - expected = isctest.kasp.policy_to_properties(ttl, key_properties) - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - ksks = [k for k in keys if k.is_ksk()] - zsks = [k for k in keys if not k.is_ksk()] - - isctest.kasp.check_keys(zone, keys, expected) - - offset = -timedelta(days=7) - for kp in expected: - kp.set_expected_keytimes(config, offset=offset) - - isctest.kasp.check_keytimes(keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - # Schedule KSK rollover in six months. - assert len(ksks) == 1 - ksk = ksks[0] - startroll = expected[0].timing["Active"] + timedelta(days=30 * 6) - expected[0].timing["Retired"] = startroll + Ipub(config) - expected[0].timing["Removed"] = expected[0].timing["Retired"] + Iret( - config, zsk=False, ksk=True - ) - - with server.watch_log_from_here() as watcher: - server.rndc(f"dnssec -rollover -key {ksk.tag} -when {startroll} {zone}") - watcher.wait_for_line(f"keymgr: {zone} done") - - isctest.kasp.check_dnssec_verify(server, zone) - isctest.kasp.check_keys(zone, keys, expected) - isctest.kasp.check_keytimes(keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - # Schedule KSK rollover now. - now = KeyTimingMetadata.now() - with server.watch_log_from_here() as watcher: - server.rndc(f"dnssec -rollover -key {ksk.tag} -when {now} {zone}") - watcher.wait_for_line(f"keymgr: {zone} done") - - isctest.kasp.check_dnssec_verify(server, zone) - - key_properties = [ - f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent", - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent", - ] - expected = isctest.kasp.policy_to_properties(ttl, key_properties) - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - ksks = [k for k in keys if k.is_ksk()] - zsks = [k for k in keys if not k.is_ksk()] - - isctest.kasp.check_keys(zone, keys, expected) - - expected[0].metadata["Successor"] = expected[1].key.tag - expected[1].metadata["Predecessor"] = expected[0].key.tag - isctest.kasp.check_keyrelationships(keys, expected) - - for kp in expected: - off = offset - if "Predecessor" in kp.metadata: - off = 0 - kp.set_expected_keytimes(config, offset=off) - - expected[0].timing["Retired"] = now + Ipub(config) - expected[0].timing["Removed"] = expected[0].timing["Retired"] + Iret( - config, zsk=False, ksk=True - ) - - isctest.kasp.check_keytimes(keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - # Schedule ZSK rollover now. - assert len(zsks) == 1 - zsk = zsks[0] - now = KeyTimingMetadata.now() - with server.watch_log_from_here() as watcher: - server.rndc(f"dnssec -rollover -key {zsk.tag} -when {now} {zone}") - watcher.wait_for_line(f"keymgr: {zone} done") - - isctest.kasp.check_dnssec_verify(server, zone) - - key_properties = [ - f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent", - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", - f"zsk unlimited {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent", - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden", - ] - expected = isctest.kasp.policy_to_properties(ttl, key_properties) - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - ksks = [k for k in keys if k.is_ksk()] - zsks = [k for k in keys if not k.is_ksk()] - - isctest.kasp.check_keys(zone, keys, expected) - - expected[0].metadata["Successor"] = expected[1].key.tag - expected[1].metadata["Predecessor"] = expected[0].key.tag - expected[2].metadata["Successor"] = expected[3].key.tag - expected[3].metadata["Predecessor"] = expected[2].key.tag - isctest.kasp.check_keyrelationships(keys, expected) - - # Try to schedule a ZSK rollover for an inactive key (should fail). - zsk = expected[3].key - response = server.rndc(f"dnssec -rollover -key {zsk.tag} {zone}") - assert "key is not actively signing" in response - - -def test_rollover_multisigner(servers): - server = servers["ns3"] - policy = "multisigner-model2" - config = { - "dnskey-ttl": timedelta(hours=1), - "ds-ttl": timedelta(days=1), - "max-zone-ttl": timedelta(days=1), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(hours=1), - "retire-safety": timedelta(hours=1), - "signatures-refresh": timedelta(days=5), - "signatures-validity": timedelta(days=14), - "zone-propagation-delay": timedelta(minutes=5), - } - ttl = int(config["dnskey-ttl"].total_seconds()) - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - - offset = -timedelta(days=7) - offval = int(offset.total_seconds()) - - def keygen(zone): - keygen_command = [ - os.environ.get("KEYGEN"), - "-a", - alg, - "-L", - "3600", - "-M", - "0:32767", - zone, - ] - - return isctest.run.cmd(keygen_command).stdout.decode("utf-8") - - zone = "multisigner-model2.kasp" - - isctest.kasp.check_dnssec_verify(server, zone) - - key_properties = [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535", - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured tag-range:32768-65535", - ] - expected = isctest.kasp.policy_to_properties(ttl, key_properties) - - newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"] - expected2 = isctest.kasp.policy_to_properties(ttl, newprops) - expected2[0].properties["private"] = False - expected2[0].properties["legacy"] = True - expected = expected + expected2 - - ownkeys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - extkeys = isctest.kasp.keydir_to_keylist(zone) - keys = ownkeys + extkeys - ksks = [k for k in ownkeys if k.is_ksk()] - zsks = [k for k in ownkeys if not k.is_ksk()] - zsks = zsks + extkeys - - isctest.kasp.check_keys(zone, keys, expected) - for kp in expected: - kp.set_expected_keytimes(config) - isctest.kasp.check_keytimes(keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - # Update zone with ZSK from another provider for zone. - out = keygen(zone) - newkeys = isctest.kasp.keystr_to_keylist(out) - newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"] - expected2 = isctest.kasp.policy_to_properties(ttl, newprops) - expected2[0].properties["private"] = False - expected2[0].properties["legacy"] = True - expected = expected + expected2 - - dnskey = newkeys[0].dnskey().split() - rdata = " ".join(dnskey[4:]) - - update_msg = dns.update.UpdateMessage(zone) - update_msg.add(f"{dnskey[0]}", 3600, "DNSKEY", rdata) - server.nsupdate(update_msg) - - isctest.kasp.check_dnssec_verify(server, zone) - - keys = keys + newkeys - zsks = zsks + newkeys - isctest.kasp.check_keys(zone, keys, expected) - isctest.kasp.check_apex(server, zone, ksks, zsks) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - # Remove ZSKs from the other providers for zone. - dnskey2 = extkeys[0].dnskey().split() - rdata2 = " ".join(dnskey2[4:]) - update_msg = dns.update.UpdateMessage(zone) - update_msg.delete(f"{dnskey[0]}", "DNSKEY", rdata) - update_msg.delete(f"{dnskey2[0]}", "DNSKEY", rdata2) - server.nsupdate(update_msg) - - isctest.kasp.check_dnssec_verify(server, zone) - - expected = isctest.kasp.policy_to_properties(ttl, key_properties) - keys = ownkeys - ksks = [k for k in ownkeys if k.is_ksk()] - zsks = [k for k in ownkeys if not k.is_ksk()] - isctest.kasp.check_keys(zone, keys, expected) - isctest.kasp.check_apex(server, zone, ksks, zsks) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - # A zone transitioning from single-signed to multi-signed. We should have - # the old omnipresent keys outside of the desired key range and the new - # keys in the desired key range. - zone = "single-to-multisigner.kasp" - - isctest.kasp.check_dnssec_verify(server, zone) - - key_properties = [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535", - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden tag-range:32768-65535", - f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent tag-range:0-32767 offset:{offval}", - f"zsk unlimited {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent tag-range:0-32767 offset:{offval}", - ] - expected = isctest.kasp.policy_to_properties(ttl, key_properties) - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - ksks = [k for k in keys if k.is_ksk()] - zsks = [k for k in keys if not k.is_ksk()] - - isctest.kasp.check_keys(zone, keys, expected) - - for kp in expected: - kp.set_expected_keytimes(config) - - start = expected[0].key.get_timing("Created") - expected[2].timing["Retired"] = start - expected[2].timing["Removed"] = expected[2].timing["Retired"] + Iret( - config, zsk=False, ksk=True - ) - expected[3].timing["Retired"] = start - expected[3].timing["Removed"] = expected[3].timing["Retired"] + Iret( - config, zsk=True, ksk=False - ) - - isctest.kasp.check_keytimes(keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - -def check_rollover_step(server, config, policy, step): - zone = step["zone"] - keyprops = step["keyprops"] - nextev = step["nextev"] - cdss = step.get("cdss", None) - keyrelationships = step.get("keyrelationships", None) - smooth = step.get("smooth", False) - ds_swap = step.get("ds-swap", True) - cds_delete = step.get("cds-delete", False) - check_keytimes = step.get("check-keytimes", True) - zone_signed = step.get("zone-signed", True) - - isctest.log.info(f"check rollover step {zone}") - - if zone_signed: - isctest.kasp.check_dnssec_verify(server, zone) - - ttl = int(config["dnskey-ttl"].total_seconds()) - expected = isctest.kasp.policy_to_properties(ttl, keyprops) - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - ksks = [k for k in keys if k.is_ksk()] - zsks = [k for k in keys if not k.is_ksk()] - isctest.kasp.check_keys(zone, keys, expected) - - for kp in expected: - key = kp.key - - # Set expected key timing metadata. - kp.set_expected_keytimes(config) - - # Set rollover relationships. - if keyrelationships is not None: - prd = keyrelationships[0] - suc = keyrelationships[1] - expected[prd].metadata["Successor"] = expected[suc].key.tag - expected[suc].metadata["Predecessor"] = expected[prd].key.tag - isctest.kasp.check_keyrelationships(keys, expected) - - # Policy changes may retire keys, set expected timing metadata. - if kp.metadata["GoalState"] == "hidden" and "Retired" not in kp.timing: - retired = kp.key.get_timing("Inactive") - kp.timing["Retired"] = retired - kp.timing["Removed"] = retired + Iret( - config, zsk=key.is_zsk(), ksk=key.is_ksk() - ) - - # Check that CDS publication/withdrawal is logged. - if "KSK" not in kp.metadata: - continue - if kp.metadata["KSK"] == "no": - continue - - if ds_swap and kp.metadata["DSState"] == "rumoured": - assert cdss is not None - for algstr in ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"]: - if algstr in cdss: - isctest.kasp.check_cdslog(server, zone, key, algstr) - else: - isctest.kasp.check_cdslog_prohibit(server, zone, key, algstr) - - # The DS can be introduced. We ignore any parent registration delay, - # so set the DS publish time to now. - server.rndc(f"dnssec -checkds -key {key.tag} published {zone}") - - if ds_swap and kp.metadata["DSState"] == "unretentive": - # The DS can be withdrawn. We ignore any parent registration - # delay, so set the DS withdraw time to now. - server.rndc(f"dnssec -checkds -key {key.tag} withdrawn {zone}") - - if check_keytimes: - isctest.kasp.check_keytimes(keys, expected) - - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss, cds_delete=cds_delete) - isctest.kasp.check_subdomain(server, zone, ksks, zsks, smooth=smooth) - - def check_next_key_event(): - return isctest.kasp.next_key_event_equals(server, zone, nextev) - - isctest.run.retry_with_timeout(check_next_key_event, timeout=5) - - -def test_rollover_enable_dnssec(servers): - server = servers["ns3"] - policy = "enable-dnssec" - cdss = ["CDNSKEY", "CDS (SHA-256)"] - config = { - "dnskey-ttl": timedelta(seconds=300), - "ds-ttl": timedelta(hours=2), - "max-zone-ttl": timedelta(hours=12), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(minutes=5), - "retire-safety": timedelta(minutes=20), - "signatures-refresh": timedelta(days=7), - "signatures-validity": timedelta(days=14), - "zone-propagation-delay": timedelta(minutes=5), - } - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - - ipub = Ipub(config) - ipubC = IpubC(config, rollover=False) - iretZSK = Iret(config, rollover=False) - iretKSK = Iret(config, zsk=False, ksk=True, rollover=False) - offsets = { - "step1": 0, - "step2": -int(ipub.total_seconds()), - "step3": -int(iretZSK.total_seconds()), - "step4": -int(ipubC.total_seconds() + iretKSK.total_seconds()), - } - - steps = [ - { - # Step 1. - "zone": "step1.enable-dnssec.autosign", - "cdss": cdss, - "keyprops": [ - f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden offset:{offsets['step1']}", - ], - # Next key event is when the DNSKEY RRset becomes OMNIPRESENT, - # after the publication interval. - "nextev": ipub, - }, - { - # Step 2. - "zone": "step2.enable-dnssec.autosign", - "cdss": cdss, - # The DNSKEY is omnipresent, but the zone signatures not yet. - # Thus, the DS remains hidden. - # dnskey: rumoured -> omnipresent - # krrsig: rumoured -> omnipresent - "keyprops": [ - f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{offsets['step2']}", - ], - # Next key event is when the zone signatures become OMNIPRESENT, - # Minus the time already elapsed. - "nextev": iretZSK - ipub, - }, - { - # Step 3. - "zone": "step3.enable-dnssec.autosign", - "cdss": cdss, - # All signatures should be omnipresent, so the DS can be submitted. - # zrrsig: rumoured -> omnipresent - # ds: hidden -> rumoured - "keyprops": [ - f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{offsets['step3']}", - ], - # Next key event is when the DS can move to the OMNIPRESENT state. - # This is after the retire interval. - "nextev": iretKSK, - }, - { - # Step 4. - "zone": "step4.enable-dnssec.autosign", - "cdss": cdss, - # DS has been published long enough. - # ds: rumoured -> omnipresent - "keyprops": [ - f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step4']}", - ], - # Next key event is never, the zone dnssec-policy has been - # established. So we fall back to the default loadkeys interval. - "nextev": timedelta(hours=1), - }, - ] - - for step in steps: - check_rollover_step(server, config, policy, step) - - -def test_rollover_zsk_prepublication(servers): - server = servers["ns3"] - policy = "zsk-prepub" - config = { - "dnskey-ttl": timedelta(seconds=3600), - "ds-ttl": timedelta(days=1), - "max-zone-ttl": timedelta(days=1), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(days=1), - "purge-keys": timedelta(hours=1), - "retire-safety": timedelta(days=2), - "signatures-refresh": timedelta(days=7), - "signatures-validity": timedelta(days=14), - "zone-propagation-delay": timedelta(hours=1), - } - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - zsk_lifetime = timedelta(days=30) - lifetime_policy = int(zsk_lifetime.total_seconds()) - - ipub = Ipub(config) - iret = Iret(config, rollover=True) - keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"] - offsets = {} - offsets["step1-p"] = -int(timedelta(days=7).total_seconds()) - offsets["step2-p"] = -int(zsk_lifetime.total_seconds() - ipub.total_seconds()) - offsets["step2-s"] = 0 - offsets["step3-p"] = -int(zsk_lifetime.total_seconds()) - offsets["step3-s"] = -int(ipub.total_seconds()) - offsets["step4-p"] = offsets["step3-p"] - int(iret.total_seconds()) - offsets["step4-s"] = offsets["step3-s"] - int(iret.total_seconds()) - offsets["step5-p"] = offsets["step4-p"] - int(keyttlprop.total_seconds()) - offsets["step5-s"] = offsets["step4-s"] - int(keyttlprop.total_seconds()) - offsets["step6-p"] = offsets["step5-p"] - int(config["purge-keys"].total_seconds()) - offsets["step6-s"] = offsets["step5-s"] - int(config["purge-keys"].total_seconds()) - - steps = [ - { - # Step 1. - # Introduce the first key. This will immediately be active. - "zone": "step1.zsk-prepub.autosign", - "keyprops": [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step1-p']}", - ], - # Next key event is when the successor ZSK needs to be published. - # That is the ZSK lifetime - prepublication time (minus time - # already passed). - "nextev": zsk_lifetime - ipub - timedelta(days=7), - }, - { - # Step 2. - # It is time to pre-publish the successor ZSK. - # ZSK1 goal: omnipresent -> hidden - # ZSK2 goal: hidden -> omnipresent - # ZSK2 dnskey: hidden -> rumoured - "zone": "step2.zsk-prepub.autosign", - "keyprops": [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step2-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden offset:{offsets['step2-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when the successor ZSK becomes OMNIPRESENT. - # That is the DNSKEY TTL plus the zone propagation delay - "nextev": ipub, - }, - { - # Step 3. - # Predecessor ZSK is no longer actively signing. Successor ZSK is - # now actively signing. - # ZSK1 zrrsig: omnipresent -> unretentive - # ZSK2 dnskey: rumoured -> omnipresent - # ZSK2 zrrsig: hidden -> rumoured - "zone": "step3.zsk-prepub.autosign", - "keyprops": [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step3-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:unretentive offset:{offsets['step3-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{offsets['step3-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when all the RRSIG records have been replaced - # with signatures of the new ZSK, in other words when ZRRSIG - # becomes OMNIPRESENT. - "nextev": iret, - # Set 'smooth' to true so expected signatures of subdomain are - # from the predecessor ZSK. - "smooth": True, - }, - { - # Step 4. - # Predecessor ZSK is no longer needed. All RRsets are signed with - # the successor ZSK. - # ZSK1 dnskey: omnipresent -> unretentive - # ZSK1 zrrsig: unretentive -> hidden - # ZSK2 zrrsig: rumoured -> omnipresent - "zone": "step4.zsk-prepub.autosign", - "keyprops": [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive zrrsig:hidden offset:{offsets['step4-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when the DNSKEY enters the HIDDEN state. - # This is the DNSKEY TTL plus zone propagation delay. - "nextev": keyttlprop, - }, - { - # Step 5. - # Predecessor ZSK is now removed. - # ZSK1 dnskey: unretentive -> hidden - "zone": "step5.zsk-prepub.autosign", - "keyprops": [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden zrrsig:hidden offset:{offsets['step5-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when the new successor needs to be published. - # This is the ZSK lifetime minus Iret minus Ipub minus time - # elapsed. - "nextev": zsk_lifetime - iret - ipub - keyttlprop, - }, - { - # Step 6. - # Predecessor ZSK is now purged. - "zone": "step6.zsk-prepub.autosign", - "keyprops": [ - f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6-p']}", - f"zsk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6-s']}", - ], - "nextev": None, - }, - ] - - for step in steps: - check_rollover_step(server, config, policy, step) - - -def test_rollover_ksk_doubleksk(servers): - server = servers["ns3"] - policy = "ksk-doubleksk" - cdss = ["CDS (SHA-256)"] - config = { - "dnskey-ttl": timedelta(hours=2), - "ds-ttl": timedelta(seconds=3600), - "max-zone-ttl": timedelta(days=1), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(days=1), - "purge-keys": timedelta(hours=1), - "retire-safety": timedelta(days=2), - "signatures-refresh": timedelta(days=7), - "signatures-validity": timedelta(days=14), - "zone-propagation-delay": timedelta(hours=1), - } - ttl = int(config["dnskey-ttl"].total_seconds()) - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - ksk_lifetime = timedelta(days=60) - lifetime_policy = int(ksk_lifetime.total_seconds()) - - ipub = Ipub(config) - ipubc = IpubC(config) - iret = Iret(config, zsk=False, ksk=True) - keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"] - offsets = {} - offsets["step1-p"] = -int(timedelta(days=7).total_seconds()) - offsets["step2-p"] = -int(ksk_lifetime.total_seconds() - ipubc.total_seconds()) - offsets["step2-s"] = 0 - offsets["step3-p"] = -int(ksk_lifetime.total_seconds()) - offsets["step3-s"] = -int(ipubc.total_seconds()) - offsets["step4-p"] = offsets["step3-p"] - int(iret.total_seconds()) - offsets["step4-s"] = offsets["step3-s"] - int(iret.total_seconds()) - offsets["step5-p"] = offsets["step4-p"] - int(keyttlprop.total_seconds()) - offsets["step5-s"] = offsets["step4-s"] - int(keyttlprop.total_seconds()) - offsets["step6-p"] = offsets["step5-p"] - int(config["purge-keys"].total_seconds()) - offsets["step6-s"] = offsets["step5-s"] - int(config["purge-keys"].total_seconds()) - - steps = [ - { - # Step 1. - # Introduce the first key. This will immediately be active. - "zone": "step1.ksk-doubleksk.autosign", - "cdss": cdss, - "keyprops": [ - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step1-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}", - ], - # Next key event is when the successor KSK needs to be published. - # That is the KSK lifetime - prepublication time (minus time - # already passed). - "nextev": ksk_lifetime - ipub - timedelta(days=7), - }, - { - # Step 2. - # Successor KSK is prepublished (and signs DNSKEY RRset). - # KSK1 goal: omnipresent -> hidden - # KSK2 goal: hidden -> omnipresent - # KSK2 dnskey: hidden -> rumoured - # KSK2 krrsig: hidden -> rumoured - "zone": "step2.ksk-doubleksk.autosign", - "cdss": cdss, - "keyprops": [ - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step2-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:{offsets['step2-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when the successor KSK becomes OMNIPRESENT. - "nextev": ipub, - }, - { - # Step 3. - # The successor DNSKEY RRset has become omnipresent. The - # predecessor DS can be withdrawn and the successor DS can be - # introduced. - # KSK1 ds: omnipresent -> unretentive - # KSK2 dnskey: rumoured -> omnipresent - # KSK2 krrsig: rumoured -> omnipresent - # KSK2 ds: hidden -> rumoured - "zone": "step3.ksk-doubleksk.autosign", - "cdss": cdss, - "keyprops": [ - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step3-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offsets['step3-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offsets['step3-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when the predecessor DS has been replaced with - # the successor DS and enough time has passed such that the all - # validators that have this DS RRset cached only know about the - # successor DS. This is the the retire interval. - "nextev": iret, - }, - { - # Step 4. - # The predecessor DNSKEY may be removed, the successor DS is - # omnipresent. - # KSK1 dnskey: omnipresent -> unretentive - # KSK1 krrsig: omnipresent -> unretentive - # KSK1 ds: unretentive -> hidden - # KSK2 ds: rumoured -> omnipresent - "zone": "step4.ksk-doubleksk.autosign", - "cdss": cdss, - "keyprops": [ - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offsets['step4-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when the DNSKEY enters the HIDDEN state. - # This is the DNSKEY TTL plus zone propagation delay. - "nextev": keyttlprop, - }, - { - # Step 5. - # The predecessor DNSKEY is long enough removed from the zone it - # has become hidden. - # KSK1 dnskey: unretentive -> hidden - # KSK1 krrsig: unretentive -> hidden - "zone": "step5.ksk-doubleksk.autosign", - "cdss": cdss, - "keyprops": [ - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offsets['step5-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5-s']}", - ], - "keyrelationships": [1, 2], - # Next key event is when the new successor needs to be published. - # This is the KSK lifetime minus Ipub minus Iret minus time elapsed. - "nextev": ksk_lifetime - ipub - iret - keyttlprop, - }, - { - # Step 6. - # Predecessor KSK is now purged. - "zone": "step6.ksk-doubleksk.autosign", - "cdss": cdss, - "keyprops": [ - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6-p']}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6-s']}", - ], - "nextev": None, - }, - ] - - for step in steps: - check_rollover_step(server, config, policy, step) - - # Test #2375: Scheduled rollovers are happening faster than they can finish. - zone = "three-is-a-crowd.kasp" - isctest.log.info( - "check that fast rollovers do not remove dependent keys from zone (#2375)" - ) - offset1 = -int(timedelta(days=60).total_seconds()) - offset2 = -int(timedelta(hours=27).total_seconds()) - isctest.kasp.check_dnssec_verify(server, zone) - keyprops = [ - f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offset1}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offset2}", - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offset1}", - ] - expected = isctest.kasp.policy_to_properties(ttl, keyprops) - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - ksks = [k for k in keys if k.is_ksk()] - zsks = [k for k in keys if not k.is_ksk()] - isctest.kasp.check_keys(zone, keys, expected) - expected[0].metadata["Successor"] = expected[1].key.tag - expected[1].metadata["Predecessor"] = expected[0].key.tag - isctest.kasp.check_keyrelationships(keys, expected) - for kp in expected: - kp.set_expected_keytimes(config, offset=None) - isctest.kasp.check_keytimes(keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - # Rollover successor KSK (with DS in rumoured state). - key = expected[1].key - now = KeyTimingMetadata.now() - with server.watch_log_from_here() as watcher: - server.rndc(f"dnssec -rollover -key {key.tag} -when {now} {zone}") - watcher.wait_for_line(f"keymgr: {zone} done") - isctest.kasp.check_dnssec_verify(server, zone) - # We now expect four keys (3x KSK, 1x ZSK). - keyprops = [ - f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offset1}", - f"ksk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offset2}", - f"ksk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:0", - f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offset1}", - ] - expected = isctest.kasp.policy_to_properties(ttl, keyprops) - keys = isctest.kasp.keydir_to_keylist(zone, server.identifier) - ksks = [k for k in keys if k.is_ksk()] - zsks = [k for k in keys if not k.is_ksk()] - isctest.kasp.check_keys(zone, keys, expected) - expected[0].metadata["Successor"] = expected[1].key.tag - expected[1].metadata["Predecessor"] = expected[0].key.tag - # Three is a crowd scenario. - expected[1].metadata["Successor"] = expected[2].key.tag - expected[2].metadata["Predecessor"] = expected[1].key.tag - isctest.kasp.check_keyrelationships(keys, expected) - for kp in expected: - kp.set_expected_keytimes(config, offset=None) - # The first successor KSK is already being retired. - expected[1].timing["Retired"] = now + ipub - expected[1].timing["Removed"] = now + ipub + iret - isctest.kasp.check_keytimes(keys, expected) - isctest.kasp.check_dnssecstatus(server, zone, keys, policy=policy) - isctest.kasp.check_apex(server, zone, ksks, zsks, cdss=cdss) - isctest.kasp.check_subdomain(server, zone, ksks, zsks) - - -def test_rollover_csk_roll1(servers): - server = servers["ns3"] - policy = "csk-roll1" - cdss = ["CDNSKEY", "CDS (SHA-384)"] - config = { - "dnskey-ttl": timedelta(hours=1), - "ds-ttl": timedelta(seconds=3600), - "max-zone-ttl": timedelta(days=1), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(hours=1), - "purge-keys": timedelta(hours=1), - "retire-safety": timedelta(hours=2), - "signatures-refresh": timedelta(days=5), - "signatures-validity": timedelta(days=30), - "zone-propagation-delay": timedelta(hours=1), - } - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - csk_lifetime = timedelta(days=31 * 6) - lifetime_policy = int(csk_lifetime.total_seconds()) - - ipub = Ipub(config) - iretZSK = Iret(config) - iretKSK = Iret(config, zsk=False, ksk=True) - keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"] - signdelay = iretZSK - iretKSK - keyttlprop - offsets = {} - offsets["step1-p"] = -int(timedelta(days=7).total_seconds()) - offsets["step2-p"] = -int(csk_lifetime.total_seconds() - ipub.total_seconds()) - offsets["step2-s"] = 0 - offsets["step3-p"] = -int(csk_lifetime.total_seconds()) - offsets["step3-s"] = -int(ipub.total_seconds()) - offsets["step4-p"] = offsets["step3-p"] - int(iretKSK.total_seconds()) - offsets["step4-s"] = offsets["step3-s"] - int(iretKSK.total_seconds()) - offsets["step5-p"] = offsets["step4-p"] - int(keyttlprop.total_seconds()) - offsets["step5-s"] = offsets["step4-s"] - int(keyttlprop.total_seconds()) - offsets["step6-p"] = offsets["step5-p"] - int(signdelay.total_seconds()) - offsets["step6-s"] = offsets["step5-s"] - int(signdelay.total_seconds()) - offsets["step7-p"] = offsets["step6-p"] - int(keyttlprop.total_seconds()) - offsets["step7-s"] = offsets["step6-s"] - int(keyttlprop.total_seconds()) - offsets["step8-p"] = offsets["step7-p"] - int(config["purge-keys"].total_seconds()) - offsets["step8-s"] = offsets["step7-s"] - int(config["purge-keys"].total_seconds()) - - steps = [ - { - # Step 1. - # Introduce the first key. This will immediately be active. - "zone": "step1.csk-roll1.autosign", - "cdss": cdss, - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}", - ], - # Next key event is when the successor CSK needs to be published - # minus time already elapsed. This is Lcsk - Ipub + Dreg (we ignore - # registration delay). - "nextev": csk_lifetime - ipub - timedelta(days=7), - }, - { - # Step 2. - # Successor CSK is prepublished (signs DNSKEY RRset, but not yet - # other RRsets). - # CSK1 goal: omnipresent -> hidden - # CSK2 goal: hidden -> omnipresent - # CSK2 dnskey: hidden -> rumoured - # CSK2 krrsig: hidden -> rumoured - "zone": "step2.csk-roll1.autosign", - "cdss": cdss, - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:hidden ds:hidden offset:{offsets['step2-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the successor CSK becomes OMNIPRESENT. - "nextev": ipub, - }, - { - # Step 3. - # Successor CSK becomes omnipresent, meaning we can start signing - # the remainder of the zone with the successor CSK, and we can - # submit the DS. - "zone": "step3.csk-roll1.autosign", - "cdss": cdss, - # Predecessor CSK will be removed, so moving to UNRETENTIVE. - # CSK1 zrrsig: omnipresent -> unretentive - # Successor CSK DNSKEY is OMNIPRESENT, so moving ZRRSIG to RUMOURED. - # CSK2 dnskey: rumoured -> omnipresent - # CSK2 krrsig: rumoured -> omnipresent - # CSK2 zrrsig: hidden -> rumoured - # The predecessor DS can be withdrawn and the successor DS can be - # introduced. - # CSK1 ds: omnipresent -> unretentive - # CSK2 ds: hidden -> rumoured - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:unretentive offset:{offsets['step3-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:rumoured offset:{offsets['step3-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the predecessor DS has been replaced with - # the successor DS and enough time has passed such that the all - # validators that have this DS RRset cached only know about the - # successor DS. This is the the retire interval. - "nextev": iretKSK, - # Set 'smooth' to true so expected signatures of subdomain are - # from the predecessor ZSK. - "smooth": True, - }, - { - # Step 4. - "zone": "step4.csk-roll1.autosign", - "cdss": cdss, - # The predecessor CSK is no longer signing the DNSKEY RRset. - # CSK1 krrsig: omnipresent -> unretentive - # The predecessor DS is hidden. The successor DS is now omnipresent. - # CSK1 ds: unretentive -> hidden - # CSK2 ds: rumoured -> omnipresent - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:unretentive zrrsig:unretentive ds:hidden offset:{offsets['step4-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{offsets['step4-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the KRRSIG enters the HIDDEN state. - # This is the DNSKEY TTL plus zone propagation delay. - "nextev": keyttlprop, - # We already swapped the DS in the previous step, so disable ds-swap. - "ds-swap": False, - }, - { - # Step 5. - "zone": "step5.csk-roll1.autosign", - "cdss": cdss, - # The predecessor KRRSIG records are now all hidden. - # CSK1 krrsig: unretentive -> hidden - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:hidden zrrsig:unretentive ds:hidden offset:{offsets['step5-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{offsets['step5-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the DNSKEY can be removed. This is when - # all ZRRSIG records have been replaced with signatures of the new - # CSK. - "nextev": signdelay, - }, - { - # Step 6. - "zone": "step6.csk-roll1.autosign", - "cdss": cdss, - # The predecessor ZRRSIG records are now all hidden (so the DNSKEY - # can be removed). - # CSK1 dnskey: omnipresent -> unretentive - # CSK1 zrrsig: unretentive -> hidden - # CSK2 zrrsig: rumoured -> omnipresent - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive krrsig:hidden zrrsig:hidden ds:hidden offset:{offsets['step6-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step6-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the DNSKEY enters the HIDDEN state. - # This is the DNSKEY TTL plus zone propagation delay. - "nextev": keyttlprop, - }, - { - # Step 7. - "zone": "step7.csk-roll1.autosign", - "cdss": cdss, - # The predecessor CSK is now completely HIDDEN. - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{offsets['step7-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step7-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the new successor needs to be published. - # This is the Lcsk, minus time passed since the key started signing, - # minus the prepublication time. - "nextev": csk_lifetime - iretZSK - ipub - keyttlprop, - }, - { - # Step 8. - # Predecessor CSK is now purged. - "zone": "step8.csk-roll1.autosign", - "cdss": cdss, - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step8-s']}", - ], - "nextev": None, - }, - ] - - for step in steps: - check_rollover_step(server, config, policy, step) - - -def test_rollover_csk_roll2(servers): - server = servers["ns3"] - policy = "csk-roll2" - cdss = ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"] - config = { - "dnskey-ttl": timedelta(hours=1), - "ds-ttl": timedelta(seconds=3600), - "max-zone-ttl": timedelta(days=1), - "parent-propagation-delay": timedelta(days=7), - "publish-safety": timedelta(hours=1), - "purge-keys": timedelta(0), - "retire-safety": timedelta(hours=1), - "signatures-refresh": timedelta(hours=12), - "signatures-validity": timedelta(days=1), - "zone-propagation-delay": timedelta(hours=1), - } - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - csk_lifetime = timedelta(days=31 * 6) - lifetime_policy = int(csk_lifetime.total_seconds()) - - ipub = Ipub(config) - iret = Iret(config, zsk=True, ksk=True) - iretZSK = Iret(config) - iretKSK = Iret(config, ksk=True) - keyttlprop = config["dnskey-ttl"] + config["zone-propagation-delay"] - offsets = {} - offsets["step1-p"] = -int(timedelta(days=7).total_seconds()) - offsets["step2-p"] = -int(csk_lifetime.total_seconds() - ipub.total_seconds()) - offsets["step2-s"] = 0 - offsets["step3-p"] = -int(csk_lifetime.total_seconds()) - offsets["step3-s"] = -int(ipub.total_seconds()) - offsets["step4-p"] = offsets["step3-p"] - int(iretZSK.total_seconds()) - offsets["step4-s"] = offsets["step3-s"] - int(iretZSK.total_seconds()) - offsets["step5-p"] = offsets["step4-p"] - int( - iretKSK.total_seconds() - iretZSK.total_seconds() - ) - offsets["step5-s"] = offsets["step4-s"] - int( - iretKSK.total_seconds() - iretZSK.total_seconds() - ) - offsets["step6-p"] = offsets["step5-p"] - int(keyttlprop.total_seconds()) - offsets["step6-s"] = offsets["step5-s"] - int(keyttlprop.total_seconds()) - offsets["step7-p"] = offsets["step6-p"] - int(timedelta(days=90).total_seconds()) - offsets["step7-s"] = offsets["step6-s"] - int(timedelta(days=90).total_seconds()) - - steps = [ - { - # Step 1. - # Introduce the first key. This will immediately be active. - "zone": "step1.csk-roll2.autosign", - "cdss": cdss, - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step1-p']}", - ], - # Next key event is when the successor CSK needs to be published - # minus time already elapsed. This is Lcsk - Ipub + Dreg (we ignore - # registration delay). - "nextev": csk_lifetime - ipub - timedelta(days=7), - }, - { - # Step 2. - # Successor CSK is prepublished (signs DNSKEY RRset, but not yet - # other RRsets). - # CSK1 goal: omnipresent -> hidden - # CSK2 goal: hidden -> omnipresent - # CSK2 dnskey: hidden -> rumoured - # CSK2 krrsig: hidden -> rumoured - "zone": "step2.csk-roll2.autosign", - "cdss": cdss, - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step2-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:hidden ds:hidden offset:{offsets['step2-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the successor CSK becomes OMNIPRESENT. - "nextev": ipub, - }, - { - # Step 3. - # Successor CSK becomes omnipresent, meaning we can start signing - # the remainder of the zone with the successor CSK, and we can - # submit the DS. - "zone": "step3.csk-roll2.autosign", - "cdss": cdss, - # Predecessor CSK will be removed, so moving to UNRETENTIVE. - # CSK1 zrrsig: omnipresent -> unretentive - # Successor CSK DNSKEY is OMNIPRESENT, so moving ZRRSIG to RUMOURED. - # CSK2 dnskey: rumoured -> omnipresent - # CSK2 krrsig: rumoured -> omnipresent - # CSK2 zrrsig: hidden -> rumoured - # The predecessor DS can be withdrawn and the successor DS can be - # introduced. - # CSK1 ds: omnipresent -> unretentive - # CSK2 ds: hidden -> rumoured - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:unretentive offset:{offsets['step3-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:rumoured offset:{offsets['step3-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the predecessor DS has been replaced with - # the successor DS and enough time has passed such that the all - # validators that have this DS RRset cached only know about the - # successor DS. This is the the retire interval. - "nextev": iretZSK, - # Set 'smooth' to true so expected signatures of subdomain are - # from the predecessor ZSK. - "smooth": True, - }, - { - # Step 4. - "zone": "step4.csk-roll2.autosign", - "cdss": cdss, - # The predecessor ZRRSIG is HIDDEN. The successor ZRRSIG is - # OMNIPRESENT. - # CSK1 zrrsig: unretentive -> hidden - # CSK2 zrrsig: rumoured -> omnipresent - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:hidden ds:unretentive offset:{offsets['step4-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{offsets['step4-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the predecessor DS has been replaced with - # the successor DS and enough time has passed such that the all - # validators that have this DS RRset cached only know about the - # successor DS. This is the retire interval of the KSK part (minus) - # time already elapsed). - "nextev": iret - iretZSK, - # We already swapped the DS in the previous step, so disable ds-swap. - "ds-swap": False, - }, - { - # Step 5. - "zone": "step5.csk-roll2.autosign", - "cdss": cdss, - # The predecessor DNSKEY can be removed. - # CSK1 dnskey: omnipresent -> unretentive - # CSK1 krrsig: omnipresent -> unretentive - # CSK1 ds: unretentive -> hidden - # The successor key is now fully OMNIPRESENT. - # CSK2 ds: rumoured -> omnipresent - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive zrrsig:hidden ds:hidden offset:{offsets['step5-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step5-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the DNSKEY enters the HIDDEN state. - # This is the DNSKEY TTL plus zone propagation delay. - "nextev": keyttlprop, - }, - { - # Step 6. - "zone": "step6.csk-roll2.autosign", - "cdss": cdss, - # The predecessor CSK is now completely HIDDEN. - # CSK1 dnskey: unretentive -> hidden - # CSK1 krrsig: unretentive -> hidden - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{offsets['step6-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step6-s']}", - ], - "keyrelationships": [0, 1], - # Next key event is when the new successor needs to be published. - # This is the Lcsk, minus time passed since the key was published. - "nextev": csk_lifetime - iret - ipub - keyttlprop, - }, - { - # Step 7. - "zone": "step7.csk-roll2.autosign", - "cdss": cdss, - # The predecessor CSK is now completely HIDDEN. - "keyprops": [ - f"csk {lifetime_policy} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{offsets['step7-p']}", - f"csk {lifetime_policy} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step7-s']}", - ], - "keyrelationships": [0, 1], - "nextev": None, - }, - ] - - for step in steps: - check_rollover_step(server, config, policy, step) - - -def test_rollover_policy_changes(servers): - server = servers["ns6"] - cdss = ["CDNSKEY", "CDS (SHA-256)"] - alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] - size = os.environ["DEFAULT_BITS"] - - default_config = { - "dnskey-ttl": timedelta(hours=1), - "ds-ttl": timedelta(days=1), - "max-zone-ttl": timedelta(days=1), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(hours=1), - "purge-keys": timedelta(days=90), - "retire-safety": timedelta(hours=1), - "signatures-refresh": timedelta(days=5), - "signatures-validity": timedelta(days=14), - "zone-propagation-delay": timedelta(seconds=300), - } - - unsigning_config = default_config.copy() - unsigning_config["dnskey-ttl"] = timedelta(seconds=7200) - - algoroll_config = { - "dnskey-ttl": timedelta(hours=1), - "ds-ttl": timedelta(seconds=7200), - "max-zone-ttl": timedelta(hours=6), - "parent-propagation-delay": timedelta(hours=1), - "publish-safety": timedelta(hours=1), - "purge-keys": timedelta(days=90), - "retire-safety": timedelta(hours=2), - "signatures-refresh": timedelta(days=5), - "signatures-validity": timedelta(days=30), - "zone-propagation-delay": timedelta(seconds=3600), - } - - start_time = KeyTimingMetadata.now() - - # Test dynamic zones that switch to inline-signing. - isctest.log.info("check dynamic zone that switches to inline-signing") - d2i = { - "zone": "dynamic2inline.kasp", - "cdss": cdss, - "config": default_config, - "policy": "default", - "keyprops": [ - f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", - ], - "nextev": None, - } - steps = [d2i] - - # Test key lifetime changes. - isctest.log.info("check key lifetime changes are updated correctly") - lifetime = { - "P1Y": int(timedelta(days=365).total_seconds()), - "P6M": int(timedelta(days=31 * 6).total_seconds()), - "P60D": int(timedelta(days=60).total_seconds()), - } - lifetime_update_tests = [ - { - "zone": "shorter-lifetime", - "policy": "long-lifetime", - "lifetime": lifetime["P1Y"], - }, - { - "zone": "longer-lifetime", - "policy": "short-lifetime", - "lifetime": lifetime["P6M"], - }, - { - "zone": "limit-lifetime", - "policy": "unlimited-lifetime", - "lifetime": 0, - }, - { - "zone": "unlimit-lifetime", - "policy": "short-lifetime", - "lifetime": lifetime["P6M"], - }, - ] - for lut in lifetime_update_tests: - step = { - "zone": lut["zone"], - "cdss": cdss, - "config": default_config, - "policy": lut["policy"], - "keyprops": [ - f"csk {lut['lifetime']} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", - ], - "nextev": None, - } - steps.append(step) - - # Test going insecure. - isctest.log.info("check going insecure") - offset = -timedelta(days=10) - offval = int(offset.total_seconds()) - zones = [ - "step1.going-insecure.kasp", - "step1.going-insecure-dynamic.kasp", - ] - for zone in zones: - step = { - "zone": zone, - "cdss": cdss, - "config": unsigning_config, - "policy": "unsigning", - "keyprops": [ - f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", - f"zsk {lifetime['P60D']} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offval}", - ], - "nextev": None, - } - steps.append(step) - - # Test going straight to none. - isctest.log.info("check going straight to none") - zones = [ - "step1.going-straight-to-none.kasp", - "step1.going-straight-to-none-dynamic.kasp", - ] - for zone in zones: - step = { - "zone": zone, - "cdss": cdss, - "config": default_config, - "policy": "default", - "keyprops": [ - f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", - ], - "nextev": None, - } - steps.append(step) - - # Test algorithm rollover (KSK/ZSK split). - isctest.log.info("check algorithm rollover ksk/zsk split") - offset = -timedelta(days=7) - offval = int(offset.total_seconds()) - step = { - "zone": "step1.algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "rsasha256", - "keyprops": [ - f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", - f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offval}", - ], - "nextev": timedelta(hours=1), - } - steps.append(step) - - # Test algorithm rollover (CSK). - isctest.log.info("check algorithm rollover csk") - step = { - "zone": "step1.csk-algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "csk-algoroll", - "keyprops": [ - f"csk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", - ], - "nextev": timedelta(hours=1), - } - steps.append(step) - - for step in steps: - check_rollover_step(server, step["config"], step["policy"], step) - - # Reconfigure, changing DNSSEC policies and other configuration options, - # triggering algorithm rollovers and other dnssec-policy changes. - shutil.copyfile("ns6/named2.conf", "ns6/named.conf") - server.rndc("reconfig") - # Calculate time passed to correctly check for next key events. - now = KeyTimingMetadata.now() - time_passed = now.value - start_time.value - - # Test dynamic zones that switch to inline-signing (after reconfig). - steps = [d2i] - - # Test key lifetime changes (after reconfig). - lifetime_update_tests = [ - { - "zone": "shorter-lifetime", - "policy": "short-lifetime", - "lifetime": lifetime["P6M"], - }, - { - "zone": "longer-lifetime", - "policy": "long-lifetime", - "lifetime": lifetime["P1Y"], - }, - { - "zone": "limit-lifetime", - "policy": "short-lifetime", - "lifetime": lifetime["P6M"], - }, - { - "zone": "unlimit-lifetime", - "policy": "unlimited-lifetime", - "lifetime": 0, - }, - ] - for lut in lifetime_update_tests: - step = { - "zone": lut["zone"], - "cdss": cdss, - "config": default_config, - "policy": lut["policy"], - "keyprops": [ - f"csk {lut['lifetime']} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", - ], - "nextev": None, - } - steps.append(step) - - # Test going insecure (after reconfig). - isctest.log.info("check going insecure (after reconfig)") - oldttl = unsigning_config["dnskey-ttl"] - offset = -timedelta(days=10) - offval = int(offset.total_seconds()) - zones = ["going-insecure.kasp", "going-insecure-dynamic.kasp"] - for parent in zones: - # Step 1. - # Key goal states should be HIDDEN. - # The DS may be removed if we are going insecure. - step = { - "zone": f"step1.{parent}", - "cdss": cdss, - "config": default_config, - "policy": "insecure", - "keyprops": [ - f"ksk 0 {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offval}", - f"zsk {lifetime['P60D']} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", - ], - # Next key event is when the DS becomes HIDDEN. This - # happens after the# parent propagation delay plus DS TTL. - "nextev": default_config["ds-ttl"] - + default_config["parent-propagation-delay"], - # Going insecure, check for CDS/CDNSKEY DELETE, and skip key timing checks. - "cds-delete": True, - "check-keytimes": False, - } - steps.append(step) - - # Step 2. - # The DS is long enough removed from the zone to be considered - # HIDDEN. This means the DNSKEY and the KSK signatures can be - # removed. - step = { - "zone": f"step2.{parent}", - "cdss": cdss, - "config": default_config, - "policy": "insecure", - "keyprops": [ - f"ksk 0 {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offval}", - f"zsk {lifetime['P60D']} {alg} {size} goal:hidden dnskey:unretentive zrrsig:unretentive offset:{offval}", - ], - # Next key event is when the DNSKEY becomes HIDDEN. - # This happens after the propagation delay, plus DNSKEY TTL. - "nextev": oldttl + default_config["zone-propagation-delay"], - # Zone is no longer signed. - "zone-signed": False, - "check-keytimes": False, - } - steps.append(step) - - # Test going straight to none. - isctest.log.info("check going straight to none (after reconfig)") - zones = [ - "step1.going-straight-to-none.kasp", - "step1.going-straight-to-none-dynamic.kasp", - ] - for zone in zones: - step = { - "zone": zone, - "cdss": cdss, - "config": default_config, - "policy": None, - # These zones will go bogus after signatures expire, but - # remain validly signed for now. - "keyprops": [ - f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", - ], - "nextev": None, - } - steps.append(step) - - # Test algorithm rollover (KSK/ZSK split) (after reconfig). - isctest.log.info("check algorithm rollover ksk/zsk split (after reconfig)") - offset = -timedelta(days=7) - offval = int(offset.total_seconds()) - ipub = Ipub(algoroll_config) - ipubc = IpubC(algoroll_config, rollover=False) - iret = Iret(algoroll_config, rollover=False) - iretKSK = Iret(algoroll_config, zsk=False, ksk=True, rollover=False) - keyttlprop = ( - algoroll_config["dnskey-ttl"] + algoroll_config["zone-propagation-delay"] - ) - offsets = {} - offsets["step2"] = -int(ipub.total_seconds()) - offsets["step3"] = -int(iret.total_seconds()) - offsets["step4"] = offsets["step3"] - int(iretKSK.total_seconds()) - offsets["step5"] = offsets["step4"] - int(keyttlprop.total_seconds()) - offsets["step6"] = offsets["step5"] - int(iret.total_seconds()) - algo_steps = [ - { - # Step 1. - "zone": "step1.algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "ecdsa256", - "keyprops": [ - # The RSASHA keys are outroducing. - f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", - f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", - # The ECDSAP256SHA256 keys are introducing. - f"ksk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", - f"zsk 0 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured", - ], - # Next key event is when the ecdsa256 keys have been propagated. - "nextev": ipub, - }, - { - # Step 2. - "zone": "step2.algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "ecdsa256", - "keyprops": [ - # The RSASHA keys are outroducing, but need to stay present - # until the new algorithm chain of trust has been established. - # Thus the expected key states of these keys stay the same. - f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offval}", - f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", - # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is - # omnipresent, but the zone signatures are not. - f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{offsets['step2']}", - f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{offsets['step2']}", - ], - # Next key event is when all zone signatures are signed with the new - # algorithm. This is the max-zone-ttl plus zone propagation delay. But - # the publication interval has already passed. Also, prevent intermittent - # false positives on slow platforms by subtracting the time passed between - # key creation and invoking 'rndc reconfig'. - "nextev": ipubc - ipub - time_passed, - }, - { - # Step 3. - "zone": "step3.algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "ecdsa256", - "keyprops": [ - # The DS can be swapped. - f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{offval}", - f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{offval}", - f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{offsets['step3']}", - f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step3']}", - ], - # Next key event is when the DS becomes OMNIPRESENT. This happens - # after the retire interval. - "nextev": iretKSK - time_passed, - }, - { - # Step 4. - "zone": "step4.algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "ecdsa256", - "keyprops": [ - # The old DS is HIDDEN, we can remove the old algorithm records. - f"ksk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{offval}", - f"zsk 0 8 2048 goal:hidden dnskey:unretentive zrrsig:unretentive offset:{offval}", - f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step4']}", - f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step4']}", - ], - # Next key event is when the old DNSKEY becomes HIDDEN. - # This happens after the DNSKEY TTL plus zone propagation delay. - "nextev": keyttlprop, - }, - { - # Step 5. - "zone": "step5.algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "ecdsa256", - "keyprops": [ - # The DNSKEY becomes HIDDEN. - f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}", - f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:unretentive offset:{offval}", - f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step5']}", - f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step5']}", - ], - # Next key event is when the RSASHA signatures become HIDDEN. - # This happens after the max-zone-ttl plus zone propagation delay - # minus the time already passed since the UNRETENTIVE state has - # been reached. Prevent intermittent false positives on slow - # platforms by subtracting the number of seconds which passed - # between key creation and invoking 'rndc reconfig'. - "nextev": iret - iretKSK - keyttlprop - time_passed, - }, - { - # Step 6. - "zone": "step6.algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "ecdsa256", - "keyprops": [ - # The zone signatures are now HIDDEN. - f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{offval}", - f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:hidden offset:{offval}", - f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{offsets['step6']}", - f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{offsets['step6']}", - ], - # Next key event is never since we established the policy and the - # keys have an unlimited lifetime. Fallback to the default - # loadkeys interval. - "nextev": timedelta(hours=1), - }, - ] - steps = steps + algo_steps - - # Test algorithm rollover (CSK) (after reconfig). - isctest.log.info("check algorithm rollover csk (after reconfig)") - offsets = {} - offsets["step2"] = -int(ipub.total_seconds()) - offsets["step3"] = -int(iret.total_seconds()) - offsets["step4"] = offsets["step3"] - int(iretKSK.total_seconds()) - offsets["step5"] = offsets["step4"] - int(keyttlprop.total_seconds()) - offsets["step6"] = offsets["step5"] - int(iret.total_seconds()) - algo_steps = [ - { - # Step 1. - "zone": "step1.csk-algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "csk-algoroll", - "keyprops": [ - # The RSASHA keys are outroducing. - f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", - # The ECDSAP256SHA256 keys are introducing. - f"csk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", - ], - # Next key event is when the ecdsa256 keys have been propagated. - "nextev": ipub, - }, - { - # Step 2. - "zone": "step2.csk-algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "csk-algoroll", - "keyprops": [ - # The RSASHA keys are outroducing, but need to stay present - # until the new algorithm chain of trust has been established. - # Thus the expected key states of these keys stay the same. - f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offval}", - # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is - # omnipresent, but the zone signatures are not. - f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{offsets['step2']}", - ], - # Next key event is when all zone signatures are signed with the - # new algorithm. This is the child publication interval, minus - # the publication interval has already passed. Also, prevent - # intermittent false positives on slow platforms by subtracting - # the time passed between key creation and invoking 'rndc reconfig'. - "nextev": ipubc - ipub - time_passed, - }, - { - # Step 3. - "zone": "step3.csk-algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "csk-algoroll", - "keyprops": [ - # The DS can be swapped. - f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:unretentive offset:{offval}", - f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{offsets['step3']}", - ], - # Next key event is when the DS becomes OMNIPRESENT. This happens - # after the publication interval of the parent side. - "nextev": iretKSK - time_passed, - }, - { - # Step 4. - "zone": "step4.csk-algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "csk-algoroll", - "keyprops": [ - # The old DS is HIDDEN, we can remove the old algorithm records. - f"csk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive zrrsig:unretentive ds:hidden offset:{offval}", - f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step4']}", - ], - # Next key event is when the old DNSKEY becomes HIDDEN. - # This happens after the DNSKEY TTL plus zone propagation delay. - "nextev": keyttlprop, - }, - { - # Step 5. - "zone": "step5.csk-algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "csk-algoroll", - "keyprops": [ - # The DNSKEY becomes HIDDEN. - f"csk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden zrrsig:unretentive ds:hidden offset:{offval}", - f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step5']}", - ], - # Next key event is when the RSASHA signatures become HIDDEN. - # This happens after the max-zone-ttl plus zone propagation delay - # minus the time already passed since the UNRETENTIVE state has - # been reached. Prevent intermittent false positives on slow - # platforms by subtracting the number of seconds which passed - # between key creation and invoking 'rndc reconfig'. - "nextev": iret - iretKSK - keyttlprop - time_passed, - }, - { - # Step 6. - "zone": "step6.csk-algorithm-roll.kasp", - "cdss": cdss, - "config": algoroll_config, - "policy": "csk-algoroll", - "keyprops": [ - # The zone signatures are now HIDDEN. - f"csk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{offval}", - f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{offsets['step6']}", - ], - # Next key event is never since we established the policy and the - # keys have an unlimited lifetime. Fallback to the default - # loadkeys interval. - "nextev": timedelta(hours=1), - }, - ] - steps = steps + algo_steps - - for step in steps: - check_rollover_step(server, step["config"], step["policy"], step) diff -Nru bind9-9.20.11/bin/tests/system/rollover/tests_rollover_manual.py bind9-9.20.15/bin/tests/system/rollover/tests_rollover_manual.py --- bind9-9.20.11/bin/tests/system/rollover/tests_rollover_manual.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover/tests_rollover_manual.py 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,155 @@ +# 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. + +from datetime import timedelta +import os + +import isctest +from isctest.kasp import KeyTimingMetadata, Ipub, Iret + +from rollover.common import pytestmark # pylint: disable=unused-import + + +def test_rollover_manual(ns3): + policy = "manual-rollover" + config = { + "dnskey-ttl": timedelta(hours=1), + "ds-ttl": timedelta(days=1), + "max-zone-ttl": timedelta(days=1), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=7), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(minutes=5), + } + ttl = int(config["dnskey-ttl"].total_seconds()) + alg = os.environ["DEFAULT_ALGORITHM_NUMBER"] + size = os.environ["DEFAULT_BITS"] + zone = "manual-rollover.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + isctest.kasp.check_dnssec_verify(ns3, zone) + + key_properties = [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent", + ] + expected = isctest.kasp.policy_to_properties(ttl, key_properties) + keys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + + isctest.kasp.check_keys(zone, keys, expected) + + offset = -timedelta(days=7) + for kp in expected: + kp.set_expected_keytimes(config, offset=offset) + + isctest.kasp.check_keytimes(keys, expected) + isctest.kasp.check_dnssecstatus(ns3, zone, keys, policy=policy) + isctest.kasp.check_apex(ns3, zone, ksks, zsks) + isctest.kasp.check_subdomain(ns3, zone, ksks, zsks) + + # Schedule KSK rollover in six months. + assert len(ksks) == 1 + ksk = ksks[0] + startroll = expected[0].timing["Active"] + timedelta(days=30 * 6) + expected[0].timing["Retired"] = startroll + Ipub(config) + expected[0].timing["Removed"] = expected[0].timing["Retired"] + Iret( + config, zsk=False, ksk=True + ) + + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -rollover -key {ksk.tag} -when {startroll} {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + + isctest.kasp.check_dnssec_verify(ns3, zone) + isctest.kasp.check_keys(zone, keys, expected) + isctest.kasp.check_keytimes(keys, expected) + isctest.kasp.check_dnssecstatus(ns3, zone, keys, policy=policy) + isctest.kasp.check_apex(ns3, zone, ksks, zsks) + isctest.kasp.check_subdomain(ns3, zone, ksks, zsks) + + # Schedule KSK rollover now. + now = KeyTimingMetadata.now() + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -rollover -key {ksk.tag} -when {now} {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + + isctest.kasp.check_dnssec_verify(ns3, zone) + + key_properties = [ + f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent", + ] + expected = isctest.kasp.policy_to_properties(ttl, key_properties) + keys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + + isctest.kasp.check_keys(zone, keys, expected) + + expected[0].metadata["Successor"] = expected[1].key.tag + expected[1].metadata["Predecessor"] = expected[0].key.tag + isctest.kasp.check_keyrelationships(keys, expected) + + for kp in expected: + off = offset + if "Predecessor" in kp.metadata: + off = 0 + kp.set_expected_keytimes(config, offset=off) + + expected[0].timing["Retired"] = now + Ipub(config) + expected[0].timing["Removed"] = expected[0].timing["Retired"] + Iret( + config, zsk=False, ksk=True + ) + + isctest.kasp.check_keytimes(keys, expected) + isctest.kasp.check_dnssecstatus(ns3, zone, keys, policy=policy) + isctest.kasp.check_apex(ns3, zone, ksks, zsks) + isctest.kasp.check_subdomain(ns3, zone, ksks, zsks) + + # Schedule ZSK rollover now. + assert len(zsks) == 1 + zsk = zsks[0] + now = KeyTimingMetadata.now() + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -rollover -key {zsk.tag} -when {now} {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + + isctest.kasp.check_dnssec_verify(ns3, zone) + + key_properties = [ + f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent", + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", + f"zsk unlimited {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent", + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden", + ] + expected = isctest.kasp.policy_to_properties(ttl, key_properties) + keys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + + isctest.kasp.check_keys(zone, keys, expected) + + expected[0].metadata["Successor"] = expected[1].key.tag + expected[1].metadata["Predecessor"] = expected[0].key.tag + expected[2].metadata["Successor"] = expected[3].key.tag + expected[3].metadata["Predecessor"] = expected[2].key.tag + isctest.kasp.check_keyrelationships(keys, expected) + + # Try to schedule a ZSK rollover for an inactive key (should fail). + zsk = expected[3].key + response = ns3.rndc(f"dnssec -rollover -key {zsk.tag} {zone}") + assert "key is not actively signing" in response diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/csk1.conf.j2 2025-10-18 10:16:12.457730658 +0000 @@ -0,0 +1,50 @@ +/* + * 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. + */ + +dnssec-policy "csk-algoroll-kasp" { + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + csk lifetime unlimited algorithm rsasha256; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +dnssec-policy "csk-algoroll-manual" { + manual-mode yes; + + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + csk lifetime unlimited algorithm rsasha256; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/csk2.conf.j2 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,50 @@ +/* + * 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. + */ + +dnssec-policy "csk-algoroll-kasp" { + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +dnssec-policy "csk-algoroll-manual" { + manual-mode yes; + + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/named.common.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,35 @@ +/* + * 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 { + query-source address 10.53.0.6; + notify-source 10.53.0.6; + transfer-source 10.53.0.6; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.6; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/named.conf.j2 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,59 @@ +/* + * 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 csk_roll = csk_roll | default(False) %} +{% set _csk_file = "csk1.conf" if not csk_roll else "csk2.conf" %} +{% set zones = ["kasp", "manual"] %} + +include "@_csk_file@"; +include "named.common.conf"; + +{% for tld in zones %} +zone "step1.csk-algorithm-roll.@tld@" { + type primary; + file "step1.csk-algorithm-roll.@tld@.db"; + dnssec-policy "csk-algoroll-@tld@"; +}; + +{% if csk_roll %} +zone "step2.csk-algorithm-roll.@tld@" { + type primary; + file "step2.csk-algorithm-roll.@tld@.db"; + dnssec-policy "csk-algoroll-@tld@"; +}; + +zone "step3.csk-algorithm-roll.@tld@" { + type primary; + file "step3.csk-algorithm-roll.@tld@.db"; + dnssec-policy "csk-algoroll-@tld@"; +}; + +zone "step4.csk-algorithm-roll.@tld@" { + type primary; + file "step4.csk-algorithm-roll.@tld@.db"; + dnssec-policy "csk-algoroll-@tld@"; +}; + +zone "step5.csk-algorithm-roll.@tld@" { + type primary; + file "step5.csk-algorithm-roll.@tld@.db"; + dnssec-policy "csk-algoroll-@tld@"; +}; + +zone "step6.csk-algorithm-roll.@tld@" { + type primary; + file "step6.csk-algorithm-roll.@tld@.db"; + dnssec-policy "csk-algoroll-@tld@"; +}; +{% endif %} +{% endfor %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/template.db.in bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/ns6/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/ns6/template.db.in 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/setup.sh bind9-9.20.15/bin/tests/system/rollover-algo-csk/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/setup.sh 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,152 @@ +#!/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 + +cd "ns6" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# +# The zones at csk-algorithm-roll.$tld represent the various steps of a CSK +# algorithm rollover. +# + +for tld in kasp manual; do + # Step 1: + # Introduce the first key. This will immediately be active. + setup step1.csk-algorithm-roll.$tld + echo "$zone" >>zones + TactN="now-7d" + TsbmN="now-161h" + csktimes="-P ${TactN} -A ${TactN}" + CSK=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone 5 "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 2: + # After the publication interval has passed the DNSKEY is OMNIPRESENT. + setup step2.csk-algorithm-roll.$tld + # The time passed since the new algorithm keys have been introduced is 3 hours. + TpubN1="now-3h" + # Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h + TsbmN1="now+4h" + csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I now" + newtimes="-P ${TpubN1} -A ${TpubN1}" + CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${CSK1}.state" + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone 5 "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 3: + # The zone signatures are also OMNIPRESENT. + setup step3.csk-algorithm-roll.$tld + # The time passed since the new algorithm keys have been introduced is 7 hours. + TpubN1="now-7h" + TsbmN1="now" + ckstimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TactN -d $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $R $TpubN1 -d $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${CSK1}.state" + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone 5 "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 4: + # The DS is swapped and can become OMNIPRESENT. + setup step4.csk-algorithm-roll.$tld + # The time passed since the DS has been swapped is 3 hours. + TpubN1="now-10h" + TsbmN1="now-3h" + csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $O $TsbmN1 -d $U $TsbmN1 -D ds $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $R $TsbmN1 -P ds $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${CSK1}.state" + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone 5 "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 5: + # The DNSKEY is removed long enough to be HIDDEN. + setup step5.csk-algorithm-roll.$tld + # The time passed since the DNSKEY has been removed is 2 hours. + TpubN1="now-12h" + TsbmN1="now-5h" + csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $U $TactN -r $U $TactN -z $U $TsbmN1 -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -z $O $TsbmN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${CSK1}.state" + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone 5 "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 6: + # The RRSIGs have been removed long enough to be HIDDEN. + setup step6.csk-algorithm-roll.$tld + # Additional time passed: 7h. + TpubN1="now-19h" + TsbmN1="now-12h" + csktimes="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + newtimes="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + CSK1=$($KEYGEN -k csk-algoroll-$tld -l csk1.conf $csktimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-algoroll-$tld -l csk2.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $H $TactN -r $U $TactN -z $U $TactN -d $H $TsbmN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O $TsubN1 -d $O $TsbmN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${CSK1}.state" + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone 5 "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -z -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py bind9-9.20.15/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_initial.py 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,48 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from isctest.util import param +from rollover.common import ( + pytestmark, + CDSS, + DURATION, + TIMEDELTA, + ALGOROLL_CONFIG, +) + + +@pytest.mark.parametrize( + "tld, policy", + [ + param("kasp", "csk-algoroll"), + param("manual", "csk-algoroll-manual"), + ], +) +def test_algoroll_csk_initial(ns6, tld, policy): + config = ALGOROLL_CONFIG + zone = f"step1.csk-algorithm-roll.{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{-DURATION['P7D']}", + ], + "nextev": TIMEDELTA["PT1H"], + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py bind9-9.20.15/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py --- bind9-9.20.11/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-csk/tests_rollover_algo_csk_reconfig.py 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,334 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from isctest.kasp import KeyTimingMetadata +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + ALGOROLL_CONFIG, + ALGOROLL_IPUB, + ALGOROLL_IPUBC, + ALGOROLL_IRET, + ALGOROLL_IRETKSK, + ALGOROLL_KEYTTLPROP, + ALGOROLL_OFFSETS, + ALGOROLL_OFFVAL, + DURATION, + TIMEDELTA, +) + +CONFIG = ALGOROLL_CONFIG +POLICY = "csk-algoroll" +TIME_PASSED = 0 # set in reconfigure() fixture + + +@pytest.fixture(scope="module", autouse=True) +def reconfigure(ns6, templates): + global TIME_PASSED # pylint: disable=global-statement + + isctest.kasp.wait_keymgr_done(ns6, "step1.csk-algorithm-roll.kasp") + + templates.render("ns6/named.conf", {"csk_roll": True}) + start_time = KeyTimingMetadata.now() + ns6.reconfigure() + + # Calculate time passed to correctly check for next key events. + TIME_PASSED = KeyTimingMetadata.now().value - start_time.value + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_csk_reconfig_step1(tld, ns6, alg, size): + zone = f"step1.csk-algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + if tld == "manual": + # Same as initial. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{-DURATION['P7D']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg1 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{tag} (CSK)" + msg2 = f"keymgr-manual-mode: block new key generation for zone {zone} (policy {policy})" + ns6.log.expect(msg1) + ns6.log.expect(msg2) + + # Force step. + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/RSASHA256" + ) + + # Check state after step. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The RSASHA keys are outroducing. + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFVAL}", + # The ECDSAP256SHA256 keys are introducing. + f"csk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + # Next key event is when the ecdsa256 keys have been propagated. + "nextev": ALGOROLL_IPUB, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_csk_reconfig_step2(tld, ns6, alg, size): + zone = f"step2.csk-algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The RSASHA keys are outroducing, but need to stay present + # until the new algorithm chain of trust has been established. + # Thus the expected key states of these keys stay the same. + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFVAL}", + # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is + # omnipresent, but the zone signatures are not. + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{ALGOROLL_OFFSETS['step2']}", + ], + # Next key event is when all zone signatures are signed with the + # new algorithm. This is the child publication interval, minus + # the publication interval has already passed. Also, prevent + # intermittent false positives on slow platforms by subtracting + # the time passed between key creation and invoking 'rndc reconfig'. + "nextev": ALGOROLL_IPUBC - ALGOROLL_IPUB - TIME_PASSED, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_csk_reconfig_step3(tld, ns6, alg, size): + zone = f"step3.csk-algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + if tld == "manual": + # Same as step 2, but the zone signatures have become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFVAL}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:hidden offset:{ALGOROLL_OFFSETS['step3']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED" + ns6.log.expect(msg) + + # Force step. + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE" + if msg in ns6.log: + # Force step. + isctest.log.debug( + f"keymgr-manual-mode blocking transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE, step again" + ) + tag = keys[1].key.tag + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The DS can be swapped. + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:unretentive offset:{ALGOROLL_OFFVAL}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{ALGOROLL_OFFSETS['step3']}", + ], + # Next key event is when the DS becomes OMNIPRESENT. This happens + # after the publication interval of the parent side. + "nextev": ALGOROLL_IRETKSK - TIME_PASSED, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_csk_reconfig_step4(tld, ns6, alg, size): + zone = f"step4.csk-algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + if tld == "manual": + # Same as step 3, but the DS has become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:hidden offset:{ALGOROLL_OFFVAL}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/RSASHA256/{tag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" + ns6.log.expect(msg) + + # Force step. + tag = keys[1].key.tag + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The old DS is HIDDEN, we can remove the old algorithm records. + f"csk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive zrrsig:unretentive ds:hidden offset:{ALGOROLL_OFFVAL}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + ], + # Next key event is when the old DNSKEY becomes HIDDEN. + # This happens after the DNSKEY TTL plus zone propagation delay. + "nextev": ALGOROLL_KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_csk_reconfig_step5(tld, ns6, alg, size): + zone = f"step5.csk-algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The DNSKEY becomes HIDDEN. + f"csk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden zrrsig:unretentive ds:hidden offset:{ALGOROLL_OFFVAL}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step5']}", + ], + # Next key event is when the RSASHA signatures become HIDDEN. + # This happens after the max-zone-ttl plus zone propagation delay + # minus the time already passed since the UNRETENTIVE state has + # been reached. Prevent intermittent false positives on slow + # platforms by subtracting the number of seconds which passed + # between key creation and invoking 'rndc reconfig'. + "nextev": ALGOROLL_IRET - ALGOROLL_IRETKSK - ALGOROLL_KEYTTLPROP - TIME_PASSED, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_csk_reconfig_step6(tld, ns6, alg, size): + zone = f"step6.csk-algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The zone signatures are now HIDDEN. + f"csk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{ALGOROLL_OFFVAL}", + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step6']}", + ], + # Next key event is never since we established the policy and the + # keys have an unlimited lifetime. Fallback to the default + # loadkeys interval. + "nextev": TIMEDELTA["PT1H"], + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/kasp.conf.j2 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,92 @@ +/* + * 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. + */ + +dnssec-policy "rsasha256-kasp" { + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + ksk lifetime unlimited algorithm rsasha256; + zsk lifetime unlimited algorithm rsasha256; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +dnssec-policy "rsasha256-manual" { + manual-mode yes; + + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + ksk lifetime unlimited algorithm rsasha256; + zsk lifetime unlimited algorithm rsasha256; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +dnssec-policy "ecdsa256-kasp" { + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + ksk lifetime unlimited algorithm ecdsa256; + zsk lifetime unlimited algorithm ecdsa256; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; + +dnssec-policy "ecdsa256-manual" { + manual-mode yes; + + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + keys { + ksk lifetime unlimited algorithm ecdsa256; + zsk lifetime unlimited algorithm ecdsa256; + }; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + zone-propagation-delay 3600; + max-zone-ttl 6h; + parent-propagation-delay pt1h; + parent-ds-ttl 7200; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.common.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,35 @@ +/* + * 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 { + query-source address 10.53.0.6; + notify-source 10.53.0.6; + transfer-source 10.53.0.6; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.6; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/named.conf.j2 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,60 @@ +/* + * 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 alg_roll = alg_roll | default(False) %} +{% set policy = "rsasha256" if not alg_roll else "ecdsa256" %} +{% set zones = ["kasp", "manual"] %} + +include "kasp.conf"; +include "named.common.conf"; + +{% for tld in zones %} +zone "step1.algorithm-roll.@tld@" { + type primary; + file "step1.algorithm-roll.@tld@.db"; + dnssec-policy @policy@-@tld@; +}; + +{% if alg_roll %} +zone "step2.algorithm-roll.@tld@" { + type primary; + file "step2.algorithm-roll.@tld@.db"; + dnssec-policy "ecdsa256-@tld@"; +}; + +zone "step3.algorithm-roll.@tld@" { + type primary; + file "step3.algorithm-roll.@tld@.db"; + dnssec-policy "ecdsa256-@tld@"; +}; + +zone "step4.algorithm-roll.@tld@" { + type primary; + file "step4.algorithm-roll.@tld@.db"; + dnssec-policy "ecdsa256-@tld@"; +}; + +zone "step5.algorithm-roll.@tld@" { + type primary; + file "step5.algorithm-roll.@tld@.db"; + dnssec-policy "ecdsa256-@tld@"; +}; + +zone "step6.algorithm-roll.@tld@" { + type primary; + file "step6.algorithm-roll.@tld@.db"; + dnssec-policy "ecdsa256-@tld@"; +}; + +{% endif %} +{% endfor %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/ns6/template.db.in 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/setup.sh bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/setup.sh 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,201 @@ +#!/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 + +cd "ns6" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# +# The zones at algorithm-roll.$tld represent the various steps of a ZSK/KSK +# algorithm rollover. +# + +for tld in kasp manual; do + # Step 1: + # Introduce the first key. This will immediately be active. + setup step1.algorithm-roll.$tld + echo "$zone" >>zones + TactN="now-7d" + TsbmN="now-161h" + ksktimes="-P ${TactN} -A ${TactN}" + zsktimes="-P ${TactN} -A ${TactN}" + KSK=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a RSASHA256 -L 3600 $zsktimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 + cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" + private_type_record $zone 8 "$KSK" >>"$infile" + private_type_record $zone 8 "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 2: + # After the publication interval has passed the DNSKEY is OMNIPRESENT. + setup step2.algorithm-roll.$tld + # The time passed since the new algorithm keys have been introduced is 3 hours. + TpubN1="now-3h" + # Tsbm(N+1) = TpubN1 + Ipub = now + TTLsig + Dprp = now - 3h + 6h + 1h = now + 4h + TsbmN1="now+4h" + ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" + ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + zsk2times="-P ${TpubN1} -A ${TpubN1}" + KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 + $SETTIME -s -g $O -k $R $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${KSK1}.state" + echo "Lifetime: 0" >>"${ZSK1}.state" + cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone 8 "$KSK1" >>"$infile" + private_type_record $zone 8 "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 3: + # The zone signatures are also OMNIPRESENT. + setup step3.algorithm-roll.$tld + # The time passed since the new algorithm keys have been introduced is 7 hours. + TpubN1="now-7h" + TsbmN1="now" + ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" + ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + zsk2times="-P ${TpubN1} -A ${TpubN1}" + KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.3 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${KSK1}.state" + echo "Lifetime: 0" >>"${ZSK1}.state" + cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone 8 "$KSK1" >>"$infile" + private_type_record $zone 8 "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 4: + # The DS is swapped and can become OMNIPRESENT. + setup step4.algorithm-roll.$tld + # The time passed since the DS has been swapped is 3 hours. + TpubN1="now-10h" + TsbmN1="now-3h" + ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" + ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + zsk2times="-P ${TpubN1} -A ${TpubN1}" + KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TsbmN1 -D ds $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $R $TsbmN1 -P ds $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${KSK1}.state" + echo "Lifetime: 0" >>"${ZSK1}.state" + cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone 8 "$KSK1" >>"$infile" + private_type_record $zone 8 "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 5: + # The DNSKEY is removed long enough to be HIDDEN. + setup step5.algorithm-roll.$tld + # The time passed since the DNSKEY has been removed is 2 hours. + TpubN1="now-12h" + TsbmN1="now-5h" + ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" + ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + zsk2times="-P ${TpubN1} -A ${TpubN1}" + KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) + $SETTIME -s -g $H -k $U $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $U $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${KSK1}.state" + echo "Lifetime: 0" >>"${ZSK1}.state" + cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone 8 "$KSK1" >>"$infile" + private_type_record $zone 8 "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 6: + # The RRSIGs have been removed long enough to be HIDDEN. + setup step6.algorithm-roll.$tld + # Additional time passed: 7h. + TpubN1="now-19h" + TsbmN1="now-12h" + ksk1times="-P ${TactN} -A ${TactN} -P sync ${TsbmN} -I ${TsbmN1}" + zsk1times="-P ${TactN} -A ${TactN} -I ${TsbmN1}" + ksk2times="-P ${TpubN1} -A ${TpubN1} -P sync ${TsbmN1}" + zsk2times="-P ${TpubN1} -A ${TpubN1}" + KSK1=$($KEYGEN -a RSASHA256 -L 3600 -f KSK $ksk1times $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a RSASHA256 -L 3600 $zsk1times $zone 2>keygen.out.$zone.2) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $ksk2times $zone 2>keygen.out.$zone.3) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $zsk2times $zone 2>keygen.out.$zone.4) + $SETTIME -s -g $H -k $H $TsbmN1 -r $U $TsbmN1 -d $H $TsbmN1 "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $H $TsbmN1 -z $U $TsbmN1 "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -r $O $TpubN1 -d $O $TsbmN1 "$KSK2" >settime.out.$zone.3 2>&1 + $SETTIME -s -g $O -k $O $TpubN1 -z $R $TpubN1 "$ZSK2" >settime.out.$zone.4 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${KSK1}.state" + echo "Lifetime: 0" >>"${ZSK1}.state" + cat template.db.in "${KSK1}.key" "${ZSK1}.key" "${KSK2}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone 8 "$KSK1" >>"$infile" + private_type_record $zone 8 "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py --- bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_initial.py 2025-10-18 10:16:12.458730673 +0000 @@ -0,0 +1,50 @@ +# 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. + +# pylint: disable=unused-import + +import pytest + +import isctest +from isctest.util import param +from rollover.common import ( + pytestmark, + CDSS, + DURATION, + TIMEDELTA, + ALGOROLL_CONFIG, +) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_initial(ns6, tld): + config = ALGOROLL_CONFIG + policy = f"rsasha256-{tld}" + zone = f"step1.algorithm-roll.{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{-DURATION['P7D']}", + f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{-DURATION['P7D']}", + ], + "nextev": TIMEDELTA["PT1H"], + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py --- bind9-9.20.11/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-algo-ksk-zsk/tests_rollover_algo_ksk_zsk_reconfig.py 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,356 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from isctest.kasp import KeyTimingMetadata +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + ALGOROLL_CONFIG, + ALGOROLL_IPUB, + ALGOROLL_IPUBC, + ALGOROLL_IRET, + ALGOROLL_IRETKSK, + ALGOROLL_KEYTTLPROP, + ALGOROLL_OFFSETS, + ALGOROLL_OFFVAL, + DURATION, + TIMEDELTA, +) + +CONFIG = ALGOROLL_CONFIG +POLICY = "ecdsa256" +TIME_PASSED = 0 # set in reconfigure() fixture + + +@pytest.fixture(scope="module", autouse=True) +def reconfigure(ns6, templates): + global TIME_PASSED # pylint: disable=global-statement + + isctest.kasp.wait_keymgr_done(ns6, "step1.algorithm-roll.kasp") + + templates.render("ns6/named.conf", {"alg_roll": True}) + start_time = KeyTimingMetadata.now() + ns6.reconfigure() + + # Calculate time passed to correctly check for next key events. + TIME_PASSED = KeyTimingMetadata.now().value - start_time.value + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step1(tld, ns6, alg, size): + zone = f"step1.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + if tld == "manual": + # Same as initial. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 8 2048 goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{-DURATION['P7D']}", + f"zsk 0 8 2048 goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{-DURATION['P7D']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + # Check logs. + ktag = keys[0].key.tag + ztag = keys[1].key.tag + msg1 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{ktag} (KSK)" + msg2 = f"keymgr-manual-mode: block retire DNSKEY {zone}/RSASHA256/{ztag} (ZSK)" + msg3 = f"keymgr-manual-mode: block new key generation for zone {zone} (policy {policy})" # twice + ns6.log.expect(msg1) + ns6.log.expect(msg2) + ns6.log.expect(msg3) + + # Force step. + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {ktag}/RSASHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The RSASHA keys are outroducing. + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFVAL}", + # The ECDSAP256SHA256 keys are introducing. + f"ksk 0 {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured", + ], + # Next key event is when the ecdsa256 keys have been propagated. + "nextev": ALGOROLL_IPUB, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step2(tld, ns6, alg, size): + zone = f"step2.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The RSASHA keys are outroducing, but need to stay present + # until the new algorithm chain of trust has been established. + # Thus the expected key states of these keys stay the same. + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFVAL}", + # The ECDSAP256SHA256 keys are introducing. The DNSKEY RRset is + # omnipresent, but the zone signatures are not. + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{ALGOROLL_OFFSETS['step2']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{ALGOROLL_OFFSETS['step2']}", + ], + # Next key event is when all zone signatures are signed with the new + # algorithm. This is the max-zone-ttl plus zone propagation delay. But + # the publication interval has already passed. Also, prevent intermittent + # false positives on slow platforms by subtracting the time passed between + # key creation and invoking 'rndc reconfig'. + "nextev": ALGOROLL_IPUBC - ALGOROLL_IPUB - TIME_PASSED, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step3(tld, ns6, alg, size): + zone = f"step3.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + if tld == "manual": + # Same as step 2, but the zone signatures have become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{ALGOROLL_OFFSETS['step3']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step3']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + # Check logs. + tag = keys[2].key.tag + msg = f"keymgr-manual-mode: block transition KSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED" + ns6.log.expect(msg) + + # Force step. + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition KSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE" + if msg in ns6.log: + # Force step. + isctest.log.debug( + f"keymgr-manual-mode blocking transition CSK {zone}/RSASHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE, step again" + ) + tag = keys[2].key.tag + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The DS can be swapped. + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{ALGOROLL_OFFSETS['step3']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step3']}", + ], + # Next key event is when the DS becomes OMNIPRESENT. This happens + # after the retire interval. + "nextev": ALGOROLL_IRETKSK - TIME_PASSED, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step4(tld, ns6, alg, size): + zone = f"step4.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + if tld == "manual": + # Same as step 3, but the DS has become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 8 2048 goal:hidden dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + # Check logs. + ktag = keys[0].key.tag + ztag = keys[1].key.tag + msg1 = f"keymgr-manual-mode: block transition KSK {zone}/RSASHA256/{ktag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" + msg2 = f"keymgr-manual-mode: block transition ZSK {zone}/RSASHA256/{ztag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" + ns6.log.expect(msg1) + ns6.log.expect(msg2) + + # Force step. + ktag = keys[3].key.tag + with ns6.watch_log_from_here() as watcher: + ns6.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {ktag}/ECDSAP256SHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The old DS is HIDDEN, we can remove the old algorithm records. + f"ksk 0 8 2048 goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:unretentive zrrsig:unretentive offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step4']}", + ], + # Next key event is when the old DNSKEY becomes HIDDEN. + # This happens after the DNSKEY TTL plus zone propagation delay. + "nextev": ALGOROLL_KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step5(tld, ns6, alg, size): + zone = f"step5.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The DNSKEY becomes HIDDEN. + f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:unretentive offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step5']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step5']}", + ], + # Next key event is when the RSASHA signatures become HIDDEN. + # This happens after the max-zone-ttl plus zone propagation delay + # minus the time already passed since the UNRETENTIVE state has + # been reached. Prevent intermittent false positives on slow + # platforms by subtracting the number of seconds which passed + # between key creation and invoking 'rndc reconfig'. + "nextev": ALGOROLL_IRET - ALGOROLL_IRETKSK - ALGOROLL_KEYTTLPROP - TIME_PASSED, + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("kasp"), + param("manual"), + ], +) +def test_algoroll_ksk_zsk_reconfig_step6(tld, ns6, alg, size): + zone = f"step6.algorithm-roll.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + # The zone signatures are now HIDDEN. + f"ksk 0 8 2048 goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{ALGOROLL_OFFVAL}", + f"zsk 0 8 2048 goal:hidden dnskey:hidden zrrsig:hidden offset:{ALGOROLL_OFFVAL}", + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{ALGOROLL_OFFSETS['step6']}", + f"zsk 0 {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{ALGOROLL_OFFSETS['step6']}", + ], + # Next key event is never since we established the policy and the + # keys have an unlimited lifetime. Fallback to the default + # loadkeys interval. + "nextev": TIMEDELTA["PT1H"], + } + isctest.kasp.check_rollover_step(ns6, CONFIG, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/kasp.conf.j2 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,58 @@ +/* + * 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. + */ + +dnssec-policy "csk-roll1-autosign" { + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + purge-keys PT1H; + + cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes + keys { + csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay 1h; + max-zone-ttl P1D; + + parent-ds-ttl 1h; + parent-propagation-delay 1h; +}; + +dnssec-policy "csk-roll1-manual" { + manual-mode yes; + + signatures-refresh P5D; + signatures-validity 30d; + signatures-validity-dnskey 30d; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 2h; + purge-keys PT1H; + + cds-digest-types { "sha-384"; }; // use a different digest type for testing purposes + keys { + csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay 1h; + max-zone-ttl P1D; + + parent-ds-ttl 1h; + parent-propagation-delay 1h; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/named.conf.j2 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,61 @@ +/* + * 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 zones = ["autosign", "manual"] %} + +include "kasp.conf"; +include "named.common.conf"; + +{% for tld in zones %} +zone "step1.csk-roll1.@tld@" { + type primary; + file "step1.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; +zone "step2.csk-roll1.@tld@" { + type primary; + file "step2.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; +zone "step3.csk-roll1.@tld@" { + type primary; + file "step3.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; +zone "step4.csk-roll1.@tld@" { + type primary; + file "step4.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; +zone "step5.csk-roll1.@tld@" { + type primary; + file "step5.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; +zone "step6.csk-roll1.@tld@" { + type primary; + file "step6.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; +zone "step7.csk-roll1.@tld@" { + type primary; + file "step7.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; +zone "step8.csk-roll1.@tld@" { + type primary; + file "step8.csk-roll1.@tld@.db"; + dnssec-policy "csk-roll1-@tld@"; +}; + +{% endfor %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/template.db.in bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-csk-roll1/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll1/ns3/template.db.in 2025-10-18 10:16:12.464730767 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll1/setup.sh bind9-9.20.15/bin/tests/system/rollover-csk-roll1/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-csk-roll1/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll1/setup.sh 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,314 @@ +#!/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 + +cd "ns3" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Set in the key state files the Predecessor/Successor fields. +# Key $1 is the predecessor of key $2. +key_successor() { + id1=$(keyfile_to_key_id "$1") + id2=$(keyfile_to_key_id "$2") + echo "Predecessor: ${id1}" >>"${2}.state" + echo "Successor: ${id2}" >>"${1}.state" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# +# The zones at csk-roll1.$tld represent the various steps of a CSK rollover +# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). +# + +for tld in autosign manual; do + # Step 1: + # Introduce the first key. This will immediately be active. + setup step1.csk-roll1.$tld + TactN="now-7d" + keytimes="-P ${TactN} -A ${TactN}" + CSK=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 2: + # It is time to introduce the new CSK. + setup step2.csk-roll1.$tld + # According to RFC 7583: + # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC + # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub + # IpubC = DprpC + TTLkey (+publish-safety) + # Ipub = IpubC + # Lcsk = Lksk = Lzsk + # + # Lcsk: 6mo (186d, 4464h) + # Dreg: N/A + # DprpC: 1h + # TTLkey: 1h + # publish-safety: 1h + # Ipub: 3h + # + # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h + # = now - 4464h + 3h = now - 4461h + TactN="now-4461h" + keytimes="-P ${TactN} -A ${TactN}" + CSK=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 3: + # It is time to submit the DS and to roll signatures. + setup step3.csk-roll1.$tld + # According to RFC 7583: + # + # Tsbm(N+1) >= Trdy(N+1) + # KSK: Tact(N+1) = Tsbm(N+1) + # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) + # KSK: Iret = DprpP + TTLds (+retire-safety) + # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) + # + # Lcsk: 186d + # Dprp: 1h + # DprpP: 1h + # Dreg: N/A + # Dsgn: 25d + # TTLds: 1h + # TTLsig: 1d + # retire-safety: 2h + # Iret: 4h + # IretZ: 26d3h + # Ipub: 3h + # + # Tpub(N) = now - Lcsk = now - 186d + # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h + # Tret(N) = now + # Trem(N) = now + IretZ = now + 26d3h = now + 627h + # Tpub(N+1) = now - Ipub = now - 3h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + Lcsk = now + 186d = now + 186d + # Trem(N+1) = now + Lcsk + IretZ = now + 186d + 26d3h = + # = now + 5091h + TpubN="now-186d" + TactN="now-4439h" + TretN="now" + TremN="now+627h" + TpubN1="now-3h" + TactN1="${TretN}" + TretN1="now+186d" + TremN1="now+5091h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 4: + # Some time later all the ZRRSIG records should be from the new CSK, and the + # DS should be swapped. The ZRRSIG records are all replaced after IretZ + # (which is 26d3h). The DS is swapped after Iret (which is 4h). + # In other words, the DS is swapped before all zone signatures are replaced. + setup step4.csk-roll1.$tld + # According to RFC 7583: + # Trem(N) = Tret(N) - Iret + IretZ + # now = Tsbm(N+1) + Iret + # + # Lcsk: 186d + # Iret: 4h + # IretZ: 26d3h + # + # Tpub(N) = now - Iret - Lcsk = now - 4h - 186d = now - 4468h + # Tret(N) = now - Iret = now - 4h = now - 4h + # Trem(N) = now - Iret + IretZ = now - 4h + 26d3h + # = now + 623h + # Tpub(N+1) = now - Iret - IpubC = now - 4h - 3h = now - 7h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now - Iret + Lcsk = now - 4h + 186d = now + 4460h + # Trem(N+1) = now - Iret + Lcsk + IretZ = now - 4h + 186d + 26d3h + # = now + 5087h + TpubN="now-4468h" + TactN="now-4443h" + TretN="now-4h" + TremN="now+623h" + TpubN1="now-7h" + TactN1="${TretN}" + TretN1="now+4460h" + TremN1="now+5087h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TactN1 -z $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -z $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 5: + # After the DS is swapped in step 4, also the KRRSIG records can be removed. + # At this time these have all become hidden. + setup step5.csk-roll1.$tld + # Subtract DNSKEY TTL plus zone propagation delay from all the times (2h). + TpubN="now-4470h" + TactN="now-4445h" + TretN="now-6h" + TremN="now+621h" + TpubN1="now-9h" + TactN1="${TretN}" + TretN1="now+4458h" + TremN1="now+5085h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $U now-2h -d $H now-2h -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O now-2h -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 6: + # After the retire interval has passed the predecessor DNSKEY can be + # removed from the zone. + setup step6.csk-roll1.$tld + # According to RFC 7583: + # Trem(N) = Tret(N) + IretZ + # Tret(N) = Tact(N) + Lcsk + # + # Lcsk: 186d + # Iret: 4h + # IretZ: 26d3h + # + # Tpub(N) = now - IretZ - Lcsk = now - 627h - 186d + # = now - 627h - 4464h = now - 5091h + # Tact(N) = now - 627h - 186d + # Tret(N) = now - IretZ = now - 627h + # Trem(N) = now + # Tpub(N+1) = now - IretZ - Ipub = now - 627h - 3h = now - 630h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now - IretZ + Lcsk = now - 627h + 186d = now + 3837h + # Trem(N+1) = now + Lcsk = now + 186d + TpubN="now-5091h" + TactN="now-5066h" + TretN="now-627h" + TremN="now" + TpubN1="now-630h" + TactN1="${TretN}" + TretN1="now+3837h" + TremN1="now+186d" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $H $TremN -d $H $TremN -z $U $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $R $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 7: + # Some time later the predecessor DNSKEY enters the HIDDEN state. + setup step7.csk-roll1.$tld + # Subtract DNSKEY TTL plus zone propagation delay from all the times (2h). + TpubN="now-5093h" + TactN="now-5068h" + TretN="now-629h" + TremN="now-2h" + TpubN1="now-632h" + TactN1="${TretN}" + TretN1="now+3835h" + TremN1="now+4462h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $U $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 8: + # The predecessor DNSKEY can be purged. + setup step8.csk-roll1.$tld + TpubN="now-5094h" + TactN="now-5069h" + TretN="now-630h" + TremN="now-3h" + TpubN1="now-633h" + TactN1="${TretN}" + TretN1="now+3834h" + TremN1="now+4461h" + # Subtract purge-keys interval from all the times (1h). + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll1-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $H $TremN -r $H $TremN -d $H $TremN -z $H $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 -z $O $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py bind9-9.20.15/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py --- bind9-9.20.11/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll1/tests_rollover_csk_roll1.py 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,434 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +from datetime import timedelta + +import pytest + +import isctest +from isctest.kasp import Ipub, Iret +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + TIMEDELTA, +) + + +CDSS = ["CDNSKEY", "CDS (SHA-384)"] +CONFIG = { + "dnskey-ttl": TIMEDELTA["PT1H"], + "ds-ttl": TIMEDELTA["PT1H"], + "max-zone-ttl": TIMEDELTA["P1D"], + "parent-propagation-delay": TIMEDELTA["PT1H"], + "publish-safety": TIMEDELTA["PT1H"], + "purge-keys": TIMEDELTA["PT1H"], + "retire-safety": TIMEDELTA["PT2H"], + "signatures-refresh": TIMEDELTA["P5D"], + "signatures-validity": TIMEDELTA["P30D"], + "zone-propagation-delay": TIMEDELTA["PT1H"], +} +POLICY = "csk-roll1" +CSK_LIFETIME = timedelta(days=31 * 6) +LIFETIME_POLICY = int(CSK_LIFETIME.total_seconds()) +IPUB = Ipub(CONFIG) +IRETZSK = Iret(CONFIG) +IRETKSK = Iret(CONFIG, zsk=False, ksk=True) +KEYTTLPROP = CONFIG["dnskey-ttl"] + CONFIG["zone-propagation-delay"] +SIGNDELAY = IRETZSK - IRETKSK - KEYTTLPROP +OFFSETS = {} +OFFSETS["step1-p"] = -int(timedelta(days=7).total_seconds()) +OFFSETS["step2-p"] = -int(CSK_LIFETIME.total_seconds() - IPUB.total_seconds()) +OFFSETS["step2-s"] = 0 +OFFSETS["step3-p"] = -int(CSK_LIFETIME.total_seconds()) +OFFSETS["step3-s"] = -int(IPUB.total_seconds()) +OFFSETS["step4-p"] = OFFSETS["step3-p"] - int(IRETKSK.total_seconds()) +OFFSETS["step4-s"] = OFFSETS["step3-s"] - int(IRETKSK.total_seconds()) +OFFSETS["step5-p"] = OFFSETS["step4-p"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step5-s"] = OFFSETS["step4-s"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(SIGNDELAY.total_seconds()) +OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(SIGNDELAY.total_seconds()) +OFFSETS["step7-p"] = OFFSETS["step6-p"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step7-s"] = OFFSETS["step6-s"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step8-p"] = OFFSETS["step7-p"] - int(CONFIG["purge-keys"].total_seconds()) +OFFSETS["step8-s"] = OFFSETS["step7-s"] - int(CONFIG["purge-keys"].total_seconds()) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step1(tld, alg, size, ns3): + zone = f"step1.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + # Note that the key was already generated during setup. + + step = { + # Introduce the first key. This will immediately be active. + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step1-p']}", + ], + # Next key event is when the successor CSK needs to be published + # minus time already elapsed. This is Lcsk - Ipub + Dreg (we ignore + # registration delay). + "nextev": CSK_LIFETIME - IPUB - timedelta(days=7), + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step2(tld, alg, size, ns3): + zone = f"step2.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 1. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block CSK rollover for key {zone}/ECDSAP256SHA256/{tag} (policy {policy})" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # Successor CSK is prepublished (signs DNSKEY RRset, but not yet + # other RRsets). + # CSK1 goal: omnipresent -> hidden + # CSK2 goal: hidden -> omnipresent + # CSK2 dnskey: hidden -> rumoured + # CSK2 krrsig: hidden -> rumoured + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:hidden ds:hidden offset:{OFFSETS['step2-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the successor CSK becomes OMNIPRESENT. + "nextev": IPUB, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step3(tld, alg, size, ns3): + zone = f"step3.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 2, but DNSKEY has become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step3-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:hidden ds:hidden offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [0, 1], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state HIDDEN to state RUMOURED" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE" + if msg in ns3.log: + # Force step. + isctest.log.debug( + f"keymgr-manual-mode blocking transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE, step again" + ) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # Successor CSK becomes omnipresent, meaning we can start signing + # the remainder of the zone with the successor CSK, and we can + # submit the DS. + "zone": zone, + "cdss": CDSS, + # Predecessor CSK will be removed, so moving to UNRETENTIVE. + # CSK1 zrrsig: omnipresent -> unretentive + # Successor CSK DNSKEY is OMNIPRESENT, so moving ZRRSIG to RUMOURED. + # CSK2 dnskey: rumoured -> omnipresent + # CSK2 krrsig: rumoured -> omnipresent + # CSK2 zrrsig: hidden -> rumoured + # The predecessor DS can be withdrawn and the successor DS can be + # introduced. + # CSK1 ds: omnipresent -> unretentive + # CSK2 ds: hidden -> rumoured + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:unretentive offset:{OFFSETS['step3-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:rumoured offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the predecessor DS has been replaced with + # the successor DS and enough time has passed such that the all + # validators that have this DS RRset cached only know about the + # successor DS. This is the the retire interval. + "nextev": IRETKSK, + # Set 'smooth' to true so expected signatures of subdomain are + # from the predecessor ZSK. + "smooth": True, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step4(tld, alg, size, ns3): + zone = f"step4.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 3, but DS has become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:hidden offset:{OFFSETS['step4-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [0, 1], + "manual-mode": True, + "nextev": None, + # We already swapped the DS in the previous step, so disable ds-swap. + "ds-swap": False, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type KRRSIG state OMNIPRESENT to state UNRETENTIVE" + + ns3.log.expect(msg) + + # Force step. + tag = keys[1].key.tag + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor CSK is no longer signing the DNSKEY RRset. + # CSK1 krrsig: omnipresent -> unretentive + # The predecessor DS is hidden. The successor DS is now omnipresent. + # CSK1 ds: unretentive -> hidden + # CSK2 ds: rumoured -> omnipresent + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:unretentive zrrsig:unretentive ds:hidden offset:{OFFSETS['step4-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the KRRSIG enters the HIDDEN state. + # This is the DNSKEY TTL plus zone propagation delay. + "nextev": KEYTTLPROP, + # We already swapped the DS in the previous step, so disable ds-swap. + "ds-swap": False, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step5(tld, alg, size, ns3): + zone = f"step5.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor KRRSIG records are now all hidden. + # CSK1 krrsig: unretentive -> hidden + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:hidden zrrsig:unretentive ds:hidden offset:{OFFSETS['step5-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:omnipresent offset:{OFFSETS['step5-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the DNSKEY can be removed. This is when + # all ZRRSIG records have been replaced with signatures of the new + # CSK. + "nextev": SIGNDELAY, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step6(tld, alg, size, ns3): + zone = f"step6.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + return + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor ZRRSIG records are now all hidden (so the DNSKEY + # can be removed). + # CSK1 dnskey: omnipresent -> unretentive + # CSK1 zrrsig: unretentive -> hidden + # CSK2 zrrsig: rumoured -> omnipresent + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:unretentive krrsig:hidden zrrsig:hidden ds:hidden offset:{OFFSETS['step6-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the DNSKEY enters the HIDDEN state. + # This is the DNSKEY TTL plus zone propagation delay. + "nextev": KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step7(tld, alg, size, ns3): + zone = f"step7.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor CSK is now completely HIDDEN. + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{OFFSETS['step7-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step7-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the new successor needs to be published. + # This is the Lcsk, minus time passed since the key started signing, + # minus the prepublication time. + "nextev": CSK_LIFETIME - IRETZSK - IPUB - KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll1_step8(tld, alg, size, ns3): + zone = f"step8.csk-roll1.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step8-s']}", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/kasp.conf.j2 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,58 @@ +/* + * 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. + */ + +dnssec-policy "csk-roll2-autosign" { + signatures-refresh 12h; + signatures-validity P1D; + signatures-validity-dnskey P1D; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 1h; + purge-keys 0; + + cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes + keys { + csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; + + parent-ds-ttl PT1H; + parent-propagation-delay P1W; +}; + +dnssec-policy "csk-roll2-manual" { + manual-mode yes; + + signatures-refresh 12h; + signatures-validity P1D; + signatures-validity-dnskey P1D; + + dnskey-ttl 1h; + publish-safety PT1H; + retire-safety 1h; + purge-keys 0; + + cds-digest-types { "sha-256"; "sha-384"; }; // use two digest type for testing purposes + keys { + csk key-directory lifetime P6M algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; + + parent-ds-ttl PT1H; + parent-propagation-delay P1W; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/named.conf.j2 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,56 @@ +/* + * 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 zones = ["autosign", "manual"] %} + +include "kasp.conf"; +include "named.common.conf"; + +{% for tld in zones %} +zone "step1.csk-roll2.@tld@" { + type primary; + file "step1.csk-roll2.@tld@.db"; + dnssec-policy "csk-roll2-@tld@"; +}; +zone "step2.csk-roll2.@tld@" { + type primary; + file "step2.csk-roll2.@tld@.db"; + dnssec-policy "csk-roll2-@tld@"; +}; +zone "step3.csk-roll2.@tld@" { + type primary; + file "step3.csk-roll2.@tld@.db"; + dnssec-policy "csk-roll2-@tld@"; +}; +zone "step4.csk-roll2.@tld@" { + type primary; + file "step4.csk-roll2.@tld@.db"; + dnssec-policy "csk-roll2-@tld@"; +}; +zone "step5.csk-roll2.@tld@" { + type primary; + file "step5.csk-roll2.@tld@.db"; + dnssec-policy "csk-roll2-@tld@"; +}; +zone "step6.csk-roll2.@tld@" { + type primary; + file "step6.csk-roll2.@tld@.db"; + dnssec-policy "csk-roll2-@tld@"; +}; +zone "step7.csk-roll2.@tld@" { + type primary; + file "step7.csk-roll2.@tld@.db"; + dnssec-policy "csk-roll2-@tld@"; +}; + +{% endfor %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/template.db.in bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-csk-roll2/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll2/ns3/template.db.in 2025-10-18 10:16:12.464730767 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll2/setup.sh bind9-9.20.15/bin/tests/system/rollover-csk-roll2/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-csk-roll2/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll2/setup.sh 2025-10-18 10:16:12.459730689 +0000 @@ -0,0 +1,301 @@ +#!/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 + +cd "ns3" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Set in the key state files the Predecessor/Successor fields. +# Key $1 is the predecessor of key $2. +key_successor() { + id1=$(keyfile_to_key_id "$1") + id2=$(keyfile_to_key_id "$2") + echo "Predecessor: ${id1}" >>"${2}.state" + echo "Successor: ${id2}" >>"${1}.state" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# +# The zones at csk-roll2.$tld represent the various steps of a CSK rollover +# (which is essentially a ZSK Pre-Publication / KSK Double-KSK rollover). +# This scenario differs from the csk-roll1 one because the zone signatures (ZRRSIG) +# are replaced with the new key sooner than the DS is swapped. +# + +for tld in autosign manual; do + # Step 1: + # Introduce the first key. This will immediately be active. + setup step1.csk-roll2.$tld + TactN="now-7d" + keytimes="-P ${TactN} -A ${TactN}" + CSK=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 2: + # It is time to introduce the new CSK. + setup step2.csk-roll2.$tld + # According to RFC 7583: + # KSK: Tpub(N+1) <= Tact(N) + Lksk - IpubC + # ZSK: Tpub(N+1) <= Tact(N) + Lzsk - Ipub + # IpubC = DprpC + TTLkey (+publish-safety) + # Ipub = IpubC + # Lcsk = Lksk = Lzsk + # + # Lcsk: 6mo (186d, 4464h) + # Dreg: N/A + # DprpC: 1h + # TTLkey: 1h + # publish-safety: 1h + # Ipub: 3h + # + # Tact(N) = now - Lcsk + Ipub = now - 186d + 3h + # = now - 4464h + 3h = now - 4461h + TactN="now-4461h" + keytimes="-P ${TactN} -A ${TactN}" + CSK=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 3: + # It is time to submit the DS and to roll signatures. + setup step3.csk-roll2.$tld + # According to RFC 7583: + # + # Tsbm(N+1) >= Trdy(N+1) + # KSK: Tact(N+1) = Tsbm(N+1) + # ZSK: Tact(N+1) = Tpub(N+1) + Ipub = Tsbm(N+1) + # KSK: Iret = DprpP + TTLds (+retire-safety) + # ZSK: IretZ = Dsgn + Dprp + TTLsig (+retire-safety) + # + # Lcsk: 186d + # Dprp: 1h + # DprpP: 1w + # Dreg: N/A + # Dsgn: 12h + # TTLds: 1h + # TTLsig: 1d + # retire-safety: 1h + # Iret: 170h + # IretZ: 38h + # Ipub: 3h + # + # Tpub(N) = now - Lcsk = now - 186d + # Tact(N) = now - Lcsk + Dprp + TTLsig = now - 4439h + # Tret(N) = now + # Trem(N) = now + Iret = now + 170h + # Tpub(N+1) = now - Ipub = now - 3h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + Lcsk = now + 186d + # Trem(N+1) = now + Lcsk + Iret = now + 186d + 170h = + # = now + 4464h + 170h = now + 4634h + TpubN="now-186d" + TactN="now-4439h" + TretN="now" + TremN="now+170h" + TpubN1="now-3h" + TactN1="${TretN}" + TretN1="now+186d" + TremN1="now+4634h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN -z $O $TactN "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 -z $H $TpubN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 4: + # Some time later all the ZRRSIG records should be from the new CSK, and the + # DS should be swapped. The ZRRSIG records are all replaced after IretZ (38h). + # The DS is swapped after Dreg + Iret (1w3h). In other words, the zone + # signatures are replaced before the DS is swapped. + setup step4.csk-roll2.$tld + # According to RFC 7583: + # Trem(N) = Tret(N) + IretZ + # + # Lcsk: 186d + # Dreg: N/A + # Iret: 170h + # IretZ: 38h + # + # Tpub(N) = now - IretZ - Lcsk = now - 38h - 186d + # = now - 38h - 4464h = now - 4502h + # Tact(N) = now - Iret - Lcsk + TTLsig = now - 4502h + 25h = now - 4477h + # Tret(N) = now - IretZ = now - 38h + # Trem(N) = now - IretZ + Iret = now - 38h + 170h = now + 132h + # Tpub(N+1) = now - IretZ - IpubC = now - 38h - 3h = now - 41h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now - IretZ + Lcsk = now - 38h + 186d + # = now + 4426h + # Trem(N+1) = now - IretZ + Lcsk + Iret + # = now + 4426h + 3h = now + 4429h + TpubN="now-4502h" + TactN="now-4477h" + TretN="now-38h" + TremN="now+132h" + TpubN1="now-41h" + TactN1="${TretN}" + TretN1="now+4426h" + TremN1="now+4429h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $U $TretN -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $R $TactN1 -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 5: + # Some time later the DS can be swapped and the old DNSKEY can be removed from + # the zone. + setup step5.csk-roll2.$tld + # Subtract Iret (170h) - IretZ (38h) = 132h. + # + # Tpub(N) = now - 4502h - 132h = now - 4634h + # Tact(N) = now - 4477h - 132h = now - 4609h + # Tret(N) = now - 38h - 132h = now - 170h + # Trem(N) = now + 132h - 132h = now + # Tpub(N+1) = now - 41h - 132h = now - 173h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4426h - 132h = now + 4294h + # Trem(N+1) = now + 4492h - 132h = now + 4360h + TpubN="now-4634h" + TactN="now-4609h" + TretN="now-170h" + TremN="now" + TpubN1="now-173h" + TactN1="${TretN}" + TretN1="now+4294h" + TremN1="now+4360h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -z $H now-133h -d $U $TactN1 -D ds $TactN1 "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -z $O now-133h -d $R $TactN1 -P ds $TactN1 "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 6: + # Some time later the predecessor DNSKEY enters the HIDDEN state. + setup step6.csk-roll2.$tld + # Subtract DNSKEY TTL plus zone propagation delay (2h). + # + # Tpub(N) = now - 4634h - 2h = now - 4636h + # Tact(N) = now - 4609h - 2h = now - 4611h + # Tret(N) = now - 170h - 2h = now - 172h + # Trem(N) = now - 2h + # Tpub(N+1) = now - 173h - 2h = now - 175h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4294h - 2h = now + 4292h + # Trem(N+1) = now + 4360h - 2h = now + 4358h + TpubN="now-4636h" + TactN="now-4611h" + TretN="now-172h" + TremN="now-2h" + TpubN1="now-175h" + TactN1="${TretN}" + TretN1="now+4292h" + TremN1="now+4358h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 7: + # The predecessor DNSKEY can be purged, but purge-keys is disabled. + setup step7.csk-roll2.$tld + # Subtract 90 days (default, 2160h) from all the times. + # + # Tpub(N) = now - 4636h - 2160h = now - 6796h + # Tact(N) = now - 4611h - 2160h = now - 6771h + # Tret(N) = now - 172h - 2160h = now - 2332h + # Trem(N) = now - 2h - 2160h = now - 2162h + # Tpub(N+1) = now - 175h - 2160h = now - 2335h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 4292h - 2160h = now + 2132h + # Trem(N+1) = now + 4358h - 2160h = now + 2198h + TpubN="now-6796h" + TactN="now-6771h" + TretN="now-2332h" + TremN="now-2162h" + TpubN1="now-2335h" + TactN1="${TretN}" + TretN1="now+2132h" + TremN1="now+2198h" + keytimes="-P ${TpubN} -P sync ${TactN} -A ${TpubN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -P sync ${TactN1} -A ${TactN1} -I ${TretN1} -D ${TremN1}" + CSK1=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + CSK2=$($KEYGEN -k csk-roll2-$tld -l kasp.conf $newtimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $U $TremN -r $U $TremN -d $H $TremN -z $H now-135h "$CSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TremN -z $O now-135h "$CSK2" >settime.out.$zone.2 2>&1 + # Set key rollover relationship. + key_successor $CSK1 $CSK2 + # Sign zone. + cat template.db.in "${CSK1}.key" "${CSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -G "cdnskey,cds:sha-256,cds:sha-384" -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py bind9-9.20.15/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py --- bind9-9.20.11/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-csk-roll2/tests_rollover_csk_roll2.py 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,409 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +from datetime import timedelta + +import pytest + +import isctest +from isctest.kasp import Ipub, Iret +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + TIMEDELTA, +) + + +CDSS = ["CDNSKEY", "CDS (SHA-256)", "CDS (SHA-384)"] +CONFIG = { + "dnskey-ttl": TIMEDELTA["PT1H"], + "ds-ttl": TIMEDELTA["PT1H"], + "max-zone-ttl": TIMEDELTA["P1D"], + "parent-propagation-delay": TIMEDELTA["P7D"], + "publish-safety": TIMEDELTA["PT1H"], + "purge-keys": TIMEDELTA[0], + "retire-safety": TIMEDELTA["PT1H"], + "signatures-refresh": TIMEDELTA["PT12H"], + "signatures-validity": TIMEDELTA["P1D"], + "zone-propagation-delay": TIMEDELTA["PT1H"], +} +POLICY = "csk-roll2" +CSK_LIFETIME = timedelta(days=31 * 6) +LIFETIME_POLICY = int(CSK_LIFETIME.total_seconds()) + +IPUB = Ipub(CONFIG) +IRET = Iret(CONFIG, zsk=True, ksk=True) +IRETZSK = Iret(CONFIG) +IRETKSK = Iret(CONFIG, ksk=True) +KEYTTLPROP = CONFIG["dnskey-ttl"] + CONFIG["zone-propagation-delay"] +OFFSETS = {} +OFFSETS["step1-p"] = -int(timedelta(days=7).total_seconds()) +OFFSETS["step2-p"] = -int(CSK_LIFETIME.total_seconds() - IPUB.total_seconds()) +OFFSETS["step2-s"] = 0 +OFFSETS["step3-p"] = -int(CSK_LIFETIME.total_seconds()) +OFFSETS["step3-s"] = -int(IPUB.total_seconds()) +OFFSETS["step4-p"] = OFFSETS["step3-p"] - int(IRETZSK.total_seconds()) +OFFSETS["step4-s"] = OFFSETS["step3-s"] - int(IRETZSK.total_seconds()) +OFFSETS["step5-p"] = OFFSETS["step4-p"] - int( + IRETKSK.total_seconds() - IRETZSK.total_seconds() +) +OFFSETS["step5-s"] = OFFSETS["step4-s"] - int( + IRETKSK.total_seconds() - IRETZSK.total_seconds() +) +OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step7-p"] = OFFSETS["step6-p"] - int(timedelta(days=90).total_seconds()) +OFFSETS["step7-s"] = OFFSETS["step6-s"] - int(timedelta(days=90).total_seconds()) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll2_step1(tld, alg, size, ns3): + zone = f"step1.csk-roll2.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + # Note that the key was already generated during setup. + + step = { + # Introduce the first key. This will immediately be active. + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step1-p']}", + ], + # Next key event is when the successor CSK needs to be published + # minus time already elapsed. This is Lcsk - Ipub + Dreg (we ignore + # registration delay). + "nextev": CSK_LIFETIME - IPUB - TIMEDELTA["P7D"], + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll2_step2(tld, alg, size, ns3): + zone = f"step2.csk-roll2.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 1. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block CSK rollover for key {zone}/ECDSAP256SHA256/{tag} (policy {policy})" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # Successor CSK is prepublished (signs DNSKEY RRset, but not yet + # other RRsets). + # CSK1 goal: omnipresent -> hidden + # CSK2 goal: hidden -> omnipresent + # CSK2 dnskey: hidden -> rumoured + # CSK2 krrsig: hidden -> rumoured + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:hidden ds:hidden offset:{OFFSETS['step2-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the successor CSK becomes OMNIPRESENT. + "nextev": IPUB, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll2_step3(tld, alg, size, ns3): + zone = f"step3.csk-roll2.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 2, but DNSKEY has become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step3-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:hidden ds:hidden offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [0, 1], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state HIDDEN to state RUMOURED" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE" + if msg in ns3.log: + # Force step. + isctest.log.debug( + f"keymgr-manual-mode blocking transition CSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE, step again" + ) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # Successor CSK becomes omnipresent, meaning we can start signing + # the remainder of the zone with the successor CSK, and we can + # submit the DS. + "zone": zone, + "cdss": CDSS, + # Predecessor CSK will be removed, so moving to UNRETENTIVE. + # CSK1 zrrsig: omnipresent -> unretentive + # Successor CSK DNSKEY is OMNIPRESENT, so moving ZRRSIG to RUMOURED. + # CSK2 dnskey: rumoured -> omnipresent + # CSK2 krrsig: rumoured -> omnipresent + # CSK2 zrrsig: hidden -> rumoured + # The predecessor DS can be withdrawn and the successor DS can be + # introduced. + # CSK1 ds: omnipresent -> unretentive + # CSK2 ds: hidden -> rumoured + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:unretentive ds:unretentive offset:{OFFSETS['step3-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:rumoured offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the predecessor DS has been replaced with + # the successor DS and enough time has passed such that the all + # validators that have this DS RRset cached only know about the + # successor DS. This is the the retire interval. + "nextev": IRETZSK, + # Set 'smooth' to true so expected signatures of subdomain are + # from the predecessor ZSK. + "smooth": True, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll2_step4(tld, alg, size, ns3): + zone = f"step4.csk-roll2.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor ZRRSIG is HIDDEN. The successor ZRRSIG is + # OMNIPRESENT. + # CSK1 zrrsig: unretentive -> hidden + # CSK2 zrrsig: rumoured -> omnipresent + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:hidden ds:unretentive offset:{OFFSETS['step4-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the predecessor DS has been replaced with + # the successor DS and enough time has passed such that the all + # validators that have this DS RRset cached only know about the + # successor DS. This is the retire interval of the KSK part (minus) + # time already elapsed). + "nextev": IRET - IRETZSK, + # We already swapped the DS in the previous step, so disable ds-swap. + "ds-swap": False, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll2_step5(tld, alg, size, ns3): + zone = f"step5.csk-roll2.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 4, but DS has become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent zrrsig:hidden ds:hidden offset:{OFFSETS['step5-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step5-s']}", + ], + "keyrelationships": [0, 1], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg1 = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" + msg2 = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type KRRSIG state OMNIPRESENT to state UNRETENTIVE" + ns3.log.expect(msg1) + ns3.log.expect(msg2) + + # Force step. + tag = keys[1].key.tag + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor DNSKEY can be removed. + # CSK1 dnskey: omnipresent -> unretentive + # CSK1 krrsig: omnipresent -> unretentive + # CSK1 ds: unretentive -> hidden + # The successor key is now fully OMNIPRESENT. + # CSK2 ds: rumoured -> omnipresent + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive zrrsig:hidden ds:hidden offset:{OFFSETS['step5-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step5-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the DNSKEY enters the HIDDEN state. + # This is the DNSKEY TTL plus zone propagation delay. + "nextev": KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll2_step6(tld, alg, size, ns3): + zone = f"step6.csk-roll2.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor CSK is now completely HIDDEN. + # CSK1 dnskey: unretentive -> hidden + # CSK1 krrsig: unretentive -> hidden + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{OFFSETS['step6-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6-s']}", + ], + "keyrelationships": [0, 1], + # Next key event is when the new successor needs to be published. + # This is the Lcsk, minus time passed since the key was published. + "nextev": CSK_LIFETIME - IRET - IPUB - KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_csk_roll2_step7(tld, alg, size, ns3): + zone = f"step7.csk-roll2.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + # The predecessor CSK is now completely HIDDEN. + "keyprops": [ + f"csk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden zrrsig:hidden ds:hidden offset:{OFFSETS['step7-p']}", + f"csk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step7-s']}", + ], + "keyrelationships": [0, 1], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db --- bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/dynamic2inline.kasp.db 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/named.common.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,35 @@ +/* + * 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 { + query-source address 10.53.0.6; + notify-source 10.53.0.6; + transfer-source 10.53.0.6; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.6; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/named.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -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. + */ + +include "named.common.conf"; + +zone "dynamic2inline.kasp" { + type primary; + file "dynamic2inline.kasp.db"; + allow-update { any; }; + dnssec-policy "default"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/ns6/template.db.in 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py --- bind9-9.20.11/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-dynamic2inline/tests_rollover_dynamic2inline.py 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,46 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import isctest +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + DEFAULT_CONFIG, +) + + +def test_dynamic2inline(alg, size, ns6, templates): + config = DEFAULT_CONFIG + policy = "default" + zone = "dynamic2inline.kasp" + + isctest.kasp.wait_keymgr_done(ns6, zone) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + "nextev": None, + } + + isctest.kasp.check_rollover_step(ns6, config, policy, step) + + templates.render("ns6/named.conf", {"change_lifetime": True}) + ns6.reconfigure() + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/kasp.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,52 @@ +/* + * 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. + */ + +dnssec-policy "enable-dnssec-autosign" { + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 300; + max-zone-ttl PT12H; + zone-propagation-delay PT5M; + retire-safety PT20M; + publish-safety PT5M; + + parent-propagation-delay 1h; + parent-ds-ttl 2h; + + keys { + csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@; + }; +}; + +dnssec-policy "enable-dnssec-manual" { + manual-mode yes; + + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 300; + max-zone-ttl PT12H; + zone-propagation-delay PT5M; + retire-safety PT20M; + publish-safety PT5M; + + parent-propagation-delay 1h; + parent-ds-ttl 2h; + + keys { + csk lifetime unlimited algorithm @DEFAULT_ALGORITHM_NUMBER@; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/named.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,41 @@ +/* + * 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 zones = ["autosign", "manual"] %} + +include "kasp.conf"; +include "named.common.conf"; + +{% for tld in zones %} +zone "step1.enable-dnssec.@tld@" { + type primary; + file "step1.enable-dnssec.@tld@.db"; + dnssec-policy "enable-dnssec-@tld@"; +}; +zone "step2.enable-dnssec.@tld@" { + type primary; + file "step2.enable-dnssec.@tld@.db"; + dnssec-policy "enable-dnssec-@tld@"; +}; +zone "step3.enable-dnssec.@tld@" { + type primary; + file "step3.enable-dnssec.@tld@.db"; + dnssec-policy "enable-dnssec-@tld@"; +}; +zone "step4.enable-dnssec.@tld@" { + type primary; + file "step4.enable-dnssec.@tld@.db"; + dnssec-policy "enable-dnssec-@tld@"; +}; + +{% endfor %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/template.db.in bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/ns3/template.db.in 2025-10-18 10:16:12.464730767 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/setup.sh bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/setup.sh 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,102 @@ +#!/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 + +cd "ns3" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Set in the key state files the Predecessor/Successor fields. +# Key $1 is the predecessor of key $2. +key_successor() { + id1=$(keyfile_to_key_id "$1") + id2=$(keyfile_to_key_id "$2") + echo "Predecessor: ${id1}" >>"${2}.state" + echo "Successor: ${id2}" >>"${1}.state" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# +# The zones at enable-dnssec.$tld represent the various steps of the +# initial signing of a zone. +# + +for tld in autosign manual; do + # Step 1: + # This is an unsigned zone and named should perform the initial steps of + # introducing the DNSSEC records in the right order. + setup step1.enable-dnssec.$tld + cp template.db.in $zonefile + + # Step 2: + # The DNSKEY has been published long enough to become OMNIPRESENT. + setup step2.enable-dnssec.$tld + # DNSKEY TTL: 300 seconds + # zone-propagation-delay: 5 minutes (300 seconds) + # publish-safety: 5 minutes (300 seconds) + # Total: 900 seconds + TpubN="now-900s" + keytimes="-P ${TpubN} -A ${TpubN}" + CSK=$($KEYGEN -k enable-dnssec-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -k $R $TpubN -r $R $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 3: + # The zone signatures have been published long enough to become OMNIPRESENT. + setup step3.enable-dnssec.$tld + # Passed time since publication: + # max-zone-ttl: 12 hours (43200 seconds) + # zone-propagation-delay: 5 minutes (300 seconds) + TpubN="now-43500s" + # We can submit the DS now. + keytimes="-P ${TpubN} -A ${TpubN}" + CSK=$($KEYGEN -k enable-dnssec-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -k $O $TpubN -r $O $TpubN -d $H $TpubN -z $R $TpubN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 4: + # The DS has been submitted long enough ago to become OMNIPRESENT. + setup step4.enable-dnssec.$tld + # DS TTL: 2 hour (7200 seconds) + # parent-propagation-delay: 1 hour (3600 seconds) + # Total aditional time: 10800 seconds + # 43500 + 10800 = 54300 + TpubN="now-54300s" + TsbmN="now-10800s" + keytimes="-P ${TpubN} -A ${TpubN} -P sync ${TsbmN}" + CSK=$($KEYGEN -k enable-dnssec-$tld -l kasp.conf $keytimes $zone 2>keygen.out.$zone.1) + $SETTIME -s -g $O -P ds $TsbmN -k $O $TpubN -r $O $TpubN -d $R $TpubN -z $O $TsbmN "$CSK" >settime.out.$zone.1 2>&1 + cat template.db.in "${CSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -z -x -s now-1h -e now+30d -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py --- bind9-9.20.11/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-enable-dnssec/tests_rollover_enable_dnssec.py 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,210 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from isctest.kasp import Ipub, IpubC, Iret +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + TIMEDELTA, +) + +CONFIG = { + "dnskey-ttl": TIMEDELTA["PT5M"], + "ds-ttl": TIMEDELTA["PT2H"], + "max-zone-ttl": TIMEDELTA["PT12H"], + "parent-propagation-delay": TIMEDELTA["PT1H"], + "publish-safety": TIMEDELTA["PT5M"], + "retire-safety": TIMEDELTA["PT20M"], + "signatures-refresh": TIMEDELTA["P7D"], + "signatures-validity": TIMEDELTA["P14D"], + "zone-propagation-delay": TIMEDELTA["PT5M"], +} +POLICY = "enable-dnssec" +IPUB = Ipub(CONFIG) +IPUBC = IpubC(CONFIG, rollover=False) +IRETZSK = Iret(CONFIG, rollover=False) +IRETKSK = Iret(CONFIG, zsk=False, ksk=True, rollover=False) +OFFSETS = {} +OFFSETS["step1"] = 0 +OFFSETS["step2"] = -int(IPUB.total_seconds()) +OFFSETS["step3"] = -int(IRETZSK.total_seconds()) +OFFSETS["step4"] = -int(IPUBC.total_seconds() + IRETKSK.total_seconds()) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_rollover_enable_dnssec_step1(tld, alg, size, ns3): + zone = f"step1.enable-dnssec.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as insecure. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [], + "manual-mode": True, + "zone-signed": False, + "nextev": None, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + msg = f"keymgr-manual-mode: block new key generation for zone {zone} (policy {policy})" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden offset:{OFFSETS['step1']}", + ], + # Next key event is when the DNSKEY RRset becomes OMNIPRESENT, + # after the publication interval. + "nextev": IPUB, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_rollover_enable_dnssec_step2(tld, alg, size, ns3): + zone = f"step2.enable-dnssec.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + # The DNSKEY is omnipresent, but the zone signatures not yet. + # Thus, the DS remains hidden. + # dnskey: rumoured -> omnipresent + # krrsig: rumoured -> omnipresent + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:rumoured ds:hidden offset:{OFFSETS['step2']}", + ], + # Next key event is when the zone signatures become OMNIPRESENT, + # Minus the time already elapsed. + "nextev": IRETZSK - IPUB, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_rollover_enable_dnssec_step3(tld, alg, size, ns3): + zone = f"step3.enable-dnssec.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 2, but zone signatures have become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:hidden offset:{OFFSETS['step3']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[0].key.tag + msg = f"keymgr-manual-mode: block transition CSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + "zone": zone, + "cdss": CDSS, + # All signatures should be omnipresent, so the DS can be submitted. + # zrrsig: rumoured -> omnipresent + # ds: hidden -> rumoured + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:rumoured offset:{OFFSETS['step3']}", + ], + # Next key event is when the DS can move to the OMNIPRESENT state. + # This is after the retire interval. + "nextev": IRETKSK, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_rollover_enable_dnssec_step4(tld, alg, size, ns3): + zone = f"step4.enable-dnssec.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + "zone": zone, + "cdss": CDSS, + # DS has been published long enough. + # ds: rumoured -> omnipresent + "keyprops": [ + f"csk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4']}", + ], + # Next key event is never, the zone dnssec-policy has been + # established. So we fall back to the default loadkeys interval. + "nextev": TIMEDELTA["PT1H"], + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/kasp.conf.j2 2025-10-18 10:16:12.461730720 +0000 @@ -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. + */ + +dnssec-policy "unsigning" { + dnskey-ttl 7200; + + keys { + ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/named.common.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,35 @@ +/* + * 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 { + query-source address 10.53.0.6; + notify-source 10.53.0.6; + transfer-source 10.53.0.6; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.6; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/named.conf.j2 2025-10-18 10:16:12.461730720 +0000 @@ -0,0 +1,49 @@ +/* + * 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 policy = policy | default("unsigning") %} + +include "kasp.conf"; +include "named.common.conf"; + +zone "step1.going-insecure.kasp" { + type primary; + file "step1.going-insecure.kasp.db"; + dnssec-policy @policy@; +}; + +{% if policy == "insecure" %} +zone "step2.going-insecure.kasp" { + type primary; + file "step2.going-insecure.kasp.db"; + dnssec-policy insecure; +}; +{% endif %} + +zone "step1.going-insecure-dynamic.kasp" { + type primary; + file "step1.going-insecure-dynamic.kasp.db"; + dnssec-policy @policy@; + inline-signing no; + allow-update { any; }; +}; + +{% if policy == "insecure" %} +zone "step2.going-insecure-dynamic.kasp" { + type primary; + file "step2.going-insecure-dynamic.kasp.db"; + dnssec-policy insecure; + inline-signing no; + allow-update { any; }; +}; +{% endif %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/template.db.in bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-going-insecure/ns6/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-going-insecure/ns6/template.db.in 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-going-insecure/setup.sh bind9-9.20.15/bin/tests/system/rollover-going-insecure/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-going-insecure/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-going-insecure/setup.sh 2025-10-18 10:16:12.461730720 +0000 @@ -0,0 +1,71 @@ +#!/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 + +cd "ns6" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# The child zones (step1, step2) beneath these zones represent the various +# steps of unsigning a zone. +for zn in going-insecure.kasp going-insecure-dynamic.kasp; do + # Step 1: + # Set up a zone with dnssec-policy that is going insecure. + setup step1.$zn + echo "$zone" >>zones + T="now-10d" + S="now-12955mi" + keytimes="-P $T -A $T" + cdstimes="-P sync $S" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) + cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 2: + # Set up a zone with dnssec-policy that is going insecure. Don't add + # this zone to the zones file, because this zone is no longer expected + # to be fully signed. + setup step2.$zn + # The DS was withdrawn from the parent zone 26 hours ago. + D="now-26h" + keytimes="-P $T -A $T -I $D -D now" + cdstimes="-P sync $S -D sync $D" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $H -k $O $T -r $O $T -d $U $D -D ds $D "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 + # Fake lifetime of old algorithm keys. + echo "Lifetime: 0" >>"${KSK}.state" + echo "Lifetime: 5184000" >>"${ZSK}.state" + cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py bind9-9.20.15/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py --- bind9-9.20.11/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_initial.py 2025-10-18 10:16:12.461730720 +0000 @@ -0,0 +1,50 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + DURATION, + UNSIGNING_CONFIG, +) + + +@pytest.mark.parametrize( + "zone", + [ + "going-insecure.kasp", + "going-insecure-dynamic.kasp", + ], +) +def test_going_insecure_initial(zone, ns6, alg, size): + config = UNSIGNING_CONFIG + policy = "unsigning" + zone = f"step1.{zone}" + + isctest.kasp.wait_keymgr_done(ns6, zone) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{-DURATION['P10D']}", + f"zsk {DURATION['P60D']} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{-DURATION['P10D']}", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py bind9-9.20.15/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py --- bind9-9.20.11/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-going-insecure/tests_rollover_going_insecure_reconfig.py 2025-10-18 10:16:12.461730720 +0000 @@ -0,0 +1,99 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + DEFAULT_CONFIG, + DURATION, + UNSIGNING_CONFIG, +) + + +@pytest.fixture(scope="module", autouse=True) +def reconfigure_policy(ns6, templates): + templates.render("ns6/named.conf", {"policy": "insecure"}) + ns6.reconfigure() + + +@pytest.mark.parametrize( + "zone", + [ + "going-insecure.kasp", + "going-insecure-dynamic.kasp", + ], +) +def test_going_insecure_reconfig_step1(zone, alg, size, ns6): + config = DEFAULT_CONFIG + policy = "insecure" + zone = f"step1.{zone}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # Key goal states should be HIDDEN. + # The DS may be removed if we are going insecure. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{-DURATION['P10D']}", + f"zsk {DURATION['P60D']} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{-DURATION['P10D']}", + ], + # Next key event is when the DS becomes HIDDEN. This + # happens after the# parent propagation delay plus DS TTL. + "nextev": DEFAULT_CONFIG["ds-ttl"] + DEFAULT_CONFIG["parent-propagation-delay"], + # Going insecure, check for CDS/CDNSKEY DELETE, and skip key timing checks. + "cds-delete": True, + "check-keytimes": False, + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) + + +@pytest.mark.parametrize( + "zone", + [ + "going-insecure.kasp", + "going-insecure-dynamic.kasp", + ], +) +def test_going_insecure_reconfig_step2(zone, alg, size, ns6): + config = DEFAULT_CONFIG + policy = "insecure" + zone = f"step2.{zone}" + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + # The DS is long enough removed from the zone to be considered + # HIDDEN. This means the DNSKEY and the KSK signatures can be + # removed. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk 0 {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{-DURATION['P10D']}", + f"zsk {DURATION['P60D']} {alg} {size} goal:hidden dnskey:unretentive zrrsig:unretentive offset:{-DURATION['P10D']}", + ], + # Next key event is when the DNSKEY becomes HIDDEN. + # This happens after the propagation delay, plus DNSKEY TTL. + "nextev": UNSIGNING_CONFIG["dnskey-ttl"] + + DEFAULT_CONFIG["zone-propagation-delay"], + # Zone is no longer signed. + "zone-signed": False, + "check-keytimes": False, + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/kasp.conf.j2 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,60 @@ +/* + * 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. + */ + +dnssec-policy "ksk-doubleksk-autosign" { + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 2h; + publish-safety P1D; + retire-safety P2D; + purge-keys PT1H; + + cdnskey no; + keys { + ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; + + parent-ds-ttl 3600; + parent-propagation-delay PT1H; +}; + +dnssec-policy "ksk-doubleksk-manual" { + manual-mode yes; + + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 2h; + publish-safety P1D; + retire-safety P2D; + purge-keys PT1H; + + cdnskey no; + keys { + ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; + + parent-ds-ttl 3600; + parent-propagation-delay PT1H; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/named.conf.j2 2025-10-18 10:16:12.461730720 +0000 @@ -0,0 +1,23 @@ +/* + * 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. + */ + +include "kasp.conf"; +include "named.common.conf"; + +zone "three-is-a-crowd.kasp" { + type primary; + file "three-is-a-crowd.kasp.db"; + inline-signing yes; + /* Use same policy as KSK rollover test zones. */ + dnssec-policy "ksk-doubleksk-autosign"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/ns3/template.db.in 2025-10-18 10:16:12.464730767 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/setup.sh bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/setup.sh 2025-10-18 10:16:12.461730720 +0000 @@ -0,0 +1,82 @@ +#!/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 + +cd "ns3" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Set in the key state files the Predecessor/Successor fields. +# Key $1 is the predecessor of key $2. +key_successor() { + id1=$(keyfile_to_key_id "$1") + id2=$(keyfile_to_key_id "$2") + echo "Predecessor: ${id1}" >>"${2}.state" + echo "Successor: ${id2}" >>"${1}.state" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# Test #2375, the "three is a crowd" bug, where a new key is introduced but the +# previous rollover has not finished yet. In other words, we have a key KEY2 +# that is the successor of key KEY1, and we introduce a new key KEY3 that is +# the successor of key KEY2: +# +# KEY1 < KEY2 < KEY3. +# +# The expected behavior is that all three keys remain in the zone, and not +# the bug behavior where KEY2 is removed and immediately replaced with KEY3. +# +# Set up a zone that has a KSK (KEY1) and have the successor key (KEY2) +# published as well. +setup three-is-a-crowd.kasp +# These times are the same as step3.ksk-doubleksk.autosign. +TpubN="now-60d" +TactN="now-1413h" +TretN="now" +TremN="now+50h" +TpubN1="now-27h" +TsbmN1="now" +TactN1="${TretN}" +TretN1="now+60d" +TremN1="now+1490h" +ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" +newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TsbmN1} -I ${TretN1} -D ${TremN1}" +zsktimes="-P ${TpubN} -A ${TpubN}" +KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) +KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) +$SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1 +$SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 +# Set key rollover relationship. +key_successor $KSK1 $KSK2 +# Sign zone. +cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" +cp $infile $zonefile +$SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py --- bind9-9.20.11/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-3crowd/tests_rollover_three_is_a_crowd.py 2025-10-18 10:16:12.461730720 +0000 @@ -0,0 +1,95 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +from datetime import timedelta + +import isctest +from isctest.kasp import KeyTimingMetadata +from rollover.common import ( + pytestmark, + alg, + size, + KSK_CONFIG, + KSK_LIFETIME_POLICY, + KSK_IPUB, + KSK_IRET, +) + + +CDSS = ["CDS (SHA-256)"] +POLICY = "ksk-doubleksk-autosign" +OFFSET1 = -int(timedelta(days=60).total_seconds()) +OFFSET2 = -int(timedelta(hours=27).total_seconds()) +TTL = int(KSK_CONFIG["dnskey-ttl"].total_seconds()) + + +def test_rollover_ksk_three_is_a_crowd(alg, size, ns3): + """Test #2375: Scheduled rollovers are happening faster than they can finish.""" + zone = "three-is-a-crowd.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{OFFSET1}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{OFFSET2}", + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSET1}", + ], + "keyrelationships": [0, 1], + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, POLICY, step) + + # Rollover successor KSK (with DS in rumoured state). + expected = isctest.kasp.policy_to_properties(TTL, step["keyprops"]) + keys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier) + isctest.kasp.check_keys(zone, keys, expected) + key = expected[1].key + now = KeyTimingMetadata.now() + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -rollover -key {key.tag} -when {now} {zone}") + watcher.wait_for_line(f"keymgr: {zone} done") + + # We now expect four keys (3x KSK, 1x ZSK). + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{OFFSET1}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{OFFSET2}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:0", + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSET1}", + ], + "check-keytimes": False, # checked manually with modified values + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, POLICY, step) + + expected = isctest.kasp.policy_to_properties(TTL, step["keyprops"]) + keys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier) + isctest.kasp.check_keys(zone, keys, expected) + + expected[0].metadata["Successor"] = expected[1].key.tag + expected[1].metadata["Predecessor"] = expected[0].key.tag + # Three is a crowd scenario. + expected[1].metadata["Successor"] = expected[2].key.tag + expected[2].metadata["Predecessor"] = expected[1].key.tag + isctest.kasp.check_keyrelationships(keys, expected) + for kp in expected: + kp.set_expected_keytimes(KSK_CONFIG) + + # The first successor KSK is already being retired. + expected[1].timing["Retired"] = now + KSK_IPUB + expected[1].timing["Removed"] = now + KSK_IPUB + KSK_IRET + + isctest.kasp.check_keytimes(keys, expected) diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/kasp.conf.j2 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,60 @@ +/* + * 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. + */ + +dnssec-policy "ksk-doubleksk-autosign" { + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 2h; + publish-safety P1D; + retire-safety P2D; + purge-keys PT1H; + + cdnskey no; + keys { + ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; + + parent-ds-ttl 3600; + parent-propagation-delay PT1H; +}; + +dnssec-policy "ksk-doubleksk-manual" { + manual-mode yes; + + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 2h; + publish-safety P1D; + retire-safety P2D; + purge-keys PT1H; + + cdnskey no; + keys { + ksk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; + + parent-ds-ttl 3600; + parent-propagation-delay PT1H; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/named.conf.j2 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,50 @@ +/* + * 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 zones = ["autosign", "manual"] %} + +include "kasp.conf"; +include "named.common.conf"; + +{% for tld in zones %} +zone "step1.ksk-doubleksk.@tld@" { + type primary; + file "step1.ksk-doubleksk.@tld@.db"; + dnssec-policy "ksk-doubleksk-@tld@"; +}; +zone "step2.ksk-doubleksk.@tld@" { + type primary; + file "step2.ksk-doubleksk.@tld@.db"; + dnssec-policy "ksk-doubleksk-@tld@"; +}; +zone "step3.ksk-doubleksk.@tld@" { + type primary; + file "step3.ksk-doubleksk.@tld@.db"; + dnssec-policy "ksk-doubleksk-@tld@"; +}; +zone "step4.ksk-doubleksk.@tld@" { + type primary; + file "step4.ksk-doubleksk.@tld@.db"; + dnssec-policy "ksk-doubleksk-@tld@"; +}; +zone "step5.ksk-doubleksk.@tld@" { + type primary; + file "step5.ksk-doubleksk.@tld@.db"; + dnssec-policy "ksk-doubleksk-@tld@"; +}; +zone "step6.ksk-doubleksk.@tld@" { + type primary; + file "step6.ksk-doubleksk.@tld@.db"; + dnssec-policy "ksk-doubleksk-@tld@"; +}; +{% endfor %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/ns3/template.db.in 2025-10-18 10:16:12.464730767 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/setup.sh bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/setup.sh 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,243 @@ +#!/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 + +cd "ns3" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Set in the key state files the Predecessor/Successor fields. +# Key $1 is the predecessor of key $2. +key_successor() { + id1=$(keyfile_to_key_id "$1") + id2=$(keyfile_to_key_id "$2") + echo "Predecessor: ${id1}" >>"${2}.state" + echo "Successor: ${id2}" >>"${1}.state" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# +# The zones at ksk-doubleksk.$tld represent the various steps of a KSK +# Double-KSK rollover. +# + +for tld in autosign manual; do + # Step 1: + # Introduce the first key. This will immediately be active. + setup step1.ksk-doubleksk.$tld + TactN="now-7d" + keytimes="-P ${TactN} -A ${TactN}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 + cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" + cp $infile $zonefile + $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 2: + # It is time to submit the introduce the new KSK. + setup step2.ksk-doubleksk.$tld + # Lksk: 60d + # Dreg: n/a + # DprpC: 1h + # TTLds: 1d + # TTLkey: 2h + # publish-safety: 1d + # retire-safety: 2d + # + # According to RFC 7583: + # Tpub(N+1) <= Tact(N) + Lksk - Dreg - IpubC + # IpubC = DprpC + TTLkey (+publish-safety) + # + # IpubC = 27h + # Tact(N) = now - Lksk + Dreg + IpubC = now - 60d + 27h + # = now - 1440h + 27h = now - 1413h + TactN="now-1413h" + keytimes="-P ${TactN} -A ${TactN}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $keytimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 + cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 3: + # It is time to submit the DS. + setup step3.ksk-doubleksk.$tld + # According to RFC 7583: + # Iret = DprpP + TTLds (+retire-safety) + # + # Iret = 50h + # Tpub(N) = now - Lksk = now - 60d = now - 60d + # Tact(N) = now - 1413h + # Tret(N) = now + # Trem(N) = now + Iret = now + 50h + # Tpub(N+1) = now - IpubC = now - 27h + # Tact(N+1) = now + # Tret(N+1) = now + Lksk = now + 60d + # Trem(N+1) = now + Lksk + Iret = now + 60d + 50h + # = now + 1440h + 50h = 1490h + TpubN="now-60d" + TactN="now-1413h" + TretN="now" + TremN="now+50h" + TpubN1="now-27h" + TactN1="now" + TretN1="now+60d" + TremN1="now+1490h" + ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" + zsktimes="-P ${TpubN} -A ${TpubN}" + KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $H -k $O $TpubN -r $O $TpubN -d $O $TactN "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $R $TpubN1 -r $R $TpubN1 -d $H $TpubN1 "$KSK2" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TpubN -z $O $TpubN "$ZSK" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $KSK1 $KSK2 + # Sign zone. + cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 4: + # The DS should be swapped now. + setup step4.ksk-doubleksk.$tld + # Tpub(N) = now - Lksk - Iret = now - 60d - 50h + # = now - 1440h - 50h = now - 1490h + # Tact(N) = now - 1490h + 27h = now - 1463h + # Tret(N) = now - Iret = now - 50h + # Trem(N) = now + # Tpub(N+1) = now - Iret - IpubC = now - 50h - 27h + # = now - 77h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + Lksk - Iret = now + 60d - 50h = now + 1390h + # Trem(N+1) = now + Lksk = now + 60d + TpubN="now-1490h" + TactN="now-1463h" + TretN="now-50h" + TremN="now" + TpubN1="now-77h" + TactN1="${TretN}" + TretN1="now+1390h" + TremN1="now+60d" + ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" + zsktimes="-P ${TpubN} -A ${TpubN}" + KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $H -k $O $TactN -r $O $TactN -d $U $TretN -D ds $TretN "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $R $TactN1 -P ds $TactN1 "$KSK2" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $KSK1 $KSK2 + # Sign zone. + cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 5: + # The predecessor DNSKEY is removed long enough that is has become HIDDEN. + setup step5.ksk-doubleksk.$tld + # Subtract DNSKEY TTL + zone-propagation-delay from all the times (3h). + # Tpub(N) = now - 1490h - 3h = now - 1493h + # Tact(N) = now - 1463h - 3h = now - 1466h + # Tret(N) = now - 50h - 3h = now - 53h + # Trem(N) = now - 3h + # Tpub(N+1) = now - 77h - 3h = now - 80h + # Tact(N+1) = Tret(N) + # Tret(N+1) = now + 1390h - 3h = now + 1387h + # Trem(N+1) = now + 60d - 3h = now + 1441h + TpubN="now-1493h" + TactN="now-1466h" + TretN="now-53h" + TremN="now-3h" + TpubN1="now-80h" + TactN1="${TretN}" + TretN1="now+1387h" + TremN1="now+1441h" + ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" + zsktimes="-P ${TpubN} -A ${TpubN}" + KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $H -k $U $TretN -r $U $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $KSK1 $KSK2 + # Sign zone. + cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 6: + # The predecessor DNSKEY can be purged. + setup step6.ksk-doubleksk.$tld + # Subtract purge-keys interval from all the times (1h). + TpubN="now-1494h" + TactN="now-1467h" + TretN="now-54h" + TremN="now-4h" + TpubN1="now-81h" + TactN1="${TretN}" + TretN1="now+1386h" + TremN1="now+1440h" + ksktimes="-P ${TpubN} -A ${TpubN} -P sync ${TactN} -I ${TretN} -D ${TremN} -D sync ${TactN1}" + newtimes="-P ${TpubN1} -A ${TactN1} -P sync ${TactN1} -I ${TretN1} -D ${TremN1}" + zsktimes="-P ${TpubN} -A ${TpubN}" + KSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $ksktimes $zone 2>keygen.out.$zone.1) + KSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 -f KSK $newtimes $zone 2>keygen.out.$zone.2) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 7200 $zsktimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $H -k $H $TretN -r $H $TretN -d $H $TretN "$KSK1" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -r $O $TactN1 -d $O $TactN1 "$KSK2" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $KSK1 $KSK2 + # Sign zone. + cat template.db.in "${KSK1}.key" "${KSK2}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK2" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -G "cds:sha-256" -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py --- bind9-9.20.11/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-ksk-doubleksk/tests_rollover_ksk_doubleksk.py 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,348 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +from datetime import timedelta + +import pytest + +import isctest +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + KSK_CONFIG, + KSK_LIFETIME, + KSK_LIFETIME_POLICY, + KSK_IPUB, + KSK_IPUBC, + KSK_IRET, + KSK_KEYTTLPROP, + TIMEDELTA, +) + + +CDSS = ["CDS (SHA-256)"] +POLICY = "ksk-doubleksk" +OFFSETS = {} +OFFSETS["step1-p"] = -int(TIMEDELTA["P7D"].total_seconds()) +OFFSETS["step2-p"] = -int(KSK_LIFETIME.total_seconds() - KSK_IPUBC.total_seconds()) +OFFSETS["step2-s"] = 0 +OFFSETS["step3-p"] = -int(KSK_LIFETIME.total_seconds()) +OFFSETS["step3-s"] = -int(KSK_IPUBC.total_seconds()) +OFFSETS["step4-p"] = OFFSETS["step3-p"] - int(KSK_IRET.total_seconds()) +OFFSETS["step4-s"] = OFFSETS["step3-s"] - int(KSK_IRET.total_seconds()) +OFFSETS["step5-p"] = OFFSETS["step4-p"] - int(KSK_KEYTTLPROP.total_seconds()) +OFFSETS["step5-s"] = OFFSETS["step4-s"] - int(KSK_KEYTTLPROP.total_seconds()) +OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(KSK_CONFIG["purge-keys"].total_seconds()) +OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(KSK_CONFIG["purge-keys"].total_seconds()) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_ksk_doubleksk_step1(tld, alg, size, ns3): + zone = f"step1.ksk-doubleksk.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + # Note that the key was already generated during setup. + + step = { + # Introduce the first key. This will immediately be active. + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step1-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step1-p']}", + ], + # Next key event is when the successor KSK needs to be published. + # That is the KSK lifetime - prepublication time (minus time + # already passed). + "nextev": KSK_LIFETIME - KSK_IPUB - timedelta(days=7), + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_ksk_doubleksk_step2(tld, alg, size, ns3): + zone = f"step2.ksk-doubleksk.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 1. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step2-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block KSK rollover for key {zone}/ECDSAP256SHA256/{tag} (policy {policy})" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # Successor KSK is prepublished (and signs DNSKEY RRset). + # KSK1 goal: omnipresent -> hidden + # KSK2 goal: hidden -> omnipresent + # KSK2 dnskey: hidden -> rumoured + # KSK2 krrsig: hidden -> rumoured + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step2-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden offset:{OFFSETS['step2-s']}", + ], + "keyrelationships": [1, 2], + # Next key event is when the successor KSK becomes OMNIPRESENT. + "nextev": KSK_IPUB, + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_ksk_doubleksk_step3(tld, alg, size, ns3): + zone = f"step3.ksk-doubleksk.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 2, but DNSKEY has become OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step3-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step3-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [1, 2], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + # Check logs. + tag = keys[2].key.tag + msg = f"keymgr-manual-mode: block transition KSK {zone}/ECDSAP256SHA256/{tag} type DS state HIDDEN to state RUMOURED" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block transition KSK {zone}/ECDSAP256SHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE" + if msg in ns3.log: + # Force step. + isctest.log.debug( + f"keymgr-manual-mode blocking transition KSK {zone}/ECDSAP256SHA256/{tag} type DS state OMNIPRESENT to state UNRETENTIVE, step again" + ) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # The successor DNSKEY RRset has become omnipresent. The + # predecessor DS can be withdrawn and the successor DS can be + # introduced. + # KSK1 ds: omnipresent -> unretentive + # KSK2 dnskey: rumoured -> omnipresent + # KSK2 krrsig: rumoured -> omnipresent + # KSK2 ds: hidden -> rumoured + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step3-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:unretentive offset:{OFFSETS['step3-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:rumoured offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [1, 2], + # Next key event is when the predecessor DS has been replaced with + # the successor DS and enough time has passed such that the all + # validators that have this DS RRset cached only know about the + # successor DS. This is the the retire interval. + "nextev": KSK_IRET, + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_ksk_doubleksk_step4(tld, alg, size, ns3): + zone = f"step4.ksk-doubleksk.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 3, but DS has become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step4-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:hidden offset:{OFFSETS['step4-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [1, 2], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + # Check logs. + tag = keys[1].key.tag + msg1 = f"keymgr-manual-mode: block transition KSK {zone}/ECDSAP256SHA256/{tag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" + msg2 = f"keymgr-manual-mode: block transition KSK {zone}/ECDSAP256SHA256/{tag} type KRRSIG state OMNIPRESENT to state UNRETENTIVE" + ns3.log.expect(msg1) + ns3.log.expect(msg2) + + # Force step. + tag = keys[2].key.tag + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # The predecessor DNSKEY may be removed, the successor DS is + # omnipresent. + # KSK1 dnskey: omnipresent -> unretentive + # KSK1 krrsig: omnipresent -> unretentive + # KSK1 ds: unretentive -> hidden + # KSK2 ds: rumoured -> omnipresent + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step4-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:unretentive krrsig:unretentive ds:hidden offset:{OFFSETS['step4-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [1, 2], + # Next key event is when the DNSKEY enters the HIDDEN state. + # This is the DNSKEY TTL plus zone propagation delay. + "nextev": KSK_KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_ksk_doubleksk_step5(tld, alg, size, ns3): + zone = f"step5.ksk-doubleksk.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + # The predecessor DNSKEY is long enough removed from the zone it + # has become hidden. + # KSK1 dnskey: unretentive -> hidden + # KSK1 krrsig: unretentive -> hidden + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step5-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:hidden krrsig:hidden ds:hidden offset:{OFFSETS['step5-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step5-s']}", + ], + "keyrelationships": [1, 2], + # Next key event is when the new successor needs to be published. + # This is the KSK lifetime minus Ipub minus Iret minus time elapsed. + "nextev": KSK_LIFETIME - KSK_IPUB - KSK_IRET - KSK_KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_ksk_doubleksk_step6(tld, alg, size, ns3): + zone = f"step6.ksk-doubleksk.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + # Predecessor KSK is now purged. + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step6-p']}", + f"ksk {KSK_LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6-s']}", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns3, KSK_CONFIG, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/kasp.conf.j2 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,29 @@ +/* + * 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. + */ + +dnssec-policy "unlimited-lifetime" { + keys { + csk lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + }; +}; +dnssec-policy "short-lifetime" { + keys { + csk lifetime P6M algorithm @DEFAULT_ALGORITHM@; + }; +}; + +dnssec-policy "long-lifetime" { + keys { + csk lifetime P1Y algorithm @DEFAULT_ALGORITHM@; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db --- bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/limit-lifetime.db 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db --- bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/longer-lifetime.db 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/named.common.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,35 @@ +/* + * 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 { + query-source address 10.53.0.6; + notify-source 10.53.0.6; + transfer-source 10.53.0.6; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.6; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/named.conf.j2 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,45 @@ +/* + * 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 change_lifetime = change_lifetime | default(False) %} +{% set longer = "short-lifetime" if not change_lifetime else "long-lifetime" %} +{% set shorter = "long-lifetime" if not change_lifetime else "short-lifetime" %} +{% set limit = "unlimited-lifetime" if not change_lifetime else "short-lifetime" %} +{% set unlimit = "short-lifetime" if not change_lifetime else "unlimited-lifetime" %} + +include "kasp.conf"; +include "named.common.conf"; + +zone longer-lifetime { + type primary; + file "longer-lifetime.db"; + dnssec-policy @longer@; +}; + +zone shorter-lifetime { + type primary; + file "shorter-lifetime.db"; + dnssec-policy @shorter@; +}; + +zone limit-lifetime { + type primary; + file "limit-lifetime.db"; + dnssec-policy @limit@; +}; + +zone unlimit-lifetime { + type primary; + file "unlimit-lifetime.db"; + dnssec-policy @unlimit@; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db --- bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/shorter-lifetime.db 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db --- bind9-9.20.11/bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/ns6/unlimit-lifetime.db 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py bind9-9.20.15/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py --- bind9-9.20.11/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_initial.py 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,50 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + DEFAULT_CONFIG, + DURATION, +) + + +@pytest.mark.parametrize( + "zone, policy, lifetime", + [ + param("shorter-lifetime", "long-lifetime", "P1Y"), + param("longer-lifetime", "short-lifetime", "P6M"), + param("limit-lifetime", "unlimited-lifetime", 0), + param("unlimit-lifetime", "short-lifetime", "P6M"), + ], +) +def test_lifetime_initial(zone, policy, lifetime, alg, size, ns6): + config = DEFAULT_CONFIG + + isctest.kasp.wait_keymgr_done(ns6, zone) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {DURATION[lifetime]} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py bind9-9.20.15/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py --- bind9-9.20.11/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-lifetime/tests_rollover_lifetime_reconfig.py 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,65 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + DEFAULT_CONFIG, + DURATION, +) + + +@pytest.fixture(scope="module", autouse=True) +def reconfigure_policy(ns6, templates): + isctest.kasp.wait_keymgr_done(ns6, "shorter-lifetime") + isctest.kasp.wait_keymgr_done(ns6, "longer-lifetime") + isctest.kasp.wait_keymgr_done(ns6, "limit-lifetime") + isctest.kasp.wait_keymgr_done(ns6, "unlimit-lifetime") + + templates.render("ns6/named.conf", {"change_lifetime": True}) + ns6.reconfigure() + + +@pytest.mark.parametrize( + "zone, policy, lifetime", + [ + param("shorter-lifetime", "short-lifetime", "P6M"), + param("longer-lifetime", "long-lifetime", "P1Y"), + param( + "limit-lifetime", + "short-lifetime", + "P6M", + ), + param("unlimit-lifetime", "unlimited-lifetime", 0), + ], +) +def test_lifetime_reconfig(zone, policy, lifetime, alg, size, ns6): + config = DEFAULT_CONFIG + + isctest.kasp.wait_keymgr_done(ns6, zone, reconfig=True) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk {DURATION[lifetime]} {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured zrrsig:rumoured ds:hidden", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/kasp.conf.j2 2025-10-18 10:16:12.462730736 +0000 @@ -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. + */ + +dnssec-policy "multisigner-model2" { + dnskey-ttl 3600; + inline-signing no; + + keys { + ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535; + zsk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@ tag-range 32768 65535; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/named.conf.j2 2025-10-18 10:16:12.462730736 +0000 @@ -0,0 +1,34 @@ +/* + * 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. + */ + +include "kasp.conf"; +include "named.common.conf"; + +/* RFC 8901 Multi-signer Model 2. */ +zone "multisigner-model2.kasp" { + type primary; + file "multisigner-model2.kasp.db"; + dnssec-policy "multisigner-model2"; + allow-update { any; }; +}; + +/* + * A zone that starts with keys that have tags that are + * outside of the desired multi-signer key tag range. + */ +zone "single-to-multisigner.kasp" { + type primary; + file "single-to-multisigner.kasp.db"; + dnssec-policy "multisigner-model2"; + allow-update { any; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/template.db.in bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-multisigner/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-multisigner/ns3/template.db.in 2025-10-18 10:16:12.464730767 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-multisigner/setup.sh bind9-9.20.15/bin/tests/system/rollover-multisigner/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-multisigner/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-multisigner/setup.sh 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,67 @@ +#!/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 + +cd "ns3" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Set in the key state files the Predecessor/Successor fields. +# Key $1 is the predecessor of key $2. +key_successor() { + id1=$(keyfile_to_key_id "$1") + id2=$(keyfile_to_key_id "$2") + echo "Predecessor: ${id1}" >>"${2}.state" + echo "Successor: ${id2}" >>"${1}.state" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# Multi-signer zones. +setup "multisigner-model2.kasp" +cp template.db.in "$zonefile" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -f KSK -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -M 32768:65535 $zone 2>keygen.out.$zone.2) +cat "${KSK}.key" | grep -v ";.*" >>"${zone}.db" +cat "${ZSK}.key" | grep -v ";.*" >>"${zone}.db" +# Import a ZSK of another provider into the DNSKEY RRset. +ZSK1=$($KEYGEN -K ../ -a $DEFAULT_ALGORITHM -L 3600 -M 0:32767 $zone 2>keygen.out.$zone.3) +cat "../${ZSK1}.key" | grep -v ";.*" >>"${zone}.db" + +# We are changing an existing single-signed zone to multi-signed +# zone where the key tags do not match the dnssec-policy key tag range +setup single-to-multisigner.kasp +T="now-7d" +S="now-8635mi" # T - 1d5m +keytimes="-P $T -A $T" +cdstimes="-P sync $S" +KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 -f KSK $keytimes $cdstimes $zone 2>keygen.out.$zone.1) +ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -M 0:32767 -L 3600 $keytimes $zone 2>keygen.out.$zone.2) +$SETTIME -s -g $O -d $O $T -k $O $T -r $O $T "$KSK" >settime.out.$zone.1 2>&1 +$SETTIME -s -g $O -k $O $T -z $O $T "$ZSK" >settime.out.$zone.2 2>&1 +cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" +$SIGNER -PS -z -x -s now-2w -e now-1mi -o $zone -f "${zonefile}" $infile >signer.out.$zone.1 2>&1 +echo "Lifetime: 0" >>"${KSK}".state +echo "Lifetime: 0" >>"${ZSK}".state diff -Nru bind9-9.20.11/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py bind9-9.20.15/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py --- bind9-9.20.11/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-multisigner/tests_rollover_multisigner.py 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,176 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +from datetime import timedelta +import os + +import pytest + +pytest.importorskip("dns", minversion="2.0.0") +import dns.update + +import isctest +from isctest.kasp import Iret +from rollover.common import ( + pytestmark, + alg, + size, +) + + +def test_rollover_multisigner(ns3, alg, size): + policy = "multisigner-model2" + config = { + "dnskey-ttl": timedelta(hours=1), + "ds-ttl": timedelta(days=1), + "max-zone-ttl": timedelta(days=1), + "parent-propagation-delay": timedelta(hours=1), + "publish-safety": timedelta(hours=1), + "retire-safety": timedelta(hours=1), + "signatures-refresh": timedelta(days=5), + "signatures-validity": timedelta(days=14), + "zone-propagation-delay": timedelta(minutes=5), + } + ttl = int(config["dnskey-ttl"].total_seconds()) + + offset = -timedelta(days=7) + offval = int(offset.total_seconds()) + + def keygen(zone): + keygen_command = [ + os.environ.get("KEYGEN"), + "-a", + alg, + "-L", + "3600", + "-M", + "0:32767", + zone, + ] + + return isctest.run.cmd(keygen_command).stdout.decode("utf-8") + + zone = "multisigner-model2.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + isctest.kasp.check_dnssec_verify(ns3, zone) + + key_properties = [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535", + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:rumoured tag-range:32768-65535", + ] + expected = isctest.kasp.policy_to_properties(ttl, key_properties) + + newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"] + expected2 = isctest.kasp.policy_to_properties(ttl, newprops) + expected2[0].properties["private"] = False + expected2[0].properties["legacy"] = True + expected = expected + expected2 + + ownkeys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier) + extkeys = isctest.kasp.keydir_to_keylist(zone) + keys = ownkeys + extkeys + ksks = [k for k in ownkeys if k.is_ksk()] + zsks = [k for k in ownkeys if not k.is_ksk()] + zsks = zsks + extkeys + + isctest.kasp.check_keys(zone, keys, expected) + for kp in expected: + kp.set_expected_keytimes(config) + isctest.kasp.check_keytimes(keys, expected) + isctest.kasp.check_dnssecstatus(ns3, zone, keys, policy=policy) + isctest.kasp.check_apex(ns3, zone, ksks, zsks) + isctest.kasp.check_subdomain(ns3, zone, ksks, zsks) + + # Update zone with ZSK from another provider for zone. + out = keygen(zone) + newkeys = isctest.kasp.keystr_to_keylist(out) + newprops = [f"zsk unlimited {alg} {size} tag-range:0-32767"] + expected2 = isctest.kasp.policy_to_properties(ttl, newprops) + expected2[0].properties["private"] = False + expected2[0].properties["legacy"] = True + expected = expected + expected2 + + dnskey = newkeys[0].dnskey().split() + rdata = " ".join(dnskey[4:]) + + update_msg = dns.update.UpdateMessage(zone) + update_msg.add(f"{dnskey[0]}", 3600, "DNSKEY", rdata) + ns3.nsupdate(update_msg) + + isctest.kasp.check_dnssec_verify(ns3, zone) + + keys = keys + newkeys + zsks = zsks + newkeys + isctest.kasp.check_keys(zone, keys, expected) + isctest.kasp.check_apex(ns3, zone, ksks, zsks) + isctest.kasp.check_subdomain(ns3, zone, ksks, zsks) + + # Remove ZSKs from the other providers for zone. + dnskey2 = extkeys[0].dnskey().split() + rdata2 = " ".join(dnskey2[4:]) + update_msg = dns.update.UpdateMessage(zone) + update_msg.delete(f"{dnskey[0]}", "DNSKEY", rdata) + update_msg.delete(f"{dnskey2[0]}", "DNSKEY", rdata2) + ns3.nsupdate(update_msg) + + isctest.kasp.check_dnssec_verify(ns3, zone) + + expected = isctest.kasp.policy_to_properties(ttl, key_properties) + keys = ownkeys + ksks = [k for k in ownkeys if k.is_ksk()] + zsks = [k for k in ownkeys if not k.is_ksk()] + isctest.kasp.check_keys(zone, keys, expected) + isctest.kasp.check_apex(ns3, zone, ksks, zsks) + isctest.kasp.check_subdomain(ns3, zone, ksks, zsks) + + # A zone transitioning from single-signed to multi-signed. We should have + # the old omnipresent keys outside of the desired key range and the new + # keys in the desired key range. + zone = "single-to-multisigner.kasp" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + isctest.kasp.check_dnssec_verify(ns3, zone) + + key_properties = [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:rumoured krrsig:rumoured ds:hidden tag-range:32768-65535", + f"zsk unlimited {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden tag-range:32768-65535", + f"ksk unlimited {alg} {size} goal:hidden dnskey:omnipresent krrsig:omnipresent ds:omnipresent tag-range:0-32767 offset:{offval}", + f"zsk unlimited {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent tag-range:0-32767 offset:{offval}", + ] + expected = isctest.kasp.policy_to_properties(ttl, key_properties) + keys = isctest.kasp.keydir_to_keylist(zone, ns3.identifier) + ksks = [k for k in keys if k.is_ksk()] + zsks = [k for k in keys if not k.is_ksk()] + + isctest.kasp.check_keys(zone, keys, expected) + + for kp in expected: + kp.set_expected_keytimes(config) + + start = expected[0].key.get_timing("Created") + expected[2].timing["Retired"] = start + expected[2].timing["Removed"] = expected[2].timing["Retired"] + Iret( + config, zsk=False, ksk=True + ) + expected[3].timing["Retired"] = start + expected[3].timing["Removed"] = expected[3].timing["Retired"] + Iret( + config, zsk=True, ksk=False + ) + + isctest.kasp.check_keytimes(keys, expected) + isctest.kasp.check_dnssecstatus(ns3, zone, keys, policy=policy) + isctest.kasp.check_apex(ns3, zone, ksks, zsks) + isctest.kasp.check_subdomain(ns3, zone, ksks, zsks) diff -Nru bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/kasp.conf.j2 2025-10-18 10:16:12.461730720 +0000 @@ -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. + */ + +dnssec-policy "unsigning" { + dnskey-ttl 7200; + + keys { + ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime P60D algorithm @DEFAULT_ALGORITHM@; + }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/named.common.conf.j2 2025-10-18 10:16:12.460730705 +0000 @@ -0,0 +1,35 @@ +/* + * 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 { + query-source address 10.53.0.6; + notify-source 10.53.0.6; + transfer-source 10.53.0.6; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.6; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + key-directory "."; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.6 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/named.conf.j2 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,31 @@ +/* + * 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 policy = policy | default("default") %} + +include "kasp.conf"; +include "named.common.conf"; + +zone "going-straight-to-none.kasp" { + type primary; + file "going-straight-to-none.kasp.db"; + dnssec-policy @policy@; +}; + +zone "going-straight-to-none-dynamic.kasp" { + type primary; + file "going-straight-to-none-dynamic.kasp.db.signed"; + inline-signing no; + dnssec-policy @policy@; + allow-update { any; }; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/template.db.in bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-straight2none/ns6/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-straight2none/ns6/template.db.in 2025-10-18 10:16:12.460730705 +0000 @@ -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 ns6 +ns6 A 10.53.0.6 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-straight2none/setup.sh bind9-9.20.15/bin/tests/system/rollover-straight2none/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-straight2none/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-straight2none/setup.sh 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,53 @@ +#!/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 + +cd "ns6" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# These zones are going straight to "none" policy. This is undefined behavior. +T="now-10d" +S="now-12955mi" +csktimes="-P $T -A $T -P sync $S" + +setup going-straight-to-none.kasp +echo "$zone" >>zones +CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" +cp $infile $zonefile +$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + +setup going-straight-to-none-dynamic.kasp +echo "$zone" >>zones +CSK=$($KEYGEN -k default $csktimes $zone 2>keygen.out.$zone.1) +$SETTIME -s -g $O -k $O $TactN -z $O $TactN -r $O $TactN -d $O $TactN "$CSK" >settime.out.$zone.1 2>&1 +cat template.db.in "${CSK}.key" >"$infile" +private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$CSK" >>"$infile" +cp $infile $zonefile +$SIGNER -S -z -x -s now-1h -e now+2w -o $zone -O full -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 diff -Nru bind9-9.20.11/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py bind9-9.20.15/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py --- bind9-9.20.11/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_initial.py 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,48 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + DURATION, + DEFAULT_CONFIG, +) + + +@pytest.mark.parametrize( + "zone", + [ + "going-straight-to-none.kasp", + "going-straight-to-none-dynamic.kasp", + ], +) +def test_straight2none_initial(zone, ns6, alg, size): + config = DEFAULT_CONFIG + policy = "default" + + isctest.kasp.wait_keymgr_done(ns6, zone) + + step = { + "zone": zone, + "cdss": CDSS, + "keyprops": [ + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{-DURATION['P10D']}", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py bind9-9.20.15/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py --- bind9-9.20.11/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-straight2none/tests_rollver_straight2none_reconfig.py 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,57 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +import pytest + +import isctest +from rollover.common import ( + pytestmark, + alg, + size, + CDSS, + DURATION, + DEFAULT_CONFIG, +) + + +@pytest.fixture(scope="module", autouse=True) +def reconfigure_policy(ns6, templates): + isctest.kasp.wait_keymgr_done(ns6, "going-straight-to-none.kasp") + isctest.kasp.wait_keymgr_done(ns6, "going-straight-to-none-dynamic.kasp") + + templates.render("ns6/named.conf", {"policy": "none"}) + ns6.reconfigure() + + +@pytest.mark.parametrize( + "zone", + [ + "going-straight-to-none.kasp", + "going-straight-to-none-dynamic.kasp", + ], +) +def test_straight2none_reconfig(zone, ns6, alg, size): + config = DEFAULT_CONFIG + policy = None + + step = { + "zone": zone, + "cdss": CDSS, + # These zones will go bogus after signatures expire, but + # remain validly signed for now. + "keyprops": [ + f"csk 0 {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent zrrsig:omnipresent ds:omnipresent offset:{-DURATION['P10D']}", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns6, config, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/kasp.conf.j2 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,52 @@ +/* + * 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. + */ + +dnssec-policy "zsk-prepub-autosign" { + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 3600; + publish-safety P1D; + retire-safety P2D; + purge-keys PT1H; + + keys { + ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime P30D algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; +}; + +dnssec-policy "zsk-prepub-manual" { + manual-mode yes; + + signatures-refresh P1W; + signatures-validity P2W; + signatures-validity-dnskey P2W; + + dnskey-ttl 3600; + publish-safety P1D; + retire-safety P2D; + purge-keys PT1H; + + keys { + ksk key-directory lifetime unlimited algorithm @DEFAULT_ALGORITHM@; + zsk key-directory lifetime P30D algorithm @DEFAULT_ALGORITHM@; + }; + + zone-propagation-delay PT1H; + max-zone-ttl 1d; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/named.common.conf.j2 bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/named.common.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/named.common.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/named.common.conf.j2 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,39 @@ +/* + * 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 { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + allow-transfer { any; }; + recursion no; + dnssec-validation no; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint.blackhole"; +}; diff -Nru bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/named.conf.j2 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/named.conf.j2 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,50 @@ +/* + * 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 zones = ["autosign", "manual"] %} + +include "kasp.conf"; +include "named.common.conf"; + +{% for tld in zones %} +zone "step1.zsk-prepub.@tld@" { + type primary; + file "step1.zsk-prepub.@tld@.db"; + dnssec-policy "zsk-prepub-@tld@"; +}; +zone "step2.zsk-prepub.@tld@" { + type primary; + file "step2.zsk-prepub.@tld@.db"; + dnssec-policy "zsk-prepub-@tld@"; +}; +zone "step3.zsk-prepub.@tld@" { + type primary; + file "step3.zsk-prepub.@tld@.db"; + dnssec-policy "zsk-prepub-@tld@"; +}; +zone "step4.zsk-prepub.@tld@" { + type primary; + file "step4.zsk-prepub.@tld@.db"; + dnssec-policy "zsk-prepub-@tld@"; +}; +zone "step5.zsk-prepub.@tld@" { + type primary; + file "step5.zsk-prepub.@tld@.db"; + dnssec-policy "zsk-prepub-@tld@"; +}; +zone "step6.zsk-prepub.@tld@" { + type primary; + file "step6.zsk-prepub.@tld@.db"; + dnssec-policy "zsk-prepub-@tld@"; +}; +{% endfor %} diff -Nru bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/template.db.in bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/template.db.in --- bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/ns3/template.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/ns3/template.db.in 2025-10-18 10:16:12.464730767 +0000 @@ -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 ns3 +ns3 A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +c A 10.0.0.3 + diff -Nru bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/setup.sh bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/setup.sh --- bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/setup.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/setup.sh 2025-10-18 10:16:12.463730751 +0000 @@ -0,0 +1,218 @@ +#!/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 + +cd "ns3" + +setup() { + zone="$1" + echo_i "setting up zone: $zone" + zonefile="${zone}.db" + infile="${zone}.db.infile" + echo "$zone" >>zones +} + +# Set in the key state files the Predecessor/Successor fields. +# Key $1 is the predecessor of key $2. +key_successor() { + id1=$(keyfile_to_key_id "$1") + id2=$(keyfile_to_key_id "$2") + echo "Predecessor: ${id1}" >>"${2}.state" + echo "Successor: ${id2}" >>"${1}.state" +} + +# Make lines shorter by storing key states in environment variables. +H="HIDDEN" +R="RUMOURED" +O="OMNIPRESENT" +U="UNRETENTIVE" + +# +# The zones at zsk-prepub.$tld represent the various steps of a ZSK +# Pre-Publication rollover. +# + +for tld in autosign manual; do + # Step 1: + # Introduce the first key. This will immediately be active. + setup step1.zsk-prepub.$tld + TactN="now-7d" + keytimes="-P ${TactN} -A ${TactN}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 + cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 2: + # It is time to pre-publish the successor ZSK. + setup step2.zsk-prepub.$tld + # According to RFC 7583: + # Tact(N) = now + Ipub - Lzsk = now + 26h - 30d + # = now + 26h - 30d = now − 694h + TactN="now-694h" + keytimes="-P ${TactN} -A ${TactN}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $keytimes $zone 2>keygen.out.$zone.2) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $O -k $O $TactN -z $O $TactN "$ZSK" >settime.out.$zone.2 2>&1 + cat template.db.in "${KSK}.key" "${ZSK}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 3: + # After the publication interval has passed the DNSKEY of the successor ZSK + # is OMNIPRESENT and the zone can thus be signed with the successor ZSK. + setup step3.zsk-prepub.$tld + # According to RFC 7583: + # Tpub(N+1) <= Tact(N) + Lzsk - Ipub + # Tact(N+1) = Tact(N) + Lzsk + # + # Tact(N) = now - Lzsk = now - 30d + # Tpub(N+1) = now - Ipub = now - 26h + # Tact(N+1) = now + # Tret(N) = now + # Trem(N) = now + Iret = now + Dsign + Dprp + TTLsig + retire-safety = 8d1h = now + 241h + TactN="now-30d" + TpubN1="now-26h" + TactN1="now" + TremN="now+241h" + keytimes="-P ${TactN} -A ${TactN}" + oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" + newtimes="-P ${TpubN1} -A ${TactN1}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $O $TactN -z $O $TactN "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $R $TpubN1 -z $H $TpubN1 "$ZSK2" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $ZSK1 $ZSK2 + # Sign zone. + cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 4: + # After the retire interval has passed the predecessor DNSKEY can be + # removed from the zone. + setup step4.zsk-prepub.$tld + # Lzsk: 30d + # Ipub: 26h + # Dsgn: 1w + # Dprp: 1h + # TTLsig: 1d + # retire-safety: 2d + # + # According to RFC 7583: + # Iret = Dsgn + Dprp + TTLsig (+retire-safety) + # Iret = 1w + 1h + 1d + 2d = 10d1h = 241h + # + # Tact(N) = now - Iret - Lzsk + # = now - 241h - 30d = now - 241h - 720h + # = now - 961h + # Tpub(N+1) = now - Iret - Ipub + # = now - 241h - 26h + # = now - 267h + # Tact(N+1) = now - Iret = now - 241h + TactN="now-961h" + TpubN1="now-267h" + TactN1="now-241h" + TremN="now" + keytimes="-P ${TactN} -A ${TactN}" + oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" + newtimes="-P ${TpubN1} -A ${TactN1}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $O $TactN -z $U $TactN1 "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -z $R $TactN1 "$ZSK2" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $ZSK1 $ZSK2 + # Sign zone. + cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" + cp $infile $zonefile + $SIGNER -PS -x -s now-2w -e now-1mi -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 5: + # The predecessor DNSKEY is removed long enough that is has become HIDDEN. + setup step5.zsk-prepub.$tld + # Subtract DNSKEY TTL + zone-propagation-delay from all the times (2h). + # Tact(N) = now - 961h - 2h = now - 963h + # Tpub(N+1) = now - 267h - 2h = now - 269h + # Tact(N+1) = now - 241h - 2h = now - 243h + # Trem(N) = Tact(N+1) + Iret = now -2h + TactN="now-963h" + TremN="now-2h" + TpubN1="now-269h" + TactN1="now-243h" + TremN="now-2h" + keytimes="-P ${TactN} -A ${TactN}" + oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" + newtimes="-P ${TpubN1} -A ${TactN1}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $U $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $ZSK1 $ZSK2 + # Sign zone. + cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 + + # Step 6: + # The predecessor DNSKEY can be purged. + setup step6.zsk-prepub.$tld + # Subtract purge-keys interval from all the times (1h). + TactN="now-964h" + TremN="now-3h" + TpubN1="now-270h" + TactN1="now-244h" + TremN="now-3h" + keytimes="-P ${TactN} -A ${TactN}" + oldtimes="-P ${TactN} -A ${TactN} -I ${TactN1} -D ${TremN}" + newtimes="-P ${TpubN1} -A ${TactN1}" + KSK=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 -f KSK $keytimes $zone 2>keygen.out.$zone.1) + ZSK1=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $oldtimes $zone 2>keygen.out.$zone.2) + ZSK2=$($KEYGEN -a $DEFAULT_ALGORITHM -L 3600 $newtimes $zone 2>keygen.out.$zone.3) + $SETTIME -s -g $O -k $O $TactN -r $O $TactN -d $O $TactN "$KSK" >settime.out.$zone.1 2>&1 + $SETTIME -s -g $H -k $H $TremN -z $H $TremN "$ZSK1" >settime.out.$zone.2 2>&1 + $SETTIME -s -g $O -k $O $TactN1 -z $O $TremN "$ZSK2" >settime.out.$zone.3 2>&1 + # Set key rollover relationship. + key_successor $ZSK1 $ZSK2 + # Sign zone. + cat template.db.in "${KSK}.key" "${ZSK1}.key" "${ZSK2}.key" >"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$KSK" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK1" >>"$infile" + private_type_record $zone $DEFAULT_ALGORITHM_NUMBER "$ZSK2" >>"$infile" + cp $infile $zonefile + $SIGNER -S -x -s now-1h -e now+2w -o $zone -O raw -f "${zonefile}.signed" $infile >signer.out.$zone.1 2>&1 +done diff -Nru bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py --- bind9-9.20.11/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rollover-zsk-prepub/tests_rollover_zsk_prepublication.py 2025-10-18 10:16:12.464730767 +0000 @@ -0,0 +1,353 @@ +# 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. + +# pylint: disable=redefined-outer-name,unused-import + +from datetime import timedelta + +import pytest + +import isctest +from isctest.kasp import Ipub, Iret +from isctest.util import param +from rollover.common import ( + pytestmark, + alg, + size, + TIMEDELTA, +) + +CONFIG = { + "dnskey-ttl": TIMEDELTA["PT1H"], + "ds-ttl": TIMEDELTA["P1D"], + "max-zone-ttl": TIMEDELTA["P1D"], + "parent-propagation-delay": TIMEDELTA["PT1H"], + "publish-safety": TIMEDELTA["P1D"], + "purge-keys": TIMEDELTA["PT1H"], + "retire-safety": TIMEDELTA["P2D"], + "signatures-refresh": TIMEDELTA["P7D"], + "signatures-validity": TIMEDELTA["P14D"], + "zone-propagation-delay": TIMEDELTA["PT1H"], +} +POLICY = "zsk-prepub" +ZSK_LIFETIME = TIMEDELTA["P30D"] +LIFETIME_POLICY = int(ZSK_LIFETIME.total_seconds()) +IPUB = Ipub(CONFIG) +IRET = Iret(CONFIG) +KEYTTLPROP = CONFIG["dnskey-ttl"] + CONFIG["zone-propagation-delay"] +OFFSETS = {} +OFFSETS["step1-p"] = -int(TIMEDELTA["P7D"].total_seconds()) +OFFSETS["step2-p"] = -int(ZSK_LIFETIME.total_seconds() - IPUB.total_seconds()) +OFFSETS["step2-s"] = 0 +OFFSETS["step3-p"] = -int(ZSK_LIFETIME.total_seconds()) +OFFSETS["step3-s"] = -int(IPUB.total_seconds()) +OFFSETS["step4-p"] = OFFSETS["step3-p"] - int(IRET.total_seconds()) +OFFSETS["step4-s"] = OFFSETS["step3-s"] - int(IRET.total_seconds()) +OFFSETS["step5-p"] = OFFSETS["step4-p"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step5-s"] = OFFSETS["step4-s"] - int(KEYTTLPROP.total_seconds()) +OFFSETS["step6-p"] = OFFSETS["step5-p"] - int(CONFIG["purge-keys"].total_seconds()) +OFFSETS["step6-s"] = OFFSETS["step5-s"] - int(CONFIG["purge-keys"].total_seconds()) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_zsk_prepub_step1(tld, alg, size, ns3): + zone = f"step1.zsk-prepub.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + # Note that the key was already generated during setup. + + step = { + # Introduce the first key. This will immediately be active. + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step1-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step1-p']}", + ], + # Next key event is when the successor ZSK needs to be published. + # That is the ZSK lifetime - prepublication time (minus time + # already passed). + "nextev": ZSK_LIFETIME - IPUB - timedelta(days=7), + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_zsk_prepub_step2(tld, alg, size, ns3): + zone = f"step2.zsk-prepub.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 1. + step = { + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step2-p']}", + ], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block ZSK rollover for key {zone}/ECDSAP256SHA256/{tag} (policy {policy})" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # it is time to pre-publish the successor zsk. + # zsk1 goal: omnipresent -> hidden + # zsk2 goal: hidden -> omnipresent + # zsk2 dnskey: hidden -> rumoured + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step2-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step2-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:rumoured zrrsig:hidden offset:{OFFSETS['step2-s']}", + ], + "keyrelationships": [1, 2], + # next key event is when the successor zsk becomes omnipresent. + # that is the dnskey ttl plus the zone propagation delay + "nextev": IPUB, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_zsk_prepub_step3(tld, alg, size, ns3): + zone = f"step3.zsk-prepub.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 2, but DNSKEY has become OMNIPRESENT. + step = { + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step3-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step3-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:hidden offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [1, 2], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[2].key.tag + msg = f"keymgr-manual-mode: block transition ZSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state HIDDEN to state RUMOURED" + ns3.log.expect(msg) + + # Force step. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block transition ZSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE" + if msg in ns3.log: + # Force step. + isctest.log.debug( + f"keymgr-manual-mode blocking transition ZSK {zone}/ECDSAP256SHA256/{tag} type ZRRSIG state OMNIPRESENT to state UNRETENTIVE, step again" + ) + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # predecessor zsk is no longer actively signing. successor zsk is + # now actively signing. + # zsk1 zrrsig: omnipresent -> unretentive + # zsk2 dnskey: rumoured -> omnipresent + # zsk2 zrrsig: hidden -> rumoured + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step3-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:unretentive offset:{OFFSETS['step3-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:rumoured offset:{OFFSETS['step3-s']}", + ], + "keyrelationships": [1, 2], + # next key event is when all the rrsig records have been replaced + # with signatures of the new zsk, in other words when zrrsig + # becomes omnipresent. + "nextev": IRET, + # set 'smooth' to true so expected signatures of subdomain are + # from the predecessor zsk. + "smooth": True, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Force full resign and check all signatures have been replaced. + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"sign {zone}", log=False) + watcher.wait_for_line(f"zone {zone}/IN (signed): sending notifies") + + step["smooth"] = False + step["nextev"] = Iret(CONFIG, smooth=False) + isctest.kasp.check_rollover_step(ns3, CONFIG, POLICY, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_zsk_prepub_step4(tld, alg, size, ns3): + zone = f"step4.zsk-prepub.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + if tld == "manual": + # Same as step 3, but zone signatures have become HIDDEN/OMNIPRESENT. + step = { + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:omnipresent zrrsig:hidden offset:{OFFSETS['step4-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [1, 2], + "manual-mode": True, + "nextev": None, + } + keys = isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + # Check logs. + tag = keys[1].key.tag + msg = f"keymgr-manual-mode: block transition ZSK {zone}/ECDSAP256SHA256/{tag} type DNSKEY state OMNIPRESENT to state UNRETENTIVE" + ns3.log.expect(msg) + + # Force step. + tag = keys[2].key.tag + with ns3.watch_log_from_here() as watcher: + ns3.rndc(f"dnssec -step {zone}") + watcher.wait_for_line( + f"zone {zone}/IN (signed): zone_rekey done: key {tag}/ECDSAP256SHA256" + ) + + step = { + # predecessor zsk is no longer needed. all rrsets are signed with + # the successor zsk. + # zsk1 dnskey: omnipresent -> unretentive + # zsk1 zrrsig: unretentive -> hidden + # zsk2 zrrsig: rumoured -> omnipresent + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step4-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:unretentive zrrsig:hidden offset:{OFFSETS['step4-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step4-s']}", + ], + "keyrelationships": [1, 2], + # next key event is when the dnskey enters the hidden state. + # this is the dnskey ttl plus zone propagation delay. + "nextev": KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_zsk_prepub_step5(tld, alg, size, ns3): + zone = f"step5.zsk-prepub.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + # predecessor zsk is now removed. + # zsk1 dnskey: unretentive -> hidden + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step5-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:hidden dnskey:hidden zrrsig:hidden offset:{OFFSETS['step5-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step5-s']}", + ], + "keyrelationships": [1, 2], + # next key event is when the new successor needs to be published. + # this is the zsk lifetime minus IRET minus IPUB minus time + # elapsed. + "nextev": ZSK_LIFETIME - IRET - IPUB - KEYTTLPROP, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) + + +@pytest.mark.parametrize( + "tld", + [ + param("autosign"), + param("manual"), + ], +) +def test_zsk_prepub_step6(tld, alg, size, ns3): + zone = f"step6.zsk-prepub.{tld}" + policy = f"{POLICY}-{tld}" + + isctest.kasp.wait_keymgr_done(ns3, zone) + + # manual-mode: Nothing changing in the zone, no 'dnssec -step' required. + + step = { + # predecessor zsk is now purged. + "zone": zone, + "keyprops": [ + f"ksk unlimited {alg} {size} goal:omnipresent dnskey:omnipresent krrsig:omnipresent ds:omnipresent offset:{OFFSETS['step6-p']}", + f"zsk {LIFETIME_POLICY} {alg} {size} goal:omnipresent dnskey:omnipresent zrrsig:omnipresent offset:{OFFSETS['step6-s']}", + ], + "nextev": None, + } + isctest.kasp.check_rollover_step(ns3, CONFIG, policy, step) diff -Nru bind9-9.20.11/bin/tests/system/rpz/ns3/evil-cname.db.in bind9-9.20.15/bin/tests/system/rpz/ns3/evil-cname.db.in --- bind9-9.20.11/bin/tests/system/rpz/ns3/evil-cname.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/ns3/evil-cname.db.in 2025-10-18 10:16:12.467730813 +0000 @@ -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. + +; RPZ test +; This basic file is copied to several zone files before being used. +; Its contents are also changed with nsupdate + + +$TTL 300 +@ SOA evil-cname. hostmaster.ns.evil-cname. ( 1 3600 1200 604800 60 ) + NS ns.tld3. + +evil.tld2 CNAME a12.tld2. diff -Nru bind9-9.20.11/bin/tests/system/rpz/ns3/named.conf.in bind9-9.20.15/bin/tests/system/rpz/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/rpz/ns3/named.conf.in 2025-07-04 09:42:08.238325908 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/ns3/named.conf.in 2025-10-18 10:16:12.468730829 +0000 @@ -29,7 +29,7 @@ notify yes; minimal-responses no; recursion yes; - dnssec-validation yes; + dnssec-validation no; min-refresh-time 1; min-retry-time 1; @@ -51,6 +51,9 @@ zone "bl.tld2"; zone "manual-update-rpz" ede forged; zone "mixed-case-rpz"; + zone "evil-cname" policy cname a12.tld2. ede blocked; + zone "wild-cname" ede blocked; + zone "slow-rpz"; } add-soa yes min-ns-dots 0 @@ -58,6 +61,7 @@ min-update-interval 0 nsdname-enable yes nsip-enable yes + servfail-until-ready yes ; include "../dnsrps.conf"; @@ -65,7 +69,6 @@ notify-delay 0; }; -trust-anchors { }; logging { category rpz { default_debug; }; }; @@ -125,6 +128,12 @@ notify no; }; +zone "slow-rpz." { + type primary; + file "slow-rpz.db"; + notify no; +}; + zone "fast-expire." { type secondary; file "fast-expire.db"; @@ -152,6 +161,16 @@ server-addresses { 10.53.0.10; }; }; +zone "evil-cname" { + type primary; + file "evil-cname.db"; +}; + +zone "wild-cname" { + type primary; + file "wild-cname.db"; +}; + # A faulty dlz configuration to check if named with response policy zones # survives a certain class of failed configuration attempts (see GL #3880). # "dlz" is used because the dlz processing code is located in an ideal place in diff -Nru bind9-9.20.11/bin/tests/system/rpz/ns3/slow-rpz.db.in bind9-9.20.15/bin/tests/system/rpz/ns3/slow-rpz.db.in --- bind9-9.20.11/bin/tests/system/rpz/ns3/slow-rpz.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/ns3/slow-rpz.db.in 2025-10-18 10:16:12.468730829 +0000 @@ -0,0 +1,16 @@ +; 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 +@ SOA mixed-case-rpz. hostmaster.ns.mixed-case-rpz. ( 1 3600 1200 604800 60 ) + NS ns.tld3. + +$GENERATE 1-30 host$ CNAME . diff -Nru bind9-9.20.11/bin/tests/system/rpz/ns3/wild-cname.db.in bind9-9.20.15/bin/tests/system/rpz/ns3/wild-cname.db.in --- bind9-9.20.11/bin/tests/system/rpz/ns3/wild-cname.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/ns3/wild-cname.db.in 2025-10-18 10:16:12.468730829 +0000 @@ -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. + +; RPZ test +; This basic file is copied to several zone files before being used. +; Its contents are also changed with nsupdate + + +$TTL 300 +@ SOA wild-cname. hostmaster.ns.wild-cname. ( 1 3600 1200 604800 60 ) + NS ns.tld3. + +*.evil.tld2 CNAME *.wc.tld4. diff -Nru bind9-9.20.11/bin/tests/system/rpz/ns4/tld4.db bind9-9.20.15/bin/tests/system/rpz/ns4/tld4.db --- bind9-9.20.11/bin/tests/system/rpz/ns4/tld4.db 2025-07-04 09:42:08.239325932 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/ns4/tld4.db 2025-10-18 10:16:12.468730829 +0000 @@ -64,3 +64,5 @@ a3-9.sub9.tld2 A 59.59.59.59 a3-10.tld2 A 60.60.60.60 + +*.wc A 61.61.61.61 diff -Nru bind9-9.20.11/bin/tests/system/rpz/ns8/named.conf.in bind9-9.20.15/bin/tests/system/rpz/ns8/named.conf.in --- bind9-9.20.11/bin/tests/system/rpz/ns8/named.conf.in 2025-07-04 09:42:08.240325955 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/ns8/named.conf.in 2025-10-18 10:16:12.469730844 +0000 @@ -29,7 +29,7 @@ notify yes; minimal-responses no; recursion yes; - dnssec-validation yes; + dnssec-validation no; response-policy { zone "manual-update-rpz"; @@ -47,7 +47,6 @@ notify-delay 0; }; -trust-anchors { }; logging { category rpz { default_debug; }; }; diff -Nru bind9-9.20.11/bin/tests/system/rpz/ns9/named.conf.in bind9-9.20.15/bin/tests/system/rpz/ns9/named.conf.in --- bind9-9.20.11/bin/tests/system/rpz/ns9/named.conf.in 2025-07-04 09:42:08.240325955 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/ns9/named.conf.in 2025-10-18 10:16:12.469730844 +0000 @@ -29,7 +29,7 @@ notify yes; minimal-responses no; recursion yes; - dnssec-validation yes; + dnssec-validation no; dns64-server "example.localdomain."; dns64 64:ff9b::/96 { }; response-policy { @@ -41,7 +41,6 @@ notify-delay 0; }; -trust-anchors { }; logging { category rpz { default_debug; }; }; diff -Nru bind9-9.20.11/bin/tests/system/rpz/setup.sh bind9-9.20.15/bin/tests/system/rpz/setup.sh --- bind9-9.20.11/bin/tests/system/rpz/setup.sh 2025-07-04 09:42:08.240325955 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/setup.sh 2025-10-18 10:16:12.469730844 +0000 @@ -51,8 +51,14 @@ cp ns3/manual-update-rpz.db.in ns3/manual-update-rpz.db cp ns8/manual-update-rpz.db.in ns8/manual-update-rpz.db +cp ns3/evil-cname.db.in ns3/evil-cname.db +cp ns3/wild-cname.db.in ns3/wild-cname.db + cp ns3/mixed-case-rpz-1.db.in ns3/mixed-case-rpz.db +# a "big" zone (tested with '-T rpzslow' enabled to slow down loading) +cp ns3/slow-rpz.db.in ns3/slow-rpz.db + # a zone that expires quickly and then can't be refreshed cp ns5/fast-expire.db.in ns5/fast-expire.db cp ns5/expire.conf.in ns5/expire.conf diff -Nru bind9-9.20.11/bin/tests/system/rpz/test2 bind9-9.20.15/bin/tests/system/rpz/test2 --- bind9-9.20.11/bin/tests/system/rpz/test2 2025-07-04 09:42:08.240325955 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/test2 2025-10-18 10:16:12.470730860 +0000 @@ -51,7 +51,11 @@ ; prefer first conflicting IP zone for a5-3.tld2 ; 12 update add 32.3.5.168.192.rpz-ip.bl 300 A 127.0.0.1 +; non canonical form entry to trigger log message +update add 128.2.0.0.0.0.3.2.2001.rpz-ip.bl 300 CNAME . send + +; update add 32.3.5.168.192.rpz-ip.bl-2 300 A 127.0.0.2 send diff -Nru bind9-9.20.11/bin/tests/system/rpz/testlib/Makefile.in bind9-9.20.15/bin/tests/system/rpz/testlib/Makefile.in --- bind9-9.20.11/bin/tests/system/rpz/testlib/Makefile.in 2025-07-04 09:43:11.102808970 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/testlib/Makefile.in 2025-10-18 10:17:04.318499070 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -353,8 +355,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -491,15 +495,13 @@ $(am__aclocal_m4_deps): clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + -$(am__rm_f) $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libdummyrpz.la: $(libdummyrpz_la_OBJECTS) $(libdummyrpz_la_DEPENDENCIES) $(EXTRA_libdummyrpz_la_DEPENDENCIES) $(AM_V_CCLD)$(libdummyrpz_la_LINK) $(libdummyrpz_la_OBJECTS) $(libdummyrpz_la_LIBADD) $(LIBS) @@ -515,7 +517,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -665,23 +667,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/dummylib.Plo + -rm -f ./$(DEPDIR)/dummylib.Plo -rm -f ./$(DEPDIR)/test-data.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ @@ -732,7 +734,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/dummylib.Plo + -rm -f ./$(DEPDIR)/dummylib.Plo -rm -f ./$(DEPDIR)/test-data.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -783,3 +785,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/bin/tests/system/rpz/tests.sh bind9-9.20.15/bin/tests/system/rpz/tests.sh --- bind9-9.20.11/bin/tests/system/rpz/tests.sh 2025-07-04 09:42:08.242326002 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/tests.sh 2025-10-18 10:16:12.471730876 +0000 @@ -34,6 +34,8 @@ HAVE_CORE= +NS_PARAMS="-m record -c named.conf -d 99 -g" + status=0 t=0 @@ -569,6 +571,8 @@ ckstats $ns6 test1 ns6 0 start_group "IP rewrites" test2 +msg='rpz IP address "128.2.0.0.0.0.3.2.2001" is not the canonical "128.2.zz.3.2.2001"' +grep "$msg" ns3/named.run >/dev/null || setret "expected 'is not the canonical' message not logged" nodata a3-1.tld2 # 1 NODATA nochange a3-2.tld2 # 2 no policy record so no change nochange a4-1.tld2 # 3 obsolete PASSTHRU record style @@ -774,6 +778,16 @@ $DIG -p ${PORT} @$ns3 walled.tld2 >dig.out.$t || setret "failed" grep -F "EDE: 4 (Forged Answer)" dig.out.$t >/dev/null || setret "failed" + t=$((t + 1)) + echo_i "checking the configured extended DNS error code, CNAME override (EDE) (${t})" + $DIG -p ${PORT} @$ns3 evil.tld2 >dig.out.$t || setret "failed" + grep -F "EDE: 15 (Blocked)" dig.out.$t >/dev/null || setret "failed" + + t=$((t + 1)) + echo_i "checking the configured extended DNS error code, wildcard CNAME override (EDE) (${t})" + $DIG -p ${PORT} @$ns3 foo.evil.tld2 >dig.out.$t || setret "failed" + grep -F "EDE: 15 (Blocked)" dig.out.$t >/dev/null || setret "failed" + # reload a RPZ zone that is now deliberately broken. t=$((t + 1)) echo_i "checking rpz failed update will keep previous rpz rules (${t})" @@ -921,6 +935,27 @@ $RNDCCMD $ns6 flush $DIG a7-2.tld2s -p ${PORT} @$ns6 +cd >dig.out.${t} || setret "failed" grep -w "1.1.1.1" dig.out.${t} >/dev/null || setret "failed" + + t=$((t + 1)) + echo_i "checking that 'servfail-until-ready yes' works (part 1) (${t})" + # Restart ns3 with '-T rpzslow' + stop_server ns3 + nextpart ns3/named.run >/dev/null + start_server --noclean --restart --port ${PORT} ns3 -- "-D rpz-ns3 $NS_PARAMS -T rpzslow" + wait_for_log 10 "all zones loaded" ns3/named.run + # Just any query that is expected to success normally, but should return + # SERVFAIL because RPZ is still processing. + $DIG tld2. NS -p ${PORT} @$ns3 >dig.out.${t} || setret "failed" + grep "status: SERVFAIL" dig.out.${t} >/dev/null || setret "failed" + + t=$((t + 1)) + echo_i "checking that 'servfail-until-ready yes' works (part 2) (${t})" + # The 'slow-rpz.' zone has 30 records (RPZ rules), and '-T rpzslow' forces a + # 100ms delay for each rule. Wait enough time for processing to finish. + wait_for_log 10 "slow-rpz: reload done" ns3/named.run + # Now the same request as in the previous test should return NOERROR + $DIG tld2. NS -p ${PORT} @$ns3 >dig.out.${t} || setret "failed" + grep "status: NOERROR" dig.out.${t} >/dev/null || setret "failed" fi [ $status -eq 0 ] || exit 1 diff -Nru bind9-9.20.11/bin/tests/system/rpz/tests_sh_rpz.py bind9-9.20.15/bin/tests/system/rpz/tests_sh_rpz.py --- bind9-9.20.11/bin/tests/system/rpz/tests_sh_rpz.py 2025-07-04 09:42:08.242326002 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/tests_sh_rpz.py 2025-10-18 10:16:12.471730876 +0000 @@ -36,11 +36,14 @@ "ns3/bl-wildcname.db", "ns3/bl.db", "ns3/bl.tld2.db", + "ns3/evil-cname.db", "ns3/fast-expire.db", "ns3/manual-update-rpz.db", "ns3/mixed-case-rpz.db", "ns3/named.conf.tmp", "ns3/named.stats", + "ns3/slow-rpz.db", + "ns3/wild-cname.db", "ns5/bl.db", "ns5/empty.db", "ns5/empty.db.jnl", diff -Nru bind9-9.20.11/bin/tests/system/rpz/tests_sh_rpz_dnsrps.py bind9-9.20.15/bin/tests/system/rpz/tests_sh_rpz_dnsrps.py --- bind9-9.20.11/bin/tests/system/rpz/tests_sh_rpz_dnsrps.py 2025-07-04 09:42:08.242326002 +0000 +++ bind9-9.20.15/bin/tests/system/rpz/tests_sh_rpz_dnsrps.py 2025-10-18 10:16:12.471730876 +0000 @@ -40,11 +40,14 @@ "ns3/bl-wildcname.db", "ns3/bl.db", "ns3/bl.tld2.db", + "ns3/evil-cname.db", "ns3/fast-expire.db", "ns3/manual-update-rpz.db", "ns3/mixed-case-rpz.db", "ns3/named.conf.tmp", "ns3/named.stats", + "ns3/slow-rpz.db", + "ns3/wild-cname.db", "ns5/bl.db", "ns5/empty.db", "ns5/empty.db.jnl", diff -Nru bind9-9.20.11/bin/tests/system/rpzextra/tests_rpzextra.py bind9-9.20.15/bin/tests/system/rpzextra/tests_rpzextra.py --- bind9-9.20.11/bin/tests/system/rpzextra/tests_rpzextra.py 2025-07-04 09:42:08.243326025 +0000 +++ bind9-9.20.15/bin/tests/system/rpzextra/tests_rpzextra.py 2025-10-18 10:16:12.472730891 +0000 @@ -12,13 +12,16 @@ # information regarding copyright ownership. import os + import pytest pytest.importorskip("dns", minversion="2.0.0") +import dns.rcode +import dns.rrset + import isctest from isctest.compat import dns_rcode -import dns.message pytestmark = pytest.mark.extra_artifacts( [ @@ -70,7 +73,7 @@ ) def test_rpz_multiple_views(qname, source, rcode): # Wait for the rpz-external.local zone transfer - msg = dns.message.make_query("rpz-external.local", "SOA") + msg = isctest.query.create("rpz-external.local", "SOA") isctest.query.tcp( msg, ip="10.53.0.3", @@ -84,7 +87,7 @@ expected_rcode=dns_rcode.NOERROR, ) - msg = dns.message.make_query(qname, "A") + msg = isctest.query.create(qname, "A") res = isctest.query.udp(msg, "10.53.0.3", source=source, expected_rcode=rcode) if rcode == dns.rcode.NOERROR: assert res.answer == [dns.rrset.from_text(qname, 300, "IN", "A", "10.53.0.2")] @@ -94,7 +97,7 @@ resolver_ip = "10.53.0.3" # Should generate a log entry into rpz_passthru.txt - msg_allowed = dns.message.make_query("allowed.", "A") + msg_allowed = isctest.query.create("allowed.", "A") res_allowed = isctest.query.udp( msg_allowed, resolver_ip, source="10.53.0.1", expected_rcode=dns.rcode.NOERROR ) @@ -103,7 +106,7 @@ ] # Should also generate a log entry into rpz_passthru.txt - msg_allowed_any = dns.message.make_query("allowed.", "ANY") + msg_allowed_any = isctest.query.create("allowed.", "ANY") res_allowed_any = isctest.query.udp( msg_allowed_any, resolver_ip, @@ -121,7 +124,7 @@ # baddomain.com isn't allowed (CNAME .), should return NXDOMAIN # Should generate a log entry into rpz.txt - msg_not_allowed = dns.message.make_query("baddomain.", "A") + msg_not_allowed = isctest.query.create("baddomain.", "A") res_not_allowed = isctest.query.udp( msg_not_allowed, resolver_ip, diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.clientip.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.clientip.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.clientip.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.clientip.conf 2025-10-18 10:16:12.474730922 +0000 @@ -33,5 +33,4 @@ zone "clientip2" { type primary; file "db.clientip2"; }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.clientip2.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.clientip2.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.clientip2.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.clientip2.conf 2025-10-18 10:16:12.474730922 +0000 @@ -33,5 +33,4 @@ zone "clientip21" { type primary; file "db.clientip21"; }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.conf.header.in bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.conf.header.in --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.conf.header.in 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.conf.header.in 2025-10-18 10:16:12.474730922 +0000 @@ -23,14 +23,13 @@ listen-on { 10.53.0.2; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; querylog yes; # let ns3 start dnsrpzd include "../dnsrps.conf"; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.default.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.default.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.default.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.default.conf 2025-10-18 10:16:12.474730922 +0000 @@ -21,5 +21,4 @@ }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.log.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.log.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.log.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.log.conf 2025-10-18 10:16:12.474730922 +0000 @@ -35,5 +35,4 @@ zone "log3" { type primary; file "db.log3"; }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.max.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.max.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.max.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.max.conf 2025-10-18 10:16:12.474730922 +0000 @@ -157,5 +157,4 @@ zone "max64" { type primary; file "db.max64.local"; }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard1.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard1.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard1.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard1.conf 2025-10-18 10:16:12.475730938 +0000 @@ -31,5 +31,4 @@ zone "wildcard1" { type primary; file "db.wildcard1"; }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard2.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard2.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard2.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard2.conf 2025-10-18 10:16:12.475730938 +0000 @@ -33,5 +33,4 @@ zone "wildcard2b" { type primary; file "db.wildcard2b"; }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard3.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard3.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard3.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard3.conf 2025-10-18 10:16:12.475730938 +0000 @@ -31,5 +31,4 @@ zone "wildcard3" { type primary; file "db.wildcard3"; }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard4.conf bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard4.conf --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns2/named.wildcard4.conf 2025-07-04 09:42:08.245326072 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns2/named.wildcard4.conf 2025-10-18 10:16:12.475730938 +0000 @@ -33,5 +33,4 @@ }; recursion yes; - dnssec-validation yes; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns3/named1.conf.in bind9-9.20.15/bin/tests/system/rpzrecurse/ns3/named1.conf.in --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns3/named1.conf.in 2025-07-04 09:42:08.246326096 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns3/named1.conf.in 2025-10-18 10:16:12.475730938 +0000 @@ -27,7 +27,7 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; response-policy { zone "policy"; } qname-wait-recurse yes nsip-enable yes @@ -36,7 +36,6 @@ include "../dnsrps.conf"; }; -trust-anchors { }; zone "policy" { type primary; file "policy.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns3/named2.conf.in bind9-9.20.15/bin/tests/system/rpzrecurse/ns3/named2.conf.in --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns3/named2.conf.in 2025-07-04 09:42:08.246326096 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns3/named2.conf.in 2025-10-18 10:16:12.475730938 +0000 @@ -26,7 +26,7 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; response-policy { zone "policy"; } nsip-wait-recurse no qname-wait-recurse yes nsip-enable yes @@ -35,7 +35,6 @@ include "../dnsrps.conf"; }; -trust-anchors { }; zone "policy" { type primary; file "policy.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/rpzrecurse/ns3/named3.conf.in bind9-9.20.15/bin/tests/system/rpzrecurse/ns3/named3.conf.in --- bind9-9.20.11/bin/tests/system/rpzrecurse/ns3/named3.conf.in 2025-07-04 09:42:08.246326096 +0000 +++ bind9-9.20.15/bin/tests/system/rpzrecurse/ns3/named3.conf.in 2025-10-18 10:16:12.475730938 +0000 @@ -26,14 +26,13 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; response-policy { zone "policy"; } nsdname-wait-recurse no nsdname-enable yes; include "../dnsrps.conf"; }; -trust-anchors { }; zone "policy" { type primary; file "policy.db"; }; diff -Nru bind9-9.20.11/bin/tests/system/rrchecker/tests_rrchecker.py bind9-9.20.15/bin/tests/system/rrchecker/tests_rrchecker.py --- bind9-9.20.11/bin/tests/system/rrchecker/tests_rrchecker.py 2025-07-04 09:42:08.247326119 +0000 +++ bind9-9.20.15/bin/tests/system/rrchecker/tests_rrchecker.py 2025-10-18 10:16:12.476730953 +0000 @@ -37,6 +37,7 @@ "APL", "ATMA", "AVC", + "BRID", "CAA", "CDNSKEY", "CDS", @@ -49,11 +50,13 @@ "DNSKEY", "DOA", "DS", + "DSYNC", "EID", "EUI48", "EUI64", "GID", "GPOS", + "HHIT", "HINFO", "HIP", "HTTPS", diff -Nru bind9-9.20.11/bin/tests/system/rrl/ns1/named.conf.j2 bind9-9.20.15/bin/tests/system/rrl/ns1/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rrl/ns1/named.conf.j2 2025-07-04 09:42:08.247326119 +0000 +++ bind9-9.20.15/bin/tests/system/rrl/ns1/named.conf.j2 2025-10-18 10:16:12.476730953 +0000 @@ -22,9 +22,8 @@ listen-on-v6 { none; }; notify no; recursion yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "." {type primary; file "root.db";}; diff -Nru bind9-9.20.11/bin/tests/system/rrl/ns2/named.conf.j2 bind9-9.20.15/bin/tests/system/rrl/ns2/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rrl/ns2/named.conf.j2 2025-07-04 09:42:08.247326119 +0000 +++ bind9-9.20.15/bin/tests/system/rrl/ns2/named.conf.j2 2025-10-18 10:16:12.477730969 +0000 @@ -23,7 +23,7 @@ listen-on-v6 { none; }; notify no; recursion yes; - dnssec-validation yes; + dnssec-validation no; rate-limit { responses-per-second 2; @@ -36,7 +36,6 @@ }; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/rrl/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rrl/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rrl/ns3/named.conf.j2 2025-07-04 09:42:08.248326143 +0000 +++ bind9-9.20.15/bin/tests/system/rrl/ns3/named.conf.j2 2025-10-18 10:16:12.477730969 +0000 @@ -22,7 +22,7 @@ listen-on-v6 { none; }; notify no; recursion yes; - dnssec-validation yes; + dnssec-validation no; // check that all of the options are parsed without limiting anything rate-limit { @@ -43,7 +43,6 @@ }; -trust-anchors { }; zone "." { type hint; file "hints"; }; diff -Nru bind9-9.20.11/bin/tests/system/rrl/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/rrl/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rrl/ns4/named.conf.j2 2025-07-04 09:42:08.248326143 +0000 +++ bind9-9.20.15/bin/tests/system/rrl/ns4/named.conf.j2 2025-10-18 10:16:12.477730969 +0000 @@ -23,7 +23,7 @@ listen-on-v6 { none; }; notify no; recursion yes; - dnssec-validation yes; + dnssec-validation no; max-udp-size 4096; rate-limit { @@ -38,7 +38,6 @@ }; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/rrl/tests_sh_rrl.py bind9-9.20.15/bin/tests/system/rrl/tests_sh_rrl.py --- bind9-9.20.11/bin/tests/system/rrl/tests_sh_rrl.py 2025-07-04 09:42:08.248326143 +0000 +++ bind9-9.20.15/bin/tests/system/rrl/tests_sh_rrl.py 2025-10-18 10:16:12.477730969 +0000 @@ -11,8 +11,6 @@ import pytest -import isctest.mark - pytestmark = pytest.mark.extra_artifacts( [ "*mdig.out*", @@ -24,6 +22,6 @@ # The rrl is known to be quite unstable. GL #172 -@isctest.mark.flaky(max_runs=2) +@pytest.mark.flaky(max_runs=2) def test_rrl(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/rrsetorder/ns3/named.conf.j2 bind9-9.20.15/bin/tests/system/rrsetorder/ns3/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rrsetorder/ns3/named.conf.j2 2025-07-04 09:42:08.248326143 +0000 +++ bind9-9.20.15/bin/tests/system/rrsetorder/ns3/named.conf.j2 2025-10-18 10:16:12.478730985 +0000 @@ -20,7 +20,7 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; rrset-order { name "fixed.example" order fixed; @@ -32,7 +32,6 @@ }; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/rrsetorder/ns4/named.conf.j2 bind9-9.20.15/bin/tests/system/rrsetorder/ns4/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rrsetorder/ns4/named.conf.j2 2025-07-04 09:42:08.249326166 +0000 +++ bind9-9.20.15/bin/tests/system/rrsetorder/ns4/named.conf.j2 2025-10-18 10:16:12.478730985 +0000 @@ -20,7 +20,7 @@ listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; rrset-order { class IN type A name "host.example.com" order random; @@ -28,7 +28,6 @@ }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/rrsetorder/ns5/named.conf.j2 bind9-9.20.15/bin/tests/system/rrsetorder/ns5/named.conf.j2 --- bind9-9.20.11/bin/tests/system/rrsetorder/ns5/named.conf.j2 2025-07-04 09:42:08.249326166 +0000 +++ bind9-9.20.15/bin/tests/system/rrsetorder/ns5/named.conf.j2 2025-10-18 10:16:12.478730985 +0000 @@ -20,11 +20,10 @@ listen-on { 10.53.0.5; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/selftest/tests_zone_analyzer.py bind9-9.20.15/bin/tests/system/selftest/tests_zone_analyzer.py --- bind9-9.20.11/bin/tests/system/selftest/tests_zone_analyzer.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/selftest/tests_zone_analyzer.py 2025-10-18 10:16:12.483731062 +0000 @@ -0,0 +1,228 @@ +#!/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. +""" +isctest.name.ZoneAnalyzer self-test +Generate insane test zone and check expected output of ZoneAnalyzer utility class +""" + + +import collections +import itertools +from pathlib import Path + +import dns.name +from dns.name import Name +import pytest + +import isctest +import isctest.name + +# set of properies present in the tested zone - read by tests_zone_analyzer.py +CATEGORIES = frozenset( + [ + "all_existing_names", + "delegations", + "dnames", + "ents", + "occluded", + "reachable", + "reachable_delegations", + "reachable_dnames", + "reachable_wildcards", + "reachable_wildcard_parents", + "wildcards", + ] +) + + +pytestmark = pytest.mark.extra_artifacts(["analyzer.db"]) +SUFFIX = dns.name.from_text("nsec3.example.") + +LABELS = (b"*", b"dname", b"ent", b"ns", b"txt") +LABEL2RRTYPE = { # leftmost label encodes RR type we will synthesize for given name + b"*": "TXT", + b"dname": "DNAME", + b"ent": None, # ENT is not really a 'type' + b"ns": "NS", + b"txt": "TXT", +} +LABEL2TAGS = { # leftmost label encodes 'initial' meaning of a complete name + b"*": {"wildcards"}, + b"dname": {"dnames"}, + b"ns": {"delegations"}, + b"txt": set(), # perhaps reachable, perhaps not, we need to decide based on other labels +} + + +def name2tags(name): + """ + Decode meaning hidden in labels and their relationships + and return all tags expected from ZoneAnalyzer + """ + tags = LABEL2TAGS[name[0]].copy() + + parent_labels = name[1:] + if b"ns" in parent_labels or b"dname" in parent_labels: + tags.add("occluded") + + if "occluded" not in tags: + tags.add("all_existing_names") + if "delegations" in tags: + # delegations are ambiguous and don't count as 'reachable' + tags.add("reachable_delegations") + elif "dnames" in tags: + tags.add("reachable") + tags.add("reachable_dnames") + elif "wildcards" in tags: + tags.add("reachable") + tags.add("reachable_wildcards") + else: + tags.add("reachable") + + return tags + + +def gen_node(nodes, labels): + name = Name(labels) + nodes[name] = name2tags(name) + + +def add_ents(nodes): + """ + Non-occluded nodes with 'ent' as a parent label imply existence of 'ent' nodes. + """ + new_ents = {} + for name, tags in nodes.items(): + if "occluded" in tags: + continue + + # check if any parent is ENT + entidx = 1 + while True: + try: + entidx = name.labels.index(b"ent", entidx) + except ValueError: + break + entname = Name(name[entidx:]) + new_ents[entname] = {"all_existing_names", "ents"} + entidx += 1 + + return new_ents + + +def tag_wildcard_parents(nodes): + """ + Non-occluded nodes with '*' as a leftmost label tag their immediate parent + nodes as 'reachable_wildcard_parents'. + """ + for name, tags in nodes.items(): + if "occluded" in tags or not name.is_wild(): + continue + + parent_name = Name(name[1:]) + nodes[parent_name].add("reachable_wildcard_parents") + + +def is_non_ent(labels): + """ + Filter out nodes with 'ent' at leftmost position. To become ENT a name must + not have data by itself but have some other node defined underneath it, + and must not be occluded, which is something itertools.product() cannot + decide. + """ + return labels[0] != b"ent" + + +def gen_zone(nodes): + """ + Generate zone file in text format. + + All names are relative. + Right-hand side of RRs contains dot-separated list of categories a node + belongs to (except for zone origin). + """ + for name, tags in sorted(nodes.items()): + if len(name) == 0: + # origin, very special case + yield "@\tSOA\treachable. origin-special-case. 0 0 0 0 0\n" + yield "@\tNS\treachable.\n" + yield "@\tA\t192.0.2.1\n" + continue + + rrtype = LABEL2RRTYPE[name[0]] + if rrtype is None: # ENT + prefix = "; " + else: + prefix = "" + assert tags + yield f"{prefix}{name}\t{rrtype}\t{'.'.join(sorted(tags))}.\n" + + +def gen_expected_output(nodes): + """ + {category: set(names)} mapping used by the pytest check + """ + categories = collections.defaultdict(set) + for name, tags in nodes.items(): + for tag in tags: + categories[tag].add(name) + + assert set(categories.keys()) == CATEGORIES, ( + "CATEGORIES needs updating", + CATEGORIES.symmetric_difference(set(categories.keys())), + ) + + return categories + + +def generate_test_data(): + """ + Prepare the analyzer.db zone file in the current working directory and + return the expected attribute values for the ZoneAnalyzer instance that + will be tested using that file. + """ + nodes = {} + + for length in range(1, len(LABELS) + 1): + for labelseq in filter(is_non_ent, itertools.product(LABELS, repeat=length)): + gen_node(nodes, labelseq) + + # special-case to make this look as a valid DNS zone - it needs zone origin node + nodes[Name([])] = {"all_existing_names", "reachable"} + + nodes.update(add_ents(nodes)) + tag_wildcard_parents(nodes) + + with open("analyzer.db", "w", encoding="ascii") as outf: + outf.writelines(gen_zone(nodes)) + + return gen_expected_output(nodes) + + +if __name__ == "__main__": + generate_test_data() + + +@pytest.fixture(scope="module") +def analyzer_fixture(): + expected_results = generate_test_data() # creates the "analyzer.db" file + analyzer = isctest.name.ZoneAnalyzer.read_path(Path("analyzer.db"), origin=SUFFIX) + return expected_results, analyzer + + +# pylint: disable=redefined-outer-name +@pytest.mark.parametrize("category", sorted(CATEGORIES)) +def test_analyzer_attrs(category, analyzer_fixture): + expected_results, analyzer = analyzer_fixture + # relativize results to zone name to make debugging easier + results = {name.relativize(SUFFIX) for name in getattr(analyzer, category)} + assert results == expected_results[category] diff -Nru bind9-9.20.11/bin/tests/system/serve-stale/ans2/ans.pl bind9-9.20.15/bin/tests/system/serve-stale/ans2/ans.pl --- bind9-9.20.11/bin/tests/system/serve-stale/ans2/ans.pl 2025-07-04 09:42:08.253326260 +0000 +++ bind9-9.20.15/bin/tests/system/serve-stale/ans2/ans.pl 2025-10-18 10:16:12.483731062 +0000 @@ -259,6 +259,15 @@ push @auth, $rr; } $rcode = "NOERROR"; + } elsif ($qname eq "cname.delegated.serve.stale") { + if ($qtype eq "A") { + my $rr = new Net::DNS::RR("cname.delegated.serve.stale 2 IN CNAME cname-target.serve.stale."); + push @ans, $rr; + } else { + my $rr = new Net::DNS::RR($ssnegSOA); + push @auth, $rr; + } + $rcode = "NOERROR"; } elsif ($qname eq "ns.slow" ) { if ($qtype eq "A") { my $rr = new Net::DNS::RR($slowA); diff -Nru bind9-9.20.11/bin/tests/system/serve-stale/ns1/stale.test.db bind9-9.20.15/bin/tests/system/serve-stale/ns1/stale.test.db --- bind9-9.20.11/bin/tests/system/serve-stale/ns1/stale.test.db 2025-07-04 09:42:08.254326283 +0000 +++ bind9-9.20.15/bin/tests/system/serve-stale/ns1/stale.test.db 2025-10-18 10:16:12.483731062 +0000 @@ -17,3 +17,11 @@ a1.stale.test. 1 A 192.0.2.1 cname2.stale.test. 1 CNAME a2.stale.test. a2.stale.test. 300 A 192.0.2.2 + +cname-a1 1 CNAME cname-a2 +cname-a2 300 CNAME cname-a3 +cname-a3 300 A 192.0.2.1 + +cname-b1 300 CNAME cname-b2 +cname-b2 1 CNAME cname-b3 +cname-b3 1 A 192.0.2.2 diff -Nru bind9-9.20.11/bin/tests/system/serve-stale/ns3/serve.stale.db bind9-9.20.15/bin/tests/system/serve-stale/ns3/serve.stale.db --- bind9-9.20.11/bin/tests/system/serve-stale/ns3/serve.stale.db 2025-07-04 09:42:08.254326283 +0000 +++ bind9-9.20.15/bin/tests/system/serve-stale/ns3/serve.stale.db 2025-10-18 10:16:12.484731078 +0000 @@ -18,4 +18,5 @@ test IN NS nss2.example.nxd. delegated IN NS ns2.delegated.serve.stale. +cname-target IN A 10.53.0.99 ns2.delegated IN A 10.53.0.2 diff -Nru bind9-9.20.11/bin/tests/system/serve-stale/tests.sh bind9-9.20.15/bin/tests/system/serve-stale/tests.sh --- bind9-9.20.11/bin/tests/system/serve-stale/tests.sh 2025-07-04 09:42:08.255326306 +0000 +++ bind9-9.20.15/bin/tests/system/serve-stale/tests.sh 2025-10-18 10:16:12.485731093 +0000 @@ -2096,6 +2096,73 @@ fi status=$((status + ret)) +# New CNAME scenario (GL #5243) +n=$((n + 1)) +echo_i "prime cache cname-a1.stale.test A (stale-answer-client-timeout 0) ($n)" +ret=0 +$DIG -p ${PORT} @10.53.0.3 cname-a1.stale.test A >dig.out.test$n || ret=1 +grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 +grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1 +grep "cname-a1\.stale\.test\..*1.*IN.*CNAME.*cname-a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-a2\.stale\.test\..*300.*IN.*CNAME.*cname-a3\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-a3\.stale\.test\..*300.*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n + 1)) +echo_i "prime cache cname-b1.stale.test A (stale-answer-client-timeout 0) ($n)" +ret=0 +$DIG -p ${PORT} @10.53.0.3 cname-b1.stale.test A >dig.out.test$n || ret=1 +grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 +grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1 +grep "cname-b1\.stale\.test\..*300.*IN.*CNAME.*cname-b2\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-b2\.stale\.test\..*1.*IN.*CNAME.*cname-b3\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-b3\.stale\.test\..*1.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +# Allow RRset to become stale. +sleep 1 + +n=$((n + 1)) +ret=0 +echo_i "check stale cname-a1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)" +nextpart ns3/named.run >/dev/null +$DIG -p ${PORT} @10.53.0.3 cname-a1.stale.test A >dig.out.test$n || ret=1 +wait_for_log 5 "cname-a1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 +# Other records in chain are still good, so do not attempt a refresh +grep "cname-a2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1 +grep "cname-a3.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1 +# Check answer +grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 +grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 +grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1 +grep "cname-a1\.stale\.test\..*3.*IN.*CNAME.*cname-a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-a2\.stale\.test\..*29[0-9].*IN.*CNAME.*cname-a3\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-a3\.stale\.test\..*29[0-9].*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n + 1)) +ret=0 +echo_i "check stale cname-b1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)" +nextpart ns3/named.run >/dev/null +$DIG -p ${PORT} @10.53.0.3 cname-b1.stale.test A >dig.out.test$n || ret=1 +wait_for_log 5 "cname-b2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 +# The next one in the chain (cname-b3.stale.test) is likely not logged because +# there is already a refresh in progress. And the first record in the chain is +# still good, so do not attempt a refresh. +grep "cname-b1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1 +# Check answer +grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 +grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 +grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1 +grep "cname-b1\.stale\.test\..*29[0-9].*IN.*CNAME.*cname-b2\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-b2\.stale\.test\..*3.*IN.*CNAME.*cname-b3\.stale\.test\." dig.out.test$n >/dev/null || ret=1 +grep "cname-b3\.stale\.test\..*3.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + #################################################################### # Test for stale-answer-client-timeout 0 and stale-refresh-time 4. # #################################################################### @@ -2506,12 +2573,13 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) -n=$((n + 1)) -echo_i "check serve-stale (stale-answer-client-timeout 0) with a delegation ($n)" -ret=0 # configure ns3 with stale-answer-client-timeout 0 and a delegated zone copy_setports ns3/named9.conf.in ns3/named.conf rndc_reload ns3 10.53.0.3 + +n=$((n + 1)) +echo_i "check serve-stale (stale-answer-client-timeout 0) with a delegation ($n)" +ret=0 # flush cache, enable ans2 responses, make sure serve-stale is on $RNDCCMD 10.53.0.3 flush >rndc.out.test$n.1 2>&1 || ret=1 $DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1 @@ -2529,6 +2597,31 @@ grep -F "status: NOERROR" dig.out.2.test$n >/dev/null || ret=1 grep -F "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.2.test$n >/dev/null || ret=1 grep -F "10.53.0.99" dig.out.2.test$n >/dev/null || ret=1 +# re-enable responses +$DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n + 1)) +echo_i "check serve-stale (stale-answer-client-timeout 0) with a delegation which is a CNAME to a local zone ($n)" +ret=0 +# flush cache, enable ans2 responses, make sure serve-stale is on +$RNDCCMD 10.53.0.3 flush >rndc.out.test$n.1 2>&1 || ret=1 +$DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1 +$RNDCCMD 10.53.0.3 serve-stale on >rndc.out.test$n.2 2>&1 || ret=1 +# prime the cache with the A response +$DIG -p ${PORT} @10.53.0.3 cname.delegated.serve.stale >dig.out.1.test$n || ret=1 +grep -F "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1 +grep -F "10.53.0.99" dig.out.1.test$n >/dev/null || ret=1 +# disable responses from the auth server +$DIG -p ${PORT} @10.53.0.2 txt disable >/dev/null || ret=1 +# wait two seconds for the previous answer to become stale +sleep 2 +# resend the query; we should immediately get a stale answer +$DIG -p ${PORT} @10.53.0.3 cname.delegated.serve.stale >dig.out.2.test$n || ret=1 +grep -F "status: NOERROR" dig.out.2.test$n >/dev/null || ret=1 +grep -F "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.2.test$n >/dev/null || ret=1 +grep -F "10.53.0.99" dig.out.2.test$n >/dev/null || ret=1 # re-enable responses $DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi diff -Nru bind9-9.20.11/bin/tests/system/serve-stale/tests_sh_serve_stale.py bind9-9.20.15/bin/tests/system/serve-stale/tests_sh_serve_stale.py --- bind9-9.20.11/bin/tests/system/serve-stale/tests_sh_serve_stale.py 2025-07-04 09:42:08.255326306 +0000 +++ bind9-9.20.15/bin/tests/system/serve-stale/tests_sh_serve_stale.py 2025-10-18 10:16:12.485731093 +0000 @@ -24,5 +24,6 @@ ) +@pytest.mark.flaky(max_runs=2) def test_serve_stale(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/shutdown/tests_shutdown.py bind9-9.20.15/bin/tests/system/shutdown/tests_shutdown.py --- bind9-9.20.11/bin/tests/system/shutdown/tests_shutdown.py 2025-07-04 09:42:08.257326353 +0000 +++ bind9-9.20.15/bin/tests/system/shutdown/tests_shutdown.py 2025-10-18 10:16:12.487731124 +0000 @@ -105,7 +105,7 @@ ) qname = relname + ".test" - msg = dns.message.make_query(qname, "A") + msg = isctest.query.create(qname, "A") futures[ executor.submit( isctest.query.udp, msg, resolver_ip, timeout=1, attempts=1 diff -Nru bind9-9.20.11/bin/tests/system/spf/tests_spf_zones.py bind9-9.20.15/bin/tests/system/spf/tests_spf_zones.py --- bind9-9.20.11/bin/tests/system/spf/tests_spf_zones.py 2025-07-04 09:42:08.258326377 +0000 +++ bind9-9.20.15/bin/tests/system/spf/tests_spf_zones.py 2025-10-18 10:16:12.488731140 +0000 @@ -13,7 +13,7 @@ @pytest.mark.requires_zones_loaded("ns1") -def test_spf_log(servers): +def test_spf_log(ns1): for msg in ( "zone spf/IN: 'y.spf' found type SPF record but no SPF TXT record found", "zone warn/IN: 'y.warn' found type SPF record but no SPF TXT record found", @@ -21,7 +21,7 @@ "zone warn/IN: loaded serial 0", "zone nowarn/IN: loaded serial 0", ): - servers["ns1"].log.expect(msg) + ns1.log.expect(msg) for msg in ( "zone nowarn/IN: 'y.nowarn' found type SPF record but no SPF TXT record found", @@ -29,4 +29,4 @@ "zone warn/IN: 'warn' found type SPF record but no SPF TXT record found", "zone nowarn/IN: 'nowarn' found type SPF record but no SPF TXT record found", ): - servers["ns1"].log.prohibit(msg) + ns1.log.prohibit(msg) diff -Nru bind9-9.20.11/bin/tests/system/statistics/ns2/named.conf.in bind9-9.20.15/bin/tests/system/statistics/ns2/named.conf.in --- bind9-9.20.11/bin/tests/system/statistics/ns2/named.conf.in 2025-07-04 09:42:08.262326470 +0000 +++ bind9-9.20.15/bin/tests/system/statistics/ns2/named.conf.in 2025-10-18 10:16:12.492731202 +0000 @@ -20,11 +20,10 @@ listen-on { 10.53.0.2; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; include "statistics-channels.conf"; diff -Nru bind9-9.20.11/bin/tests/system/statistics/ns3/named.conf.in bind9-9.20.15/bin/tests/system/statistics/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/statistics/ns3/named.conf.in 2025-07-04 09:42:08.262326470 +0000 +++ bind9-9.20.15/bin/tests/system/statistics/ns3/named.conf.in 2025-10-18 10:16:12.492731202 +0000 @@ -21,13 +21,12 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; qname-minimization disabled; zone-statistics yes; }; -trust-anchors { }; include "statistics-channels.conf"; diff -Nru bind9-9.20.11/bin/tests/system/statschannel/tests_json.py bind9-9.20.15/bin/tests/system/statschannel/tests_json.py --- bind9-9.20.11/bin/tests/system/statschannel/tests_json.py 2025-07-04 09:42:08.265326541 +0000 +++ bind9-9.20.15/bin/tests/system/statschannel/tests_json.py 2025-10-18 10:16:12.494731233 +0000 @@ -119,6 +119,6 @@ ) -@isctest.mark.flaky(max_runs=2, rerun_filter=isctest.mark.with_tsan) +@pytest.mark.flaky(max_runs=2) def test_traffic_json(statsport): generic.test_traffic(fetch_traffic_json, statsip="10.53.0.2", statsport=statsport) diff -Nru bind9-9.20.11/bin/tests/system/statschannel/tests_xml.py bind9-9.20.15/bin/tests/system/statschannel/tests_xml.py --- bind9-9.20.11/bin/tests/system/statschannel/tests_xml.py 2025-07-04 09:42:08.265326541 +0000 +++ bind9-9.20.15/bin/tests/system/statschannel/tests_xml.py 2025-10-18 10:16:12.495731249 +0000 @@ -148,6 +148,6 @@ ) -@isctest.mark.flaky(max_runs=2, rerun_filter=isctest.mark.with_tsan) +@pytest.mark.flaky(max_runs=2) def test_traffic_xml(statsport): generic.test_traffic(fetch_traffic_xml, statsip="10.53.0.2", statsport=statsport) diff -Nru bind9-9.20.11/bin/tests/system/stress/ns3/named.conf.in bind9-9.20.15/bin/tests/system/stress/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/stress/ns3/named.conf.in 2025-07-04 09:42:08.267326588 +0000 +++ bind9-9.20.15/bin/tests/system/stress/ns3/named.conf.in 2025-10-18 10:16:12.496731264 +0000 @@ -22,11 +22,10 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/stress/ns4/named.conf.in bind9-9.20.15/bin/tests/system/stress/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/stress/ns4/named.conf.in 2025-07-04 09:42:08.267326588 +0000 +++ bind9-9.20.15/bin/tests/system/stress/ns4/named.conf.in 2025-10-18 10:16:12.496731264 +0000 @@ -22,11 +22,10 @@ listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; notify yes; }; -trust-anchors { }; zone "zone000000.example" { type secondary; diff -Nru bind9-9.20.11/bin/tests/system/stub/tests_stub.py bind9-9.20.15/bin/tests/system/stub/tests_stub.py --- bind9-9.20.11/bin/tests/system/stub/tests_stub.py 2025-07-04 09:42:08.268326611 +0000 +++ bind9-9.20.15/bin/tests/system/stub/tests_stub.py 2025-10-18 10:16:12.497731280 +0000 @@ -26,20 +26,20 @@ ) -def test_stub_zones_availability(servers): +def test_stub_zones_availability(ns3): # check that the stub zone has been saved to disk assert os.path.exists("ns3/child.example.st") # try an AXFR that should be denied (NOTAUTH) def axfr_denied(): - msg = dns.message.make_query("child.example.", "AXFR") + msg = isctest.query.create("child.example.", "AXFR") res = isctest.query.tcp(msg, "10.53.0.3") isctest.check.notauth(res) # look for stub zone data without recursion (should not be found) def stub_zone_lookout_without_recursion(): # drop all flags (dns.flags.RD is set by default) - msg = dns.message.make_query("data.child.example.", "TXT") + msg = isctest.query.create("data.child.example.", "TXT") msg.flags = 0 res = isctest.query.tcp(msg, "10.53.0.3") isctest.check.noerror(res) @@ -54,7 +54,7 @@ # look for stub zone data with recursion (should be found) def stub_zone_lookout_with_recursion(): # dns.flags.RD is set by default - msg = dns.message.make_query("data.child.example.", "TXT") + msg = isctest.query.create("data.child.example.", "TXT") res = isctest.query.tcp(msg, "10.53.0.3") isctest.check.noerror(res) assert res.answer[0] == dns.rrset.from_text( @@ -65,8 +65,8 @@ stub_zone_lookout_without_recursion() stub_zone_lookout_with_recursion() - servers["ns3"].stop() - servers["ns3"].start(["--noclean", "--restart", "--port", os.environ["PORT"]]) + ns3.stop() + ns3.start(["--noclean", "--restart", "--port", os.environ["PORT"]]) axfr_denied() stub_zone_lookout_without_recursion() @@ -79,7 +79,7 @@ assert os.path.exists("ns5/example.db") # this query would fail if NS glue wasn't transferred - msg_txt = dns.message.make_query("target.example.", "TXT", want_dnssec=False) + msg_txt = isctest.query.create("target.example.", "TXT", dnssec=False) res_txt = isctest.query.tcp(msg_txt, "10.53.0.5") isctest.check.noerror(res_txt) assert res_txt.answer[0] == dns.rrset.from_text( @@ -87,13 +87,13 @@ ) # ensure both IPv4 and IPv6 glue records were transferred - msg_a = dns.message.make_query("ns4.example.", "A") + msg_a = isctest.query.create("ns4.example.", "A") res_a = isctest.query.tcp(msg_a, "10.53.0.5") assert res_a.answer[0] == dns.rrset.from_text( "ns4.example.", "300", "IN", "A", "10.53.0.4" ) - msg_aaaa = dns.message.make_query("ns4.example.", "AAAA") + msg_aaaa = isctest.query.create("ns4.example.", "AAAA") res_aaaa = isctest.query.tcp(msg_aaaa, "10.53.0.5") assert res_aaaa.answer[0] == dns.rrset.from_text( "ns4.example.", "300", "IN", "AAAA", "fd92:7065:b8e:ffff::4" diff -Nru bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/named.conf.in bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/named.conf.in 2025-07-04 09:42:08.268326611 +0000 +++ bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/named.conf.in 2025-10-18 10:16:12.498731295 +0000 @@ -62,6 +62,11 @@ file "minimal.db.signed"; }; +zone "no-apex-covering" { + type primary; + file "no-apex-covering.db.signed"; +}; + zone "soa-without-dnskey" { type primary; file "soa-without-dnskey.db.signed"; diff -Nru bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in --- bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/no-apex-covering.db.in 2025-10-18 10:16:12.498731295 +0000 @@ -0,0 +1,28 @@ +; 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 3600 +@ SOA ns1 hostmaster 1 3600 1200 604800 3600 +@ NS ns1 +ns1 A 10.53.0.1 +; \007 sorts before * so the covering NSEC for the wildcard is not +; the apex NSEC. +\007 HINFO "" "" +nodata TXT nodata +*.wild-a A 1.2.3.4 +*.wild-cname CNAME ns1 +*.wild-1-nsec A 1.2.3.4 +*.wild-2-nsec A 1.2.3.4 +_x.wild-2-nsec TXT a name beween wild-2-nsec and a.wild-2-nsec +*.wild-2-nsec-afterdata A 1.2.3.4 +*.wild-2-nsec-afterdata AAAA 2002::1 +_x.wild-2-nsec-afterdata TXT a name beween wild-2-nsec-afterdata and a.wild-2-nsec-afterdata +dnamed DNAME dnamed. diff -Nru bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/root.db.in bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/root.db.in --- bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/root.db.in 2025-07-04 09:42:08.268326611 +0000 +++ bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/root.db.in 2025-10-18 10:16:12.498731295 +0000 @@ -16,6 +16,8 @@ example NS ns1.example fun NS ns1.example ns1.example A 10.53.0.1 +no-apex-covering NS ns1.no-apex-covering +ns1.no-apex-covering A 10.53.0.1 dnamed NS ns1.dnamed ns1.dnamed A 10.53.0.1 minimal NS ns1.minimal diff -Nru bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/sign.sh bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/sign.sh --- bind9-9.20.11/bin/tests/system/synthfromdnssec/ns1/sign.sh 2025-07-04 09:42:08.268326611 +0000 +++ bind9-9.20.15/bin/tests/system/synthfromdnssec/ns1/sign.sh 2025-10-18 10:16:12.498731295 +0000 @@ -25,6 +25,17 @@ $SIGNER -P -o $zone $zonefile >/dev/null +zone=no-apex-covering +infile=no-apex-covering.db.in +zonefile=no-apex-covering.db + +keyname=$($KEYGEN -q -a ${DEFAULT_ALGORITHM} $zone) +cat "$infile" "$keyname.key" >"$zonefile" +echo insecure NS ns1.insecure >>"$zonefile" +echo ns1.insecure A 10.53.0.1 >>"$zonefile" + +$SIGNER -P -o $zone $zonefile >/dev/null + zone=insecure.example infile=example.db.in zonefile=insecure.example.db diff -Nru bind9-9.20.11/bin/tests/system/synthfromdnssec/tests.sh bind9-9.20.15/bin/tests/system/synthfromdnssec/tests.sh --- bind9-9.20.11/bin/tests/system/synthfromdnssec/tests.sh 2025-07-04 09:42:08.270326658 +0000 +++ bind9-9.20.15/bin/tests/system/synthfromdnssec/tests.sh 2025-10-18 10:16:12.500731326 +0000 @@ -132,6 +132,17 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) + echo_i "prime negative NXDOMAIN response no-apex-covering (synth-from-dnssec ${description};) ($n)" + ret=0 + dig_with_opts a.no-apex-covering. @10.53.0.${ns} a >dig.out.ns${ns}.test$n || ret=1 + check_ad_flag $ad dig.out.ns${ns}.test$n || ret=1 + check_status NXDOMAIN dig.out.ns${ns}.test$n || ret=1 + check_nosynth_soa no-apex-covering. dig.out.ns${ns}.test$n || ret=1 + [ $ns -eq 2 ] && cp dig.out.ns${ns}.test$n no-apex-covering.out + n=$((n + 1)) + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + echo_i "prime negative NODATA response (synth-from-dnssec ${description};) ($n)" ret=0 dig_with_opts nodata.example. @10.53.0.${ns} a >dig.out.ns${ns}.test$n || ret=1 @@ -370,6 +381,24 @@ if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) + echo_i "check synthesized NXDOMAIN response no-apex-covering (synth-from-dnssec ${description};) ($n)" + ret=0 + nextpart ns1/named.run >/dev/null + dig_with_opts b.no-apex-covering. @10.53.0.${ns} a >dig.out.ns${ns}.test$n || ret=1 + check_ad_flag $ad dig.out.ns${ns}.test$n || ret=1 + check_status NXDOMAIN dig.out.ns${ns}.test$n || ret=1 + if [ ${synth} = yes ]; then + check_synth_soa no-apex-covering. dig.out.ns${ns}.test$n || ret=1 + nextpart ns1/named.run | grep b.no-apex-covering/A >/dev/null && ret=1 + else + check_nosynth_soa no-apex-covering. dig.out.ns${ns}.test$n || ret=1 + nextpart ns1/named.run | grep b.no-apex-covering/A >/dev/null || ret=1 + fi + digcomp no-apex-covering.out dig.out.ns${ns}.test$n || ret=1 + n=$((n + 1)) + if [ $ret != 0 ]; then echo_i "failed"; fi + status=$((status + ret)) + echo_i "check synthesized NODATA response (synth-from-dnssec ${description};) ($n)" ret=0 nextpart ns1/named.run >/dev/null @@ -670,7 +699,7 @@ for synthesized in NXDOMAIN no-data wildcard; do case $synthesized in - NXDOMAIN) count=1 ;; + NXDOMAIN) count=2 ;; no-data) count=4 ;; wildcard) count=2 ;; esac @@ -727,7 +756,7 @@ for synthesized in SynthNXDOMAIN SynthNODATA SynthWILDCARD; do case $synthesized in - SynthNXDOMAIN) count=1 ;; + SynthNXDOMAIN) count=2 ;; SynthNODATA) count=4 ;; SynthWILDCARD) count=2 ;; esac @@ -786,7 +815,7 @@ for synthesized in SynthNXDOMAIN SynthNODATA SynthWILDCARD; do case $synthesized in - SynthNXDOMAIN) count=1 ;; + SynthNXDOMAIN) count=2 ;; SynthNODATA) count=4 ;; SynthWILDCARD) count=2 ;; esac diff -Nru bind9-9.20.11/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py bind9-9.20.15/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py --- bind9-9.20.11/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py 2025-07-04 09:42:08.270326658 +0000 +++ bind9-9.20.15/bin/tests/system/synthfromdnssec/tests_sh_synthfromdnssec.py 2025-10-18 10:16:12.500731326 +0000 @@ -24,6 +24,7 @@ "insecure.wildnodata2nsecafterdata.out", "json.out*", "minimal.nxdomain.out", + "no-apex-covering.out", "nodata.out", "nxdomain.out", "wild.out", @@ -45,6 +46,8 @@ "ns1/insecure.example.db.signed", "ns1/minimal.db", "ns1/minimal.db.signed", + "ns1/no-apex-covering.db", + "ns1/no-apex-covering.db.signed", "ns1/root.db", "ns1/root.db.signed", "ns1/soa-without-dnskey.db", diff -Nru bind9-9.20.11/bin/tests/system/timeouts/tests_tcp_timeouts.py bind9-9.20.15/bin/tests/system/timeouts/tests_tcp_timeouts.py --- bind9-9.20.11/bin/tests/system/timeouts/tests_tcp_timeouts.py 2025-07-04 09:42:08.272326705 +0000 +++ bind9-9.20.15/bin/tests/system/timeouts/tests_tcp_timeouts.py 2025-10-18 10:16:12.502731358 +0000 @@ -13,7 +13,6 @@ # pylint: disable=unused-variable -import platform import socket import time @@ -68,11 +67,7 @@ raise EOFError from e -def is_host_freebsd_13(*_): - return platform.system() == "FreeBSD" and platform.release().startswith("13") - - -@isctest.mark.flaky(max_runs=2, rerun_filter=is_host_freebsd_13) +@pytest.mark.flaky(max_runs=2, rerun_filter=isctest.mark.is_host_freebsd_13) def test_idle_timeout(named_port): # # The idle timeout is 5 seconds, so the third message should fail @@ -194,7 +189,7 @@ assert soa is not None -@isctest.mark.flaky(max_runs=3) +@pytest.mark.flaky(max_runs=3) def test_send_timeout(named_port): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect(("10.53.0.1", named_port)) diff -Nru bind9-9.20.11/bin/tests/system/tools/tests.sh bind9-9.20.15/bin/tests/system/tools/tests.sh --- bind9-9.20.11/bin/tests/system/tools/tests.sh 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/tools/tests.sh 2025-10-18 10:16:12.502731358 +0000 @@ -0,0 +1,24 @@ +#!/usr/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 + +echo_i "tools must not crash if stdio is closed" +"$NSUPDATE" 0>&- +"$NSUPDATE" 0>&- 1>&- +"$NSUPDATE" 0>&- 1>&- 2>&- +"$NSUPDATE" 0>&- 2>&- +"$NSUPDATE" 1>&- +"$NSUPDATE" 1>&- 2>&- +"$NSUPDATE" 2>&- diff -Nru bind9-9.20.11/bin/tests/system/tools/tests_sh_tools.py bind9-9.20.15/bin/tests/system/tools/tests_sh_tools.py --- bind9-9.20.11/bin/tests/system/tools/tests_sh_tools.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/tools/tests_sh_tools.py 2025-10-18 10:16:12.502731358 +0000 @@ -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. + +import pytest + +pytestmark = pytest.mark.extra_artifacts([]) + + +def test_tools(run_tests_sh): + run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/tools/tests_tools_nsec3hash.py bind9-9.20.15/bin/tests/system/tools/tests_tools_nsec3hash.py --- bind9-9.20.11/bin/tests/system/tools/tests_tools_nsec3hash.py 2025-07-04 09:42:08.272326705 +0000 +++ bind9-9.20.15/bin/tests/system/tools/tests_tools_nsec3hash.py 2025-10-18 10:16:12.502731358 +0000 @@ -15,6 +15,12 @@ import pytest import isctest +from isctest.hypothesis.strategies import dns_names + +from hypothesis import strategies, given, settings + +from dns.dnssectypes import NSEC3Hash +import dns.dnssec NSEC3HASH = os.environ.get("NSEC3HASH") @@ -120,3 +126,51 @@ def test_nsec3_bad_option(): with pytest.raises(subprocess.CalledProcessError): isctest.run.cmd([NSEC3HASH, "-?"]) + + +@given( + domain=dns_names(), + it=strategies.integers(min_value=0, max_value=65535), + salt_bytes=strategies.binary(min_size=0, max_size=255), +) +def test_nsec3hash_acceptable_values(domain, it, salt_bytes) -> None: + if not salt_bytes: + salt_text = "-" + else: + salt_text = salt_bytes.hex() + # calculate the hash using dnspython: + hash1 = dns.dnssec.nsec3_hash( + domain, salt=salt_bytes, iterations=it, algorithm=NSEC3Hash.SHA1 + ) + + # calculate the hash using nsec3hash: + output = isctest.run.cmd( + [NSEC3HASH, salt_text, "1", str(it), str(domain)] + ).stdout.decode("ascii") + hash2 = output.partition(" ")[0] + + assert hash1 == hash2 + + +@settings(max_examples=5) +@given( + domain=dns_names(), + it=strategies.integers(min_value=0, max_value=65535), + salt_bytes=strategies.binary(min_size=256), +) +def test_nsec3hash_salt_too_long(domain, it, salt_bytes) -> None: + salt_text = salt_bytes.hex() + with pytest.raises(subprocess.CalledProcessError): + isctest.run.cmd([NSEC3HASH, salt_text, "1", str(it), str(domain)]) + + +@settings(max_examples=5) +@given( + domain=dns_names(), + it=strategies.integers(min_value=65536), + salt_bytes=strategies.binary(min_size=0, max_size=255), +) +def test_nsec3hash_too_many_iterations(domain, it, salt_bytes) -> None: + salt_text = salt_bytes.hex() + with pytest.raises(subprocess.CalledProcessError): + isctest.run.cmd([NSEC3HASH, salt_text, "1", str(it), str(domain)]) diff -Nru bind9-9.20.11/bin/tests/system/transport-acl/ns1/named.conf.in bind9-9.20.15/bin/tests/system/transport-acl/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/transport-acl/ns1/named.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-acl/ns1/named.conf.in 2025-10-18 10:16:12.502731358 +0000 @@ -64,11 +64,10 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; }; -trust-anchors { }; zone "example0" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-http-plain-proxy.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-http-plain-proxy.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-http-plain-proxy.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-http-plain-proxy.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-http-plain.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-http-plain.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-http-plain.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-http-plain.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-https-proxy-encrypted.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-https-proxy-encrypted.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-https-proxy-encrypted.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-https-proxy-encrypted.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-https-proxy-plain.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-https-proxy-plain.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-https-proxy-plain.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-https-proxy-plain.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-https.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-https.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-https.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-https.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-proxy.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-proxy.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-proxy.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-proxy.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-tls-proxy-encrypted.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-tls-proxy-encrypted.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-tls-proxy-encrypted.conf.in 2025-07-04 09:42:08.273326728 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-tls-proxy-encrypted.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-tls-proxy-plain.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-tls-proxy-plain.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-tls-proxy-plain.conf.in 2025-07-04 09:42:08.274326752 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-tls-proxy-plain.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named-tls.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named-tls.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named-tls.conf.in 2025-07-04 09:42:08.274326752 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named-tls.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/transport-change/ns1/named.conf.in bind9-9.20.15/bin/tests/system/transport-change/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/transport-change/ns1/named.conf.in 2025-07-04 09:42:08.274326752 +0000 +++ bind9-9.20.15/bin/tests/system/transport-change/ns1/named.conf.in 2025-10-18 10:16:12.503731373 +0000 @@ -34,13 +34,12 @@ recursion no; notify explicit; statistics-file "named.stats"; - dnssec-validation yes; + dnssec-validation no; tcp-initial-timeout 1200; allow-proxy { any; }; allow-proxy-on { 10.53.0.1; fd92:7065:b8e:ffff::1; }; }; -trust-anchors { }; zone "example" { type primary; diff -Nru bind9-9.20.11/bin/tests/system/tsig/ans2/ans.pl bind9-9.20.15/bin/tests/system/tsig/ans2/ans.pl --- bind9-9.20.11/bin/tests/system/tsig/ans2/ans.pl 2025-07-04 09:42:08.274326752 +0000 +++ bind9-9.20.15/bin/tests/system/tsig/ans2/ans.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +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. - -# -# An adhoc server that returns a TC=1 response with the final byte -# removed to generate UNEXPECTEDEND form dns_message_parse. -# - -use IO::File; -use IO::Socket; - -my $localport = int($ENV{'PORT'}); -if (!$localport) { $localport = 5300; } -printf "localport %u\n", $localport; - -my $sock = IO::Socket::INET->new(LocalAddr => "10.53.0.2", - LocalPort => $localport, Proto => "udp") or die "$!"; - -my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!"; -print $pidf "$$\n" or die "cannot write pid file: $!"; -$pidf->close or die "cannot close pid file: $!"; -sub rmpid { unlink "ans.pid"; exit 1; }; - -$SIG{INT} = \&rmpid; -$SIG{TERM} = \&rmpid; - -sub arraystring { - my $string = join("", @_); - return $string; -} - -for (;;) { - $from = $sock->recv($buf, 512); - ($port, $ip_address) = unpack_sockaddr_in($from); - $l = length($buf); - printf "received %u bytes from %s#%u\n", $l, inet_ntoa($ip_address), $port; - @up = unpack("C[$l]", $buf); - $up[2] |= 0x80; # QR - $up[2] |= 0x02; # TC - $up[3] |= 0x80; # RA - $l -= 1; # truncate the response 1 byte - $replydata = pack("C[$l]", @up); - printf "sent %u bytes\n", $sock->send($replydata); -} diff -Nru bind9-9.20.11/bin/tests/system/tsig/ans2/ans.py bind9-9.20.15/bin/tests/system/tsig/ans2/ans.py --- bind9-9.20.11/bin/tests/system/tsig/ans2/ans.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/tsig/ans2/ans.py 2025-10-18 10:16:12.504731389 +0000 @@ -0,0 +1,49 @@ +""" +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. +""" + +from typing import AsyncGenerator + +import dns.flags + +from isctest.asyncserver import ( + AsyncDnsServer, + BytesResponseSend, + QueryContext, + ResponseHandler, +) + + +class TruncatedWithLastByteDroppedHandler(ResponseHandler): + """ + Return a TC=1 response with the final byte removed to make + dns_message_parse() return ISC_R_UNEXPECTEDEND. + """ + + async def get_responses( + self, qctx: QueryContext + ) -> AsyncGenerator[BytesResponseSend, None]: + tc_response = qctx.query + tc_response.flags |= dns.flags.QR + tc_response.flags |= dns.flags.TC + tc_response.flags |= dns.flags.RA + yield BytesResponseSend(tc_response.to_wire()[:-1]) + + +def main() -> None: + server = AsyncDnsServer(acknowledge_tsig_dnspython_hacks=True) + server.install_response_handler(TruncatedWithLastByteDroppedHandler()) + server.run() + + +if __name__ == "__main__": + main() diff -Nru bind9-9.20.11/bin/tests/system/tsig/tests_sh_tsig.py bind9-9.20.15/bin/tests/system/tsig/tests_sh_tsig.py --- bind9-9.20.11/bin/tests/system/tsig/tests_sh_tsig.py 2025-07-04 09:42:08.276326798 +0000 +++ bind9-9.20.15/bin/tests/system/tsig/tests_sh_tsig.py 2025-10-18 10:16:12.506731420 +0000 @@ -21,6 +21,9 @@ ] ) +# TSIG queries not supported by isctest.asyncserver with old dnspython +pytest.importorskip("dns", minversion="2.0.0") + def test_tsig(run_tests_sh): run_tests_sh() diff -Nru bind9-9.20.11/bin/tests/system/tsig/tests_tsig_hypothesis.py bind9-9.20.15/bin/tests/system/tsig/tests_tsig_hypothesis.py --- bind9-9.20.11/bin/tests/system/tsig/tests_tsig_hypothesis.py 2025-07-04 09:42:08.276326798 +0000 +++ bind9-9.20.15/bin/tests/system/tsig/tests_tsig_hypothesis.py 2025-10-18 10:16:12.506731420 +0000 @@ -101,11 +101,10 @@ error, mangle_orig_id, other, - servers, + ns1, named_port, ): alg, mac = alg_and_mac - ns1 = servers["ns1"] msg = dns.message.make_query("example.com.", "AXFR") msg.keyring = False # don't validate received TSIG diff -Nru bind9-9.20.11/bin/tests/system/tsiggss/tests_isc_spnego_flaws.py bind9-9.20.15/bin/tests/system/tsiggss/tests_isc_spnego_flaws.py --- bind9-9.20.11/bin/tests/system/tsiggss/tests_isc_spnego_flaws.py 2025-07-04 09:42:08.277326822 +0000 +++ bind9-9.20.15/bin/tests/system/tsiggss/tests_isc_spnego_flaws.py 2025-10-18 10:16:12.507731435 +0000 @@ -56,7 +56,7 @@ rrset = dns.rrset.from_rdata(dns.name.root, dns.rdatatype.TKEY, rdata) # Prepare complete TKEY query to send - self.msg = dns.message.make_query( + self.msg = isctest.query.create( dns.name.root, dns.rdatatype.TKEY, dns.rdataclass.ANY ) self.msg.additional.append(rrset) diff -Nru bind9-9.20.11/bin/tests/system/ttl/tests_cache_ttl.py bind9-9.20.15/bin/tests/system/ttl/tests_cache_ttl.py --- bind9-9.20.11/bin/tests/system/ttl/tests_cache_ttl.py 2025-07-04 09:42:08.277326822 +0000 +++ bind9-9.20.15/bin/tests/system/ttl/tests_cache_ttl.py 2025-10-18 10:16:12.507731435 +0000 @@ -13,9 +13,6 @@ import isctest -pytest.importorskip("dns") -import dns.message - @pytest.mark.parametrize( "qname,rdtype,expected_ttl", @@ -27,7 +24,7 @@ ], ) def test_cache_ttl(qname, rdtype, expected_ttl): - msg = dns.message.make_query(qname, rdtype) + msg = isctest.query.create(qname, rdtype) response = isctest.query.udp(msg, "10.53.0.2") for rr in response.answer + response.authority: assert rr.ttl == expected_ttl diff -Nru bind9-9.20.11/bin/tests/system/wildcard/tests_wildcard.py bind9-9.20.15/bin/tests/system/wildcard/tests_wildcard.py --- bind9-9.20.11/bin/tests/system/wildcard/tests_wildcard.py 2025-07-04 09:42:08.286327032 +0000 +++ bind9-9.20.15/bin/tests/system/wildcard/tests_wildcard.py 2025-10-18 10:16:12.516731575 +0000 @@ -94,7 +94,7 @@ # See RFC 4592 section 2.2.1. assume(name == SUFFIX or name.labels[-len(SUFFIX) - 1] != b"*") - query_msg = dns.message.make_query(name, rdtype) + query_msg = isctest.query.create(name, rdtype) response_msg = isctest.query.tcp(query_msg, IP_ADDR, named_port, timeout=TIMEOUT) isctest.check.is_response_to(response_msg, query_msg) @@ -111,7 +111,7 @@ # See RFC 4592 section 2.2.1. assume(name.labels[-len(SUFFIX) - 1] != b"*") - query_msg = dns.message.make_query(name, WILDCARD_RDTYPE) + query_msg = isctest.query.create(name, WILDCARD_RDTYPE) response_msg = isctest.query.tcp(query_msg, IP_ADDR, named_port, timeout=TIMEOUT) isctest.check.is_response_to(response_msg, query_msg) @@ -140,7 +140,7 @@ name: dns.name.Name, named_port: int ) -> None: """RFC 4592 section 2.2.1 ghost.*.example.""" - query_msg = dns.message.make_query(name, WILDCARD_RDTYPE) + query_msg = isctest.query.create(name, WILDCARD_RDTYPE) response_msg = isctest.query.tcp(query_msg, IP_ADDR, named_port, timeout=TIMEOUT) isctest.check.is_response_to(response_msg, query_msg) @@ -170,7 +170,7 @@ or name.labels[-len(NESTED_SUFFIX) - 1] != b"*" ) - query_msg = dns.message.make_query(name, WILDCARD_RDTYPE) + query_msg = isctest.query.create(name, WILDCARD_RDTYPE) response_msg = isctest.query.tcp(query_msg, IP_ADDR, named_port, timeout=TIMEOUT) isctest.check.is_response_to(response_msg, query_msg) @@ -201,7 +201,7 @@ `foo.*.*.*.nestedwild.test. A` must not be synthesized. """ - query_msg = dns.message.make_query(name, WILDCARD_RDTYPE) + query_msg = isctest.query.create(name, WILDCARD_RDTYPE) response_msg = isctest.query.tcp(query_msg, IP_ADDR, named_port, timeout=TIMEOUT) isctest.check.is_response_to(response_msg, query_msg) diff -Nru bind9-9.20.11/bin/tests/system/xfer/dig1.good bind9-9.20.15/bin/tests/system/xfer/dig1.good --- bind9-9.20.11/bin/tests/system/xfer/dig1.good 2025-07-04 09:42:08.287327056 +0000 +++ bind9-9.20.15/bin/tests/system/xfer/dig1.good 2025-10-18 10:16:12.517731591 +0000 @@ -25,6 +25,7 @@ atma03.example. 3600 IN ATMA 1234567890abcdef atma04.example. 3600 IN ATMA fedcba0987654321 avc.example. 3600 IN AVC "foo:bar" +brid.example. 3600 IN BRID abcd caa01.example. 3600 IN CAA 0 issue "ca.example.net; policy=ev" caa02.example. 3600 IN CAA 128 tbs "Unknown" caa03.example. 3600 IN CAA 128 tbs "" @@ -49,12 +50,14 @@ ds01.example. 3600 IN NS ns42.example. ds02.example. 3600 IN DS 12892 5 1 7AA4A3F416C2F2391FB7AB0D434F762CD62D1390 ds02.example. 3600 IN NS ns43.example. +dsync01.example. 3600 IN DSYNC CDS NOTIFY 53 . eid01.example. 3600 IN EID 1289AB eui48.example. 3600 IN EUI48 01-23-45-67-89-ab eui64.example. 3600 IN EUI64 01-23-45-67-89-ab-cd-ef gid01.example. 3600 IN GID \# 1 03 gpos01.example. 3600 IN GPOS "-22.6882" "116.8652" "250.0" gpos02.example. 3600 IN GPOS "" "" "" +hhit.example. 3600 IN HHIT abcd hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4" hinfo02.example. 3600 IN HINFO "PC" "NetBSD" hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D diff -Nru bind9-9.20.11/bin/tests/system/xfer/dig2.good bind9-9.20.15/bin/tests/system/xfer/dig2.good --- bind9-9.20.11/bin/tests/system/xfer/dig2.good 2025-07-04 09:42:08.287327056 +0000 +++ bind9-9.20.15/bin/tests/system/xfer/dig2.good 2025-10-18 10:16:12.517731591 +0000 @@ -25,6 +25,7 @@ atma03.example. 3600 IN ATMA 1234567890abcdef atma04.example. 3600 IN ATMA fedcba0987654321 avc.example. 3600 IN AVC "foo:bar" +brid.example. 3600 IN BRID abcd caa01.example. 3600 IN CAA 0 issue "ca.example.net; policy=ev" caa02.example. 3600 IN CAA 128 tbs "Unknown" caa03.example. 3600 IN CAA 128 tbs "" @@ -49,12 +50,14 @@ ds01.example. 3600 IN DS 12892 5 2 26584835CA80C81C91999F31CFAF2A0E89D4FF1C8FAFD0DDB31A85C7 19277C13 ds02.example. 3600 IN NS ns43.example. ds02.example. 3600 IN DS 12892 5 1 7AA4A3F416C2F2391FB7AB0D434F762CD62D1390 +dsync01.example. 3600 IN DSYNC CDS NOTIFY 53 . eid01.example. 3600 IN EID 1289AB eui48.example. 3600 IN EUI48 01-23-45-67-89-ab eui64.example. 3600 IN EUI64 01-23-45-67-89-ab-cd-ef gid01.example. 3600 IN GID \# 1 03 gpos01.example. 3600 IN GPOS "-22.6882" "116.8652" "250.0" gpos02.example. 3600 IN GPOS "" "" "" +hhit.example. 3600 IN HHIT abcd hinfo01.example. 3600 IN HINFO "Generic PC clone" "NetBSD-1.4" hinfo02.example. 3600 IN HINFO "PC" "NetBSD" hip1.example. 3600 IN HIP 2 200100107B1A74DF365639CC39F1D578 AwEAAbdxyhNuSutc5EMzxTs9LBPCIkOFH8cIvM4p9+LrV4e19WzK00+CI6zBCQTdtWsuxKbWIy87UOoJTwkUs7lBu+Upr1gsNrut79ryra+bSRGQb1slImA8YVJyuIDsj7kwzG7jnERNqnWxZ48AWkskmdHaVDP4BcelrTI3rMXdXF5D diff -Nru bind9-9.20.11/bin/tests/system/xferquota/tests_xferquota.py bind9-9.20.15/bin/tests/system/xferquota/tests_xferquota.py --- bind9-9.20.11/bin/tests/system/xferquota/tests_xferquota.py 2025-07-04 09:42:08.290327126 +0000 +++ bind9-9.20.15/bin/tests/system/xferquota/tests_xferquota.py 2025-10-18 10:16:12.521731653 +0000 @@ -33,14 +33,14 @@ ) -def test_xferquota(named_port, servers): +def test_xferquota(named_port, ns1, ns2): # Changing test zone ensuring that the time stamp changes time.sleep(1) shutil.copyfile("ns1/changing2.db", "ns1/changing.db") with open("ns1/named.pid", "r", encoding="utf-8") as pidfile: pid = int(pidfile.read()) os.kill(pid, signal.SIGHUP) - with servers["ns1"].watch_log_from_start() as watcher: + with ns1.watch_log_from_start() as watcher: watcher.wait_for_line("received SIGHUP signal to reload zones") def check_line_count(): @@ -60,8 +60,8 @@ isctest.run.retry_with_timeout(check_line_count, timeout=360) - axfr_msg = dns.message.make_query("zone000099.example.", "AXFR") - a_msg = dns.message.make_query("a.changing.", "A") + axfr_msg = isctest.query.create("zone000099.example.", "AXFR") + a_msg = isctest.query.create("a.changing.", "A") def query_and_compare(msg): ns1response = isctest.query.tcp(msg, "10.53.0.1") @@ -75,9 +75,6 @@ f"transfer of 'changing/IN' from 10.53.0.1#{named_port}: " f"Transfer completed: .*\\(serial 2\\)" ) - with servers["ns2"].watch_log_from_start() as watcher: - watcher.wait_for_line( - pattern, - timeout=30, - ) + with ns2.watch_log_from_start(timeout=30) as watcher: + watcher.wait_for_line(pattern) query_and_compare(a_msg) diff -Nru bind9-9.20.11/bin/tests/system/zero/ans5/ans.pl bind9-9.20.15/bin/tests/system/zero/ans5/ans.pl --- bind9-9.20.11/bin/tests/system/zero/ans5/ans.pl 2025-07-04 09:42:08.290327126 +0000 +++ bind9-9.20.15/bin/tests/system/zero/ans5/ans.pl 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -#!/usr/bin/perl -w - -# 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. - -# -# Don't respond if the "norespond" file exists; otherwise respond to -# any A or AAAA query. -# - -use IO::File; -use IO::Socket; -use Net::DNS; -use Net::DNS::Packet; - -my $localport = int($ENV{'PORT'}); -if (!$localport) { $localport = 5300; } - -my $sock = IO::Socket::INET->new(LocalAddr => "10.53.0.5", - LocalPort => $localport, Proto => "udp") or die "$!"; - -my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!"; -print $pidf "$$\n" or die "cannot write pid file: $!"; -$pidf->close or die "cannot close pid file: $!"; -sub rmpid { unlink "ans.pid"; exit 1; }; - -$SIG{INT} = \&rmpid; -$SIG{TERM} = \&rmpid; - -my $octet = 0; - -for (;;) { - $sock->recv($buf, 512); - - print "**** request from " , $sock->peerhost, " port ", $sock->peerport, "\n"; - - my $packet; - - if ($Net::DNS::VERSION > 0.68) { - $packet = new Net::DNS::Packet(\$buf, 0); - $@ and die $@; - } else { - my $err; - ($packet, $err) = new Net::DNS::Packet(\$buf, 0); - $err and die $err; - } - - print "REQUEST:\n"; - $packet->print; - - $packet->header->qr(1); - - my @questions = $packet->question; - my $qname = $questions[0]->qname; - my $qtype = $questions[0]->qtype; - - $packet->header->aa(1); - if ($qtype eq "A") { - $packet->push("answer", - new Net::DNS::RR($qname . - " 0 A 192.0.2." . $octet)); - $octet = $octet + 1; - } elsif ($qtype eq "AAAA") { - $packet->push("answer", - new Net::DNS::RR($qname . - " 300 AAAA 2001:db8:beef::1")); - } - - $sock->send($packet->data); - print "RESPONSE:\n"; - $packet->print; - print "\n"; -} diff -Nru bind9-9.20.11/bin/tests/system/zero/ans5/ans.py bind9-9.20.15/bin/tests/system/zero/ans5/ans.py --- bind9-9.20.11/bin/tests/system/zero/ans5/ans.py 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/bin/tests/system/zero/ans5/ans.py 2025-10-18 10:16:12.521731653 +0000 @@ -0,0 +1,62 @@ +""" +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 ipaddress +from typing import AsyncGenerator + +import dns.flags +import dns.message +import dns.rdata +import dns.rdataclass +import dns.rdatatype +import dns.rrset + +from isctest.asyncserver import ( + AsyncDnsServer, + DnsResponseSend, + QueryContext, + ResponseHandler, +) + + +class IncrementARecordHandler(ResponseHandler): + """ + To test the TTL=0 behavior, increment the IPv4 address by one every + time we get queried. + """ + + def __init__(self): + self._ip_address = ipaddress.ip_address("192.0.2.0") + + async def get_responses( + self, qctx: QueryContext + ) -> AsyncGenerator[DnsResponseSend, None]: + if qctx.qtype == dns.rdatatype.A: + rrset = dns.rrset.from_text( + qctx.qname, 0, qctx.qclass, dns.rdatatype.A, str(self._ip_address) + ) + qctx.response.answer.append(rrset) + self._ip_address += 1 + + qctx.response.set_rcode(dns.rcode.NOERROR) + yield DnsResponseSend(qctx.response, authoritative=True) + + +def main() -> None: + server = AsyncDnsServer() + server.install_response_handler(IncrementARecordHandler()) + server.run() + + +if __name__ == "__main__": + main() diff -Nru bind9-9.20.11/bin/tests/system/zero/ns3/named.conf.in bind9-9.20.15/bin/tests/system/zero/ns3/named.conf.in --- bind9-9.20.11/bin/tests/system/zero/ns3/named.conf.in 2025-07-04 09:42:08.291327150 +0000 +++ bind9-9.20.15/bin/tests/system/zero/ns3/named.conf.in 2025-10-18 10:16:12.521731653 +0000 @@ -20,11 +20,10 @@ listen-on { 10.53.0.3; }; listen-on-v6 { none; }; recursion yes; - dnssec-validation yes; + dnssec-validation no; servfail-ttl 0; }; -trust-anchors { }; zone "." { type hint; diff -Nru bind9-9.20.11/bin/tests/system/zero/ns4/named.conf.in bind9-9.20.15/bin/tests/system/zero/ns4/named.conf.in --- bind9-9.20.11/bin/tests/system/zero/ns4/named.conf.in 2025-07-04 09:42:08.291327150 +0000 +++ bind9-9.20.15/bin/tests/system/zero/ns4/named.conf.in 2025-10-18 10:16:12.522731669 +0000 @@ -20,10 +20,9 @@ listen-on { 10.53.0.4; }; listen-on-v6 { none; }; recursion no; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; zone "example" { type secondary; diff -Nru bind9-9.20.11/bin/tests/system/zonechecks/ns1/named.conf.in bind9-9.20.15/bin/tests/system/zonechecks/ns1/named.conf.in --- bind9-9.20.11/bin/tests/system/zonechecks/ns1/named.conf.in 2025-07-04 09:42:08.292327173 +0000 +++ bind9-9.20.15/bin/tests/system/zonechecks/ns1/named.conf.in 2025-10-18 10:16:12.523731684 +0000 @@ -23,10 +23,9 @@ listen-on-v6 { none; }; recursion no; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tests/system/zonechecks/ns2/named.conf.in bind9-9.20.15/bin/tests/system/zonechecks/ns2/named.conf.in --- bind9-9.20.11/bin/tests/system/zonechecks/ns2/named.conf.in 2025-07-04 09:42:08.292327173 +0000 +++ bind9-9.20.15/bin/tests/system/zonechecks/ns2/named.conf.in 2025-10-18 10:16:12.523731684 +0000 @@ -23,10 +23,9 @@ listen-on-v6 { none; }; recursion no; notify yes; - dnssec-validation yes; + dnssec-validation no; }; -trust-anchors { }; key rndc_key { secret "1234abcd8765"; diff -Nru bind9-9.20.11/bin/tools/Makefile.in bind9-9.20.15/bin/tools/Makefile.in --- bind9-9.20.11/bin/tools/Makefile.in 2025-07-04 09:43:11.134809715 +0000 +++ bind9-9.20.15/bin/tools/Makefile.in 2025-10-18 10:17:04.349499545 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -396,8 +398,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -591,16 +595,11 @@ `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files + cd "$(DESTDIR)$(bindir)" && $(am__rm_f) $$files clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(bin_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(bin_PROGRAMS:$(EXEEXT)=) arpaname$(EXEEXT): $(arpaname_OBJECTS) $(arpaname_DEPENDENCIES) $(EXTRA_arpaname_DEPENDENCIES) @rm -f arpaname$(EXEEXT) @@ -646,7 +645,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -827,22 +826,22 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/arpaname.Po + -rm -f ./$(DEPDIR)/arpaname.Po -rm -f ./$(DEPDIR)/dnstap_read-dnstap-read.Po -rm -f ./$(DEPDIR)/mdig.Po -rm -f ./$(DEPDIR)/named-journalprint.Po @@ -898,7 +897,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/arpaname.Po + -rm -f ./$(DEPDIR)/arpaname.Po -rm -f ./$(DEPDIR)/dnstap_read-dnstap-read.Po -rm -f ./$(DEPDIR)/mdig.Po -rm -f ./$(DEPDIR)/named-journalprint.Po @@ -954,3 +953,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/compile bind9-9.20.15/compile --- bind9-9.20.11/compile 2025-07-04 09:43:10.566796479 +0000 +++ bind9-9.20.15/compile 2025-10-18 10:17:03.747490325 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2018-03-07.03; # UTC +scriptversion=2024-06-19.01; # UTC -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -143,7 +143,7 @@ # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in - *.o | *.[oO][bB][jJ]) + *.o | *.lo | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift @@ -248,14 +248,17 @@ right script to run: please start by reading the file 'INSTALL'. Report bugs to . +GNU Automake home page: . +General help using GNU software: . EOF exit $? ;; -v | --v*) - echo "compile $scriptversion" + echo "compile (GNU Automake) $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + clang-cl | *[/\\]clang-cl | clang-cl.exe | *[/\\]clang-cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; diff -Nru bind9-9.20.11/config.guess bind9-9.20.15/config.guess --- bind9-9.20.11/config.guess 2025-07-04 09:43:10.628797925 +0000 +++ bind9-9.20.15/config.guess 2025-10-18 10:17:03.840491754 +0000 @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2022-01-09' +timestamp='2024-07-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -47,7 +47,7 @@ usage="\ Usage: $0 [OPTION] -Output the configuration name of the system \`$me' is run on. +Output the configuration name of the system '$me' is run on. Options: -h, --help print this help, then exit @@ -60,13 +60,13 @@ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -102,8 +102,8 @@ # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. +# Historically, 'CC_FOR_BUILD' used to be named 'HOST_CC'. We still +# use 'HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. @@ -123,7 +123,7 @@ dummy=$tmp/dummy case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in ,,) echo "int x;" > "$dummy.c" - for driver in cc gcc c89 c99 ; do + for driver in cc gcc c17 c99 c89 ; do if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD=$driver break @@ -155,6 +155,9 @@ set_cc_for_build cat <<-EOF > "$dummy.c" + #if defined(__ANDROID__) + LIBC=android + #else #include #if defined(__UCLIBC__) LIBC=uclibc @@ -162,6 +165,8 @@ LIBC=dietlibc #elif defined(__GLIBC__) LIBC=gnu + #elif defined(__LLVM_LIBC__) + LIBC=llvm #else #include /* First heuristic to detect musl libc. */ @@ -169,6 +174,7 @@ LIBC=musl #endif #endif + #endif EOF cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` eval "$cc_set_libc" @@ -459,7 +465,7 @@ UNAME_RELEASE=`uname -v` ;; esac - # Japanese Language versions have a version number like `4.1.3-JL'. + # Japanese Language versions have a version number like '4.1.3-JL'. SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'` GUESS=sparc-sun-sunos$SUN_REL ;; @@ -628,7 +634,8 @@ sed 's/^ //' << EOF > "$dummy.c" #include - main() + int + main () { if (!__power_pc()) exit(1); @@ -712,7 +719,8 @@ #include #include - int main () + int + main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); @@ -904,7 +912,7 @@ fi ;; *:FreeBSD:*:*) - UNAME_PROCESSOR=`/usr/bin/uname -p` + UNAME_PROCESSOR=`uname -p` case $UNAME_PROCESSOR in amd64) UNAME_PROCESSOR=x86_64 ;; @@ -966,11 +974,37 @@ GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'` GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC ;; + x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-pc-managarm-mlibc" + ;; + *:[Mm]anagarm:*:*) + GUESS="$UNAME_MACHINE-unknown-managarm-mlibc" + ;; *:Minix:*:*) GUESS=$UNAME_MACHINE-unknown-minix ;; aarch64:Linux:*:*) - GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + set_cc_for_build + CPU=$UNAME_MACHINE + LIBCABI=$LIBC + if test "$CC_FOR_BUILD" != no_compiler_found; then + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __ARM_EABI__ + #ifdef __ARM_PCS_VFP + ABI=eabihf + #else + ABI=eabi + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + eabi | eabihf) CPU=armv8l; LIBCABI=$LIBC$ABI ;; + esac + fi + GUESS=$CPU-unknown-linux-$LIBCABI ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be @@ -1036,7 +1070,16 @@ k1om:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; - loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) + kvx:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; + kvx:cos:*:*) + GUESS=$UNAME_MACHINE-unknown-cos + ;; + kvx:mbr:*:*) + GUESS=$UNAME_MACHINE-unknown-mbr + ;; + loongarch32:Linux:*:* | loongarch64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; m32r*:Linux:*:*) @@ -1151,16 +1194,27 @@ ;; x86_64:Linux:*:*) set_cc_for_build + CPU=$UNAME_MACHINE LIBCABI=$LIBC if test "$CC_FOR_BUILD" != no_compiler_found; then - if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \ - (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_X32 >/dev/null - then - LIBCABI=${LIBC}x32 - fi + ABI=64 + sed 's/^ //' << EOF > "$dummy.c" + #ifdef __i386__ + ABI=x86 + #else + #ifdef __ILP32__ + ABI=x32 + #endif + #endif +EOF + cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'` + eval "$cc_set_abi" + case $ABI in + x86) CPU=i686 ;; + x32) LIBCABI=${LIBC}x32 ;; + esac fi - GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI + GUESS=$CPU-pc-linux-$LIBCABI ;; xtensa*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC @@ -1180,7 +1234,7 @@ GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION ;; i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility + # If we were able to find 'uname', then EMX Unix compatibility # is probably installed. GUESS=$UNAME_MACHINE-pc-os2-emx ;; @@ -1321,7 +1375,7 @@ GUESS=ns32k-sni-sysv fi ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + PENTIUM:*:4.0*:*) # Unisys 'ClearPath HMP IX 4000' SVR4/MP effort # says GUESS=i586-unisys-sysv4 ;; @@ -1367,8 +1421,11 @@ BePC:Haiku:*:*) # Haiku running on Intel PC compatible. GUESS=i586-pc-haiku ;; - x86_64:Haiku:*:*) - GUESS=x86_64-unknown-haiku + ppc:Haiku:*:*) # Haiku running on Apple PowerPC + GUESS=powerpc-apple-haiku + ;; + *:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat) + GUESS=$UNAME_MACHINE-unknown-haiku ;; SX-4:SUPER-UX:*:*) GUESS=sx4-nec-superux$UNAME_RELEASE @@ -1540,6 +1597,9 @@ *:Unleashed:*:*) GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; + *:Ironclad:*:*) + GUESS=$UNAME_MACHINE-unknown-ironclad + ;; esac # Do we have a guess based on uname results? @@ -1563,6 +1623,7 @@ #endif #endif #endif +int main () { #if defined (sony) diff -Nru bind9-9.20.11/config.h.in bind9-9.20.15/config.h.in --- bind9-9.20.11/config.h.in 2025-07-04 09:43:10.293790102 +0000 +++ bind9-9.20.15/config.h.in 2025-10-18 10:17:03.541487217 +0000 @@ -27,19 +27,22 @@ /* define if you want TCP_FASTOPEN enabled if available */ #undef ENABLE_TCP_FASTOPEN +/* Define to 1 if you have the 'arc4random' function. */ +#undef HAVE_ARC4RANDOM + /* define if the ARM yield instruction is available */ #undef HAVE_ARM_YIELD -/* Define to 1 if you have the `backtrace_symbols' function. */ +/* Define to 1 if you have the 'backtrace_symbols' function. */ #undef HAVE_BACKTRACE_SYMBOLS -/* Define to 1 if you have the `BIO_read_ex' function. */ +/* Define to 1 if you have the 'BIO_read_ex' function. */ #undef HAVE_BIO_READ_EX -/* Define to 1 if you have the `BIO_write_ex' function. */ +/* Define to 1 if you have the 'BIO_write_ex' function. */ #undef HAVE_BIO_WRITE_EX -/* Define to 1 if you have the `BN_GENCB_new' function. */ +/* Define to 1 if you have the 'BN_GENCB_new' function. */ #undef HAVE_BN_GENCB_NEW /* define if the compiler supports __builtin_add_overflow(). */ @@ -57,34 +60,34 @@ /* define if the compiler supports __builtin_unreachable(). */ #undef HAVE_BUILTIN_UNREACHABLE -/* Define to 1 if you have the `chroot' function. */ +/* Define to 1 if you have the 'chroot' function. */ #undef HAVE_CHROOT -/* Define to 1 if you have the `clock_gettime' function. */ +/* Define to 1 if you have the 'clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME /* Use CMocka */ #undef HAVE_CMOCKA -/* Define to 1 if you have the `cpuset_getaffinity' function. */ +/* Define to 1 if you have the 'cpuset_getaffinity' function. */ #undef HAVE_CPUSET_GETAFFINITY -/* Define to 1 if you have the `CRYPTO_zalloc' function. */ +/* Define to 1 if you have the 'CRYPTO_zalloc' function. */ #undef HAVE_CRYPTO_ZALLOC -/* Define to 1 if you have the declaration of `UV_UDP_LINUX_RECVERR', and to 0 +/* Define to 1 if you have the declaration of 'UV_UDP_LINUX_RECVERR', and to 0 if you don't. */ #undef HAVE_DECL_UV_UDP_LINUX_RECVERR -/* Define to 1 if you have the declaration of `UV_UDP_MMSG_CHUNK', and to 0 if +/* Define to 1 if you have the declaration of 'UV_UDP_MMSG_CHUNK', and to 0 if you don't. */ #undef HAVE_DECL_UV_UDP_MMSG_CHUNK -/* Define to 1 if you have the declaration of `UV_UDP_MMSG_FREE', and to 0 if +/* Define to 1 if you have the declaration of 'UV_UDP_MMSG_FREE', and to 0 if you don't. */ #undef HAVE_DECL_UV_UDP_MMSG_FREE -/* Define to 1 if you have the declaration of `UV_UDP_RECVMMSG', and to 0 if +/* Define to 1 if you have the declaration of 'UV_UDP_RECVMMSG', and to 0 if you don't. */ #undef HAVE_DECL_UV_UDP_RECVMMSG @@ -94,65 +97,65 @@ /* Define to 1 to enable dnstap support */ #undef HAVE_DNSTAP -/* Define to 1 if you have the `ECDSA_SIG_get0' function. */ +/* Define to 1 if you have the 'ECDSA_SIG_get0' function. */ #undef HAVE_ECDSA_SIG_GET0 -/* Define to 1 if you have the `ERR_get_error_all' function. */ +/* Define to 1 if you have the 'ERR_get_error_all' function. */ #undef HAVE_ERR_GET_ERROR_ALL -/* Define to 1 if you have the `EVP_CIPHER_CTX_free' function. */ +/* Define to 1 if you have the 'EVP_CIPHER_CTX_free' function. */ #undef HAVE_EVP_CIPHER_CTX_FREE -/* Define to 1 if you have the `EVP_CIPHER_CTX_new' function. */ +/* Define to 1 if you have the 'EVP_CIPHER_CTX_new' function. */ #undef HAVE_EVP_CIPHER_CTX_NEW -/* Define to 1 if you have the `EVP_default_properties_enable_fips' function. +/* Define to 1 if you have the 'EVP_default_properties_enable_fips' function. */ #undef HAVE_EVP_DEFAULT_PROPERTIES_ENABLE_FIPS -/* Define to 1 if you have the `EVP_DigestSignInit' function. */ +/* Define to 1 if you have the 'EVP_DigestSignInit' function. */ #undef HAVE_EVP_DIGESTSIGNINIT -/* Define to 1 if you have the `EVP_DigestVerifyInit' function. */ +/* Define to 1 if you have the 'EVP_DigestVerifyInit' function. */ #undef HAVE_EVP_DIGESTVERIFYINIT -/* Define to 1 if you have the `EVP_MD_CTX_free' function. */ +/* Define to 1 if you have the 'EVP_MD_CTX_free' function. */ #undef HAVE_EVP_MD_CTX_FREE -/* Define to 1 if you have the `EVP_MD_CTX_get0_md' function. */ +/* Define to 1 if you have the 'EVP_MD_CTX_get0_md' function. */ #undef HAVE_EVP_MD_CTX_GET0_MD -/* Define to 1 if you have the `EVP_MD_CTX_new' function. */ +/* Define to 1 if you have the 'EVP_MD_CTX_new' function. */ #undef HAVE_EVP_MD_CTX_NEW -/* Define to 1 if you have the `EVP_MD_CTX_reset' function. */ +/* Define to 1 if you have the 'EVP_MD_CTX_reset' function. */ #undef HAVE_EVP_MD_CTX_RESET -/* Define to 1 if you have the `EVP_PKEY_eq' function. */ +/* Define to 1 if you have the 'EVP_PKEY_eq' function. */ #undef HAVE_EVP_PKEY_EQ -/* Define to 1 if you have the `EVP_PKEY_get0_EC_KEY' function. */ +/* Define to 1 if you have the 'EVP_PKEY_get0_EC_KEY' function. */ #undef HAVE_EVP_PKEY_GET0_EC_KEY -/* Define to 1 if you have the `EVP_PKEY_get0_RSA' function. */ +/* Define to 1 if you have the 'EVP_PKEY_get0_RSA' function. */ #undef HAVE_EVP_PKEY_GET0_RSA -/* Define to 1 if you have the `EVP_PKEY_new_raw_private_key' function. */ +/* Define to 1 if you have the 'EVP_PKEY_new_raw_private_key' function. */ #undef HAVE_EVP_PKEY_NEW_RAW_PRIVATE_KEY -/* Define to 1 if you have the `EVP_sha1' function. */ +/* Define to 1 if you have the 'EVP_sha1' function. */ #undef HAVE_EVP_SHA1 -/* Define to 1 if you have the `EVP_sha224' function. */ +/* Define to 1 if you have the 'EVP_sha224' function. */ #undef HAVE_EVP_SHA224 -/* Define to 1 if you have the `EVP_sha256' function. */ +/* Define to 1 if you have the 'EVP_sha256' function. */ #undef HAVE_EVP_SHA256 -/* Define to 1 if you have the `EVP_sha384' function. */ +/* Define to 1 if you have the 'EVP_sha384' function. */ #undef HAVE_EVP_SHA384 -/* Define to 1 if you have the `EVP_sha512' function. */ +/* Define to 1 if you have the 'EVP_sha512' function. */ #undef HAVE_EVP_SHA512 /* Define to 1 if you have the header file. */ @@ -161,13 +164,13 @@ /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H -/* Define to 1 if you have the `FIPS_mode' function. */ +/* Define to 1 if you have the 'FIPS_mode' function. */ #undef HAVE_FIPS_MODE -/* Define to 1 if you have the `flockfile' function. */ +/* Define to 1 if you have the 'flockfile' function. */ #undef HAVE_FLOCKFILE -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +/* Define to 1 if fseeko (and ftello) are declared in stdio.h. */ #undef HAVE_FSEEKO /* Define to 1 if the system has the `constructor' function attribute */ @@ -188,7 +191,7 @@ /* Build with GeoIP2 support */ #undef HAVE_GEOIP2 -/* Define to 1 if you have the `getc_unlocked' function. */ +/* Define to 1 if you have the 'getc_unlocked' function. */ #undef HAVE_GETC_UNLOCKED /* Define to 1 if you have the header file. */ @@ -209,13 +212,13 @@ /* Define to 1 if you have the header file. */ #undef HAVE_GSSAPI_KRB5_H -/* Define to 1 if you have the `gss_acquire_cred' function. */ +/* Define to 1 if you have the 'gss_acquire_cred' function. */ #undef HAVE_GSS_ACQUIRE_CRED /* Define to 1 if you have the header file. */ #undef HAVE_IDN2_H -/* Define to 1 if you have the `if_nametoindex' function. */ +/* Define to 1 if you have the 'if_nametoindex' function. */ #undef HAVE_IF_NAMETOINDEX /* Define to 1 if you have the header file. */ @@ -233,7 +236,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_KRB5_H -/* Define to 1 if you have the `krb5_init_context' function. */ +/* Define to 1 if you have the 'krb5_init_context' function. */ #undef HAVE_KRB5_INIT_CONTEXT /* Define to 1 if you have the header file. */ @@ -275,7 +278,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_NET_ROUTE_H -/* Define to 1 if you have the `OPENSSL_cleanup' function. */ +/* Define to 1 if you have the 'OPENSSL_cleanup' function. */ #undef HAVE_OPENSSL_CLEANUP /* define if OpenSSL supports Ed25519 */ @@ -284,22 +287,22 @@ /* define if OpenSSL supports Ed448 */ #undef HAVE_OPENSSL_ED448 -/* Define to 1 if you have the `OPENSSL_init_crypto' function. */ +/* Define to 1 if you have the 'OPENSSL_init_crypto' function. */ #undef HAVE_OPENSSL_INIT_CRYPTO -/* Define to 1 if you have the `OPENSSL_init_ssl' function. */ +/* Define to 1 if you have the 'OPENSSL_init_ssl' function. */ #undef HAVE_OPENSSL_INIT_SSL /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD -/* Define to 1 if you have the `pthread_attr_getstacksize' function. */ +/* Define to 1 if you have the 'pthread_attr_getstacksize' function. */ #undef HAVE_PTHREAD_ATTR_GETSTACKSIZE -/* Define to 1 if you have the `pthread_attr_setstacksize' function. */ +/* Define to 1 if you have the 'pthread_attr_setstacksize' function. */ #undef HAVE_PTHREAD_ATTR_SETSTACKSIZE -/* Define to 1 if you have the `pthread_barrier_init' function. */ +/* Define to 1 if you have the 'pthread_barrier_init' function. */ #undef HAVE_PTHREAD_BARRIER_INIT /* Define to 1 if PTHREAD_MUTEX_ADAPTIVE_NP is available */ @@ -311,22 +314,22 @@ /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT -/* Define to 1 if you have the `pthread_rwlock_rdlock' function. */ +/* Define to 1 if you have the 'pthread_rwlock_rdlock' function. */ #undef HAVE_PTHREAD_RWLOCK_RDLOCK -/* Define to 1 if you have the `pthread_setname_np' function. */ +/* Define to 1 if you have the 'pthread_setname_np' function. */ #undef HAVE_PTHREAD_SETNAME_NP -/* Define to 1 if you have the `pthread_set_name_np' function. */ +/* Define to 1 if you have the 'pthread_set_name_np' function. */ #undef HAVE_PTHREAD_SET_NAME_NP -/* Define to 1 if you have the `pthread_spin_init' function. */ +/* Define to 1 if you have the 'pthread_spin_init' function. */ #undef HAVE_PTHREAD_SPIN_INIT -/* Define to 1 if you have the `pthread_yield' function. */ +/* Define to 1 if you have the 'pthread_yield' function. */ #undef HAVE_PTHREAD_YIELD -/* Define to 1 if you have the `pthread_yield_np' function. */ +/* Define to 1 if you have the 'pthread_yield_np' function. */ #undef HAVE_PTHREAD_YIELD_NP /* Build with editline support */ @@ -341,46 +344,46 @@ /* Define to 1 if you have the header file. */ #undef HAVE_REGEX_H -/* Define to 1 if you have the `RSA_set0_key' function. */ +/* Define to 1 if you have the 'RSA_set0_key' function. */ #undef HAVE_RSA_SET0_KEY -/* Define to 1 if you have the `sched_getaffinity' function. */ +/* Define to 1 if you have the 'sched_getaffinity' function. */ #undef HAVE_SCHED_GETAFFINITY /* Define to 1 if you have the header file. */ #undef HAVE_SCHED_H -/* Define to 1 if you have the `sched_yield' function. */ +/* Define to 1 if you have the 'sched_yield' function. */ #undef HAVE_SCHED_YIELD /* define if the SPARC pause instruction is available */ #undef HAVE_SPARC_PAUSE -/* Define to 1 if you have the `SSL_CTX_set1_cert_store' function. */ +/* Define to 1 if you have the 'SSL_CTX_set1_cert_store' function. */ #undef HAVE_SSL_CTX_SET1_CERT_STORE -/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */ +/* Define to 1 if you have the 'SSL_CTX_set_ciphersuites' function. */ #undef HAVE_SSL_CTX_SET_CIPHERSUITES -/* Define to 1 if you have the `SSL_CTX_set_keylog_callback' function. */ +/* Define to 1 if you have the 'SSL_CTX_set_keylog_callback' function. */ #undef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK -/* Define to 1 if you have the `SSL_CTX_set_min_proto_version' function. */ +/* Define to 1 if you have the 'SSL_CTX_set_min_proto_version' function. */ #undef HAVE_SSL_CTX_SET_MIN_PROTO_VERSION -/* Define to 1 if you have the `SSL_CTX_up_ref' function. */ +/* Define to 1 if you have the 'SSL_CTX_up_ref' function. */ #undef HAVE_SSL_CTX_UP_REF -/* Define to 1 if you have the `SSL_peek_ex' function. */ +/* Define to 1 if you have the 'SSL_peek_ex' function. */ #undef HAVE_SSL_PEEK_EX -/* Define to 1 if you have the `SSL_read_ex' function. */ +/* Define to 1 if you have the 'SSL_read_ex' function. */ #undef HAVE_SSL_READ_EX -/* Define to 1 if you have the `SSL_SESSION_is_resumable' function. */ +/* Define to 1 if you have the 'SSL_SESSION_is_resumable' function. */ #undef HAVE_SSL_SESSION_IS_RESUMABLE -/* Define to 1 if you have the `SSL_write_ex' function. */ +/* Define to 1 if you have the 'SSL_write_ex' function. */ #undef HAVE_SSL_WRITE_EX /* define if struct stat has st_mtim.tv_nsec field */ @@ -407,19 +410,19 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the `strlcat' function. */ +/* Define to 1 if you have the 'strlcat' function. */ #undef HAVE_STRLCAT -/* Define to 1 if you have the `strlcpy' function. */ +/* Define to 1 if you have the 'strlcpy' function. */ #undef HAVE_STRLCPY -/* Define to 1 if you have the `strnstr' function. */ +/* Define to 1 if you have the 'strnstr' function. */ #undef HAVE_STRNSTR -/* Define to 1 if you have the `sysconf' function. */ +/* Define to 1 if you have the 'sysconf' function. */ #undef HAVE_SYSCONF -/* Define to 1 if you have the `sysctlbyname' function. */ +/* Define to 1 if you have the 'sysctlbyname' function. */ #undef HAVE_SYSCTLBYNAME /* Define to 1 if you have the header file. */ @@ -458,19 +461,19 @@ /* Define to 1 if you have the header file. */ #undef HAVE_THREADS_H -/* Define to 1 if you have the `TLS_client_method' function. */ +/* Define to 1 if you have the 'TLS_client_method' function. */ #undef HAVE_TLS_CLIENT_METHOD -/* Define to 1 if you have the `TLS_server_method' function. */ +/* Define to 1 if you have the 'TLS_server_method' function. */ #undef HAVE_TLS_SERVER_METHOD -/* Define to 1 if you have the `tzset' function. */ +/* Define to 1 if you have the 'tzset' function. */ #undef HAVE_TZSET /* Define to 1 if you have the header file. */ #undef HAVE_UCHAR_H -/* Define to 1 if the system has the type `uintptr_t'. */ +/* Define to 1 if the system has the type 'uintptr_t'. */ #undef HAVE_UINTPTR_T /* define if uname is available */ @@ -482,7 +485,7 @@ /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H -/* Define to 1 if you have the `X509_STORE_up_ref' function. */ +/* Define to 1 if you have the 'X509_STORE_up_ref' function. */ #undef HAVE_X509_STORE_UP_REF /* Use zlib library */ @@ -568,7 +571,7 @@ /* Compile-time Userspace-RCU version */ #undef RCU_VERSION -/* Define to 1 if all of the C90 standard headers exist (not just the ones +/* Define to 1 if all of the C89 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS @@ -582,7 +585,7 @@ /* Define if you want to use pthread rwlock implementation */ #undef USE_PTHREAD_RWLOCK -/* Enable extensions on AIX 3, Interix. */ +/* Enable extensions on AIX, Interix, z/OS. */ #ifndef _ALL_SOURCE # undef _ALL_SOURCE #endif @@ -643,11 +646,15 @@ #ifndef __STDC_WANT_IEC_60559_DFP_EXT__ # undef __STDC_WANT_IEC_60559_DFP_EXT__ #endif +/* Enable extensions specified by C23 Annex F. */ +#ifndef __STDC_WANT_IEC_60559_EXT__ +# undef __STDC_WANT_IEC_60559_EXT__ +#endif /* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ #ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ # undef __STDC_WANT_IEC_60559_FUNCS_EXT__ #endif -/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */ #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ # undef __STDC_WANT_IEC_60559_TYPES_EXT__ #endif @@ -700,34 +707,40 @@ /* Number of bits in a file offset, on hosts where this is settable. */ #undef _FILE_OFFSET_BITS -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* Define to 1 if necessary to make fseeko visible. */ #undef _LARGEFILE_SOURCE -/* Define for large files, on AIX-style hosts. */ +/* Define to 1 on platforms where this makes off_t a 64-bit type. */ #undef _LARGE_FILES +/* Number of bits in time_t, on hosts where this is settable. */ +#undef _TIME_BITS + /* Select RFC3542 IPv6 API on macOS */ #undef __APPLE_USE_RFC_3542 -/* Define to empty if `const' does not conform to ANSI C. */ +/* Define to 1 on platforms where this makes time_t a 64-bit type. */ +#undef __MINGW_USE_VC2005_COMPAT + +/* Define to empty if 'const' does not conform to ANSI C. */ #undef const -/* Define to `__inline__' or `__inline' if that's what the C compiler +/* Define to '__inline__' or '__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif -/* Define to `unsigned int' if does not define. */ +/* Define as 'unsigned int' if doesn't define. */ #undef size_t -/* Define to `int' if does not define. */ +/* Define as 'int' if doesn't define. */ #undef ssize_t /* Define to the type of an unsigned integer type wide enough to hold a pointer, if such a type exists, and if the system does not define it. */ #undef uintptr_t -/* Define to empty if the keyword `volatile' does not work. Warning: valid - code using `volatile' can become incorrect without. Disable with care. */ +/* Define to empty if the keyword 'volatile' does not work. Warning: valid + code using 'volatile' can become incorrect without. Disable with care. */ #undef volatile diff -Nru bind9-9.20.11/config.sub bind9-9.20.15/config.sub --- bind9-9.20.11/config.sub 2025-07-04 09:43:10.631797995 +0000 +++ bind9-9.20.15/config.sub 2025-10-18 10:17:03.843491799 +0000 @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2022 Free Software Foundation, Inc. +# Copyright 1992-2024 Free Software Foundation, Inc. -# shellcheck disable=SC2006,SC2268 # see below for rationale +# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale -timestamp='2022-01-03' +timestamp='2024-05-27' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,13 +76,13 @@ version="\ GNU config.sub ($timestamp) -Copyright 1992-2022 Free Software Foundation, Inc. +Copyright 1992-2024 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" -Try \`$me --help' for more information." +Try '$me --help' for more information." # Parse command line while test $# -gt 0 ; do @@ -120,7 +120,6 @@ esac # Split fields of configuration type -# shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read field1 field2 field3 field4 <&2 + echo "Invalid configuration '$1': more than four components" >&2 exit 1 ;; *-*-*-*) @@ -142,10 +141,21 @@ # parts maybe_os=$field2-$field3 case $maybe_os in - nto-qnx* | linux-* | uclinux-uclibc* \ - | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \ - | netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \ - | storm-chaos* | os2-emx* | rtmk-nova*) + cloudabi*-eabi* \ + | kfreebsd*-gnu* \ + | knetbsd*-gnu* \ + | kopensolaris*-gnu* \ + | linux-* \ + | managarm-* \ + | netbsd*-eabi* \ + | netbsd*-gnu* \ + | nto-qnx* \ + | os2-emx* \ + | rtmk-nova* \ + | storm-chaos* \ + | uclinux-gnu* \ + | uclinux-uclibc* \ + | windows-* ) basic_machine=$field1 basic_os=$maybe_os ;; @@ -160,8 +170,12 @@ esac ;; *-*) - # A lone config we happen to match not fitting any pattern case $field1-$field2 in + # Shorthands that happen to contain a single dash + convex-c[12] | convex-c3[248]) + basic_machine=$field2-convex + basic_os= + ;; decstation-3100) basic_machine=mips-dec basic_os= @@ -169,28 +183,88 @@ *-*) # Second component is usually, but not always the OS case $field2 in - # Prevent following clause from handling this valid os + # Do not treat sunos as a manufacturer sun*os*) basic_machine=$field1 basic_os=$field2 ;; - zephyr*) - basic_machine=$field1-unknown - basic_os=$field2 - ;; # Manufacturers - dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \ - | att* | 7300* | 3300* | delta* | motorola* | sun[234]* \ - | unicom* | ibm* | next | hp | isi* | apollo | altos* \ - | convergent* | ncr* | news | 32* | 3600* | 3100* \ - | hitachi* | c[123]* | convex* | sun | crds | omron* | dg \ - | ultra | tti* | harris | dolphin | highlevel | gould \ - | cbm | ns | masscomp | apple | axis | knuth | cray \ - | microblaze* | sim | cisco \ - | oki | wec | wrs | winbond) + 3100* \ + | 32* \ + | 3300* \ + | 3600* \ + | 7300* \ + | acorn \ + | altos* \ + | apollo \ + | apple \ + | atari \ + | att* \ + | axis \ + | be \ + | bull \ + | cbm \ + | ccur \ + | cisco \ + | commodore \ + | convergent* \ + | convex* \ + | cray \ + | crds \ + | dec* \ + | delta* \ + | dg \ + | digital \ + | dolphin \ + | encore* \ + | gould \ + | harris \ + | highlevel \ + | hitachi* \ + | hp \ + | ibm* \ + | intergraph \ + | isi* \ + | knuth \ + | masscomp \ + | microblaze* \ + | mips* \ + | motorola* \ + | ncr* \ + | news \ + | next \ + | ns \ + | oki \ + | omron* \ + | pc533* \ + | rebel \ + | rom68k \ + | rombug \ + | semi \ + | sequent* \ + | siemens \ + | sgi* \ + | siemens \ + | sim \ + | sni \ + | sony* \ + | stratus \ + | sun \ + | sun[234]* \ + | tektronix \ + | tti* \ + | ultra \ + | unicom* \ + | wec \ + | winbond \ + | wrs) basic_machine=$field1-$field2 basic_os= ;; + zephyr*) + basic_machine=$field1-unknown + basic_os=$field2 + ;; *) basic_machine=$field1 basic_os=$field2 @@ -271,26 +345,6 @@ basic_machine=arm-unknown basic_os=cegcc ;; - convex-c1) - basic_machine=c1-convex - basic_os=bsd - ;; - convex-c2) - basic_machine=c2-convex - basic_os=bsd - ;; - convex-c32) - basic_machine=c32-convex - basic_os=bsd - ;; - convex-c34) - basic_machine=c34-convex - basic_os=bsd - ;; - convex-c38) - basic_machine=c38-convex - basic_os=bsd - ;; cray) basic_machine=j90-cray basic_os=unicos @@ -713,15 +767,26 @@ vendor=dec basic_os=tops20 ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) + delta | 3300 | delta-motorola | 3300-motorola | motorola-delta | motorola-3300) cpu=m68k vendor=motorola ;; - dpx2*) + # This used to be dpx2*, but that gets the RS6000-based + # DPX/20 and the x86-based DPX/2-100 wrong. See + # https://oldskool.silicium.org/stations/bull_dpx20.htm + # https://www.feb-patrimoine.com/english/bull_dpx2.htm + # https://www.feb-patrimoine.com/english/unix_and_bull.htm + dpx2 | dpx2[23]00 | dpx2[23]xx) cpu=m68k vendor=bull - basic_os=sysv3 + ;; + dpx2100 | dpx21xx) + cpu=i386 + vendor=bull + ;; + dpx20) + cpu=rs6000 + vendor=bull ;; encore | umax | mmax) cpu=ns32k @@ -836,18 +901,6 @@ next | m*-next) cpu=m68k vendor=next - case $basic_os in - openstep*) - ;; - nextstep*) - ;; - ns2*) - basic_os=nextstep2 - ;; - *) - basic_os=nextstep3 - ;; - esac ;; np1) cpu=np1 @@ -936,14 +989,13 @@ ;; *-*) - # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read cpu vendor <&2 + echo "Invalid configuration '$1': machine '$cpu-$vendor' not recognized" 1>&2 exit 1 ;; esac @@ -1306,11 +1491,12 @@ # Decode manufacturer-specific aliases for certain operating systems. -if test x$basic_os != x +if test x"$basic_os" != x then # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just # set os. +obj= case $basic_os in gnu/linux*) kernel=linux @@ -1325,7 +1511,6 @@ os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'` ;; *-*) - # shellcheck disable=SC2162 saved_IFS=$IFS IFS="-" read kernel os <&2 + fi + ;; *) - echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2 + echo "Invalid configuration '$1': OS '$os' not recognized" 1>&2 + exit 1 + ;; +esac + +case $obj in + aout* | coff* | elf* | pe*) + ;; + '') + # empty is fine + ;; + *) + echo "Invalid configuration '$1': Machine code format '$obj' not recognized" 1>&2 + exit 1 + ;; +esac + +# Here we handle the constraint that a (synthetic) cpu and os are +# valid only in combination with each other and nowhere else. +case $cpu-$os in + # The "javascript-unknown-ghcjs" triple is used by GHC; we + # accept it here in order to tolerate that, but reject any + # variations. + javascript-ghcjs) + ;; + javascript-* | *-ghcjs) + echo "Invalid configuration '$1': cpu '$cpu' is not valid with os '$os$obj'" 1>&2 exit 1 ;; esac # As a final step for OS-related things, validate the OS-kernel combination # (given a valid OS), if there is a kernel. -case $kernel-$os in - linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \ - | linux-musl* | linux-relibc* | linux-uclibc* ) +case $kernel-$os-$obj in + linux-gnu*- | linux-android*- | linux-dietlibc*- | linux-llvm*- \ + | linux-mlibc*- | linux-musl*- | linux-newlib*- \ + | linux-relibc*- | linux-uclibc*- | linux-ohos*- ) + ;; + uclinux-uclibc*- | uclinux-gnu*- ) + ;; + managarm-mlibc*- | managarm-kernel*- ) ;; - uclinux-uclibc* ) + windows*-msvc*-) ;; - -dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* ) + -dietlibc*- | -llvm*- | -mlibc*- | -musl*- | -newlib*- | -relibc*- \ + | -uclibc*- ) # These are just libc implementations, not actual OSes, and thus # require a kernel. - echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2 + echo "Invalid configuration '$1': libc '$os' needs explicit kernel." 1>&2 exit 1 ;; - kfreebsd*-gnu* | kopensolaris*-gnu*) + -kernel*- ) + echo "Invalid configuration '$1': '$os' needs explicit kernel." 1>&2 + exit 1 ;; - vxworks-simlinux | vxworks-simwindows | vxworks-spe) + *-kernel*- ) + echo "Invalid configuration '$1': '$kernel' does not support '$os'." 1>&2 + exit 1 ;; - nto-qnx*) + *-msvc*- ) + echo "Invalid configuration '$1': '$os' needs 'windows'." 1>&2 + exit 1 ;; - os2-emx) + kfreebsd*-gnu*- | knetbsd*-gnu*- | netbsd*-gnu*- | kopensolaris*-gnu*-) + ;; + vxworks-simlinux- | vxworks-simwindows- | vxworks-spe-) + ;; + nto-qnx*-) ;; - *-eabi* | *-gnueabi*) + os2-emx-) ;; - -*) + rtmk-nova-) + ;; + *-eabi*- | *-gnueabi*-) + ;; + none--*) + # None (no kernel, i.e. freestanding / bare metal), + # can be paired with an machine code file format + ;; + -*-) # Blank kernel with real OS is always fine. ;; - *-*) - echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2 + --*) + # Blank kernel and OS with real machine code file format is always fine. + ;; + *-*-*) + echo "Invalid configuration '$1': Kernel '$kernel' not known to work with OS '$os'." 1>&2 exit 1 ;; esac @@ -1809,7 +2273,7 @@ *-riscix*) vendor=acorn ;; - *-sunos*) + *-sunos* | *-solaris*) vendor=sun ;; *-cnk* | *-aix*) @@ -1879,7 +2343,7 @@ ;; esac -echo "$cpu-$vendor-${kernel:+$kernel-}$os" +echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}" exit # Local variables: diff -Nru bind9-9.20.11/configure bind9-9.20.15/configure --- bind9-9.20.11/configure 2025-07-04 09:43:09.853779863 +0000 +++ bind9-9.20.15/configure 2025-10-18 10:17:03.105480997 +0000 @@ -1,11 +1,11 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for BIND 9.20.11. +# Generated by GNU Autoconf 2.72 for BIND 9.20.15. # # Report bugs to . # # -# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, +# Copyright (C) 1992-1996, 1998-2017, 2020-2023 Free Software Foundation, # Inc. # # @@ -17,7 +17,6 @@ # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh @@ -26,12 +25,13 @@ # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( +else case e in #( + e) case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi @@ -103,7 +103,7 @@ ;; esac -# We did not find ourselves, most probably we were run as `sh COMMAND' +# We did not find ourselves, most probably we were run as 'sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 @@ -133,15 +133,14 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. +# out after a failed 'exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="as_nop=: -if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 + as_bourne_compatible="if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: @@ -149,12 +148,13 @@ # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST -else \$as_nop - case \`(set -o) 2>/dev/null\` in #( +else case e in #( + e) case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi " @@ -172,8 +172,9 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : -else \$as_nop - exitcode=1; echo positional parameters were not saved. +else case e in #( + e) exitcode=1; echo positional parameters were not saved. ;; +esac fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) @@ -195,14 +196,15 @@ if (eval "$as_required") 2>/dev/null then : as_have_required=yes -else $as_nop - as_have_required=no +else case e in #( + e) as_have_required=no ;; +esac fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do @@ -235,12 +237,13 @@ if $as_found then : -else $as_nop - if { test -f "$SHELL" || test -f "$SHELL.exe"; } && +else case e in #( + e) if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes -fi +fi ;; +esac fi @@ -262,7 +265,7 @@ esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. +# out after a failed 'exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi @@ -283,7 +286,8 @@ $0: have one." fi exit 1 -fi +fi ;; +esac fi fi SHELL=${CONFIG_SHELL-/bin/sh} @@ -322,14 +326,6 @@ as_fn_set_status $1 exit $1 } # as_fn_exit -# as_fn_nop -# --------- -# Do nothing but, unlike ":", preserve the value of $?. -as_fn_nop () -{ - return $? -} -as_nop=as_fn_nop # as_fn_mkdir_p # ------------- @@ -398,11 +394,12 @@ { eval $1+=\$2 }' -else $as_nop - as_fn_append () +else case e in #( + e) as_fn_append () { eval $1=\$$1\$2 - } + } ;; +esac fi # as_fn_append # as_fn_arith ARG... @@ -416,21 +413,14 @@ { as_val=$(( $* )) }' -else $as_nop - as_fn_arith () +else case e in #( + e) as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` - } + } ;; +esac fi # as_fn_arith -# as_fn_nop -# --------- -# Do nothing but, unlike ":", preserve the value of $?. -as_fn_nop () -{ - return $? -} -as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- @@ -504,6 +494,8 @@ /[$]LINENO/= ' <$as_myself | sed ' + t clear + :clear s/[$]LINENO.*/&-/ t lineno b @@ -552,7 +544,6 @@ as_echo='printf %s\n' as_echo_n='printf %s' - rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file @@ -564,9 +555,9 @@ if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then @@ -591,10 +582,12 @@ as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated # Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated SHELL=${CONFIG_SHELL-/bin/sh} @@ -622,8 +615,8 @@ # Identity of this package. PACKAGE_NAME='BIND' PACKAGE_TARNAME='bind' -PACKAGE_VERSION='9.20.11' -PACKAGE_STRING='BIND 9.20.11' +PACKAGE_VERSION='9.20.15' +PACKAGE_STRING='BIND 9.20.15' PACKAGE_BUGREPORT='https://gitlab.isc.org/isc-projects/bind9/-/issues/new?issuable_template=Bug' PACKAGE_URL='https://www.isc.org/downloads/' @@ -660,6 +653,8 @@ #endif" ac_header_c_list= +ac_func_c_list= +enable_year2038=no ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS @@ -834,6 +829,8 @@ MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE +am__xargs_n +am__rm_f_notfound AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V @@ -924,9 +921,11 @@ enable_dependency_tracking enable_largefile enable_static +enable_pic with_pic enable_shared enable_fast_install +enable_aix_soname with_aix_soname with_gnu_ld with_sysroot @@ -969,6 +968,7 @@ enable_tracing with_zonedb with_cachedb +enable_year2038 enable_full_report ' ac_precious_vars='build_alias @@ -1130,7 +1130,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: \`$ac_useropt'" + as_fn_error $? "invalid feature name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1156,7 +1156,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: \`$ac_useropt'" + as_fn_error $? "invalid feature name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1369,7 +1369,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: \`$ac_useropt'" + as_fn_error $? "invalid package name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1385,7 +1385,7 @@ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: \`$ac_useropt'" + as_fn_error $? "invalid package name: '$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in @@ -1415,8 +1415,8 @@ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" + -*) as_fn_error $? "unrecognized option: '$ac_option' +Try '$0 --help' for more information" ;; *=*) @@ -1424,7 +1424,7 @@ # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + as_fn_error $? "invalid variable name: '$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; @@ -1474,7 +1474,7 @@ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done -# There might be people who depend on the old broken behavior: `$host' +# There might be people who depend on the old broken behavior: '$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias @@ -1542,7 +1542,7 @@ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_msg="sources are in $srcdir, but 'cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` @@ -1570,7 +1570,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures BIND 9.20.11 to adapt to many kinds of systems. +'configure' configures BIND 9.20.15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1584,11 +1584,11 @@ --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages + -q, --quiet, --silent do not print 'checking ...' messages --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' + -C, --config-cache alias for '--cache-file=config.cache' -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] + --srcdir=DIR find the sources in DIR [configure dir or '..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX @@ -1596,10 +1596,10 @@ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. +By default, 'make install' will install all the files in +'$ac_default_prefix/bin', '$ac_default_prefix/lib' etc. You can specify +an installation prefix other than '$ac_default_prefix' using '--prefix', +for instance '--prefix=\$HOME'. For better control, use the options below. @@ -1642,7 +1642,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of BIND 9.20.11:";; + short | recursive ) echo "Configuration of BIND 9.20.15:";; esac cat <<\_ACEOF @@ -1661,9 +1661,14 @@ speeds up one-time build --disable-largefile omit support for large files --enable-static[=PKGS] build static libraries [default=no] + --enable-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] --enable-shared[=PKGS] build shared libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] + --enable-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. --disable-libtool-lock avoid locking (might break parallel builds) --enable-developer enable developer build settings --enable-warn-error turn on -Werror when compiling @@ -1693,16 +1698,12 @@ [default=yes] --enable-dnsrps enable DNS Response Policy Service API --enable-tracing enable User Statically Defined Tracing + --enable-year2038 support timestamps after 2038 --enable-full-report report values of all configure options Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use - both] - --with-aix-soname=aix|svr4|both - shared library versioning (aka "SONAME") variant to - provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). @@ -1823,7 +1824,7 @@ DTRACE path to dtrace binary used to build User Statically Defined Tracing probes -Use these variables to override the choices made by `configure' or to help +Use these variables to override the choices made by 'configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to . @@ -1891,10 +1892,10 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -BIND configure 9.20.11 -generated by GNU Autoconf 2.71 +BIND configure 9.20.15 +generated by GNU Autoconf 2.72 -Copyright (C) 2021 Free Software Foundation, Inc. +Copyright (C) 2023 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1933,11 +1934,12 @@ } && test -s conftest.$ac_objext then : ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 ;; +esac fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval @@ -1956,8 +1958,8 @@ if eval test \${$3+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> @@ -1965,10 +1967,12 @@ if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" -else $as_nop - eval "$3=no" +else case e in #( + e) eval "$3=no" ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 @@ -2004,59 +2008,17 @@ } then : ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that -# executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; + ac_retval=1 ;; esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; } -then : - ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: program exited with status $ac_status" >&5 - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval -} # ac_fn_c_try_run +} # ac_fn_c_try_cpp # ac_fn_c_try_link LINENO # ----------------------- @@ -2089,11 +2051,12 @@ } then : ac_retval=0 -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_retval=1 + ac_retval=1 ;; +esac fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would @@ -2105,6 +2068,50 @@ } # ac_fn_c_try_link +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status ;; +esac +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly @@ -2116,15 +2123,15 @@ if eval test \${$3+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. */ + which can conflict with char $2 (void); below. */ #include #undef $2 @@ -2135,7 +2142,7 @@ #ifdef __cplusplus extern "C" #endif -char $2 (); +char $2 (void); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ @@ -2154,11 +2161,13 @@ if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" -else $as_nop - eval "$3=no" +else case e in #( + e) eval "$3=no" ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext + conftest$ac_exeext conftest.$ac_ext ;; +esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 @@ -2179,8 +2188,8 @@ if eval test \${$3+y} then : printf %s "(cached) " >&6 -else $as_nop - eval "$3=no" +else case e in #( + e) eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 @@ -2210,12 +2219,14 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - eval "$3=yes" +else case e in #( + e) eval "$3=yes" ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 @@ -2237,8 +2248,8 @@ if eval test \${$3+y} then : printf %s "(cached) " >&6 -else $as_nop - as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` +else case e in #( + e) as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` eval ac_save_FLAGS=\$$6 as_fn_append $6 " $5" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -2262,12 +2273,14 @@ if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" -else $as_nop - eval "$3=no" +else case e in #( + e) eval "$3=no" ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext eval $6=\$ac_save_FLAGS - + ;; +esac fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 @@ -2299,8 +2312,8 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by BIND $as_me 9.20.11, which was -generated by GNU Autoconf 2.71. Invocation command line was +It was created by BIND $as_me 9.20.15, which was +generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -2546,10 +2559,10 @@ printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ - || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } fi done @@ -2586,9 +2599,7 @@ /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; +static char *e (char **p, int i) { return p[i]; } @@ -2602,6 +2613,21 @@ return s; } +/* C89 style stringification. */ +#define noexpand_stringify(a) #a +const char *stringified = noexpand_stringify(arbitrary+token=sequence); + +/* C89 style token pasting. Exercises some of the corner cases that + e.g. old MSVC gets wrong, but not very hard. */ +#define noexpand_concat(a,b) a##b +#define expand_concat(a,b) noexpand_concat(a,b) +extern int vA; +extern int vbee; +#define aye A +#define bee B +int *pvA = &expand_concat(v,aye); +int *pvbee = &noexpand_concat(v,bee); + /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated @@ -2629,16 +2655,19 @@ # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' -// Does the compiler advertise C99 conformance? +/* Does the compiler advertise C99 conformance? */ #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif +// See if C++-style comments work. + #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); +extern void free (void *); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare @@ -2688,7 +2717,6 @@ static inline int test_restrict (ccp restrict text) { - // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) @@ -2754,6 +2782,8 @@ ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; + // Work around memory leak warnings. + free (ia); // Check named initializers. struct named_init ni = { @@ -2775,7 +2805,7 @@ # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' -// Does the compiler advertise C11 conformance? +/* Does the compiler advertise C11 conformance? */ #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif @@ -2889,6 +2919,7 @@ as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" as_fn_append ac_header_c_list " wchar.h wchar_h HAVE_WCHAR_H" as_fn_append ac_header_c_list " minix/config.h minix_config_h HAVE_MINIX_CONFIG_H" +as_fn_append ac_func_c_list " arc4random HAVE_ARC4RANDOM" # Auxiliary files required by this configure script. ac_aux_files="ltmain.sh ar-lib compile missing install-sh config.guess config.sub" @@ -2968,8 +2999,9 @@ if $as_found then : -else $as_nop - as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 ;; +esac fi @@ -2997,12 +3029,12 @@ eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was set to '$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' was not set in the previous run" >&5 +printf "%s\n" "$as_me: error: '$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) @@ -3011,18 +3043,18 @@ ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: '$ac_var' has changed since the previous run:" >&5 +printf "%s\n" "$as_me: error: '$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&5 +printf "%s\n" "$as_me: warning: ignoring whitespace changes in '$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: '$ac_old_val'" >&5 +printf "%s\n" "$as_me: former value: '$ac_old_val'" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: '$ac_new_val'" >&5 +printf "%s\n" "$as_me: current value: '$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. @@ -3038,11 +3070,11 @@ fi done if $ac_cache_corrupted; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' + as_fn_error $? "run '${MAKE-make} distclean' and/or 'rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## @@ -3065,7 +3097,7 @@ printf "%s\n" "#define PACKAGE_VERSION_MINOR \"20\"" >>confdefs.h -printf "%s\n" "#define PACKAGE_VERSION_PATCH \"11\"" >>confdefs.h +printf "%s\n" "#define PACKAGE_VERSION_PATCH \"15\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION_EXTRA \"\"" >>confdefs.h @@ -3074,7 +3106,7 @@ printf "%s\n" "#define PACKAGE_DESCRIPTION \" (Stable Release)\"" >>confdefs.h -printf "%s\n" "#define PACKAGE_SRCID \"c6b2e31\"" >>confdefs.h +printf "%s\n" "#define PACKAGE_SRCID \"0c0fcf7\"" >>confdefs.h bind_CONFIGARGS="${ac_configure_args:-default}" @@ -3101,15 +3133,16 @@ if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_build_alias=$build_alias +else case e in #( + e) ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } @@ -3136,14 +3169,15 @@ if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 -else $as_nop - if test "x$host_alias" = x; then +else case e in #( + e) if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } @@ -3170,14 +3204,15 @@ if test ${ac_cv_target+y} then : printf %s "(cached) " >&6 -else $as_nop - if test "x$target_alias" = x; then +else case e in #( + e) if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "${ac_aux_dir}config.sub" $target_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $target_alias failed" "$LINENO" 5 fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 printf "%s\n" "$ac_cv_target" >&6; } @@ -3207,7 +3242,7 @@ program_prefix=${target_alias}- -am__api_version='1.16' +am__api_version='1.17' # Find a good install program. We prefer a C program (faster), @@ -3230,8 +3265,8 @@ if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS @@ -3285,7 +3320,8 @@ IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir - + ;; +esac fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install @@ -3308,6 +3344,165 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether sleep supports fractional seconds" >&5 +printf %s "checking whether sleep supports fractional seconds... " >&6; } +if test ${am_cv_sleep_fractional_seconds+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if sleep 0.001 2>/dev/null +then : + am_cv_sleep_fractional_seconds=yes +else case e in #( + e) am_cv_sleep_fractional_seconds=no ;; +esac +fi + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_sleep_fractional_seconds" >&5 +printf "%s\n" "$am_cv_sleep_fractional_seconds" >&6; } + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking filesystem timestamp resolution" >&5 +printf %s "checking filesystem timestamp resolution... " >&6; } +if test ${am_cv_filesystem_timestamp_resolution+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) # Default to the worst case. +am_cv_filesystem_timestamp_resolution=2 + +# Only try to go finer than 1 sec if sleep can do it. +# Don't try 1 sec, because if 0.01 sec and 0.1 sec don't work, +# - 1 sec is not much of a win compared to 2 sec, and +# - it takes 2 seconds to perform the test whether 1 sec works. +# +# Instead, just use the default 2s on platforms that have 1s resolution, +# accept the extra 1s delay when using $sleep in the Automake tests, in +# exchange for not incurring the 2s delay for running the test for all +# packages. +# +am_try_resolutions= +if test "$am_cv_sleep_fractional_seconds" = yes; then + # Even a millisecond often causes a bunch of false positives, + # so just try a hundredth of a second. The time saved between .001 and + # .01 is not terribly consequential. + am_try_resolutions="0.01 0.1 $am_try_resolutions" +fi + +# In order to catch current-generation FAT out, we must *modify* files +# that already exist; the *creation* timestamp is finer. Use names +# that make ls -t sort them differently when they have equal +# timestamps than when they have distinct timestamps, keeping +# in mind that ls -t prints the *newest* file first. +rm -f conftest.ts? +: > conftest.ts1 +: > conftest.ts2 +: > conftest.ts3 + +# Make sure ls -t actually works. Do 'set' in a subshell so we don't +# clobber the current shell's arguments. (Outer-level square brackets +# are removed by m4; they're present so that m4 does not expand +# ; be careful, easy to get confused.) +if ( + set X `ls -t conftest.ts[12]` && + { + test "$*" != "X conftest.ts1 conftest.ts2" || + test "$*" != "X conftest.ts2 conftest.ts1"; + } +); then :; else + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + printf "%s\n" ""Bad output from ls -t: \"`ls -t conftest.ts[12]`\""" >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "ls -t produces unexpected output. +Make sure there is not a broken ls alias in your environment. +See 'config.log' for more details" "$LINENO" 5; } +fi + +for am_try_res in $am_try_resolutions; do + # Any one fine-grained sleep might happen to cross the boundary + # between two values of a coarser actual resolution, but if we do + # two fine-grained sleeps in a row, at least one of them will fall + # entirely within a coarse interval. + echo alpha > conftest.ts1 + sleep $am_try_res + echo beta > conftest.ts2 + sleep $am_try_res + echo gamma > conftest.ts3 + + # We assume that 'ls -t' will make use of high-resolution + # timestamps if the operating system supports them at all. + if (set X `ls -t conftest.ts?` && + test "$2" = conftest.ts3 && + test "$3" = conftest.ts2 && + test "$4" = conftest.ts1); then + # + # Ok, ls -t worked. If we're at a resolution of 1 second, we're done, + # because we don't need to test make. + make_ok=true + if test $am_try_res != 1; then + # But if we've succeeded so far with a subsecond resolution, we + # have one more thing to check: make. It can happen that + # everything else supports the subsecond mtimes, but make doesn't; + # notably on macOS, which ships make 3.81 from 2006 (the last one + # released under GPLv2). https://bugs.gnu.org/68808 + # + # We test $MAKE if it is defined in the environment, else "make". + # It might get overridden later, but our hope is that in practice + # it does not matter: it is the system "make" which is (by far) + # the most likely to be broken, whereas if the user overrides it, + # probably they did so with a better, or at least not worse, make. + # https://lists.gnu.org/archive/html/automake/2024-06/msg00051.html + # + # Create a Makefile (real tab character here): + rm -f conftest.mk + echo 'conftest.ts1: conftest.ts2' >conftest.mk + echo ' touch conftest.ts2' >>conftest.mk + # + # Now, running + # touch conftest.ts1; touch conftest.ts2; make + # should touch ts1 because ts2 is newer. This could happen by luck, + # but most often, it will fail if make's support is insufficient. So + # test for several consecutive successes. + # + # (We reuse conftest.ts[12] because we still want to modify existing + # files, not create new ones, per above.) + n=0 + make=${MAKE-make} + until test $n -eq 3; do + echo one > conftest.ts1 + sleep $am_try_res + echo two > conftest.ts2 # ts2 should now be newer than ts1 + if $make -f conftest.mk | grep 'up to date' >/dev/null; then + make_ok=false + break # out of $n loop + fi + n=`expr $n + 1` + done + fi + # + if $make_ok; then + # Everything we know to check worked out, so call this resolution good. + am_cv_filesystem_timestamp_resolution=$am_try_res + break # out of $am_try_res loop + fi + # Otherwise, we'll go on to check the next resolution. + fi +done +rm -f conftest.ts? +# (end _am_filesystem_timestamp_resolution) + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_filesystem_timestamp_resolution" >&5 +printf "%s\n" "$am_cv_filesystem_timestamp_resolution" >&6; } + +# This check should not be cached, as it may vary across builds of +# different projects. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory @@ -3328,49 +3523,45 @@ # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then +am_build_env_is_sane=no +am_has_slept=no +rm -f conftest.file +for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + test "$2" = conftest.file + ); then + am_build_env_is_sane=yes + break + fi + # Just in case. + sleep "$am_cv_filesystem_timestamp_resolution" + am_has_slept=yes +done - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_build_env_is_sane" >&5 +printf "%s\n" "$am_build_env_is_sane" >&6; } +if test "$am_build_env_is_sane" = no; then + as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } + # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & +if test -e conftest.file || grep 'slept: no' conftest.file >/dev/null 2>&1 +then : + +else case e in #( + e) ( sleep "$am_cv_filesystem_timestamp_resolution" ) & am_sleep_pid=$! + ;; +esac fi rm -f conftest.file @@ -3381,7 +3572,7 @@ test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. -# By default was `s,x,x', remove it if useless. +# By default was 's,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` @@ -3424,8 +3615,8 @@ if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$STRIP"; then +else case e in #( + e) if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -3447,7 +3638,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then @@ -3469,8 +3661,8 @@ if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_STRIP"; then +else case e in #( + e) if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -3492,7 +3684,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then @@ -3528,8 +3721,8 @@ if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 -else $as_nop - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +else case e in #( + e) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS @@ -3543,7 +3736,7 @@ as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ - 'BusyBox '* | \ + *'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; @@ -3552,18 +3745,17 @@ done done IFS=$as_save_IFS - + ;; +esac fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" + # As a last resort, use plain mkdir -p, + # in the hope it doesn't have the bugs of ancient mkdir. + MKDIR_P='mkdir -p' fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 @@ -3578,8 +3770,8 @@ if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$AWK"; then +else case e in #( + e) if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -3601,7 +3793,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then @@ -3623,8 +3816,8 @@ if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 -else $as_nop - cat >conftest.make <<\_ACEOF +else case e in #( + e) cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' @@ -3636,7 +3829,8 @@ *) eval ac_cv_prog_make_${ac_make}_set=no;; esac -rm -f conftest.make +rm -f conftest.make ;; +esac fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -3657,25 +3851,21 @@ fi rmdir .tst 2>/dev/null +AM_DEFAULT_VERBOSITY=1 # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 -else $as_nop - if printf "%s\n" 'TRUE=$(BAR$(V)) +else case e in #( + e) if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 @@ -3685,19 +3875,50 @@ am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no -fi +fi ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi AM_BACKSLASH='\' +am__rm_f_notfound= +if (rm -f && rm -fr && rm -rf) 2>/dev/null +then : + +else case e in #( + e) am__rm_f_notfound='""' ;; +esac +fi + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking xargs -n works" >&5 +printf %s "checking xargs -n works... " >&6; } +if test ${am_cv_xargs_n_works+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test "`echo 1 2 3 | xargs -n2 echo`" = "1 2 +3" +then : + am_cv_xargs_n_works=yes +else case e in #( + e) am_cv_xargs_n_works=no ;; +esac +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_xargs_n_works" >&5 +printf "%s\n" "$am_cv_xargs_n_works" >&6; } +if test "$am_cv_xargs_n_works" = yes +then : + am__xargs_n='xargs -n' +else case e in #( + e) am__xargs_n='am__xargs_n () { shift; sed "s/ /\\n/g" | while read am__xargs_n_arg; do "" "$am__xargs_n_arg"; done; }' + ;; +esac +fi + if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." @@ -3720,7 +3941,7 @@ # Define the identity of the package. PACKAGE='bind' - VERSION='9.20.11' + VERSION='9.20.15' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -3841,8 +4062,9 @@ if test ${am_cv_prog_tar_pax+y} then : printf %s "(cached) " >&6 -else $as_nop - am_cv_prog_tar_pax=$_am_tool +else case e in #( + e) am_cv_prog_tar_pax=$_am_tool ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_pax" >&5 @@ -3867,89 +4089,12 @@ -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: - -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 - fi -fi -# Check whether --enable-silent-rules was given. -if test ${enable_silent_rules+y} -then : - enableval=$enable_silent_rules; -fi -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -printf %s "checking whether $am_make supports nested variables... " >&6; } -if test ${am_cv_make_support_nested_variables+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if printf "%s\n" 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' +AM_DEFAULT_VERBOSITY=0 ac_config_headers="$ac_config_headers config.h" @@ -3969,8 +4114,9 @@ if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else $as_nop - USE_MAINTAINER_MODE=yes +else case e in #( + e) USE_MAINTAINER_MODE=yes ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 @@ -3986,16 +4132,17 @@ MAINT=$MAINTAINER_MODE_TRUE -else $as_nop - +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5 printf %s "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } # Check whether --enable-maintainer-mode was given. if test ${enable_maintainer_mode+y} then : enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval -else $as_nop - USE_MAINTAINER_MODE=no +else case e in #( + e) USE_MAINTAINER_MODE=no ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5 @@ -4010,7 +4157,8 @@ MAINT=$MAINTAINER_MODE_TRUE - + ;; +esac fi # @@ -4102,8 +4250,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4125,7 +4273,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -4147,8 +4296,8 @@ if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4170,7 +4319,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -4205,8 +4355,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4228,7 +4378,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -4250,8 +4401,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no @@ -4290,7 +4441,8 @@ ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -4314,8 +4466,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4337,7 +4489,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -4363,8 +4516,8 @@ if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4386,7 +4539,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -4424,8 +4578,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4447,7 +4601,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -4469,8 +4624,8 @@ if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -4492,7 +4647,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -4521,10 +4677,10 @@ fi -test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -4596,8 +4752,8 @@ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' + # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'. +# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. @@ -4617,7 +4773,7 @@ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' + # safe: cross compilers may not add the suffix if given an '-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. @@ -4628,8 +4784,9 @@ done test "$ac_cv_exeext" = no && ac_cv_exeext= -else $as_nop - ac_file='' +else case e in #( + e) ac_file='' ;; +esac fi if test -z "$ac_file" then : @@ -4638,13 +4795,14 @@ printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } +See 'config.log' for more details" "$LINENO" 5; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } @@ -4668,10 +4826,10 @@ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. + # If both 'conftest.exe' and 'conftest' are 'present' (well, observable) +# catch 'conftest.exe'. For instance with Cygwin, 'ls conftest' will +# work properly (i.e., refer to 'conftest.exe'), while it won't with +# 'rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in @@ -4681,11 +4839,12 @@ * ) break;; esac done -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 @@ -4701,6 +4860,8 @@ main (void) { FILE *f = fopen ("conftest.out", "w"); + if (!f) + return 1; return ferror (f) || fclose (f) != 0; ; @@ -4740,26 +4901,27 @@ if test "$cross_compiling" = maybe; then cross_compiling=yes else - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } +If you meant to cross compile, use '--host'. +See 'config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +rm -f conftest.$ac_ext conftest$ac_cv_exeext \ + conftest.o conftest.obj conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -4791,16 +4953,18 @@ break;; esac done -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext +rm -f conftest.$ac_cv_objext conftest.$ac_ext ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } @@ -4811,8 +4975,8 @@ if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -4829,12 +4993,14 @@ if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes -else $as_nop - ac_compiler_gnu=no +else case e in #( + e) ac_compiler_gnu=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } @@ -4852,8 +5018,8 @@ if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_save_c_werror_flag=$ac_c_werror_flag +else case e in #( + e) ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" @@ -4871,8 +5037,8 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes -else $as_nop - CFLAGS="" +else case e in #( + e) CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4887,8 +5053,8 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - ac_c_werror_flag=$ac_save_c_werror_flag +else case e in #( + e) ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4905,12 +5071,15 @@ then : ac_cv_prog_cc_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag + ac_c_werror_flag=$ac_save_c_werror_flag ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } @@ -4937,8 +5106,8 @@ if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c11=no +else case e in #( + e) ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -4955,25 +5124,28 @@ test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext -CC=$ac_save_CC +CC=$ac_save_CC ;; +esac fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c11" = x +else case e in #( + e) if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } - CC="$CC $ac_cv_prog_cc_c11" + CC="$CC $ac_cv_prog_cc_c11" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 - ac_prog_cc_stdc=c11 + ac_prog_cc_stdc=c11 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -4983,8 +5155,8 @@ if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c99=no +else case e in #( + e) ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5001,25 +5173,28 @@ test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext -CC=$ac_save_CC +CC=$ac_save_CC ;; +esac fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c99" = x +else case e in #( + e) if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } - CC="$CC $ac_cv_prog_cc_c99" + CC="$CC $ac_cv_prog_cc_c99" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 - ac_prog_cc_stdc=c99 + ac_prog_cc_stdc=c99 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -5029,8 +5204,8 @@ if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c89=no +else case e in #( + e) ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5047,25 +5222,28 @@ test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext -CC=$ac_save_CC +CC=$ac_save_CC ;; +esac fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c89" = x +else case e in #( + e) if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } - CC="$CC $ac_cv_prog_cc_c89" + CC="$CC $ac_cv_prog_cc_c89" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 - ac_prog_cc_stdc=c89 + ac_prog_cc_stdc=c89 ;; +esac fi fi @@ -5086,8 +5264,8 @@ if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -5117,7 +5295,8 @@ fi done rm -f core conftest* - unset am_i + unset am_i ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } @@ -5143,8 +5322,8 @@ if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then +else case e in #( + e) if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up @@ -5231,7 +5410,7 @@ # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: + # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported @@ -5248,7 +5427,8 @@ else am_cv_CC_dependencies_compiler_type=none fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } @@ -5306,8 +5486,8 @@ if test ${ac_cv_safe_to_define___extensions__+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # define __EXTENSIONS__ 1 @@ -5323,10 +5503,12 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_safe_to_define___extensions__=yes -else $as_nop - ac_cv_safe_to_define___extensions__=no +else case e in #( + e) ac_cv_safe_to_define___extensions__=no ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 printf "%s\n" "$ac_cv_safe_to_define___extensions__" >&6; } @@ -5336,8 +5518,8 @@ if test ${ac_cv_should_define__xopen_source+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_should_define__xopen_source=no +else case e in #( + e) ac_cv_should_define__xopen_source=no if test $ac_cv_header_wchar_h = yes then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -5356,8 +5538,8 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #define _XOPEN_SOURCE 500 @@ -5375,10 +5557,12 @@ then : ac_cv_should_define__xopen_source=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -fi +fi ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 printf "%s\n" "$ac_cv_should_define__xopen_source" >&6; } @@ -5403,6 +5587,8 @@ printf "%s\n" "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_IEC_60559_EXT__ 1" >>confdefs.h + printf "%s\n" "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h printf "%s\n" "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h @@ -5422,8 +5608,9 @@ printf "%s\n" "#define _POSIX_1_SOURCE 2" >>confdefs.h -else $as_nop - MINIX= +else case e in #( + e) MINIX= ;; +esac fi if test $ac_cv_safe_to_define___extensions__ = yes then : @@ -5453,8 +5640,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5476,7 +5663,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -5498,8 +5686,8 @@ if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5521,7 +5709,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -5556,8 +5745,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5579,7 +5768,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -5601,8 +5791,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no @@ -5641,7 +5831,8 @@ ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -5665,8 +5856,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5688,7 +5879,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -5714,8 +5906,8 @@ if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5737,7 +5929,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -5775,8 +5968,8 @@ if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC"; then +else case e in #( + e) if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5798,7 +5991,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC=$ac_cv_prog_CC if test -n "$CC"; then @@ -5820,8 +6014,8 @@ if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC"; then +else case e in #( + e) if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -5843,7 +6037,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then @@ -5872,10 +6067,10 @@ fi -test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -5907,8 +6102,8 @@ if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -5925,12 +6120,14 @@ if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes -else $as_nop - ac_compiler_gnu=no +else case e in #( + e) ac_compiler_gnu=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } @@ -5948,8 +6145,8 @@ if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_save_c_werror_flag=$ac_c_werror_flag +else case e in #( + e) ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" @@ -5967,8 +6164,8 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes -else $as_nop - CFLAGS="" +else case e in #( + e) CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -5983,8 +6180,8 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - ac_c_werror_flag=$ac_save_c_werror_flag +else case e in #( + e) ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6001,12 +6198,15 @@ then : ac_cv_prog_cc_g=yes fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag + ac_c_werror_flag=$ac_save_c_werror_flag ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } @@ -6033,8 +6233,8 @@ if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c11=no +else case e in #( + e) ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6051,25 +6251,28 @@ test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext -CC=$ac_save_CC +CC=$ac_save_CC ;; +esac fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c11" = x +else case e in #( + e) if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } - CC="$CC $ac_cv_prog_cc_c11" + CC="$CC $ac_cv_prog_cc_c11" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 - ac_prog_cc_stdc=c11 + ac_prog_cc_stdc=c11 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -6079,8 +6282,8 @@ if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c99=no +else case e in #( + e) ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6097,25 +6300,28 @@ test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext -CC=$ac_save_CC +CC=$ac_save_CC ;; +esac fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c99" = x +else case e in #( + e) if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } - CC="$CC $ac_cv_prog_cc_c99" + CC="$CC $ac_cv_prog_cc_c99" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 - ac_prog_cc_stdc=c99 + ac_prog_cc_stdc=c99 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -6125,8 +6331,8 @@ if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_prog_cc_c89=no +else case e in #( + e) ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -6143,25 +6349,28 @@ test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext -CC=$ac_save_CC +CC=$ac_save_CC ;; +esac fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_prog_cc_c89" = x +else case e in #( + e) if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } - CC="$CC $ac_cv_prog_cc_c89" + CC="$CC $ac_cv_prog_cc_c89" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 - ac_prog_cc_stdc=c89 + ac_prog_cc_stdc=c89 ;; +esac fi fi @@ -6182,8 +6391,8 @@ if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -6213,7 +6422,8 @@ fi done rm -f core conftest* - unset am_i + unset am_i ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } @@ -6239,8 +6449,8 @@ if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then +else case e in #( + e) if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up @@ -6327,7 +6537,7 @@ # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: + # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported @@ -6344,7 +6554,8 @@ else am_cv_CC_dependencies_compiler_type=none fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } @@ -6376,8 +6587,8 @@ if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 -else $as_nop - # Double quotes because $CC needs to be expanded +else case e in #( + e) # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false @@ -6395,9 +6606,10 @@ if ac_fn_c_try_cpp "$LINENO" then : -else $as_nop - # Broken: fails on valid input. -continue +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext @@ -6411,15 +6623,16 @@ then : # Broken: success on invalid input. continue -else $as_nop - # Passes both tests. +else case e in #( + e) # Passes both tests. ac_preproc_ok=: -break +break ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : @@ -6428,7 +6641,8 @@ done ac_cv_prog_CPP=$CPP - + ;; +esac fi CPP=$ac_cv_prog_CPP else @@ -6451,9 +6665,10 @@ if ac_fn_c_try_cpp "$LINENO" then : -else $as_nop - # Broken: fails on valid input. -continue +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext @@ -6467,24 +6682,26 @@ then : # Broken: success on invalid input. continue -else $as_nop - # Passes both tests. +else case e in #( + e) # Passes both tests. ac_preproc_ok=: -break +break ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi ac_ext=c @@ -6538,8 +6755,8 @@ if test ${ac_cv_prog_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$CC_FOR_BUILD"; then ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -6561,7 +6778,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD if test -n "$CC_FOR_BUILD"; then @@ -6583,8 +6801,8 @@ if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$ac_ct_CC_FOR_BUILD"; then ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -6606,7 +6824,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD if test -n "$ac_ct_CC_FOR_BUILD"; then @@ -6641,8 +6860,8 @@ if test ${ac_cv_prog_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$CC_FOR_BUILD"; then ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -6664,7 +6883,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD if test -n "$CC_FOR_BUILD"; then @@ -6686,8 +6906,8 @@ if test ${ac_cv_prog_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$CC_FOR_BUILD"; then ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. else ac_prog_rejected=no @@ -6726,7 +6946,8 @@ ac_cv_prog_CC_FOR_BUILD="$as_dir$ac_word${1+' '}$@" fi fi -fi +fi ;; +esac fi CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD if test -n "$CC_FOR_BUILD"; then @@ -6750,8 +6971,8 @@ if test ${ac_cv_prog_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$CC_FOR_BUILD"; then ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -6773,7 +6994,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD if test -n "$CC_FOR_BUILD"; then @@ -6799,8 +7021,8 @@ if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$ac_ct_CC_FOR_BUILD"; then ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -6822,7 +7044,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD if test -n "$ac_ct_CC_FOR_BUILD"; then @@ -6860,8 +7083,8 @@ if test ${ac_cv_prog_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$CC_FOR_BUILD"; then ac_cv_prog_CC_FOR_BUILD="$CC_FOR_BUILD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -6883,7 +7106,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi CC_FOR_BUILD=$ac_cv_prog_CC_FOR_BUILD if test -n "$CC_FOR_BUILD"; then @@ -6905,8 +7129,8 @@ if test ${ac_cv_prog_ac_ct_CC_FOR_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_CC_FOR_BUILD"; then +else case e in #( + e) if test -n "$ac_ct_CC_FOR_BUILD"; then ac_cv_prog_ac_ct_CC_FOR_BUILD="$ac_ct_CC_FOR_BUILD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -6928,7 +7152,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_CC_FOR_BUILD=$ac_cv_prog_ac_ct_CC_FOR_BUILD if test -n "$ac_ct_CC_FOR_BUILD"; then @@ -6957,10 +7182,10 @@ fi -test -z "$CC_FOR_BUILD" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +test -z "$CC_FOR_BUILD" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 @@ -6992,8 +7217,8 @@ if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -7010,12 +7235,14 @@ if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes -else $as_nop - ac_compiler_gnu=no +else case e in #( + e) ac_compiler_gnu=no ;; +esac fi rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } @@ -7033,8 +7260,8 @@ if test ${ac_cv_build_prog_cc_g+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_save_c_werror_flag=$ac_c_werror_flag +else case e in #( + e) ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_build_prog_cc_g=no CFLAGS_FOR_BUILD="-g" @@ -7052,8 +7279,8 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_build_prog_cc_g=yes -else $as_nop - CFLAGS_FOR_BUILD="" +else case e in #( + e) CFLAGS_FOR_BUILD="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7068,8 +7295,8 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - ac_c_werror_flag=$ac_save_c_werror_flag +else case e in #( + e) ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS_FOR_BUILD="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7086,12 +7313,15 @@ then : ac_cv_build_prog_cc_g=yes fi -rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext ;; +esac fi -rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext ;; +esac fi rm -f core conftest.err conftest.$ac_build_objext conftest.beam conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag + ac_c_werror_flag=$ac_save_c_werror_flag ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_g" >&5 printf "%s\n" "$ac_cv_build_prog_cc_g" >&6; } @@ -7118,8 +7348,8 @@ if test ${ac_cv_build_prog_cc_c11+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_build_prog_cc_c11=no +else case e in #( + e) ac_cv_build_prog_cc_c11=no ac_save_CC=$CC_FOR_BUILD cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7136,25 +7366,28 @@ test "x$ac_cv_build_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext -CC_FOR_BUILD=$ac_save_CC +CC_FOR_BUILD=$ac_save_CC ;; +esac fi if test "x$ac_cv_build_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_build_prog_cc_c11" = x +else case e in #( + e) if test "x$ac_cv_build_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c11" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_build_prog_cc_c11" >&6; } - CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c11" + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c11" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c11 - ac_prog_cc_stdc=c11 + ac_prog_cc_stdc=c11 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -7164,8 +7397,8 @@ if test ${ac_cv_build_prog_cc_c99+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_build_prog_cc_c99=no +else case e in #( + e) ac_cv_build_prog_cc_c99=no ac_save_CC=$CC_FOR_BUILD cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7182,25 +7415,28 @@ test "x$ac_cv_build_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext -CC_FOR_BUILD=$ac_save_CC +CC_FOR_BUILD=$ac_save_CC ;; +esac fi if test "x$ac_cv_build_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_build_prog_cc_c99" = x +else case e in #( + e) if test "x$ac_cv_build_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c99" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_build_prog_cc_c99" >&6; } - CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c99" + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c99" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c99 - ac_prog_cc_stdc=c99 + ac_prog_cc_stdc=c99 ;; +esac fi fi if test x$ac_prog_cc_stdc = xno @@ -7210,8 +7446,8 @@ if test ${ac_cv_build_prog_cc_c89+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_build_prog_cc_c89=no +else case e in #( + e) ac_cv_build_prog_cc_c89=no ac_save_CC=$CC_FOR_BUILD cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7228,25 +7464,28 @@ test "x$ac_cv_build_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext -CC_FOR_BUILD=$ac_save_CC +CC_FOR_BUILD=$ac_save_CC ;; +esac fi if test "x$ac_cv_build_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } -else $as_nop - if test "x$ac_cv_build_prog_cc_c89" = x +else case e in #( + e) if test "x$ac_cv_build_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c89" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_build_prog_cc_c89" >&6; } - CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c89" + CC_FOR_BUILD="$CC_FOR_BUILD $ac_cv_build_prog_cc_c89" ;; +esac fi ac_cv_prog_cc_stdc=$ac_cv_build_prog_cc_c89 - ac_prog_cc_stdc=c89 + ac_prog_cc_stdc=c89 ;; +esac fi fi @@ -7267,8 +7506,8 @@ if test ${am_cv_build_prog_cc_c_o+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -7298,7 +7537,8 @@ fi done rm -f core conftest* - unset am_i + unset am_i ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_build_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_build_prog_cc_c_o" >&6; } @@ -7324,8 +7564,8 @@ if test ${am_cv_build_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then +else case e in #( + e) if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up @@ -7412,7 +7652,7 @@ # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: + # When given -MP, icc 7.0 and 7.1 complain thus: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported @@ -7429,7 +7669,8 @@ else am_cv_build_CC_dependencies_compiler_type=none fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_build_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_build_CC_dependencies_compiler_type" >&6; } @@ -7497,8 +7738,8 @@ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' + # Autoconf-2.13 could set the ac_cv_exeext variable to 'no'. +# So ignore a value of 'no', otherwise this would lead to 'EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. @@ -7518,7 +7759,7 @@ ac_cv_build_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' + # safe: cross compilers may not add the suffix if given an '-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. @@ -7529,8 +7770,9 @@ done test "$ac_cv_build_exeext" = no && ac_cv_build_exeext= -else $as_nop - ac_file='' +else case e in #( + e) ac_file='' ;; +esac fi if test -z "$ac_file" then : @@ -7539,13 +7781,14 @@ printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } +See 'config.log' for more details" "$LINENO" 5; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } @@ -7569,10 +7812,10 @@ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. + # If both 'conftest.exe' and 'conftest' are 'present' (well, observable) +# catch 'conftest.exe'. For instance with Cygwin, 'ls conftest' will +# work properly (i.e., refer to 'conftest.exe'), while it won't with +# 'rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in @@ -7582,11 +7825,12 @@ * ) break;; esac done -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f conftest conftest$ac_cv_build_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_exeext" >&5 @@ -7602,6 +7846,8 @@ main (void) { FILE *f = fopen ("conftest.out", "w"); + if (!f) + return 1; return ferror (f) || fclose (f) != 0; ; @@ -7641,18 +7887,19 @@ if test "$cross_compiling_build" = maybe; then cross_compiling_build=yes else - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. -If you meant to cross compile, use \`--build'. -See \`config.log' for more details" "$LINENO" 5; } +If you meant to cross compile, use '--build'. +See 'config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling_build" >&5 printf "%s\n" "$cross_compiling_build" >&6; } -rm -f conftest.$ac_ext conftest$ac_cv_build_exeext conftest.out +rm -f conftest.$ac_ext conftest$ac_cv_build_exeext \ + conftest.o conftest.obj conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 @@ -7660,8 +7907,8 @@ if test ${ac_cv_build_objext+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -7693,16 +7940,18 @@ break;; esac done -else $as_nop - printf "%s\n" "$as_me: failed program was:" >&5 +else case e in #( + e) printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi -rm -f conftest.$ac_cv_build_objext conftest.$ac_ext +rm -f conftest.$ac_cv_build_objext conftest.$ac_ext ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build_objext" >&5 printf "%s\n" "$ac_cv_build_objext" >&6; } @@ -7724,8 +7973,8 @@ if test ${ac_cv_build_prog_CPP+y} then : printf %s "(cached) " >&6 -else $as_nop - # Double quotes because $CC needs to be expanded +else case e in #( + e) # Double quotes because $CC needs to be expanded for CPP_FOR_BUILD in "$CC_FOR_BUILD -E" "$CC_FOR_BUILD -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false @@ -7743,9 +7992,10 @@ if ac_fn_c_try_cpp "$LINENO" then : -else $as_nop - # Broken: fails on valid input. -continue +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext @@ -7759,15 +8009,16 @@ then : # Broken: success on invalid input. continue -else $as_nop - # Passes both tests. +else case e in #( + e) # Passes both tests. ac_preproc_ok=: -break +break ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : @@ -7776,7 +8027,8 @@ done ac_cv_build_prog_CPP=$CPP_FOR_BUILD - + ;; +esac fi CPP_FOR_BUILD=$ac_cv_build_prog_CPP else @@ -7799,9 +8051,10 @@ if ac_fn_c_try_cpp "$LINENO" then : -else $as_nop - # Broken: fails on valid input. -continue +else case e in #( + e) # Broken: fails on valid input. +continue ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext @@ -7815,24 +8068,26 @@ then : # Broken: success on invalid input. continue -else $as_nop - # Passes both tests. +else case e in #( + e) # Passes both tests. ac_preproc_ok=: -break +break ;; +esac fi rm -f conftest.err conftest.i conftest.$ac_ext done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +# Because of 'break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP_FOR_BUILD\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi ac_ext=c @@ -7860,8 +8115,8 @@ if test ${ac_cv_c_bigendian+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_c_bigendian=unknown +else case e in #( + e) ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -7907,8 +8162,8 @@ int main (void) { -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ - && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ +#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \\ + && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \\ && LITTLE_ENDIAN) bogus endian macros #endif @@ -7939,8 +8194,9 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_bigendian=yes -else $as_nop - ac_cv_c_bigendian=no +else case e in #( + e) ac_cv_c_bigendian=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi @@ -7984,8 +8240,9 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_bigendian=yes -else $as_nop - ac_cv_c_bigendian=no +else case e in #( + e) ac_cv_c_bigendian=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi @@ -8012,22 +8269,23 @@ int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } - extern int foo; - -int -main (void) -{ -return use_ascii (foo) == use_ebcdic (foo); - ; - return 0; -} + int + main (int argc, char **argv) + { + /* Intimidate the compiler so that it does not + optimize the arrays away. */ + char *p = argv[0]; + ascii_mm[1] = *p++; ebcdic_mm[1] = *p++; + ascii_ii[1] = *p++; ebcdic_ii[1] = *p++; + return use_ascii (argc) == use_ebcdic (*p); + } _ACEOF -if ac_fn_c_try_compile "$LINENO" +if ac_fn_c_try_link "$LINENO" then : - if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then + if grep BIGenDianSyS conftest$ac_exeext >/dev/null; then ac_cv_c_bigendian=yes fi - if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then + if grep LiTTleEnDian conftest$ac_exeext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else @@ -8036,9 +8294,10 @@ fi fi fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int @@ -8061,14 +8320,17 @@ if ac_fn_c_try_run "$LINENO" then : ac_cv_c_bigendian=no -else $as_nop - ac_cv_c_bigendian=yes +else case e in #( + e) ac_cv_c_bigendian=yes ;; +esac fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi - fi + fi ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 printf "%s\n" "$ac_cv_c_bigendian" >&6; } @@ -8097,31 +8359,34 @@ then : enableval=$enable_largefile; fi - -if test "$enable_largefile" != no; then - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 -printf %s "checking for special C compiler options needed for large files... " >&6; } -if test ${ac_cv_sys_largefile_CC+y} +if test "$enable_largefile,$enable_year2038" != no,no +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CPPFLAGS option for large files" >&5 +printf %s "checking for $CPPFLAGS option for large files... " >&6; } +if test ${ac_cv_sys_largefile_opts+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_sys_largefile_CC=no - if test "$GCC" != yes; then - ac_save_CC=$CC - while :; do - # IRIX 6.2 and later do not support large files by default, - # so use the C compiler's -n32 option if that helps. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) ac_save_CPPFLAGS=$CPPFLAGS + ac_opt_found=no + for ac_opt in "none needed" "-D_FILE_OFFSET_BITS=64" "-D_LARGE_FILES=1"; do + if test x"$ac_opt" != x"none needed" +then : + CPPFLAGS="$ac_save_CPPFLAGS $ac_opt" +fi + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, +#ifndef FTYPE +# define FTYPE off_t +#endif + /* Check that FTYPE can represent 2**63 - 1 correctly. + We can't simply define LARGE_FTYPE to be 9223372036854775807, since some C++ compilers masquerading as C compilers incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) +#define LARGE_FTYPE (((FTYPE) 1 << 31 << 31) - 1 + ((FTYPE) 1 << 31 << 31)) + int FTYPE_is_large[(LARGE_FTYPE % 2147483629 == 721 + && LARGE_FTYPE % 2147483647 == 1) ? 1 : -1]; int main (void) @@ -8131,142 +8396,86 @@ return 0; } _ACEOF - if ac_fn_c_try_compile "$LINENO" +if ac_fn_c_try_compile "$LINENO" then : - break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam - CC="$CC -n32" + if test x"$ac_opt" = x"none needed" +then : + # GNU/Linux s390x and alpha need _FILE_OFFSET_BITS=64 for wide ino_t. + CPPFLAGS="$CPPFLAGS -DFTYPE=ino_t" if ac_fn_c_try_compile "$LINENO" then : - ac_cv_sys_largefile_CC=' -n32'; break + +else case e in #( + e) CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" + if ac_fn_c_try_compile "$LINENO" +then : + ac_opt='-D_FILE_OFFSET_BITS=64' +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam - break - done - CC=$ac_save_CC - rm -f conftest.$ac_ext - fi fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 -printf "%s\n" "$ac_cv_sys_largefile_CC" >&6; } - if test "$ac_cv_sys_largefile_CC" != no; then - CC=$CC$ac_cv_sys_largefile_CC - fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 -printf %s "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } -if test ${ac_cv_sys_file_offset_bits+y} -then : - printf %s "(cached) " >&6 -else $as_nop - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sys_file_offset_bits=no; break + ac_cv_sys_largefile_opts=$ac_opt + ac_opt_found=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _FILE_OFFSET_BITS 64 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ + test $ac_opt_found = no || break + done + CPPFLAGS=$ac_save_CPPFLAGS - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" -then : - ac_cv_sys_file_offset_bits=64; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_cv_sys_file_offset_bits=unknown - break -done + test $ac_opt_found = yes || ac_cv_sys_largefile_opts="support not detected" ;; +esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 -printf "%s\n" "$ac_cv_sys_file_offset_bits" >&6; } -case $ac_cv_sys_file_offset_bits in #( - no | unknown) ;; - *) -printf "%s\n" "#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits" >>confdefs.h -;; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_opts" >&5 +printf "%s\n" "$ac_cv_sys_largefile_opts" >&6; } + +ac_have_largefile=yes +case $ac_cv_sys_largefile_opts in #( + "none needed") : + ;; #( + "supported through gnulib") : + ;; #( + "support not detected") : + ac_have_largefile=no ;; #( + "-D_FILE_OFFSET_BITS=64") : + +printf "%s\n" "#define _FILE_OFFSET_BITS 64" >>confdefs.h + ;; #( + "-D_LARGE_FILES=1") : + +printf "%s\n" "#define _LARGE_FILES 1" >>confdefs.h + ;; #( + *) : + as_fn_error $? "internal error: bad value for \$ac_cv_sys_largefile_opts" "$LINENO" 5 ;; esac -rm -rf conftest* - if test $ac_cv_sys_file_offset_bits = unknown; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 -printf %s "checking for _LARGE_FILES value needed for large files... " >&6; } -if test ${ac_cv_sys_large_files+y} + +if test "$enable_year2038" != no +then : + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CPPFLAGS option for timestamps after 2038" >&5 +printf %s "checking for $CPPFLAGS option for timestamps after 2038... " >&6; } +if test ${ac_cv_sys_year2038_opts+y} then : printf %s "(cached) " >&6 -else $as_nop - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main (void) -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO" +else case e in #( + e) ac_save_CPPFLAGS="$CPPFLAGS" + ac_opt_found=no + for ac_opt in "none needed" "-D_TIME_BITS=64" "-D__MINGW_USE_VC2005_COMPAT" "-U_USE_32_BIT_TIME_T -D__MINGW_USE_VC2005_COMPAT"; do + if test x"$ac_opt" != x"none needed" then : - ac_cv_sys_large_files=no; break + CPPFLAGS="$ac_save_CPPFLAGS $ac_opt" fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#define _LARGE_FILES 1 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 31 << 31) - 1 + ((off_t) 1 << 31 << 31)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; + + #include + /* Check that time_t can represent 2**32 - 1 correctly. */ + #define LARGE_TIME_T \\ + ((time_t) (((time_t) 1 << 30) - 1 + 3 * ((time_t) 1 << 30))) + int verify_time_t_range[(LARGE_TIME_T / 65537 == 65535 + && LARGE_TIME_T % 65537 == 0) + ? 1 : -1]; + int main (void) { @@ -8277,93 +8486,140 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - ac_cv_sys_large_files=1; break + ac_cv_sys_year2038_opts="$ac_opt" + ac_opt_found=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - ac_cv_sys_large_files=unknown - break -done + test $ac_opt_found = no || break + done + CPPFLAGS="$ac_save_CPPFLAGS" + test $ac_opt_found = yes || ac_cv_sys_year2038_opts="support not detected" ;; +esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 -printf "%s\n" "$ac_cv_sys_large_files" >&6; } -case $ac_cv_sys_large_files in #( - no | unknown) ;; - *) -printf "%s\n" "#define _LARGE_FILES $ac_cv_sys_large_files" >>confdefs.h -;; +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_year2038_opts" >&5 +printf "%s\n" "$ac_cv_sys_year2038_opts" >&6; } + +ac_have_year2038=yes +case $ac_cv_sys_year2038_opts in #( + "none needed") : + ;; #( + "support not detected") : + ac_have_year2038=no ;; #( + "-D_TIME_BITS=64") : + +printf "%s\n" "#define _TIME_BITS 64" >>confdefs.h + ;; #( + "-D__MINGW_USE_VC2005_COMPAT") : + +printf "%s\n" "#define __MINGW_USE_VC2005_COMPAT 1" >>confdefs.h + ;; #( + "-U_USE_32_BIT_TIME_T"*) : + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} +as_fn_error $? "the 'time_t' type is currently forced to be 32-bit. It +will stop working after mid-January 2038. Remove +_USE_32BIT_TIME_T from the compiler flags. +See 'config.log' for more details" "$LINENO" 5; } ;; #( + *) : + as_fn_error $? "internal error: bad value for \$ac_cv_sys_year2038_opts" "$LINENO" 5 ;; esac -rm -rf conftest* - fi + fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for _LARGEFILE_SOURCE value needed for large files" >&5 -printf %s "checking for _LARGEFILE_SOURCE value needed for large files... " >&6; } -if test ${ac_cv_sys_largefile_source+y} +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for declarations of fseeko and ftello" >&5 +printf %s "checking for declarations of fseeko and ftello... " >&6; } +if test ${ac_cv_func_fseeko_ftello+y} then : printf %s "(cached) " >&6 -else $as_nop - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ + +#if defined __hpux && !defined _LARGEFILE_SOURCE +# include +# if LONG_MAX >> 31 == 0 +# error "32-bit HP-UX 11/ia64 needs _LARGEFILE_SOURCE for fseeko in C++" +# endif +#endif #include /* for off_t */ - #include +#include + int main (void) { -int (*fp) (FILE *, off_t, int) = fseeko; - return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + + int (*fp1) (FILE *, off_t, int) = fseeko; + off_t (*fp2) (FILE *) = ftello; + return fseeko (stdin, 0, 0) + && fp1 (stdin, 0, 0) + && ftello (stdin) >= 0 + && fp2 (stdin) >= 0; + ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO" +if ac_fn_c_try_compile "$LINENO" then : - ac_cv_sys_largefile_source=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext + ac_cv_func_fseeko_ftello=yes +else case e in #( + e) ac_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -D_LARGEFILE_SOURCE=1" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ -#define _LARGEFILE_SOURCE 1 + +#if defined __hpux && !defined _LARGEFILE_SOURCE +# include +# if LONG_MAX >> 31 == 0 +# error "32-bit HP-UX 11/ia64 needs _LARGEFILE_SOURCE for fseeko in C++" +# endif +#endif #include /* for off_t */ - #include +#include + int main (void) { -int (*fp) (FILE *, off_t, int) = fseeko; - return fseeko (stdin, 0, 0) && fp (stdin, 0, 0); + + int (*fp1) (FILE *, off_t, int) = fseeko; + off_t (*fp2) (FILE *) = ftello; + return fseeko (stdin, 0, 0) + && fp1 (stdin, 0, 0) + && ftello (stdin) >= 0 + && fp2 (stdin) >= 0; + ; return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO" +if ac_fn_c_try_compile "$LINENO" then : - ac_cv_sys_largefile_source=1; break + ac_cv_func_fseeko_ftello="need _LARGEFILE_SOURCE" +else case e in #( + e) ac_cv_func_fseeko_ftello=no ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam \ - conftest$ac_exeext conftest.$ac_ext - ac_cv_sys_largefile_source=unknown - break -done +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_source" >&5 -printf "%s\n" "$ac_cv_sys_largefile_source" >&6; } -case $ac_cv_sys_largefile_source in #( - no | unknown) ;; - *) -printf "%s\n" "#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source" >>confdefs.h -;; +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; esac -rm -rf conftest* - -# We used to try defining _XOPEN_SOURCE=500 too, to work around a bug -# in glibc 2.1.3, but that breaks too many other things. -# If you want fseeko and ftello with glibc, upgrade to a fixed glibc. -if test $ac_cv_sys_largefile_source != unknown; then +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fseeko_ftello" >&5 +printf "%s\n" "$ac_cv_func_fseeko_ftello" >&6; } +if test "$ac_cv_func_fseeko_ftello" != no +then : printf "%s\n" "#define HAVE_FSEEKO 1" >>confdefs.h fi +if test "$ac_cv_func_fseeko_ftello" = "need _LARGEFILE_SOURCE" +then : + +printf "%s\n" "#define _LARGEFILE_SOURCE 1" >>confdefs.h + +fi # Enable RFC 3542 APIs on macOS @@ -8378,8 +8634,8 @@ if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 -else $as_nop - cat >conftest.make <<\_ACEOF +else case e in #( + e) cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' @@ -8391,7 +8647,8 @@ *) eval ac_cv_prog_make_${ac_make}_set=no;; esac -rm -f conftest.make +rm -f conftest.make ;; +esac fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 @@ -8416,8 +8673,8 @@ if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$AR"; then +else case e in #( + e) if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -8439,7 +8696,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi AR=$ac_cv_prog_AR if test -n "$AR"; then @@ -8465,8 +8723,8 @@ if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_AR"; then +else case e in #( + e) if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -8488,7 +8746,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then @@ -8517,14 +8776,15 @@ fi : ${AR=ar} +: ${ARFLAGS=cr} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5 printf %s "checking the archiver ($AR) interface... " >&6; } if test ${am_cv_ar_interface+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_ext=c +else case e in #( + e) ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' @@ -8537,7 +8797,7 @@ _ACEOF if ac_fn_c_try_compile "$LINENO" then : - am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5' + am_ar_try='$AR $ARFLAGS libconftest.a conftest.$ac_objext >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5 (eval $am_ar_try) 2>&5 ac_status=$? @@ -8567,7 +8827,8 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5 printf "%s\n" "$am_cv_ar_interface" >&6; } @@ -8607,8 +8868,8 @@ if test ${ac_cv_prog_shell+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_test_shell_script=' +else case e in #( + e) ac_test_shell_script=' test "$(expr 1 + 1)" = "2" && test "$(( 1 + 1 ))" = "2" ' @@ -8627,7 +8888,8 @@ ;; esac done - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_shell" >&5 printf "%s\n" "$ac_cv_prog_shell" >&6; } @@ -8637,9 +8899,10 @@ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using $SHELL, even though it does not conform to POSIX" >&5 printf "%s\n" "$as_me: WARNING: using $SHELL, even though it does not conform to POSIX" >&2;} -else $as_nop - SHELL="$ac_cv_prog_shell" - +else case e in #( + e) SHELL="$ac_cv_prog_shell" + ;; +esac fi @@ -8654,8 +8917,8 @@ -macro_version='2.4.7' -macro_revision='2.4.7' +macro_version='2.5.4' +macro_revision='2.5.4' @@ -8746,8 +9009,8 @@ if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ +else case e in #( + e) ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done @@ -8772,9 +9035,10 @@ as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in +case `"$ac_path_SED" --version 2>&1` in #( *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +#( *) ac_count=0 printf %s 0123456789 >"conftest.in" @@ -8809,7 +9073,8 @@ else ac_cv_path_SED=$SED fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } @@ -8834,8 +9099,8 @@ if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -z "$GREP"; then +else case e in #( + e) if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -8854,9 +9119,10 @@ as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in +case `"$ac_path_GREP" --version 2>&1` in #( *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +#( *) ac_count=0 printf %s 0123456789 >"conftest.in" @@ -8891,7 +9157,8 @@ else ac_cv_path_GREP=$GREP fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } @@ -8903,8 +9170,8 @@ if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 -else $as_nop - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 +else case e in #( + e) if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then @@ -8926,9 +9193,10 @@ as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in +case `"$ac_path_EGREP" --version 2>&1` in #( *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +#( *) ac_count=0 printf %s 0123456789 >"conftest.in" @@ -8964,20 +9232,23 @@ ac_cv_path_EGREP=$EGREP fi - fi + fi ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" + EGREP_TRADITIONAL=$EGREP + ac_cv_path_EGREP_TRADITIONAL=$EGREP { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 -else $as_nop - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 +else case e in #( + e) if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then @@ -8999,9 +9270,10 @@ as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in +case `"$ac_path_FGREP" --version 2>&1` in #( *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +#( *) ac_count=0 printf %s 0123456789 >"conftest.in" @@ -9037,7 +9309,8 @@ ac_cv_path_FGREP=$FGREP fi - fi + fi ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } @@ -9068,8 +9341,9 @@ if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes -else $as_nop - with_gnu_ld=no +else case e in #( + e) with_gnu_ld=no ;; +esac fi ac_prog=ld @@ -9078,7 +9352,7 @@ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in - *-*-mingw*) + *-*-mingw* | *-*-windows*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) @@ -9114,8 +9388,8 @@ if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -z "$LD"; then +else case e in #( + e) if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs @@ -9138,7 +9412,8 @@ IFS=$lt_save_ifs else lt_cv_path_LD=$LD # Let the user override the test with a path. -fi +fi ;; +esac fi LD=$lt_cv_path_LD @@ -9155,8 +9430,8 @@ if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 -else $as_nop - # I'd rather use --version here, but apparently some GNU lds only accept -v. +else case e in #( + e) # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 @@ -9183,8 +9459,8 @@ if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$NM"; then +else case e in #( + e) if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else @@ -9205,7 +9481,7 @@ # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; + mingw* | windows*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in @@ -9231,7 +9507,8 @@ IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} -fi +fi ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } @@ -9252,8 +9529,8 @@ if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$DUMPBIN"; then +else case e in #( + e) if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -9275,7 +9552,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then @@ -9301,8 +9579,8 @@ if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_DUMPBIN"; then +else case e in #( + e) if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -9324,7 +9602,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then @@ -9378,8 +9657,8 @@ if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_nm_interface="BSD nm" +else case e in #( + e) lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) @@ -9392,7 +9671,8 @@ if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi - rm -f conftest* + rm -f conftest* ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } @@ -9403,8 +9683,8 @@ if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 -else $as_nop - i=0 +else case e in #( + e) i=0 teststring=ABCD case $build_os in @@ -9416,14 +9696,14 @@ lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. + gnu* | ironclad*) + # Under GNU Hurd and Ironclad, this test is not required because there + # is no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, @@ -9445,7 +9725,7 @@ lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) + darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -9526,7 +9806,8 @@ fi ;; esac - + ;; +esac fi if test -n "$lt_cv_sys_max_cmd_len"; then @@ -9583,11 +9864,11 @@ if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 -else $as_nop - case $host in +else case e in #( + e) case $host in *-*-mingw* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) @@ -9600,7 +9881,7 @@ ;; *-*-cygwin* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) @@ -9615,7 +9896,8 @@ lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac - + ;; +esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd @@ -9631,19 +9913,20 @@ if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 -else $as_nop - #assume ordinary cross tools, or native build. +else case e in #( + e) #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in - *-*-mingw* ) + *-*-mingw* | *-*-windows* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac - + ;; +esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd @@ -9659,8 +9942,9 @@ if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_ld_reload_flag='-r' +else case e in #( + e) lt_cv_ld_reload_flag='-r' ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } @@ -9671,7 +9955,7 @@ esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi @@ -9693,16 +9977,15 @@ -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. -set dummy ${ac_tool_prefix}file; ac_word=$2 +# Extract the first word of "file", so it can be a program name with args. +set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$FILECMD"; then +else case e in #( + e) if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -9716,7 +9999,7 @@ esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_FILECMD="${ac_tool_prefix}file" + ac_cv_prog_FILECMD="file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi @@ -9724,7 +10007,9 @@ done IFS=$as_save_IFS -fi + test -z "$ac_cv_prog_FILECMD" && ac_cv_prog_FILECMD=":" +fi ;; +esac fi FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then @@ -9736,65 +10021,6 @@ fi -fi -if test -z "$ac_cv_prog_FILECMD"; then - ac_ct_FILECMD=$FILECMD - # Extract the first word of "file", so it can be a program name with args. -set dummy file; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_FILECMD+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_FILECMD"; then - ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_FILECMD="file" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD -if test -n "$ac_ct_FILECMD"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 -printf "%s\n" "$ac_ct_FILECMD" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_FILECMD" = x; then - FILECMD=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - FILECMD=$ac_ct_FILECMD - fi -else - FILECMD="$ac_cv_prog_FILECMD" -fi - @@ -9809,8 +10035,8 @@ if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$OBJDUMP"; then +else case e in #( + e) if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -9832,7 +10058,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then @@ -9854,8 +10081,8 @@ if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_OBJDUMP"; then +else case e in #( + e) if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -9877,7 +10104,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then @@ -9918,8 +10146,8 @@ if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_file_magic_cmd='$MAGIC_CMD' +else case e in #( + e) lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support @@ -9927,7 +10155,6 @@ # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure @@ -9954,7 +10181,7 @@ lt_cv_file_magic_cmd='func_win32_libid' ;; -mingw* | pw32*) +mingw* | windows* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. @@ -9963,7 +10190,7 @@ lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; @@ -10036,6 +10263,10 @@ lt_cv_deplibs_check_method=pass_all ;; +*-mlibc) + lt_cv_deplibs_check_method=pass_all + ;; + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' @@ -10054,7 +10285,7 @@ lt_cv_deplibs_check_method=pass_all ;; -openbsd* | bitrig*) +openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else @@ -10070,6 +10301,10 @@ lt_cv_deplibs_check_method=pass_all ;; +serenity*) + lt_cv_deplibs_check_method=pass_all + ;; + solaris*) lt_cv_deplibs_check_method=pass_all ;; @@ -10112,7 +10347,8 @@ lt_cv_deplibs_check_method=pass_all ;; esac - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } @@ -10121,7 +10357,7 @@ want_nocaseglob=no if test "$build" = "$host"; then case $host_os in - mingw* | pw32*) + mingw* | windows* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else @@ -10164,8 +10400,8 @@ if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$DLLTOOL"; then +else case e in #( + e) if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -10187,7 +10423,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then @@ -10209,8 +10446,8 @@ if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_DLLTOOL"; then +else case e in #( + e) if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -10232,7 +10469,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then @@ -10274,11 +10512,11 @@ if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_sharedlib_from_linklib_cmd='unknown' +else case e in #( + e) lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in @@ -10295,7 +10533,8 @@ lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } @@ -10309,6 +10548,110 @@ if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RANLIB+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +printf "%s\n" "$RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RANLIB+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi ;; +esac +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +printf "%s\n" "$ac_ct_RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. @@ -10318,8 +10661,8 @@ if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$AR"; then +else case e in #( + e) if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -10341,7 +10684,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi AR=$ac_cv_prog_AR if test -n "$AR"; then @@ -10367,8 +10711,8 @@ if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_AR"; then +else case e in #( + e) if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -10390,7 +10734,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then @@ -10427,7 +10772,7 @@ # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have -# higher priority because thats what people were doing historically (setting +# higher priority because that's what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. @@ -10452,8 +10797,8 @@ if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_ar_at_file=no +else case e in #( + e) lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -10490,7 +10835,8 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } @@ -10515,8 +10861,8 @@ if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$STRIP"; then +else case e in #( + e) if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -10538,7 +10884,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then @@ -10560,8 +10907,8 @@ if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_STRIP"; then +else case e in #( + e) if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -10583,7 +10930,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then @@ -10616,107 +10964,6 @@ -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_RANLIB+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -printf "%s\n" "$RANLIB" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_RANLIB+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -printf "%s\n" "$ac_ct_RANLIB" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi test -z "$RANLIB" && RANLIB=: @@ -10731,15 +10978,8 @@ old_postuninstall_cmds= if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -10803,8 +11043,8 @@ if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] @@ -10819,7 +11059,7 @@ aix*) symcode='[BCDT]' ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) @@ -10834,7 +11074,7 @@ symcode='[BCDEGQRST]' ;; solaris*) - symcode='[BDRT]' + symcode='[BCDRT]' ;; sco3.2v5*) symcode='[DT]' @@ -10898,7 +11138,7 @@ # Handle CRLF in mingw tool chain opt_cr= case $build_os in -mingw*) +mingw* | windows*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac @@ -10949,7 +11189,7 @@ #ifdef __cplusplus } #endif -int main(){nm_test_var='a';nm_test_func();return(0);} +int main(void){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 @@ -11056,7 +11296,8 @@ lt_cv_sys_global_symbol_pipe= fi done - + ;; +esac fi if test -z "$lt_cv_sys_global_symbol_pipe"; then @@ -11120,8 +11361,9 @@ if test ${with_sysroot+y} then : withval=$with_sysroot; -else $as_nop - with_sysroot=no +else case e in #( + e) with_sysroot=no ;; +esac fi @@ -11129,7 +11371,9 @@ case $with_sysroot in #( yes) if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` + # Trim trailing / since we'll always append absolute paths and we want + # to avoid //, if only for less confusing output for the user. + lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'` fi ;; #( /*) @@ -11156,8 +11400,8 @@ if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 -else $as_nop - printf 0123456789abcdef0123456789abcdef >conftest.i +else case e in #( + e) printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then @@ -11193,7 +11437,8 @@ ac_cv_path_lt_DD=$lt_DD fi -rm -f conftest.i conftest2.i conftest.out +rm -f conftest.i conftest2.i conftest.out ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } @@ -11204,8 +11449,8 @@ if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 -else $as_nop - printf 0123456789abcdef0123456789abcdef >conftest.i +else case e in #( + e) printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then @@ -11213,7 +11458,8 @@ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out -test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } @@ -11344,7 +11590,7 @@ ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) +s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when @@ -11363,7 +11609,7 @@ x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; - x86_64-*linux*) + x86_64-*linux*|x86_64-gnu*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" @@ -11392,7 +11638,7 @@ x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; - x86_64-*linux*) + x86_64-*linux*|x86_64-gnu*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) @@ -11423,8 +11669,8 @@ if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_ext=c +else case e in #( + e) ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' @@ -11444,8 +11690,9 @@ if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes -else $as_nop - lt_cv_cc_needs_belf=no +else case e in #( + e) lt_cv_cc_needs_belf=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -11454,7 +11701,8 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } @@ -11512,8 +11760,8 @@ if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$MANIFEST_TOOL"; then +else case e in #( + e) if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11535,7 +11783,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then @@ -11557,8 +11806,8 @@ if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_MANIFEST_TOOL"; then +else case e in #( + e) if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11580,7 +11829,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then @@ -11609,22 +11859,23 @@ test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if test ${lt_cv_path_mainfest_tool+y} +if test ${lt_cv_path_manifest_tool+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_path_mainfest_tool=no +else case e in #( + e) lt_cv_path_manifest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes + lt_cv_path_manifest_tool=yes fi - rm -f conftest* + rm -f conftest* ;; +esac fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } -if test yes != "$lt_cv_path_mainfest_tool"; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_manifest_tool" >&5 +printf "%s\n" "$lt_cv_path_manifest_tool" >&6; } +if test yes != "$lt_cv_path_manifest_tool"; then MANIFEST_TOOL=: fi @@ -11643,8 +11894,8 @@ if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$DSYMUTIL"; then +else case e in #( + e) if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11666,7 +11917,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then @@ -11688,8 +11940,8 @@ if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_DSYMUTIL"; then +else case e in #( + e) if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11711,7 +11963,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then @@ -11745,8 +11998,8 @@ if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$NMEDIT"; then +else case e in #( + e) if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11768,7 +12021,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then @@ -11790,8 +12044,8 @@ if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_NMEDIT"; then +else case e in #( + e) if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11813,7 +12067,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then @@ -11847,8 +12102,8 @@ if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$LIPO"; then +else case e in #( + e) if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11870,7 +12125,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then @@ -11892,8 +12148,8 @@ if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_LIPO"; then +else case e in #( + e) if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11915,7 +12171,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then @@ -11949,8 +12206,8 @@ if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$OTOOL"; then +else case e in #( + e) if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -11972,7 +12229,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then @@ -11994,8 +12252,8 @@ if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_OTOOL"; then +else case e in #( + e) if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -12017,7 +12275,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then @@ -12051,8 +12310,8 @@ if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$OTOOL64"; then +else case e in #( + e) if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -12074,7 +12333,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then @@ -12096,8 +12356,8 @@ if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_OTOOL64"; then +else case e in #( + e) if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -12119,7 +12379,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then @@ -12176,8 +12437,8 @@ if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_apple_cc_single_mod=no +else case e in #( + e) lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE @@ -12203,18 +12464,58 @@ fi rm -rf libconftest.dylib* rm -f conftest.* - fi + fi ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } + # Feature test to disable chained fixups since it is not + # compatible with '-undefined dynamic_lookup' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -no_fixup_chains linker flag" >&5 +printf %s "checking for -no_fixup_chains linker flag... " >&6; } +if test ${lt_cv_support_no_fixup_chains+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_support_no_fixup_chains=yes +else case e in #( + e) lt_cv_support_no_fixup_chains=no + ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_support_no_fixup_chains" >&5 +printf "%s\n" "$lt_cv_support_no_fixup_chains" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_ld_exported_symbols_list=no +else case e in #( + e) lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" @@ -12232,13 +12533,15 @@ if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes -else $as_nop - lt_cv_ld_exported_symbols_list=no +else case e in #( + e) lt_cv_ld_exported_symbols_list=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } @@ -12248,8 +12551,8 @@ if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_ld_force_load=no +else case e in #( + e) lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF @@ -12260,7 +12563,7 @@ echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF -int main() { return 0;} +int main(void) { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err @@ -12274,7 +12577,8 @@ fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } @@ -12288,13 +12592,32 @@ 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' + if test yes = "$lt_cv_support_no_fixup_chains"; then + as_fn_append _lt_dar_allow_undefined ' $wl-no_fixup_chains' + fi + ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi + _lt_dar_needs_single_mod=no + case $host_os in + rhapsody* | darwin1.*) + _lt_dar_needs_single_mod=yes ;; + darwin*) + # When targeting Mac OS X 10.4 (darwin 8) or later, + # -single_module is the default and -multi_module is unsupported. + # The toolchain on macOS 10.14 (darwin 18) and later cannot + # target any OS version that needs -single_module. + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*-darwin[567].*|10.[0-3],*-darwin[5-9].*|10.[0-3],*-darwin1[0-7].*) + _lt_dar_needs_single_mod=yes ;; + esac + ;; + esac if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else @@ -12376,8 +12699,9 @@ IFS=$lt_save_ifs ;; esac -else $as_nop - enable_static=no +else case e in #( + e) enable_static=no ;; +esac fi @@ -12387,28 +12711,52 @@ enable_dlopen=yes - -# Check whether --with-pic was given. +# Check whether --enable-pic was given. +if test ${enable_pic+y} +then : + enableval=$enable_pic; lt_p=${PACKAGE-default} + case $enableval in + yes|no) pic_mode=$enableval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else case e in #( + e) # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac -else $as_nop - pic_mode=yes + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else case e in #( + e) pic_mode=yes ;; +esac +fi + + ;; +esac fi @@ -12443,8 +12791,9 @@ IFS=$lt_save_ifs ;; esac -else $as_nop - enable_shared=yes +else case e in #( + e) enable_shared=yes ;; +esac fi @@ -12477,8 +12826,9 @@ IFS=$lt_save_ifs ;; esac -else $as_nop - enable_fast_install=yes +else case e in #( + e) enable_fast_install=yes ;; +esac fi @@ -12493,29 +12843,46 @@ power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } - -# Check whether --with-aix-soname was given. + # Check whether --enable-aix-soname was given. +if test ${enable_aix_soname+y} +then : + enableval=$enable_aix_soname; case $enableval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --enable-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$enable_aix_soname +else case e in #( + e) # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in - aix|svr4|both) - ;; - *) - as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname -else $as_nop - if test ${lt_cv_with_aix_soname+y} + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else case e in #( + e) if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_with_aix_soname=aix +else case e in #( + e) lt_cv_with_aix_soname=aix ;; +esac +fi + ;; +esac fi - with_aix_soname=$lt_cv_with_aix_soname + enable_aix_soname=$lt_cv_with_aix_soname ;; +esac fi + with_aix_soname=$enable_aix_soname { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then @@ -12604,8 +12971,8 @@ if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 -else $as_nop - rm -f .libs 2>/dev/null +else case e in #( + e) rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs @@ -12613,7 +12980,8 @@ # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi -rmdir .libs 2>/dev/null +rmdir .libs 2>/dev/null ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } @@ -12674,8 +13042,8 @@ if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 -else $as_nop - case $MAGIC_CMD in +else case e in #( + e) case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; @@ -12718,6 +13086,7 @@ IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; +esac ;; esac fi @@ -12741,8 +13110,8 @@ if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 -else $as_nop - case $MAGIC_CMD in +else case e in #( + e) case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; @@ -12785,6 +13154,7 @@ IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; +esac ;; esac fi @@ -12828,7 +13198,7 @@ lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' +lt_simple_link_test_code='int main(void){return(0);}' @@ -12884,8 +13254,8 @@ if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_rtti_exceptions=no +else case e in #( + e) lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment @@ -12913,7 +13283,8 @@ fi fi $RM conftest* - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } @@ -12969,7 +13340,7 @@ # PIC is the default for these OSes. ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -13072,7 +13443,7 @@ esac ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' @@ -13113,6 +13484,12 @@ lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; + *flang* | ftn | f18* | f95*) + # Flang compiler. + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' @@ -13201,6 +13578,12 @@ lt_prog_compiler_static='-Bstatic' ;; + *-mlibc) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. @@ -13217,6 +13600,9 @@ lt_prog_compiler_static='-non_shared' ;; + serenity*) + ;; + solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' @@ -13284,8 +13670,9 @@ if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +else case e in #( + e) lt_cv_prog_compiler_pic=$lt_prog_compiler_pic ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } @@ -13300,8 +13687,8 @@ if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_pic_works=no +else case e in #( + e) lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment @@ -13329,7 +13716,8 @@ fi fi $RM conftest* - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } @@ -13365,8 +13753,8 @@ if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_static_works=no +else case e in #( + e) lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext @@ -13387,7 +13775,8 @@ fi $RM -r conftest* LDFLAGS=$save_LDFLAGS - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } @@ -13409,8 +13798,8 @@ if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_c_o=no +else case e in #( + e) lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest @@ -13450,7 +13839,8 @@ cd .. $RM -r conftest $RM conftest* - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } @@ -13465,8 +13855,8 @@ if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler_c_o=no +else case e in #( + e) lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest @@ -13506,7 +13896,8 @@ cd .. $RM -r conftest $RM conftest* - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } @@ -13585,7 +13976,7 @@ extract_expsyms_cmds= case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. @@ -13597,9 +13988,6 @@ # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd* | bitrig*) - with_gnu_ld=no - ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; @@ -13703,7 +14091,7 @@ fi ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' @@ -13713,6 +14101,7 @@ enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + file_list_spec='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -13732,7 +14121,7 @@ haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - link_all_deplibs=yes + link_all_deplibs=no ;; os2*) @@ -13759,7 +14148,7 @@ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; @@ -13859,6 +14248,11 @@ fi ;; + *-mlibc) + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' @@ -14105,8 +14499,8 @@ if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -14138,7 +14532,8 @@ if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi - + ;; +esac fi aix_libpath=$lt_cv_aix_libpath_ @@ -14160,8 +14555,8 @@ if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -14193,7 +14588,8 @@ if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi - + ;; +esac fi aix_libpath=$lt_cv_aix_libpath_ @@ -14249,7 +14645,7 @@ export_dynamic_flag_spec=-rdynamic ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is @@ -14266,14 +14662,14 @@ # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_cmds='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' @@ -14444,8 +14840,8 @@ if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_prog_compiler__b=no +else case e in #( + e) lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext @@ -14466,7 +14862,8 @@ fi $RM -r conftest* LDFLAGS=$save_LDFLAGS - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } @@ -14514,8 +14911,8 @@ if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 -else $as_nop - save_LDFLAGS=$LDFLAGS +else case e in #( + e) save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -14524,12 +14921,14 @@ if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes -else $as_nop - lt_cv_irix_exported_symbol=no +else case e in #( + e) lt_cv_irix_exported_symbol=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS + LDFLAGS=$save_LDFLAGS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } @@ -14559,6 +14958,9 @@ esac ;; + *-mlibc) + ;; + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out @@ -14581,7 +14983,7 @@ *nto* | *qnx*) ;; - openbsd* | bitrig*) + openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no @@ -14624,7 +15026,7 @@ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; @@ -14660,6 +15062,9 @@ hardcode_libdir_separator=: ;; + serenity*) + ;; + solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then @@ -14857,8 +15262,8 @@ if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 -else $as_nop - $RM conftest* +else case e in #( + e) $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 @@ -14894,7 +15299,8 @@ cat conftest.err 1>&5 fi $RM conftest* - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } @@ -15065,7 +15471,7 @@ *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` @@ -15123,7 +15529,7 @@ # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` @@ -15197,7 +15603,7 @@ # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the @@ -15291,7 +15697,7 @@ # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no @@ -15302,15 +15708,29 @@ # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' + # If user builds GCC with multilib enabled, + # it should just install on $(libdir) + # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. + if test xyes = x"$multilib"; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' + else + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' @@ -15323,7 +15743,7 @@ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; - mingw* | cegcc*) + mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; @@ -15342,7 +15762,7 @@ library_names_spec='$libname.dll.lib' case $build_os in - mingw*) + mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' @@ -15449,7 +15869,28 @@ need_version=yes ;; esac + case $host_cpu in + powerpc64) + # On FreeBSD bi-arch platforms, a different variable is used for 32-bit + # binaries. See . + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int test_pointer_size[sizeof (void *) - 5]; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : shlibpath_var=LD_LIBRARY_PATH +else case e in #( + e) shlibpath_var=LD_32_LIBRARY_PATH ;; +esac +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; + *) + shlibpath_var=LD_LIBRARY_PATH + ;; + esac case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes @@ -15479,8 +15920,9 @@ soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes + sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' + sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' + hardcode_into_libs=no ;; hpux9* | hpux10* | hpux11*) @@ -15590,7 +16032,7 @@ version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no - library_names_spec='$libname$release$shared_ext' + library_names_spec='$libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH @@ -15602,8 +16044,9 @@ hardcode_into_libs=yes dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - hardcode_libdir_flag_spec='-L$libdir' + # -rpath works at least for libraries that are not overridden by + # libraries installed in system locations. + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; # This must be glibc/ELF. @@ -15621,8 +16064,8 @@ if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 -else $as_nop - lt_cv_shlibpath_overrides_runpath=no +else case e in #( + e) lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ @@ -15649,7 +16092,8 @@ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir - + ;; +esac fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath @@ -15659,7 +16103,7 @@ # before this can be enabled. hardcode_into_libs=yes - # Ideally, we could use ldconfig to report *all* directores which are + # Ideally, we could use ldconfig to report *all* directories which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, @@ -15683,6 +16127,18 @@ version_type=linux need_lib_prefix=no need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH @@ -15709,6 +16165,18 @@ hardcode_into_libs=yes ;; +*-mlibc) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='mlibc ld.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' @@ -15728,7 +16196,7 @@ dynamic_linker='ldqnx.so' ;; -openbsd* | bitrig*) +openbsd*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no @@ -15788,6 +16256,17 @@ dynamic_linker=no ;; +serenity*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + dynamic_linker='SerenityOS LibELF' + ;; + solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -15885,6 +16364,502 @@ shlibpath_var=LD_LIBRARY_PATH ;; +emscripten*) + version_type=none + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + dynamic_linker="Emscripten linker" + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + *flang* | ftn | f18* | f95*) + # Flang compiler. + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | $SED 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *-mlibc) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + serenity*) + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) lt_cv_prog_compiler_pic=$lt_prog_compiler_pic ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + +='-fPIC' + archive_cmds='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' + archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' + archive_cmds_need_lc=no + no_undefined_flag= + ;; + *) dynamic_linker=no ;; @@ -16069,7 +17044,7 @@ lt_cv_dlopen_self=yes ;; - mingw* | pw32* | cegcc*) + mingw* | windows* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; @@ -16086,16 +17061,22 @@ if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dlopen (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (void); int main (void) { @@ -16107,24 +17088,27 @@ if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes -else $as_nop - ac_cv_lib_dl_dlopen=no +else case e in #( + e) ac_cv_lib_dl_dlopen=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +LIBS=$ac_check_lib_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl -else $as_nop - +else case e in #( + e) lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes - + ;; +esac fi ;; @@ -16142,22 +17126,28 @@ if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char shl_load (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (void); int main (void) { @@ -16169,39 +17159,47 @@ if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes -else $as_nop - ac_cv_lib_dld_shl_load=no +else case e in #( + e) ac_cv_lib_dld_shl_load=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +LIBS=$ac_check_lib_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld -else $as_nop - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +else case e in #( + e) ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dlopen (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (void); int main (void) { @@ -16213,34 +17211,42 @@ if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes -else $as_nop - ac_cv_lib_dl_dlopen=no +else case e in #( + e) ac_cv_lib_dl_dlopen=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +LIBS=$ac_check_lib_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dlopen (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (void); int main (void) { @@ -16252,34 +17258,42 @@ if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes -else $as_nop - ac_cv_lib_svld_dlopen=no +else case e in #( + e) ac_cv_lib_svld_dlopen=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +LIBS=$ac_check_lib_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_check_lib_save_LIBS=$LIBS +else case e in #( + e) ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char dld_link (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (void); int main (void) { @@ -16291,12 +17305,14 @@ if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes -else $as_nop - ac_cv_lib_dld_dld_link=no +else case e in #( + e) ac_cv_lib_dld_dld_link=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS +LIBS=$ac_check_lib_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } @@ -16305,19 +17321,24 @@ lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi - + ;; +esac fi - + ;; +esac fi - + ;; +esac fi - + ;; +esac fi - + ;; +esac fi ;; @@ -16345,8 +17366,8 @@ if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 -else $as_nop - if test yes = "$cross_compiling"; then : +else case e in #( + e) if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -16396,11 +17417,11 @@ /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); +int fnord (void) __attribute__((visibility("default"))); #endif -int fnord () { return 42; } -int main () +int fnord (void) { return 42; } +int main (void) { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; @@ -16440,7 +17461,8 @@ fi rm -fr conftest* - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } @@ -16452,8 +17474,8 @@ if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 -else $as_nop - if test yes = "$cross_compiling"; then : +else case e in #( + e) if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 @@ -16503,11 +17525,11 @@ /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); +int fnord (void) __attribute__((visibility("default"))); #endif -int fnord () { return 42; } -int main () +int fnord (void) { return 42; } +int main (void) { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; @@ -16547,7 +17569,8 @@ fi rm -fr conftest* - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } @@ -16749,8 +17772,9 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - STD_CFLAGS="$STD_CFLAGS -Wno-stringop-overread" +else case e in #( + e) STD_CFLAGS="$STD_CFLAGS -Wno-stringop-overread" ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -16779,8 +17803,8 @@ if test ${ax_cv_check_cflags___fno_strict_aliasing+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -fno-strict-aliasing" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -16797,19 +17821,22 @@ if ac_fn_c_try_compile "$LINENO" then : ax_cv_check_cflags___fno_strict_aliasing=yes -else $as_nop - ax_cv_check_cflags___fno_strict_aliasing=no +else case e in #( + e) ax_cv_check_cflags___fno_strict_aliasing=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags + CFLAGS=$ax_check_save_flags ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fno_strict_aliasing" >&5 printf "%s\n" "$ax_cv_check_cflags___fno_strict_aliasing" >&6; } if test "x$ax_cv_check_cflags___fno_strict_aliasing" = xyes then : STD_CFLAGS="$STD_CFLAGS -fno-strict-aliasing" -else $as_nop - : +else case e in #( + e) : ;; +esac fi # Clang only issues a warning so use -Werror to force a error. @@ -16818,8 +17845,8 @@ if test ${ax_cv_check_cflags___Werror__fno_delete_null_pointer_checks+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -Werror -fno-delete-null-pointer-checks" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -16836,19 +17863,22 @@ if ac_fn_c_try_compile "$LINENO" then : ax_cv_check_cflags___Werror__fno_delete_null_pointer_checks=yes -else $as_nop - ax_cv_check_cflags___Werror__fno_delete_null_pointer_checks=no +else case e in #( + e) ax_cv_check_cflags___Werror__fno_delete_null_pointer_checks=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags + CFLAGS=$ax_check_save_flags ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Werror__fno_delete_null_pointer_checks" >&5 printf "%s\n" "$ax_cv_check_cflags___Werror__fno_delete_null_pointer_checks" >&6; } if test "x$ax_cv_check_cflags___Werror__fno_delete_null_pointer_checks" = xyes then : STD_CFLAGS="$STD_CFLAGS -fno-delete-null-pointer-checks" -else $as_nop - : +else case e in #( + e) : ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -fdiagnostics-show-option" >&5 @@ -16856,8 +17886,8 @@ if test ${ax_cv_check_cflags___fdiagnostics_show_option+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$CFLAGS CFLAGS="$CFLAGS -fdiagnostics-show-option" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -16874,19 +17904,22 @@ if ac_fn_c_try_compile "$LINENO" then : ax_cv_check_cflags___fdiagnostics_show_option=yes -else $as_nop - ax_cv_check_cflags___fdiagnostics_show_option=no +else case e in #( + e) ax_cv_check_cflags___fdiagnostics_show_option=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext - CFLAGS=$ax_check_save_flags + CFLAGS=$ax_check_save_flags ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___fdiagnostics_show_option" >&5 printf "%s\n" "$ax_cv_check_cflags___fdiagnostics_show_option" >&6; } if test "x$ax_cv_check_cflags___fdiagnostics_show_option" = xyes then : STD_CFLAGS="$STD_CFLAGS -fdiagnostics-show-option" -else $as_nop - : +else case e in #( + e) : ;; +esac fi @@ -16895,8 +17928,8 @@ if test ${ax_cv_check_ldflags___Wl___export_dynamic+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) ax_check_save_flags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,--export-dynamic" cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -16913,20 +17946,23 @@ if ac_fn_c_try_link "$LINENO" then : ax_cv_check_ldflags___Wl___export_dynamic=yes -else $as_nop - ax_cv_check_ldflags___Wl___export_dynamic=no +else case e in #( + e) ax_cv_check_ldflags___Wl___export_dynamic=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$ax_check_save_flags + LDFLAGS=$ax_check_save_flags ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_ldflags___Wl___export_dynamic" >&5 printf "%s\n" "$ax_cv_check_ldflags___Wl___export_dynamic" >&6; } if test "x$ax_cv_check_ldflags___Wl___export_dynamic" = xyes then : STD_LDFLAGS="$STD_LDFLAGS -Wl,--export-dynamic" -else $as_nop - : +else case e in #( + e) : ;; +esac fi @@ -16981,8 +18017,9 @@ if test ${enable_warn_error+y} then : enableval=$enable_warn_error; -else $as_nop - enable_warn_error=no +else case e in #( + e) enable_warn_error=no ;; +esac fi if test "$enable_warn_error" = "yes" @@ -17010,8 +18047,8 @@ if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - case $PKG_CONFIG in +else case e in #( + e) case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; @@ -17036,6 +18073,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG @@ -17058,8 +18096,8 @@ if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - case $ac_pt_PKG_CONFIG in +else case e in #( + e) case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; @@ -17084,6 +18122,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG @@ -17138,8 +18177,9 @@ if test ${with_liburcu+y} then : withval=$with_liburcu; -else $as_nop - with_liburcu=membarrier +else case e in #( + e) with_liburcu=membarrier ;; +esac fi @@ -17313,8 +18353,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -17324,7 +18364,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else LIBURCU_CFLAGS=$pkg_cv_LIBURCU_CFLAGS LIBURCU_LIBS=$pkg_cv_LIBURCU_LIBS @@ -17407,8 +18447,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -17418,7 +18458,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else LIBURCU_CFLAGS=$pkg_cv_LIBURCU_CFLAGS LIBURCU_LIBS=$pkg_cv_LIBURCU_LIBS @@ -17494,9 +18534,10 @@ printf "%s\n" "#define URCU_INLINE_SMALL_FUNCTIONS 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -17508,8 +18549,9 @@ if test ${enable_fuzzing+y} then : enableval=$enable_fuzzing; -else $as_nop - enable_fuzzing=no +else case e in #( + e) enable_fuzzing=no ;; +esac fi @@ -17579,8 +18621,9 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - as_fn_error $? "set CC=afl- when --enable-fuzzing=afl is used" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "set CC=afl- when --enable-fuzzing=afl is used" "$LINENO" 5 ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -17598,8 +18641,8 @@ if test ${ac_cv_path_PERL+y} then : printf %s "(cached) " >&6 -else $as_nop - case $PERL in +else case e in #( + e) case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; @@ -17624,6 +18667,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi PERL=$ac_cv_path_PERL @@ -17679,10 +18723,11 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - as_fn_error $? "Python interpreter is too old" "$LINENO" 5 + as_fn_error $? "Python interpreter is too old" "$LINENO" 5 ;; +esac fi am_display_PYTHON=$PYTHON else @@ -17693,9 +18738,9 @@ if test ${am_cv_pathless_PYTHON+y} then : printf %s "(cached) " >&6 -else $as_nop - - for am_cv_pathless_PYTHON in python python2 python3 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do +else case e in #( + e) + for am_cv_pathless_PYTHON in python python3 python3.20 python3.19 python3.18 python3.17 python3.16 python3.15 python3.14 python3.13 python3.12 python3.11 python3.10 python3.9 python3.8 python3.7 python3.6 python3.5 python3.4 python3.3 python3.2 python3.1 python3.0 python2 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do test "$am_cv_pathless_PYTHON" = none && break prog="import sys # split strings by '.' and convert to numeric. Append some zeros @@ -17714,7 +18759,8 @@ then : break fi - done + done ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 printf "%s\n" "$am_cv_pathless_PYTHON" >&6; } @@ -17729,8 +18775,8 @@ if test ${ac_cv_path_PYTHON+y} then : printf %s "(cached) " >&6 -else $as_nop - case $PYTHON in +else case e in #( + e) case $PYTHON in [\\/]* | ?:[\\/]*) ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; @@ -17755,6 +18801,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi PYTHON=$ac_cv_path_PYTHON @@ -17781,8 +18828,9 @@ if test ${am_cv_python_version+y} then : printf %s "(cached) " >&6 -else $as_nop - am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[:2])"` +else case e in #( + e) am_cv_python_version=`$PYTHON -c "import sys; print ('%u.%u' % sys.version_info[:2])"` ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 printf "%s\n" "$am_cv_python_version" >&6; } @@ -17794,8 +18842,9 @@ if test ${am_cv_python_platform+y} then : printf %s "(cached) " >&6 -else $as_nop - am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` +else case e in #( + e) am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 printf "%s\n" "$am_cv_python_platform" >&6; } @@ -17815,8 +18864,9 @@ if test ${with_python_sys_prefix+y} then : withval=$with_python_sys_prefix; am_use_python_sys=: -else $as_nop - am_use_python_sys=false +else case e in #( + e) am_use_python_sys=false ;; +esac fi @@ -17831,8 +18881,8 @@ printf %s "checking for explicit $am_display_PYTHON prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5 printf "%s\n" "$am_cv_python_prefix" >&6; } -else $as_nop - +else case e in #( + e) if $am_use_python_sys; then # using python sys.prefix value, not GNU { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for python default $am_display_PYTHON prefix" >&5 @@ -17840,8 +18890,9 @@ if test ${am_cv_python_prefix+y} then : printf %s "(cached) " >&6 -else $as_nop - am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"` +else case e in #( + e) am_cv_python_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.prefix)"` ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_prefix" >&5 printf "%s\n" "$am_cv_python_prefix" >&6; } @@ -17862,7 +18913,8 @@ printf %s "checking for GNU default $am_display_PYTHON prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_python_prefix" >&5 printf "%s\n" "$am_python_prefix" >&6; } - fi + fi ;; +esac fi # Substituting python_prefix_subst value. @@ -17881,8 +18933,8 @@ printf %s "checking for explicit $am_display_PYTHON exec_prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 printf "%s\n" "$am_cv_python_exec_prefix" >&6; } -else $as_nop - +else case e in #( + e) # no explicit --with-python_exec_prefix, but if # --with-python_prefix was given, use its value for python_exec_prefix too. if test -n "$with_python_prefix" @@ -17893,8 +18945,8 @@ printf %s "checking for python_prefix-given $am_display_PYTHON exec_prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 printf "%s\n" "$am_cv_python_exec_prefix" >&6; } -else $as_nop - +else case e in #( + e) # Set am__usable_exec_prefix whether using GNU or Python values, # since we use that variable for pyexecdir. if test "x$exec_prefix" = xNONE; then @@ -17909,8 +18961,9 @@ if test ${am_cv_python_exec_prefix+y} then : printf %s "(cached) " >&6 -else $as_nop - am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"` +else case e in #( + e) am_cv_python_exec_prefix=`$PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)"` ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_exec_prefix" >&5 printf "%s\n" "$am_cv_python_exec_prefix" >&6; } @@ -17930,8 +18983,10 @@ printf %s "checking for GNU default $am_display_PYTHON exec_prefix... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_python_exec_prefix" >&5 printf "%s\n" "$am_python_exec_prefix" >&6; } - fi -fi + fi ;; +esac +fi ;; +esac fi # Substituting python_exec_prefix_subst. @@ -17956,7 +19011,21 @@ if python_implementation() == 'CPython' and sys.version[:3] == '2.7': can_use_sysconfig = 0 except ImportError: - pass" + pass" # end of am_python_setup_sysconfig + + # More repeated code, for figuring out the installation scheme to use. + am_python_setup_scheme="if hasattr(sysconfig, 'get_default_scheme'): + scheme = sysconfig.get_default_scheme() + else: + scheme = sysconfig._get_default_scheme() + if scheme == 'posix_local': + if '$am_py_prefix' == '/usr': + scheme = 'deb_system' # should only happen during Debian package builds + else: + # Debian's default scheme installs to /usr/local/ but we want to + # follow the prefix, as we always have. + # See bugs#54412, #64837, et al. + scheme = 'posix_prefix'" # end of am_python_setup_scheme { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory (pythondir)" >&5 @@ -17964,8 +19033,8 @@ if test ${am_cv_python_pythondir+y} then : printf %s "(cached) " >&6 -else $as_nop - if test "x$am_cv_python_prefix" = x; then +else case e in #( + e) if test "x$am_cv_python_prefix" = x; then am_py_prefix=$am__usable_prefix else am_py_prefix=$am_cv_python_prefix @@ -17973,14 +19042,11 @@ am_cv_python_pythondir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: - if hasattr(sysconfig, 'get_default_scheme'): - scheme = sysconfig.get_default_scheme() - else: - scheme = sysconfig._get_default_scheme() - if scheme == 'posix_local': - # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ - scheme = 'posix_prefix' - sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) + try: + $am_python_setup_scheme + sitedir = sysconfig.get_path('purelib', scheme, vars={'base':'$am_py_prefix'}) + except: + sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') @@ -17999,7 +19065,8 @@ esac ;; esac - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 printf "%s\n" "$am_cv_python_pythondir" >&6; } @@ -18009,13 +19076,13 @@ pkgpythondir=\${pythondir}/$PACKAGE - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory (pyexecdir)" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory (pyexecdir)" >&5 printf %s "checking for $am_display_PYTHON extension module directory (pyexecdir)... " >&6; } if test ${am_cv_python_pyexecdir+y} then : printf %s "(cached) " >&6 -else $as_nop - if test "x$am_cv_python_exec_prefix" = x; then +else case e in #( + e) if test "x$am_cv_python_exec_prefix" = x; then am_py_exec_prefix=$am__usable_exec_prefix else am_py_exec_prefix=$am_cv_python_exec_prefix @@ -18023,14 +19090,11 @@ am_cv_python_pyexecdir=`$PYTHON -c " $am_python_setup_sysconfig if can_use_sysconfig: - if hasattr(sysconfig, 'get_default_scheme'): - scheme = sysconfig.get_default_scheme() - else: - scheme = sysconfig._get_default_scheme() - if scheme == 'posix_local': - # Debian's default scheme installs to /usr/local/ but we want to find headers in /usr/ - scheme = 'posix_prefix' - sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) + try: + $am_python_setup_scheme + sitedir = sysconfig.get_path('platlib', scheme, vars={'platbase':'$am_py_exec_prefix'}) + except: + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_exec_prefix'}) else: from distutils import sysconfig sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_exec_prefix') @@ -18049,7 +19113,8 @@ esac ;; esac - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 printf "%s\n" "$am_cv_python_pyexecdir" >&6; } @@ -18080,8 +19145,8 @@ if test ${ac_cv_path_PYTEST+y} then : printf %s "(cached) " >&6 -else $as_nop - case $PYTEST in +else case e in #( + e) case $PYTEST in [\\/]* | ?:[\\/]*) ac_cv_path_PYTEST="$PYTEST" # Let the user override the test with a path. ;; @@ -18106,6 +19171,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi PYTEST=$ac_cv_path_PYTEST @@ -18146,8 +19212,8 @@ if test ${ac_cv_path_XSLTPROC+y} then : printf %s "(cached) " >&6 -else $as_nop - case $XSLTPROC in +else case e in #( + e) case $XSLTPROC in [\\/]* | ?:[\\/]*) ac_cv_path_XSLTPROC="$XSLTPROC" # Let the user override the test with a path. ;; @@ -18172,6 +19238,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi XSLTPROC=$ac_cv_path_XSLTPROC @@ -18410,8 +19477,9 @@ then : printf "%s\n" "#define HAVE_STDATOMIC_H 1" >>confdefs.h -else $as_nop - as_fn_error $? "C11 Atomic Operations required, update your toolchain to build BIND 9" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "C11 Atomic Operations required, update your toolchain to build BIND 9" "$LINENO" 5 ;; +esac fi done @@ -18448,8 +19516,8 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } -else $as_nop - LIBS="$LIBS -latomic" +else case e in #( + e) LIBS="$LIBS -latomic" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include @@ -18466,24 +19534,27 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "libatomic needed, but linking with -latomic failed, please fix your toolchain. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "stdatomic.h header found, but compilation failed, please fix your toolchain. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -18494,8 +19565,9 @@ then : printf "%s\n" "#define HAVE_STDNORETURN_H 1" >>confdefs.h -else $as_nop - as_fn_error $? "C11 standard headers not found, update your toolchain." "$LINENO" 5 +else case e in #( + e) as_fn_error $? "C11 standard headers not found, update your toolchain." "$LINENO" 5 ;; +esac fi done @@ -18505,8 +19577,8 @@ if test ${ac_cv_c_const+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -18570,10 +19642,12 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_const=yes -else $as_nop - ac_cv_c_const=no +else case e in #( + e) ac_cv_c_const=no ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 printf "%s\n" "$ac_cv_c_const" >&6; } @@ -18588,8 +19662,8 @@ if test ${ac_cv_c_inline+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_cv_c_inline=no +else case e in #( + e) ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -18607,7 +19681,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test "$ac_cv_c_inline" != no && break done - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 printf "%s\n" "$ac_cv_c_inline" >&6; } @@ -18632,8 +19707,8 @@ if test ${ac_cv_c_volatile+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int @@ -18650,10 +19725,12 @@ if ac_fn_c_try_compile "$LINENO" then : ac_cv_c_volatile=yes -else $as_nop - ac_cv_c_volatile=no +else case e in #( + e) ac_cv_c_volatile=no ;; +esac fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5 printf "%s\n" "$ac_cv_c_volatile" >&6; } @@ -18689,9 +19766,10 @@ printf "%s\n" "#define HAVE_ARM_YIELD 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; #( *) : @@ -18723,9 +19801,10 @@ printf "%s\n" "#define HAVE_SPARC_PAUSE 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; #( *) : @@ -18744,20 +19823,22 @@ if test "x$ac_cv_type_size_t" = xyes then : -else $as_nop - +else case e in #( + e) printf "%s\n" "#define size_t unsigned int" >>confdefs.h - + ;; +esac fi ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" if test "x$ac_cv_type_ssize_t" = xyes then : -else $as_nop - +else case e in #( + e) printf "%s\n" "#define ssize_t int" >>confdefs.h - + ;; +esac fi @@ -18767,8 +19848,8 @@ printf "%s\n" "#define HAVE_UINTPTR_T 1" >>confdefs.h -else $as_nop - for ac_type in 'unsigned int' 'unsigned long int' \ +else case e in #( + e) for ac_type in 'unsigned int' 'unsigned long int' \ 'unsigned long long int'; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -18793,7 +19874,8 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext test -z "$ac_type" && break - done + done ;; +esac fi @@ -18829,12 +19911,13 @@ printf "%s\n" "#define HAVE_UNAME 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: uname is not correctly supported" >&5 printf "%s\n" "$as_me: WARNING: uname is not correctly supported" >&2;} - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -18849,8 +19932,8 @@ if test ${ax_cv_have_func_attribute_noreturn+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -18871,15 +19954,18 @@ if grep -- -Wattributes conftest.err then : ax_cv_have_func_attribute_noreturn=no -else $as_nop - ax_cv_have_func_attribute_noreturn=yes +else case e in #( + e) ax_cv_have_func_attribute_noreturn=yes ;; +esac fi -else $as_nop - ax_cv_have_func_attribute_noreturn=no +else case e in #( + e) ax_cv_have_func_attribute_noreturn=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_noreturn" >&5 printf "%s\n" "$ax_cv_have_func_attribute_noreturn" >&6; } @@ -18905,8 +19991,8 @@ if test ${ax_cv_have_func_attribute_malloc+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -18927,15 +20013,18 @@ if grep -- -Wattributes conftest.err then : ax_cv_have_func_attribute_malloc=no -else $as_nop - ax_cv_have_func_attribute_malloc=yes +else case e in #( + e) ax_cv_have_func_attribute_malloc=yes ;; +esac fi -else $as_nop - ax_cv_have_func_attribute_malloc=no +else case e in #( + e) ax_cv_have_func_attribute_malloc=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_malloc" >&5 printf "%s\n" "$ax_cv_have_func_attribute_malloc" >&6; } @@ -18979,9 +20068,10 @@ printf "%s\n" "#define HAVE_MALLOC_EXT_ATTR 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -18996,8 +20086,8 @@ if test ${ax_cv_have_func_attribute_returns_nonnull+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -19018,15 +20108,18 @@ if grep -- -Wattributes conftest.err then : ax_cv_have_func_attribute_returns_nonnull=no -else $as_nop - ax_cv_have_func_attribute_returns_nonnull=yes +else case e in #( + e) ax_cv_have_func_attribute_returns_nonnull=yes ;; +esac fi -else $as_nop - ax_cv_have_func_attribute_returns_nonnull=no +else case e in #( + e) ax_cv_have_func_attribute_returns_nonnull=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_returns_nonnull" >&5 printf "%s\n" "$ax_cv_have_func_attribute_returns_nonnull" >&6; } @@ -19049,15 +20142,21 @@ if test ${ac_cv_search_sqrt+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char sqrt (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sqrt (void); int main (void) { @@ -19088,11 +20187,13 @@ if test ${ac_cv_search_sqrt+y} then : -else $as_nop - ac_cv_search_sqrt=no +else case e in #( + e) ac_cv_search_sqrt=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sqrt" >&5 printf "%s\n" "$ac_cv_search_sqrt" >&6; } @@ -19114,8 +20215,9 @@ if test ${enable_geoip+y} then : enableval=$enable_geoip; -else $as_nop - enable_geoip="yes" +else case e in #( + e) enable_geoip="yes" ;; +esac fi @@ -19125,8 +20227,9 @@ if test ${with_maxminddb+y} then : withval=$with_maxminddb; -else $as_nop - with_maxminddb="auto" +else case e in #( + e) with_maxminddb="auto" ;; +esac fi @@ -19307,8 +20410,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -19318,7 +20421,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else MAXMINDDB_CFLAGS=$pkg_cv_MAXMINDDB_CFLAGS MAXMINDDB_LIBS=$pkg_cv_MAXMINDDB_LIBS @@ -19434,15 +20537,21 @@ if test ${ac_cv_search_MMDB_open+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char MMDB_open (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char MMDB_open (void); int main (void) { @@ -19473,11 +20582,13 @@ if test ${ac_cv_search_MMDB_open+y} then : -else $as_nop - ac_cv_search_MMDB_open=no +else case e in #( + e) ac_cv_search_MMDB_open=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_MMDB_open" >&5 printf "%s\n" "$ac_cv_search_MMDB_open" >&6; } @@ -19493,8 +20604,9 @@ printf "%s\n" "$as_me: GeoIP2 default database path set to $with_maxminddb/share/GeoIP" >&6;} MAXMINDDB_PREFIX=$with_maxminddb -else $as_nop - as_fn_error $? "GeoIP2 requested, but libmaxminddb not found" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "GeoIP2 requested, but libmaxminddb not found" "$LINENO" 5 ;; +esac fi @@ -19569,6 +20681,140 @@ +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep -e" >&5 +printf %s "checking for egrep -e... " >&6; } +if test ${ac_cv_path_EGREP_TRADITIONAL+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) if test -z "$EGREP_TRADITIONAL"; then + ac_path_EGREP_TRADITIONAL_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in grep ggrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue +# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found. + # Check for GNU $ac_path_EGREP_TRADITIONAL +case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #( +*GNU*) + ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_found=:;; +#( +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'EGREP_TRADITIONAL' >> "conftest.nl" + "$ac_path_EGREP_TRADITIONAL" -E 'EGR(EP|AC)_TRADITIONAL$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_TRADITIONAL_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" + ac_path_EGREP_TRADITIONAL_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_TRADITIONAL_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP_TRADITIONAL"; then + : + fi +else + ac_cv_path_EGREP_TRADITIONAL=$EGREP_TRADITIONAL +fi + + if test "$ac_cv_path_EGREP_TRADITIONAL" +then : + ac_cv_path_EGREP_TRADITIONAL="$ac_cv_path_EGREP_TRADITIONAL -E" +else case e in #( + e) if test -z "$EGREP_TRADITIONAL"; then + ac_path_EGREP_TRADITIONAL_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_prog in egrep + do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP_TRADITIONAL="$as_dir$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP_TRADITIONAL" || continue +# Check for GNU ac_path_EGREP_TRADITIONAL and select it if it is found. + # Check for GNU $ac_path_EGREP_TRADITIONAL +case `"$ac_path_EGREP_TRADITIONAL" --version 2>&1` in #( +*GNU*) + ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" ac_path_EGREP_TRADITIONAL_found=:;; +#( +*) + ac_count=0 + printf %s 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + printf "%s\n" 'EGREP_TRADITIONAL' >> "conftest.nl" + "$ac_path_EGREP_TRADITIONAL" 'EGR(EP|AC)_TRADITIONAL$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_TRADITIONAL_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP_TRADITIONAL="$ac_path_EGREP_TRADITIONAL" + ac_path_EGREP_TRADITIONAL_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_TRADITIONAL_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP_TRADITIONAL"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP_TRADITIONAL=$EGREP_TRADITIONAL +fi + ;; +esac +fi ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP_TRADITIONAL" >&5 +printf "%s\n" "$ac_cv_path_EGREP_TRADITIONAL" >&6; } + EGREP_TRADITIONAL=$ac_cv_path_EGREP_TRADITIONAL + @@ -19609,8 +20855,14 @@ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char pthread_join (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char pthread_join (void); int main (void) { @@ -19704,7 +20956,7 @@ _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1 + $EGREP_TRADITIONAL "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1 then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5 printf "%s\n" "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;} @@ -19734,8 +20986,8 @@ if test ${ax_cv_PTHREAD_CLANG+y} then : printf %s "(cached) " >&6 -else $as_nop - ax_cv_PTHREAD_CLANG=no +else case e in #( + e) ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -19747,14 +20999,15 @@ _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1 + $EGREP_TRADITIONAL "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1 then : ax_cv_PTHREAD_CLANG=yes fi rm -rf conftest* fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG" >&6; } @@ -19804,8 +21057,9 @@ if test "x$ax_pthread_check_macro" = "x--" then : ax_pthread_check_cond=0 -else $as_nop - ax_pthread_check_cond="!defined($ax_pthread_check_macro)" +else case e in #( + e) ax_pthread_check_cond="!defined($ax_pthread_check_macro)" ;; +esac fi @@ -19839,8 +21093,8 @@ if test ${ac_cv_prog_ax_pthread_config+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ax_pthread_config"; then +else case e in #( + e) if test -n "$ax_pthread_config"; then ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -19863,7 +21117,8 @@ IFS=$as_save_IFS test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" -fi +fi ;; +esac fi ax_pthread_config=$ac_cv_prog_ax_pthread_config if test -n "$ax_pthread_config"; then @@ -19996,8 +21251,8 @@ if test ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+y} then : printf %s "(cached) " >&6 -else $as_nop - ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown +else case e in #( + e) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second @@ -20043,7 +21298,8 @@ ax_pthread_try=no fi ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; } @@ -20070,8 +21326,8 @@ if test ${ax_cv_PTHREAD_JOINABLE_ATTR+y} then : printf %s "(cached) " >&6 -else $as_nop - ax_cv_PTHREAD_JOINABLE_ATTR=unknown +else case e in #( + e) ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -20091,7 +21347,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext done - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5 printf "%s\n" "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; } @@ -20111,14 +21368,15 @@ if test ${ax_cv_PTHREAD_SPECIAL_FLAGS+y} then : printf %s "(cached) " >&6 -else $as_nop - ax_cv_PTHREAD_SPECIAL_FLAGS=no +else case e in #( + e) ax_cv_PTHREAD_SPECIAL_FLAGS=no case $target_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5 printf "%s\n" "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; } @@ -20134,8 +21392,8 @@ if test ${ax_cv_PTHREAD_PRIO_INHERIT+y} then : printf %s "(cached) " >&6 -else $as_nop - cat confdefs.h - <<_ACEOF >conftest.$ac_ext +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int @@ -20150,12 +21408,14 @@ if ac_fn_c_try_link "$LINENO" then : ax_cv_PTHREAD_PRIO_INHERIT=yes -else $as_nop - ax_cv_PTHREAD_PRIO_INHERIT=no +else case e in #( + e) ax_cv_PTHREAD_PRIO_INHERIT=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 printf "%s\n" "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } @@ -20205,8 +21465,8 @@ if test ${ac_cv_prog_PTHREAD_CC+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$PTHREAD_CC"; then +else case e in #( + e) if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -20228,7 +21488,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then @@ -20255,8 +21516,8 @@ if test ${ac_cv_prog_PTHREAD_CXX+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$PTHREAD_CXX"; then +else case e in #( + e) if test -n "$PTHREAD_CXX"; then ac_cv_prog_PTHREAD_CXX="$PTHREAD_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -20278,7 +21539,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi PTHREAD_CXX=$ac_cv_prog_PTHREAD_CXX if test -n "$PTHREAD_CXX"; then @@ -20357,9 +21619,10 @@ printf "%s\n" "#define HAVE_PTHREAD_MUTEX_ADAPTIVE_NP 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -20402,15 +21665,21 @@ if test ${ac_cv_search_sched_yield+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char sched_yield (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sched_yield (void); int main (void) { @@ -20441,11 +21710,13 @@ if test ${ac_cv_search_sched_yield+y} then : -else $as_nop - ac_cv_search_sched_yield=no +else case e in #( + e) ac_cv_search_sched_yield=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sched_yield" >&5 printf "%s\n" "$ac_cv_search_sched_yield" >&6; } @@ -20816,8 +22087,8 @@ if test ${ac_cv_c_undeclared_builtin_options+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_save_CFLAGS=$CFLAGS +else case e in #( + e) ac_save_CFLAGS=$CFLAGS ac_cv_c_undeclared_builtin_options='cannot detect' for ac_arg in '' -fno-builtin; do CFLAGS="$ac_save_CFLAGS $ac_arg" @@ -20836,8 +22107,8 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - # This test program should compile successfully. +else case e in #( + e) # This test program should compile successfully. # No library function is consistently available on # freestanding implementations, so test against a dummy # declaration. Include always-available headers on the @@ -20865,26 +22136,29 @@ if test x"$ac_arg" = x then : ac_cv_c_undeclared_builtin_options='none needed' -else $as_nop - ac_cv_c_undeclared_builtin_options=$ac_arg +else case e in #( + e) ac_cv_c_undeclared_builtin_options=$ac_arg ;; +esac fi break fi -rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done CFLAGS=$ac_save_CFLAGS - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_undeclared_builtin_options" >&5 printf "%s\n" "$ac_cv_c_undeclared_builtin_options" >&6; } case $ac_cv_c_undeclared_builtin_options in #( 'cannot detect') : - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "cannot make $CC report undeclared builtins -See \`config.log' for more details" "$LINENO" 5; } ;; #( +See 'config.log' for more details" "$LINENO" 5; } ;; #( 'none needed') : ac_c_undeclared_builtin_options='' ;; #( *) : @@ -20896,8 +22170,9 @@ if test "x$ac_cv_have_decl_UV_UDP_MMSG_FREE" = xyes then : ac_have_decl=1 -else $as_nop - ac_have_decl=0 +else case e in #( + e) ac_have_decl=0 ;; +esac fi printf "%s\n" "#define HAVE_DECL_UV_UDP_MMSG_FREE $ac_have_decl" >>confdefs.h ac_fn_check_decl "$LINENO" "UV_UDP_MMSG_CHUNK" "ac_cv_have_decl_UV_UDP_MMSG_CHUNK" "#include @@ -20905,8 +22180,9 @@ if test "x$ac_cv_have_decl_UV_UDP_MMSG_CHUNK" = xyes then : ac_have_decl=1 -else $as_nop - ac_have_decl=0 +else case e in #( + e) ac_have_decl=0 ;; +esac fi printf "%s\n" "#define HAVE_DECL_UV_UDP_MMSG_CHUNK $ac_have_decl" >>confdefs.h @@ -20930,19 +22206,21 @@ printf "%s\n" "#define HAVE_DECL_UV_UDP_RECVMMSG 0" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ac_fn_check_decl "$LINENO" "UV_UDP_RECVMMSG" "ac_cv_have_decl_UV_UDP_RECVMMSG" "#include " "$ac_c_undeclared_builtin_options" "CFLAGS" if test "x$ac_cv_have_decl_UV_UDP_RECVMMSG" = xyes then : ac_have_decl=1 -else $as_nop - ac_have_decl=0 +else case e in #( + e) ac_have_decl=0 ;; +esac fi printf "%s\n" "#define HAVE_DECL_UV_UDP_RECVMMSG $ac_have_decl" >>confdefs.h - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -20952,8 +22230,9 @@ if test "x$ac_cv_have_decl_UV_UDP_LINUX_RECVERR" = xyes then : ac_have_decl=1 -else $as_nop - ac_have_decl=0 +else case e in #( + e) ac_have_decl=0 ;; +esac fi printf "%s\n" "#define HAVE_DECL_UV_UDP_LINUX_RECVERR $ac_have_decl" >>confdefs.h @@ -21017,8 +22296,9 @@ if test ${enable_doh+y} then : enableval=$enable_doh; -else $as_nop - enable_doh=yes +else case e in #( + e) enable_doh=yes ;; +esac fi @@ -21028,8 +22308,9 @@ if test ${with_libnghttp2+y} then : withval=$with_libnghttp2; -else $as_nop - with_libnghttp2="auto" +else case e in #( + e) with_libnghttp2="auto" ;; +esac fi @@ -21194,8 +22475,9 @@ if test ${enable_pthread_rwlock+y} then : enableval=$enable_pthread_rwlock; -else $as_nop - enable_pthread_rwlock=no +else case e in #( + e) enable_pthread_rwlock=no ;; +esac fi @@ -21209,8 +22491,9 @@ then : printf "%s\n" "#define HAVE_PTHREAD_RWLOCK_RDLOCK 1" >>confdefs.h -else $as_nop - as_fn_error $? "pthread_rwlock_rdlock requested but not found" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "pthread_rwlock_rdlock requested but not found" "$LINENO" 5 ;; +esac fi done @@ -21228,7 +22511,20 @@ fi -CRYPTO=OpenSSL +ac_func= +for ac_item in $ac_func_c_list +do + if test $ac_func; then + ac_fn_c_check_func "$LINENO" $ac_func ac_cv_func_$ac_func + if eval test \"x\$ac_cv_func_$ac_func\" = xyes; then + echo "#define $ac_item 1" >> confdefs.h + fi + ac_func= + else + ac_func=$ac_item + fi +done + # # OpenSSL/LibreSSL is mandatory @@ -21299,8 +22595,8 @@ if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ +else case e in #( + e) ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done @@ -21325,9 +22621,10 @@ as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in +case `"$ac_path_SED" --version 2>&1` in #( *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +#( *) ac_count=0 printf %s 0123456789 >"conftest.in" @@ -21362,7 +22659,8 @@ else ac_cv_path_SED=$SED fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } @@ -21382,8 +22680,8 @@ ;; esac -else $as_nop - +else case e in #( + e) # if pkg-config is installed and openssl has installed a .pc file, # then use that information and don't search ssldirs if test -n "$ac_tool_prefix"; then @@ -21394,8 +22692,8 @@ if test ${ac_cv_prog_PKG_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$PKG_CONFIG"; then +else case e in #( + e) if test -n "$PKG_CONFIG"; then ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -21417,7 +22715,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi PKG_CONFIG=$ac_cv_prog_PKG_CONFIG if test -n "$PKG_CONFIG"; then @@ -21439,8 +22738,8 @@ if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_PKG_CONFIG"; then +else case e in #( + e) if test -n "$ac_ct_PKG_CONFIG"; then ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -21462,7 +22761,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG if test -n "$ac_ct_PKG_CONFIG"; then @@ -21503,7 +22803,8 @@ ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" fi - + ;; +esac fi @@ -21570,15 +22871,16 @@ printf "%s\n" "yes" >&6; } : -else $as_nop - +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "OpenSSL/LibreSSL not found -See \`config.log' for more details" "$LINENO" 5; } - +See 'config.log' for more details" "$LINENO" 5; } + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -21601,8 +22903,8 @@ if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ +else case e in #( + e) ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done @@ -21627,9 +22929,10 @@ as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in +case `"$ac_path_SED" --version 2>&1` in #( *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +#( *) ac_count=0 printf %s 0123456789 >"conftest.in" @@ -21664,7 +22967,8 @@ else ac_cv_path_SED=$SED fi - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } @@ -21684,8 +22988,8 @@ ;; esac -else $as_nop - +else case e in #( + e) # if pkg-config is installed and openssl has installed a .pc file, # then use that information and don't search ssldirs if test -n "$ac_tool_prefix"; then @@ -21696,8 +23000,8 @@ if test ${ac_cv_prog_PKG_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$PKG_CONFIG"; then +else case e in #( + e) if test -n "$PKG_CONFIG"; then ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -21719,7 +23023,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi PKG_CONFIG=$ac_cv_prog_PKG_CONFIG if test -n "$PKG_CONFIG"; then @@ -21741,8 +23046,8 @@ if test ${ac_cv_prog_ac_ct_PKG_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_PKG_CONFIG"; then +else case e in #( + e) if test -n "$ac_ct_PKG_CONFIG"; then ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -21764,7 +23069,8 @@ done IFS=$as_save_IFS -fi +fi ;; +esac fi ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG if test -n "$ac_ct_PKG_CONFIG"; then @@ -21805,7 +23111,8 @@ ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr" fi - + ;; +esac fi @@ -21872,15 +23179,16 @@ printf "%s\n" "yes" >&6; } : -else $as_nop - +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "OpenSSL/LibreSSL not found -See \`config.log' for more details" "$LINENO" 5; } - +See 'config.log' for more details" "$LINENO" 5; } + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -22019,11 +23327,12 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "not found -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -22217,19 +23526,20 @@ for ac_func in EVP_DigestSignInit EVP_DigestVerifyInit do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | sed "$as_sed_sh"` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes" then : cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_func" | sed "$as_sed_cpp"` 1 _ACEOF : -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "EVP_DigestSignInit/EVP_DigestVerifyInit support in OpenSSL is mandatory. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi done @@ -22251,11 +23561,12 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "not found. ECDSA P-256 support in OpenSSL is mandatory. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -22276,11 +23587,12 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "not found. ECDSA P-384 support in OpenSSL is mandatory. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -22304,9 +23616,10 @@ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -22330,9 +23643,10 @@ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -22347,11 +23661,12 @@ then : printf "%s\n" "#define HAVE_EVP_SHA1 1" >>confdefs.h : -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "SHA-1 support in OpenSSL is mandatory. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi done @@ -22362,19 +23677,20 @@ for ac_func in EVP_sha224 EVP_sha256 EVP_sha384 EVP_sha512 do : - as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | $as_tr_sh` + as_ac_var=`printf "%s\n" "ac_cv_func_$ac_func" | sed "$as_sed_sh"` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes" then : cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_func" | sed "$as_sed_cpp"` 1 _ACEOF : -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "SHA-2 support in OpenSSL is mandatory. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi done @@ -22448,8 +23764,9 @@ if test ${enable_fips_mode+y} then : enableval=$enable_fips_mode; -else $as_nop - enable_fips_mode="no" +else case e in #( + e) enable_fips_mode="no" ;; +esac fi @@ -22464,10 +23781,10 @@ if test "x$ac_cv_func_FIPS_mode" != xyes -a "x$ac_cv_func_EVP_default_properties_enable_fips" != xyes then : - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "OpenSSL FIPS mode requested but not available. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } fi ;; #( no) : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 @@ -22547,8 +23864,9 @@ if test ${with_gssapi+y} then : withval=$with_gssapi; -else $as_nop - with_gssapi="auto" +else case e in #( + e) with_gssapi="auto" ;; +esac fi @@ -22567,8 +23885,8 @@ if test ${ac_cv_path_KRB5_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - case $KRB5_CONFIG in +else case e in #( + e) case $KRB5_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path. ;; @@ -22593,6 +23911,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG @@ -22617,8 +23936,8 @@ if test ${ac_cv_path_KRB5_CONFIG+y} then : printf %s "(cached) " >&6 -else $as_nop - case $KRB5_CONFIG in +else case e in #( + e) case $KRB5_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_KRB5_CONFIG="$KRB5_CONFIG" # Let the user override the test with a path. ;; @@ -22643,6 +23962,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi KRB5_CONFIG=$ac_cv_path_KRB5_CONFIG @@ -22752,19 +24072,21 @@ then : printf "%s\n" "#define HAVE_GSSAPI_GSSAPI_H 1" >>confdefs.h -else $as_nop - for ac_header in gssapi.h +else case e in #( + e) for ac_header in gssapi.h do : ac_fn_c_check_header_compile "$LINENO" "gssapi.h" "ac_cv_header_gssapi_h" "$ac_includes_default" if test "x$ac_cv_header_gssapi_h" = xyes then : printf "%s\n" "#define HAVE_GSSAPI_H 1" >>confdefs.h -else $as_nop - as_fn_error $? "neither gssapi/gssapi.h nor gssapi.h found" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "neither gssapi/gssapi.h nor gssapi.h found" "$LINENO" 5 ;; +esac fi -done +done ;; +esac fi done @@ -22796,8 +24118,9 @@ then : printf "%s\n" "#define HAVE_GSS_ACQUIRE_CRED 1" >>confdefs.h -else $as_nop - as_fn_error $? "linking with $GSSAPI_LIBS does not work" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "linking with $GSSAPI_LIBS does not work" "$LINENO" 5 ;; +esac fi done @@ -22940,19 +24263,21 @@ then : printf "%s\n" "#define HAVE_KRB5_KRB5_H 1" >>confdefs.h -else $as_nop - for ac_header in krb5.h +else case e in #( + e) for ac_header in krb5.h do : ac_fn_c_check_header_compile "$LINENO" "krb5.h" "ac_cv_header_krb5_h" "$ac_includes_default" if test "x$ac_cv_header_krb5_h" = xyes then : printf "%s\n" "#define HAVE_KRB5_H 1" >>confdefs.h -else $as_nop - as_fn_error $? "neither krb5/krb5.h nor krb5 found" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "neither krb5/krb5.h nor krb5 found" "$LINENO" 5 ;; +esac fi -done +done ;; +esac fi done @@ -22964,8 +24289,9 @@ then : printf "%s\n" "#define HAVE_KRB5_INIT_CONTEXT 1" >>confdefs.h -else $as_nop - as_fn_error $? "linking with $KRB5_LIBS failed" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "linking with $KRB5_LIBS failed" "$LINENO" 5 ;; +esac fi done @@ -23057,8 +24383,9 @@ if test ${with_lmdb+y} then : withval=$with_lmdb; : -else $as_nop - with_lmdb="auto" +else case e in #( + e) with_lmdb="auto" ;; +esac fi @@ -23216,15 +24543,21 @@ if test ${ac_cv_search_mdb_env_create+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char mdb_env_create (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char mdb_env_create (void); int main (void) { @@ -23255,11 +24588,13 @@ if test ${ac_cv_search_mdb_env_create+y} then : -else $as_nop - ac_cv_search_mdb_env_create=no +else case e in #( + e) ac_cv_search_mdb_env_create=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_mdb_env_create" >&5 printf "%s\n" "$ac_cv_search_mdb_env_create" >&6; } @@ -23324,8 +24659,8 @@ ac_lib_lmdb_found=yes break -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } LMDB_CFLAGS="" LMDB_LIBS="" @@ -23383,13 +24718,15 @@ - + ;; +esac fi -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi done @@ -23486,15 +24823,21 @@ if test ${ac_cv_search_mdb_env_create+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char mdb_env_create (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char mdb_env_create (void); int main (void) { @@ -23525,11 +24868,13 @@ if test ${ac_cv_search_mdb_env_create+y} then : -else $as_nop - ac_cv_search_mdb_env_create=no +else case e in #( + e) ac_cv_search_mdb_env_create=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_mdb_env_create" >&5 printf "%s\n" "$ac_cv_search_mdb_env_create" >&6; } @@ -23594,8 +24939,8 @@ ac_lib_lmdb_found=yes break -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } LMDB_CFLAGS="" LMDB_LIBS="" @@ -23653,13 +24998,15 @@ - + ;; +esac fi -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi done @@ -23760,15 +25107,21 @@ if test ${ac_cv_search_mdb_env_create+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char mdb_env_create (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char mdb_env_create (void); int main (void) { @@ -23799,11 +25152,13 @@ if test ${ac_cv_search_mdb_env_create+y} then : -else $as_nop - ac_cv_search_mdb_env_create=no +else case e in #( + e) ac_cv_search_mdb_env_create=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_mdb_env_create" >&5 printf "%s\n" "$ac_cv_search_mdb_env_create" >&6; } @@ -23867,8 +25222,8 @@ ac_lib_lmdb_found=yes -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } LMDB_CFLAGS="" LMDB_LIBS="" @@ -23926,13 +25281,15 @@ - + ;; +esac fi -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi ;; esac @@ -23975,8 +25332,9 @@ if test ${with_libxml2+y} then : withval=$with_libxml2; -else $as_nop - with_libxml2="auto" +else case e in #( + e) with_libxml2="auto" ;; +esac fi @@ -24130,8 +25488,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -24141,7 +25499,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else LIBXML2_CFLAGS=$pkg_cv_LIBXML2_CFLAGS LIBXML2_LIBS=$pkg_cv_LIBXML2_LIBS @@ -24173,8 +25531,9 @@ if test ${with_json_c+y} then : withval=$with_json_c; -else $as_nop - with_json_c="detect" +else case e in #( + e) with_json_c="detect" ;; +esac fi @@ -24328,8 +25687,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -24339,7 +25698,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else JSON_C_CFLAGS=$pkg_cv_JSON_C_CFLAGS JSON_C_LIBS=$pkg_cv_JSON_C_LIBS @@ -24375,8 +25734,9 @@ if test ${with_zlib+y} then : withval=$with_zlib; -else $as_nop - with_zlib="auto" +else case e in #( + e) with_zlib="auto" ;; +esac fi @@ -24530,8 +25890,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -24541,7 +25901,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else ZLIB_CFLAGS=$pkg_cv_ZLIB_CFLAGS ZLIB_LIBS=$pkg_cv_ZLIB_LIBS @@ -24571,15 +25931,21 @@ if test ${ac_cv_search_backtrace_symbols+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char backtrace_symbols (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char backtrace_symbols (void); int main (void) { @@ -24610,11 +25976,13 @@ if test ${ac_cv_search_backtrace_symbols+y} then : -else $as_nop - ac_cv_search_backtrace_symbols=no +else case e in #( + e) ac_cv_search_backtrace_symbols=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_backtrace_symbols" >&5 printf "%s\n" "$ac_cv_search_backtrace_symbols" >&6; } @@ -24669,11 +26037,12 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} +else case e in #( + e) { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "IPv6 support is mandatory -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -24687,8 +26056,9 @@ if test ${enable_tcp_fastopen+y} then : enableval=$enable_tcp_fastopen; -else $as_nop - enable_tcp_fastopen="yes" +else case e in #( + e) enable_tcp_fastopen="yes" ;; +esac fi @@ -24738,8 +26108,9 @@ if test ${with_readline+y} then : withval=$with_readline; -else $as_nop - with_readline="auto" +else case e in #( + e) with_readline="auto" ;; +esac fi @@ -25349,8 +26720,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -25360,7 +26731,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else READLINE_CFLAGS=$pkg_cv_READLINE_CFLAGS READLINE_LIBS=$pkg_cv_READLINE_LIBS @@ -25443,8 +26814,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -25454,7 +26825,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else READLINE_CFLAGS=$pkg_cv_READLINE_CFLAGS READLINE_LIBS=$pkg_cv_READLINE_LIBS @@ -25537,8 +26908,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -25548,7 +26919,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else READLINE_CFLAGS=$pkg_cv_READLINE_CFLAGS READLINE_LIBS=$pkg_cv_READLINE_LIBS @@ -25673,8 +27044,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -25684,7 +27055,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else LIBCAP_CFLAGS=$pkg_cv_LIBCAP_CFLAGS LIBCAP_LIBS=$pkg_cv_LIBCAP_LIBS @@ -25735,14 +27106,15 @@ then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } GEN_NEED_OPTARG="-DNEED_OPTARG=1" printf "%s\n" "#define NEED_OPTARG 1" >>confdefs.h - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -25771,9 +27143,10 @@ printf "%s\n" "#define HAVE_STAT_NSEC 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -25821,10 +27194,11 @@ printf "%s\n" "#define HAVE_BUILTIN_UNREACHABLE 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -25854,10 +27228,11 @@ printf "%s\n" "#define HAVE_BUILTIN_CLZ 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -25887,10 +27262,11 @@ printf "%s\n" "#define HAVE_BUILTIN_ADD_OVERFLOW 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -25917,10 +27293,11 @@ printf "%s\n" "#define HAVE_BUILTIN_SUB_OVERFLOW 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -25949,10 +27326,11 @@ printf "%s\n" "#define HAVE_BUILTIN_MUL_OVERFLOW 1" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext @@ -25965,8 +27343,9 @@ if test ${enable_fixed_rrset+y} then : enableval=$enable_fixed_rrset; -else $as_nop - enable_fixed_rrset="no" +else case e in #( + e) enable_fixed_rrset="no" ;; +esac fi if test "$enable_fixed_rrset" = "yes" @@ -25986,8 +27365,9 @@ if test ${enable_dnstap+y} then : enableval=$enable_dnstap; -else $as_nop - enable_dnstap=no +else case e in #( + e) enable_dnstap=no ;; +esac fi @@ -26052,17 +27432,17 @@ # Put the nasty error message in config.log where it belongs echo "$DNSTAP_PKG_ERRORS" >&5 - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "Required libraries (fstrm, protobuf-c) were not found, please install them. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "Required libraries (fstrm, protobuf-c) were not found, please install them. -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else DNSTAP_CFLAGS=$pkg_cv_DNSTAP_CFLAGS DNSTAP_LIBS=$pkg_cv_DNSTAP_LIBS @@ -26077,8 +27457,8 @@ if test ${ac_cv_path_FSTRM_CAPTURE+y} then : printf %s "(cached) " >&6 -else $as_nop - case $FSTRM_CAPTURE in +else case e in #( + e) case $FSTRM_CAPTURE in [\\/]* | ?:[\\/]*) ac_cv_path_FSTRM_CAPTURE="$FSTRM_CAPTURE" # Let the user override the test with a path. ;; @@ -26103,6 +27483,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi FSTRM_CAPTURE=$ac_cv_path_FSTRM_CAPTURE @@ -26122,8 +27503,8 @@ if test ${ac_cv_path_PROTOC_C+y} then : printf %s "(cached) " >&6 -else $as_nop - case $PROTOC_C in +else case e in #( + e) case $PROTOC_C in [\\/]* | ?:[\\/]*) ac_cv_path_PROTOC_C="$PROTOC_C" # Let the user override the test with a path. ;; @@ -26148,6 +27529,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi PROTOC_C=$ac_cv_path_PROTOC_C @@ -26197,8 +27579,8 @@ if test ${ac_cv_path_SPHINX_BUILD+y} then : printf %s "(cached) " >&6 -else $as_nop - case $SPHINX_BUILD in +else case e in #( + e) case $SPHINX_BUILD in [\\/]* | ?:[\\/]*) ac_cv_path_SPHINX_BUILD="$SPHINX_BUILD" # Let the user override the test with a path. ;; @@ -26223,6 +27605,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi SPHINX_BUILD=$ac_cv_path_SPHINX_BUILD @@ -26276,8 +27659,8 @@ if test ${ac_cv_path_DOXYGEN+y} then : printf %s "(cached) " >&6 -else $as_nop - case $DOXYGEN in +else case e in #( + e) case $DOXYGEN in [\\/]* | ?:[\\/]*) ac_cv_path_DOXYGEN="$DOXYGEN" # Let the user override the test with a path. ;; @@ -26302,6 +27685,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi DOXYGEN=$ac_cv_path_DOXYGEN @@ -26332,8 +27716,8 @@ if test ${ac_cv_path_CURL+y} then : printf %s "(cached) " >&6 -else $as_nop - case $CURL in +else case e in #( + e) case $CURL in [\\/]* | ?:[\\/]*) ac_cv_path_CURL="$CURL" # Let the user override the test with a path. ;; @@ -26359,6 +27743,7 @@ test -z "$ac_cv_path_CURL" && ac_cv_path_CURL="curl" ;; +esac ;; esac fi CURL=$ac_cv_path_CURL @@ -26386,8 +27771,8 @@ if test ${ac_cv_path_NC+y} then : printf %s "(cached) " >&6 -else $as_nop - case $NC in +else case e in #( + e) case $NC in [\\/]* | ?:[\\/]*) ac_cv_path_NC="$NC" # Let the user override the test with a path. ;; @@ -26412,6 +27797,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi NC=$ac_cv_path_NC @@ -26443,8 +27829,9 @@ if test ${with_libidn2+y} then : withval=$with_libidn2; with_libidn2="$withval" -else $as_nop - with_libidn2="no" +else case e in #( + e) with_libidn2="no" ;; +esac fi case $with_libidn2 in #( @@ -26521,8 +27908,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -26532,7 +27919,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else LIBIDN2_CFLAGS=$pkg_cv_LIBIDN2_CFLAGS LIBIDN2_LIBS=$pkg_cv_LIBIDN2_LIBS @@ -26626,8 +28013,9 @@ then : printf "%s\n" "#define HAVE_IDN2_H 1" >>confdefs.h -else $as_nop - as_fn_error $? "idn2.h not found" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "idn2.h not found" "$LINENO" 5 ;; +esac fi done @@ -26636,15 +28024,21 @@ if test ${ac_cv_search_idn2_to_ascii_lz+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char idn2_to_ascii_lz (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char idn2_to_ascii_lz (void); int main (void) { @@ -26675,11 +28069,13 @@ if test ${ac_cv_search_idn2_to_ascii_lz+y} then : -else $as_nop - ac_cv_search_idn2_to_ascii_lz=no +else case e in #( + e) ac_cv_search_idn2_to_ascii_lz=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_idn2_to_ascii_lz" >&5 printf "%s\n" "$ac_cv_search_idn2_to_ascii_lz" >&6; } @@ -26691,8 +28087,9 @@ printf "%s\n" "#define HAVE_LIBIDN2 1" >>confdefs.h -else $as_nop - as_fn_error $? "libidn2 requested, but not found" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "libidn2 requested, but not found" "$LINENO" 5 ;; +esac fi @@ -26763,8 +28160,9 @@ if test ${with_cmocka+y} then : withval=$with_cmocka; -else $as_nop - with_cmocka=detect +else case e in #( + e) with_cmocka=detect ;; +esac fi @@ -26919,8 +28317,8 @@ elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -26930,7 +28328,7 @@ See the pkg-config man page for more details. To get pkg-config, see . -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } else CMOCKA_CFLAGS=$pkg_cv_CMOCKA_CFLAGS CMOCKA_LIBS=$pkg_cv_CMOCKA_LIBS @@ -26965,8 +28363,9 @@ if test ${with_jemalloc+y} then : withval=$with_jemalloc; -else $as_nop - with_jemalloc=detect +else case e in #( + e) with_jemalloc=detect ;; +esac fi @@ -27038,12 +28437,12 @@ for ac_header in malloc_np.h jemalloc/jemalloc.h do : - as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | sed "$as_sed_sh"` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_header" | sed "$as_sed_cpp"` 1 _ACEOF save_LIBS="$LIBS" @@ -27054,15 +28453,21 @@ if test ${ac_cv_search_sdallocx+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char sdallocx (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sdallocx (void); int main (void) { @@ -27093,11 +28498,13 @@ if test ${ac_cv_search_sdallocx+y} then : -else $as_nop - ac_cv_search_sdallocx=no +else case e in #( + e) ac_cv_search_sdallocx=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sdallocx" >&5 printf "%s\n" "$ac_cv_search_sdallocx" >&6; } @@ -27129,12 +28536,12 @@ for ac_header in malloc_np.h jemalloc/jemalloc.h do : - as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | sed "$as_sed_sh"` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_header" | sed "$as_sed_cpp"` 1 _ACEOF save_LIBS="$LIBS" @@ -27145,15 +28552,21 @@ if test ${ac_cv_search_sdallocx+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char sdallocx (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sdallocx (void); int main (void) { @@ -27184,11 +28597,13 @@ if test ${ac_cv_search_sdallocx+y} then : -else $as_nop - ac_cv_search_sdallocx=no +else case e in #( + e) ac_cv_search_sdallocx=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sdallocx" >&5 printf "%s\n" "$ac_cv_search_sdallocx" >&6; } @@ -27253,8 +28668,9 @@ printf "%s\n" "#define HAVE_JEMALLOC 1" >>confdefs.h -else $as_nop - as_fn_error $? "jemalloc not found" "$LINENO" 5 +else case e in #( + e) as_fn_error $? "jemalloc not found" "$LINENO" 5 ;; +esac fi @@ -27325,12 +28741,12 @@ for ac_header in malloc_np.h jemalloc/jemalloc.h do : - as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | sed "$as_sed_sh"` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_header" | sed "$as_sed_cpp"` 1 _ACEOF save_LIBS="$LIBS" @@ -27341,15 +28757,21 @@ if test ${ac_cv_search_sdallocx+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char sdallocx (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sdallocx (void); int main (void) { @@ -27380,11 +28802,13 @@ if test ${ac_cv_search_sdallocx+y} then : -else $as_nop - ac_cv_search_sdallocx=no +else case e in #( + e) ac_cv_search_sdallocx=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sdallocx" >&5 printf "%s\n" "$ac_cv_search_sdallocx" >&6; } @@ -27416,12 +28840,12 @@ for ac_header in malloc_np.h jemalloc/jemalloc.h do : - as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` + as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | sed "$as_sed_sh"` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF -#define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `printf "%s\n" "HAVE_$ac_header" | sed "$as_sed_cpp"` 1 _ACEOF save_LIBS="$LIBS" @@ -27432,15 +28856,21 @@ if test ${ac_cv_search_sdallocx+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char sdallocx (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char sdallocx (void); int main (void) { @@ -27471,11 +28901,13 @@ if test ${ac_cv_search_sdallocx+y} then : -else $as_nop - ac_cv_search_sdallocx=no +else case e in #( + e) ac_cv_search_sdallocx=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sdallocx" >&5 printf "%s\n" "$ac_cv_search_sdallocx" >&6; } @@ -27541,10 +28973,11 @@ printf "%s\n" "#define HAVE_JEMALLOC 1" >>confdefs.h with_jemalloc=yes -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: jemalloc not found; performance will be reduced" >&5 +else case e in #( + e) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: jemalloc not found; performance will be reduced" >&5 printf "%s\n" "$as_me: WARNING: jemalloc not found; performance will be reduced" >&2;} - with_jemalloc=no + with_jemalloc=no ;; +esac fi @@ -27579,8 +29012,9 @@ if test ${enable_leak_detection+y} then : enableval=$enable_leak_detection; -else $as_nop - enable_leak_detection=no +else case e in #( + e) enable_leak_detection=no ;; +esac fi case $enable_leak_detection in #( @@ -27600,8 +29034,9 @@ if test ${enable_singletrace+y} then : enableval=$enable_singletrace; enable_singletrace="$enableval" -else $as_nop - enable_singletrace="no" +else case e in #( + e) enable_singletrace="no" ;; +esac fi @@ -27630,8 +29065,9 @@ if test ${enable_querytrace+y} then : enableval=$enable_querytrace; enable_querytrace="$enableval" -else $as_nop - enable_querytrace="$enable_singletrace" +else case e in #( + e) enable_querytrace="$enable_singletrace" ;; +esac fi @@ -27669,8 +29105,9 @@ if test ${enable_auto_validation+y} then : enableval=$enable_auto_validation; : -else $as_nop - enable_auto_validation=yes +else case e in #( + e) enable_auto_validation=yes ;; +esac fi if test "$enable_auto_validation" = "no" @@ -27716,12 +29153,13 @@ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } -else $as_nop - +else case e in #( + e) librpz_have_attr=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext @@ -27730,8 +29168,9 @@ if test ${enable_dnsrps_dl+y} then : enableval=$enable_dnsrps_dl; enable_dnsrps_dl="$enableval" -else $as_nop - enable_dnsrps_dl="yes" +else case e in #( + e) enable_dnsrps_dl="yes" ;; +esac fi @@ -27746,8 +29185,9 @@ if test ${with_dnsrps_libname+y} then : withval=$with_dnsrps_libname; librpz_name="$withval" -else $as_nop - librpz_name="librpz.so" +else case e in #( + e) librpz_name="librpz.so" ;; +esac fi @@ -27757,8 +29197,9 @@ if test ${with_dnsrps_dir+y} then : withval=$with_dnsrps_dir; librpz_path="$withval/$librpz_name" -else $as_nop - librpz_path="$librpz_name" +else case e in #( + e) librpz_path="$librpz_name" ;; +esac fi @@ -27769,8 +29210,8 @@ dnsrps_lib_open=2 -else $as_nop - +else case e in #( + e) dnsrps_lib_open=1 # Add librpz.so to linked libraries if we are not using dlopen() { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing librpz_client_create" >&5 @@ -27778,15 +29219,21 @@ if test ${ac_cv_search_librpz_client_create+y} then : printf %s "(cached) " >&6 -else $as_nop - ac_func_search_save_LIBS=$LIBS +else case e in #( + e) ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -char librpz_client_create (); + builtin and then its argument prototype would still apply. + The 'extern "C"' is for builds by C++ compilers; + although this is not generally supported in C code supporting it here + has little cost and some practical benefit (sr 110532). */ +#ifdef __cplusplus +extern "C" +#endif +char librpz_client_create (void); int main (void) { @@ -27817,11 +29264,13 @@ if test ${ac_cv_search_librpz_client_create+y} then : -else $as_nop - ac_cv_search_librpz_client_create=no +else case e in #( + e) ac_cv_search_librpz_client_create=no ;; +esac fi rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS +LIBS=$ac_func_search_save_LIBS ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_librpz_client_create" >&5 printf "%s\n" "$ac_cv_search_librpz_client_create" >&6; } @@ -27830,12 +29279,14 @@ then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" -else $as_nop - dnsrps_lib_open=0 - dnsrps_avail=no +else case e in #( + e) dnsrps_lib_open=0 + dnsrps_avail=no ;; +esac fi - + ;; +esac fi printf "%s\n" "#define DNSRPS_LIB_OPEN $dnsrps_lib_open" >>confdefs.h @@ -27846,8 +29297,9 @@ if test ${enable_dnsrps+y} then : enableval=$enable_dnsrps; enable_dnsrps=$enableval -else $as_nop - enable_dnsrps=no +else case e in #( + e) enable_dnsrps=no ;; +esac fi @@ -27892,8 +29344,8 @@ if test ${ax_cv_have_func_attribute_constructor+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -27914,15 +29366,18 @@ if grep -- -Wattributes conftest.err then : ax_cv_have_func_attribute_constructor=no -else $as_nop - ax_cv_have_func_attribute_constructor=yes +else case e in #( + e) ax_cv_have_func_attribute_constructor=yes ;; +esac fi -else $as_nop - ax_cv_have_func_attribute_constructor=no +else case e in #( + e) ax_cv_have_func_attribute_constructor=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_constructor" >&5 printf "%s\n" "$ax_cv_have_func_attribute_constructor" >&6; } @@ -27944,8 +29399,8 @@ if test ${ax_cv_have_func_attribute_destructor+y} then : printf %s "(cached) " >&6 -else $as_nop - +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -27966,15 +29421,18 @@ if grep -- -Wattributes conftest.err then : ax_cv_have_func_attribute_destructor=no -else $as_nop - ax_cv_have_func_attribute_destructor=yes +else case e in #( + e) ax_cv_have_func_attribute_destructor=yes ;; +esac fi -else $as_nop - ax_cv_have_func_attribute_destructor=no +else case e in #( + e) ax_cv_have_func_attribute_destructor=no ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext - + ;; +esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_have_func_attribute_destructor" >&5 printf "%s\n" "$ax_cv_have_func_attribute_destructor" >&6; } @@ -27999,8 +29457,9 @@ if test ${enable_tracing+y} then : enableval=$enable_tracing; -else $as_nop - enable_tracing=auto +else case e in #( + e) enable_tracing=auto ;; +esac fi @@ -28014,8 +29473,8 @@ if test ${ac_cv_path_DTRACE+y} then : printf %s "(cached) " >&6 -else $as_nop - case $DTRACE in +else case e in #( + e) case $DTRACE in [\\/]* | ?:[\\/]*) ac_cv_path_DTRACE="$DTRACE" # Let the user override the test with a path. ;; @@ -28040,6 +29499,7 @@ IFS=$as_save_IFS ;; +esac ;; esac fi DTRACE=$ac_cv_path_DTRACE @@ -28099,9 +29559,10 @@ if ac_fn_c_try_compile "$LINENO" then : -else $as_nop - enable_tracing=no - +else case e in #( + e) enable_tracing=no + ;; +esac fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ;; #( *) : @@ -28166,8 +29627,9 @@ if test ${with_zonedb+y} then : withval=$with_zonedb; -else $as_nop - with_zonedb=qp +else case e in #( + e) with_zonedb=qp ;; +esac fi zonedb="qpzone" @@ -28193,8 +29655,9 @@ if test ${with_cachedb+y} then : withval=$with_cachedb; -else $as_nop - with_cachedb=qp +else case e in #( + e) with_cachedb=qp ;; +esac fi cachedb="qpcache" @@ -28263,7 +29726,7 @@ # Misc -ac_config_files="$ac_config_files util/check-make-install" +ac_config_files="$ac_config_files util/check-make-install.sh" # @@ -28280,8 +29743,8 @@ # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the +# 'ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* 'ac_cv_foo' will be assigned the # following values. _ACEOF @@ -28311,14 +29774,14 @@ (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote + # 'set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) - # `set' quotes correctly as required by POSIX, so do not add quotes. + # 'set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | @@ -28387,6 +29850,18 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; +esac +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi + if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' @@ -28420,6 +29895,12 @@ Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +# Check whether --enable-year2038 was given. +if test ${enable_year2038+y} +then : + enableval=$enable_year2038; +fi + if test -z "${HOST_MACOS_TRUE}" && test -z "${HOST_MACOS_FALSE}"; then as_fn_error $? "conditional \"HOST_MACOS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -28533,7 +30014,6 @@ # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh -as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh @@ -28542,12 +30022,13 @@ # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST -else $as_nop - case `(set -o) 2>/dev/null` in #( +else case e in #( + e) case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; +esac ;; esac fi @@ -28619,7 +30100,7 @@ ;; esac -# We did not find ourselves, most probably we were run as `sh COMMAND' +# We did not find ourselves, most probably we were run as 'sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 @@ -28648,7 +30129,6 @@ } # as_fn_error - # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. @@ -28688,11 +30168,12 @@ { eval $1+=\$2 }' -else $as_nop - as_fn_append () +else case e in #( + e) as_fn_append () { eval $1=\$$1\$2 - } + } ;; +esac fi # as_fn_append # as_fn_arith ARG... @@ -28706,11 +30187,12 @@ { as_val=$(( $* )) }' -else $as_nop - as_fn_arith () +else case e in #( + e) as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` - } + } ;; +esac fi # as_fn_arith @@ -28793,9 +30275,9 @@ if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # 1) On MSYS, both 'ln -s file dir' and 'ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; 'ln -s' creates a wrapper executable. + # In both cases, we have to default to 'cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then @@ -28876,10 +30358,12 @@ as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +as_sed_cpp="y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed '$as_sed_cpp'" # deprecated # Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" +as_sed_sh="y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed '$as_sed_sh'" # deprecated exec 6>&1 @@ -28894,8 +30378,8 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by BIND $as_me 9.20.11, which was -generated by GNU Autoconf 2.71. Invocation command line was +This file was extended by BIND $as_me 9.20.15, which was +generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -28927,7 +30411,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions +'$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. @@ -28963,11 +30447,11 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -BIND config.status 9.20.11 -configured by $0, generated by GNU Autoconf 2.71, +BIND config.status 9.20.15 +configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" -Copyright (C) 2021 Free Software Foundation, Inc. +Copyright (C) 2023 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." @@ -29029,8 +30513,8 @@ ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; + as_fn_error $? "ambiguous option: '$1' +Try '$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ @@ -29038,8 +30522,8 @@ ac_cs_silent=: ;; # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; + -*) as_fn_error $? "unrecognized option: '$1' +Try '$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; @@ -29431,9 +30915,9 @@ "bin/tests/system/start.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/start.sh" ;; "bin/tests/system/stop.sh") CONFIG_FILES="$CONFIG_FILES bin/tests/system/stop.sh" ;; "fuzz/Makefile") CONFIG_FILES="$CONFIG_FILES fuzz/Makefile" ;; - "util/check-make-install") CONFIG_FILES="$CONFIG_FILES util/check-make-install" ;; + "util/check-make-install.sh") CONFIG_FILES="$CONFIG_FILES util/check-make-install.sh" ;; - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + *) as_fn_error $? "invalid argument: '$ac_config_target'" "$LINENO" 5;; esac done @@ -29453,7 +30937,7 @@ # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. +# after its creation but before its name has been assigned to '$tmp'. $debug || { tmp= ac_tmp= @@ -29477,7 +30961,7 @@ # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. +# This happens for instance with './config.status config.h'. if test -n "$CONFIG_FILES"; then @@ -29635,13 +31119,13 @@ # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. +# This happens for instance with './config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF -# Transform confdefs.h into an awk script `defines.awk', embedded as +# Transform confdefs.h into an awk script 'defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. @@ -29751,7 +31235,7 @@ esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :L* | :C*:*) as_fn_error $? "invalid tag '$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac @@ -29773,19 +31257,19 @@ -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. + # because $ac_f cannot contain ':'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + as_fn_error 1 "cannot find input file: '$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done - # Let's still pretend it is `configure' which instantiates (i.e., don't + # Let's still pretend it is 'configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` @@ -29918,7 +31402,7 @@ esac _ACEOF -# Neutralize VPATH when `$srcdir' = `.'. +# Neutralize VPATH when '$srcdir' = '.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 @@ -29949,9 +31433,9 @@ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable 'datarootdir' which seems to be undefined. Please make sure it is defined" >&5 -printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable 'datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" @@ -30106,15 +31590,15 @@ (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in '$ac_pwd':" >&5 +printf "%s\n" "$as_me: error: in '$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). -See \`config.log' for more details" "$LINENO" 5; } +See 'config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} @@ -30143,13 +31627,13 @@ # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 -# Copyright (C) 2014 Free Software Foundation, Inc. +# Copyright (C) 2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of of the License, or +# the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you @@ -30530,7 +32014,7 @@ # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# "absolute",i.e. impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute @@ -30833,12 +32317,13 @@ if test "$GCC" = "yes" then : $CC --version 2>&1 | sed 's/^/ /' -else $as_nop - case $host in #( +else case e in #( + e) case $host in #( *-solaris*) : $CC -V 2>&1 | sed 's/^/ /' ;; #( *) : $CC --version 2>&1 | sed 's/^/ /' ;; +esac ;; esac fi echo "CFLAGS: $STD_CFLAGS $CFLAGS" diff -Nru bind9-9.20.11/configure.ac bind9-9.20.15/configure.ac --- bind9-9.20.11/configure.ac 2025-07-04 09:42:08.297327290 +0000 +++ bind9-9.20.15/configure.ac 2025-10-18 10:16:12.528731762 +0000 @@ -16,7 +16,7 @@ # m4_define([bind_VERSION_MAJOR], 9)dnl m4_define([bind_VERSION_MINOR], 20)dnl -m4_define([bind_VERSION_PATCH], 11)dnl +m4_define([bind_VERSION_PATCH], 15)dnl m4_define([bind_VERSION_EXTRA], )dnl m4_define([bind_DESCRIPTION], [(Stable Release)])dnl m4_define([bind_SRCID], [m4_esyscmd_s([git rev-parse --short HEAD | cut -b1-7])])dnl @@ -653,7 +653,7 @@ ]) AM_CONDITIONAL([USE_ISC_RWLOCK], [test "$enable_pthread_rwlock" != "yes"]) -CRYPTO=OpenSSL +AC_CHECK_FUNCS_ONCE([arc4random]) # # OpenSSL/LibreSSL is mandatory @@ -1669,7 +1669,7 @@ # Misc -AC_CONFIG_FILES([util/check-make-install]) +AC_CONFIG_FILES([util/check-make-install.sh]) # # Do it diff -Nru bind9-9.20.11/debian/changelog bind9-9.20.15/debian/changelog --- bind9-9.20.11/debian/changelog 2025-07-27 10:04:56.000000000 +0000 +++ bind9-9.20.15/debian/changelog 2025-10-22 16:00:33.000000000 +0000 @@ -1,3 +1,14 @@ +bind9 (1:9.20.15-1~deb13u1) trixie-security; urgency=high + + * New upstream version 9.20.15 + - [CVE-2025-8677]: DNSSEC validation fails if matching but invalid + DNSKEY is found + - [CVE-2025-40778]: Address various spoofing attacks. + - [CVE-2025-40780]: Cache-poisoning due to weak pseudo-random number + generator + + -- OndÅ™ej Surý Wed, 22 Oct 2025 18:00:33 +0200 + bind9 (1:9.20.11-4) unstable; urgency=medium * Remove named.conf.default-zones.dpkg-dist from /etc/bind diff -Nru bind9-9.20.11/debian/gbp.conf bind9-9.20.15/debian/gbp.conf --- bind9-9.20.11/debian/gbp.conf 2025-07-27 10:04:56.000000000 +0000 +++ bind9-9.20.15/debian/gbp.conf 2025-10-22 16:00:33.000000000 +0000 @@ -1,5 +1,5 @@ [DEFAULT] -debian-branch = debian/9.20 +debian-branch = debian/trixie upstream-branch = upstream/9.20 pristine-tar = True diff -Nru bind9-9.20.11/depcomp bind9-9.20.15/depcomp --- bind9-9.20.11/depcomp 2025-07-04 09:43:11.927828195 +0000 +++ bind9-9.20.15/depcomp 2025-10-18 10:17:05.143511705 +0000 @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2018-03-07.03; # UTC +scriptversion=2024-06-19.01; # UTC -# Copyright (C) 1999-2021 Free Software Foundation, Inc. +# Copyright (C) 1999-2024 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -47,11 +47,13 @@ libtool Whether libtool is used (yes/no). Report bugs to . +GNU Automake home page: . +General help using GNU software: . EOF exit $? ;; -v | --v*) - echo "depcomp $scriptversion" + echo "depcomp (GNU Automake) $scriptversion" exit $? ;; esac @@ -113,7 +115,6 @@ # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz -digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then @@ -128,7 +129,7 @@ rm -f "$tmpdepfile" -# Avoid interferences from the environment. +# Avoid interference from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We @@ -198,8 +199,8 @@ ;; gcc) -## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. -## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## Note that this doesn't just cater to obsolete pre-3.x GCC compilers. +## but also to in-use compilers like IBM xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: diff -Nru bind9-9.20.11/doc/Makefile.in bind9-9.20.15/doc/Makefile.in --- bind9-9.20.11/doc/Makefile.in 2025-07-04 09:43:11.150810088 +0000 +++ bind9-9.20.15/doc/Makefile.in 2025-10-18 10:17:04.364499775 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -69,6 +69,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -357,8 +359,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -637,8 +641,8 @@ clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -743,3 +747,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/doc/arm/Makefile.in bind9-9.20.15/doc/arm/Makefile.in --- bind9-9.20.11/doc/arm/Makefile.in 2025-07-04 09:43:11.167810484 +0000 +++ bind9-9.20.15/doc/arm/Makefile.in 2025-10-18 10:17:04.382500050 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -72,6 +72,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -300,8 +302,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -642,16 +646,16 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am @@ -784,3 +788,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/doc/arm/advanced.inc.rst bind9-9.20.15/doc/arm/advanced.inc.rst --- bind9-9.20.11/doc/arm/advanced.inc.rst 2025-07-04 09:42:08.300327360 +0000 +++ bind9-9.20.15/doc/arm/advanced.inc.rst 2025-10-18 10:16:12.530731793 +0000 @@ -31,11 +31,10 @@ :iscman:`named` at startup. See :ref:`dynamic_update_policies` for more details. Dynamic updates using Kerberos-signed requests can be made using the -TKEY/GSS protocol, either by setting the :any:`tkey-gssapi-keytab` option -or by setting both the :any:`tkey-gssapi-credential` and -:any:`tkey-domain` options. Once enabled, Kerberos-signed requests are -matched against the update policies for the zone, using the Kerberos -principal as the signer for the request. +TKEY/GSS protocol, by setting the :any:`tkey-gssapi-keytab` option. +Once enabled, Kerberos-signed requests are matched against the update +policies for the zone, using the Kerberos principal as the signer for +the request. Updating of secure zones (zones using DNSSEC) follows :rfc:`3007`: RRSIG, NSEC, and NSEC3 records affected by updates are automatically regenerated diff -Nru bind9-9.20.11/doc/arm/changelog.rst bind9-9.20.15/doc/arm/changelog.rst --- bind9-9.20.11/doc/arm/changelog.rst 2025-07-04 09:42:08.300327360 +0000 +++ bind9-9.20.15/doc/arm/changelog.rst 2025-10-18 10:16:12.531731809 +0000 @@ -18,6 +18,10 @@ development. Regular users should refer to :ref:`Release Notes ` for changes relevant to them. +.. include:: ../changelog/changelog-9.20.15.rst +.. include:: ../changelog/changelog-9.20.14.rst +.. include:: ../changelog/changelog-9.20.13.rst +.. include:: ../changelog/changelog-9.20.12.rst .. include:: ../changelog/changelog-9.20.11.rst .. include:: ../changelog/changelog-9.20.10.rst .. include:: ../changelog/changelog-9.20.9.rst diff -Nru bind9-9.20.11/doc/arm/conf.py bind9-9.20.15/doc/arm/conf.py --- bind9-9.20.11/doc/arm/conf.py 2025-07-04 09:42:08.301327384 +0000 +++ bind9-9.20.15/doc/arm/conf.py 2025-10-18 10:16:12.531731809 +0000 @@ -185,6 +185,8 @@ # The master toctree document. master_doc = "index" +smartquotes = False + # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for diff -Nru bind9-9.20.11/doc/arm/index.rst bind9-9.20.15/doc/arm/index.rst --- bind9-9.20.11/doc/arm/index.rst 2025-07-04 09:42:08.303327431 +0000 +++ bind9-9.20.15/doc/arm/index.rst 2025-10-18 10:16:12.534731855 +0000 @@ -36,9 +36,9 @@ :name: appendices :maxdepth: 2 + dnssec-guide + manpages + general notes changelog - dnssec-guide history - general - manpages diff -Nru bind9-9.20.11/doc/arm/notes.rst bind9-9.20.15/doc/arm/notes.rst --- bind9-9.20.11/doc/arm/notes.rst 2025-07-04 09:42:08.304327454 +0000 +++ bind9-9.20.15/doc/arm/notes.rst 2025-10-18 10:16:12.535731871 +0000 @@ -45,6 +45,10 @@ found at https://gitlab.isc.org/isc-projects/bind9/-/wikis/Known-Issues-in-BIND-9.20 +.. include:: ../notes/notes-9.20.15.rst +.. include:: ../notes/notes-9.20.14.rst +.. include:: ../notes/notes-9.20.13.rst +.. include:: ../notes/notes-9.20.12.rst .. include:: ../notes/notes-9.20.11.rst .. include:: ../notes/notes-9.20.10.rst .. include:: ../notes/notes-9.20.9.rst diff -Nru bind9-9.20.11/doc/arm/platforms.inc.rst bind9-9.20.15/doc/arm/platforms.inc.rst --- bind9-9.20.11/doc/arm/platforms.inc.rst 2025-07-04 09:42:08.304327454 +0000 +++ bind9-9.20.15/doc/arm/platforms.inc.rst 2025-10-18 10:16:12.535731871 +0000 @@ -43,10 +43,10 @@ Current versions of BIND 9 are fully supported and regularly tested on the following systems: -- Debian 12 +- Debian 12, 13 - Ubuntu LTS 22.04, 24.04 - Fedora 42 -- Red Hat Enterprise Linux / CentOS / AlmaLinux 8, 9 +- Red Hat Enterprise Linux / CentOS / AlmaLinux 8, 9, 10 - FreeBSD 13.4, 14.2 - Alpine Linux 3.22 diff -Nru bind9-9.20.11/doc/arm/reference.rst bind9-9.20.15/doc/arm/reference.rst --- bind9-9.20.11/doc/arm/reference.rst 2025-07-04 09:42:08.306327501 +0000 +++ bind9-9.20.15/doc/arm/reference.rst 2025-10-18 10:16:12.537731902 +0000 @@ -1461,24 +1461,7 @@ principal which the server can acquire through the default system key file, normally ``/etc/krb5.keytab``. The location of the keytab file can be overridden using the :any:`tkey-gssapi-keytab` option. Normally this - principal is of the form ``DNS/server.domain``. To use - GSS-TSIG, :any:`tkey-domain` must also be set if a specific keytab is - not set with :any:`tkey-gssapi-keytab`. - -.. namedconf:statement:: tkey-domain - :tags: security - :short: Sets the domain appended to the names of all shared keys generated with ``TKEY``. - - This domain is appended to the names of all shared keys generated with - ``TKEY``. When a client requests a ``TKEY`` exchange, it may or may - not specify the desired name for the key. If present, the name of the - shared key is ``client-specified part`` + :any:`tkey-domain`. - Otherwise, the name of the shared key is ``random hex digits`` - + :any:`tkey-domain`. In most cases, the ``domainname`` - should be the server's domain name, or an otherwise nonexistent - subdomain like ``_tkey.domainname``. If using GSS-TSIG, - this variable must be defined, unless a specific keytab - is indicated using :any:`tkey-gssapi-keytab`. + principal is of the form ``DNS/server.domain``. .. namedconf:statement:: dump-file :tags: logging @@ -1634,7 +1617,7 @@ :short: Disables DNSSEC algorithms from a specified zone. This disables the specified DNSSEC algorithms at and below the specified - name. Multiple :any:`disable-algorithms` statements are allowed. Only + zone. Multiple :any:`disable-algorithms` statements are allowed. Only the best-match :any:`disable-algorithms` clause is used to determine the algorithms. @@ -2246,6 +2229,8 @@ autodetection of DNS COOKIE support to determine when to retry a request over TCP. + For DNAME lookups the default is ``yes`` and it is enforced. Servers + serving DNAME must correctly support DNS over TCP. .. note:: If a UDP response is signed using TSIG, :iscman:`named` accepts it even if @@ -2791,7 +2776,8 @@ Forwarding ^^^^^^^^^^ -The forwarding facility can be used to create a large site-wide cache on +The forwarding facility sends queries which cannot be answered using local data +to different resolvers. This can be used to create a large site-wide cache on a few servers, reducing traffic over links to external name servers. It can also be used to allow queries by servers that do not have direct access to the Internet, but that wish to look up exterior names anyway. @@ -2802,7 +2788,7 @@ :tags: query :short: Allows or disallows fallback to recursion if forwarding has failed; it is always used in conjunction with the :any:`forwarders` statement. - This option is only meaningful if the forwarders list is not empty. A + This option is only meaningful if the :any:`forwarders` list is not empty. A value of ``first`` is the default and causes the server to query the forwarders first; if that does not answer the question, the server then looks for the answer itself. If ``only`` is @@ -2810,9 +2796,10 @@ .. namedconf:statement:: forwarders :tags: query - :short: Defines one or more hosts to which queries are forwarded. + :short: Defines one or more resolvers to which queries are forwarded. - This specifies a list of IP addresses to which queries are forwarded. The + This specifies a list of IP addresses of DNS resolvers, to which queries + which cannot be answered using locally available data are forwarded. The default is the empty list (no forwarding). Each address in the list can be associated with an optional port number and a TLS transport. A default port number and a TLS transport can be set for the entire list. @@ -4273,7 +4260,8 @@ ``--enable-fixed-rrset`` at compile time. ``random`` - Records are returned in a random order. + Records are returned in a non-deterministic order. The random ordering + doesn't guarantee uniform distribution of all permutations. ``cyclic`` Records are returned in a cyclic round-robin order, rotating by one @@ -5331,6 +5319,15 @@ RPZ to delete answers that would otherwise contain :rfc:`1918` values on the externally visible name server or view. +Also by default, when :iscman:`named` is started it may start answering to +queries before the response policy zones are completely loaded and processed. +This can be changed with the ``servfail-until-ready yes`` option, in which case +incoming requests will result in SERVFAIL answer, until all the response policy +zones are ready. Note that if one or more response policy zones fail to load, +:iscman:`named` starts responding to queries according to those zones that did +load. Note, that enabling this option has no effect when a DNS Response Policy +Service (DNSRPS) interface is used. + Also by default, RPZ actions are applied only to DNS requests that either do not request DNSSEC metadata (DO=0) or when no DNSSEC records are available for the requested name in the original zone (not the response @@ -6643,6 +6640,16 @@ ``insecure``. In this specific case, the existing key files should be moved to the zone's ``key-directory`` from the new configuration. +.. namedconf:statement:: manual-mode + :tags: dnssec + :short: Run key management in a manual mode. + + If enabled, BIND 9 does not automatically start and progress key rollovers, + instead the change is logged. Only after manual confirmation with + :option:`rndc dnssec -step ` the change is made. + + This feature is off by default. + .. namedconf:statement:: offline-ksk :tags: dnssec :short: Specifies whether the DNSKEY, CDS, and CDNSKEY RRsets are being signed offline. @@ -7171,20 +7178,24 @@ .. namedconf:statement:: type stub :tags: zone - :short: Contains a duplicate of the NS records of a primary zone. + :short: Contains a duplicate of the NS records of a zone. - A stub zone is similar to a secondary zone, except that it replicates only - the NS records of a primary zone instead of the entire zone. Stub zones - are not a standard part of the DNS; they are a feature specific to the - BIND implementation. - - Stub zones can be used to eliminate the need for a glue NS record in a parent - zone, at the expense of maintaining a stub zone entry and a set of name - server addresses in :iscman:`named.conf`. This usage is not recommended for - new configurations, and BIND 9 supports it only in a limited way. If a BIND 9 - primary, serving a parent zone, has child stub - zones configured, all the secondary servers for the parent zone also need to - have the same child stub zones configured. + A stub zone specifies a set of name servers to use when contacting the zone + for the first time. A stub zone overrides any NS records (delegations) + that might exist in the parent zone. Once an authoritative server is + reached, the NS records from that server are honored. + + A stub zone can work around missing or broken delegations, but comes at + expense of maintaining a set of name server addresses in + :iscman:`named.conf`. + + .. warning:: Use of stub zones is not recommended. Proper delegation + with NS records in the parent zone should be used. + + + :iscman:`named` queries authoritative servers configured as :any:`primaries` + to obtain up-to-date NS records. These new NS records are then used + to obtain answers from a given zone. Stub zones can also be used as a way to force the resolution of a given domain to use a particular set of authoritative servers. For example, the @@ -7192,19 +7203,37 @@ configured with stub zones for ``10.in-addr.arpa`` to use a set of internal name servers as the authoritative servers for that domain. + If a BIND 9 primary, serving a parent zone, has child stub zones configured, + all the secondary servers for the parent zone also need to have the same + child stub zones configured. + + Stub zones are not a standard part of the DNS; they are a feature specific + to the BIND implementation. + + .. namedconf:statement:: type static-stub :tags: zone - :short: Contains a duplicate of the NS records of a primary zone, but statically configured rather than transferred from a primary server. + :short: Contains statically configured NS records for a zone. - A static-stub zone is similar to a stub zone, with the following - exceptions: the zone data is statically configured, rather than - transferred from a primary server; and when recursion is necessary for a query - that matches a static-stub zone, the locally configured data (name server - names and glue addresses) is always used, even if different authoritative - information is cached. + A static-stub zone specifies a set of name servers to use to resolve *all* + queries for the given zone. A stub zone overrides any NS records + (delegations) that might exist in the parent zone, and also any records + received from the otherwise-authoritative server. + + Like a :any:`stub ` zone, this can work around missing or broken + delegations at the parent. Unlike stub, static-stub also overrides any NS + records offered by the specified servers. + + When recursion is necessary for a query that matches a static-stub zone, + the locally configured data (name server names and glue addresses) is + always used, even if different authoritative information is cached. + + The zone data is configured via the :any:`server-addresses` and + :any:`server-names` zone statements. These must point to authoritative + servers. - Zone data is configured via the :any:`server-addresses` and :any:`server-names` - zone options. + .. warning:: Use of static-stub zones is not recommended. Proper delegation + with NS records in the parent zone should be used. The zone data is maintained in the form of NS and (if necessary) glue A or AAAA RRs internally, which can be seen by dumping zone databases with @@ -7215,7 +7244,7 @@ Since the data is statically configured, no zone maintenance action takes place for a static-stub zone. For example, there is no periodic refresh - attempt, and an incoming notify message is rejected with an rcode + attempt, and an incoming :ref:`NOTIFY ` message is rejected with an rcode of NOTAUTH. Each static-stub zone is configured with internally generated NS and (if @@ -7478,7 +7507,7 @@ :tags: query, zone :short: Specifies a list of IP addresses to which queries should be sent in recursive resolution for a static-stub zone. - This option is only meaningful for static-stub zones. This is a list of IP addresses + This option is only meaningful for :any:`static-stub ` zones. This is a list of IP addresses to which queries should be sent in recursive resolution for the zone. A non-empty list for this option internally configures the apex NS RR with associated glue A or AAAA RRs. @@ -7503,7 +7532,7 @@ :tags: zone :short: Specifies a list of domain names of name servers that act as authoritative servers of a static-stub zone. - This option is only meaningful for static-stub zones. This is a list of domain names + This option is only meaningful for :any:`static-stub ` zones. This is a list of domain names of name servers that act as authoritative servers of the static-stub zone. These names are resolved to IP addresses when :iscman:`named` needs to send queries to these servers. For this supplemental diff -Nru bind9-9.20.11/doc/changelog/changelog-9.20.12.rst bind9-9.20.15/doc/changelog/changelog-9.20.12.rst --- bind9-9.20.11/doc/changelog/changelog-9.20.12.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/changelog/changelog-9.20.12.rst 2025-10-18 10:16:12.539731933 +0000 @@ -0,0 +1,140 @@ +.. 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. + +BIND 9.20.12 +------------ + +New Features +~~~~~~~~~~~~ + +- Support for parsing the DSYNC record has been added. ``f440fe712d`` + + :gl:`#5440` :gl:`!10820` + +Feature Changes +~~~~~~~~~~~~~~~ + +- Adaptive memory allocation strategy for qp-tries. ``9a046cbed5`` + + qp-tries allocate their nodes (twigs) in chunks to reduce allocator + pressure and improve memory locality. The choice of chunk size + presents a tradeoff: larger chunks benefit qp-tries with many values + (as seen in large zones and resolvers) but waste memory in smaller use + cases. + + Previously, our fixed chunk size of 2^10 twigs meant that even an + empty qp-trie would consume 12KB of memory, while reducing this size + would negatively impact resolver performance. + + This MR implements an adaptive chunking strategy that tracks the size + of the most recently allocated chunk and doubles the chunk size for + each new allocation until reaching a predefined maximum. + + This approach effectively balances memory efficiency for small tries + while maintaining the performance benefits of larger chunk sizes for + bigger data structures. :gl:`#5445` :gl:`!10804` + +- Add deprecation warnings for RSASHA1, RSASHA1-NSEC3SHA1 and DS digest + type 1. ``5aefaa4b97`` + + RSASHA1 and RSASHA1-NSEC-SHA1 DNSKEY algorithms have been deprecated + by the IETF and should no longer be used for DNSSEC. DS digest type 1 + (SHA1) has also been deprecated. Validators are now expected to treat + these algorithms and digest as unknown, resulting in some zones being + treated as insecure when they were previously treated as secure. + Warnings have been added to named and tools when these algorithms and + this digest are being used for signing. + + Zones signed with RSASHA1 or RSASHA1-NSEC-SHA1 should be migrated to a + different DNSKEY algorithm. + + Zones with DS or CDS records with digest type 1 (SHA1) should be + updated to use a different digest type (e.g. SHA256) and the digest + type 1 records should be removed. + + Related to #5358 :gl:`!10738` + +Bug Fixes +~~~~~~~~~ + +- Stale RRsets in a CNAME chain were not always refreshed. + ``ed37c7825e`` + + With serve-stale enabled, a CNAME chain that contains a stale RRset, + the refresh query doesn't always properly refresh the stale RRsets. + This has been fixed. :gl:`#5243` :gl:`!10767` + +- Add RPZ extended DNS error for zones with a CNAME override policy + configured. ``39ad2016c1`` + + When the zone is configured with a CNAME override policy, or the + response policy zone contains a wildcard CNAME, the extended DNS error + code was not added. This has been fixed. :gl:`#5342` :gl:`!10819` + +- Fix a possible crash when adding a zone while recursing. + ``7a3ec8dd94`` + + A query for a zone that was not yet loaded may yield an unexpected + result such as a CNAME or DNAME, triggering an assertion failure. This + has been fixed. :gl:`#5357` :gl:`!10718` + +- Fix dig issues. ``8c50819aa8`` + + When used with the ``+keepopen`` option with a TCP connection, + iscman:`dig` could terminate unexpectedly in rare situations. + Additionally, iscman:`dig` could hang and fail to shutdown properly + when interrupted during a query. These have been fixed. :gl:`#5381` + :gl:`!10727` + +- Log dropped or slipped responses in the query-errors category. + ``47470b586d`` + + Responses which were dropped or slipped because of RRL (Response Rate + Limiting) were logged in the ``rate-limit`` category instead of the + ``query-errors`` category, as documented in ARM. This has been fixed. + :gl:`#5388` :gl:`!10725` + +- Separate out adbname type flags. ``fc689c6525`` + + There are three adbname flags that are used to identify different + types of adbname lookups when hashing rather than using multiple hash + tables. Separate these to their own structure element as these need + to be able to be read without locking the adbname structure. + :gl:`#5404` :gl:`!10695` + +- Synth-from-dnssec was not working in some scenarios. ``bc54f059e0`` + + Aggressive use of DNSSEC-Validated cache with NSEC was not working in + scenarios when no parent NSEC was not in cache. This has been fixed. + :gl:`#5422` :gl:`!10754` + +- Clean enough memory when adding new ADB names/entries under memory + pressure. ``b7e7923daa`` + + The ADB memory cleaning is opportunistic even when we are under memory + pressure (in the overmem condition). Split the opportunistic LRU + cleaning and overmem cleaning and make the overmem cleaning always + cleanup double of the newly allocated adbname/adbentry to ensure we + never allocate more memory than the assigned limit. :gl:`!10707` + +- Prevent spurious validation failures. ``3b98c7cc9d`` + + Under rare circumstances, validation could fail if multiple clients + simultaneously iterated the same set of signatures. + + References #3014 :gl:`!10815` + +- Rename variable called 'free' to prevent the clash with free() + ``7f25d92c5d`` + + :gl:`!10757` + + diff -Nru bind9-9.20.11/doc/changelog/changelog-9.20.13.rst bind9-9.20.15/doc/changelog/changelog-9.20.13.rst --- bind9-9.20.11/doc/changelog/changelog-9.20.13.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/changelog/changelog-9.20.13.rst 2025-10-18 10:16:12.539731933 +0000 @@ -0,0 +1,139 @@ +.. 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. + +BIND 9.20.13 +------------ + +New Features +~~~~~~~~~~~~ + +- Add manual mode configuration option to dnsec-policy. ``1e435b107f`` + + Add a new option ``manual-mode`` to :any:`dnssec-policy`. The intended + use is that if it is enabled, it will not automatically move to the + next state transition, but instead the transition is logged. Only + after manual confirmation with ``rndc dnssec -step`` the transition is + made. :gl:`#4606` :gl:`!10880` + +- Add a new 'servfail-until-ready' configuration option for RPZ. + ``925af17d21`` + + By default, when :iscman:`named` is started it may start answering to + queries before the response policy zones are completely loaded and + processed. This new feature gives an option to the users to tell + :iscman:`named` that incoming requests should result in SERVFAIL + answer until all the response policy zones are processed and ready. + Note that if one or more response policy zones fail to load, + :iscman:`named` starts responding to queries according to those zones + that did load. + + Note, that enabling this option has no effect when a DNS Response + Policy Service (DNSRPS) interface is used. :gl:`#5222` :gl:`!10889` + +- Support for parsing HHIT and BRID records has been added. + ``1f051af24d`` + + :gl:`#5444` :gl:`!10932` + +Removed Features +~~~~~~~~~~~~~~~~ + +- Deprecate the "tkey-gssapi-credential" statement. ``b239a70cac`` + + The :any:`tkey-gssapi-keytab` statement allows GSS-TSIG to be set up + in a simpler and more reliable way than using the + :any:`tkey-gssapi-credential` statement and setting environment + variables (e.g. ``KRB5_KTNAME``). Therefore, the + :any:`tkey-gssapi-credential` statement has been deprecated; + :any:`tkey-gssapi-keytab` should be used instead. + + For configurations currently using a combination of both + :any:`tkey-gssapi-keytab` *and* :any:`tkey-gssapi-credential`, the + latter should be dropped and the keytab pointed to by + :any:`tkey-gssapi-keytab` should now only contain the credential + previously specified by :any:`tkey-gssapi-credential`. :gl:`#4204` + :gl:`!10924` + +- Obsolete the "tkey-domain" statement. ``9352ae65d7`` + + Mark the ``tkey-domain`` statement as obsolete, since it has not had + any effect on server behavior since support for TKEY Mode 2 + (Diffie-Hellman) was removed (in BIND 9.20.0). :gl:`#4204` + :gl:`!10926` + +Feature Changes +~~~~~~~~~~~~~~~ + +- Update clang-format style with options added in newer versions. + ``0c2c477c31`` + + Add and apply InsertBraces statement to add missing curly braces + around one-line statements and use + ControlStatementsExceptControlMacros for SpaceBeforeParens to remove + space between foreach macro and the brace, e.g. `FOREACH (x) {` + becomes `FOREACH(x) {`. :gl:`!10864` + +Bug Fixes +~~~~~~~~~ + +- Ensure file descriptors 0-2 are in use. ``35dee6eb90`` + + libuv expect file descriptors <= STDERR_FILENO are in use. otherwise, + it may abort when closing a file descriptor it opened. :gl:`#5226` + :gl:`!10908` + +- Prevent spurious SERVFAILs for certain 0-TTL resource records. + ``6b266b222c`` + + Under certain circumstances, BIND 9 can return SERVFAIL when updating + existing entries in the cache with new NS, A, AAAA, or DS records with + 0-TTL. :gl:`#5294` :gl:`!10898` + +- Use DNS_RDATACOMMON_INIT to hide branch differences. ``a64df9729b`` + + Initialization of the common members of rdata type structures varies + across branches. Standardize it by using the `DNS_RDATACOMMON_INIT` + macro for all types, so that new types are more likely to use it, and + hence backport more cleanly. :gl:`#5467` :gl:`!10834` + +- RPZ canonical warning displays zone entry incorrectly. ``d833676515`` + + When an IPv6 rpz prefix entry is entered incorrectly the log message + was just displaying the prefix rather than the full entry. This has + been corrected. :gl:`#5491` :gl:`!10930` + +- Fix a catalog zone issue when having an unset 'default-primaries' + configuration clause. ``293e75af28`` + + A catalog zone with an unset ``default-primaries`` clause could cause + an unexpected termination of the :iscman:`named` process after two + reloading or reconfiguration commands. This has been fixed. + :gl:`#5494` :gl:`!10905` + +- Add and use __attribute__((nonnull)) in dnssec-signzone.c. + ``a8eed36d3e`` + + Clang 20 was spuriously warning about the possibility of passing a + NULL file pointer to `fprintf()`, which uses the 'nonnull' attribute. + To silence the warning, the functions calling `fprintf()` have been + marked with the same attribute to assure that NULL can't be passed to + them in the first place. + + Close #5487 :gl:`!10913` + +- RPZ 'servfail-until-ready': skip updating SERVFAIL cache. + ``af2fb26325`` + + In order to not pollute the SERVFAIL cache with the configured + SERVFAIL answers while RPZ is loading, set the NS_CLIENTATTR_NOSETFC + attribute for the client. :gl:`!10940` + + diff -Nru bind9-9.20.11/doc/changelog/changelog-9.20.14.rst bind9-9.20.15/doc/changelog/changelog-9.20.14.rst --- bind9-9.20.11/doc/changelog/changelog-9.20.14.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/changelog/changelog-9.20.14.rst 2025-10-18 10:16:12.539731933 +0000 @@ -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. + +BIND 9.20.14 +------------ + +.. note:: + + The BIND 9.20.14 release was withdrawn after the discovery of a + regression in a security fix in it during pre-release testing. diff -Nru bind9-9.20.11/doc/changelog/changelog-9.20.15.rst bind9-9.20.15/doc/changelog/changelog-9.20.15.rst --- bind9-9.20.11/doc/changelog/changelog-9.20.15.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/changelog/changelog-9.20.15.rst 2025-10-18 10:16:12.539731933 +0000 @@ -0,0 +1,133 @@ +.. 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. + +BIND 9.20.15 +------------ + +Security Fixes +~~~~~~~~~~~~~~ + +- [CVE-2025-8677] DNSSEC validation fails if matching but invalid DNSKEY + is found. ``0d676bf9f23`` + + Previously, if a matching but cryptographically invalid key was + encountered during DNSSEC validation, the key was skipped and not + counted towards validation failures. :iscman:`named` now treats such + DNSSEC keys as hard failures and the DNSSEC validation fails + immediately, instead of continuing with the next DNSKEYs in the RRset. + + ISC would like to thank Zuyao Xu and Xiang Li from the All-in-One + Security and Privacy Laboratory at Nankai University for bringing this + vulnerability to our attention. :gl:`#5343` + +- [CVE-2025-40778] Address various spoofing attacks. ``23de94fd236`` + + Previously, several issues could be exploited to poison a DNS cache + with spoofed records for zones which were not DNSSEC-signed or if the + resolver was configured to not do DNSSEC validation. These issues were + assigned CVE-2025-40778 and have now been fixed. + + As an additional layer of protection, :iscman:`named` no longer + accepts DNAME records or extraneous NS records in the AUTHORITY + section unless these are received via spoofing-resistant transport + (TCP, UDP with DNS cookies, TSIG, or SIG(0)). + + ISC would like to thank Yuxiao Wu, Yunyi Zhang, Baojun Liu, and Haixin + Duan from Tsinghua University for bringing this vulnerability to our + attention. :gl:`#5414` + +- [CVE-2025-40780] Cache-poisoning due to weak pseudo-random number + generator. ``34af35c2df8`` + + It was discovered during research for an upcoming academic paper that + a xoshiro128\*\* internal state can be recovered by an external 3rd + party, allowing the prediction of UDP ports and DNS IDs in outgoing + queries. This could lead to an attacker spoofing the DNS answers with + great efficiency and poisoning the DNS cache. + + The internal random generator has been changed to a cryptographically + secure pseudo-random generator. + + ISC would like to thank Prof. Amit Klein and Omer Ben Simhon from + Hebrew University of Jerusalem for bringing this vulnerability to our + attention. :gl:`#5484` + +New Features +~~~~~~~~~~~~ + +- Add dnssec-policy keys configuration check to named-checkconf. + ``1f5a0405f72`` + + A new option `-k` is added to `named-checkconf` that allows checking + the `dnssec-policy` `keys` configuration against the configured key + stores. If the found key files are not in sync with the given + `dnssec-policy`, the check will fail. + + This is useful to run before migrating to `dnssec-policy`. :gl:`#5486` + :gl:`!11011` + +Feature Changes +~~~~~~~~~~~~~~~ + +- Minor refactor of dst code. ``c6acbaa020b`` + + Convert the defines to enums. Initialize the tags more explicitly and + less ugly. :gl:`!11038` + +Bug Fixes +~~~~~~~~~ + +- Use signer name when disabling DNSSEC algorithms. ``986816baa74`` + + ``disable-algorithms`` could cause DNSSEC validation failures when the + parent zone was signed with the algorithms that were being disabled + for the child zone. This has been fixed; `disable-algorithms` now + works on a whole-of-zone basis. + + If the zone's name is at or below the ``disable-algorithms`` name the + algorithm is disabled for that zone, using deepest match when there + are multiple ``disable-algorithms`` clauses. :gl:`#5165` :gl:`!11014` + +- Rndc sign during ZSK rollover will now replace signatures. + ``d2f551140cd`` + + When performing a ZSK rollover, if the new DNSKEY is omnipresent, the + :option:`rndc sign` command now signs the zone completely with the + successor key, replacing all zone signatures from the predecessor key + with new ones. :gl:`#5483` :gl:`!11017` + +- Missing DNSSEC information when CD bit is set in query. + ``968a6be41fb`` + + The RRSIGs for glue records were not being cached correctly for CD=1 + queries. This has been fixed. :gl:`#5502` :gl:`!10956` + +- Preserve cache when reload fails and reload the server again. + ``975aeda10b4`` + + Fixes an issue where failing to reconfigure/reload the server would + prevent to preserved the views caches on the subsequent server + reconfiguration/reload. :gl:`#5523` :gl:`!10988` + +- Check plugin config before registering. ``e2260b80702`` + + In `named_config_parsefile()`, when checking the validity of + `named.conf`, the checking of plugin correctness was deliberately + postponed until the plugin is loaded and registered. However, the + checking was never actually done: the `plugin_register()` + implementation was called, but `plugin_check()` was not. + + `ns_plugin_register()` (used by `named`) now calls the check function + before the register function, and aborts if either one fails. + `ns_plugin_check()` (used by `named-checkconf`) calls only the check + function. :gl:`!11032` + + diff -Nru bind9-9.20.11/doc/man/Makefile.in bind9-9.20.15/doc/man/Makefile.in --- bind9-9.20.11/doc/man/Makefile.in 2025-07-04 09:43:11.188810974 +0000 +++ bind9-9.20.15/doc/man/Makefile.in 2025-10-18 10:17:04.403500372 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -72,6 +72,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -164,10 +166,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } man1dir = $(mandir)/man1 am__installdirs = "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man5dir)" \ @@ -340,8 +341,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -862,17 +865,17 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -$(am__rm_f) $(BUILT_SOURCES) + -$(am__rm_f) $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am @@ -1016,3 +1019,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/doc/man/dnssec-dsfromkey.1in bind9-9.20.15/doc/man/dnssec-dsfromkey.1in --- bind9-9.20.11/doc/man/dnssec-dsfromkey.1in 2025-07-04 09:44:08.185153309 +0000 +++ bind9-9.20.15/doc/man/dnssec-dsfromkey.1in 2025-10-18 10:17:58.823298478 +0000 @@ -41,28 +41,32 @@ \fBdnssec\-dsfromkey\fP [ \fB\-h\fP | \fB\-V\fP ] .SH DESCRIPTION .sp -The \fBdnssec\-dsfromkey\fP command outputs DS (Delegation Signer) resource records -(RRs), or CDS (Child DS) RRs with the \fI\%\-C\fP option. +The \fBdnssec\-dsfromkey\fP command outputs DS (Delegation +Signer) resource records (RRs), or CDS (Child DS) RRs with the +\fI\%\-C\fP option. .sp By default, only KSKs are converted (keys with flags = 257). The -\fI\%\-A\fP option includes ZSKs (flags = 256). Revoked keys are never -included. +\fI\%\-A\fP option includes ZSKs (flags = 256). Revoked keys are +never included. .sp The input keys can be specified in a number of ways: .sp -By default, \fBdnssec\-dsfromkey\fP reads a key file named in the format -\fBKnnnn.+aaa+iiiii.key\fP, as generated by \fI\%dnssec\-keygen\fP\&. +By default, \fBdnssec\-dsfromkey\fP reads a key file named in +the format \fBKnnnn.+aaa+iiiii.key\fP, as generated by +\fI\%dnssec\-keygen\fP\&. +.sp +With the \fI\%\-f file\fP option, \fBdnssec\-dsfromkey\fP +reads keys from a zone file or partial zone file (which can contain +just the DNSKEY records). .sp -With the \fI\%\-f file\fP option, \fBdnssec\-dsfromkey\fP reads keys from a zone -file or partial zone file (which can contain just the DNSKEY records). -.sp -With the \fI\%\-s\fP option, \fBdnssec\-dsfromkey\fP reads a \fBkeyset\-\fP file, -as generated by \fI\%dnssec\-keygen\fP \fI\%\-C\fP\&. +With the \fI\%\-s\fP option, \fBdnssec\-dsfromkey\fP reads a +\fBkeyset\-\fP file, as generated by \fI\%dnssec\-keygen\fP \fI\%\-C\fP\&. .SH OPTIONS .INDENT 0.0 .TP .B \-1 -This option is an abbreviation for \fI\%\-a SHA1\fP\&. +This option is an abbreviation for \fI\%\-a SHA1\fP\&. This +digest is deprecated. .UNINDENT .INDENT 0.0 .TP @@ -72,26 +76,28 @@ .INDENT 0.0 .TP .B \-a algorithm -This option specifies a digest algorithm to use when converting DNSKEY records to -DS records. This option can be repeated, so that multiple DS records -are created for each DNSKEY record. -.sp -The algorithm must be one of SHA\-1, SHA\-256, or SHA\-384. These values -are case\-insensitive, and the hyphen may be omitted. If no algorithm -is specified, the default is SHA\-256. +This option specifies a digest algorithm to use when converting +DNSKEY records to DS records. This option can be repeated, so +that multiple DS records are created for each DNSKEY record. +.sp +The algorithm must be one of SHA\-1 (deprecated), SHA\-256, or +SHA\-384. These values are case\-insensitive, and the hyphen may +be omitted. If no algorithm is specified, the default is SHA\-256. .UNINDENT .INDENT 0.0 .TP .B \-A -This option indicates that ZSKs are to be included when generating DS records. Without this option, only -keys which have the KSK flag set are converted to DS records and -printed. This option is only useful in \fI\%\-f\fP zone file mode. +This option indicates that ZSKs are to be included when generating +DS records. Without this option, only keys which have the KSK +flag set are converted to DS records and printed. This option +is only useful in \fI\%\-f\fP zone file mode. .UNINDENT .INDENT 0.0 .TP .B \-c class -This option specifies the DNS class; the default is IN. This option is only useful in \fI\%\-s\fP keyset -or \fI\%\-f\fP zone file mode. +This option specifies the DNS class; the default is IN. This +option is only useful in \fI\%\-s\fP keyset or \fI\%\-f\fP +zone file mode. .UNINDENT .INDENT 0.0 .TP @@ -101,10 +107,10 @@ .INDENT 0.0 .TP .B \-f file -This option sets zone file mode, in which the final dnsname argument of \fBdnssec\-dsfromkey\fP is the -DNS domain name of a zone whose master file can be read from -\fBfile\fP\&. If the zone name is the same as \fBfile\fP, then it may be -omitted. +This option sets zone file mode, in which the final dnsname +argument of \fBdnssec\-dsfromkey\fP is the DNS domain name +of a zone whose master file can be read from \fBfile\fP\&. If the +zone name is the same as \fBfile\fP, then it may be omitted. .sp If \fBfile\fP is \fB\-\fP, then the zone data is read from the standard input. This makes it possible to use the output of the \fI\%dig\fP @@ -120,18 +126,21 @@ .INDENT 0.0 .TP .B \-K directory -This option tells BIND 9 to look for key files or \fBkeyset\-\fP files in \fBdirectory\fP\&. +This option tells BIND 9 to look for key files or \fBkeyset\-\fP +files in \fBdirectory\fP\&. .UNINDENT .INDENT 0.0 .TP .B \-s -This option enables keyset mode, in which the final dnsname argument from \fBdnssec\-dsfromkey\fP is the DNS -domain name used to locate a \fBkeyset\-\fP file. +This option enables keyset mode, in which the final dnsname +argument from \fBdnssec\-dsfromkey\fP is the DNS domain name +used to locate a \fBkeyset\-\fP file. .UNINDENT .INDENT 0.0 .TP .B \-T TTL -This option specifies the TTL of the DS records. By default the TTL is omitted. +This option specifies the TTL of the DS records. By default the +TTL is omitted. .UNINDENT .INDENT 0.0 .TP diff -Nru bind9-9.20.11/doc/man/dnssec-keyfromlabel.1in bind9-9.20.15/doc/man/dnssec-keyfromlabel.1in --- bind9-9.20.11/doc/man/dnssec-keyfromlabel.1in 2025-07-04 09:44:08.264155158 +0000 +++ bind9-9.20.15/doc/man/dnssec-keyfromlabel.1in 2025-10-18 10:17:58.836298673 +0000 @@ -48,28 +48,32 @@ .INDENT 0.0 .TP .B \-a algorithm -This option selects the cryptographic algorithm. The value of \fBalgorithm\fP must -be one of RSASHA1, NSEC3RSASHA1, RSASHA256, RSASHA512, -ECDSAP256SHA256, ECDSAP384SHA384, ED25519, or ED448. +This option selects the cryptographic algorithm. The value of +\fBalgorithm\fP must be one of RSASHA1 (deprecated), NSEC3RSASHA1 +(deprecated), RSASHA256, RSASHA512, ECDSAP256SHA256, ECDSAP384SHA384, +ED25519, or ED448. .sp -These values are case\-insensitive. In some cases, abbreviations are -supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 for -ECDSAP384SHA384. If RSASHA1 is specified along with the \fI\%\-3\fP -option, then NSEC3RSASHA1 is used instead. +These values are case\-insensitive. In some cases, abbreviations +are supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 +for ECDSAP384SHA384. If RSASHA1 (deprecated) is specified along +with the \fI\%\-3\fP option, then NSEC3RSASHA1 (deprecated) is +used instead. .sp -This option is mandatory except when using the -\fI\%\-S\fP option, which copies the algorithm from the predecessory key. +This option is mandatory except when using the \fI\%\-S\fP +option, which copies the algorithm from the predecessory key. .sp -Changed in version 9.12.0: The default value RSASHA1 for newly generated keys was removed. +Changed in version 9.12.0: The default value RSASHA1 (deprecated) for newly generated +keys was removed. .UNINDENT .INDENT 0.0 .TP .B \-3 -This option uses an NSEC3\-capable algorithm to generate a DNSSEC key. If this -option is used with an algorithm that has both NSEC and NSEC3 -versions, then the NSEC3 version is used; for example, -\fBdnssec\-keygen \-3a RSASHA1\fP specifies the NSEC3RSASHA1 algorithm. +This option uses an NSEC3\-capable algorithm to generate a DNSSEC +key. If this option is used with an algorithm that has both NSEC +and NSEC3 versions, then the NSEC3 version is used; for example, +\fBdnssec\-keygen \-3a RSASHA1\fP specifies the NSEC3RSASHA1 +(deprecated) algorithm. .UNINDENT .INDENT 0.0 .TP diff -Nru bind9-9.20.11/doc/man/dnssec-keygen.1in bind9-9.20.15/doc/man/dnssec-keygen.1in --- bind9-9.20.11/doc/man/dnssec-keygen.1in 2025-07-04 09:44:08.275155416 +0000 +++ bind9-9.20.15/doc/man/dnssec-keygen.1in 2025-10-18 10:17:58.847298839 +0000 @@ -45,22 +45,25 @@ .INDENT 0.0 .TP .B \-3 -This option uses an NSEC3\-capable algorithm to generate a DNSSEC key. If this -option is used with an algorithm that has both NSEC and NSEC3 -versions, then the NSEC3 version is selected; for example, -\fBdnssec\-keygen \-3 \-a RSASHA1\fP specifies the NSEC3RSASHA1 algorithm. +This option uses an NSEC3\-capable algorithm to generate a DNSSEC +key. If this option is used with an algorithm that has both NSEC +and NSEC3 versions, then the NSEC3 version is selected; for +example, \fBdnssec\-keygen \-3 \-a RSASHA1\fP specifies the NSEC3RSASHA1 +(deprecated) algorithm. .UNINDENT .INDENT 0.0 .TP .B \-a algorithm -This option selects the cryptographic algorithm. For DNSSEC keys, the value of -\fBalgorithm\fP must be one of RSASHA1, NSEC3RSASHA1, RSASHA256, -RSASHA512, ECDSAP256SHA256, ECDSAP384SHA384, ED25519, or ED448. +This option selects the cryptographic algorithm. For DNSSEC keys, +the value of \fBalgorithm\fP must be one of RSASHA1 (deprecated), +NSEC3RSASHA1 (deprecated), RSASHA256, RSASHA512, ECDSAP256SHA256, +ECDSAP384SHA384, ED25519, or ED448. .sp -These values are case\-insensitive. In some cases, abbreviations are -supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 for -ECDSAP384SHA384. If RSASHA1 is specified along with the \fI\%\-3\fP -option, NSEC3RSASHA1 is used instead. +These values are case\-insensitive. In some cases, abbreviations +are supported, such as ECDSA256 for ECDSAP256SHA256 and ECDSA384 +for ECDSAP384SHA384. If RSASHA1 (deprecated) is specified along +with the \fI\%\-3\fP option, NSEC3RSASHA1 (deprecated) is used +instead. .sp This parameter \fImust\fP be specified except when using the \fI\%\-S\fP option, which copies the algorithm from the predecessor key. diff -Nru bind9-9.20.11/doc/man/named-checkconf.1in bind9-9.20.15/doc/man/named-checkconf.1in --- bind9-9.20.11/doc/man/named-checkconf.1in 2025-07-04 09:44:08.341156960 +0000 +++ bind9-9.20.15/doc/man/named-checkconf.1in 2025-10-18 10:17:58.971300705 +0000 @@ -32,7 +32,7 @@ named-checkconf \- named configuration file syntax checking tool .SH SYNOPSIS .sp -\fBnamed\-checkconf\fP [\fB\-achjlvz\fP] [\fB\-p\fP [\fB\-x\fP ]] [\fB\-t\fP directory] {filename} +\fBnamed\-checkconf\fP [\fB\-achjklvz\fP] [\fB\-p\fP [\fB\-x\fP ]] [\fB\-t\fP directory] {filename} .SH DESCRIPTION .sp \fBnamed\-checkconf\fP checks the syntax, but not the semantics, of a @@ -67,6 +67,13 @@ .UNINDENT .INDENT 0.0 .TP +.B \-k +Check the \fIdnssec\-policy\fP\(aqs DNSSEC keys against the key files in +the \fIkey\-directory\fP\&. This is useful when checking a \fInamed.conf\fP +to ensure a DNSSEC policy matches the existing keys. +.UNINDENT +.INDENT 0.0 +.TP .B \-l This option lists all the configured zones. Each line of output contains the zone name, class (e.g. IN), view, and type (e.g. primary or secondary). diff -Nru bind9-9.20.11/doc/man/named.conf.5in bind9-9.20.15/doc/man/named.conf.5in --- bind9-9.20.11/doc/man/named.conf.5in 2025-07-04 09:44:08.451159534 +0000 +++ bind9-9.20.15/doc/man/named.conf.5in 2025-10-18 10:17:59.007301247 +0000 @@ -72,6 +72,7 @@ dnskey\-ttl ; inline\-signing ; keys { ( csk | ksk | zsk ) [ key\-directory | key\-store ] lifetime algorithm [ tag\-range ] [ ]; ... }; + manual\-mode ; max\-zone\-ttl ; nsec3param [ iterations ] [ optout ] [ salt\-length ]; offline\-ksk ; @@ -321,7 +322,7 @@ resolver\-query\-timeout ; resolver\-use\-dns64 ; response\-padding { ; ... } block\-size ; - response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ ede ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; + response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ ede ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ servfail\-until\-ready ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; responselog ; reuseport ; root\-key\-sentinel ; @@ -360,8 +361,8 @@ tcp\-listen\-queue ; tcp\-receive\-buffer ; tcp\-send\-buffer ; - tkey\-domain ; - tkey\-gssapi\-credential ; + tkey\-domain ; // obsolete + tkey\-gssapi\-credential ; // deprecated tkey\-gssapi\-keytab ; tls\-port ; transfer\-format ( many\-answers | one\-answer ); @@ -607,7 +608,7 @@ resolver\-query\-timeout ; resolver\-use\-dns64 ; response\-padding { ; ... } block\-size ; - response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ ede ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; + response\-policy { zone [ add\-soa ] [ log ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ policy ( cname | disabled | drop | given | no\-op | nodata | nxdomain | passthru | tcp\-only ) ] [ recursive\-only ] [ nsip\-enable ] [ nsdname\-enable ] [ ede ]; ... } [ add\-soa ] [ break\-dnssec ] [ max\-policy\-ttl ] [ min\-update\-interval ] [ min\-ns\-dots ] [ nsip\-wait\-recurse ] [ nsdname\-wait\-recurse ] [ qname\-wait\-recurse ] [ recursive\-only ] [ servfail\-until\-ready ] [ nsip\-enable ] [ nsdname\-enable ] [ dnsrps\-enable ] [ dnsrps\-options { } ]; root\-key\-sentinel ; rrset\-order { [ class ] [ type ] [ name ] ; ... }; send\-cookie ; diff -Nru bind9-9.20.11/doc/man/rndc.8in bind9-9.20.15/doc/man/rndc.8in --- bind9-9.20.11/doc/man/rndc.8in 2025-07-04 09:44:08.516161055 +0000 +++ bind9-9.20.15/doc/man/rndc.8in 2025-10-18 10:17:59.069302180 +0000 @@ -191,13 +191,20 @@ .UNINDENT .INDENT 0.0 .TP -.B dnssec (\-status | \-rollover \-key id [\-alg algorithm] [\-when time] | \-checkds [\-key id [\-alg algorithm]] [\-when time] published | withdrawn)) zone [class [view]] +.B dnssec (\-status | \-step | \-rollover \-key id [\-alg algorithm] [\-when time] | \-checkds [\-key id [\-alg algorithm]] [\-when time] published | withdrawn)) zone [class [view]] This command allows you to interact with the \(dqdnssec\-policy\(dq of a given zone. .sp \fBrndc dnssec \-status\fP show the DNSSEC signing state for the specified zone. .sp +\fBrndc dnssec \-step\fP sends a signal to an instance of \fI\%named\fP for a +zone configured with \fBdnssec\-policy\fP in manual mode, telling it to +continue with the operations that had previously been blocked but logged. +This gives the human operator a chance to review the log messages, +understand what will happen next and then, using \fBrndc dnssec \-step\fP, to +inform \fI\%named\fP to proceed to the next stage. +.sp \fBrndc dnssec \-rollover\fP allows you to schedule key rollover for a specific key (overriding the original key lifetime). .sp diff -Nru bind9-9.20.11/doc/misc/Makefile.in bind9-9.20.15/doc/misc/Makefile.in --- bind9-9.20.11/doc/misc/Makefile.in 2025-07-04 09:43:11.214811580 +0000 +++ bind9-9.20.15/doc/misc/Makefile.in 2025-10-18 10:17:04.430500785 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -73,6 +73,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -358,8 +360,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -578,13 +582,8 @@ $(am__aclocal_m4_deps): clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(noinst_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(noinst_PROGRAMS:$(EXEEXT)=) cfg_test$(EXEEXT): $(cfg_test_OBJECTS) $(cfg_test_DEPENDENCIES) $(EXTRA_cfg_test_DEPENDENCIES) @rm -f cfg_test$(EXEEXT) @@ -600,7 +599,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -764,24 +763,24 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) - -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) + -$(am__rm_f) $(BUILT_SOURCES) + -$(am__rm_f) $(MAINTAINERCLEANFILES) clean: clean-am clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/cfg_test-cfg_test.Po + -rm -f ./$(DEPDIR)/cfg_test-cfg_test.Po -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -831,7 +830,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/cfg_test-cfg_test.Po + -rm -f ./$(DEPDIR)/cfg_test-cfg_test.Po -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -918,3 +917,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/doc/misc/options bind9-9.20.15/doc/misc/options --- bind9-9.20.11/doc/misc/options 2025-07-04 09:44:00.649976698 +0000 +++ bind9-9.20.15/doc/misc/options 2025-10-18 10:17:52.149198163 +0000 @@ -16,6 +16,7 @@ dnskey-ttl ; inline-signing ; keys { ( csk | ksk | zsk ) [ key-directory | key-store ] lifetime algorithm [ tag-range ] [ ]; ... }; + manual-mode ; max-zone-ttl ; nsec3param [ iterations ] [ optout ] [ salt-length ]; offline-ksk ; @@ -265,7 +266,7 @@ resolver-query-timeout ; resolver-use-dns64 ; response-padding { ; ... } block-size ; - response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ ede ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; + response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ ede ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ servfail-until-ready ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; responselog ; reuseport ; root-key-sentinel ; @@ -304,8 +305,8 @@ tcp-listen-queue ; tcp-receive-buffer ; tcp-send-buffer ; - tkey-domain ; - tkey-gssapi-credential ; + tkey-domain ; // obsolete + tkey-gssapi-credential ; // deprecated tkey-gssapi-keytab ; tls-port ; transfer-format ( many-answers | one-answer ); @@ -551,7 +552,7 @@ resolver-query-timeout ; resolver-use-dns64 ; response-padding { ; ... } block-size ; - response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ ede ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; + response-policy { zone [ add-soa ] [ log ] [ max-policy-ttl ] [ min-update-interval ] [ policy ( cname | disabled | drop | given | no-op | nodata | nxdomain | passthru | tcp-only ) ] [ recursive-only ] [ nsip-enable ] [ nsdname-enable ] [ ede ]; ... } [ add-soa ] [ break-dnssec ] [ max-policy-ttl ] [ min-update-interval ] [ min-ns-dots ] [ nsip-wait-recurse ] [ nsdname-wait-recurse ] [ qname-wait-recurse ] [ recursive-only ] [ servfail-until-ready ] [ nsip-enable ] [ nsdname-enable ] [ dnsrps-enable ] [ dnsrps-options { } ]; root-key-sentinel ; rrset-order { [ class ] [ type ] [ name ] ; ... }; send-cookie ; diff -Nru bind9-9.20.11/doc/notes/notes-9.20.12.rst bind9-9.20.15/doc/notes/notes-9.20.12.rst --- bind9-9.20.11/doc/notes/notes-9.20.12.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/notes/notes-9.20.12.rst 2025-10-18 10:16:12.563732306 +0000 @@ -0,0 +1,98 @@ +.. 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. + +Notes for BIND 9.20.12 +---------------------- + +New Features +~~~~~~~~~~~~ + +- Support for parsing DSYNC records has been added. + + These records are used for discovering the receiver endpoint for DNS + notification messages. For more information, see + `draft-ietf-dnsop-generalized-notify-09`_. :gl:`#5440` + +.. _`draft-ietf-dnsop-generalized-notify-09`: https://datatracker.ietf.org/doc/draft-ietf-dnsop-generalized-notify/09/ + +Feature Changes +~~~~~~~~~~~~~~~ + +- Add deprecation warnings for RSASHA1, RSASHA1-NSEC3SHA1, and DS digest + type 1. + + RSASHA1 and RSASHA1-NSEC-SHA1 DNSKEY algorithms have been deprecated + by the IETF and should no longer be used for DNSSEC. DS digest type 1 + (SHA1) has also been deprecated in BIND 9. Validators are now expected to treat + these algorithms and digest as unknown, resulting in some zones being + treated as insecure when they were previously treated as secure. + Warnings have been added to :iscman:`named` and tools when these algorithms and + this digest are being used for signing. + + Zones signed with RSASHA1 or RSASHA1-NSEC-SHA1 should be migrated to a + different DNSKEY algorithm. + + Zones with DS or CDS records with digest type 1 (SHA1) should be + updated to use a different digest type (e.g. SHA256) and the digest + type 1 records should be removed. :gl:`#5358` + +Bug Fixes +~~~~~~~~~ + +- Stale RRsets in a CNAME chain were not always refreshed. + + Previously, with serve-stale enabled and a CNAME chain that contained a stale RRset, + the refresh query didn't always properly refresh the stale RRsets. + This has been fixed. :gl:`#5243` + +- Add RPZ extended DNS error for zones with a CNAME override policy + configured. + + Previously, when the zone was configured with a CNAME override policy, or the + response policy zone contained a wildcard CNAME, the extended DNS error + code was not added. This has been fixed. :gl:`#5342` + +- Fix :iscman:`dig` issues. + + When used with the ``+keepopen`` option, + :iscman:`dig` could terminate unexpectedly in rare situations. + Additionally, :iscman:`dig` could hang and fail to shutdown properly + when interrupted during a query. These have been fixed. :gl:`#5381` + +- Log dropped or slipped responses in the ``query-errors`` category. + + Responses which were dropped or slipped because of Response Rate + Limiting (RRL) were logged in the ``rate-limit`` category instead of the + ``query-errors`` category, as documented in the ARM. This has been fixed. + :gl:`#5388` + +- :any:`synth-from-dnssec` was not working in some scenarios. + + Aggressive use of DNSSEC-Validated cache with NSEC was not working in + scenarios when no parent NSEC was in cache. This has been fixed. + :gl:`#5422` + +- Clean enough memory when adding new ADB names/entries under memory + pressure. + + The ADB memory cleaning is opportunistic even when BIND is under memory + pressure (in the overmem condition). :iscman:`named` now ensures that the assigned memory + limit is not exceeded by releasing twice the amount of memory + allocated for each new ADB name/entry when under memory pressure. + :gl:`!10637` + +- Prevent spurious validation failures. + + Under rare circumstances, validation could fail if multiple clients + simultaneously iterated the same set of DNSSEC signatures. This has + been fixed. :gl:`#3014` + + diff -Nru bind9-9.20.11/doc/notes/notes-9.20.13.rst bind9-9.20.15/doc/notes/notes-9.20.13.rst --- bind9-9.20.11/doc/notes/notes-9.20.13.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/notes/notes-9.20.13.rst 2025-10-18 10:16:12.563732306 +0000 @@ -0,0 +1,82 @@ +.. 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. + +Notes for BIND 9.20.13 +---------------------- + +New Features +~~~~~~~~~~~~ + +- Add a new option ``manual-mode`` to :any:`dnssec-policy`. + + When enabled, :iscman:`named` will not modify DNSSEC keys or key states + automatically. The proposed change will be logged and only after manual + confirmation with ``rndc dnssec -step`` will the modification be made. + :gl:`#4606` + +- Add a new option ``servfail-until-ready`` to :namedconf:ref:`response-policy` + zones. + + By default, when :iscman:`named` is started, it starts answering + queries before all response policy zones are completely loaded and + processed. This new option instructs :iscman:`named` to respond with + SERVFAIL until all the response policy zones are processed and ready. + Note that if one or more response policy zones fail to load, + :iscman:`named` starts responding to queries according to those zones + that did load. + + Note, that enabling this option has no effect when a DNS Response + Policy Service (DNSRPS) interface is used. :gl:`#5222` + +- Support for parsing HHIT and BRID records has been added. + + :gl:`#5444` + +Removed Features +~~~~~~~~~~~~~~~~ + +- Deprecate the :namedconf:ref:`tkey-gssapi-credential` statement. + + The :any:`tkey-gssapi-keytab` statement allows GSS-TSIG to be set up + in a simpler and more reliable way than using the + :any:`tkey-gssapi-credential` statement and setting environment + variables (e.g. ``KRB5_KTNAME``). Therefore, the + :any:`tkey-gssapi-credential` statement has been deprecated; + :any:`tkey-gssapi-keytab` should be used instead. + + For configurations currently using a combination of both + :any:`tkey-gssapi-keytab` *and* :any:`tkey-gssapi-credential`, the + latter should be dropped and the keytab pointed to by + :any:`tkey-gssapi-keytab` should now only contain the credential + previously specified by :any:`tkey-gssapi-credential`. :gl:`#4204` + +- Obsolete the "tkey-domain" statement. + + Mark the ``tkey-domain`` statement as obsolete because it has not had + any effect on server behavior since support for TKEY Mode 2 + (Diffie-Hellman) was removed (in BIND 9.20.0). :gl:`#4204` + +Bug Fixes +~~~~~~~~~ + +- Prevent spurious SERVFAILs for certain 0-TTL resource records. + + Under certain circumstances, BIND 9 can return SERVFAIL when updating + existing entries in the cache with new NS, A, AAAA, or DS records that have a + TTL of zero. :gl:`#5294` + +- Fix unexpected termination if :namedconf:ref:`catalog-zones` had undefined + ``default-primaries``. + + The issue manifested only if the server was reloaded or reconfigured twice. + :gl:`#5494` + + diff -Nru bind9-9.20.11/doc/notes/notes-9.20.14.rst bind9-9.20.15/doc/notes/notes-9.20.14.rst --- bind9-9.20.11/doc/notes/notes-9.20.14.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/notes/notes-9.20.14.rst 2025-10-18 10:16:12.563732306 +0000 @@ -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. + +Notes for BIND 9.20.14 +---------------------- + +.. note:: + + The BIND 9.20.14 release was withdrawn after the discovery of a + regression in a security fix in it during pre-release testing. diff -Nru bind9-9.20.11/doc/notes/notes-9.20.15.rst bind9-9.20.15/doc/notes/notes-9.20.15.rst --- bind9-9.20.11/doc/notes/notes-9.20.15.rst 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/doc/notes/notes-9.20.15.rst 2025-10-18 10:16:12.563732306 +0000 @@ -0,0 +1,108 @@ +.. 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. + +Notes for BIND 9.20.15 +---------------------- + +Security Fixes +~~~~~~~~~~~~~~ + +- DNSSEC validation fails if matching but invalid DNSKEY is found. + :cve:`2025-8677` + + Previously, if a matching but cryptographically invalid key was + encountered during DNSSEC validation, the key was skipped and not + counted towards validation failures. :iscman:`named` now treats such + DNSSEC keys as hard failures and the DNSSEC validation fails + immediately, instead of continuing with the next DNSKEYs in the RRset. + + ISC would like to thank Zuyao Xu and Xiang Li from the All-in-One + Security and Privacy Laboratory at Nankai University for bringing this + vulnerability to our attention. :gl:`#5343` + +- Address various spoofing attacks. :cve:`2025-40778` + + Previously, several issues could be exploited to poison a DNS cache + with spoofed records for zones which were not DNSSEC-signed or if the + resolver was configured to not do DNSSEC validation. These issues were + assigned CVE-2025-40778 and have now been fixed. + + As an additional layer of protection, :iscman:`named` no longer + accepts DNAME records or extraneous NS records in the AUTHORITY + section unless these are received via spoofing-resistant transport + (TCP, UDP with DNS cookies, TSIG, or SIG(0)). + + ISC would like to thank Yuxiao Wu, Yunyi Zhang, Baojun Liu, and Haixin + Duan from Tsinghua University for bringing this vulnerability to our + attention. :gl:`#5414` + +- Cache-poisoning due to weak pseudo-random number generator. + :cve:`2025-40780` + + It was discovered during research for an upcoming academic paper that + a xoshiro128\*\* internal state can be recovered by an external 3rd + party, allowing the prediction of UDP ports and DNS IDs in outgoing + queries. This could lead to an attacker spoofing the DNS answers with + great efficiency and poisoning the DNS cache. + + The internal random generator has been changed to a cryptographically + secure pseudo-random generator. + + ISC would like to thank Prof. Amit Klein and Omer Ben Simhon from + Hebrew University of Jerusalem for bringing this vulnerability to our + attention. :gl:`#5484` + +New Features +~~~~~~~~~~~~ + +- Add :any:`dnssec-policy` keys configuration check to + :iscman:`named-checkconf`. + + A new option :option:`-k ` was added to + :iscman:`named-checkconf` that allows checking the + :any:`dnssec-policy` :any:`keys` configuration against the configured + key stores. If the found key files are not in sync with the given + :any:`dnssec-policy`, the check will fail. + + This is useful to run before migrating to :any:`dnssec-policy`. + :gl:`#5486` + +Bug Fixes +~~~~~~~~~ + +- Missing DNSSEC information when CD bit is set in query. + + The RRSIGs for glue records were not being cached correctly for CD=1 + queries. This has been fixed. :gl:`#5502` + +- :option:`rndc sign` during ZSK rollover will now replace signatures. + + When performing a ZSK rollover, if the new DNSKEY is omnipresent, the + :option:`rndc sign` command now signs the zone completely with the + successor key, replacing all zone signatures from the predecessor key + with new ones. :gl:`#5483` + +- Use signer name when disabling DNSSEC algorithms. + + :any:`disable-algorithms` could cause DNSSEC validation failures when + the parent zone was signed with the algorithms that were being + disabled for the child zone. This has been fixed; + :any:`disable-algorithms` now works on a whole-of-zone basis. + + If the zone's name is at or below the :any:`disable-algorithms` name + the algorithm is disabled for that zone, using deepest match when + there are multiple :any:`disable-algorithms` clauses. :gl:`#5165` + +- Preserve cache when reload fails and reload the server again. + + This fixes an issue where failing to reconfigure/reload the server + would fail to preserve the views' caches for subsequent server + reconfigurations/reloads. :gl:`#5523` diff -Nru bind9-9.20.11/fuzz/Makefile.in bind9-9.20.15/fuzz/Makefile.in --- bind9-9.20.11/fuzz/Makefile.in 2025-07-04 09:43:11.258812605 +0000 +++ bind9-9.20.15/fuzz/Makefile.in 2025-10-18 10:17:04.472501429 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -72,6 +72,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -327,10 +329,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* @@ -418,6 +419,7 @@ # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ + $$am__collect_skipped_logs \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the @@ -442,6 +444,11 @@ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ +if test -n '$(IGNORE_SKIPPED_LOGS)'; then \ + am__collect_skipped_logs='--collect-skipped-logs no'; \ +else \ + am__collect_skipped_logs=''; \ +fi; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ @@ -649,8 +656,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -814,24 +823,17 @@ $(am__aclocal_m4_deps): clean-checkPROGRAMS: - @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list + $(am__rm_f) $(check_PROGRAMS) + test -z "$(EXEEXT)" || $(am__rm_f) $(check_PROGRAMS:$(EXEEXT)=) clean-checkLTLIBRARIES: - -test -z "$(check_LTLIBRARIES)" || rm -f $(check_LTLIBRARIES) + -$(am__rm_f) $(check_LTLIBRARIES) @list='$(check_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libfuzzmain.la: $(libfuzzmain_la_OBJECTS) $(libfuzzmain_la_DEPENDENCIES) $(EXTRA_libfuzzmain_la_DEPENDENCIES) $(AM_V_CCLD)$(LINK) $(libfuzzmain_la_OBJECTS) $(libfuzzmain_la_LIBADD) $(LIBS) @@ -902,7 +904,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -1004,7 +1006,6 @@ am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: - $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ @@ -1080,10 +1081,37 @@ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ + output_system_information () \ + { \ + echo; \ + { uname -a | $(AWK) '{ \ + printf "System information (uname -a):"; \ + for (i = 1; i < NF; ++i) \ + { \ + if (i != 2) \ + printf " %s", $$i; \ + } \ + printf "\n"; \ +}'; } 2>&1; \ + if test -r /etc/os-release; then \ + echo "Distribution information (/etc/os-release):"; \ + sed 8q /etc/os-release; \ + elif test -r /etc/issue; then \ + echo "Distribution information (/etc/issue):"; \ + cat /etc/issue; \ + fi; \ + }; \ + please_report () \ + { \ +echo "Some test(s) failed. Please report this to $(PACKAGE_BUGREPORT),"; \ +echo "together with the test-suite.log file (gzipped) and your system"; \ +echo "information. Thanks."; \ + }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ + output_system_information; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ @@ -1103,26 +1131,25 @@ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ - echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG) for debugging.$${std}";\ if test -n "$(PACKAGE_BUGREPORT)"; then \ - echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + please_report | sed -e "s/^/$${col}/" -e s/'$$'/"$${std}"/; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: $(check_PROGRAMS) $(check_LTLIBRARIES) - @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list - @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @$(am__rm_f) $(RECHECK_LOGS) + @$(am__rm_f) $(RECHECK_LOGS:.log=.trs) + @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ - trs_list=`for i in $$bases; do echo $$i.trs; done`; \ - log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all $(check_PROGRAMS) $(check_LTLIBRARIES) - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @$(am__rm_f) $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ @@ -1285,28 +1312,28 @@ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + -$(am__rm_f) $(TEST_LOGS) + -$(am__rm_f) $(TEST_LOGS:.log=.trs) + -$(am__rm_f) $(TEST_SUITE_LOG) clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-checkLTLIBRARIES clean-checkPROGRAMS clean-generic \ clean-libtool mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/dns_master_load.Po + -rm -f ./$(DEPDIR)/dns_master_load.Po -rm -f ./$(DEPDIR)/dns_message_checksig.Po -rm -f ./$(DEPDIR)/dns_message_parse.Po -rm -f ./$(DEPDIR)/dns_name_fromtext_target.Po @@ -1368,7 +1395,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/dns_master_load.Po + -rm -f ./$(DEPDIR)/dns_master_load.Po -rm -f ./$(DEPDIR)/dns_message_checksig.Po -rm -f ./$(DEPDIR)/dns_message_parse.Po -rm -f ./$(DEPDIR)/dns_name_fromtext_target.Po @@ -1434,3 +1461,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/install-sh bind9-9.20.15/install-sh --- bind9-9.20.11/install-sh 2025-07-04 09:43:10.633798042 +0000 +++ bind9-9.20.15/install-sh 2025-10-18 10:17:03.846491845 +0000 @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2020-11-14.01; # UTC +scriptversion=2024-06-19.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -124,9 +124,9 @@ If -S is not specified, no backups are attempted. -Email bug reports to bug-automake@gnu.org. -Automake home page: https://www.gnu.org/software/automake/ -" +Report bugs to . +GNU Automake home page: . +General help using GNU software: ." while test $# -ne 0; do case $1 in @@ -170,7 +170,7 @@ -T) is_target_a_directory=never;; - --version) echo "$0 $scriptversion"; exit $?;; + --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;; --) shift break;; @@ -345,7 +345,7 @@ ' 0 # Because "mkdir -p" follows existing symlinks and we likely work - # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directly in world-writable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && @@ -353,7 +353,7 @@ exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. + # Check for POSIX incompatibility with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. diff -Nru bind9-9.20.11/lib/Makefile.in bind9-9.20.15/lib/Makefile.in --- bind9-9.20.11/lib/Makefile.in 2025-07-04 09:43:11.275813001 +0000 +++ bind9-9.20.15/lib/Makefile.in 2025-10-18 10:17:04.489501689 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -72,6 +72,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -357,8 +359,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -691,16 +695,16 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am @@ -802,3 +806,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/lib/dns/Makefile.am bind9-9.20.15/lib/dns/Makefile.am --- bind9-9.20.11/lib/dns/Makefile.am 2025-07-04 09:42:08.368328953 +0000 +++ bind9-9.20.15/lib/dns/Makefile.am 2025-10-18 10:16:12.600732882 +0000 @@ -67,9 +67,10 @@ include/dns/dns64.h \ include/dns/dnsrps.h \ include/dns/dnssec.h \ + include/dns/dnstap.h \ include/dns/ds.h \ include/dns/dsdigest.h \ - include/dns/dnstap.h \ + include/dns/dsync.h \ include/dns/dyndb.h \ include/dns/ecs.h \ include/dns/ede.h \ diff -Nru bind9-9.20.11/lib/dns/Makefile.in bind9-9.20.15/lib/dns/Makefile.in --- bind9-9.20.11/lib/dns/Makefile.in 2025-07-04 09:43:11.399815891 +0000 +++ bind9-9.20.15/lib/dns/Makefile.in 2025-10-18 10:17:04.614503603 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -77,6 +77,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -188,10 +190,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(dstdir)" \ "$(DESTDIR)$(irsdir)" "$(DESTDIR)$(libdns_ladir)" \ @@ -222,8 +223,8 @@ include/dns/db.h include/dns/dbiterator.h include/dns/diff.h \ include/dns/dispatch.h include/dns/dlz.h \ include/dns/dlz_dlopen.h include/dns/dns64.h \ - include/dns/dnsrps.h include/dns/dnssec.h include/dns/ds.h \ - include/dns/dsdigest.h include/dns/dnstap.h \ + include/dns/dnsrps.h include/dns/dnssec.h include/dns/dnstap.h \ + include/dns/ds.h include/dns/dsdigest.h include/dns/dsync.h \ include/dns/dyndb.h include/dns/ecs.h include/dns/ede.h \ include/dns/edns.h include/dns/fixedname.h \ include/dns/forward.h include/dns/geoip.h \ @@ -635,8 +636,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -776,9 +779,10 @@ include/dns/dns64.h \ include/dns/dnsrps.h \ include/dns/dnssec.h \ + include/dns/dnstap.h \ include/dns/ds.h \ include/dns/dsdigest.h \ - include/dns/dnstap.h \ + include/dns/dsync.h \ include/dns/dyndb.h \ include/dns/ecs.h \ include/dns/ede.h \ @@ -960,15 +964,13 @@ done clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libdns.la: $(libdns_la_OBJECTS) $(libdns_la_DEPENDENCIES) $(EXTRA_libdns_la_DEPENDENCIES) $(AM_V_CCLD)$(libdns_la_LINK) -rpath $(libdir) $(libdns_la_OBJECTS) $(libdns_la_LIBADD) $(LIBS) @@ -1082,7 +1084,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -2019,23 +2021,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/libdns_la-acl.Plo + -rm -f ./$(DEPDIR)/libdns_la-acl.Plo -rm -f ./$(DEPDIR)/libdns_la-adb.Plo -rm -f ./$(DEPDIR)/libdns_la-badcache.Plo -rm -f ./$(DEPDIR)/libdns_la-byaddr.Plo @@ -2185,7 +2187,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libdns_la-acl.Plo + -rm -f ./$(DEPDIR)/libdns_la-acl.Plo -rm -f ./$(DEPDIR)/libdns_la-adb.Plo -rm -f ./$(DEPDIR)/libdns_la-badcache.Plo -rm -f ./$(DEPDIR)/libdns_la-byaddr.Plo @@ -2369,3 +2371,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/lib/dns/acl.c bind9-9.20.15/lib/dns/acl.c --- bind9-9.20.11/lib/dns/acl.c 2025-07-04 09:42:08.368328953 +0000 +++ bind9-9.20.15/lib/dns/acl.c 2025-10-18 10:16:12.601732897 +0000 @@ -462,8 +462,7 @@ dns__acl_destroy_port_transports(dns_acl_t *acl) { dns_acl_port_transports_t *port_proto = NULL; dns_acl_port_transports_t *next = NULL; - ISC_LIST_FOREACH_SAFE (acl->ports_and_transports, port_proto, link, - next) + ISC_LIST_FOREACH_SAFE(acl->ports_and_transports, port_proto, link, next) { ISC_LIST_DEQUEUE(acl->ports_and_transports, port_proto, link); isc_mem_put(acl->mctx, port_proto, sizeof(*port_proto)); diff -Nru bind9-9.20.11/lib/dns/adb.c bind9-9.20.15/lib/dns/adb.c --- bind9-9.20.11/lib/dns/adb.c 2025-07-04 09:42:08.368328953 +0000 +++ bind9-9.20.15/lib/dns/adb.c 2025-10-18 10:16:12.601732897 +0000 @@ -139,6 +139,7 @@ dns_name_t *name; unsigned int partial_result; unsigned int flags; + unsigned int type; dns_name_t target; isc_stdtime_t expire_target; isc_stdtime_t expire_v4; @@ -267,7 +268,7 @@ * Internal functions (and prototypes). */ static dns_adbname_t * -new_adbname(dns_adb_t *adb, const dns_name_t *, unsigned int flags); +new_adbname(dns_adb_t *adb, const dns_name_t *, unsigned int type); static void destroy_adbname(dns_adbname_t *); static bool @@ -296,11 +297,15 @@ free_adbfetch(dns_adb_t *, dns_adbfetch_t **); static void purge_stale_names(dns_adb_t *adb, isc_stdtime_t now); +static void +purge_names_overmem(dns_adb_t *adb, size_t requested); static dns_adbname_t * -get_attached_and_locked_name(dns_adb_t *, const dns_name_t *, - unsigned int flags, isc_stdtime_t now); +get_attached_and_locked_name(dns_adb_t *, const dns_name_t *, unsigned int type, + isc_stdtime_t now); static void purge_stale_entries(dns_adb_t *adb, isc_stdtime_t now); +static void +purge_entries_overmem(dns_adb_t *adb, size_t requested); static dns_adbentry_t * get_attached_and_locked_entry(dns_adb_t *adb, isc_stdtime_t now, const isc_sockaddr_t *addr); @@ -321,7 +326,7 @@ clean_finds_at_name(dns_adbname_t *, dns_adbstatus_t, unsigned int); static void maybe_expire_namehooks(dns_adbname_t *, isc_stdtime_t); -static bool +static void maybe_expire_name(dns_adbname_t *adbname, isc_stdtime_t now); static void expire_name(dns_adbname_t *adbname, dns_adbstatus_t astat); @@ -415,7 +420,9 @@ #define FIND_HAS_ADDRS(fn) (!ISC_LIST_EMPTY((fn)->list)) #define FIND_NOFETCH(fn) (((fn)->options & DNS_ADBFIND_NOFETCH) != 0) -#define ADBNAME_FLAGS_MASK (DNS_ADBFIND_STARTATZONE | DNS_ADBFIND_STATICSTUB) +#define ADBNAME_TYPE_MASK (DNS_ADBFIND_STARTATZONE | DNS_ADBFIND_STATICSTUB) + +#define ADBNAME_TYPE(options) ((options) & ADBNAME_TYPE_MASK) /* * These are currently used on simple unsigned ints, so they are @@ -426,15 +433,6 @@ #define EXPIRE_OK(exp, now) ((exp == INT_MAX) || (exp < now)) -/* - * Find out if the flags on a name (nf) indicate if it is a hint or - * glue, and compare this to the appropriate bits set in o, to see if - * this is ok. - */ -#define STARTATZONE_MATCHES(nf, o) \ - (((nf)->flags & DNS_ADBFIND_STARTATZONE) == \ - ((o) & DNS_ADBFIND_STARTATZONE)) - #define ENTER_LEVEL ISC_LOG_DEBUG(50) #define CLEAN_LEVEL ISC_LOG_DEBUG(100) #define DEF_LEVEL ISC_LOG_DEBUG(5) @@ -956,7 +954,7 @@ } static dns_adbname_t * -new_adbname(dns_adb_t *adb, const dns_name_t *dnsname, unsigned int flags) { +new_adbname(dns_adb_t *adb, const dns_name_t *dnsname, unsigned int type) { dns_adbname_t *name = NULL; name = isc_mem_get(adb->mctx, sizeof(*name)); @@ -971,7 +969,7 @@ .v6 = ISC_LIST_INITIALIZER, .finds = ISC_LIST_INITIALIZER, .link = ISC_LINK_INITIALIZER, - .flags = flags & ADBNAME_FLAGS_MASK, + .type = type, .magic = DNS_ADBNAME_MAGIC, }; @@ -1237,9 +1235,7 @@ const dns_adbname_t *adbname0 = node; const dns_adbname_t *adbname1 = key; - if ((adbname0->flags & ADBNAME_FLAGS_MASK) != - (adbname1->flags & ADBNAME_FLAGS_MASK)) - { + if (adbname0->type != adbname1->type) { return false; } @@ -1249,12 +1245,11 @@ static uint32_t hash_adbname(const dns_adbname_t *adbname) { isc_hash32_t hash; - unsigned int flags = adbname->flags & ADBNAME_FLAGS_MASK; isc_hash32_init(&hash); isc_hash32_hash(&hash, adbname->name->ndata, adbname->name->length, false); - isc_hash32_hash(&hash, &flags, sizeof(flags), true); + isc_hash32_hash(&hash, &adbname->type, sizeof(adbname->type), true); return isc_hash32_finalize(&hash); } @@ -1263,29 +1258,32 @@ */ static dns_adbname_t * get_attached_and_locked_name(dns_adb_t *adb, const dns_name_t *name, - unsigned int flags, isc_stdtime_t now) { + unsigned int type, isc_stdtime_t now) { isc_result_t result; dns_adbname_t *adbname = NULL; isc_time_t timenow; isc_stdtime_t last_update; dns_adbname_t key = { .name = UNCONST(name), - .flags = flags & ADBNAME_FLAGS_MASK, + .type = type, }; uint32_t hashval = hash_adbname(&key); isc_rwlocktype_t locktype = isc_rwlocktype_read; + bool overmem = isc_mem_isovermem(adb->mctx); isc_time_set(&timenow, now, 0); RWLOCK(&adb->names_lock, locktype); last_update = adb->names_last_update; - if (last_update + ADB_STALE_MARGIN >= now || - isc_mem_isovermem(adb->mctx)) - { + if (last_update + ADB_STALE_MARGIN >= now || overmem) { last_update = now; UPGRADELOCK(&adb->names_lock, locktype); - purge_stale_names(adb, now); + if (overmem) { + purge_names_overmem(adb, 2 * sizeof(*adbname)); + } else { + purge_stale_names(adb, now); + } adb->names_last_update = last_update; } @@ -1296,7 +1294,7 @@ UPGRADELOCK(&adb->names_lock, locktype); /* Allocate a new name and add it to the hash table. */ - adbname = new_adbname(adb, name, key.flags); + adbname = new_adbname(adb, name, key.type); void *found = NULL; result = isc_hashmap_add(adb->names, hashval, match_adbname, @@ -1339,16 +1337,6 @@ return adbname; } -static void -upgrade_entries_lock(dns_adb_t *adb, isc_rwlocktype_t *locktypep, - isc_stdtime_t now) { - if (*locktypep == isc_rwlocktype_read) { - UPGRADELOCK(&adb->entries_lock, *locktypep); - purge_stale_entries(adb, now); - adb->entries_last_update = now; - } -} - static bool match_adbentry(void *node, const void *key) { dns_adbentry_t *adbentry = node; @@ -1368,25 +1356,30 @@ isc_stdtime_t last_update; uint32_t hashval = isc_sockaddr_hash(addr, true); isc_rwlocktype_t locktype = isc_rwlocktype_read; + bool overmem = isc_mem_isovermem(adb->mctx); isc_time_set(&timenow, now, 0); RWLOCK(&adb->entries_lock, locktype); last_update = adb->entries_last_update; - if (now - last_update > ADB_STALE_MARGIN || - isc_mem_isovermem(adb->mctx)) - { + if (now - last_update > ADB_STALE_MARGIN || overmem) { last_update = now; - upgrade_entries_lock(adb, &locktype, now); + UPGRADELOCK(&adb->entries_lock, locktype); + if (overmem) { + purge_entries_overmem(adb, 2 * sizeof(*adbentry)); + } else { + purge_stale_entries(adb, now); + } + adb->entries_last_update = now; } result = isc_hashmap_find(adb->entries, hashval, match_adbentry, (const unsigned char *)addr, (void **)&adbentry); if (result == ISC_R_NOTFOUND) { - upgrade_entries_lock(adb, &locktype, now); + UPGRADELOCK(&adb->entries_lock, locktype); create: INSIST(locktype == isc_rwlocktype_write); @@ -1421,7 +1414,7 @@ /* We need to upgrade the LRU lock */ UNLOCK(&adbentry->lock); - upgrade_entries_lock(adb, &locktype, now); + UPGRADELOCK(&adb->entries_lock, locktype); LOCK(&adbentry->lock); FALLTHROUGH; case isc_rwlocktype_write: @@ -1527,18 +1520,18 @@ /* * The name must be locked and write lock on adb->names_lock must be held. */ -static bool +static void maybe_expire_name(dns_adbname_t *adbname, isc_stdtime_t now) { REQUIRE(DNS_ADBNAME_VALID(adbname)); /* Leave this name alone if it still has active namehooks... */ if (NAME_HAS_V4(adbname) || NAME_HAS_V6(adbname)) { - return false; + return; } /* ...an active fetch in progres... */ if (NAME_FETCH(adbname)) { - return false; + return; } /* ... or is not yet expired. */ @@ -1546,12 +1539,10 @@ !EXPIRE_OK(adbname->expire_v6, now) || !EXPIRE_OK(adbname->expire_target, now)) { - return false; + return; } expire_name(adbname, DNS_ADB_EXPIRED); - - return true; } static void @@ -1610,68 +1601,45 @@ */ static void purge_stale_names(dns_adb_t *adb, isc_stdtime_t now) { - bool overmem = isc_mem_isovermem(adb->mctx); - int max_removed = overmem ? 2 : 1; - int scans = 0, removed = 0; - dns_adbname_t *prev = NULL; + dns_adbname_t *adbname = ISC_LIST_TAIL(adb->names_lru); + + if (adbname == NULL) { + return; + } + + dns_adbname_ref(adbname); + LOCK(&adbname->lock); /* - * We limit the number of scanned entries to 10 (arbitrary choice) - * in order to avoid examining too many entries when there are many - * tail entries that have fetches (this should be rare, but could - * happen). + * Remove the name if it's expired or unused, has no address data. */ + maybe_expire_namehooks(adbname, now); + maybe_expire_name(adbname, now); + + UNLOCK(&adbname->lock); + dns_adbname_detach(&adbname); +} + +static void +purge_names_overmem(dns_adb_t *adb, size_t requested) { + dns_adbname_t *prev = NULL; + size_t expired = 0; for (dns_adbname_t *adbname = ISC_LIST_TAIL(adb->names_lru); - adbname != NULL && removed < max_removed && scans < 10; - adbname = prev) + adbname != NULL && expired < requested; adbname = prev) { prev = ISC_LIST_PREV(adbname, link); dns_adbname_ref(adbname); LOCK(&adbname->lock); - scans++; - /* * Remove the name if it's expired or unused, * has no address data. */ - maybe_expire_namehooks(adbname, now); - if (maybe_expire_name(adbname, now)) { - removed++; - goto next; - } - - /* - * Make sure that we are not purging ADB names that has been - * just created. - */ - if (adbname->last_used + ADB_CACHE_MINIMUM >= now) { - prev = NULL; - goto next; - } - - if (overmem) { - expire_name(adbname, DNS_ADB_CANCELED); - removed++; - goto next; - } - - if (adbname->last_used + ADB_STALE_MARGIN < now) { - expire_name(adbname, DNS_ADB_CANCELED); - removed++; - goto next; - } - - /* - * We won't expire anything on the LRU list as the - * .last_used + ADB_STALE_MARGIN will always be bigger - * than `now` for all previous entries, so we just stop - * the scanning. - */ - prev = NULL; - next: + maybe_expire_namehooks(adbname, INT_MAX); + expire_name(adbname, DNS_ADB_CANCELED); + expired += sizeof(*adbname); UNLOCK(&adbname->lock); dns_adbname_detach(&adbname); } @@ -1696,7 +1664,7 @@ * fetches, we can remove this name from the bucket. */ maybe_expire_namehooks(adbname, now); - (void)maybe_expire_name(adbname, now); + maybe_expire_name(adbname, now); UNLOCK(&adbname->lock); dns_adbname_detach(&adbname); } @@ -1715,10 +1683,28 @@ */ static void purge_stale_entries(dns_adb_t *adb, isc_stdtime_t now) { - bool overmem = isc_mem_isovermem(adb->mctx); - int max_removed = overmem ? 2 : 1; - int scans = 0, removed = 0; + dns_adbentry_t *adbentry = ISC_LIST_TAIL(adb->entries_lru); + + if (adbentry == NULL) { + return; + } + + dns_adbentry_ref(adbentry); + LOCK(&adbentry->lock); + + /* + * Remove the entry if it's expired and unused. + */ + (void)maybe_expire_entry(adbentry, now); + + UNLOCK(&adbentry->lock); + dns_adbentry_detach(&adbentry); +} + +static void +purge_entries_overmem(dns_adb_t *adb, size_t requested) { dns_adbentry_t *prev = NULL; + size_t expired = 0; /* * We limit the number of scanned entries to 10 (arbitrary choice) @@ -1728,53 +1714,16 @@ */ for (dns_adbentry_t *adbentry = ISC_LIST_TAIL(adb->entries_lru); - adbentry != NULL && removed < max_removed && scans < 10; - adbentry = prev) + adbentry != NULL && expired < requested; adbentry = prev) { prev = ISC_LIST_PREV(adbentry, link); dns_adbentry_ref(adbentry); LOCK(&adbentry->lock); - scans++; - - /* - * Remove the entry if it's expired and unused. - */ - if (maybe_expire_entry(adbentry, now)) { - removed++; - goto next; - } - - /* - * Make sure that we are not purging ADB entry that has been - * just created. - */ - if (adbentry->last_used + ADB_CACHE_MINIMUM >= now) { - prev = NULL; - goto next; - } - - if (overmem) { - maybe_expire_entry(adbentry, INT_MAX); - removed++; - goto next; - } - - if (adbentry->last_used + ADB_STALE_MARGIN < now) { - maybe_expire_entry(adbentry, INT_MAX); - removed++; - goto next; - } + (void)maybe_expire_entry(adbentry, INT_MAX); + expired += sizeof(*adbentry); - /* - * We won't expire anything on the LRU list as the - * .last_used + ADB_STALE_MARGIN will always be bigger - * than `now` for all previous entries, so we just stop - * the scanning - */ - prev = NULL; - next: UNLOCK(&adbentry->lock); dns_adbentry_detach(&adbentry); } @@ -1985,7 +1934,8 @@ again: /* Try to see if we know anything about this name at all. */ - adbname = get_attached_and_locked_name(adb, name, find->options, now); + adbname = get_attached_and_locked_name( + adb, name, ADBNAME_TYPE(find->options), now); if (NAME_DEAD(adbname)) { UNLOCK(&adbname->lock); @@ -2673,7 +2623,7 @@ result = dns_view_find(adb->view, adbname->name, rdtype, now, DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, true, - (adbname->flags & DNS_ADBFIND_STARTATZONE) != 0, + (adbname->type & DNS_ADBFIND_STARTATZONE) != 0, NULL, NULL, fname, &rdataset, NULL); switch (result) { @@ -3429,8 +3379,8 @@ * Delete all entries - with and without DNS_ADBFIND_STARTATZONE set * and with and without DNS_ADBFIND_STATICSTUB set. */ - key.flags = ((static_stub) ? DNS_ADBFIND_STATICSTUB : 0) | - ((start_at_zone) ? DNS_ADBFIND_STARTATZONE : 0); + key.type = ((static_stub) ? DNS_ADBFIND_STATICSTUB : 0) | + ((start_at_zone) ? DNS_ADBFIND_STARTATZONE : 0); result = isc_hashmap_find(adb->names, hash_adbname(&key), match_adbname, (void *)&key, (void **)&adbname); diff -Nru bind9-9.20.11/lib/dns/dnssec.c bind9-9.20.15/lib/dns/dnssec.c --- bind9-9.20.11/lib/dns/dnssec.c 2025-07-04 09:42:08.371329023 +0000 +++ bind9-9.20.15/lib/dns/dnssec.c 2025-10-18 10:16:12.604732944 +0000 @@ -409,7 +409,7 @@ } /* - * NS, SOA and DNSSKEY records are signed by their owner. + * NS, SOA and DNSKEY records are signed by their owner. * DS records are signed by the parent. */ switch (set->type) { diff -Nru bind9-9.20.11/lib/dns/dst_api.c bind9-9.20.15/lib/dns/dst_api.c --- bind9-9.20.11/lib/dns/dst_api.c 2025-07-04 09:42:08.372329047 +0000 +++ bind9-9.20.15/lib/dns/dst_api.c 2025-10-18 10:16:12.604732944 +0000 @@ -99,30 +99,44 @@ goto cleanup; \ } -#define NUMERIC_NTAGS (DST_MAX_NUMERIC + 1) -static const char *numerictags[NUMERIC_NTAGS] = { - "Predecessor:", "Successor:", "MaxTTL:", "RollPeriod:", - "Lifetime:", "DSPubCount:", "DSRemCount:" +static const char *numerictags[DST_MAX_NUMERIC] = { + [DST_NUM_PREDECESSOR] = "Predecessor:", + [DST_NUM_SUCCESSOR] = "Successor:", + [DST_NUM_MAXTTL] = "MaxTTL:", + [DST_NUM_ROLLPERIOD] = "RollPeriod:", + [DST_NUM_LIFETIME] = "Lifetime:", + [DST_NUM_DSPUBCOUNT] = "DSPubCount:", + [DST_NUM_DSDELCOUNT] = "DSRemCount:", }; -#define BOOLEAN_NTAGS (DST_MAX_BOOLEAN + 1) -static const char *booleantags[BOOLEAN_NTAGS] = { "KSK:", "ZSK:" }; - -#define TIMING_NTAGS (DST_MAX_TIMES + 1) -static const char *timingtags[TIMING_NTAGS] = { - "Generated:", "Published:", "Active:", "Revoked:", - "Retired:", "Removed:", - - "DSPublish:", "SyncPublish:", "SyncDelete:", - - "DNSKEYChange:", "ZRRSIGChange:", "KRRSIGChange:", "DSChange:", +static const char *booleantags[DST_MAX_BOOLEAN] = { + [DST_BOOL_KSK] = "KSK:", + [DST_BOOL_ZSK] = "ZSK:", +}; - "DSRemoved:" +static const char *timingtags[DST_MAX_TIMES] = { + [DST_TIME_CREATED] = "Generated:", + [DST_TIME_PUBLISH] = "Published:", + [DST_TIME_ACTIVATE] = "Active:", + [DST_TIME_REVOKE] = "Revoked:", + [DST_TIME_INACTIVE] = "Retired:", + [DST_TIME_DELETE] = "Removed:", + [DST_TIME_DSPUBLISH] = "DSPublish:", + [DST_TIME_SYNCPUBLISH] = "SyncPublish:", + [DST_TIME_SYNCDELETE] = "SyncDelete:", + [DST_TIME_DNSKEY] = "DNSKEYChange:", + [DST_TIME_ZRRSIG] = "ZRRSIGChange:", + [DST_TIME_KRRSIG] = "KRRSIGChange:", + [DST_TIME_DS] = "DSChange:", + [DST_TIME_DSDELETE] = "DSRemoved:", + [DST_TIME_SIGPUBLISH] = "ZRRSIGPublish:", + [DST_TIME_SIGDELETE] = "ZZRRSIGDelete:", }; -#define KEYSTATES_NTAGS (DST_MAX_KEYSTATES + 1) -static const char *keystatestags[KEYSTATES_NTAGS] = { - "DNSKEYState:", "ZRRSIGState:", "KRRSIGState:", "DSState:", "GoalState:" +static const char *keystatestags[DST_MAX_KEYSTATES] = { + [DST_KEY_DNSKEY] = "DNSKEYState:", [DST_KEY_ZRRSIG] = "ZRRSIGState:", + [DST_KEY_KRRSIG] = "KRRSIGState:", [DST_KEY_DS] = "DSState:", + [DST_KEY_GOAL] = "GoalState:", }; #define KEYSTATES_NVALUES 4 @@ -1089,7 +1103,7 @@ dst_key_getbool(const dst_key_t *key, int type, bool *valuep) { REQUIRE(VALID_KEY(key)); REQUIRE(valuep != NULL); - REQUIRE(type <= DST_MAX_BOOLEAN); + REQUIRE(type < DST_MAX_BOOLEAN); isc_mutex_lock(&(((dst_key_t *)key)->mdlock)); if (!key->boolset[type]) { @@ -1105,7 +1119,7 @@ void dst_key_setbool(dst_key_t *key, int type, bool value) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_BOOLEAN); + REQUIRE(type < DST_MAX_BOOLEAN); isc_mutex_lock(&key->mdlock); key->modified = key->modified || !key->boolset[type] || @@ -1118,7 +1132,7 @@ void dst_key_unsetbool(dst_key_t *key, int type) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_BOOLEAN); + REQUIRE(type < DST_MAX_BOOLEAN); isc_mutex_lock(&key->mdlock); key->modified = key->modified || key->boolset[type]; @@ -1130,7 +1144,7 @@ dst_key_getnum(const dst_key_t *key, int type, uint32_t *valuep) { REQUIRE(VALID_KEY(key)); REQUIRE(valuep != NULL); - REQUIRE(type <= DST_MAX_NUMERIC); + REQUIRE(type < DST_MAX_NUMERIC); isc_mutex_lock(&(((dst_key_t *)key)->mdlock)); if (!key->numset[type]) { @@ -1146,7 +1160,7 @@ void dst_key_setnum(dst_key_t *key, int type, uint32_t value) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_NUMERIC); + REQUIRE(type < DST_MAX_NUMERIC); isc_mutex_lock(&key->mdlock); key->modified = key->modified || !key->numset[type] || @@ -1159,7 +1173,7 @@ void dst_key_unsetnum(dst_key_t *key, int type) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_NUMERIC); + REQUIRE(type < DST_MAX_NUMERIC); isc_mutex_lock(&key->mdlock); key->modified = key->modified || key->numset[type]; @@ -1171,7 +1185,7 @@ dst_key_gettime(const dst_key_t *key, int type, isc_stdtime_t *timep) { REQUIRE(VALID_KEY(key)); REQUIRE(timep != NULL); - REQUIRE(type <= DST_MAX_TIMES); + REQUIRE(type < DST_MAX_TIMES); isc_mutex_lock(&(((dst_key_t *)key)->mdlock)); if (!key->timeset[type]) { @@ -1186,7 +1200,7 @@ void dst_key_settime(dst_key_t *key, int type, isc_stdtime_t when) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_TIMES); + REQUIRE(type < DST_MAX_TIMES); isc_mutex_lock(&key->mdlock); key->modified = key->modified || !key->timeset[type] || @@ -1199,7 +1213,7 @@ void dst_key_unsettime(dst_key_t *key, int type) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_TIMES); + REQUIRE(type < DST_MAX_TIMES); isc_mutex_lock(&key->mdlock); key->modified = key->modified || key->timeset[type]; @@ -1211,7 +1225,7 @@ dst_key_getstate(const dst_key_t *key, int type, dst_key_state_t *statep) { REQUIRE(VALID_KEY(key)); REQUIRE(statep != NULL); - REQUIRE(type <= DST_MAX_KEYSTATES); + REQUIRE(type < DST_MAX_KEYSTATES); isc_mutex_lock(&(((dst_key_t *)key)->mdlock)); if (!key->keystateset[type]) { @@ -1227,7 +1241,7 @@ void dst_key_setstate(dst_key_t *key, int type, dst_key_state_t state) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_KEYSTATES); + REQUIRE(type < DST_MAX_KEYSTATES); isc_mutex_lock(&key->mdlock); key->modified = key->modified || !key->keystateset[type] || @@ -1240,7 +1254,7 @@ void dst_key_unsetstate(dst_key_t *key, int type) { REQUIRE(VALID_KEY(key)); - REQUIRE(type <= DST_MAX_KEYSTATES); + REQUIRE(type < DST_MAX_KEYSTATES); isc_mutex_lock(&key->mdlock); key->modified = key->modified || key->keystateset[type]; @@ -1751,22 +1765,22 @@ static int find_numericdata(const char *s) { - return find_metadata(s, numerictags, NUMERIC_NTAGS); + return find_metadata(s, numerictags, DST_MAX_NUMERIC); } static int find_booleandata(const char *s) { - return find_metadata(s, booleantags, BOOLEAN_NTAGS); + return find_metadata(s, booleantags, DST_MAX_BOOLEAN); } static int find_timingdata(const char *s) { - return find_metadata(s, timingtags, TIMING_NTAGS); + return find_metadata(s, timingtags, DST_MAX_TIMES); } static int find_keystatedata(const char *s) { - return find_metadata(s, keystatestags, KEYSTATES_NTAGS); + return find_metadata(s, keystatestags, DST_MAX_KEYSTATES); } static isc_result_t @@ -1858,7 +1872,7 @@ /* Numeric metadata */ tag = find_numericdata(DST_AS_STR(token)); if (tag >= 0) { - INSIST(tag < NUMERIC_NTAGS); + INSIST(tag < DST_MAX_NUMERIC); NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); if (token.type != isc_tokentype_number) { @@ -1872,7 +1886,7 @@ /* Boolean metadata */ tag = find_booleandata(DST_AS_STR(token)); if (tag >= 0) { - INSIST(tag < BOOLEAN_NTAGS); + INSIST(tag < DST_MAX_BOOLEAN); NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) { @@ -1894,7 +1908,7 @@ if (tag >= 0) { uint32_t when; - INSIST(tag < TIMING_NTAGS); + INSIST(tag < DST_MAX_TIMES); NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) { @@ -1915,7 +1929,7 @@ if (tag >= 0) { dst_key_state_t state; - INSIST(tag < KEYSTATES_NTAGS); + INSIST(tag < DST_MAX_KEYSTATES); NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) { @@ -2116,6 +2130,8 @@ printtime(key, DST_TIME_DELETE, "Removed", fp); printtime(key, DST_TIME_DSPUBLISH, "DSPublish", fp); printtime(key, DST_TIME_DSDELETE, "DSRemoved", fp); + printtime(key, DST_TIME_SIGPUBLISH, "SigPublish", fp); + printtime(key, DST_TIME_SIGDELETE, "SigRemoved", fp); printtime(key, DST_TIME_SYNCPUBLISH, "PublishCDS", fp); printtime(key, DST_TIME_SYNCDELETE, "DeleteCDS", fp); @@ -2420,7 +2436,7 @@ * None of the key timing metadata, except Created, may be set. Key * state times may be set only if their respective state is HIDDEN. */ - for (int i = 0; i < DST_MAX_TIMES + 1; i++) { + for (int i = 0; i < DST_MAX_TIMES; i++) { state_type_set = false; switch (i) { @@ -2741,7 +2757,7 @@ REQUIRE(VALID_KEY(to)); REQUIRE(VALID_KEY(from)); - for (int i = 0; i < DST_MAX_TIMES + 1; i++) { + for (int i = 0; i < DST_MAX_TIMES; i++) { result = dst_key_gettime(from, i, &when); if (result == ISC_R_SUCCESS) { dst_key_settime(to, i, when); @@ -2750,7 +2766,7 @@ } } - for (int i = 0; i < DST_MAX_NUMERIC + 1; i++) { + for (int i = 0; i < DST_MAX_NUMERIC; i++) { result = dst_key_getnum(from, i, &num); if (result == ISC_R_SUCCESS) { dst_key_setnum(to, i, num); @@ -2759,7 +2775,7 @@ } } - for (int i = 0; i < DST_MAX_BOOLEAN + 1; i++) { + for (int i = 0; i < DST_MAX_BOOLEAN; i++) { result = dst_key_getbool(from, i, &yesno); if (result == ISC_R_SUCCESS) { dst_key_setbool(to, i, yesno); @@ -2768,7 +2784,7 @@ } } - for (int i = 0; i < DST_MAX_KEYSTATES + 1; i++) { + for (int i = 0; i < DST_MAX_KEYSTATES; i++) { result = dst_key_getstate(from, i, &state); if (result == ISC_R_SUCCESS) { dst_key_setstate(to, i, state); diff -Nru bind9-9.20.11/lib/dns/dst_internal.h bind9-9.20.15/lib/dns/dst_internal.h --- bind9-9.20.11/lib/dns/dst_internal.h 2025-07-04 09:42:08.372329047 +0000 +++ bind9-9.20.15/lib/dns/dst_internal.h 2025-10-18 10:16:12.604732944 +0000 @@ -104,21 +104,20 @@ } pkeypair; } keydata; /*%< pointer to key in crypto pkg fmt */ - isc_stdtime_t times[DST_MAX_TIMES + 1]; /*%< timing metadata */ - bool timeset[DST_MAX_TIMES + 1]; /*%< data set? */ + isc_stdtime_t times[DST_MAX_TIMES]; /*%< timing metadata */ + bool timeset[DST_MAX_TIMES]; /*%< data set? */ - uint32_t nums[DST_MAX_NUMERIC + 1]; /*%< numeric metadata - * */ - bool numset[DST_MAX_NUMERIC + 1]; /*%< data set? */ + uint32_t nums[DST_MAX_NUMERIC]; /*%< numeric metadata + * */ + bool numset[DST_MAX_NUMERIC]; /*%< data set? */ - bool bools[DST_MAX_BOOLEAN + 1]; /*%< boolean metadata - * */ - bool boolset[DST_MAX_BOOLEAN + 1]; /*%< data set? */ + bool bools[DST_MAX_BOOLEAN]; /*%< boolean metadata + * */ + bool boolset[DST_MAX_BOOLEAN]; /*%< data set? */ - dst_key_state_t keystates[DST_MAX_KEYSTATES + 1]; /*%< key states - * */ - bool keystateset[DST_MAX_KEYSTATES + 1]; /*%< data - * set? */ + dst_key_state_t keystates[DST_MAX_KEYSTATES]; /*%< key states + * */ + bool keystateset[DST_MAX_KEYSTATES]; /*%< data set? */ bool kasp; /*%< key has kasp state */ bool inactive; /*%< private key not present as it is diff -Nru bind9-9.20.11/lib/dns/dst_parse.c bind9-9.20.15/lib/dns/dst_parse.c --- bind9-9.20.11/lib/dns/dst_parse.c 2025-07-04 09:42:08.372329047 +0000 +++ bind9-9.20.15/lib/dns/dst_parse.c 2025-10-18 10:16:12.605732959 +0000 @@ -52,17 +52,33 @@ #define PRIVATE_KEY_STR "Private-key-format:" #define ALGORITHM_STR "Algorithm:" -#define TIMING_NTAGS (DST_MAX_TIMES + 1) -static const char *timetags[TIMING_NTAGS] = { - "Created:", "Publish:", "Activate:", "Revoke:", - "Inactive:", "Delete:", "DSPublish:", "SyncPublish:", - "SyncDelete:", NULL, NULL, NULL, - NULL +static const char *timetags[DST_MAX_TIMES] = { + [DST_TIME_CREATED] = "Created:", + [DST_TIME_PUBLISH] = "Publish:", + [DST_TIME_ACTIVATE] = "Activate:", + [DST_TIME_REVOKE] = "Revoke:", + [DST_TIME_INACTIVE] = "Inactive:", + [DST_TIME_DELETE] = "Delete:", + [DST_TIME_DSPUBLISH] = "DSPublish:", + [DST_TIME_SYNCPUBLISH] = "SyncPublish:", + [DST_TIME_SYNCDELETE] = "SyncDelete:", + [DST_TIME_DNSKEY] = NULL, + [DST_TIME_ZRRSIG] = NULL, + [DST_TIME_KRRSIG] = NULL, + [DST_TIME_DS] = NULL, + [DST_TIME_DSDELETE] = NULL, + [DST_TIME_SIGPUBLISH] = NULL, + [DST_TIME_SIGDELETE] = NULL, }; -#define NUMERIC_NTAGS (DST_MAX_NUMERIC + 1) -static const char *numerictags[NUMERIC_NTAGS] = { - "Predecessor:", "Successor:", "MaxTTL:", "RollPeriod:", NULL, NULL, NULL +static const char *numerictags[DST_MAX_NUMERIC] = { + [DST_NUM_PREDECESSOR] = "Predecessor:", + [DST_NUM_SUCCESSOR] = "Successor:", + [DST_NUM_MAXTTL] = "MaxTTL:", + [DST_NUM_ROLLPERIOD] = "RollPeriod:", + [DST_NUM_LIFETIME] = NULL, + [DST_NUM_DSPUBCOUNT] = NULL, + [DST_NUM_DSDELCOUNT] = NULL, }; struct parse_map { @@ -152,12 +168,12 @@ static int find_timedata(const char *s) { - return find_metadata(s, timetags, TIMING_NTAGS); + return find_metadata(s, timetags, DST_MAX_TIMES); } static int find_numericdata(const char *s) { - return find_metadata(s, numerictags, NUMERIC_NTAGS); + return find_metadata(s, numerictags, DST_MAX_NUMERIC); } static int @@ -490,7 +506,7 @@ /* Numeric metadata */ tag = find_numericdata(DST_AS_STR(token)); if (tag >= 0) { - INSIST(tag < NUMERIC_NTAGS); + INSIST(tag < DST_MAX_NUMERIC); NEXTTOKEN(lex, opt | ISC_LEXOPT_NUMBER, &token); if (token.type != isc_tokentype_number) { @@ -505,7 +521,7 @@ /* Timing metadata */ tag = find_timedata(DST_AS_STR(token)); if (tag >= 0) { - INSIST(tag < TIMING_NTAGS); + INSIST(tag < DST_MAX_TIMES); NEXTTOKEN(lex, opt, &token); if (token.type != isc_tokentype_string) { @@ -722,7 +738,7 @@ /* Add the metadata tags */ if (major > 1 || (major == 1 && minor >= 3)) { - for (i = 0; i < NUMERIC_NTAGS; i++) { + for (i = 0; i < DST_MAX_NUMERIC; i++) { result = dst_key_getnum(key, i, &value); if (result != ISC_R_SUCCESS) { continue; @@ -731,7 +747,7 @@ fprintf(fp, "%s %u\n", numerictags[i], value); } } - for (i = 0; i < TIMING_NTAGS; i++) { + for (i = 0; i < DST_MAX_TIMES; i++) { result = dst_key_gettime(key, i, &when); if (result != ISC_R_SUCCESS) { continue; diff -Nru bind9-9.20.11/lib/dns/include/dns/db.h bind9-9.20.15/lib/dns/include/dns/db.h --- bind9-9.20.11/lib/dns/include/dns/db.h 2025-07-04 09:42:08.375329117 +0000 +++ bind9-9.20.15/lib/dns/include/dns/db.h 2025-10-18 10:16:12.607732991 +0000 @@ -302,6 +302,7 @@ #define DNS_DBADD_EXACT 0x04 #define DNS_DBADD_EXACTTTL 0x08 #define DNS_DBADD_PREFETCH 0x10 +#define DNS_DBADD_EQUALOK 0x20 /*@}*/ /*% @@ -1248,6 +1249,10 @@ * the old and new rdata sets. If #DNS_DBADD_EXACTTTL is set then both * the old and new rdata sets must have the same ttl. * + * \li If the #DNS_DBADD_EQUALOK option is set, and the database is not + * changed, compare the old and new rdatasets; if they are equal, + * return #ISC_R_SUCCESS instead of #DNS_R_UNCHANGED. + * * \li The 'now' field is ignored if 'db' is a zone database. If 'db' is * a cache database, then the added rdataset will expire no later than * now + rdataset->ttl. @@ -1277,8 +1282,12 @@ * Returns: * * \li #ISC_R_SUCCESS - * \li #DNS_R_UNCHANGED The operation did not change - * anything. \li #ISC_R_NOMEMORY \li #DNS_R_NOTEXACT + * \li #DNS_R_UNCHANGED The operation did not change anything. + * \li #ISC_R_NOMEMORY + * \li #DNS_R_NOTEXACT The TTL didn't match and #DNS_DBADD_EXACTTTL + * was set, or there was a partial overlap + * between the old and new rdatasets and + * DNS_DBADD_EXACT was set. * * \li Other results are possible, depending upon the database * implementation used. diff -Nru bind9-9.20.11/lib/dns/include/dns/ds.h bind9-9.20.15/lib/dns/include/dns/ds.h --- bind9-9.20.11/lib/dns/include/dns/ds.h 2025-07-04 09:42:08.376329140 +0000 +++ bind9-9.20.15/lib/dns/include/dns/ds.h 2025-10-18 10:16:12.608733006 +0000 @@ -23,6 +23,8 @@ #define DNS_DSDIGEST_GOST (3) #define DNS_DSDIGEST_SHA384 (4) +#define DNS_DSDIGEST_MAX (255) + /* * Assuming SHA-384 digest type. */ diff -Nru bind9-9.20.11/lib/dns/include/dns/dsync.h bind9-9.20.15/lib/dns/include/dns/dsync.h --- bind9-9.20.11/lib/dns/include/dns/dsync.h 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/lib/dns/include/dns/dsync.h 2025-10-18 10:16:12.608733006 +0000 @@ -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. + */ + +#pragma once + +#define DNS_DSYNCSCHEME_NOTIFY (1) + +#define DNS_DSYNCSCHEMEFORMAT_SIZE (7) + +isc_result_t +dns_dsyncscheme_fromtext(dns_dsyncscheme_t *schemep, isc_textregion_t *source); + +isc_result_t +dns_dsyncscheme_totext(dns_dsyncscheme_t scheme, isc_buffer_t *target); + +void +dns_dsyncscheme_format(dns_dsyncscheme_t scheme, char *cp, unsigned int size); diff -Nru bind9-9.20.11/lib/dns/include/dns/kasp.h bind9-9.20.15/lib/dns/include/dns/kasp.h --- bind9-9.20.11/lib/dns/include/dns/kasp.h 2025-07-04 09:42:08.377329164 +0000 +++ bind9-9.20.15/lib/dns/include/dns/kasp.h 2025-10-18 10:16:12.609733022 +0000 @@ -32,6 +32,7 @@ #include #include +#include #include ISC_LANG_BEGINDECLS @@ -111,6 +112,7 @@ dns_ttl_t zone_max_ttl; uint32_t zone_propagation_delay; bool inline_signing; + bool manual_mode; /* Parent settings */ dns_ttl_t parent_ds_ttl; @@ -139,6 +141,8 @@ #define DNS_KASP_KEY_ROLE_KSK 0x01 #define DNS_KASP_KEY_ROLE_ZSK 0x02 +#define DNS_KASP_KEY_FORMATSIZE (DNS_NAME_FORMATSIZE + 64) + isc_result_t dns_kasp_create(isc_mem_t *mctx, const char *name, dns_kasp_t **kaspp); /*%< @@ -447,6 +451,30 @@ *\li 'kasp' is a valid, thawed kasp. */ +bool +dns_kasp_manualmode(dns_kasp_t *kasp); +/*%< + * Should we use manual-mode for this DNSSEC policy? + * + * Requires: + * + *\li 'kasp' is a valid, frozen kasp. + * + * Returns: + * + *\li true or false. + */ + +void +dns_kasp_setmanualmode(dns_kasp_t *kasp, bool value); +/*%< + * Set manual-mode. + * + * Requires: + * + *\li 'kasp' is a valid, thawed kasp. + */ + dns_ttl_t dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback); /*%< @@ -761,6 +789,17 @@ *\li False, otherwise. */ +void +dns_kasp_key_format(dns_kasp_key_t *key, char *cp, unsigned int size); +/*%< + * Write the identifying information about the policy key (role, + * algorithm, tag range) into a string 'cp' of size 'size'. + * Requires: + * + *\li key != NULL + *\li cp != NULL + */ + bool dns_kasp_nsec3(dns_kasp_t *kasp); /*%< diff -Nru bind9-9.20.11/lib/dns/include/dns/keymgr.h bind9-9.20.15/lib/dns/include/dns/keymgr.h --- bind9-9.20.11/lib/dns/include/dns/keymgr.h 2025-07-04 09:42:08.377329164 +0000 +++ bind9-9.20.15/lib/dns/include/dns/keymgr.h 2025-10-18 10:16:12.610733037 +0000 @@ -24,6 +24,12 @@ ISC_LANG_BEGINDECLS +#define DNS_KEYMGRATTR_NONE 0x00 /*%< No ordering. */ +#define DNS_KEYMGRATTR_S2I 0x01 /*%< Secure to insecure. */ +#define DNS_KEYMGRATTR_NOROLL 0x02 /*%< No rollover allowed. */ +#define DNS_KEYMGRATTR_FORCESTEP 0x04 /*%< Force next step in manual-mode. */ +#define DNS_KEYMGRATTR_FULLSIGN 0x08 /*%< Full sign was issued. */ + void dns_keymgr_settime_syncpublish(dst_key_t *key, dns_kasp_t *kasp, bool first); /*%< @@ -35,11 +41,27 @@ *\li 'kasp' is a valid DNSSEC policy. */ +void +dns_keymgr_key_init(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now, + bool csk); +/* + * Initialize this key's properties if not already present. A key created + * and derived from a dnssec-policy will have the required metadata available, + * otherwise these may be missing and need to be initialized. The key states + * will be initialized according to existing timing metadata. If 'csk' is + * set to true, the key is considered a combined signing key (CSK). + * + * Requires: + *\li 'key' is a valid DNSSEC key. + *\li 'kasp' is a valid DNSSEC policy. + */ + isc_result_t dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass, isc_mem_t *mctx, dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *dnskeys, const char *keydir, - dns_kasp_t *kasp, isc_stdtime_t now, isc_stdtime_t *nexttime); + dns_kasp_t *kasp, uint8_t options, isc_stdtime_t now, + isc_stdtime_t *nexttime); /*%< * Manage keys in 'keyring' and update timing data according to 'kasp' policy. * Create new keys for 'origin' if necessary. Append all such keys, along @@ -48,6 +70,10 @@ * Update key states and store changes back to disk. Store when to run next * in 'nexttime'. * + * If 'options' has DNS_KEYMGRATTR_FORCESTEP set, the next steps in the process + * are allowed, even if 'kasp' has 'manual-mode' enabled. Other options should + * not be set in 'options'. + * * Requires: *\li 'origin' is a valid FQDN. *\li 'mctx' is a valid memory context. diff -Nru bind9-9.20.11/lib/dns/include/dns/message.h bind9-9.20.15/lib/dns/include/dns/message.h --- bind9-9.20.11/lib/dns/include/dns/message.h 2025-07-04 09:42:08.378329187 +0000 +++ bind9-9.20.15/lib/dns/include/dns/message.h 2025-10-18 10:16:12.611733053 +0000 @@ -262,6 +262,7 @@ unsigned int rdclass_set : 1; /* 14 */ unsigned int fuzzing : 1; /* 15 */ unsigned int free_pools : 1; /* 16 */ + unsigned int has_dname : 1; /* 17 */ unsigned int : 0; unsigned int opt_reserved; @@ -1482,4 +1483,11 @@ void dns_message_destroypools(isc_mempool_t **namepoolp, isc_mempool_t **rdspoolp); +bool +dns_message_hasdname(dns_message_t *msg); +/*%< + * Return whether a DNAME was detected in the ANSWER section of a QUERY + * message when it was parsed. + */ + ISC_LANG_ENDDECLS diff -Nru bind9-9.20.11/lib/dns/include/dns/qp.h bind9-9.20.15/lib/dns/include/dns/qp.h --- bind9-9.20.11/lib/dns/include/dns/qp.h 2025-07-04 09:42:08.379329211 +0000 +++ bind9-9.20.15/lib/dns/include/dns/qp.h 2025-10-18 10:16:12.612733068 +0000 @@ -90,6 +90,12 @@ #include /*% + * How many bytes a qp-trie might allocate as part of an insert. Needed for + * overmem checks. + */ +#define QP_SAFETY_MARGIN ((1ul << 12ul) * 12) + +/*% * A `dns_qp_t` supports single-threaded read/write access. */ typedef struct dns_qp dns_qp_t; @@ -306,7 +312,6 @@ size_t hold; /*%< nodes retained for readers */ size_t free; /*%< nodes to be reclaimed */ size_t node_size; /*%< in bytes */ - size_t chunk_size; /*%< nodes per chunk */ size_t chunk_count; /*%< allocated chunks */ size_t bytes; /*%< total memory in chunks and metadata */ bool fragmented; /*%< trie needs compaction */ diff -Nru bind9-9.20.11/lib/dns/include/dns/rdataset.h bind9-9.20.15/lib/dns/include/dns/rdataset.h --- bind9-9.20.11/lib/dns/include/dns/rdataset.h 2025-07-04 09:42:08.380329234 +0000 +++ bind9-9.20.15/lib/dns/include/dns/rdataset.h 2025-10-18 10:16:12.613733084 +0000 @@ -101,8 +101,6 @@ void (*getownercase)(const dns_rdataset_t *rdataset, dns_name_t *name); isc_result_t (*addglue)(dns_rdataset_t *rdataset, dns_dbversion_t *version, dns_message_t *msg); - bool (*equals)(const dns_rdataset_t *rdataset1, - const dns_rdataset_t *rdataset2); } dns_rdatasetmethods_t; #define DNS_RDATASET_MAGIC ISC_MAGIC('D', 'N', 'S', 'R') @@ -245,11 +243,6 @@ * * \def DNS_RDATASETATTR_LOADORDER * Output the RRset in load order. - * - * \def DNS_RDATASETATTR_STALE_ADDED - * Set on rdatasets that were added during a stale-answer-client-timeout - * lookup. In other words, the RRset was added during a lookup of stale - * data and does not necessarily mean that the rdataset itself is stale. */ #define DNS_RDATASETATTR_NONE 0x00000000 /*%< No ordering. */ @@ -281,9 +274,9 @@ #define DNS_RDATASETATTR_STALE 0x01000000 #define DNS_RDATASETATTR_ANCIENT 0x02000000 #define DNS_RDATASETATTR_STALE_WINDOW 0x04000000 -#define DNS_RDATASETATTR_STALE_ADDED 0x08000000 -#define DNS_RDATASETATTR_KEEPCASE 0x10000000 -#define DNS_RDATASETATTR_STATICSTUB 0x20000000 +/* #define DNS_RDATASETATTR_STALE_ADDED 0x08000000 - Obsolete */ +#define DNS_RDATASETATTR_KEEPCASE 0x10000000 +#define DNS_RDATASETATTR_STATICSTUB 0x20000000 /*% * _OMITDNSSEC: @@ -698,14 +691,4 @@ * Display trust in textual form. */ -bool -dns_rdataset_equals(const dns_rdataset_t *rdataset1, - const dns_rdataset_t *rdataset2); -/*%< - * Returns true if the rdata in the rdataset is equal. - * - * Requires: - * \li 'rdataset1' is a valid rdataset. - * \li 'rdataset2' is a valid rdataset. - */ ISC_LANG_ENDDECLS diff -Nru bind9-9.20.11/lib/dns/include/dns/rpz.h bind9-9.20.15/lib/dns/include/dns/rpz.h --- bind9-9.20.11/lib/dns/include/dns/rpz.h 2025-07-04 09:42:08.381329257 +0000 +++ bind9-9.20.15/lib/dns/include/dns/rpz.h 2025-10-18 10:16:12.614733099 +0000 @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -154,6 +155,8 @@ dns_rpz_zones_t *rpzs; /* owner */ isc_time_t lastupdated; /* last time the zone was processed * */ + bool processed; /* the zone is processed. */ + bool dbregistered; /* db callback notify is registered. */ bool updatepending; /* there is an update pending */ bool updaterunning; /* there is an update running */ isc_result_t updateresult; /* result from the offloaded work */ @@ -205,6 +208,8 @@ bool qname_wait_recurse; bool nsip_wait_recurse; bool nsdname_wait_recurse; + bool servfail_until_ready; + bool slow_mode; /* Used for system tests with '-T rpzslow' */ unsigned int min_ns_labels; dns_rpz_num_t num_zones; }; @@ -222,6 +227,9 @@ dns_rpz_zone_t *zones[DNS_RPZ_MAX_ZONES]; dns_rpz_triggers_t triggers[DNS_RPZ_MAX_ZONES]; + _Atomic(dns_rpz_num_t) zones_registered; + _Atomic(dns_rpz_num_t) zones_processed; + /* * RPZ policy version number. * It is initially 0 and it increases whenever the server is @@ -264,6 +272,7 @@ isc_rwlock_t search_lock; isc_mutex_t maint_lock; + bool first_time; bool shuttingdown; dns_rpz_cidr_node_t *cidr; @@ -393,7 +402,8 @@ isc_result_t dns_rpz_new_zones(dns_view_t *view, isc_loopmgr_t *loopmgr, char *rps_cstr, - size_t rps_cstr_size, dns_rpz_zones_t **rpzsp); + size_t rps_cstr_size, dns_rpz_zones_t **rpzsp, + bool first_time); isc_result_t dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp); diff -Nru bind9-9.20.11/lib/dns/include/dns/tkey.h bind9-9.20.15/lib/dns/include/dns/tkey.h --- bind9-9.20.11/lib/dns/include/dns/tkey.h 2025-07-04 09:42:08.382329281 +0000 +++ bind9-9.20.15/lib/dns/include/dns/tkey.h 2025-10-18 10:16:12.615733115 +0000 @@ -35,7 +35,6 @@ #define DNS_TKEYMODE_DELETE 5 struct dns_tkeyctx { - dns_name_t *domain; dns_gss_cred_id_t gsscred; isc_mem_t *mctx; char *gssapi_keytab; diff -Nru bind9-9.20.11/lib/dns/include/dns/types.h bind9-9.20.15/lib/dns/include/dns/types.h --- bind9-9.20.11/lib/dns/include/dns/types.h 2025-07-04 09:42:08.383329304 +0000 +++ bind9-9.20.15/lib/dns/include/dns/types.h 2025-10-18 10:16:12.616733130 +0000 @@ -80,6 +80,7 @@ typedef struct dns_dnsseckey dns_dnsseckey_t; typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t; typedef uint8_t dns_dsdigest_t; +typedef uint8_t dns_dsyncscheme_t; typedef struct dns_dtdata dns_dtdata_t; typedef struct dns_dtenv dns_dtenv_t; typedef struct dns_dtmsg dns_dtmsg_t; diff -Nru bind9-9.20.11/lib/dns/include/dns/zone.h bind9-9.20.15/lib/dns/include/dns/zone.h --- bind9-9.20.11/lib/dns/include/dns/zone.h 2025-07-04 09:42:08.384329328 +0000 +++ bind9-9.20.15/lib/dns/include/dns/zone.h 2025-10-18 10:16:12.617733146 +0000 @@ -103,6 +103,7 @@ DNS_ZONEOPT_CHECKTTL = 1 << 28, /*%< check max-zone-ttl */ DNS_ZONEOPT_AUTOEMPTY = 1 << 29, /*%< automatic empty zone */ DNS_ZONEOPT_CHECKSVCB = 1 << 30, /*%< check SVBC records */ + DNS_ZONEOPT_FORCEKEYMGR = 1ULL << 31, /*%< force keymgr step */ DNS_ZONEOPT___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */ } dns_zoneopt_t; @@ -2301,14 +2302,6 @@ */ isc_result_t -dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, - bool deleteit); -/*%< - * Initiate/resume signing of the entire zone with the zone DNSKEY(s) - * that match the given algorithm and keyid. - */ - -isc_result_t dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param); /*%< * Incrementally add a NSEC3 chain that corresponds to 'nsec3param'. @@ -2324,7 +2317,7 @@ */ void -dns_zone_rekey(dns_zone_t *zone, bool fullsign); +dns_zone_rekey(dns_zone_t *zone, bool fullsign, bool forcekeymgr); /*%< * Update the zone's DNSKEY set from the key repository. * @@ -2332,6 +2325,9 @@ * the zone with the new key. Otherwise, if there are no keys or * if the new keys are for algorithms that have already signed the * zone, then the zone can be re-signed incrementally. + * + * If 'forcekeymgr' is true, trigger a rekey event and allow the + * next steps in the run to happen. */ isc_result_t diff -Nru bind9-9.20.11/lib/dns/include/dst/dst.h bind9-9.20.15/lib/dns/include/dst/dst.h --- bind9-9.20.11/lib/dns/include/dst/dst.h 2025-07-04 09:42:08.384329328 +0000 +++ bind9-9.20.15/lib/dns/include/dst/dst.h 2025-10-18 10:16:12.617733146 +0000 @@ -133,44 +133,58 @@ #define DST_TYPE_TEMPLATE 0x10000000 /* Key timing metadata definitions */ -#define DST_TIME_CREATED 0 -#define DST_TIME_PUBLISH 1 -#define DST_TIME_ACTIVATE 2 -#define DST_TIME_REVOKE 3 -#define DST_TIME_INACTIVE 4 -#define DST_TIME_DELETE 5 -#define DST_TIME_DSPUBLISH 6 -#define DST_TIME_SYNCPUBLISH 7 -#define DST_TIME_SYNCDELETE 8 -#define DST_TIME_DNSKEY 9 -#define DST_TIME_ZRRSIG 10 -#define DST_TIME_KRRSIG 11 -#define DST_TIME_DS 12 -#define DST_TIME_DSDELETE 13 -#define DST_MAX_TIMES 13 +enum { + DST_TIME_CREATED = 0, + DST_TIME_PUBLISH = 1, + DST_TIME_ACTIVATE = 2, + DST_TIME_REVOKE = 3, + DST_TIME_INACTIVE = 4, + DST_TIME_DELETE = 5, + DST_TIME_DSPUBLISH = 6, + DST_TIME_SYNCPUBLISH = 7, + DST_TIME_SYNCDELETE = 8, + DST_TIME_DNSKEY = 9, + DST_TIME_ZRRSIG = 10, + DST_TIME_KRRSIG = 11, + DST_TIME_DS = 12, + DST_TIME_DSDELETE = 13, + DST_TIME_SIGPUBLISH = 14, + DST_TIME_SIGDELETE = 15, + + DST_MAX_TIMES = 16 /* MUST BE LAST */ +}; /* Numeric metadata definitions */ -#define DST_NUM_PREDECESSOR 0 -#define DST_NUM_SUCCESSOR 1 -#define DST_NUM_MAXTTL 2 -#define DST_NUM_ROLLPERIOD 3 -#define DST_NUM_LIFETIME 4 -#define DST_NUM_DSPUBCOUNT 5 -#define DST_NUM_DSDELCOUNT 6 -#define DST_MAX_NUMERIC 6 +enum { + DST_NUM_PREDECESSOR = 0, + DST_NUM_SUCCESSOR = 1, + DST_NUM_MAXTTL = 2, + DST_NUM_ROLLPERIOD = 3, + DST_NUM_LIFETIME = 4, + DST_NUM_DSPUBCOUNT = 5, + DST_NUM_DSDELCOUNT = 6, + + DST_MAX_NUMERIC = 7 /* MUST BE LAST */ +}; /* Boolean metadata definitions */ -#define DST_BOOL_KSK 0 -#define DST_BOOL_ZSK 1 -#define DST_MAX_BOOLEAN 1 +enum { + DST_BOOL_KSK = 0, + DST_BOOL_ZSK = 1, + + DST_MAX_BOOLEAN = 2 /* MUST BE LAST */ +}; /* Key state metadata definitions */ -#define DST_KEY_DNSKEY 0 -#define DST_KEY_ZRRSIG 1 -#define DST_KEY_KRRSIG 2 -#define DST_KEY_DS 3 -#define DST_KEY_GOAL 4 -#define DST_MAX_KEYSTATES 4 +enum { + DST_KEY_DNSKEY = 0, + DST_KEY_ZRRSIG = 1, + DST_KEY_KRRSIG = 2, + DST_KEY_DS = 3, + DST_KEY_GOAL = 4, + + DST_MAX_KEYSTATES = 5 /* MUST BE LAST */ +}; /* * Current format version number of the private key parser. @@ -905,7 +919,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_BOOLEAN + * "type" is smaller than DST_MAX_BOOLEAN * "valuep" is not null. */ @@ -916,7 +930,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_BOOLEAN + * "type" is smaller than DST_MAX_BOOLEAN */ void @@ -926,7 +940,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_BOOLEAN + * "type" is smaller than DST_MAX_BOOLEAN */ isc_result_t @@ -936,7 +950,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_NUMERIC + * "type" is smaller than DST_MAX_NUMERIC * "valuep" is not null. */ @@ -947,7 +961,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_NUMERIC + * "type" is smaller than DST_MAX_NUMERIC */ void @@ -957,7 +971,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_NUMERIC + * "type" is smaller than DST_MAX_NUMERIC */ isc_result_t @@ -967,7 +981,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_TIMES + * "type" is smaller than DST_MAX_TIMES * "timep" is not null. */ @@ -978,7 +992,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_TIMES + * "type" is smaller than DST_MAX_TIMES */ void @@ -988,7 +1002,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_TIMES + * "type" is smaller than DST_MAX_TIMES */ isc_result_t @@ -998,7 +1012,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_KEYSTATES + * "type" is smaller than DST_MAX_KEYSTATES * "statep" is not null. */ @@ -1010,7 +1024,7 @@ * Requires: * "key" is a valid key. * "state" is a valid state. - * "type" is no larger than DST_MAX_KEYSTATES + * "type" is smaller than DST_MAX_KEYSTATES */ void @@ -1020,7 +1034,7 @@ * * Requires: * "key" is a valid key. - * "type" is no larger than DST_MAX_KEYSTATES + * "type" is smaller than DST_MAX_KEYSTATES */ isc_result_t diff -Nru bind9-9.20.11/lib/dns/kasp.c bind9-9.20.15/lib/dns/kasp.c --- bind9-9.20.11/lib/dns/kasp.c 2025-07-04 09:42:08.385329351 +0000 +++ bind9-9.20.15/lib/dns/kasp.c 2025-10-18 10:16:12.618733161 +0000 @@ -282,6 +282,22 @@ kasp->inline_signing = value; } +bool +dns_kasp_manualmode(dns_kasp_t *kasp) { + REQUIRE(DNS_KASP_VALID(kasp)); + REQUIRE(kasp->frozen); + + return kasp->manual_mode; +} + +void +dns_kasp_setmanualmode(dns_kasp_t *kasp, bool value) { + REQUIRE(DNS_KASP_VALID(kasp)); + REQUIRE(!kasp->frozen); + + kasp->manual_mode = value; +} + dns_ttl_t dns_kasp_zonemaxttl(dns_kasp_t *kasp, bool fallback) { REQUIRE(DNS_KASP_VALID(kasp)); @@ -559,6 +575,21 @@ return true; } +void +dns_kasp_key_format(dns_kasp_key_t *key, char *cp, unsigned int size) { + REQUIRE(key != NULL); + REQUIRE(cp != NULL); + + char algstr[DNS_NAME_FORMATSIZE]; + bool csk = dns_kasp_key_ksk(key) && dns_kasp_key_zsk(key); + const char *rolestr = (csk ? "csk" + : (dns_kasp_key_ksk(key) ? "ksk" : "zsk")); + + dns_secalg_format((dns_secalg_t)key->algorithm, algstr, sizeof(algstr)); + snprintf(cp, size, "%s algorithm:%s length:%u tag-range:%u-%u", rolestr, + algstr, dns_kasp_key_size(key), key->tag_min, key->tag_max); +} + uint8_t dns_kasp_nsec3iter(dns_kasp_t *kasp) { REQUIRE(kasp != NULL); diff -Nru bind9-9.20.11/lib/dns/keymgr.c bind9-9.20.15/lib/dns/keymgr.c --- bind9-9.20.11/lib/dns/keymgr.c 2025-07-04 09:42:08.386329375 +0000 +++ bind9-9.20.15/lib/dns/keymgr.c 2025-10-18 10:16:12.619733177 +0000 @@ -77,14 +77,15 @@ #define NA DST_KEY_STATE_NA /* Quickly get key state timing metadata. */ -#define NUM_KEYSTATES (DST_MAX_KEYSTATES) -static int keystatetimes[NUM_KEYSTATES] = { DST_TIME_DNSKEY, DST_TIME_ZRRSIG, - DST_TIME_KRRSIG, DST_TIME_DS }; +static int keystatetimes[] = { DST_TIME_DNSKEY, DST_TIME_ZRRSIG, + DST_TIME_KRRSIG, DST_TIME_DS }; +#define NUM_KEYSTATES (int)ARRAY_SIZE(keystatetimes) + /* Readable key state types and values. */ static const char *keystatetags[NUM_KEYSTATES] = { "DNSKEY", "ZRRSIG", "KRRSIG", "DS" }; -static const char *keystatestrings[4] = { "HIDDEN", "RUMOURED", "OMNIPRESENT", - "UNRETENTIVE" }; +static const char *keystatestrings[] = { "HIDDEN", "RUMOURED", "OMNIPRESENT", + "UNRETENTIVE" }; static void log_key_overflow(dst_key_t *key, const char *what) { @@ -343,7 +344,8 @@ } static void -keymgr_key_retire(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now) { +keymgr_key_retire(dns_dnsseckey_t *key, dns_kasp_t *kasp, uint8_t opts, + isc_stdtime_t now) { char keystr[DST_KEY_FORMATSIZE]; isc_result_t ret; isc_stdtime_t retire; @@ -353,17 +355,40 @@ REQUIRE(key != NULL); REQUIRE(key->key != NULL); - /* This key wants to retire and hide in a corner. */ + dst_key_format(key->key, keystr, sizeof(keystr)); + + ret = dst_key_getstate(key->key, DST_KEY_GOAL, &s); + INSIST(ret == ISC_R_SUCCESS); + + if (dns_kasp_manualmode(kasp) && + (opts & DNS_KEYMGRATTR_FORCESTEP) == 0 && s != HIDDEN) + { + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "keymgr-manual-mode: block retire DNSKEY " + "%s (%s)", + keystr, keymgr_keyrole(key->key)); + return; + } else { + /* This key wants to retire and hide in a corner. */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "keymgr: retire DNSKEY %s (%s)", keystr, + keymgr_keyrole(key->key)); + + dst_key_setstate(key->key, DST_KEY_GOAL, HIDDEN); + } + + /* + * This key may not have key states set yet. Pretend as if they are + * in the OMNIPRESENT state. + */ ret = dst_key_gettime(key->key, DST_TIME_INACTIVE, &retire); if (ret != ISC_R_SUCCESS || (retire > now)) { dst_key_settime(key->key, DST_TIME_INACTIVE, now); } - dst_key_setstate(key->key, DST_KEY_GOAL, HIDDEN); keymgr_settime_remove(key, kasp); - /* This key may not have key states set yet. Pretend as if they are - * in the OMNIPRESENT state. - */ if (dst_key_getstate(key->key, DST_KEY_DNSKEY, &s) != ISC_R_SUCCESS) { dst_key_setstate(key->key, DST_KEY_DNSKEY, OMNIPRESENT); dst_key_settime(key->key, DST_TIME_DNSKEY, now); @@ -392,11 +417,6 @@ dst_key_settime(key->key, DST_TIME_ZRRSIG, now); } } - - dst_key_format(key->key, keystr, sizeof(keystr)); - isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, - ISC_LOG_INFO, "keymgr: retire DNSKEY %s (%s)", keystr, - keymgr_keyrole(key->key)); } /* Update lifetime and retire and remove time accordingly. */ @@ -980,7 +1000,7 @@ */ static bool keymgr_have_ds(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, int type, - dst_key_state_t next_state, bool secure_to_insecure) { + dst_key_state_t next_state, uint8_t opts) { /* (3a) */ dst_key_state_t states[2][NUM_KEYSTATES] = { /* DNSKEY, ZRRSIG, KRRSIG, DS */ @@ -998,7 +1018,7 @@ states[0], na, false, false) || keymgr_key_exists_with_state(keyring, key, type, next_state, states[1], na, false, false) || - (secure_to_insecure && + ((opts & DNS_KEYMGRATTR_S2I) != 0 && keymgr_key_exists_with_state(keyring, key, type, next_state, na, na, false, false)); } @@ -1237,17 +1257,14 @@ */ static bool keymgr_transition_allowed(dns_dnsseckeylist_t *keyring, dns_dnsseckey_t *key, - int type, dst_key_state_t next_state, - bool secure_to_insecure) { + int type, dst_key_state_t next_state, uint8_t opts) { /* Debug logging. */ if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { bool rule1a, rule1b, rule2a, rule2b, rule3a, rule3b; char keystr[DST_KEY_FORMATSIZE]; dst_key_format(key->key, keystr, sizeof(keystr)); - rule1a = keymgr_have_ds(keyring, key, type, NA, - secure_to_insecure); - rule1b = keymgr_have_ds(keyring, key, type, next_state, - secure_to_insecure); + rule1a = keymgr_have_ds(keyring, key, type, NA, opts); + rule1b = keymgr_have_ds(keyring, key, type, next_state, opts); rule2a = keymgr_have_dnskey(keyring, key, type, NA); rule2b = keymgr_have_dnskey(keyring, key, type, next_state); rule3a = keymgr_have_rrsig(keyring, key, type, NA); @@ -1272,9 +1289,8 @@ * invalid state. If the rule check passes, also check if * the next state is also still a valid situation. */ - (!keymgr_have_ds(keyring, key, type, NA, secure_to_insecure) || - keymgr_have_ds(keyring, key, type, next_state, - secure_to_insecure)) && + (!keymgr_have_ds(keyring, key, type, NA, opts) || + keymgr_have_ds(keyring, key, type, next_state, opts)) && /* * Rule 2: There must be a DNSKEY at all times. Again, first * check the current situation, then assess the next state. @@ -1299,9 +1315,9 @@ dst_key_state_t next_state, dns_kasp_t *kasp, isc_stdtime_t now, isc_stdtime_t *when) { isc_result_t ret; - isc_stdtime_t lastchange, dstime, nexttime = now; + isc_stdtime_t lastchange, dstime, sigtime, nexttime = now; dns_ttl_t ttlsig = dns_kasp_zonemaxttl(kasp, true); - uint32_t dsstate; + uint32_t dsstate, sigstate, signdelay = 0; /* * No need to wait if we move things into an uncertain state. @@ -1355,6 +1371,17 @@ switch (next_state) { case OMNIPRESENT: case HIDDEN: + /* Was there a full sign? */ + sigstate = (next_state == HIDDEN) ? DST_TIME_SIGDELETE + : DST_TIME_SIGPUBLISH; + ret = dst_key_gettime(key->key, sigstate, &sigtime); + if (ret == ISC_R_SUCCESS && sigtime <= now) { + signdelay = 0; + } else { + sigtime = lastchange; + signdelay = dns_kasp_signdelay(kasp); + } + /* * RFC 7583: The retire interval (Iret) is the amount * of time that must elapse after a DNSKEY or @@ -1372,7 +1399,7 @@ * * Dsgn + zone-propagation-delay + max-zone-ttl. */ - nexttime = lastchange + ttlsig + + nexttime = sigtime + ttlsig + dns_kasp_zonepropagationdelay(kasp); /* * Only add the sign delay Dsgn and retire-safety if @@ -1386,7 +1413,7 @@ DST_NUM_SUCCESSOR, &tag); } if (ret == ISC_R_SUCCESS) { - nexttime += dns_kasp_signdelay(kasp) + + nexttime += signdelay + dns_kasp_retiresafety(kasp); } break; @@ -1465,8 +1492,10 @@ */ static isc_result_t keymgr_update(dns_dnsseckeylist_t *keyring, dns_kasp_t *kasp, isc_stdtime_t now, - isc_stdtime_t *nexttime, bool secure_to_insecure) { + isc_stdtime_t *nexttime, uint8_t opts) { + isc_result_t result = DNS_R_UNCHANGED; bool changed; + bool force = ((opts & DNS_KEYMGRATTR_FORCESTEP) != 0); /* Repeat until nothing changed. */ transition: @@ -1553,8 +1582,7 @@ /* Is the transition DNSSEC safe? */ if (!keymgr_transition_allowed(keyring, dkey, i, - next_state, - secure_to_insecure)) + next_state, opts)) { /* No, this would make the zone bogus. */ isc_log_write( @@ -1591,6 +1619,29 @@ continue; } + /* + * Are we allowed to make the transition automatically? + */ + if (next_state != OMNIPRESENT && next_state != HIDDEN) { + if (dns_kasp_manualmode(kasp) && !force) { + isc_log_write( + dns_lctx, + DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, + ISC_LOG_INFO, + "keymgr-manual-mode: block " + "transition " + "%s %s type %s " + "state %s to state %s", + keymgr_keyrole(dkey->key), + keystr, keystatetags[i], + keystatestrings[state], + keystatestrings[next_state]); + continue; + } + } + + /* It is safe to make the transition. */ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), "keymgr: transition %s %s type %s " @@ -1599,7 +1650,6 @@ keystatetags[i], keystatestrings[state], keystatestrings[next_state]); - /* It is safe to make the transition. */ dst_key_setstate(dkey->key, i, next_state); dst_key_settime(dkey->key, keystatetimes[i], now); INSIST(dst_key_ismodified(dkey->key)); @@ -1609,22 +1659,18 @@ /* We changed something, continue processing. */ if (changed) { + result = ISC_R_SUCCESS; + /* No longer force for the next run */ + force = false; goto transition; } - return ISC_R_SUCCESS; + return result; } -/* - * See if this key needs to be initialized with properties. A key created - * and derived from a dnssec-policy will have the required metadata available, - * otherwise these may be missing and need to be initialized. The key states - * will be initialized according to existing timing metadata. - * - */ -static void -keymgr_key_init(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now, - bool csk) { +void +dns_keymgr_key_init(dns_dnsseckey_t *key, dns_kasp_t *kasp, isc_stdtime_t now, + bool csk) { bool ksk, zsk; isc_result_t ret; isc_stdtime_t active = 0, pub = 0, syncpub = 0, retire = 0, remove = 0; @@ -1735,9 +1781,10 @@ dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *newkeys, const dns_name_t *origin, dns_rdataclass_t rdclass, dns_kasp_t *kasp, const char *keydir, uint32_t lifetime, - bool rollover, isc_stdtime_t now, isc_stdtime_t *nexttime, + uint8_t opts, isc_stdtime_t now, isc_stdtime_t *nexttime, isc_mem_t *mctx) { char keystr[DST_KEY_FORMATSIZE]; + char namestr[DNS_NAME_FORMATSIZE]; isc_stdtime_t retire = 0, active = 0, prepub = 0; dns_dnsseckey_t *new_key = NULL; dns_dnsseckey_t *candidate = NULL; @@ -1814,7 +1861,7 @@ /* * If rollover is not allowed, warn. */ - if (!rollover) { + if ((opts & DNS_KEYMGRATTR_NOROLL) != 0) { dst_key_format(active_key->key, keystr, sizeof(keystr)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING, @@ -1825,7 +1872,6 @@ return ISC_R_SUCCESS; } } else if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(1))) { - char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(origin, namestr, sizeof(namestr)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1), @@ -1846,11 +1892,55 @@ dst_key_is_unused(candidate->key)) { /* Found a candidate in keyring. */ + new_key = candidate; break; } } - if (candidate == NULL) { + if (dns_kasp_manualmode(kasp) && (opts & DNS_KEYMGRATTR_FORCESTEP) == 0) + { + if (active_key != NULL && new_key != NULL) { + char keystr2[DST_KEY_FORMATSIZE]; + dst_key_format(active_key->key, keystr, sizeof(keystr)); + dst_key_format(new_key->key, keystr2, sizeof(keystr2)); + dns_name_format(origin, namestr, sizeof(namestr)); + isc_log_write( + dns_lctx, DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "keymgr-manual-mode: block %s rollover for key " + "%s to key %s (policy %s)", + keymgr_keyrole(active_key->key), keystr, + keystr2, dns_kasp_getname(kasp)); + } else if (active_key != NULL) { + dst_key_format(active_key->key, keystr, sizeof(keystr)); + dns_name_format(origin, namestr, sizeof(namestr)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "keymgr-manual-mode: block %s rollover " + "for key %s (policy %s)", + keymgr_keyrole(active_key->key), keystr, + dns_kasp_getname(kasp)); + } else if (new_key != NULL) { + dst_key_format(new_key->key, keystr, sizeof(keystr)); + dns_name_format(origin, namestr, sizeof(namestr)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "keymgr-manual-mode: block %s " + "introduction %s (policy %s)", + keymgr_keyrole(new_key->key), keystr, + dns_kasp_getname(kasp)); + } else { + dns_name_format(origin, namestr, sizeof(namestr)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, + DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO, + "keymgr-manual-mode: block new key " + "generation for zone %s (policy %s)", + namestr, dns_kasp_getname(kasp)); + } + return ISC_R_SUCCESS; + } + + if (new_key == NULL) { /* No key available in keyring, create a new one. */ bool csk = (dns_kasp_key_ksk(kaspkey) && dns_kasp_key_zsk(kaspkey)); @@ -1864,9 +1954,7 @@ dst_key_setttl(dst_key, dns_kasp_dnskeyttl(kasp)); dst_key_settime(dst_key, DST_TIME_CREATED, now); dns_dnsseckey_create(mctx, &dst_key, &new_key); - keymgr_key_init(new_key, kasp, now, csk); - } else { - new_key = candidate; + dns_keymgr_key_init(new_key, kasp, now, csk); } dst_key_setnum(new_key->key, DST_NUM_LIFETIME, lifetime); @@ -2054,6 +2142,34 @@ return matches > 1; } +static void +keymgr_zrrsig(dns_dnsseckeylist_t *keyring, isc_stdtime_t now) { + for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; + dkey = ISC_LIST_NEXT(dkey, link)) + { + isc_result_t ret; + bool zsk = false; + + ret = dst_key_getbool(dkey->key, DST_BOOL_ZSK, &zsk); + if (ret == ISC_R_SUCCESS && zsk) { + dst_key_state_t state; + isc_result_t result = dst_key_getstate( + dkey->key, DST_KEY_ZRRSIG, &state); + if (result == ISC_R_SUCCESS) { + if (state == RUMOURED) { + dst_key_settime(dkey->key, + DST_TIME_SIGPUBLISH, + now); + } else if (state == UNRETENTIVE) { + dst_key_settime(dkey->key, + DST_TIME_SIGDELETE, + now); + } + } + } + } +} + /* * Examine 'keys' and match 'kasp' policy. * @@ -2062,12 +2178,12 @@ dns_keymgr_run(const dns_name_t *origin, dns_rdataclass_t rdclass, isc_mem_t *mctx, dns_dnsseckeylist_t *keyring, dns_dnsseckeylist_t *dnskeys, const char *keydir, - dns_kasp_t *kasp, isc_stdtime_t now, isc_stdtime_t *nexttime) { - isc_result_t result = ISC_R_SUCCESS; + dns_kasp_t *kasp, uint8_t opts, isc_stdtime_t now, + isc_stdtime_t *nexttime) { + isc_result_t result = DNS_R_UNCHANGED; dns_dnsseckeylist_t newkeys; dns_kasp_key_t *kkey; dns_dnsseckey_t *newkey = NULL; - bool secure_to_insecure = false; int numkeys = 0; int options = (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC | DST_TYPE_STATE); char keystr[DST_KEY_FORMATSIZE]; @@ -2125,7 +2241,7 @@ { bool found_match = false; - keymgr_key_init(dkey, kasp, now, numkeys == 1); + dns_keymgr_key_init(dkey, kasp, now, numkeys == 1); for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; kkey = ISC_LIST_NEXT(kkey, link)) @@ -2138,7 +2254,7 @@ /* No match, so retire unwanted retire key. */ if (!found_match) { - keymgr_key_retire(dkey, kasp, now); + keymgr_key_retire(dkey, kasp, opts, now); } /* Check purge-keys interval. */ @@ -2166,7 +2282,6 @@ { uint32_t lifetime = dns_kasp_key_lifetime(kkey); dns_dnsseckey_t *active_key = NULL; - bool rollover_allowed = true; /* Do we have keys available for this kasp key? */ for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); @@ -2207,7 +2322,7 @@ * Retire excess keys in use. */ keymgr_key_retire(dkey, kasp, - now); + opts, now); } continue; } @@ -2249,7 +2364,7 @@ keystr, keymgr_keyrole(dnskey->key), dns_kasp_getname(kasp)); - rollover_allowed = false; + opts |= DNS_KEYMGRATTR_NOROLL; active_key = dnskey; break; } @@ -2257,10 +2372,11 @@ } /* See if this key requires a rollover. */ - RETERR(keymgr_key_rollover(kkey, active_key, keyring, &newkeys, - origin, rdclass, kasp, keydir, - lifetime, rollover_allowed, now, - nexttime, mctx)); + RETERR(keymgr_key_rollover( + kkey, active_key, keyring, &newkeys, origin, rdclass, + kasp, keydir, lifetime, opts, now, nexttime, mctx)); + + opts &= ~DNS_KEYMGRATTR_NOROLL; } /* Walked all kasp key configurations. Append new keys. */ @@ -2272,10 +2388,17 @@ * If the policy has an empty key list, this means the zone is going * back to unsigned. */ - secure_to_insecure = dns_kasp_keylist_empty(kasp); + if (dns_kasp_keylist_empty(kasp)) { + opts |= DNS_KEYMGRATTR_S2I; + } + + /* In case of a full sign, store ZRRSIGPublish/ZRRSIGDelete. */ + if ((opts & DNS_KEYMGRATTR_FULLSIGN) != 0) { + keymgr_zrrsig(keyring, now); + } /* Read to update key states. */ - keymgr_update(keyring, kasp, now, nexttime, secure_to_insecure); + isc_result_t retval = keymgr_update(keyring, kasp, now, nexttime, opts); /* Store key states and update hints. */ for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(*keyring); dkey != NULL; @@ -2285,6 +2408,7 @@ if (dst_key_getttl(dkey->key) != dns_kasp_dnskeyttl(kasp)) { dst_key_setttl(dkey->key, dns_kasp_dnskeyttl(kasp)); modified = true; + retval = ISC_R_SUCCESS; } if (modified && !dkey->purge) { const char *directory = dst_key_directory(dkey->key); @@ -2310,10 +2434,9 @@ dst_key_setmodified(dkey->key, false); } - result = ISC_R_SUCCESS; - + result = retval; failure: - if (result != ISC_R_SUCCESS) { + if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED) { while ((newkey = ISC_LIST_HEAD(newkeys)) != NULL) { ISC_LIST_UNLINK(newkeys, newkey, link); INSIST(newkey->key != NULL); @@ -2755,7 +2878,7 @@ continue; } - keymgr_key_init(dkey, kasp, now, false); + dns_keymgr_key_init(dkey, kasp, now, false); /* Get current metadata */ RETERR(dst_key_getstate(dkey->key, DST_KEY_DNSKEY, diff -Nru bind9-9.20.11/lib/dns/message.c bind9-9.20.15/lib/dns/message.c --- bind9-9.20.11/lib/dns/message.c 2025-07-04 09:42:08.387329398 +0000 +++ bind9-9.20.15/lib/dns/message.c 2025-10-18 10:16:12.620733192 +0000 @@ -463,6 +463,7 @@ m->cc_bad = 0; m->tkey = 0; m->rdclass_set = 0; + m->has_dname = 0; m->querytsig = NULL; m->indent.string = "\t"; m->indent.count = 0; @@ -472,7 +473,7 @@ msgresetname(dns_message_t *msg, dns_name_t *name) { dns_rdataset_t *rds = NULL, *next_rds = NULL; - ISC_LIST_FOREACH_SAFE (name->list, rds, link, next_rds) { + ISC_LIST_FOREACH_SAFE(name->list, rds, link, next_rds) { ISC_LIST_UNLINK(name->list, rds, link); dns__message_putassociatedrdataset(msg, &rds); @@ -485,8 +486,7 @@ for (size_t i = first_section; i < DNS_SECTION_MAX; i++) { dns_name_t *name = NULL, *next_name = NULL; - ISC_LIST_FOREACH_SAFE (msg->sections[i], name, link, next_name) - { + ISC_LIST_FOREACH_SAFE(msg->sections[i], name, link, next_name) { ISC_LIST_UNLINK(msg->sections[i], name, link); msgresetname(msg, name); @@ -814,7 +814,7 @@ dns_namelist_t *section) { dns_name_t *name = NULL; - ISC_LIST_FOREACH_REV (*section, name, link) { + ISC_LIST_FOREACH_REV(*section, name, link) { if (dns_name_equal(name, target)) { if (foundname != NULL) { *foundname = name; @@ -855,7 +855,7 @@ REQUIRE(name != NULL); REQUIRE(rdatasetp == NULL || *rdatasetp == NULL); - ISC_LIST_FOREACH_REV (name->list, rds, link) { + ISC_LIST_FOREACH_REV(name->list, rds, link) { if (rds->type == type && rds->covers == covers) { SET_IF_NOT_NULL(rdatasetp, rds); @@ -971,7 +971,7 @@ static void cleanup_name_hashmaps(dns_namelist_t *section) { dns_name_t *name = NULL; - ISC_LIST_FOREACH (*section, name, link) { + ISC_LIST_FOREACH(*section, name, link) { if (name->hashmap != NULL) { isc_hashmap_destroy(&name->hashmap); } @@ -1645,6 +1645,11 @@ */ msg->tsigname->attributes.nocompress = true; free_name = false; + } else if (rdtype == dns_rdatatype_dname && + sectionid == DNS_SECTION_ANSWER && + msg->opcode == dns_opcode_query) + { + msg->has_dname = 1; } rdataset = NULL; @@ -2415,9 +2420,9 @@ msg->cursors[i] = NULL; msg->counts[i] = 0; - ISC_LIST_FOREACH (msg->sections[i], name, link) { + ISC_LIST_FOREACH(msg->sections[i], name, link) { dns_rdataset_t *rds = NULL; - ISC_LIST_FOREACH (name->list, rds, link) { + ISC_LIST_FOREACH(name->list, rds, link) { rds->attributes &= ~DNS_RDATASETATTR_RENDERED; } } @@ -3417,7 +3422,7 @@ dns_message_currentname(msg, section, &name); dns_rdataset_t *rds = NULL; - ISC_LIST_FOREACH (name->list, rds, link) { + ISC_LIST_FOREACH(name->list, rds, link) { if (section == DNS_SECTION_ANSWER && rds->type == dns_rdatatype_soa) { @@ -5072,7 +5077,7 @@ dns_message_currentname(msg, DNS_SECTION_AUTHORITY, &name); dns_rdataset_t *rds = NULL; - ISC_LIST_FOREACH (name->list, rds, link) { + ISC_LIST_FOREACH(name->list, rds, link) { if ((rds->attributes & DNS_RDATASETATTR_RENDERED) == 0) { continue; @@ -5146,3 +5151,9 @@ isc_mempool_destroy(rdspoolp); isc_mempool_destroy(namepoolp); } + +bool +dns_message_hasdname(dns_message_t *msg) { + REQUIRE(DNS_MESSAGE_VALID(msg)); + return msg->has_dname; +} diff -Nru bind9-9.20.11/lib/dns/qp.c bind9-9.20.15/lib/dns/qp.c --- bind9-9.20.11/lib/dns/qp.c 2025-07-04 09:42:08.390329468 +0000 +++ bind9-9.20.15/lib/dns/qp.c 2025-10-18 10:16:12.623733239 +0000 @@ -49,7 +49,7 @@ #include "qp_p.h" #ifndef DNS_QP_LOG_STATS -#define DNS_QP_LOG_STATS 1 +#define DNS_QP_LOG_STATS 0 #endif #ifndef DNS_QP_TRACE #define DNS_QP_TRACE 0 @@ -96,6 +96,19 @@ #define TRACE(...) #endif +#if DNS_QPMULTI_TRACE +ISC_REFCOUNT_STATIC_TRACE_DECL(dns_qpmulti); +#define dns_qpmulti_ref(ptr) dns_qpmulti__ref(ptr, __func__, __FILE__, __LINE__) +#define dns_qpmulti_unref(ptr) \ + dns_qpmulti__unref(ptr, __func__, __FILE__, __LINE__) +#define dns_qpmulti_attach(ptr, ptrp) \ + dns_qpmulti__attach(ptr, ptrp, __func__, __FILE__, __LINE__) +#define dns_qpmulti_detach(ptrp) \ + dns_qpmulti__detach(ptrp, __func__, __FILE__, __LINE__) +#else +ISC_REFCOUNT_STATIC_DECL(dns_qpmulti); +#endif + /*********************************************************************** * * converting DNS names to trie keys @@ -427,7 +440,7 @@ #else -#define chunk_get_raw(qp) isc_mem_allocate(qp->mctx, QP_CHUNK_BYTES) +#define chunk_get_raw(qp, size) isc_mem_allocate(qp->mctx, size) #define chunk_free_raw(qp, ptr) isc_mem_free(qp->mctx, ptr) #define chunk_shrink_raw(qp, ptr, size) isc_mem_reallocate(qp->mctx, ptr, size) @@ -457,6 +470,22 @@ } /* + * Find the next power that is both bigger than size and prev_capacity, + * but still within the chunk min and max sizes. + */ +static dns_qpcell_t +next_capacity(uint32_t prev_capacity, uint32_t size) { + /* + * Unfortunately builtin_clz is undefined for 0. We work around this + * issue by flooring the request size at 2. + */ + size = ISC_MAX3(size, prev_capacity, 2u); + uint32_t log2 = 32u - __builtin_clz(size - 1u); + + return 1U << ISC_CLAMP(log2, QP_CHUNK_LOG_MIN, QP_CHUNK_LOG_MAX); +} + +/* * Create a fresh bump chunk and allocate some twigs from it. */ static dns_qpref_t @@ -464,9 +493,15 @@ INSIST(qp->base->ptr[chunk] == NULL); INSIST(qp->usage[chunk].used == 0); INSIST(qp->usage[chunk].free == 0); + INSIST(qp->chunk_capacity <= QP_CHUNK_SIZE); - qp->base->ptr[chunk] = chunk_get_raw(qp); - qp->usage[chunk] = (qp_usage_t){ .exists = true, .used = size }; + qp->chunk_capacity = next_capacity(qp->chunk_capacity * 2u, size); + qp->base->ptr[chunk] = + chunk_get_raw(qp, qp->chunk_capacity * sizeof(dns_qpnode_t)); + + qp->usage[chunk] = (qp_usage_t){ .exists = true, + .used = size, + .capacity = qp->chunk_capacity }; qp->used_count += size; qp->bump = chunk; qp->fender = 0; @@ -546,7 +581,7 @@ dns_qpchunk_t chunk = qp->bump; dns_qpcell_t cell = qp->usage[chunk].used; - if (cell + size <= QP_CHUNK_SIZE) { + if (cell + size <= qp->usage[chunk].capacity) { qp->usage[chunk].used += size; qp->used_count += size; return make_ref(chunk, cell); @@ -664,7 +699,7 @@ */ static void recycle(dns_qp_t *qp) { - unsigned int free = 0; + unsigned int nfree = 0; isc_nanosecs_t start = isc_time_monotonic(); @@ -673,15 +708,15 @@ qp->usage[chunk].exists && !qp->usage[chunk].immutable) { chunk_free(qp, chunk); - free++; + nfree++; } } isc_nanosecs_t time = isc_time_monotonic() - start; atomic_fetch_add_relaxed(&recycle_time, time); - if (free > 0) { - LOG_STATS("qp recycle" PRItime "free %u chunks", time, free); + if (nfree > 0) { + LOG_STATS("qp recycle" PRItime "free %u chunks", time, nfree); LOG_STATS("qp recycle leaf %u live %u used %u free %u hold %u", qp->leaf_count, qp->used_count - qp->free_count, qp->used_count, qp->free_count, qp->hold_count); @@ -699,38 +734,47 @@ REQUIRE(QPMULTI_VALID(multi)); LOCK(&multi->mutex); - dns_qp_t *qp = &multi->writer; - REQUIRE(QP_VALID(qp)); - unsigned int free = 0; - isc_nanosecs_t start = isc_time_monotonic(); - - for (unsigned int i = 0; i < rcuctx->count; i++) { - dns_qpchunk_t chunk = rcuctx->chunk[i]; - if (qp->usage[chunk].snapshot) { - /* cleanup when snapshot is destroyed */ - qp->usage[chunk].snapfree = true; - } else { - chunk_free(qp, chunk); - free++; + /* + * If chunk_max is zero, chunks have already been freed. + */ + if (qp->chunk_max != 0) { + unsigned int free = 0; + isc_nanosecs_t start = isc_time_monotonic(); + + INSIST(QP_VALID(qp)); + + for (unsigned int i = 0; i < rcuctx->count; i++) { + dns_qpchunk_t chunk = rcuctx->chunk[i]; + if (qp->usage[chunk].snapshot) { + /* clean up when snapshot is destroyed */ + qp->usage[chunk].snapfree = true; + } else { + chunk_free(qp, chunk); + free++; + } } - } - - isc_mem_putanddetach(&rcuctx->mctx, rcuctx, - STRUCT_FLEX_SIZE(rcuctx, chunk, rcuctx->count)); - isc_nanosecs_t time = isc_time_monotonic() - start; - recycle_time += time; + isc_nanosecs_t time = isc_time_monotonic() - start; + recycle_time += time; - if (free > 0) { - LOG_STATS("qp reclaim" PRItime "free %u chunks", time, free); - LOG_STATS("qp reclaim leaf %u live %u used %u free %u hold %u", - qp->leaf_count, qp->used_count - qp->free_count, - qp->used_count, qp->free_count, qp->hold_count); + if (free > 0) { + LOG_STATS("qp reclaim" PRItime "free %u chunks", time, + free); + LOG_STATS( + "qp reclaim leaf %u live %u used %u free %u " + "hold %u", + qp->leaf_count, qp->used_count - qp->free_count, + qp->used_count, qp->free_count, qp->hold_count); + } } UNLOCK(&multi->mutex); + + dns_qpmulti_detach(&multi); + isc_mem_putanddetach(&rcuctx->mctx, rcuctx, + STRUCT_FLEX_SIZE(rcuctx, chunk, rcuctx->count)); } /* @@ -775,6 +819,11 @@ } } + /* + * Reference the qpmulti object to keep it from being + * freed until reclaim_chunks_cb() runs. + */ + dns_qpmulti_ref(multi); call_rcu(&rcuctx->rcu_head, reclaim_chunks_cb); LOG_STATS("qp will reclaim %u chunks", count); @@ -786,7 +835,7 @@ */ static void marksweep_chunks(dns_qpmulti_t *multi) { - unsigned int free = 0; + unsigned int nfree = 0; isc_nanosecs_t start = isc_time_monotonic(); @@ -809,15 +858,15 @@ qpw->usage[chunk].snapmark = false; if (qpw->usage[chunk].snapfree && !qpw->usage[chunk].snapshot) { chunk_free(qpw, chunk); - free++; + nfree++; } } isc_nanosecs_t time = isc_time_monotonic() - start; recycle_time += time; - if (free > 0) { - LOG_STATS("qp marksweep" PRItime "free %u chunks", time, free); + if (nfree > 0) { + LOG_STATS("qp marksweep" PRItime "free %u chunks", time, nfree); LOG_STATS( "qp marksweep leaf %u live %u used %u free %u hold %u", qpw->leaf_count, qpw->used_count - qpw->free_count, @@ -1027,12 +1076,13 @@ .hold = qp->hold_count, .free = qp->free_count, .node_size = sizeof(dns_qpnode_t), - .chunk_size = QP_CHUNK_SIZE, .fragmented = QP_NEEDGC(qp), }; + size_t chunk_usage_bytes = 0; for (dns_qpchunk_t chunk = 0; chunk < qp->chunk_max; chunk++) { if (qp->base->ptr[chunk] != NULL) { + chunk_usage_bytes += qp->usage[chunk].capacity; memusage.chunk_count += 1; } } @@ -1041,7 +1091,7 @@ * XXXFANF does not subtract chunks that have been shrunk, * and does not count unreclaimed dns_qpbase_t objects */ - memusage.bytes = memusage.chunk_count * QP_CHUNK_BYTES + + memusage.bytes = chunk_usage_bytes + qp->chunk_max * sizeof(qp->base->ptr[0]) + qp->chunk_max * sizeof(qp->usage[0]); @@ -1058,8 +1108,8 @@ dns_qp_memusage_t memusage = dns_qp_memusage(qp); - if (qp->transaction_mode == QP_UPDATE) { - memusage.bytes -= QP_CHUNK_BYTES; + if (qp->transaction_mode == QP_UPDATE && qp->usage != NULL) { + memusage.bytes -= qp->usage[qp->bump].capacity; memusage.bytes += qp->usage[qp->bump].used * sizeof(dns_qpnode_t); } @@ -1254,7 +1304,10 @@ */ void dns_qpmulti_rollback(dns_qpmulti_t *multi, dns_qp_t **qptp) { - unsigned int free = 0; + /* + * nfree is only used when logging stats, hence the attribute. + */ + unsigned int nfree ISC_ATTR_UNUSED = 0; REQUIRE(QPMULTI_VALID(multi)); REQUIRE(multi->writer.transaction_mode == QP_UPDATE); @@ -1277,7 +1330,7 @@ INSIST(!multi->rollback->usage[chunk].exists); multi->rollback->base->ptr[chunk] = NULL; } - free++; + nfree++; } } @@ -1300,7 +1353,7 @@ isc_nanosecs_t time = isc_time_monotonic() - start; atomic_fetch_add_relaxed(&rollback_time, time); - LOG_STATS("qp rollback" PRItime "free %u chunks", time, free); + LOG_STATS("qp rollback" PRItime "free %u chunks", time, nfree); *qptp = NULL; UNLOCK(&multi->mutex); @@ -1444,12 +1497,12 @@ REQUIRE(qpmp != NULL && *qpmp == NULL); dns_qpmulti_t *multi = isc_mem_get(mctx, sizeof(*multi)); - *multi = (dns_qpmulti_t){ - .magic = QPMULTI_MAGIC, - .reader_ref = INVALID_REF, - }; + *multi = (dns_qpmulti_t){ .magic = QPMULTI_MAGIC, + .reader_ref = INVALID_REF, + .references = ISC_REFCOUNT_INITIALIZER(1) }; isc_mutex_init(&multi->mutex); ISC_LIST_INIT(multi->snapshots); + /* * Do not waste effort allocating a bump chunk that will be thrown * away when a transaction is opened. dns_qpmulti_update() always @@ -1469,11 +1522,13 @@ if (qp->chunk_max == 0) { return; } + for (dns_qpchunk_t chunk = 0; chunk < qp->chunk_max; chunk++) { if (qp->base->ptr[chunk] != NULL) { chunk_free(qp, chunk); } } + qp->chunk_max = 0; ENSURE(qp->used_count == 0); ENSURE(qp->free_count == 0); ENSURE(isc_refcount_current(&qp->base->refcount) == 1); @@ -1499,7 +1554,26 @@ } static void -qpmulti_destroy_cb(struct rcu_head *arg) { +qpmulti_free_mem(dns_qpmulti_t *multi) { + REQUIRE(QPMULTI_VALID(multi)); + + /* reassure thread sanitizer */ + LOCK(&multi->mutex); + dns_qp_t *qp = &multi->writer; + UNLOCK(&multi->mutex); + + isc_mutex_destroy(&multi->mutex); + isc_mem_putanddetach(&qp->mctx, multi, sizeof(*multi)); +} + +#if QPMULTI_TRACE +ISC_REFCOUNT_STATIC_TRACE_IMPL(dns_qpmulti, qpmulti_free_mem) +#else +ISC_REFCOUNT_STATIC_IMPL(dns_qpmulti, qpmulti_free_mem) +#endif + +static void +qpmulti_destroy_guts_cb(struct rcu_head *arg) { qp_rcuctx_t *rcuctx = caa_container_of(arg, qp_rcuctx_t, rcu_head); REQUIRE(QPRCU_VALID(rcuctx)); /* only nonzero for reclaim_chunks_cb() */ @@ -1518,10 +1592,9 @@ UNLOCK(&multi->mutex); - isc_mutex_destroy(&multi->mutex); + dns_qpmulti_detach(&multi); isc_mem_putanddetach(&rcuctx->mctx, rcuctx, STRUCT_FLEX_SIZE(rcuctx, chunk, rcuctx->count)); - isc_mem_putanddetach(&qp->mctx, multi, sizeof(*multi)); } void @@ -1547,7 +1620,7 @@ .multi = multi, }; isc_mem_attach(qp->mctx, &rcuctx->mctx); - call_rcu(&rcuctx->rcu_head, qpmulti_destroy_cb); + call_rcu(&rcuctx->rcu_head, qpmulti_destroy_guts_cb); } /*********************************************************************** diff -Nru bind9-9.20.11/lib/dns/qp_p.h bind9-9.20.15/lib/dns/qp_p.h --- bind9-9.20.11/lib/dns/qp_p.h 2025-07-04 09:42:08.390329468 +0000 +++ bind9-9.20.15/lib/dns/qp_p.h 2025-10-18 10:16:12.623733239 +0000 @@ -19,6 +19,10 @@ #pragma once +#include + +#include + /*********************************************************************** * * interior node basics @@ -139,22 +143,29 @@ * size to make the allocator work harder. */ #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -#define QP_CHUNK_LOG 7 +#define QP_CHUNK_LOG_MIN 7 +#define QP_CHUNK_LOG_MAX 7 #else -#define QP_CHUNK_LOG 10 +#define QP_CHUNK_LOG_MIN 3 +#define QP_CHUNK_LOG_MAX 12 #endif -STATIC_ASSERT(6 <= QP_CHUNK_LOG && QP_CHUNK_LOG <= 20, - "qp-trie chunk size is unreasonable"); +STATIC_ASSERT(2 <= QP_CHUNK_LOG_MIN && QP_CHUNK_LOG_MIN <= QP_CHUNK_LOG_MAX, + "qp-trie min chunk size is unreasonable"); +STATIC_ASSERT(6 <= QP_CHUNK_LOG_MAX && QP_CHUNK_LOG_MAX <= 20, + "qp-trie max chunk size is unreasonable"); -#define QP_CHUNK_SIZE (1U << QP_CHUNK_LOG) +#define QP_CHUNK_SIZE (1U << QP_CHUNK_LOG_MAX) #define QP_CHUNK_BYTES (QP_CHUNK_SIZE * sizeof(dns_qpnode_t)) +STATIC_ASSERT(QP_SAFETY_MARGIN >= QP_CHUNK_BYTES, + "qp-trie safety margin too small"); + /* * We need a bitfield this big to count how much of a chunk is in use: - * it needs to count from 0 up to and including `1 << QP_CHUNK_LOG`. + * it needs to count from 0 up to and including `1 << QP_CHUNK_LOG_MAX`. */ -#define QP_USAGE_BITS (QP_CHUNK_LOG + 1) +#define QP_USAGE_BITS (QP_CHUNK_LOG_MAX + 1) /* * A chunk needs to be compacted if it is less full than this threshold. @@ -266,6 +277,8 @@ typedef struct qp_usage { /*% the allocation point, increases monotonically */ dns_qpcell_t used : QP_USAGE_BITS; + /*% the actual size of the allocation */ + dns_qpcell_t capacity : QP_USAGE_BITS; /*% count of nodes no longer needed, also monotonic */ dns_qpcell_t free : QP_USAGE_BITS; /*% qp->base->ptr[chunk] != NULL */ @@ -320,6 +333,7 @@ struct rcu_head rcu_head; isc_mem_t *mctx; dns_qpmulti_t *multi; + ISC_LINK(struct qp_rcuctx) link; dns_qpchunk_t count; dns_qpchunk_t chunk[]; } qp_rcuctx_t; @@ -477,6 +491,8 @@ dns_qpcell_t used_count, free_count; /*% free cells that cannot be recovered right now */ dns_qpcell_t hold_count; + /*% capacity of last allocated chunk, for exponential chunk growth */ + dns_qpcell_t chunk_capacity; /*% what kind of transaction was most recently started [MT] */ enum { QP_NONE, QP_WRITE, QP_UPDATE } transaction_mode : 2; /*% compact the entire trie [MT] */ @@ -521,6 +537,8 @@ dns_qp_t *rollback; /*% all snapshots of this trie */ ISC_LIST(dns_qpsnap_t) snapshots; + /*% refcount for memory reclamation */ + isc_refcount_t references; }; /*********************************************************************** diff -Nru bind9-9.20.11/lib/dns/qpcache.c bind9-9.20.15/lib/dns/qpcache.c --- bind9-9.20.11/lib/dns/qpcache.c 2025-07-04 09:42:08.391329492 +0000 +++ bind9-9.20.15/lib/dns/qpcache.c 2025-10-18 10:16:12.624733255 +0000 @@ -1517,7 +1517,13 @@ */ result = dns_qp_lookup(search->qpdb->nsec, name, NULL, &iter, NULL, (void **)&node, NULL); - if (result != DNS_R_PARTIALMATCH) { + /* + * When DNS_R_PARTIALMATCH or ISC_R_NOTFOUND is returned from + * dns_qp_lookup there is potentially a covering NSEC present + * in the cache so we need to search for it. Otherwise we are + * done here. + */ + if (result != DNS_R_PARTIALMATCH && result != ISC_R_NOTFOUND) { return ISC_R_NOTFOUND; } @@ -2454,7 +2460,7 @@ */ purgesize = 2 * (sizeof(qpcnode_t) + dns_name_size(&HEADERNODE(newheader)->name)) + - rdataset_size(newheader) + 12288; + rdataset_size(newheader) + QP_SAFETY_MARGIN; again: do { isc_rwlocktype_t nlocktype = isc_rwlocktype_none; @@ -2987,39 +2993,43 @@ */ if (trust < header->trust && (ACTIVE(header, now) || header_nx)) { - dns_slabheader_destroy(&newheader); - if (addedrdataset != NULL) { - bindrdataset(qpdb, qpnode, header, now, - nlocktype, tlocktype, - addedrdataset DNS__DB_FLARG_PASS); + isc_result_t result = DNS_R_UNCHANGED; + bindrdataset(qpdb, qpnode, header, now, nlocktype, + tlocktype, + addedrdataset DNS__DB_FLARG_PASS); + if (ACTIVE(header, now) && + (options & DNS_DBADD_EQUALOK) != 0 && + dns_rdataslab_equalx( + (unsigned char *)header, + (unsigned char *)newheader, + (unsigned int)(sizeof(*newheader)), + qpdb->common.rdclass, + (dns_rdatatype_t)header->type)) + { + result = ISC_R_SUCCESS; } - return DNS_R_UNCHANGED; + dns_slabheader_destroy(&newheader); + return result; } /* - * Don't replace existing NS, A and AAAA RRsets in the - * cache if they are already exist. This prevents named - * being locked to old servers. Don't lower trust of - * existing record if the update is forced. Nothing - * special to be done w.r.t stale data; it gets replaced - * normally further down. + * Don't replace existing NS in the cache if they already exist + * and replacing the existing one would increase the TTL. This + * prevents named being locked to old servers. Don't lower trust + * of existing record if the update is forced. Nothing special + * to be done w.r.t stale data; it gets replaced normally + * further down. */ if (ACTIVE(header, now) && header->type == dns_rdatatype_ns && !header_nx && !newheader_nx && header->trust >= newheader->trust && + header->ttl < newheader->ttl && dns_rdataslab_equalx((unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)), qpdb->common.rdclass, (dns_rdatatype_t)header->type)) { - /* - * Honour the new ttl if it is less than the - * older one. - */ - if (header->ttl > newheader->ttl) { - setttl(header, newheader->ttl); - } if (header->last_used != now) { ISC_LIST_UNLINK( qpdb->buckets[HEADERNODE(header)->locknum] @@ -3053,7 +3063,7 @@ } /* - * If we have will be replacing a NS RRset force its TTL + * If we will be replacing a NS RRset force its TTL * to be no more than the current NS RRset's TTL. This * ensures the delegations that are withdrawn are honoured. */ @@ -3062,6 +3072,11 @@ header->trust <= newheader->trust) { if (newheader->ttl > header->ttl) { + if (ZEROTTL(header)) { + DNS_SLABHEADER_SETATTR( + newheader, + DNS_SLABHEADERATTR_ZEROTTL); + } newheader->ttl = header->ttl; } } @@ -3073,17 +3088,11 @@ header->type == DNS_SIGTYPE(dns_rdatatype_ds)) && !header_nx && !newheader_nx && header->trust >= newheader->trust && + header->ttl < newheader->ttl && dns_rdataslab_equal((unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)))) { - /* - * Honour the new ttl if it is less than the - * older one. - */ - if (header->ttl > newheader->ttl) { - setttl(header, newheader->ttl); - } if (header->last_used != now) { ISC_LIST_UNLINK( qpdb->buckets[HEADERNODE(header)->locknum] diff -Nru bind9-9.20.11/lib/dns/rbtdb.c bind9-9.20.15/lib/dns/rbtdb.c --- bind9-9.20.11/lib/dns/rbtdb.c 2025-07-04 09:42:08.393329539 +0000 +++ bind9-9.20.15/lib/dns/rbtdb.c 2025-10-18 10:16:12.626733286 +0000 @@ -2729,14 +2729,24 @@ if (rbtversion == NULL && trust < header->trust && (ACTIVE(header, now) || header_nx)) { - dns_slabheader_destroy(&newheader); - if (addedrdataset != NULL) { - dns__rbtdb_bindrdataset( - rbtdb, rbtnode, header, now, - isc_rwlocktype_write, - addedrdataset DNS__DB_FLARG_PASS); + result = DNS_R_UNCHANGED; + dns__rbtdb_bindrdataset( + rbtdb, rbtnode, header, now, + isc_rwlocktype_write, + addedrdataset DNS__DB_FLARG_PASS); + if (ACTIVE(header, now) && + (options & DNS_DBADD_EQUALOK) != 0 && + dns_rdataslab_equalx( + (unsigned char *)header, + (unsigned char *)newheader, + (unsigned int)(sizeof(*newheader)), + rbtdb->common.rdclass, + (dns_rdatatype_t)header->type)) + { + result = ISC_R_SUCCESS; } - return DNS_R_UNCHANGED; + dns_slabheader_destroy(&newheader); + return result; } /* @@ -2815,29 +2825,23 @@ } } /* - * Don't replace existing NS, A and AAAA RRsets in the - * cache if they are already exist. This prevents named - * being locked to old servers. Don't lower trust of - * existing record if the update is forced. Nothing - * special to be done w.r.t stale data; it gets replaced - * normally further down. + * Don't replace existing NS in the cache if they already exist + * and replacing the existing one would increase the TTL. This + * prevents named being locked to old servers. Don't lower trust + * of existing record if the update is forced. Nothing special + * to be done w.r.t stale data; it gets replaced normally + * further down. */ if (IS_CACHE(rbtdb) && ACTIVE(header, now) && header->type == dns_rdatatype_ns && !header_nx && !newheader_nx && header->trust >= newheader->trust && + header->ttl < newheader->ttl && dns_rdataslab_equalx((unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)), rbtdb->common.rdclass, (dns_rdatatype_t)header->type)) { - /* - * Honour the new ttl if it is less than the - * older one. - */ - if (header->ttl > newheader->ttl) { - dns__rbtdb_setttl(header, newheader->ttl); - } if (header->last_used != now) { ISC_LIST_UNLINK( rbtdb->lru[RBTDB_HEADERNODE(header) @@ -2872,7 +2876,7 @@ } /* - * If we have will be replacing a NS RRset force its TTL + * If we will be replacing a NS RRset force its TTL * to be no more than the current NS RRset's TTL. This * ensures the delegations that are withdrawn are honoured. */ @@ -2881,6 +2885,11 @@ !newheader_nx && header->trust <= newheader->trust) { if (newheader->ttl > header->ttl) { + if (ZEROTTL(header)) { + DNS_SLABHEADER_SETATTR( + newheader, + DNS_SLABHEADERATTR_ZEROTTL); + } newheader->ttl = header->ttl; } } @@ -2892,17 +2901,11 @@ header->type == DNS_SIGTYPE(dns_rdatatype_ds)) && !header_nx && !newheader_nx && header->trust >= newheader->trust && + header->ttl < newheader->ttl && dns_rdataslab_equal((unsigned char *)header, (unsigned char *)newheader, (unsigned int)(sizeof(*newheader)))) { - /* - * Honour the new ttl if it is less than the - * older one. - */ - if (header->ttl > newheader->ttl) { - dns__rbtdb_setttl(header, newheader->ttl); - } if (header->last_used != now) { ISC_LIST_UNLINK( rbtdb->lru[RBTDB_HEADERNODE(header) diff -Nru bind9-9.20.11/lib/dns/rcode.c bind9-9.20.15/lib/dns/rcode.c --- bind9-9.20.11/lib/dns/rcode.c 2025-07-04 09:42:08.393329539 +0000 +++ bind9-9.20.15/lib/dns/rcode.c 2025-10-18 10:16:12.626733286 +0000 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -47,6 +48,10 @@ #define TOTEXTONLY 0x01 +/* clang-format off */ +#define SENTINEL { 0, NULL, 0 } +/* clang-format on */ + #define RCODENAMES \ /* standard rcodes */ \ { dns_rcode_noerror, "NOERROR", 0 }, \ @@ -130,6 +135,8 @@ { DNS_DSDIGEST_SHA384, "SHA-384", 0 }, \ { DNS_DSDIGEST_SHA384, "SHA384", 0 }, { 0, NULL, 0 } +#define DSYNCSCHEMES { DNS_DSYNCSCHEME_NOTIFY, "NOTIFY", 0 }, SENTINEL + struct tbl { unsigned int value; const char *name; @@ -143,6 +150,7 @@ static struct tbl secprotos[] = { SECPROTONAMES }; static struct tbl hashalgs[] = { HASHALGNAMES }; static struct tbl dsdigests[] = { DSDIGESTNAMES }; +static struct tbl dsyncschemes[] = { DSYNCSCHEMES }; static struct keyflag { const char *name; @@ -446,6 +454,41 @@ isc_buffer_usedregion(&b, &r); r.base[r.length] = 0; if (result != ISC_R_SUCCESS) { + r.base[0] = 0; + } +} + +/* + * DSYNC Scheme + */ + +isc_result_t +dns_dsyncscheme_fromtext(dns_dsyncscheme_t *schemep, isc_textregion_t *source) { + unsigned int value; + + REQUIRE(schemep != NULL); + RETERR(dns_mnemonic_fromtext(&value, source, dsyncschemes, 0xff)); + *schemep = value; + return ISC_R_SUCCESS; +} + +isc_result_t +dns_dsyncscheme_totext(dns_dsyncscheme_t scheme, isc_buffer_t *target) { + return dns_mnemonic_totext(scheme, target, dsyncschemes); +} + +void +dns_dsyncscheme_format(dns_dsyncscheme_t scheme, char *cp, unsigned int size) { + isc_buffer_t b; + isc_region_t r; + isc_result_t result; + + REQUIRE(cp != NULL && size > 0); + isc_buffer_init(&b, cp, size - 1); + result = dns_dsyncscheme_totext(scheme, &b); + isc_buffer_usedregion(&b, &r); + r.base[r.length] = 0; + if (result != ISC_R_SUCCESS) { r.base[0] = 0; } } diff -Nru bind9-9.20.11/lib/dns/rdata/any_255/tsig_250.c bind9-9.20.15/lib/dns/rdata/any_255/tsig_250.c --- bind9-9.20.11/lib/dns/rdata/any_255/tsig_250.c 2025-07-04 09:42:08.394329562 +0000 +++ bind9-9.20.15/lib/dns/rdata/any_255/tsig_250.c 2025-10-18 10:16:12.626733286 +0000 @@ -454,9 +454,7 @@ REQUIRE(rdata->length != 0); tsig = (dns_rdata_any_tsig_t *)target; - tsig->common.rdclass = rdata->rdclass; - tsig->common.rdtype = rdata->type; - ISC_LINK_INIT(&tsig->common, link); + DNS_RDATACOMMON_INIT(tsig, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/ch_3/a_1.c bind9-9.20.15/lib/dns/rdata/ch_3/a_1.c --- bind9-9.20.11/lib/dns/rdata/ch_3/a_1.c 2025-07-04 09:42:08.394329562 +0000 +++ bind9-9.20.15/lib/dns/rdata/ch_3/a_1.c 2025-10-18 10:16:12.627733301 +0000 @@ -226,9 +226,7 @@ REQUIRE(rdata->rdclass == dns_rdataclass_ch); REQUIRE(rdata->length != 0); - a->common.rdclass = rdata->rdclass; - a->common.rdtype = rdata->type; - ISC_LINK_INIT(&a->common, link); + DNS_RDATACOMMON_INIT(a, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/afsdb_18.c bind9-9.20.15/lib/dns/rdata/generic/afsdb_18.c --- bind9-9.20.11/lib/dns/rdata/generic/afsdb_18.c 2025-07-04 09:42:08.394329562 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/afsdb_18.c 2025-10-18 10:16:12.627733301 +0000 @@ -207,9 +207,7 @@ REQUIRE(afsdb != NULL); REQUIRE(rdata->length != 0); - afsdb->common.rdclass = rdata->rdclass; - afsdb->common.rdtype = rdata->type; - ISC_LINK_INIT(&afsdb->common, link); + DNS_RDATACOMMON_INIT(afsdb, rdata->type, rdata->rdclass); dns_name_init(&afsdb->server, NULL); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/amtrelay_260.c bind9-9.20.15/lib/dns/rdata/generic/amtrelay_260.c --- bind9-9.20.11/lib/dns/rdata/generic/amtrelay_260.c 2025-07-04 09:42:08.394329562 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/amtrelay_260.c 2025-10-18 10:16:12.627733301 +0000 @@ -314,9 +314,7 @@ REQUIRE(amtrelay != NULL); REQUIRE(rdata->length >= 2); - amtrelay->common.rdclass = rdata->rdclass; - amtrelay->common.rdtype = rdata->type; - ISC_LINK_INIT(&amtrelay->common, link); + DNS_RDATACOMMON_INIT(amtrelay, rdata->type, rdata->rdclass); dns_name_init(&amtrelay->gateway, NULL); amtrelay->data = NULL; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/avc_258.c bind9-9.20.15/lib/dns/rdata/generic/avc_258.c --- bind9-9.20.11/lib/dns/rdata/generic/avc_258.c 2025-07-04 09:42:08.395329585 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/avc_258.c 2025-10-18 10:16:12.627733301 +0000 @@ -75,9 +75,7 @@ REQUIRE(rdata->type == dns_rdatatype_avc); REQUIRE(avc != NULL); - avc->common.rdclass = rdata->rdclass; - avc->common.rdtype = rdata->type; - ISC_LINK_INIT(&avc->common, link); + DNS_RDATACOMMON_INIT(avc, rdata->type, rdata->rdclass); return generic_tostruct_txt(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/brid_68.c bind9-9.20.15/lib/dns/rdata/generic/brid_68.c --- bind9-9.20.11/lib/dns/rdata/generic/brid_68.c 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/brid_68.c 2025-10-18 10:16:12.628733317 +0000 @@ -0,0 +1,213 @@ +/* + * 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. + */ + +#ifndef RDATA_GENERIC_BRID_68_C +#define RDATA_GENERIC_BRID_68_C + +#include + +#define RRTYPE_BRID_ATTRIBUTES (0) + +static isc_result_t +fromtext_brid(ARGS_FROMTEXT) { + REQUIRE(type == dns_rdatatype_brid); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + return isc_base64_tobuffer(lexer, target, -1); +} + +static isc_result_t +totext_brid(ARGS_TOTEXT) { + isc_region_t sr; + + REQUIRE(rdata->type == dns_rdatatype_brid); + REQUIRE(rdata->length > 0); + + dns_rdata_toregion(rdata, &sr); + + /* data */ + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { + RETERR(str_totext(" (", target)); + } + + RETERR(str_totext(tctx->linebreak, target)); + + if (tctx->width == 0) { /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + } else { + RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, + target)); + } + + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { + RETERR(str_totext(" )", target)); + } + + return ISC_R_SUCCESS; +} + +static isc_result_t +fromwire_brid(ARGS_FROMWIRE) { + isc_region_t sr; + + REQUIRE(type == dns_rdatatype_brid); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(dctx); + + isc_buffer_activeregion(source, &sr); + if (sr.length == 0) { + return ISC_R_UNEXPECTEDEND; + } + + RETERR(mem_tobuffer(target, sr.base, sr.length)); + isc_buffer_forward(source, sr.length); + return ISC_R_SUCCESS; +} + +static isc_result_t +towire_brid(ARGS_TOWIRE) { + REQUIRE(rdata->type == dns_rdatatype_brid); + REQUIRE(rdata->length >= 3); + + UNUSED(cctx); + + return mem_tobuffer(target, rdata->data, rdata->length); +} + +static int +compare_brid(ARGS_COMPARE) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == dns_rdatatype_brid); + REQUIRE(rdata1->length > 0); + REQUIRE(rdata2->length > 0); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return isc_region_compare(&r1, &r2); +} + +static isc_result_t +fromstruct_brid(ARGS_FROMSTRUCT) { + dns_rdata_brid_t *brid = source; + + REQUIRE(type == dns_rdatatype_brid); + REQUIRE(brid != NULL); + REQUIRE(brid->common.rdtype == type); + REQUIRE(brid->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + /* Data */ + return mem_tobuffer(target, brid->data, brid->datalen); +} + +static isc_result_t +tostruct_brid(ARGS_TOSTRUCT) { + dns_rdata_brid_t *brid = target; + isc_region_t sr; + + REQUIRE(rdata->type == dns_rdatatype_brid); + REQUIRE(brid != NULL); + REQUIRE(rdata->length > 0); + + DNS_RDATACOMMON_INIT(brid, rdata->type, rdata->rdclass); + + dns_rdata_toregion(rdata, &sr); + + /* Data */ + brid->datalen = sr.length; + brid->data = mem_maybedup(mctx, sr.base, brid->datalen); + brid->mctx = mctx; + return ISC_R_SUCCESS; +} + +static void +freestruct_brid(ARGS_FREESTRUCT) { + dns_rdata_brid_t *brid = (dns_rdata_brid_t *)source; + + REQUIRE(brid != NULL); + REQUIRE(brid->common.rdtype == dns_rdatatype_brid); + + if (brid->mctx == NULL) { + return; + } + + if (brid->data != NULL) { + isc_mem_free(brid->mctx, brid->data); + } + brid->mctx = NULL; +} + +static isc_result_t +additionaldata_brid(ARGS_ADDLDATA) { + REQUIRE(rdata->type == dns_rdatatype_brid); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(add); + UNUSED(arg); + + return ISC_R_SUCCESS; +} + +static isc_result_t +digest_brid(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == dns_rdatatype_brid); + + dns_rdata_toregion(rdata, &r); + + return (digest)(arg, &r); +} + +static bool +checkowner_brid(ARGS_CHECKOWNER) { + REQUIRE(type == dns_rdatatype_brid); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return true; +} + +static bool +checknames_brid(ARGS_CHECKNAMES) { + REQUIRE(rdata->type == dns_rdatatype_brid); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return true; +} + +static int +casecompare_brid(ARGS_COMPARE) { + return compare_brid(rdata1, rdata2); +} +#endif /* RDATA_GENERIC_BRID_68_C */ diff -Nru bind9-9.20.11/lib/dns/rdata/generic/brid_68.h bind9-9.20.15/lib/dns/rdata/generic/brid_68.h --- bind9-9.20.11/lib/dns/rdata/generic/brid_68.h 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/brid_68.h 2025-10-18 10:16:12.628733317 +0000 @@ -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. + */ + +#pragma once + +typedef struct dns_rdata_brid_t { + dns_rdatacommon_t common; + isc_mem_t *mctx; + uint16_t datalen; + unsigned char *data; +} dns_rdata_brid_t; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/caa_257.c bind9-9.20.15/lib/dns/rdata/generic/caa_257.c --- bind9-9.20.11/lib/dns/rdata/generic/caa_257.c 2025-07-04 09:42:08.395329585 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/caa_257.c 2025-10-18 10:16:12.628733317 +0000 @@ -498,9 +498,7 @@ REQUIRE(rdata->length >= 3U); REQUIRE(rdata->data != NULL); - caa->common.rdclass = rdata->rdclass; - caa->common.rdtype = rdata->type; - ISC_LINK_INIT(&caa->common, link); + DNS_RDATACOMMON_INIT(caa, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/cdnskey_60.c bind9-9.20.15/lib/dns/rdata/generic/cdnskey_60.c --- bind9-9.20.11/lib/dns/rdata/generic/cdnskey_60.c 2025-07-04 09:42:08.395329585 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/cdnskey_60.c 2025-10-18 10:16:12.628733317 +0000 @@ -88,9 +88,7 @@ REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_cdnskey); - dnskey->common.rdclass = rdata->rdclass; - dnskey->common.rdtype = rdata->type; - ISC_LINK_INIT(&dnskey->common, link); + DNS_RDATACOMMON_INIT(dnskey, rdata->type, rdata->rdclass); return generic_tostruct_key(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/cds_59.c bind9-9.20.15/lib/dns/rdata/generic/cds_59.c --- bind9-9.20.11/lib/dns/rdata/generic/cds_59.c 2025-07-04 09:42:08.395329585 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/cds_59.c 2025-10-18 10:16:12.628733317 +0000 @@ -89,9 +89,7 @@ /* * Checked by generic_tostruct_ds(). */ - cds->common.rdclass = rdata->rdclass; - cds->common.rdtype = rdata->type; - ISC_LINK_INIT(&cds->common, link); + DNS_RDATACOMMON_INIT(cds, rdata->type, rdata->rdclass); return generic_tostruct_ds(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/cert_37.c bind9-9.20.15/lib/dns/rdata/generic/cert_37.c --- bind9-9.20.11/lib/dns/rdata/generic/cert_37.c 2025-07-04 09:42:08.395329585 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/cert_37.c 2025-10-18 10:16:12.628733317 +0000 @@ -191,9 +191,7 @@ REQUIRE(cert != NULL); REQUIRE(rdata->length != 0); - cert->common.rdclass = rdata->rdclass; - cert->common.rdtype = rdata->type; - ISC_LINK_INIT(&cert->common, link); + DNS_RDATACOMMON_INIT(cert, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/cname_5.c bind9-9.20.15/lib/dns/rdata/generic/cname_5.c --- bind9-9.20.11/lib/dns/rdata/generic/cname_5.c 2025-07-04 09:42:08.396329609 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/cname_5.c 2025-10-18 10:16:12.628733317 +0000 @@ -147,9 +147,7 @@ REQUIRE(cname != NULL); REQUIRE(rdata->length != 0); - cname->common.rdclass = rdata->rdclass; - cname->common.rdtype = rdata->type; - ISC_LINK_INIT(&cname->common, link); + DNS_RDATACOMMON_INIT(cname, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/csync_62.c bind9-9.20.15/lib/dns/rdata/generic/csync_62.c --- bind9-9.20.11/lib/dns/rdata/generic/csync_62.c 2025-07-04 09:42:08.396329609 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/csync_62.c 2025-10-18 10:16:12.629733333 +0000 @@ -168,9 +168,7 @@ REQUIRE(csync != NULL); REQUIRE(rdata->length != 0); - csync->common.rdclass = rdata->rdclass; - csync->common.rdtype = rdata->type; - ISC_LINK_INIT(&csync->common, link); + DNS_RDATACOMMON_INIT(csync, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/dlv_32769.c bind9-9.20.15/lib/dns/rdata/generic/dlv_32769.c --- bind9-9.20.11/lib/dns/rdata/generic/dlv_32769.c 2025-07-04 09:42:08.396329609 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/dlv_32769.c 2025-10-18 10:16:12.629733333 +0000 @@ -85,9 +85,7 @@ REQUIRE(rdata->type == dns_rdatatype_dlv); REQUIRE(dlv != NULL); - dlv->common.rdclass = rdata->rdclass; - dlv->common.rdtype = rdata->type; - ISC_LINK_INIT(&dlv->common, link); + DNS_RDATACOMMON_INIT(dlv, rdata->type, rdata->rdclass); return generic_tostruct_ds(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/dname_39.c bind9-9.20.15/lib/dns/rdata/generic/dname_39.c --- bind9-9.20.11/lib/dns/rdata/generic/dname_39.c 2025-07-04 09:42:08.396329609 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/dname_39.c 2025-10-18 10:16:12.629733333 +0000 @@ -147,9 +147,7 @@ REQUIRE(dname != NULL); REQUIRE(rdata->length != 0); - dname->common.rdclass = rdata->rdclass; - dname->common.rdtype = rdata->type; - ISC_LINK_INIT(&dname->common, link); + DNS_RDATACOMMON_INIT(dname, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/dnskey_48.c bind9-9.20.15/lib/dns/rdata/generic/dnskey_48.c --- bind9-9.20.11/lib/dns/rdata/generic/dnskey_48.c 2025-07-04 09:42:08.396329609 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/dnskey_48.c 2025-10-18 10:16:12.629733333 +0000 @@ -89,9 +89,7 @@ REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_dnskey); - dnskey->common.rdclass = rdata->rdclass; - dnskey->common.rdtype = rdata->type; - ISC_LINK_INIT(&dnskey->common, link); + DNS_RDATACOMMON_INIT(dnskey, rdata->type, rdata->rdclass); return generic_tostruct_key(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/doa_259.c bind9-9.20.15/lib/dns/rdata/generic/doa_259.c --- bind9-9.20.11/lib/dns/rdata/generic/doa_259.c 2025-07-04 09:42:08.396329609 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/doa_259.c 2025-10-18 10:16:12.629733333 +0000 @@ -214,9 +214,7 @@ REQUIRE(doa != NULL); REQUIRE(rdata->length >= 10); - doa->common.rdclass = rdata->rdclass; - doa->common.rdtype = rdata->type; - ISC_LINK_INIT(&doa->common, link); + DNS_RDATACOMMON_INIT(doa, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/ds_43.c bind9-9.20.15/lib/dns/rdata/generic/ds_43.c --- bind9-9.20.11/lib/dns/rdata/generic/ds_43.c 2025-07-04 09:42:08.397329632 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/ds_43.c 2025-10-18 10:16:12.630733348 +0000 @@ -303,9 +303,7 @@ REQUIRE(rdata->type == dns_rdatatype_ds); REQUIRE(ds != NULL); - ds->common.rdclass = rdata->rdclass; - ds->common.rdtype = rdata->type; - ISC_LINK_INIT(&ds->common, link); + DNS_RDATACOMMON_INIT(ds, rdata->type, rdata->rdclass); return generic_tostruct_ds(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/dsync_66.c bind9-9.20.15/lib/dns/rdata/generic/dsync_66.c --- bind9-9.20.11/lib/dns/rdata/generic/dsync_66.c 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/dsync_66.c 2025-10-18 10:16:12.630733348 +0000 @@ -0,0 +1,359 @@ +/* + * 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. + */ + +#ifndef RDATA_GENERIC_DSYNC_66_C +#define RDATA_GENERIC_DSYNC_66_C + +#include + +#include + +#include +#include + +#define RRTYPE_DSYNC_ATTRIBUTES (0) + +static isc_result_t +fromtext_dsync(ARGS_FROMTEXT) { + isc_token_t token; + isc_result_t result; + dns_fixedname_t fn; + dns_name_t *name = dns_fixedname_initname(&fn); + isc_buffer_t buffer; + dns_rdatatype_t rrtype; + dns_dsyncscheme_t scheme; + bool ok = true; + + REQUIRE(type == dns_rdatatype_dsync); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(callbacks); + + /* + * RRtype + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + false)); + result = dns_rdatatype_fromtext(&rrtype, &token.value.as_textregion); + if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) { + char *e = NULL; + long i = strtol(DNS_AS_STR(token), &e, 10); + if (i < 0 || i > 65535) { + RETTOK(ISC_R_RANGE); + } + if (*e != 0) { + RETTOK(result); + } + rrtype = (dns_rdatatype_t)i; + } + RETERR(uint16_tobuffer(rrtype, target)); + + /* + * Scheme + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + false)); + RETERR(dns_dsyncscheme_fromtext(&scheme, &token.value.as_textregion)); + RETERR(uint8_tobuffer(scheme, target)); + + /* + * Port + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + false)); + if (token.value.as_ulong > 0xffffU) { + RETTOK(ISC_R_RANGE); + } + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + /* + * Target + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, + false)); + + buffer_fromregion(&buffer, &token.value.as_region); + if (origin == NULL) { + origin = dns_rootname; + } + RETTOK(dns_name_fromtext(name, &buffer, origin, options, target)); + if ((options & DNS_RDATA_CHECKNAMES) != 0) { + ok = dns_name_ishostname(name, false); + } + if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) { + RETTOK(DNS_R_BADNAME); + } + if (!ok && callbacks != NULL) { + warn_badname(name, lexer, callbacks); + } + return ISC_R_SUCCESS; +} + +static isc_result_t +totext_dsync(ARGS_TOTEXT) { + isc_region_t region; + dns_name_t name; + dns_name_t prefix; + unsigned int opts; + char buf[sizeof("TYPE64000")]; + unsigned short num; + dns_rdatatype_t type; + dns_dsyncscheme_t scheme; + + REQUIRE(rdata->type == dns_rdatatype_dsync); + REQUIRE(rdata->length != 0); + + dns_name_init(&name, NULL); + dns_name_init(&prefix, NULL); + + dns_rdata_toregion(rdata, ®ion); + + /* + * Type. + */ + type = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + /* + * XXXAG We should have something like dns_rdatatype_isknown() + * that does the right thing with type 0. + */ + if (dns_rdatatype_isknown(type) && type != 0) { + RETERR(dns_rdatatype_totext(type, target)); + } else { + snprintf(buf, sizeof(buf), "TYPE%u", type); + RETERR(str_totext(buf, target)); + } + RETERR(str_totext(" ", target)); + + /* + * Scheme. + */ + scheme = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + RETERR(dns_dsyncscheme_totext(scheme, target)); + + RETERR(str_totext(" ", target)); + + /* + * Port + */ + num = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + snprintf(buf, sizeof(buf), "%u", num); + RETERR(str_totext(buf, target)); + + RETERR(str_totext(" ", target)); + + /* + * Target + */ + dns_name_fromregion(&name, ®ion); + opts = name_prefix(&name, tctx->origin, &prefix) ? DNS_NAME_OMITFINALDOT + : 0; + return dns_name_totext(&prefix, opts, target); +} + +static isc_result_t +fromwire_dsync(ARGS_FROMWIRE) { + dns_name_t name; + isc_region_t sregion; + + REQUIRE(type == dns_rdatatype_dsync); + + UNUSED(type); + UNUSED(rdclass); + + dctx = dns_decompress_setpermitted(dctx, false); + + dns_name_init(&name, NULL); + + isc_buffer_activeregion(source, &sregion); + if (sregion.length < 5) { + return ISC_R_UNEXPECTEDEND; + } + RETERR(mem_tobuffer(target, sregion.base, 5)); + isc_buffer_forward(source, 5); + return dns_name_fromwire(&name, source, dctx, target); +} + +static isc_result_t +towire_dsync(ARGS_TOWIRE) { + dns_name_t name; + isc_region_t region; + + REQUIRE(rdata->type == dns_rdatatype_dsync); + REQUIRE(rdata->length != 0); + + dns_compress_setpermitted(cctx, false); + + dns_rdata_toregion(rdata, ®ion); + RETERR(mem_tobuffer(target, region.base, 5)); + isc_region_consume(®ion, 5); + + dns_name_init(&name, NULL); + dns_name_fromregion(&name, ®ion); + + return dns_name_towire(&name, cctx, target, NULL); +} + +static int +compare_dsync(ARGS_COMPARE) { + isc_region_t region1; + isc_region_t region2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == dns_rdatatype_dsync); + REQUIRE(rdata1->length != 0); + REQUIRE(rdata2->length != 0); + + dns_rdata_toregion(rdata1, ®ion1); + dns_rdata_toregion(rdata2, ®ion2); + return isc_region_compare(®ion1, ®ion2); +} + +static isc_result_t +fromstruct_dsync(ARGS_FROMSTRUCT) { + dns_rdata_dsync_t *dsync = source; + isc_region_t region; + + REQUIRE(type == dns_rdatatype_dsync); + REQUIRE(dsync != NULL); + REQUIRE(dsync->common.rdtype == type); + REQUIRE(dsync->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + RETERR(uint16_tobuffer(dsync->type, target)); + RETERR(uint16_tobuffer(dsync->scheme, target)); + RETERR(uint16_tobuffer(dsync->port, target)); + dns_name_toregion(&dsync->target, ®ion); + return isc_buffer_copyregion(target, ®ion); +} + +static isc_result_t +tostruct_dsync(ARGS_TOSTRUCT) { + isc_region_t region; + dns_rdata_dsync_t *dsync = target; + dns_name_t name; + + REQUIRE(rdata->type == dns_rdatatype_dsync); + REQUIRE(dsync != NULL); + REQUIRE(rdata->length != 0); + + DNS_RDATACOMMON_INIT(dsync, rdata->type, rdata->rdclass); + + dns_name_init(&name, NULL); + dns_rdata_toregion(rdata, ®ion); + dsync->type = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + dsync->scheme = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + dsync->port = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + dns_name_fromregion(&name, ®ion); + dns_name_init(&dsync->target, NULL); + name_duporclone(&name, mctx, &dsync->target); + dsync->mctx = mctx; + return ISC_R_SUCCESS; +} + +static void +freestruct_dsync(ARGS_FREESTRUCT) { + dns_rdata_dsync_t *dsync = source; + + REQUIRE(dsync != NULL); + REQUIRE(dsync->common.rdtype == dns_rdatatype_dsync); + + if (dsync->mctx == NULL) { + return; + } + + dns_name_free(&dsync->target, dsync->mctx); + dsync->mctx = NULL; +} + +static isc_result_t +additionaldata_dsync(ARGS_ADDLDATA) { + dns_name_t name; + isc_region_t region; + + REQUIRE(rdata->type == dns_rdatatype_dsync); + + UNUSED(owner); + + dns_name_init(&name, NULL); + dns_rdata_toregion(rdata, ®ion); + isc_region_consume(®ion, 5); + dns_name_fromregion(&name, ®ion); + + if (dns_name_equal(&name, dns_rootname)) { + return ISC_R_SUCCESS; + } + + return (add)(arg, &name, dns_rdatatype_a, NULL DNS__DB_FILELINE); +} + +static isc_result_t +digest_dsync(ARGS_DIGEST) { + isc_region_t r1; + + REQUIRE(rdata->type == dns_rdatatype_dsync); + + dns_rdata_toregion(rdata, &r1); + return (digest)(arg, &r1); +} + +static bool +checkowner_dsync(ARGS_CHECKOWNER) { + REQUIRE(type == dns_rdatatype_dsync); + + UNUSED(name); + UNUSED(rdclass); + UNUSED(type); + UNUSED(wildcard); + + return true; +} + +static bool +checknames_dsync(ARGS_CHECKNAMES) { + isc_region_t region; + dns_name_t name; + + REQUIRE(rdata->type == dns_rdatatype_dsync); + REQUIRE(rdata->length > 5); + + UNUSED(owner); + + dns_rdata_toregion(rdata, ®ion); + isc_region_consume(®ion, 5); + dns_name_init(&name, NULL); + dns_name_fromregion(&name, ®ion); + if (!dns_name_ishostname(&name, false)) { + if (bad != NULL) { + dns_name_clone(&name, bad); + } + return false; + } + return true; +} + +static int +casecompare_dsync(ARGS_COMPARE) { + return compare_dsync(rdata1, rdata2); +} + +#endif /* RDATA_GENERIC_DSYNC_66_C */ diff -Nru bind9-9.20.11/lib/dns/rdata/generic/dsync_66.h bind9-9.20.15/lib/dns/rdata/generic/dsync_66.h --- bind9-9.20.11/lib/dns/rdata/generic/dsync_66.h 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/dsync_66.h 2025-10-18 10:16:12.630733348 +0000 @@ -0,0 +1,24 @@ +/* + * 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 + +typedef struct dns_rdata_dsync { + dns_rdatacommon_t common; + isc_mem_t *mctx; + uint16_t type; + uint8_t scheme; + uint16_t port; + dns_name_t target; +} dns_rdata_dsync_t; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/eui48_108.c bind9-9.20.15/lib/dns/rdata/generic/eui48_108.c --- bind9-9.20.11/lib/dns/rdata/generic/eui48_108.c 2025-07-04 09:42:08.397329632 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/eui48_108.c 2025-10-18 10:16:12.630733348 +0000 @@ -136,9 +136,7 @@ UNUSED(mctx); - eui48->common.rdclass = rdata->rdclass; - eui48->common.rdtype = rdata->type; - ISC_LINK_INIT(&eui48->common, link); + DNS_RDATACOMMON_INIT(eui48, rdata->type, rdata->rdclass); memmove(eui48->eui48, rdata->data, rdata->length); return ISC_R_SUCCESS; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/eui64_109.c bind9-9.20.15/lib/dns/rdata/generic/eui64_109.c --- bind9-9.20.11/lib/dns/rdata/generic/eui64_109.c 2025-07-04 09:42:08.397329632 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/eui64_109.c 2025-10-18 10:16:12.630733348 +0000 @@ -139,9 +139,7 @@ UNUSED(mctx); - eui64->common.rdclass = rdata->rdclass; - eui64->common.rdtype = rdata->type; - ISC_LINK_INIT(&eui64->common, link); + DNS_RDATACOMMON_INIT(eui64, rdata->type, rdata->rdclass); memmove(eui64->eui64, rdata->data, rdata->length); return ISC_R_SUCCESS; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/gpos_27.c bind9-9.20.15/lib/dns/rdata/generic/gpos_27.c --- bind9-9.20.11/lib/dns/rdata/generic/gpos_27.c 2025-07-04 09:42:08.397329632 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/gpos_27.c 2025-10-18 10:16:12.630733348 +0000 @@ -132,9 +132,7 @@ REQUIRE(gpos != NULL); REQUIRE(rdata->length != 0); - gpos->common.rdclass = rdata->rdclass; - gpos->common.rdtype = rdata->type; - ISC_LINK_INIT(&gpos->common, link); + DNS_RDATACOMMON_INIT(gpos, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); gpos->long_len = uint8_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/hhit_67.c bind9-9.20.15/lib/dns/rdata/generic/hhit_67.c --- bind9-9.20.11/lib/dns/rdata/generic/hhit_67.c 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/hhit_67.c 2025-10-18 10:16:12.630733348 +0000 @@ -0,0 +1,213 @@ +/* + * 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. + */ + +#ifndef RDATA_GENERIC_HHIT_67_C +#define RDATA_GENERIC_HHIT_67_C + +#include + +#define RRTYPE_HHIT_ATTRIBUTES (0) + +static isc_result_t +fromtext_hhit(ARGS_FROMTEXT) { + REQUIRE(type == dns_rdatatype_hhit); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + return isc_base64_tobuffer(lexer, target, -1); +} + +static isc_result_t +totext_hhit(ARGS_TOTEXT) { + isc_region_t sr; + + REQUIRE(rdata->type == dns_rdatatype_hhit); + REQUIRE(rdata->length > 0); + + dns_rdata_toregion(rdata, &sr); + + /* data */ + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { + RETERR(str_totext(" (", target)); + } + + RETERR(str_totext(tctx->linebreak, target)); + + if (tctx->width == 0) { /* No splitting */ + RETERR(isc_base64_totext(&sr, 60, "", target)); + } else { + RETERR(isc_base64_totext(&sr, tctx->width - 2, tctx->linebreak, + target)); + } + + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) { + RETERR(str_totext(" )", target)); + } + + return ISC_R_SUCCESS; +} + +static isc_result_t +fromwire_hhit(ARGS_FROMWIRE) { + isc_region_t sr; + + REQUIRE(type == dns_rdatatype_hhit); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(dctx); + + isc_buffer_activeregion(source, &sr); + if (sr.length == 0) { + return ISC_R_UNEXPECTEDEND; + } + + RETERR(mem_tobuffer(target, sr.base, sr.length)); + isc_buffer_forward(source, sr.length); + return ISC_R_SUCCESS; +} + +static isc_result_t +towire_hhit(ARGS_TOWIRE) { + REQUIRE(rdata->type == dns_rdatatype_hhit); + REQUIRE(rdata->length >= 3); + + UNUSED(cctx); + + return mem_tobuffer(target, rdata->data, rdata->length); +} + +static int +compare_hhit(ARGS_COMPARE) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == dns_rdatatype_hhit); + REQUIRE(rdata1->length > 0); + REQUIRE(rdata2->length > 0); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return isc_region_compare(&r1, &r2); +} + +static isc_result_t +fromstruct_hhit(ARGS_FROMSTRUCT) { + dns_rdata_hhit_t *hhit = source; + + REQUIRE(type == dns_rdatatype_hhit); + REQUIRE(hhit != NULL); + REQUIRE(hhit->common.rdtype == type); + REQUIRE(hhit->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + /* Data */ + return mem_tobuffer(target, hhit->data, hhit->datalen); +} + +static isc_result_t +tostruct_hhit(ARGS_TOSTRUCT) { + dns_rdata_hhit_t *hhit = target; + isc_region_t sr; + + REQUIRE(rdata->type == dns_rdatatype_hhit); + REQUIRE(hhit != NULL); + REQUIRE(rdata->length > 0); + + DNS_RDATACOMMON_INIT(hhit, rdata->type, rdata->rdclass); + + dns_rdata_toregion(rdata, &sr); + + /* Data */ + hhit->datalen = sr.length; + hhit->data = mem_maybedup(mctx, sr.base, hhit->datalen); + hhit->mctx = mctx; + return ISC_R_SUCCESS; +} + +static void +freestruct_hhit(ARGS_FREESTRUCT) { + dns_rdata_hhit_t *hhit = (dns_rdata_hhit_t *)source; + + REQUIRE(hhit != NULL); + REQUIRE(hhit->common.rdtype == dns_rdatatype_hhit); + + if (hhit->mctx == NULL) { + return; + } + + if (hhit->data != NULL) { + isc_mem_free(hhit->mctx, hhit->data); + } + hhit->mctx = NULL; +} + +static isc_result_t +additionaldata_hhit(ARGS_ADDLDATA) { + REQUIRE(rdata->type == dns_rdatatype_hhit); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(add); + UNUSED(arg); + + return ISC_R_SUCCESS; +} + +static isc_result_t +digest_hhit(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == dns_rdatatype_hhit); + + dns_rdata_toregion(rdata, &r); + + return (digest)(arg, &r); +} + +static bool +checkowner_hhit(ARGS_CHECKOWNER) { + REQUIRE(type == dns_rdatatype_hhit); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return true; +} + +static bool +checknames_hhit(ARGS_CHECKNAMES) { + REQUIRE(rdata->type == dns_rdatatype_hhit); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return true; +} + +static int +casecompare_hhit(ARGS_COMPARE) { + return compare_hhit(rdata1, rdata2); +} +#endif /* RDATA_GENERIC_HHIT_67_C */ diff -Nru bind9-9.20.11/lib/dns/rdata/generic/hhit_67.h bind9-9.20.15/lib/dns/rdata/generic/hhit_67.h --- bind9-9.20.11/lib/dns/rdata/generic/hhit_67.h 1970-01-01 00:00:00.000000000 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/hhit_67.h 2025-10-18 10:16:12.630733348 +0000 @@ -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. + */ + +#pragma once + +typedef struct dns_rdata_hhit_t { + dns_rdatacommon_t common; + isc_mem_t *mctx; + uint16_t datalen; + unsigned char *data; +} dns_rdata_hhit_t; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/hinfo_13.c bind9-9.20.15/lib/dns/rdata/generic/hinfo_13.c --- bind9-9.20.11/lib/dns/rdata/generic/hinfo_13.c 2025-07-04 09:42:08.397329632 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/hinfo_13.c 2025-10-18 10:16:12.631733364 +0000 @@ -116,9 +116,7 @@ REQUIRE(hinfo != NULL); REQUIRE(rdata->length != 0); - hinfo->common.rdclass = rdata->rdclass; - hinfo->common.rdtype = rdata->type; - ISC_LINK_INIT(&hinfo->common, link); + DNS_RDATACOMMON_INIT(hinfo, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); hinfo->cpu_len = uint8_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/hip_55.c bind9-9.20.15/lib/dns/rdata/generic/hip_55.c --- bind9-9.20.11/lib/dns/rdata/generic/hip_55.c 2025-07-04 09:42:08.397329632 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/hip_55.c 2025-10-18 10:16:12.631733364 +0000 @@ -306,9 +306,7 @@ REQUIRE(hip != NULL); REQUIRE(rdata->length != 0); - hip->common.rdclass = rdata->rdclass; - hip->common.rdtype = rdata->type; - ISC_LINK_INIT(&hip->common, link); + DNS_RDATACOMMON_INIT(hip, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/ipseckey_45.c bind9-9.20.15/lib/dns/rdata/generic/ipseckey_45.c --- bind9-9.20.11/lib/dns/rdata/generic/ipseckey_45.c 2025-07-04 09:42:08.398329656 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/ipseckey_45.c 2025-10-18 10:16:12.631733364 +0000 @@ -353,9 +353,7 @@ REQUIRE(ipseckey != NULL); REQUIRE(rdata->length >= 3); - ipseckey->common.rdclass = rdata->rdclass; - ipseckey->common.rdtype = rdata->type; - ISC_LINK_INIT(&ipseckey->common, link); + DNS_RDATACOMMON_INIT(ipseckey, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/isdn_20.c bind9-9.20.15/lib/dns/rdata/generic/isdn_20.c --- bind9-9.20.11/lib/dns/rdata/generic/isdn_20.c 2025-07-04 09:42:08.398329656 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/isdn_20.c 2025-10-18 10:16:12.631733364 +0000 @@ -137,9 +137,7 @@ REQUIRE(isdn != NULL); REQUIRE(rdata->length != 0); - isdn->common.rdclass = rdata->rdclass; - isdn->common.rdtype = rdata->type; - ISC_LINK_INIT(&isdn->common, link); + DNS_RDATACOMMON_INIT(isdn, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/key_25.c bind9-9.20.15/lib/dns/rdata/generic/key_25.c --- bind9-9.20.11/lib/dns/rdata/generic/key_25.c 2025-07-04 09:42:08.398329656 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/key_25.c 2025-10-18 10:16:12.631733364 +0000 @@ -415,9 +415,7 @@ REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_key); - key->common.rdclass = rdata->rdclass; - key->common.rdtype = rdata->type; - ISC_LINK_INIT(&key->common, link); + DNS_RDATACOMMON_INIT(key, rdata->type, rdata->rdclass); return generic_tostruct_key(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/keydata_65533.c bind9-9.20.15/lib/dns/rdata/generic/keydata_65533.c --- bind9-9.20.11/lib/dns/rdata/generic/keydata_65533.c 2025-07-04 09:42:08.398329656 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/keydata_65533.c 2025-10-18 10:16:12.632733379 +0000 @@ -330,9 +330,7 @@ REQUIRE(rdata->type == dns_rdatatype_keydata); REQUIRE(keydata != NULL); - keydata->common.rdclass = rdata->rdclass; - keydata->common.rdtype = rdata->type; - ISC_LINK_INIT(&keydata->common, link); + DNS_RDATACOMMON_INIT(keydata, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/l32_105.c bind9-9.20.15/lib/dns/rdata/generic/l32_105.c --- bind9-9.20.11/lib/dns/rdata/generic/l32_105.c 2025-07-04 09:42:08.399329679 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/l32_105.c 2025-10-18 10:16:12.632733379 +0000 @@ -152,9 +152,7 @@ UNUSED(mctx); - l32->common.rdclass = rdata->rdclass; - l32->common.rdtype = rdata->type; - ISC_LINK_INIT(&l32->common, link); + DNS_RDATACOMMON_INIT(l32, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); l32->pref = uint16_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/l64_106.c bind9-9.20.15/lib/dns/rdata/generic/l64_106.c --- bind9-9.20.11/lib/dns/rdata/generic/l64_106.c 2025-07-04 09:42:08.399329679 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/l64_106.c 2025-10-18 10:16:12.632733379 +0000 @@ -147,9 +147,7 @@ UNUSED(mctx); - l64->common.rdclass = rdata->rdclass; - l64->common.rdtype = rdata->type; - ISC_LINK_INIT(&l64->common, link); + DNS_RDATACOMMON_INIT(l64, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); l64->pref = uint16_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/loc_29.c bind9-9.20.15/lib/dns/rdata/generic/loc_29.c --- bind9-9.20.11/lib/dns/rdata/generic/loc_29.c 2025-07-04 09:42:08.399329679 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/loc_29.c 2025-10-18 10:16:12.632733379 +0000 @@ -752,9 +752,7 @@ return ISC_R_NOTIMPLEMENTED; } - loc->common.rdclass = rdata->rdclass; - loc->common.rdtype = rdata->type; - ISC_LINK_INIT(&loc->common, link); + DNS_RDATACOMMON_INIT(loc, rdata->type, rdata->rdclass); loc->v.v0.version = version; isc_region_consume(&r, 1); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/lp_107.c bind9-9.20.15/lib/dns/rdata/generic/lp_107.c --- bind9-9.20.11/lib/dns/rdata/generic/lp_107.c 2025-07-04 09:42:08.399329679 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/lp_107.c 2025-10-18 10:16:12.632733379 +0000 @@ -157,9 +157,7 @@ REQUIRE(lp != NULL); REQUIRE(rdata->length != 0); - lp->common.rdclass = rdata->rdclass; - lp->common.rdtype = rdata->type; - ISC_LINK_INIT(&lp->common, link); + DNS_RDATACOMMON_INIT(lp, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/mb_7.c bind9-9.20.15/lib/dns/rdata/generic/mb_7.c --- bind9-9.20.11/lib/dns/rdata/generic/mb_7.c 2025-07-04 09:42:08.399329679 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/mb_7.c 2025-10-18 10:16:12.633733395 +0000 @@ -146,9 +146,7 @@ REQUIRE(mb != NULL); REQUIRE(rdata->length != 0); - mb->common.rdclass = rdata->rdclass; - mb->common.rdtype = rdata->type; - ISC_LINK_INIT(&mb->common, link); + DNS_RDATACOMMON_INIT(mb, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/md_3.c bind9-9.20.15/lib/dns/rdata/generic/md_3.c --- bind9-9.20.11/lib/dns/rdata/generic/md_3.c 2025-07-04 09:42:08.399329679 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/md_3.c 2025-10-18 10:16:12.633733395 +0000 @@ -146,9 +146,7 @@ REQUIRE(md != NULL); REQUIRE(rdata->length != 0); - md->common.rdclass = rdata->rdclass; - md->common.rdtype = rdata->type; - ISC_LINK_INIT(&md->common, link); + DNS_RDATACOMMON_INIT(md, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, &r); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/mf_4.c bind9-9.20.15/lib/dns/rdata/generic/mf_4.c --- bind9-9.20.11/lib/dns/rdata/generic/mf_4.c 2025-07-04 09:42:08.400329702 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/mf_4.c 2025-10-18 10:16:12.633733395 +0000 @@ -146,9 +146,7 @@ REQUIRE(mf != NULL); REQUIRE(rdata->length != 0); - mf->common.rdclass = rdata->rdclass; - mf->common.rdtype = rdata->type; - ISC_LINK_INIT(&mf->common, link); + DNS_RDATACOMMON_INIT(mf, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, &r); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/mg_8.c bind9-9.20.15/lib/dns/rdata/generic/mg_8.c --- bind9-9.20.11/lib/dns/rdata/generic/mg_8.c 2025-07-04 09:42:08.400329702 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/mg_8.c 2025-10-18 10:16:12.633733395 +0000 @@ -146,9 +146,7 @@ REQUIRE(mg != NULL); REQUIRE(rdata->length != 0); - mg->common.rdclass = rdata->rdclass; - mg->common.rdtype = rdata->type; - ISC_LINK_INIT(&mg->common, link); + DNS_RDATACOMMON_INIT(mg, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/minfo_14.c bind9-9.20.15/lib/dns/rdata/generic/minfo_14.c --- bind9-9.20.11/lib/dns/rdata/generic/minfo_14.c 2025-07-04 09:42:08.400329702 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/minfo_14.c 2025-10-18 10:16:12.633733395 +0000 @@ -209,9 +209,7 @@ REQUIRE(minfo != NULL); REQUIRE(rdata->length != 0); - minfo->common.rdclass = rdata->rdclass; - minfo->common.rdtype = rdata->type; - ISC_LINK_INIT(&minfo->common, link); + DNS_RDATACOMMON_INIT(minfo, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/mr_9.c bind9-9.20.15/lib/dns/rdata/generic/mr_9.c --- bind9-9.20.11/lib/dns/rdata/generic/mr_9.c 2025-07-04 09:42:08.400329702 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/mr_9.c 2025-10-18 10:16:12.634733410 +0000 @@ -146,9 +146,7 @@ REQUIRE(mr != NULL); REQUIRE(rdata->length != 0); - mr->common.rdclass = rdata->rdclass; - mr->common.rdtype = rdata->type; - ISC_LINK_INIT(&mr->common, link); + DNS_RDATACOMMON_INIT(mr, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/mx_15.c bind9-9.20.15/lib/dns/rdata/generic/mx_15.c --- bind9-9.20.11/lib/dns/rdata/generic/mx_15.c 2025-07-04 09:42:08.400329702 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/mx_15.c 2025-10-18 10:16:12.634733410 +0000 @@ -231,9 +231,7 @@ REQUIRE(mx != NULL); REQUIRE(rdata->length != 0); - mx->common.rdclass = rdata->rdclass; - mx->common.rdtype = rdata->type; - ISC_LINK_INIT(&mx->common, link); + DNS_RDATACOMMON_INIT(mx, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/naptr_35.c bind9-9.20.15/lib/dns/rdata/generic/naptr_35.c --- bind9-9.20.11/lib/dns/rdata/generic/naptr_35.c 2025-07-04 09:42:08.401329726 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/naptr_35.c 2025-10-18 10:16:12.634733410 +0000 @@ -502,9 +502,7 @@ REQUIRE(naptr != NULL); REQUIRE(rdata->length != 0); - naptr->common.rdclass = rdata->rdclass; - naptr->common.rdtype = rdata->type; - ISC_LINK_INIT(&naptr->common, link); + DNS_RDATACOMMON_INIT(naptr, rdata->type, rdata->rdclass); naptr->flags = NULL; naptr->service = NULL; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/nid_104.c bind9-9.20.15/lib/dns/rdata/generic/nid_104.c --- bind9-9.20.11/lib/dns/rdata/generic/nid_104.c 2025-07-04 09:42:08.401329726 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/nid_104.c 2025-10-18 10:16:12.634733410 +0000 @@ -147,9 +147,7 @@ UNUSED(mctx); - nid->common.rdclass = rdata->rdclass; - nid->common.rdtype = rdata->type; - ISC_LINK_INIT(&nid->common, link); + DNS_RDATACOMMON_INIT(nid, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); nid->pref = uint16_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/ninfo_56.c bind9-9.20.15/lib/dns/rdata/generic/ninfo_56.c --- bind9-9.20.11/lib/dns/rdata/generic/ninfo_56.c 2025-07-04 09:42:08.401329726 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/ninfo_56.c 2025-10-18 10:16:12.634733410 +0000 @@ -75,9 +75,7 @@ REQUIRE(rdata->type == dns_rdatatype_ninfo); REQUIRE(ninfo != NULL); - ninfo->common.rdclass = rdata->rdclass; - ninfo->common.rdtype = rdata->type; - ISC_LINK_INIT(&ninfo->common, link); + DNS_RDATACOMMON_INIT(ninfo, rdata->type, rdata->rdclass); return generic_tostruct_txt(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/ns_2.c bind9-9.20.15/lib/dns/rdata/generic/ns_2.c --- bind9-9.20.11/lib/dns/rdata/generic/ns_2.c 2025-07-04 09:42:08.401329726 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/ns_2.c 2025-10-18 10:16:12.635733426 +0000 @@ -157,9 +157,7 @@ REQUIRE(ns != NULL); REQUIRE(rdata->length != 0); - ns->common.rdclass = rdata->rdclass; - ns->common.rdtype = rdata->type; - ISC_LINK_INIT(&ns->common, link); + DNS_RDATACOMMON_INIT(ns, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/nsec3_50.c bind9-9.20.15/lib/dns/rdata/generic/nsec3_50.c --- bind9-9.20.11/lib/dns/rdata/generic/nsec3_50.c 2025-07-04 09:42:08.401329726 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/nsec3_50.c 2025-10-18 10:16:12.635733426 +0000 @@ -292,9 +292,7 @@ REQUIRE(nsec3 != NULL); REQUIRE(rdata->length != 0); - nsec3->common.rdclass = rdata->rdclass; - nsec3->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsec3->common, link); + DNS_RDATACOMMON_INIT(nsec3, rdata->type, rdata->rdclass); region.base = rdata->data; region.length = rdata->length; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/nsec3param_51.c bind9-9.20.15/lib/dns/rdata/generic/nsec3param_51.c --- bind9-9.20.11/lib/dns/rdata/generic/nsec3param_51.c 2025-07-04 09:42:08.401329726 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/nsec3param_51.c 2025-10-18 10:16:12.635733426 +0000 @@ -228,9 +228,7 @@ REQUIRE(nsec3param != NULL); REQUIRE(rdata->length != 0); - nsec3param->common.rdclass = rdata->rdclass; - nsec3param->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsec3param->common, link); + DNS_RDATACOMMON_INIT(nsec3param, rdata->type, rdata->rdclass); region.base = rdata->data; region.length = rdata->length; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/nsec_47.c bind9-9.20.15/lib/dns/rdata/generic/nsec_47.c --- bind9-9.20.11/lib/dns/rdata/generic/nsec_47.c 2025-07-04 09:42:08.402329749 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/nsec_47.c 2025-10-18 10:16:12.635733426 +0000 @@ -165,9 +165,7 @@ REQUIRE(nsec != NULL); REQUIRE(rdata->length != 0); - nsec->common.rdclass = rdata->rdclass; - nsec->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsec->common, link); + DNS_RDATACOMMON_INIT(nsec, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/null_10.c bind9-9.20.15/lib/dns/rdata/generic/null_10.c --- bind9-9.20.11/lib/dns/rdata/generic/null_10.c 2025-07-04 09:42:08.402329749 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/null_10.c 2025-10-18 10:16:12.635733426 +0000 @@ -100,9 +100,7 @@ REQUIRE(rdata->type == dns_rdatatype_null); REQUIRE(null != NULL); - null->common.rdclass = rdata->rdclass; - null->common.rdtype = rdata->type; - ISC_LINK_INIT(&null->common, link); + DNS_RDATACOMMON_INIT(null, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); null->length = r.length; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/nxt_30.c bind9-9.20.15/lib/dns/rdata/generic/nxt_30.c --- bind9-9.20.11/lib/dns/rdata/generic/nxt_30.c 2025-07-04 09:42:08.402329749 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/nxt_30.c 2025-10-18 10:16:12.635733426 +0000 @@ -244,9 +244,7 @@ REQUIRE(nxt != NULL); REQUIRE(rdata->length != 0); - nxt->common.rdclass = rdata->rdclass; - nxt->common.rdtype = rdata->type; - ISC_LINK_INIT(&nxt->common, link); + DNS_RDATACOMMON_INIT(nxt, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/openpgpkey_61.c bind9-9.20.15/lib/dns/rdata/generic/openpgpkey_61.c --- bind9-9.20.11/lib/dns/rdata/generic/openpgpkey_61.c 2025-07-04 09:42:08.402329749 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/openpgpkey_61.c 2025-10-18 10:16:12.636733441 +0000 @@ -144,9 +144,7 @@ REQUIRE(sig != NULL); REQUIRE(rdata->length != 0); - sig->common.rdclass = rdata->rdclass; - sig->common.rdtype = rdata->type; - ISC_LINK_INIT(&sig->common, link); + DNS_RDATACOMMON_INIT(sig, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/opt_41.c bind9-9.20.15/lib/dns/rdata/generic/opt_41.c --- bind9-9.20.11/lib/dns/rdata/generic/opt_41.c 2025-07-04 09:42:08.402329749 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/opt_41.c 2025-10-18 10:16:12.636733441 +0000 @@ -328,9 +328,7 @@ REQUIRE(rdata->type == dns_rdatatype_opt); REQUIRE(opt != NULL); - opt->common.rdclass = rdata->rdclass; - opt->common.rdtype = rdata->type; - ISC_LINK_INIT(&opt->common, link); + DNS_RDATACOMMON_INIT(opt, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); opt->length = r.length; diff -Nru bind9-9.20.11/lib/dns/rdata/generic/ptr_12.c bind9-9.20.15/lib/dns/rdata/generic/ptr_12.c --- bind9-9.20.11/lib/dns/rdata/generic/ptr_12.c 2025-07-04 09:42:08.403329773 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/ptr_12.c 2025-10-18 10:16:12.636733441 +0000 @@ -159,9 +159,7 @@ REQUIRE(ptr != NULL); REQUIRE(rdata->length != 0); - ptr->common.rdclass = rdata->rdclass; - ptr->common.rdtype = rdata->type; - ISC_LINK_INIT(&ptr->common, link); + DNS_RDATACOMMON_INIT(ptr, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/resinfo_261.c bind9-9.20.15/lib/dns/rdata/generic/resinfo_261.c --- bind9-9.20.11/lib/dns/rdata/generic/resinfo_261.c 2025-07-04 09:42:08.403329773 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/resinfo_261.c 2025-10-18 10:16:12.636733441 +0000 @@ -76,9 +76,7 @@ REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_resinfo); - resinfo->common.rdclass = rdata->rdclass; - resinfo->common.rdtype = rdata->type; - ISC_LINK_INIT(&resinfo->common, link); + DNS_RDATACOMMON_INIT(resinfo, rdata->type, rdata->rdclass); return generic_tostruct_txt(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/rkey_57.c bind9-9.20.15/lib/dns/rdata/generic/rkey_57.c --- bind9-9.20.11/lib/dns/rdata/generic/rkey_57.c 2025-07-04 09:42:08.403329773 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/rkey_57.c 2025-10-18 10:16:12.636733441 +0000 @@ -85,9 +85,7 @@ REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_rkey); - rkey->common.rdclass = rdata->rdclass; - rkey->common.rdtype = rdata->type; - ISC_LINK_INIT(&rkey->common, link); + DNS_RDATACOMMON_INIT(rkey, rdata->type, rdata->rdclass); return generic_tostruct_key(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/rp_17.c bind9-9.20.15/lib/dns/rdata/generic/rp_17.c --- bind9-9.20.11/lib/dns/rdata/generic/rp_17.c 2025-07-04 09:42:08.403329773 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/rp_17.c 2025-10-18 10:16:12.637733457 +0000 @@ -209,9 +209,7 @@ REQUIRE(rp != NULL); REQUIRE(rdata->length != 0); - rp->common.rdclass = rdata->rdclass; - rp->common.rdtype = rdata->type; - ISC_LINK_INIT(&rp->common, link); + DNS_RDATACOMMON_INIT(rp, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/rrsig_46.c bind9-9.20.15/lib/dns/rdata/generic/rrsig_46.c --- bind9-9.20.11/lib/dns/rdata/generic/rrsig_46.c 2025-07-04 09:42:08.403329773 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/rrsig_46.c 2025-10-18 10:16:12.637733457 +0000 @@ -500,9 +500,7 @@ REQUIRE(sig != NULL); REQUIRE(rdata->length != 0); - sig->common.rdclass = rdata->rdclass; - sig->common.rdtype = rdata->type; - ISC_LINK_INIT(&sig->common, link); + DNS_RDATACOMMON_INIT(sig, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/rt_21.c bind9-9.20.15/lib/dns/rdata/generic/rt_21.c --- bind9-9.20.11/lib/dns/rdata/generic/rt_21.c 2025-07-04 09:42:08.404329796 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/rt_21.c 2025-10-18 10:16:12.637733457 +0000 @@ -204,9 +204,7 @@ REQUIRE(rt != NULL); REQUIRE(rdata->length != 0); - rt->common.rdclass = rdata->rdclass; - rt->common.rdtype = rdata->type; - ISC_LINK_INIT(&rt->common, link); + DNS_RDATACOMMON_INIT(rt, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/sig_24.c bind9-9.20.15/lib/dns/rdata/generic/sig_24.c --- bind9-9.20.11/lib/dns/rdata/generic/sig_24.c 2025-07-04 09:42:08.404329796 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/sig_24.c 2025-10-18 10:16:12.637733457 +0000 @@ -464,9 +464,7 @@ REQUIRE(sig != NULL); REQUIRE(rdata->length != 0); - sig->common.rdclass = rdata->rdclass; - sig->common.rdtype = rdata->type; - ISC_LINK_INIT(&sig->common, link); + DNS_RDATACOMMON_INIT(sig, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/sink_40.c bind9-9.20.15/lib/dns/rdata/generic/sink_40.c --- bind9-9.20.11/lib/dns/rdata/generic/sink_40.c 2025-07-04 09:42:08.404329796 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/sink_40.c 2025-10-18 10:16:12.637733457 +0000 @@ -183,9 +183,7 @@ REQUIRE(sink != NULL); REQUIRE(rdata->length >= 3); - sink->common.rdclass = rdata->rdclass; - sink->common.rdtype = rdata->type; - ISC_LINK_INIT(&sink->common, link); + DNS_RDATACOMMON_INIT(sink, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/smimea_53.c bind9-9.20.15/lib/dns/rdata/generic/smimea_53.c --- bind9-9.20.11/lib/dns/rdata/generic/smimea_53.c 2025-07-04 09:42:08.404329796 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/smimea_53.c 2025-10-18 10:16:12.638733473 +0000 @@ -82,9 +82,7 @@ REQUIRE(rdata->type == dns_rdatatype_smimea); REQUIRE(smimea != NULL); - smimea->common.rdclass = rdata->rdclass; - smimea->common.rdtype = rdata->type; - ISC_LINK_INIT(&smimea->common, link); + DNS_RDATACOMMON_INIT(smimea, rdata->type, rdata->rdclass); return generic_tostruct_tlsa(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/soa_6.c bind9-9.20.15/lib/dns/rdata/generic/soa_6.c --- bind9-9.20.11/lib/dns/rdata/generic/soa_6.c 2025-07-04 09:42:08.404329796 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/soa_6.c 2025-10-18 10:16:12.638733473 +0000 @@ -313,9 +313,7 @@ REQUIRE(soa != NULL); REQUIRE(rdata->length != 0); - soa->common.rdclass = rdata->rdclass; - soa->common.rdtype = rdata->type; - ISC_LINK_INIT(&soa->common, link); + DNS_RDATACOMMON_INIT(soa, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/spf_99.c bind9-9.20.15/lib/dns/rdata/generic/spf_99.c --- bind9-9.20.11/lib/dns/rdata/generic/spf_99.c 2025-07-04 09:42:08.405329819 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/spf_99.c 2025-10-18 10:16:12.638733473 +0000 @@ -76,9 +76,7 @@ REQUIRE(rdata != NULL); REQUIRE(rdata->type == dns_rdatatype_spf); - spf->common.rdclass = rdata->rdclass; - spf->common.rdtype = rdata->type; - ISC_LINK_INIT(&spf->common, link); + DNS_RDATACOMMON_INIT(spf, rdata->type, rdata->rdclass); return generic_tostruct_txt(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/sshfp_44.c bind9-9.20.15/lib/dns/rdata/generic/sshfp_44.c --- bind9-9.20.11/lib/dns/rdata/generic/sshfp_44.c 2025-07-04 09:42:08.405329819 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/sshfp_44.c 2025-10-18 10:16:12.638733473 +0000 @@ -204,9 +204,7 @@ REQUIRE(sshfp != NULL); REQUIRE(rdata->length != 0); - sshfp->common.rdclass = rdata->rdclass; - sshfp->common.rdtype = rdata->type; - ISC_LINK_INIT(&sshfp->common, link); + DNS_RDATACOMMON_INIT(sshfp, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/ta_32768.c bind9-9.20.15/lib/dns/rdata/generic/ta_32768.c --- bind9-9.20.11/lib/dns/rdata/generic/ta_32768.c 2025-07-04 09:42:08.405329819 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/ta_32768.c 2025-10-18 10:16:12.638733473 +0000 @@ -85,9 +85,7 @@ /* * Checked by generic_tostruct_ds(). */ - ds->common.rdclass = rdata->rdclass; - ds->common.rdtype = rdata->type; - ISC_LINK_INIT(&ds->common, link); + DNS_RDATACOMMON_INIT(ds, rdata->type, rdata->rdclass); return generic_tostruct_ds(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/talink_58.c bind9-9.20.15/lib/dns/rdata/generic/talink_58.c --- bind9-9.20.11/lib/dns/rdata/generic/talink_58.c 2025-07-04 09:42:08.405329819 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/talink_58.c 2025-10-18 10:16:12.638733473 +0000 @@ -171,9 +171,7 @@ REQUIRE(talink != NULL); REQUIRE(rdata->length != 0); - talink->common.rdclass = rdata->rdclass; - talink->common.rdtype = rdata->type; - ISC_LINK_INIT(&talink->common, link); + DNS_RDATACOMMON_INIT(talink, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/tkey_249.c bind9-9.20.15/lib/dns/rdata/generic/tkey_249.c --- bind9-9.20.11/lib/dns/rdata/generic/tkey_249.c 2025-07-04 09:42:08.405329819 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/tkey_249.c 2025-10-18 10:16:12.639733488 +0000 @@ -426,9 +426,7 @@ REQUIRE(tkey != NULL); REQUIRE(rdata->length != 0); - tkey->common.rdclass = rdata->rdclass; - tkey->common.rdtype = rdata->type; - ISC_LINK_INIT(&tkey->common, link); + DNS_RDATACOMMON_INIT(tkey, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/tlsa_52.c bind9-9.20.15/lib/dns/rdata/generic/tlsa_52.c --- bind9-9.20.11/lib/dns/rdata/generic/tlsa_52.c 2025-07-04 09:42:08.406329843 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/tlsa_52.c 2025-10-18 10:16:12.639733488 +0000 @@ -264,9 +264,7 @@ REQUIRE(rdata->type == dns_rdatatype_tlsa); REQUIRE(tlsa != NULL); - tlsa->common.rdclass = rdata->rdclass; - tlsa->common.rdtype = rdata->type; - ISC_LINK_INIT(&tlsa->common, link); + DNS_RDATACOMMON_INIT(tlsa, rdata->type, rdata->rdclass); return generic_tostruct_tlsa(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/txt_16.c bind9-9.20.15/lib/dns/rdata/generic/txt_16.c --- bind9-9.20.11/lib/dns/rdata/generic/txt_16.c 2025-07-04 09:42:08.406329843 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/txt_16.c 2025-10-18 10:16:12.639733488 +0000 @@ -207,9 +207,7 @@ REQUIRE(rdata->type == dns_rdatatype_txt); REQUIRE(txt != NULL); - txt->common.rdclass = rdata->rdclass; - txt->common.rdtype = rdata->type; - ISC_LINK_INIT(&txt->common, link); + DNS_RDATACOMMON_INIT(txt, rdata->type, rdata->rdclass); return generic_tostruct_txt(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/uri_256.c bind9-9.20.15/lib/dns/rdata/generic/uri_256.c --- bind9-9.20.11/lib/dns/rdata/generic/uri_256.c 2025-07-04 09:42:08.406329843 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/uri_256.c 2025-10-18 10:16:12.639733488 +0000 @@ -210,9 +210,7 @@ REQUIRE(uri != NULL); REQUIRE(rdata->length >= 4); - uri->common.rdclass = rdata->rdclass; - uri->common.rdtype = rdata->type; - ISC_LINK_INIT(&uri->common, link); + DNS_RDATACOMMON_INIT(uri, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &sr); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/wallet_262.c bind9-9.20.15/lib/dns/rdata/generic/wallet_262.c --- bind9-9.20.11/lib/dns/rdata/generic/wallet_262.c 2025-07-04 09:42:08.406329843 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/wallet_262.c 2025-10-18 10:16:12.639733488 +0000 @@ -75,9 +75,7 @@ REQUIRE(rdata->type == dns_rdatatype_wallet); REQUIRE(wallet != NULL); - wallet->common.rdclass = rdata->rdclass; - wallet->common.rdtype = rdata->type; - ISC_LINK_INIT(&wallet->common, link); + DNS_RDATACOMMON_INIT(wallet, rdata->type, rdata->rdclass); return generic_tostruct_txt(CALL_TOSTRUCT); } diff -Nru bind9-9.20.11/lib/dns/rdata/generic/x25_19.c bind9-9.20.15/lib/dns/rdata/generic/x25_19.c --- bind9-9.20.11/lib/dns/rdata/generic/x25_19.c 2025-07-04 09:42:08.406329843 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/x25_19.c 2025-10-18 10:16:12.640733504 +0000 @@ -145,9 +145,7 @@ REQUIRE(x25 != NULL); REQUIRE(rdata->length != 0); - x25->common.rdclass = rdata->rdclass; - x25->common.rdtype = rdata->type; - ISC_LINK_INIT(&x25->common, link); + DNS_RDATACOMMON_INIT(x25, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); x25->x25_len = uint8_fromregion(&r); diff -Nru bind9-9.20.11/lib/dns/rdata/generic/zonemd_63.c bind9-9.20.15/lib/dns/rdata/generic/zonemd_63.c --- bind9-9.20.11/lib/dns/rdata/generic/zonemd_63.c 2025-07-04 09:42:08.407329866 +0000 +++ bind9-9.20.15/lib/dns/rdata/generic/zonemd_63.c 2025-10-18 10:16:12.640733504 +0000 @@ -256,9 +256,7 @@ REQUIRE(zonemd != NULL); REQUIRE(rdata->length != 0); - zonemd->common.rdclass = rdata->rdclass; - zonemd->common.rdtype = rdata->type; - ISC_LINK_INIT(&zonemd->common, link); + DNS_RDATACOMMON_INIT(zonemd, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/hs_4/a_1.c bind9-9.20.15/lib/dns/rdata/hs_4/a_1.c --- bind9-9.20.11/lib/dns/rdata/hs_4/a_1.c 2025-07-04 09:42:08.407329866 +0000 +++ bind9-9.20.15/lib/dns/rdata/hs_4/a_1.c 2025-10-18 10:16:12.640733504 +0000 @@ -158,9 +158,7 @@ UNUSED(mctx); - a->common.rdclass = rdata->rdclass; - a->common.rdtype = rdata->type; - ISC_LINK_INIT(&a->common, link); + DNS_RDATACOMMON_INIT(a, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); n = uint32_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/a6_38.c bind9-9.20.15/lib/dns/rdata/in_1/a6_38.c --- bind9-9.20.11/lib/dns/rdata/in_1/a6_38.c 2025-07-04 09:42:08.407329866 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/a6_38.c 2025-10-18 10:16:12.640733504 +0000 @@ -347,9 +347,7 @@ REQUIRE(a6 != NULL); REQUIRE(rdata->length != 0); - a6->common.rdclass = rdata->rdclass; - a6->common.rdtype = rdata->type; - ISC_LINK_INIT(&a6->common, link); + DNS_RDATACOMMON_INIT(a6, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/a_1.c bind9-9.20.15/lib/dns/rdata/in_1/a_1.c --- bind9-9.20.11/lib/dns/rdata/in_1/a_1.c 2025-07-04 09:42:08.407329866 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/a_1.c 2025-10-18 10:16:12.640733504 +0000 @@ -159,9 +159,7 @@ UNUSED(mctx); - a->common.rdclass = rdata->rdclass; - a->common.rdtype = rdata->type; - ISC_LINK_INIT(&a->common, link); + DNS_RDATACOMMON_INIT(a, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); n = uint32_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/aaaa_28.c bind9-9.20.15/lib/dns/rdata/in_1/aaaa_28.c --- bind9-9.20.11/lib/dns/rdata/in_1/aaaa_28.c 2025-07-04 09:42:08.408329890 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/aaaa_28.c 2025-10-18 10:16:12.640733504 +0000 @@ -171,9 +171,7 @@ UNUSED(mctx); - aaaa->common.rdclass = rdata->rdclass; - aaaa->common.rdtype = rdata->type; - ISC_LINK_INIT(&aaaa->common, link); + DNS_RDATACOMMON_INIT(aaaa, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); INSIST(r.length == 16); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/apl_42.c bind9-9.20.15/lib/dns/rdata/in_1/apl_42.c --- bind9-9.20.11/lib/dns/rdata/in_1/apl_42.c 2025-07-04 09:42:08.408329890 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/apl_42.c 2025-10-18 10:16:12.641733519 +0000 @@ -288,9 +288,7 @@ REQUIRE(rdata->type == dns_rdatatype_apl); REQUIRE(rdata->rdclass == dns_rdataclass_in); - apl->common.rdclass = rdata->rdclass; - apl->common.rdtype = rdata->type; - ISC_LINK_INIT(&apl->common, link); + DNS_RDATACOMMON_INIT(apl, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); apl->apl_len = r.length; diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/atma_34.c bind9-9.20.15/lib/dns/rdata/in_1/atma_34.c --- bind9-9.20.11/lib/dns/rdata/in_1/atma_34.c 2025-07-04 09:42:08.408329890 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/atma_34.c 2025-10-18 10:16:12.641733519 +0000 @@ -224,9 +224,7 @@ REQUIRE(atma != NULL); REQUIRE(rdata->length != 0); - atma->common.rdclass = rdata->rdclass; - atma->common.rdtype = rdata->type; - ISC_LINK_INIT(&atma->common, link); + DNS_RDATACOMMON_INIT(atma, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); atma->format = r.base[0]; diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/dhcid_49.c bind9-9.20.15/lib/dns/rdata/in_1/dhcid_49.c --- bind9-9.20.11/lib/dns/rdata/in_1/dhcid_49.c 2025-07-04 09:42:08.408329890 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/dhcid_49.c 2025-10-18 10:16:12.641733519 +0000 @@ -144,9 +144,7 @@ REQUIRE(dhcid != NULL); REQUIRE(rdata->length != 0); - dhcid->common.rdclass = rdata->rdclass; - dhcid->common.rdtype = rdata->type; - ISC_LINK_INIT(&dhcid->common, link); + DNS_RDATACOMMON_INIT(dhcid, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/eid_31.c bind9-9.20.15/lib/dns/rdata/in_1/eid_31.c --- bind9-9.20.11/lib/dns/rdata/in_1/eid_31.c 2025-07-04 09:42:08.409329913 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/eid_31.c 2025-10-18 10:16:12.641733519 +0000 @@ -133,9 +133,7 @@ REQUIRE(eid != NULL); REQUIRE(rdata->length != 0); - eid->common.rdclass = rdata->rdclass; - eid->common.rdtype = rdata->type; - ISC_LINK_INIT(&eid->common, link); + DNS_RDATACOMMON_INIT(eid, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); eid->eid_len = r.length; diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/kx_36.c bind9-9.20.15/lib/dns/rdata/in_1/kx_36.c --- bind9-9.20.11/lib/dns/rdata/in_1/kx_36.c 2025-07-04 09:42:08.409329913 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/kx_36.c 2025-10-18 10:16:12.641733519 +0000 @@ -189,9 +189,7 @@ REQUIRE(kx != NULL); REQUIRE(rdata->length != 0); - kx->common.rdclass = rdata->rdclass; - kx->common.rdtype = rdata->type; - ISC_LINK_INIT(&kx->common, link); + DNS_RDATACOMMON_INIT(kx, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/nimloc_32.c bind9-9.20.15/lib/dns/rdata/in_1/nimloc_32.c --- bind9-9.20.11/lib/dns/rdata/in_1/nimloc_32.c 2025-07-04 09:42:08.409329913 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/nimloc_32.c 2025-10-18 10:16:12.642733535 +0000 @@ -133,9 +133,7 @@ REQUIRE(nimloc != NULL); REQUIRE(rdata->length != 0); - nimloc->common.rdclass = rdata->rdclass; - nimloc->common.rdtype = rdata->type; - ISC_LINK_INIT(&nimloc->common, link); + DNS_RDATACOMMON_INIT(nimloc, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); nimloc->nimloc_len = r.length; diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/nsap-ptr_23.c bind9-9.20.15/lib/dns/rdata/in_1/nsap-ptr_23.c --- bind9-9.20.11/lib/dns/rdata/in_1/nsap-ptr_23.c 2025-07-04 09:42:08.409329913 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/nsap-ptr_23.c 2025-10-18 10:16:12.642733535 +0000 @@ -154,9 +154,7 @@ REQUIRE(nsap_ptr != NULL); REQUIRE(rdata->length != 0); - nsap_ptr->common.rdclass = rdata->rdclass; - nsap_ptr->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsap_ptr->common, link); + DNS_RDATACOMMON_INIT(nsap_ptr, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/nsap_22.c bind9-9.20.15/lib/dns/rdata/in_1/nsap_22.c --- bind9-9.20.11/lib/dns/rdata/in_1/nsap_22.c 2025-07-04 09:42:08.409329913 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/nsap_22.c 2025-10-18 10:16:12.642733535 +0000 @@ -168,9 +168,7 @@ REQUIRE(nsap != NULL); REQUIRE(rdata->length != 0); - nsap->common.rdclass = rdata->rdclass; - nsap->common.rdtype = rdata->type; - ISC_LINK_INIT(&nsap->common, link); + DNS_RDATACOMMON_INIT(nsap, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, &r); nsap->nsap_len = r.length; diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/px_26.c bind9-9.20.15/lib/dns/rdata/in_1/px_26.c --- bind9-9.20.11/lib/dns/rdata/in_1/px_26.c 2025-07-04 09:42:08.410329937 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/px_26.c 2025-10-18 10:16:12.642733535 +0000 @@ -258,9 +258,7 @@ REQUIRE(px != NULL); REQUIRE(rdata->length != 0); - px->common.rdclass = rdata->rdclass; - px->common.rdtype = rdata->type; - ISC_LINK_INIT(&px->common, link); + DNS_RDATACOMMON_INIT(px, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/srv_33.c bind9-9.20.15/lib/dns/rdata/in_1/srv_33.c --- bind9-9.20.11/lib/dns/rdata/in_1/srv_33.c 2025-07-04 09:42:08.410329937 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/srv_33.c 2025-10-18 10:16:12.643733550 +0000 @@ -268,9 +268,7 @@ REQUIRE(srv != NULL); REQUIRE(rdata->length != 0); - srv->common.rdclass = rdata->rdclass; - srv->common.rdtype = rdata->type; - ISC_LINK_INIT(&srv->common, link); + DNS_RDATACOMMON_INIT(srv, rdata->type, rdata->rdclass); dns_name_init(&name, NULL); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/svcb_64.c bind9-9.20.15/lib/dns/rdata/in_1/svcb_64.c --- bind9-9.20.11/lib/dns/rdata/in_1/svcb_64.c 2025-07-04 09:42:08.410329937 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/svcb_64.c 2025-10-18 10:16:12.643733550 +0000 @@ -1013,9 +1013,7 @@ REQUIRE(svcb != NULL); REQUIRE(rdata->length != 0); - svcb->common.rdclass = rdata->rdclass; - svcb->common.rdtype = rdata->type; - ISC_LINK_INIT(&svcb->common, link); + DNS_RDATACOMMON_INIT(svcb, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); diff -Nru bind9-9.20.11/lib/dns/rdata/in_1/wks_11.c bind9-9.20.15/lib/dns/rdata/in_1/wks_11.c --- bind9-9.20.11/lib/dns/rdata/in_1/wks_11.c 2025-07-04 09:42:08.410329937 +0000 +++ bind9-9.20.15/lib/dns/rdata/in_1/wks_11.c 2025-10-18 10:16:12.643733550 +0000 @@ -305,9 +305,7 @@ REQUIRE(rdata->rdclass == dns_rdataclass_in); REQUIRE(rdata->length != 0); - wks->common.rdclass = rdata->rdclass; - wks->common.rdtype = rdata->type; - ISC_LINK_INIT(&wks->common, link); + DNS_RDATACOMMON_INIT(wks, rdata->type, rdata->rdclass); dns_rdata_toregion(rdata, ®ion); n = uint32_fromregion(®ion); diff -Nru bind9-9.20.11/lib/dns/rdataset.c bind9-9.20.15/lib/dns/rdataset.c --- bind9-9.20.11/lib/dns/rdataset.c 2025-07-04 09:42:08.411329960 +0000 +++ bind9-9.20.15/lib/dns/rdataset.c 2025-10-18 10:16:12.643733550 +0000 @@ -676,18 +676,3 @@ rdataset->ttl = ttl; sigrdataset->ttl = ttl; } - -bool -dns_rdataset_equals(const dns_rdataset_t *rdataset1, - const dns_rdataset_t *rdataset2) { - REQUIRE(DNS_RDATASET_VALID(rdataset1)); - REQUIRE(DNS_RDATASET_VALID(rdataset2)); - - if (rdataset1->methods->equals != NULL && - rdataset1->methods->equals == rdataset2->methods->equals) - { - return (rdataset1->methods->equals)(rdataset1, rdataset2); - } - - return false; -} diff -Nru bind9-9.20.11/lib/dns/rdataslab.c bind9-9.20.15/lib/dns/rdataslab.c --- bind9-9.20.11/lib/dns/rdataslab.c 2025-07-04 09:42:08.411329960 +0000 +++ bind9-9.20.15/lib/dns/rdataslab.c 2025-10-18 10:16:12.644733566 +0000 @@ -125,9 +125,6 @@ rdataset_setownercase(dns_rdataset_t *rdataset, const dns_name_t *name); static void rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name); -static bool -rdataset_equals(const dns_rdataset_t *rdataset1, - const dns_rdataset_t *rdataset2); /*% Note: the "const void *" are just to make qsort happy. */ static int @@ -1158,7 +1155,6 @@ .clearprefetch = rdataset_clearprefetch, .setownercase = rdataset_setownercase, .getownercase = rdataset_getownercase, - .equals = rdataset_equals, }; /* Fixed RRSet helper macros */ @@ -1477,18 +1473,3 @@ unlock: dns_db_unlocknode(header->db, header->node, isc_rwlocktype_read); } - -static bool -rdataset_equals(const dns_rdataset_t *rdataset1, - const dns_rdataset_t *rdataset2) { - if (rdataset1->rdclass != rdataset2->rdclass || - rdataset1->type != rdataset2->type) - { - return false; - } - - unsigned char *header1 = rdataset1->slab.raw - sizeof(dns_slabheader_t); - unsigned char *header2 = rdataset2->slab.raw - sizeof(dns_slabheader_t); - return dns_rdataslab_equalx(header1, header2, sizeof(dns_slabheader_t), - rdataset1->rdclass, rdataset2->type); -} diff -Nru bind9-9.20.11/lib/dns/request.c bind9-9.20.15/lib/dns/request.c --- bind9-9.20.11/lib/dns/request.c 2025-07-04 09:42:08.411329960 +0000 +++ bind9-9.20.15/lib/dns/request.c 2025-10-18 10:16:12.644733566 +0000 @@ -174,7 +174,7 @@ dns_request_t *request = NULL, *next = NULL; uint32_t tid = isc_tid(); - ISC_LIST_FOREACH_SAFE (requestmgr->requests[tid], request, link, next) { + ISC_LIST_FOREACH_SAFE(requestmgr->requests[tid], request, link, next) { req_log(ISC_LOG_DEBUG(3), "%s(%" PRIu32 ": request %p", __func__, tid, request); if (DNS_REQUEST_COMPLETE(request)) { diff -Nru bind9-9.20.11/lib/dns/resolver.c bind9-9.20.15/lib/dns/resolver.c --- bind9-9.20.11/lib/dns/resolver.c 2025-07-04 09:42:08.412329983 +0000 +++ bind9-9.20.15/lib/dns/resolver.c 2025-10-18 10:16:12.645733581 +0000 @@ -107,6 +107,14 @@ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), \ "fctx %p(%s): %s %s%u", fctx, fctx->info, (m1), (m2), \ (v)) +#define FCTXTRACEN(m1, name, res) \ + do { \ + if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) { \ + char dbuf[DNS_NAME_FORMATSIZE]; \ + dns_name_format((name), dbuf, sizeof(dbuf)); \ + FCTXTRACE4((m1), dbuf, (res)); \ + } \ + } while (0) #define FTRACE(m) \ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, \ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3), \ @@ -158,6 +166,7 @@ UNUSED(m2); \ UNUSED(v); \ } while (0) +#define FCTXTRACEN(m1, name, res) FCTXTRACE4(m1, name, res) #define FTRACE(m) \ do { \ UNUSED(m); \ @@ -234,9 +243,9 @@ #define NS_PROCESSING_LIMIT 20 STATIC_ASSERT(NS_PROCESSING_LIMIT > NS_RR_LIMIT, - "The maximum number of NS RRs processed for each delegation " - "(NS_PROCESSING_LIMIT) must be larger than the large delegation " - "threshold (NS_RR_LIMIT)."); + "The maximum number of NS RRs processed for each " + "delegation (NS_PROCESSING_LIMIT) must be larger than the large " + "delegation threshold (NS_RR_LIMIT)."); /* Hash table for zone counters */ #ifndef RES_DOMAIN_HASH_BITS @@ -806,6 +815,7 @@ bool get_nameservers; /* get a new NS rrset at * zone cut? */ bool resend; /* resend this query? */ + bool secured; /* message was signed or had a valid cookie */ bool nextitem; /* invalid response; keep * listening for the correct one */ bool truncated; /* response was truncated */ @@ -4265,13 +4275,20 @@ result = dns_view_findzonecut(res->view, fctx->name, fname, dcname, fctx->now, findoptions, true, true, &fctx->nameservers, NULL); + FCTXTRACEN("resume_qmin findzonecut", fname, result); /* * DNS_R_NXDOMAIN here means we have not loaded the root zone * mirror yet - but DNS_R_NXDOMAIN is not a valid return value * when doing recursion, we need to patch it. + * + * CNAME or DNAME means zone were added with that record + * after the start of a recursion. It means we do not have + * initialized correct hevent->foundname and have to fail. */ - if (result == DNS_R_NXDOMAIN) { + if (result == DNS_R_NXDOMAIN || result == DNS_R_CNAME || + result == DNS_R_DNAME) + { result = DNS_R_SERVFAIL; } @@ -5004,6 +5021,8 @@ /* This is the head resp; keep a pointer and move on */ if (hresp == NULL) { hresp = ISC_LIST_HEAD(fctx->resps); + FCTXTRACEN("clone_results", hresp->foundname, + hresp->result); continue; } @@ -5859,7 +5878,7 @@ bool have_answer = false; isc_result_t result, eresult = ISC_R_SUCCESS; dns_fetchresponse_t *resp = NULL; - unsigned int options; + unsigned int options = 0, equalok = 0; bool fail; unsigned int valoptions = 0; bool checknta = true; @@ -6071,6 +6090,7 @@ } if (!need_validation || !ANSWER(rdataset)) { options = 0; + equalok = 0; if (ANSWER(rdataset) && rdataset->type != dns_rdatatype_rrsig) { @@ -6096,10 +6116,23 @@ { options |= DNS_DBADD_FORCE; } + /* + * If we're validating and passing the added + * rdataset back to the caller, then we ask + * dns_db_addrdataset() to compare the old and + * new rdatasets whenever the result would + * normally have been DNS_R_UNCHANGED, and to + * return ISC_R_SUCCESS if they compare equal. + * This allows us to continue and cache RRSIGs + * in that case. + */ + if (!need_validation && ardataset != NULL) { + equalok = DNS_DBADD_EQUALOK; + } addedrdataset = ardataset; result = dns_db_addrdataset( fctx->cache, node, NULL, now, rdataset, - options, addedrdataset); + options | equalok, addedrdataset); if (result == DNS_R_UNCHANGED) { result = ISC_R_SUCCESS; if (!need_validation && @@ -6123,25 +6156,11 @@ DNS_R_NCACHENXRRSET; } continue; - } else if (!need_validation && - ardataset != NULL && - sigrdataset != NULL && - !dns_rdataset_equals( - rdataset, ardataset)) - { - /* - * The cache wasn't updated - * because something was - * already there. If the - * data was the same as what - * we were trying to add, - * then sigrdataset might - * still be useful, and we - * should carry on caching - * it. Otherwise, move on. - */ + } + if (equalok) { continue; } + result = ISC_R_SUCCESS; } if (result != ISC_R_SUCCESS) { break; @@ -6662,7 +6681,8 @@ * locally served zone. */ static inline bool -name_external(const dns_name_t *name, dns_rdatatype_t type, fetchctx_t *fctx) { +name_external(const dns_name_t *name, dns_rdatatype_t type, respctx_t *rctx) { + fetchctx_t *fctx = rctx->fctx; isc_result_t result; dns_forwarders_t *forwarders = NULL; dns_name_t *apex = NULL; @@ -6672,7 +6692,7 @@ dns_namereln_t rel; apex = (ISDUALSTACK(fctx->addrinfo) || !ISFORWARDER(fctx->addrinfo)) - ? fctx->domain + ? rctx->ns_name != NULL ? rctx->ns_name : fctx->domain : fctx->fwdname; /* @@ -6776,7 +6796,7 @@ result = dns_message_findname(rctx->query->rmessage, section, addname, dns_rdatatype_any, 0, &name, NULL); if (result == ISC_R_SUCCESS) { - external = name_external(name, type, fctx); + external = name_external(name, type, rctx); if (type == dns_rdatatype_a) { for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; @@ -7532,6 +7552,119 @@ isc_mem_putanddetach(&rctx->mctx, rctx, sizeof(*rctx)); } +static isc_result_t +rctx_cookiecheck(respctx_t *rctx) { + fetchctx_t *fctx = rctx->fctx; + resquery_t *query = rctx->query; + + /* + * If the message was secured or TCP is already in the + * retry flags, no need to continue. + */ + if (rctx->secured || (rctx->retryopts & DNS_FETCHOPT_TCP) != 0) { + return ISC_R_SUCCESS; + } + + /* + * If we've had a cookie from the same server previously, + * retry with TCP. This may be a misconfigured anycast server + * or an attempt to send a spoofed response. + */ + if (dns_adb_getcookie(query->addrinfo, NULL, 0) > CLIENT_COOKIE_SIZE) { + if (isc_log_wouldlog(dns_lctx, ISC_LOG_INFO)) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, + sizeof(addrbuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, + DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, + "missing expected cookie from %s", + addrbuf); + } + rctx->retryopts |= DNS_FETCHOPT_TCP; + rctx->resend = true; + rctx_done(rctx, ISC_R_SUCCESS); + return ISC_R_COMPLETE; + } + + /* + * Retry over TCP if require-cookie is true. + */ + if (fctx->res->view->peers != NULL) { + isc_result_t result; + dns_peer_t *peer = NULL; + bool required = false; + isc_netaddr_t netaddr; + + isc_netaddr_fromsockaddr(&netaddr, &query->addrinfo->sockaddr); + result = dns_peerlist_peerbyaddr(fctx->res->view->peers, + &netaddr, &peer); + if (result == ISC_R_SUCCESS) { + dns_peer_getrequirecookie(peer, &required); + } + if (!required) { + return ISC_R_SUCCESS; + } + + if (isc_log_wouldlog(dns_lctx, ISC_LOG_INFO)) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, + sizeof(addrbuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER, + DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, + "missing required cookie from %s", + addrbuf); + } + + rctx->retryopts |= DNS_FETCHOPT_TCP; + rctx->resend = true; + rctx_done(rctx, ISC_R_SUCCESS); + return ISC_R_COMPLETE; + } + + return ISC_R_SUCCESS; +} + +static bool +rctx_need_tcpretry(respctx_t *rctx) { + resquery_t *query = rctx->query; + if ((rctx->retryopts & DNS_FETCHOPT_TCP) != 0) { + /* TCP is already in the retry flags */ + return false; + } + + /* + * If the message was secured, no need to continue. + */ + if (rctx->secured) { + return false; + } + + /* + * Currently the only extra reason why we might need to + * retry a UDP response over TCP is a DNAME in the message. + */ + if (dns_message_hasdname(query->rmessage)) { + return true; + } + + return false; +} + +static isc_result_t +rctx_tcpretry(respctx_t *rctx) { + /* + * Do we need to retry a UDP response over TCP? + */ + if (rctx_need_tcpretry(rctx)) { + rctx->retryopts |= DNS_FETCHOPT_TCP; + rctx->resend = true; + rctx_done(rctx, ISC_R_SUCCESS); + return ISC_R_COMPLETE; + } + + return ISC_R_SUCCESS; +} + static void resquery_response_continue(void *arg, isc_result_t result) { respctx_t *rctx = arg; @@ -7550,81 +7683,41 @@ } /* + * Remember whether this message was signed or had a + * valid client cookie; if not, we may need to retry over + * TCP later. + */ + if (query->rmessage->cc_ok || query->rmessage->tsig != NULL || + query->rmessage->sig0 != NULL) + { + rctx->secured = true; + } + + /* * The dispatcher should ensure we only get responses with QR * set. */ INSIST((query->rmessage->flags & DNS_MESSAGEFLAG_QR) != 0); /* - * If we have had a server cookie and don't get one retry over - * TCP. This may be a misconfigured anycast server or an attempt - * to send a spoofed response. Additionally retry over TCP if - * require-cookie is true and we don't have a got client cookie. - * Skip if we have a valid TSIG. + * Check for cookie issues; if found, maybe retry over TCP. */ - if (dns_message_gettsig(query->rmessage, NULL) == NULL && - !query->rmessage->cc_ok && !query->rmessage->cc_bad && - (rctx->retryopts & DNS_FETCHOPT_TCP) == 0) - { - if (dns_adb_getcookie(query->addrinfo, NULL, 0) > - CLIENT_COOKIE_SIZE) - { - if (isc_log_wouldlog(dns_lctx, ISC_LOG_INFO)) { - char addrbuf[ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format(&query->addrinfo->sockaddr, - addrbuf, sizeof(addrbuf)); - isc_log_write( - dns_lctx, DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, - "missing expected cookie " - "from %s", - addrbuf); - } - rctx->retryopts |= DNS_FETCHOPT_TCP; - rctx->resend = true; - rctx_done(rctx, result); - goto cleanup; - } else if (fctx->res->view->peers != NULL) { - dns_peer_t *peer = NULL; - isc_netaddr_t netaddr; - isc_netaddr_fromsockaddr(&netaddr, - &query->addrinfo->sockaddr); - result = dns_peerlist_peerbyaddr(fctx->res->view->peers, - &netaddr, &peer); - if (result == ISC_R_SUCCESS) { - bool required = false; - result = dns_peer_getrequirecookie(peer, - &required); - if (result == ISC_R_SUCCESS && required) { - if (isc_log_wouldlog(dns_lctx, - ISC_LOG_INFO)) - { - char addrbuf - [ISC_SOCKADDR_FORMATSIZE]; - isc_sockaddr_format( - &query->addrinfo - ->sockaddr, - addrbuf, - sizeof(addrbuf)); - isc_log_write( - dns_lctx, - DNS_LOGCATEGORY_RESOLVER, - DNS_LOGMODULE_RESOLVER, - ISC_LOG_INFO, - "missing required " - "cookie " - "from %s", - addrbuf); - } - rctx->retryopts |= DNS_FETCHOPT_TCP; - rctx->resend = true; - rctx_done(rctx, result); - goto cleanup; - } - } - } + result = rctx_cookiecheck(rctx); + if (result == ISC_R_COMPLETE) { + goto cleanup; } + /* + * Check whether we need to retry over TCP for some other reason. + */ + result = rctx_tcpretry(rctx); + if (result == ISC_R_COMPLETE) { + goto cleanup; + } + + /* + * Check for EDNS issues. + */ rctx_edns(rctx); /* @@ -8356,8 +8449,8 @@ } /* - * Cache records in the authority section, if - * there are any suitable for caching. + * Cache records in the authority section, if there are + * any suitable for caching. */ rctx_authority_positive(rctx); @@ -8429,7 +8522,7 @@ /* * Don't accept DNAME from parent namespace. */ - if (name_external(name, dns_rdatatype_dname, fctx)) { + if (name_external(name, dns_rdatatype_dname, rctx)) { continue; } @@ -8730,14 +8823,14 @@ /* * rctx_authority_positive(): - * Examine the records in the authority section (if there are any) for a - * positive answer. We expect the names for all rdatasets in this - * section to be subdomains of the domain being queried; any that are - * not are skipped. We expect to find only *one* owner name; any names - * after the first one processed are ignored. We expect to find only - * rdatasets of type NS, RRSIG, or SIG; all others are ignored. Whatever - * remains can be cached at trust level authauthority or additional - * (depending on whether the AA bit was set on the answer). + * If a positive answer was received over TCP or secured with a cookie + * or TSIG, examine the authority section. We expect names for all + * rdatasets in this section to be subdomains of the domain being queried; + * any that are not are skipped. We expect to find only *one* owner name; + * any names after the first one processed are ignored. We expect to find + * only rdatasets of type NS; all others are ignored. Whatever remains can + * be cached at trust level authauthority or additional (depending on + * whether the AA bit was set on the answer). */ static void rctx_authority_positive(respctx_t *rctx) { @@ -8745,6 +8838,11 @@ bool done = false; isc_result_t result; + /* If it's spoofable, don't cache it. */ + if (!rctx->secured && (rctx->query->options & DNS_FETCHOPT_TCP) == 0) { + return; + } + result = dns_message_firstname(rctx->query->rmessage, DNS_SECTION_AUTHORITY); while (!done && result == ISC_R_SUCCESS) { @@ -8753,7 +8851,9 @@ dns_message_currentname(rctx->query->rmessage, DNS_SECTION_AUTHORITY, &name); - if (!name_external(name, dns_rdatatype_ns, fctx)) { + if (!name_external(name, dns_rdatatype_ns, rctx) && + dns_name_issubdomain(fctx->name, name)) + { dns_rdataset_t *rdataset = NULL; /* @@ -9018,11 +9118,10 @@ if (rctx->ns_name != NULL && name != rctx->ns_name) { - log_formerr(fctx, "multiple NS " - "RRsets " - "in " - "authority " - "section"); + log_formerr( + fctx, + "multiple NS RRsets in " + "authority section"); rctx->result = DNS_R_FORMERR; return ISC_R_COMPLETE; } @@ -9043,11 +9142,10 @@ if (rctx->soa_name != NULL && name != rctx->soa_name) { - log_formerr(fctx, "multiple " - "SOA RRs " - "in " - "authority " - "section"); + log_formerr( + fctx, + "multiple SOA RRs in " + "authority section"); rctx->result = DNS_R_FORMERR; return ISC_R_COMPLETE; } @@ -9197,8 +9295,8 @@ * one DS RRset. */ if (rctx->ns_name == NULL) { - log_formerr(fctx, "DS with no " - "referral"); + log_formerr(fctx, + "DS with no referral"); rctx->result = DNS_R_FORMERR; return ISC_R_COMPLETE; } @@ -9207,10 +9305,9 @@ if (rctx->ds_name != NULL && name != rctx->ds_name) { - log_formerr(fctx, "DS doesn't " - "match " - "referral " - "(NS)"); + log_formerr(fctx, + "DS doesn't match " + "referral (NS)"); rctx->result = DNS_R_FORMERR; return ISC_R_COMPLETE; } diff -Nru bind9-9.20.11/lib/dns/rpz.c bind9-9.20.15/lib/dns/rpz.c --- bind9-9.20.11/lib/dns/rpz.c 2025-07-04 09:42:08.413330007 +0000 +++ bind9-9.20.15/lib/dns/rpz.c 2025-10-18 10:16:12.646733597 +0000 @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -867,7 +868,7 @@ dns_fixedname_t ip_name2f; dns_name_t ip_name; const char *prefix_str = NULL, *cp = NULL, *end = NULL; - char *cp2; + char *prefix_end, *cp2; int ip_labels; dns_rpz_prefix_t prefix; unsigned long prefix_num, l; @@ -905,12 +906,9 @@ ""); return ISC_R_FAILURE; } - /* - * Patch in trailing nul character to print just the length - * label (for various cases below). - */ - *cp2 = '\0'; + prefix_end = cp2; if (prefix_num < 1U || prefix_num > 128U) { + *prefix_end = '\0'; badname(log_level, src_name, "; invalid prefix length of ", prefix_str); return ISC_R_FAILURE; @@ -923,6 +921,7 @@ * from the form "prefix.z.y.x.w" */ if (prefix_num > 32U) { + *prefix_end = '\0'; badname(log_level, src_name, "; invalid IPv4 prefix length of ", prefix_str); return ISC_R_FAILURE; @@ -1001,6 +1000,7 @@ i = prefix % DNS_RPZ_CIDR_WORD_BITS; aword = tgt_ip->w[prefix / DNS_RPZ_CIDR_WORD_BITS]; if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) { + *prefix_end = '\0'; badname(log_level, src_name, "; too small prefix length of ", prefix_str); return ISC_R_FAILURE; @@ -1499,7 +1499,8 @@ */ isc_result_t dns_rpz_new_zones(dns_view_t *view, isc_loopmgr_t *loopmgr, char *rps_cstr, - size_t rps_cstr_size, dns_rpz_zones_t **rpzsp) { + size_t rps_cstr_size, dns_rpz_zones_t **rpzsp, + bool first_time) { dns_rpz_zones_t *rpzs = NULL; isc_mem_t *mctx = NULL; #ifdef USE_DNSRPS @@ -1517,6 +1518,7 @@ .rps_cstr_size = rps_cstr_size, .loopmgr = loopmgr, .magic = DNS_RPZ_ZONES_MAGIC, + .first_time = first_time, }; isc_rwlock_init(&rpzs->search_lock); @@ -1668,7 +1670,19 @@ REQUIRE(DNS_DB_VALID(db)); REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); + LOCK(&rpz->rpzs->maint_lock); dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback, rpz); + if (rpz->processed) { + rpz->processed = false; + INSIST(atomic_fetch_sub_acq_rel(&rpz->rpzs->zones_processed, + 1) > 0); + } + if (rpz->dbregistered) { + rpz->dbregistered = false; + INSIST(atomic_fetch_sub_acq_rel(&rpz->rpzs->zones_registered, + 1) > 0); + } + UNLOCK(&rpz->rpzs->maint_lock); } void @@ -1676,8 +1690,15 @@ REQUIRE(DNS_DB_VALID(db)); REQUIRE(DNS_RPZ_ZONE_VALID(rpz)); + LOCK(&rpz->rpzs->maint_lock); + if (!rpz->dbregistered) { + rpz->dbregistered = true; + atomic_fetch_add_acq_rel(&rpz->rpzs->zones_registered, 1); + } dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback, rpz); + UNLOCK(&rpz->rpzs->maint_lock); } + static void dns__rpz_timer_start(dns_rpz_zone_t *rpz) { uint64_t tdiff; @@ -1742,6 +1763,11 @@ dns_db_closeversion(rpz->updb, &rpz->updbversion, false); dns_db_detach(&rpz->updb); + if (rpz->dbregistered && !rpz->processed) { + rpz->processed = true; + atomic_fetch_add_acq_rel(&rpz->rpzs->zones_processed, 1); + } + UNLOCK(&rpz->rpzs->maint_lock); isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER, @@ -1758,6 +1784,7 @@ dns_name_t *name = NULL; dns_fixedname_t fixname; char domain[DNS_NAME_FORMATSIZE]; + bool slow_mode; dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE); @@ -1781,6 +1808,10 @@ goto cleanup; } + LOCK(&rpz->rpzs->maint_lock); + slow_mode = rpz->rpzs->p.slow_mode; + UNLOCK(&rpz->rpzs->maint_lock); + while (result == ISC_R_SUCCESS) { char namebuf[DNS_NAME_FORMATSIZE]; dns_rdatasetiter_t *rdsiter = NULL; @@ -1881,6 +1912,10 @@ next: result = dns_dbiterator_next(updbit); + + if (slow_mode) { + uv_sleep(100); + } } INSIST(result != ISC_R_SUCCESS); if (result == ISC_R_NOMORE) { diff -Nru bind9-9.20.11/lib/dns/tkey.c bind9-9.20.15/lib/dns/tkey.c --- bind9-9.20.11/lib/dns/tkey.c 2025-07-04 09:42:08.415330054 +0000 +++ bind9-9.20.15/lib/dns/tkey.c 2025-10-18 10:16:12.647733612 +0000 @@ -101,12 +101,6 @@ *tctxp = NULL; mctx = tctx->mctx; - if (tctx->domain != NULL) { - if (dns_name_dynamic(tctx->domain)) { - dns_name_free(tctx->domain, mctx); - } - isc_mem_put(mctx, tctx->domain, sizeof(dns_name_t)); - } if (tctx->gssapi_keytab != NULL) { isc_mem_free(mctx, tctx->gssapi_keytab); } @@ -441,21 +435,6 @@ ring)); break; case DNS_TKEYMODE_GSSAPI: - /* - * For non-delete operations we do this: - * - * if (qname != ".") - * keyname = qname + defaultdomain - * else - * keyname = + defaultdomain - */ - if (tctx->domain == NULL && tkeyin.mode != DNS_TKEYMODE_GSSAPI) - { - tkey_log("dns_tkey_processquery: tkey-domain not set"); - result = DNS_R_REFUSED; - goto failure; - } - keyname = dns_fixedname_initname(&fkeyname); if (!dns_name_equal(qname, dns_rootname)) { diff -Nru bind9-9.20.11/lib/dns/validator.c bind9-9.20.15/lib/dns/validator.c --- bind9-9.20.11/lib/dns/validator.c 2025-07-04 09:42:08.416330077 +0000 +++ bind9-9.20.15/lib/dns/validator.c 2025-10-18 10:16:12.649733644 +0000 @@ -378,6 +378,12 @@ static void resume_answer_with_key_done(void *arg); +static bool +over_max_fails(dns_validator_t *val); + +static void +consume_validation_fail(dns_validator_t *val); + static void resume_answer_with_key(void *arg) { dns_validator_t *val = arg; @@ -386,6 +392,13 @@ isc_result_t result = select_signing_key(val, rdataset); if (result == ISC_R_SUCCESS) { val->keyset = &val->frdataset; + } else if (result != ISC_R_NOTFOUND) { + val->result = result; + if (over_max_fails(val)) { + INSIST(val->key == NULL); + val->result = ISC_R_QUOTA; + } + consume_validation_fail(val); } (void)validate_async_run(val, resume_answer_with_key_done); @@ -395,6 +408,16 @@ resume_answer_with_key_done(void *arg) { dns_validator_t *val = arg; + switch (val->result) { + case ISC_R_CANCELED: /* Validation was canceled */ + case ISC_R_SHUTTINGDOWN: /* Server shutting down */ + case ISC_R_QUOTA: /* Validation fails quota reached */ + dns_validator_cancel(val); + break; + default: + break; + } + resume_answer(val); } @@ -1070,6 +1093,8 @@ goto done; } dst_key_free(&val->key); + } else { + break; } dns_rdata_reset(&rdata); result = dns_rdataset_next(rdataset); @@ -1309,6 +1334,7 @@ dns_name_t *name = val->name; isc_result_t result; isc_mem_t *mctx = val->view->mctx; + bool match = false; if (rdataset->type != dns_rdatatype_dnskey) { return DNS_R_NOKEYMATCH; @@ -1349,17 +1375,16 @@ /* * If the REVOKE bit is not set we have a - * theoretically self signed DNSKEY RRset. - * This will be verified later. + * theoretically self-signed DNSKEY RRset; + * this will be verified later. + * + * We don't return the answer yet, though, + * because we need to check the remaining keys + * and possbly remove them if they're revoked. */ if ((key.flags & DNS_KEYFLAG_REVOKE) == 0) { - return ISC_R_SUCCESS; - } - - result = dns_dnssec_keyfromrdata(name, &keyrdata, mctx, - &dstkey); - if (result != ISC_R_SUCCESS) { - continue; + match = true; + break; } /* @@ -1369,6 +1394,20 @@ if (DNS_TRUST_PENDING(rdataset->trust) && dns_view_istrusted(val->view, name, &key)) { + result = dns_dnssec_keyfromrdata( + name, &keyrdata, mctx, &dstkey); + if (result == DST_R_UNSUPPORTEDALG) { + /* don't count towards max fails */ + break; /* continue with next key */ + } else if (result != ISC_R_SUCCESS) { + consume_validation(val); + if (over_max_fails(val)) { + return ISC_R_QUOTA; + } + consume_validation_fail(val); + break; /* continue with next key */ + } + if (over_max_validations(val)) { dst_key_free(&dstkey); return ISC_R_QUOTA; @@ -1402,6 +1441,8 @@ } consume_validation_fail(val); } + + dst_key_free(&dstkey); } else if (rdataset->trust >= dns_trust_secure) { /* * We trust this RRset so if the key is @@ -1409,12 +1450,14 @@ */ dns_view_untrust(val->view, name, &key); } - - dst_key_free(&dstkey); } } - return DNS_R_NOKEYMATCH; + if (!match) { + return DNS_R_NOKEYMATCH; + } + + return ISC_R_SUCCESS; } /*% @@ -1599,7 +1642,7 @@ static void validate_answer_signing_key(void *arg) { dns_validator_t *val = arg; - isc_result_t result = ISC_R_NOTFOUND; + isc_result_t result; if (CANCELED(val) || CANCELING(val)) { val->result = ISC_R_CANCELED; @@ -1622,15 +1665,21 @@ default: /* Select next signing key */ result = select_signing_key(val, val->keyset); + if (result == ISC_R_SUCCESS) { + INSIST(val->key != NULL); + } else if (result == ISC_R_NOTFOUND) { + INSIST(val->key == NULL); + } else { + val->result = result; + if (over_max_fails(val)) { + INSIST(val->key == NULL); + val->result = ISC_R_QUOTA; + } + consume_validation_fail(val); + } break; } - if (result == ISC_R_SUCCESS) { - INSIST(val->key != NULL); - } else { - INSIST(val->key == NULL); - } - (void)validate_async_run(val, validate_answer_signing_key_done); } @@ -1679,7 +1728,8 @@ * At this point we could check that the signature algorithm * was known and "sufficiently good". */ - if (!dns_resolver_algorithm_supported(val->view->resolver, val->name, + if (!dns_resolver_algorithm_supported(val->view->resolver, + &val->siginfo->signer, val->siginfo->algorithm)) { if (val->unsupported_algorithm == 0) { @@ -1875,14 +1925,15 @@ dns_rdata_rrsig_t sig; dst_key_t *dstkey = NULL; isc_result_t result; + dns_rdataset_t rdataset = DNS_RDATASET_INIT; + dns_rdataset_clone(val->sigrdataset, &rdataset); - for (result = dns_rdataset_first(val->sigrdataset); - result == ISC_R_SUCCESS; - result = dns_rdataset_next(val->sigrdataset)) + for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) { dns_rdata_t rdata = DNS_RDATA_INIT; - dns_rdataset_current(val->sigrdataset, &rdata); + dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (keyid != sig.keyid || algorithm != sig.algorithm) { @@ -1892,10 +1943,7 @@ result = dns_dnssec_keyfromrdata( val->name, keyrdata, val->view->mctx, &dstkey); if (result != ISC_R_SUCCESS) { - /* - * This really shouldn't happen, but... - */ - continue; + return result; } } result = verify(val, dstkey, &rdata, sig.keyid); @@ -1907,6 +1955,7 @@ if (dstkey != NULL) { dst_key_free(&dstkey); } + dns_rdataset_disassociate(&rdataset); return result; } diff -Nru bind9-9.20.11/lib/dns/zone.c bind9-9.20.15/lib/dns/zone.c --- bind9-9.20.11/lib/dns/zone.c 2025-07-04 09:42:08.419330147 +0000 +++ bind9-9.20.15/lib/dns/zone.c 2025-10-18 10:16:12.652733690 +0000 @@ -750,6 +750,7 @@ dns_secalg_t algorithm; uint16_t keyid; bool deleteit; + bool fullsign; bool done; ISC_LINK(dns_signing_t) link; }; @@ -992,7 +993,7 @@ dump_done(void *arg, isc_result_t result); static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, - bool deleteit); + bool deleteit, bool fullsign); static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, dns_diff_t *diff); @@ -3201,18 +3202,18 @@ dns_rdata_mx_t mx; dns_rdata_ns_t ns; dns_rdata_in_srv_t srv; - dns_rdata_t rdata; dns_name_t *name; dns_name_t *bottom; isc_result_t result; bool ok = true, have_spf, have_txt; int level; char namebuf[DNS_NAME_FORMATSIZE]; + bool logged_algorithm[DST_MAX_ALGS]; + bool logged_digest_type[DNS_DSDIGEST_MAX + 1]; name = dns_fixedname_initname(&fixed); bottom = dns_fixedname_initname(&fixedbottom); dns_rdataset_init(&rdataset); - dns_rdata_init(&rdata); result = dns_db_createiterator(db, 0, &dbiterator); if (result != ISC_R_SUCCESS) { @@ -3239,6 +3240,55 @@ dns_dbiterator_pause(dbiterator); /* + * Check for deprecated KEY algorithms + */ + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_key, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) { + goto checkforns; + } + + memset(logged_algorithm, 0, sizeof(logged_algorithm)); + for (result = dns_rdataset_first(&rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) + { + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdata_key_t key; + dns_rdataset_current(&rdataset, &rdata); + + result = dns_rdata_tostruct(&rdata, &key, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + + /* + * If we ever deprecate a private algorithm use + * dst_algorithm_fromdata() here. + */ + switch (key.algorithm) { + case DNS_KEYALG_RSASHA1: + case DNS_KEYALG_NSEC3RSASHA1: + if (!logged_algorithm[key.algorithm]) { + char algbuf[DNS_SECALG_FORMATSIZE]; + dns_name_format(name, namebuf, + sizeof(namebuf)); + dns_secalg_format(key.algorithm, algbuf, + sizeof(algbuf)); + dnssec_log(zone, ISC_LOG_WARNING, + "%s/KEY deprecated " + "algorithm %u (%s)", + namebuf, key.algorithm, + algbuf); + logged_algorithm[key.algorithm] = true; + } + break; + default: + break; + } + } + dns_rdataset_disassociate(&rdataset); + + checkforns: + /* * Don't check the NS records at the origin. */ if (dns_name_equal(name, &zone->origin)) { @@ -3250,6 +3300,7 @@ if (result != ISC_R_SUCCESS) { goto checkfords; } + /* * Remember bottom of zone due to NS. */ @@ -3257,6 +3308,7 @@ result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { + dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &ns, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); @@ -3267,6 +3319,74 @@ result = dns_rdataset_next(&rdataset); } dns_rdataset_disassociate(&rdataset); + + /* + * Check for deprecated DS digest types. + */ + result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, + 0, 0, &rdataset, NULL); + if (result != ISC_R_SUCCESS) { + goto next; + } + + memset(logged_algorithm, 0, sizeof(logged_algorithm)); + memset(logged_digest_type, 0, sizeof(logged_digest_type)); + for (result = dns_rdataset_first(&rdataset); + result == ISC_R_SUCCESS; + result = dns_rdataset_next(&rdataset)) + { + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_rdataset_current(&rdataset, &rdata); + dns_rdata_ds_t ds; + + result = dns_rdata_tostruct(&rdata, &ds, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + switch (ds.digest_type) { + case DNS_DSDIGEST_SHA1: + case DNS_DSDIGEST_GOST: + if (!logged_digest_type[ds.digest_type]) { + char algbuf[DNS_DSDIGEST_FORMATSIZE]; + dns_name_format(name, namebuf, + sizeof(namebuf)); + dns_dsdigest_format(ds.digest_type, + algbuf, + sizeof(algbuf)); + dnssec_log(zone, ISC_LOG_WARNING, + "%s/DS deprecated digest " + "type %u (%s)", + namebuf, ds.digest_type, + algbuf); + logged_digest_type[ds.digest_type] = + true; + } + break; + } + + /* + * If we ever deprecate a private algorithm use + * dst_algorithm_fromdata() here. + */ + switch (ds.algorithm) { + case DNS_KEYALG_RSASHA1: + case DNS_KEYALG_NSEC3RSASHA1: + if (!logged_algorithm[ds.algorithm]) { + char algbuf[DNS_SECALG_FORMATSIZE]; + dns_name_format(name, namebuf, + sizeof(namebuf)); + dns_secalg_format(ds.algorithm, algbuf, + sizeof(algbuf)); + dnssec_log(zone, ISC_LOG_WARNING, + "%s/DS deprecated algorithm " + "%u (%s)", + namebuf, ds.algorithm, + algbuf); + logged_algorithm[ds.algorithm] = true; + } + break; + } + } + dns_rdataset_disassociate(&rdataset); + goto next; checkfords: @@ -3306,6 +3426,7 @@ } result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { + dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &mx, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); @@ -3328,6 +3449,7 @@ } result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { + dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &srv, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); @@ -3364,6 +3486,7 @@ } result = dns_rdataset_first(&rdataset); while (result == ISC_R_SUCCESS) { + dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); have_txt = isspf(&rdata); dns_rdata_reset(&rdata); @@ -3408,9 +3531,10 @@ dns_dbnode_t *node = NULL; dns_dbversion_t *version = NULL; dns_rdata_dnskey_t dnskey; - dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_t rdataset; isc_result_t result; + bool logged_algorithm[DST_MAX_ALGS] = { 0 }; + bool alldeprecated = true; result = dns_db_findnode(db, &zone->origin, false, &node); if (result != ISC_R_SUCCESS) { @@ -3428,6 +3552,8 @@ for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&rdataset)) { + char algbuf[DNS_SECALG_FORMATSIZE]; + dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdataset_current(&rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &dnskey, NULL); INSIST(result == ISC_R_SUCCESS); @@ -3469,10 +3595,36 @@ algorithm, dnskey.algorithm, dst_region_computeid(&r)); } - dns_rdata_reset(&rdata); + + switch (dnskey.algorithm) { + case DNS_KEYALG_RSAMD5: + case DNS_KEYALG_DSA: + case DNS_KEYALG_RSASHA1: + case DNS_KEYALG_NSEC3DSA: + case DNS_KEYALG_NSEC3RSASHA1: + case DNS_KEYALG_ECCGOST: + if (!logged_algorithm[dnskey.algorithm]) { + dns_secalg_format(dnskey.algorithm, algbuf, + sizeof(algbuf)); + dnssec_log(zone, ISC_LOG_WARNING, + "deprecated DNSKEY algorithm found: " + "%u (%s)\n", + dnskey.algorithm, algbuf); + logged_algorithm[dnskey.algorithm] = true; + } + break; + default: + alldeprecated = false; + break; + } } dns_rdataset_disassociate(&rdataset); + if (alldeprecated) { + dnssec_log(zone, ISC_LOG_WARNING, + "all DNSKEY algorithms found are deprecated"); + } + cleanup: if (node != NULL) { dns_db_detachnode(db, &node); @@ -3527,7 +3679,7 @@ result = zone_signwithkey(zone, rdata.data[0], (rdata.data[1] << 8) | rdata.data[2], - rdata.data[3]); + rdata.data[3], false); if (result != ISC_R_SUCCESS) { dnssec_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: %s", @@ -7354,7 +7506,7 @@ static bool signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rdatatype_t type, - dst_key_t *key) { + dst_key_t *key, bool fullsign) { isc_result_t result; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; @@ -7387,7 +7539,7 @@ dns_rdata_reset(&rdata); } - if (zone->kasp != NULL) { + if (zone->kasp != NULL && !fullsign) { dns_kasp_key_t *kkey; int zsk_count = 0; bool approved; @@ -7499,8 +7651,9 @@ dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3, bool build_nsec, dst_key_t *key, isc_stdtime_t now, isc_stdtime_t inception, isc_stdtime_t expire, dns_ttl_t nsecttl, - bool both, bool is_ksk, bool is_zsk, bool is_bottom_of_zone, - dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx) { + bool both, bool is_ksk, bool is_zsk, bool fullsign, + bool is_bottom_of_zone, dns_diff_t *diff, int32_t *signatures, + isc_mem_t *mctx) { isc_result_t result; dns_rdatasetiter_t *iterator = NULL; dns_rdataset_t rdataset; @@ -7611,7 +7764,7 @@ goto next_rdataset; } if (signed_with_good_key(zone, db, node, version, rdataset.type, - key)) + key, fullsign)) { goto next_rdataset; } @@ -9665,8 +9818,8 @@ db, zone, name, node, version, build_nsec3, build_nsec, zone_keys[i], now, inception, expire, zone_nsecttl(zone), both, is_ksk, - is_zsk, is_bottom_of_zone, zonediff.diff, - &signatures, zone->mctx)); + is_zsk, signing->fullsign, is_bottom_of_zone, + zonediff.diff, &signatures, zone->mctx)); /* * If we are adding we are done. Look for other keys * of the same algorithm if deleting. @@ -20261,22 +20414,6 @@ UNLOCK_ZONE(zone); } -isc_result_t -dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, - bool deleteit) { - isc_result_t result; - REQUIRE(DNS_ZONE_VALID(zone)); - - dnssec_log(zone, ISC_LOG_NOTICE, - "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm, - keyid); - LOCK_ZONE(zone); - result = zone_signwithkey(zone, algorithm, keyid, deleteit); - UNLOCK_ZONE(zone); - - return result; -} - /* * Called when a dynamic update for an NSEC3PARAM record is received. * @@ -20348,7 +20485,7 @@ static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid, - bool deleteit) { + bool deleteit, bool fullsign) { dns_signing_t *signing; dns_signing_t *current; isc_result_t result = ISC_R_SUCCESS; @@ -20363,6 +20500,7 @@ signing->algorithm = algorithm; signing->keyid = keyid; signing->deleteit = deleteit; + signing->fullsign = fullsign; signing->done = false; now = isc_time_now(); @@ -20437,7 +20575,7 @@ now = *timep; - for (i = 0; i <= DST_MAX_TIMES; i++) { + for (i = 0; i < DST_MAX_TIMES; i++) { result = dst_key_gettime(key, i, &event); if (result == ISC_R_SUCCESS && event > now && (then == 0 || event < then)) @@ -21210,7 +21348,7 @@ /* Rekey after checkds. */ if (rekey) { - dns_zone_rekey(zone, false); + dns_zone_rekey(zone, false, false); } failure: @@ -22275,6 +22413,8 @@ bool newalg = false; bool fullsign; bool offlineksk = false; + bool kasp_change = false; + uint8_t options = 0; uint32_t sigval = 0; dns_ttl_t ttl = 3600; const char *dir = NULL; @@ -22413,6 +22553,17 @@ * fully signed now. */ fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN); + if (fullsign) { + options |= DNS_KEYMGRATTR_FULLSIGN; + } + + /* + * True when called from "rndc dnssec -step". Indicates the zone + * is allowed to do the next step(s) in the keymgr process. + */ + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FORCEKEYMGR)) { + options |= DNS_KEYMGRATTR_FORCESTEP; + } if (offlineksk) { /* Lookup the correct bundle in the SKR. */ @@ -22519,10 +22670,14 @@ dns_zone_lock_keyfiles(zone); result = dns_keymgr_run(&zone->origin, zone->rdclass, mctx, &keys, &dnskeys, dir, - kasp, now, &nexttime); + kasp, options, now, &nexttime); dns_zone_unlock_keyfiles(zone); - if (result != ISC_R_SUCCESS) { + if (result == ISC_R_SUCCESS) { + kasp_change = true; + } else if (result == DNS_R_UNCHANGED) { + result = ISC_R_SUCCESS; + } else { dnssec_log(zone, ISC_LOG_ERROR, "zone_rekey:dns_keymgr_run " "failed: %s", @@ -22750,7 +22905,7 @@ "allowed"); } - if (newactive || fullsign || sane_diff) { + if (newactive || fullsign || sane_diff || kasp_change) { CHECK(dns_diff_apply(&diff, db, ver)); CHECK(clean_nsec3param(zone, db, ver, &diff)); CHECK(add_signing_records(db, zone->privatetype, ver, @@ -22787,7 +22942,7 @@ { result = zone_signwithkey( zone, dst_key_alg(key->key), - dst_key_id(key->key), true); + dst_key_id(key->key), true, false); if (result != ISC_R_SUCCESS) { dnssec_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: " @@ -22827,7 +22982,7 @@ result = zone_signwithkey( zone, dst_key_alg(key->key), - dst_key_id(key->key), false); + dst_key_id(key->key), false, true); if (result != ISC_R_SUCCESS) { dnssec_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: " @@ -22835,6 +22990,26 @@ isc_result_totext(result)); } } + /* + * ...and remove signatures for all inactive keys. + */ + ISC_LIST_FOREACH(dnskeys, key, link) { + if (!key->force_sign && !key->hint_sign) { + result = zone_signwithkey( + zone, dst_key_alg(key->key), + dst_key_id(key->key), true, + false); + if (result != ISC_R_SUCCESS) { + dnssec_log(zone, ISC_LOG_ERROR, + "zone_signwithkey " + "failed: " + "%s", + isc_result_totext( + result)); + } + } + } + } else if (newalg) { /* * We haven't been told to sign fully, but a new @@ -22851,7 +23026,7 @@ result = zone_signwithkey( zone, dst_key_alg(key->key), - dst_key_id(key->key), false); + dst_key_id(key->key), false, false); if (result != ISC_R_SUCCESS) { dnssec_log(zone, ISC_LOG_ERROR, "zone_signwithkey failed: " @@ -23026,6 +23201,13 @@ 0); isc_time_nowplusinterval(&zone->refreshkeytime, &ival); } + + /* + * Clear forcekeymgr flag, if it was set, so we don't do + * another force next time. + */ + DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_FORCEKEYMGR); + UNLOCK_ZONE(zone); dns_diff_clear(&diff); @@ -23064,7 +23246,7 @@ } void -dns_zone_rekey(dns_zone_t *zone, bool fullsign) { +dns_zone_rekey(dns_zone_t *zone, bool fullsign, bool forcekeymgr) { isc_time_t now; if (zone->type == dns_zone_primary && zone->loop != NULL) { @@ -23073,6 +23255,9 @@ if (fullsign) { DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN); } + if (forcekeymgr) { + DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_FORCEKEYMGR); + } now = isc_time_now(); zone->refreshkeytime = now; @@ -23155,6 +23340,7 @@ * record which must be by itself. */ if (dns_rdataset_isassociated(&cds)) { + bool logged_digest_type[DNS_DSDIGEST_MAX + 1] = { 0 }; bool delete = false; memset(algorithms, notexpected, sizeof(algorithms)); for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS; @@ -23182,6 +23368,30 @@ } CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL)); + + /* + * Log deprecated CDS digest types. + */ + switch (structcds.digest_type) { + case DNS_DSDIGEST_SHA1: + case DNS_DSDIGEST_GOST: + if (!logged_digest_type[structcds.digest_type]) + { + char algbuf[DNS_DSDIGEST_FORMATSIZE]; + dns_dsdigest_format( + structcds.digest_type, algbuf, + sizeof(algbuf)); + dnssec_log(zone, ISC_LOG_WARNING, + "deprecated CDS digest type " + "%u (%s)", + structcds.digest_type, + algbuf); + logged_digest_type[structcds.digest_type] = + true; + } + break; + } + if (algorithms[structcds.algorithm] == 0) { algorithms[structcds.algorithm] = expected; } diff -Nru bind9-9.20.11/lib/isc/Makefile.am bind9-9.20.15/lib/isc/Makefile.am --- bind9-9.20.11/lib/isc/Makefile.am 2025-07-04 09:42:08.419330147 +0000 +++ bind9-9.20.15/lib/isc/Makefile.am 2025-10-18 10:16:12.652733690 +0000 @@ -21,7 +21,6 @@ include/isc/dir.h \ include/isc/dnsstream.h \ include/isc/endian.h \ - include/isc/entropy.h \ include/isc/errno.h \ include/isc/error.h \ include/isc/file.h \ @@ -127,7 +126,6 @@ counter.c \ crc64.c \ dir.c \ - entropy.c \ errno.c \ errno2result.c \ errno2result.h \ @@ -165,7 +163,6 @@ net.c \ netaddr.c \ netscope.c \ - nonce.c \ openssl_shim.c \ openssl_shim.h \ os.c \ diff -Nru bind9-9.20.11/lib/isc/Makefile.in bind9-9.20.15/lib/isc/Makefile.in --- bind9-9.20.11/lib/isc/Makefile.in 2025-07-04 09:43:11.509818454 +0000 +++ bind9-9.20.15/lib/isc/Makefile.in 2025-10-18 10:17:04.723505273 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -77,6 +77,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -175,10 +177,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libisc_ladir)" LTLIBRARIES = $(lib_LTLIBRARIES) @@ -199,13 +200,12 @@ include/isc/commandline.h include/isc/condition.h \ include/isc/counter.h include/isc/crc64.h include/isc/dir.h \ include/isc/dnsstream.h include/isc/endian.h \ - include/isc/entropy.h include/isc/errno.h include/isc/error.h \ - include/isc/file.h include/isc/fips.h \ - include/isc/formatcheck.h include/isc/fuzz.h \ - include/isc/getaddresses.h include/isc/hash.h \ - include/isc/hashmap.h include/isc/heap.h include/isc/helper.h \ - include/isc/hex.h include/isc/histo.h include/isc/hmac.h \ - include/isc/ht.h include/isc/httpd.h \ + include/isc/errno.h include/isc/error.h include/isc/file.h \ + include/isc/fips.h include/isc/formatcheck.h \ + include/isc/fuzz.h include/isc/getaddresses.h \ + include/isc/hash.h include/isc/hashmap.h include/isc/heap.h \ + include/isc/helper.h include/isc/hex.h include/isc/histo.h \ + include/isc/hmac.h include/isc/ht.h include/isc/httpd.h \ include/isc/interfaceiter.h include/isc/iterated_hash.h \ include/isc/job.h include/isc/lang.h include/isc/lex.h \ include/isc/list.h include/isc/log.h include/isc/loop.h \ @@ -234,20 +234,19 @@ netmgr/socket.c netmgr/streamdns.c netmgr/tcp.c netmgr/timer.c \ netmgr/tlsstream.c netmgr/udp.c ascii.c assertions.c async.c \ async_p.h backtrace.c base32.c base64.c commandline.c \ - condition.c counter.c crc64.c dir.c entropy.c errno.c \ - errno2result.c errno2result.h error.c file.c fips.c \ - getaddresses.c hash.c hashmap.c heap.c helper.c hex.c histo.c \ - hmac.c ht.c httpd.c interfaceiter.c iterated_hash.c \ - jemalloc_shim.h job.c job_p.h lex.c lib.c log.c loop.c \ - loop_p.h managers.c md.c mem.c mem_p.h meminfo.c mutex.c \ - mutex_p.h mutexblock.c net.c netaddr.c netscope.c nonce.c \ - openssl_shim.c openssl_shim.h os.c os_p.h parseint.c \ - picohttpparser.c picohttpparser.h portset.c probes.d proxy2.c \ - quota.c radix.c random.c ratelimiter.c regex.c region.c \ - result.c safe.c serial.c signal.c sockaddr.c stats.c stdio.c \ - stdtime.c string.c symtab.c syslog.c thread.c tid.c time.c \ - timer.c tls.c tm.c url.c utf8.c uv.c xml.c work.c rwlock.c \ - netmgr/http.c + condition.c counter.c crc64.c dir.c errno.c errno2result.c \ + errno2result.h error.c file.c fips.c getaddresses.c hash.c \ + hashmap.c heap.c helper.c hex.c histo.c hmac.c ht.c httpd.c \ + interfaceiter.c iterated_hash.c jemalloc_shim.h job.c job_p.h \ + lex.c lib.c log.c loop.c loop_p.h managers.c md.c mem.c \ + mem_p.h meminfo.c mutex.c mutex_p.h mutexblock.c net.c \ + netaddr.c netscope.c openssl_shim.c openssl_shim.h os.c os_p.h \ + parseint.c picohttpparser.c picohttpparser.h portset.c \ + probes.d proxy2.c quota.c radix.c random.c ratelimiter.c \ + regex.c region.c result.c safe.c serial.c signal.c sockaddr.c \ + stats.c stdio.c stdtime.c string.c symtab.c syslog.c thread.c \ + tid.c time.c timer.c tls.c tm.c url.c utf8.c uv.c xml.c work.c \ + rwlock.c netmgr/http.c am__objects_1 = am__dirstamp = $(am__leading_dot)dirstamp @USE_ISC_RWLOCK_TRUE@am__objects_2 = libisc_la-rwlock.lo @@ -261,9 +260,9 @@ libisc_la-backtrace.lo libisc_la-base32.lo libisc_la-base64.lo \ libisc_la-commandline.lo libisc_la-condition.lo \ libisc_la-counter.lo libisc_la-crc64.lo libisc_la-dir.lo \ - libisc_la-entropy.lo libisc_la-errno.lo \ - libisc_la-errno2result.lo libisc_la-error.lo libisc_la-file.lo \ - libisc_la-fips.lo libisc_la-getaddresses.lo libisc_la-hash.lo \ + libisc_la-errno.lo libisc_la-errno2result.lo \ + libisc_la-error.lo libisc_la-file.lo libisc_la-fips.lo \ + libisc_la-getaddresses.lo libisc_la-hash.lo \ libisc_la-hashmap.lo libisc_la-heap.lo libisc_la-helper.lo \ libisc_la-hex.lo libisc_la-histo.lo libisc_la-hmac.lo \ libisc_la-ht.lo libisc_la-httpd.lo libisc_la-interfaceiter.lo \ @@ -272,21 +271,20 @@ libisc_la-managers.lo libisc_la-md.lo libisc_la-mem.lo \ libisc_la-meminfo.lo libisc_la-mutex.lo \ libisc_la-mutexblock.lo libisc_la-net.lo libisc_la-netaddr.lo \ - libisc_la-netscope.lo libisc_la-nonce.lo \ - libisc_la-openssl_shim.lo libisc_la-os.lo \ - libisc_la-parseint.lo libisc_la-picohttpparser.lo \ - libisc_la-portset.lo libisc_la-proxy2.lo libisc_la-quota.lo \ - libisc_la-radix.lo libisc_la-random.lo \ - libisc_la-ratelimiter.lo libisc_la-regex.lo \ - libisc_la-region.lo libisc_la-result.lo libisc_la-safe.lo \ - libisc_la-serial.lo libisc_la-signal.lo libisc_la-sockaddr.lo \ - libisc_la-stats.lo libisc_la-stdio.lo libisc_la-stdtime.lo \ - libisc_la-string.lo libisc_la-symtab.lo libisc_la-syslog.lo \ - libisc_la-thread.lo libisc_la-tid.lo libisc_la-time.lo \ - libisc_la-timer.lo libisc_la-tls.lo libisc_la-tm.lo \ - libisc_la-url.lo libisc_la-utf8.lo libisc_la-uv.lo \ - libisc_la-xml.lo libisc_la-work.lo $(am__objects_2) \ - $(am__objects_3) + libisc_la-netscope.lo libisc_la-openssl_shim.lo \ + libisc_la-os.lo libisc_la-parseint.lo \ + libisc_la-picohttpparser.lo libisc_la-portset.lo \ + libisc_la-proxy2.lo libisc_la-quota.lo libisc_la-radix.lo \ + libisc_la-random.lo libisc_la-ratelimiter.lo \ + libisc_la-regex.lo libisc_la-region.lo libisc_la-result.lo \ + libisc_la-safe.lo libisc_la-serial.lo libisc_la-signal.lo \ + libisc_la-sockaddr.lo libisc_la-stats.lo libisc_la-stdio.lo \ + libisc_la-stdtime.lo libisc_la-string.lo libisc_la-symtab.lo \ + libisc_la-syslog.lo libisc_la-thread.lo libisc_la-tid.lo \ + libisc_la-time.lo libisc_la-timer.lo libisc_la-tls.lo \ + libisc_la-tm.lo libisc_la-url.lo libisc_la-utf8.lo \ + libisc_la-uv.lo libisc_la-xml.lo libisc_la-work.lo \ + $(am__objects_2) $(am__objects_3) libisc_la_OBJECTS = $(am_libisc_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -320,7 +318,6 @@ ./$(DEPDIR)/libisc_la-condition.Plo \ ./$(DEPDIR)/libisc_la-counter.Plo \ ./$(DEPDIR)/libisc_la-crc64.Plo ./$(DEPDIR)/libisc_la-dir.Plo \ - ./$(DEPDIR)/libisc_la-entropy.Plo \ ./$(DEPDIR)/libisc_la-errno.Plo \ ./$(DEPDIR)/libisc_la-errno2result.Plo \ ./$(DEPDIR)/libisc_la-error.Plo ./$(DEPDIR)/libisc_la-file.Plo \ @@ -345,7 +342,6 @@ ./$(DEPDIR)/libisc_la-net.Plo \ ./$(DEPDIR)/libisc_la-netaddr.Plo \ ./$(DEPDIR)/libisc_la-netscope.Plo \ - ./$(DEPDIR)/libisc_la-nonce.Plo \ ./$(DEPDIR)/libisc_la-openssl_shim.Plo \ ./$(DEPDIR)/libisc_la-os.Plo \ ./$(DEPDIR)/libisc_la-parseint.Plo \ @@ -593,8 +589,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -716,7 +714,6 @@ include/isc/dir.h \ include/isc/dnsstream.h \ include/isc/endian.h \ - include/isc/entropy.h \ include/isc/errno.h \ include/isc/error.h \ include/isc/file.h \ @@ -803,19 +800,18 @@ netmgr/socket.c netmgr/streamdns.c netmgr/tcp.c netmgr/timer.c \ netmgr/tlsstream.c netmgr/udp.c ascii.c assertions.c async.c \ async_p.h backtrace.c base32.c base64.c commandline.c \ - condition.c counter.c crc64.c dir.c entropy.c errno.c \ - errno2result.c errno2result.h error.c file.c fips.c \ - getaddresses.c hash.c hashmap.c heap.c helper.c hex.c histo.c \ - hmac.c ht.c httpd.c interfaceiter.c iterated_hash.c \ - jemalloc_shim.h job.c job_p.h lex.c lib.c log.c loop.c \ - loop_p.h managers.c md.c mem.c mem_p.h meminfo.c mutex.c \ - mutex_p.h mutexblock.c net.c netaddr.c netscope.c nonce.c \ - openssl_shim.c openssl_shim.h os.c os_p.h parseint.c \ - picohttpparser.c picohttpparser.h portset.c probes.d proxy2.c \ - quota.c radix.c random.c ratelimiter.c regex.c region.c \ - result.c safe.c serial.c signal.c sockaddr.c stats.c stdio.c \ - stdtime.c string.c symtab.c syslog.c thread.c tid.c time.c \ - timer.c tls.c tm.c url.c utf8.c uv.c xml.c work.c \ + condition.c counter.c crc64.c dir.c errno.c errno2result.c \ + errno2result.h error.c file.c fips.c getaddresses.c hash.c \ + hashmap.c heap.c helper.c hex.c histo.c hmac.c ht.c httpd.c \ + interfaceiter.c iterated_hash.c jemalloc_shim.h job.c job_p.h \ + lex.c lib.c log.c loop.c loop_p.h managers.c md.c mem.c \ + mem_p.h meminfo.c mutex.c mutex_p.h mutexblock.c net.c \ + netaddr.c netscope.c openssl_shim.c openssl_shim.h os.c os_p.h \ + parseint.c picohttpparser.c picohttpparser.h portset.c \ + probes.d proxy2.c quota.c radix.c random.c ratelimiter.c \ + regex.c region.c result.c safe.c serial.c signal.c sockaddr.c \ + stats.c stdio.c stdtime.c string.c symtab.c syslog.c thread.c \ + tid.c time.c timer.c tls.c tm.c url.c utf8.c uv.c xml.c work.c \ $(am__append_2) $(am__append_7) libisc_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBISC_CFLAGS) $(LIBUV_CFLAGS) \ $(OPENSSL_CFLAGS) $(ZLIB_CFLAGS) $(am__append_3) \ @@ -894,21 +890,19 @@ done clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} netmgr/$(am__dirstamp): @$(MKDIR_P) netmgr - @: > netmgr/$(am__dirstamp) + @: >>netmgr/$(am__dirstamp) netmgr/$(DEPDIR)/$(am__dirstamp): @$(MKDIR_P) netmgr/$(DEPDIR) - @: > netmgr/$(DEPDIR)/$(am__dirstamp) + @: >>netmgr/$(DEPDIR)/$(am__dirstamp) netmgr/libisc_la-netmgr.lo: netmgr/$(am__dirstamp) \ netmgr/$(DEPDIR)/$(am__dirstamp) netmgr/libisc_la-proxystream.lo: netmgr/$(am__dirstamp) \ @@ -952,7 +946,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-counter.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-crc64.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-dir.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-entropy.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-errno.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-errno2result.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-error.Plo@am__quote@ # am--include-marker @@ -984,7 +977,6 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-net.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-netaddr.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-netscope.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-nonce.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-openssl_shim.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-os.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libisc_la-parseint.Plo@am__quote@ # am--include-marker @@ -1033,7 +1025,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -1201,13 +1193,6 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisc_la-dir.lo `test -f 'dir.c' || echo '$(srcdir)/'`dir.c -libisc_la-entropy.lo: entropy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisc_la-entropy.lo -MD -MP -MF $(DEPDIR)/libisc_la-entropy.Tpo -c -o libisc_la-entropy.lo `test -f 'entropy.c' || echo '$(srcdir)/'`entropy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisc_la-entropy.Tpo $(DEPDIR)/libisc_la-entropy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='entropy.c' object='libisc_la-entropy.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisc_la-entropy.lo `test -f 'entropy.c' || echo '$(srcdir)/'`entropy.c - libisc_la-errno.lo: errno.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisc_la-errno.lo -MD -MP -MF $(DEPDIR)/libisc_la-errno.Tpo -c -o libisc_la-errno.lo `test -f 'errno.c' || echo '$(srcdir)/'`errno.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisc_la-errno.Tpo $(DEPDIR)/libisc_la-errno.Plo @@ -1425,13 +1410,6 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisc_la-netscope.lo `test -f 'netscope.c' || echo '$(srcdir)/'`netscope.c -libisc_la-nonce.lo: nonce.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisc_la-nonce.lo -MD -MP -MF $(DEPDIR)/libisc_la-nonce.Tpo -c -o libisc_la-nonce.lo `test -f 'nonce.c' || echo '$(srcdir)/'`nonce.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisc_la-nonce.Tpo $(DEPDIR)/libisc_la-nonce.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='nonce.c' object='libisc_la-nonce.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libisc_la-nonce.lo `test -f 'nonce.c' || echo '$(srcdir)/'`nonce.c - libisc_la-openssl_shim.lo: openssl_shim.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libisc_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libisc_la-openssl_shim.lo -MD -MP -MF $(DEPDIR)/libisc_la-openssl_shim.Tpo -c -o libisc_la-openssl_shim.lo `test -f 'openssl_shim.c' || echo '$(srcdir)/'`openssl_shim.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libisc_la-openssl_shim.Tpo $(DEPDIR)/libisc_la-openssl_shim.Plo @@ -1831,25 +1809,25 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -rm -f netmgr/$(DEPDIR)/$(am__dirstamp) - -rm -f netmgr/$(am__dirstamp) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) netmgr/$(DEPDIR)/$(am__dirstamp) + -$(am__rm_f) netmgr/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/libisc_la-ascii.Plo + -rm -f ./$(DEPDIR)/libisc_la-ascii.Plo -rm -f ./$(DEPDIR)/libisc_la-assertions.Plo -rm -f ./$(DEPDIR)/libisc_la-async.Plo -rm -f ./$(DEPDIR)/libisc_la-backtrace.Plo @@ -1860,7 +1838,6 @@ -rm -f ./$(DEPDIR)/libisc_la-counter.Plo -rm -f ./$(DEPDIR)/libisc_la-crc64.Plo -rm -f ./$(DEPDIR)/libisc_la-dir.Plo - -rm -f ./$(DEPDIR)/libisc_la-entropy.Plo -rm -f ./$(DEPDIR)/libisc_la-errno.Plo -rm -f ./$(DEPDIR)/libisc_la-errno2result.Plo -rm -f ./$(DEPDIR)/libisc_la-error.Plo @@ -1892,7 +1869,6 @@ -rm -f ./$(DEPDIR)/libisc_la-net.Plo -rm -f ./$(DEPDIR)/libisc_la-netaddr.Plo -rm -f ./$(DEPDIR)/libisc_la-netscope.Plo - -rm -f ./$(DEPDIR)/libisc_la-nonce.Plo -rm -f ./$(DEPDIR)/libisc_la-openssl_shim.Plo -rm -f ./$(DEPDIR)/libisc_la-os.Plo -rm -f ./$(DEPDIR)/libisc_la-parseint.Plo @@ -1987,7 +1963,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libisc_la-ascii.Plo + -rm -f ./$(DEPDIR)/libisc_la-ascii.Plo -rm -f ./$(DEPDIR)/libisc_la-assertions.Plo -rm -f ./$(DEPDIR)/libisc_la-async.Plo -rm -f ./$(DEPDIR)/libisc_la-backtrace.Plo @@ -1998,7 +1974,6 @@ -rm -f ./$(DEPDIR)/libisc_la-counter.Plo -rm -f ./$(DEPDIR)/libisc_la-crc64.Plo -rm -f ./$(DEPDIR)/libisc_la-dir.Plo - -rm -f ./$(DEPDIR)/libisc_la-entropy.Plo -rm -f ./$(DEPDIR)/libisc_la-errno.Plo -rm -f ./$(DEPDIR)/libisc_la-errno2result.Plo -rm -f ./$(DEPDIR)/libisc_la-error.Plo @@ -2030,7 +2005,6 @@ -rm -f ./$(DEPDIR)/libisc_la-net.Plo -rm -f ./$(DEPDIR)/libisc_la-netaddr.Plo -rm -f ./$(DEPDIR)/libisc_la-netscope.Plo - -rm -f ./$(DEPDIR)/libisc_la-nonce.Plo -rm -f ./$(DEPDIR)/libisc_la-openssl_shim.Plo -rm -f ./$(DEPDIR)/libisc_la-os.Plo -rm -f ./$(DEPDIR)/libisc_la-parseint.Plo @@ -2132,3 +2106,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/lib/isc/entropy.c bind9-9.20.15/lib/isc/entropy.c --- bind9-9.20.11/lib/isc/entropy.c 2025-07-04 09:42:08.420330171 +0000 +++ bind9-9.20.15/lib/isc/entropy.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,24 +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. - */ - -#include -#include -#include -#include - -void -isc_entropy_get(void *buf, size_t buflen) { - int r = uv_random(NULL, NULL, buf, buflen, 0, NULL); - - UV_RUNTIME_CHECK(uv_random, r); -} diff -Nru bind9-9.20.11/lib/isc/hash.c bind9-9.20.15/lib/isc/hash.c --- bind9-9.20.11/lib/isc/hash.c 2025-07-04 09:42:08.421330194 +0000 +++ bind9-9.20.15/lib/isc/hash.c 2025-10-18 10:16:12.654733721 +0000 @@ -16,7 +16,6 @@ #include #include -#include #include /* IWYU pragma: keep */ #include #include @@ -35,7 +34,7 @@ */ uint8_t key[16] = { 1 }; #if !FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - isc_entropy_get(key, sizeof(key)); + isc_random_buf(key, sizeof(key)); #endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ STATIC_ASSERT(sizeof(key) >= sizeof(isc_hash_key), "sizeof(key) < sizeof(isc_hash_key)"); diff -Nru bind9-9.20.11/lib/isc/hashmap.c bind9-9.20.15/lib/isc/hashmap.c --- bind9-9.20.11/lib/isc/hashmap.c 2025-07-04 09:42:08.421330194 +0000 +++ bind9-9.20.15/lib/isc/hashmap.c 2025-10-18 10:16:12.654733721 +0000 @@ -32,7 +32,6 @@ #include #include -#include #include #include #include diff -Nru bind9-9.20.11/lib/isc/httpd.c bind9-9.20.15/lib/isc/httpd.c --- bind9-9.20.11/lib/isc/httpd.c 2025-07-04 09:42:08.422330218 +0000 +++ bind9-9.20.15/lib/isc/httpd.c 2025-10-18 10:16:12.655733737 +0000 @@ -291,7 +291,7 @@ * memory. */ isc_httpdurl_t *url, *next; - ISC_LIST_FOREACH_SAFE (httpdmgr->urls, url, link, next) { + ISC_LIST_FOREACH_SAFE(httpdmgr->urls, url, link, next) { isc_mem_free(httpdmgr->mctx, url->url); ISC_LIST_UNLINK(httpdmgr->urls, url, link); isc_mem_put(httpdmgr->mctx, url, sizeof(isc_httpdurl_t)); @@ -781,7 +781,7 @@ } LOCK(&mgr->lock); - ISC_LIST_FOREACH (mgr->urls, url, link) { + ISC_LIST_FOREACH(mgr->urls, url, link) { if (strncmp(path, url->url, path_len) == 0) { break; } @@ -980,7 +980,7 @@ LOCK(&httpdmgr->lock); isc_httpd_t *httpd = NULL, *next = NULL; - ISC_LIST_FOREACH_SAFE (httpdmgr->running, httpd, link, next) { + ISC_LIST_FOREACH_SAFE(httpdmgr->running, httpd, link, next) { if (httpd->handle != NULL) { httpd_request(httpd->handle, ISC_R_SUCCESS, NULL, httpd); diff -Nru bind9-9.20.11/lib/isc/include/isc/attributes.h bind9-9.20.15/lib/isc/include/isc/attributes.h --- bind9-9.20.11/lib/isc/include/isc/attributes.h 2025-07-04 09:42:08.423330241 +0000 +++ bind9-9.20.15/lib/isc/include/isc/attributes.h 2025-10-18 10:16:12.655733737 +0000 @@ -110,3 +110,9 @@ #else #define ISC_CONSTEXPR static const #endif + +#if __has_attribute(__nonnull__) +#define ISC_ATTR_NONNULL(...) __attribute__((__nonnull__(__VA_ARGS__))) +#else +#define ISC_ATTR_NONNULL(...) +#endif diff -Nru bind9-9.20.11/lib/isc/include/isc/entropy.h bind9-9.20.15/lib/isc/include/isc/entropy.h --- bind9-9.20.11/lib/isc/include/isc/entropy.h 2025-07-04 09:42:08.424330265 +0000 +++ bind9-9.20.15/lib/isc/include/isc/entropy.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,35 +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. - */ - -#pragma once - -#include - -#include - -/*! \file isc/entropy.h - * \brief Implements wrapper around CSPRNG cryptographic library calls - * for getting cryptographically secure pseudo-random numbers. - * - * Uses synchronous version of uv_random(). - */ - -ISC_LANG_BEGINDECLS - -void -isc_entropy_get(void *buf, size_t buflen); -/*!< - * \brief Get cryptographically-secure pseudo-random data. - */ - -ISC_LANG_ENDDECLS diff -Nru bind9-9.20.11/lib/isc/include/isc/nonce.h bind9-9.20.15/lib/isc/include/isc/nonce.h --- bind9-9.20.11/lib/isc/include/isc/nonce.h 2025-07-04 09:42:08.427330335 +0000 +++ bind9-9.20.15/lib/isc/include/isc/nonce.h 2025-10-18 10:16:12.660733815 +0000 @@ -16,6 +16,7 @@ #include #include +#include /*! \file isc/nonce.h * \brief Provides a function for generating an arbitrarily long nonce. @@ -23,8 +24,10 @@ ISC_LANG_BEGINDECLS -void -isc_nonce_buf(void *buf, size_t buflen); +static inline void +isc_nonce_buf(void *buf, size_t buflen) { + isc_random_buf(buf, buflen); +} /*!< * Fill 'buf', up to 'buflen' bytes, with random data from the * crypto provider's random function. diff -Nru bind9-9.20.11/lib/isc/include/isc/random.h bind9-9.20.15/lib/isc/include/isc/random.h --- bind9-9.20.11/lib/isc/include/isc/random.h 2025-07-04 09:42:08.428330358 +0000 +++ bind9-9.20.15/lib/isc/include/isc/random.h 2025-10-18 10:16:12.661733830 +0000 @@ -20,25 +20,18 @@ #include /*! \file isc/random.h - * \brief Implements wrapper around a non-cryptographically secure + * \brief Implements wrapper around a cryptographically secure * pseudo-random number generator. * */ ISC_LANG_BEGINDECLS -uint8_t -isc_random8(void); -/*!< - * \brief Returns a single 8-bit random value. - */ - -uint16_t -isc_random16(void); -/*!< - * \brief Returns a single 16-bit random value. - */ - +#if HAVE_ARC4RANDOM && !defined(__linux__) +#define isc_random32() arc4random() +#define isc_random_buf(buf, buflen) arc4random_buf(buf, buflen) +#define isc_random_uniform(upper_bound) arc4random_uniform(upper_bound) +#else /* HAVE_ARC4RANDOM && !defined(__linux__) */ uint32_t isc_random32(void); /*!< @@ -68,4 +61,21 @@ * when upper_bound is UINT32_MAX/2. */ +#endif /* HAVE_ARC4RANDOM && !defined(__linux__) */ + +static inline uint8_t +isc_random8(void) { + return (uint8_t)isc_random32(); +} +/*!< + * \brief Returns a single 8-bit random value. + */ + +static inline uint16_t +isc_random16(void) { + return (uint16_t)isc_random32(); +} +/*!< + * \brief Returns a single 16-bit random value. + */ ISC_LANG_ENDDECLS diff -Nru bind9-9.20.11/lib/isc/include/isc/util.h bind9-9.20.15/lib/isc/include/isc/util.h --- bind9-9.20.11/lib/isc/include/isc/util.h 2025-07-04 09:42:08.431330428 +0000 +++ bind9-9.20.15/lib/isc/include/isc/util.h 2025-10-18 10:16:12.663733861 +0000 @@ -79,6 +79,8 @@ #define ISC_CLAMP(v, x, y) ((v) < (x) ? (x) : ((v) > (y) ? (y) : (v))) +#define ISC_MAX3(a, b, c) ISC_MAX(ISC_MAX((a), (b)), (c)) + /*% * The UNCONST() macro can be used to omit warnings produced by certain * compilers when operating with pointers declared with the const type qual- diff -Nru bind9-9.20.11/lib/isc/mem.c bind9-9.20.15/lib/isc/mem.c --- bind9-9.20.11/lib/isc/mem.c 2025-07-04 09:42:08.432330452 +0000 +++ bind9-9.20.15/lib/isc/mem.c 2025-10-18 10:16:12.665733892 +0000 @@ -446,6 +446,8 @@ mem_shutdown(void) { bool empty; + rcu_barrier(); + isc__mem_checkdestroyed(); LOCK(&contextslock); diff -Nru bind9-9.20.11/lib/isc/nonce.c bind9-9.20.15/lib/isc/nonce.c --- bind9-9.20.11/lib/isc/nonce.c 2025-07-04 09:42:08.436330546 +0000 +++ bind9-9.20.15/lib/isc/nonce.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,20 +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. - */ - -#include -#include - -void -isc_nonce_buf(void *buf, size_t buflen) { - isc_entropy_get(buf, buflen); -} diff -Nru bind9-9.20.11/lib/isc/os.c bind9-9.20.15/lib/isc/os.c --- bind9-9.20.11/lib/isc/os.c 2025-07-04 09:42:08.436330546 +0000 +++ bind9-9.20.15/lib/isc/os.c 2025-10-18 10:16:12.668733939 +0000 @@ -87,8 +87,9 @@ int i, n = 0; for (i = 0; i < CPU_SETSIZE; ++i) { - if (CPU_ISSET(i, &cpus)) + if (CPU_ISSET(i, &cpus)) { ++n; + } } return n; #endif @@ -115,8 +116,9 @@ if (result != -1) { int i, n = 0; for (i = 0; i < CPU_SETSIZE; ++i) { - if (CPU_ISSET(i, &cpus)) + if (CPU_ISSET(i, &cpus)) { ++n; + } } return n; } diff -Nru bind9-9.20.11/lib/isc/picohttpparser.c bind9-9.20.15/lib/isc/picohttpparser.c --- bind9-9.20.11/lib/isc/picohttpparser.c 2025-07-04 09:42:08.436330546 +0000 +++ bind9-9.20.15/lib/isc/picohttpparser.c 2025-10-18 10:16:12.669733955 +0000 @@ -752,7 +752,9 @@ if (decoder->_total_overhead >= 100 * 1024 && decoder->_total_read - decoder->_total_overhead < decoder->_total_read / 4) + { ret = -1; + } } return ret; } diff -Nru bind9-9.20.11/lib/isc/random.c bind9-9.20.15/lib/isc/random.c --- bind9-9.20.11/lib/isc/random.c 2025-07-04 09:42:08.437330569 +0000 +++ bind9-9.20.15/lib/isc/random.c 2025-10-18 10:16:12.669733955 +0000 @@ -30,126 +30,55 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#if !HAVE_ARC4RANDOM || defined(__linux__) + #include -#include -#include -#include +#include -#include +#include #include -#include #include -#include #include +#include -/* - * Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org) - * - * To the extent possible under law, the author has dedicated all - * copyright and related and neighboring rights to this software to the - * public domain worldwide. This software is distributed without any - * warranty. - * - * See . - */ - -/* - * This is xoshiro128** 1.0, our 32-bit all-purpose, rock-solid generator. - * It has excellent (sub-ns) speed, a state size (128 bits) that is large - * enough for mild parallelism, and it passes all tests we are aware of. - * - * The state must be seeded so that it is not everywhere zero. - */ - -static thread_local bool initialized = false; -static thread_local uint32_t seed[4] = { 0 }; - -static uint32_t -rotl(const uint32_t x, int k) { - return (x << k) | (x >> (32 - k)); -} - -static uint32_t -next(void) { - uint32_t result_starstar, t; +#define ISC_RANDOM_BUFSIZE (ISC_OS_CACHELINE_SIZE / sizeof(uint32_t)) - result_starstar = rotl(seed[0] * 5, 7) * 9; - t = seed[1] << 9; - - seed[2] ^= seed[0]; - seed[3] ^= seed[1]; - seed[1] ^= seed[2]; - seed[0] ^= seed[3]; - - seed[2] ^= t; - - seed[3] = rotl(seed[3], 11); - - return result_starstar; -} - -static void -isc__random_initialize(void) { - if (initialized) { - return; - } +thread_local static uint32_t isc__random_pool[ISC_RANDOM_BUFSIZE]; +thread_local static size_t isc__random_pos = ISC_RANDOM_BUFSIZE; +uint32_t +isc_random32(void) { #if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /* - * A fixed seed helps with problem reproduction when fuzzing. It must be - * non-zero else xoshiro128starstar will generate only zeroes, and the - * first result needs to be non-zero as expected by random_test.c + * A fixed stream of numbers helps with problem reproduction when + * fuzzing. The first result needs to be non-zero as expected by + * random_test.c (it starts with ISC_RANDOM_BUFSIZE, see above). */ - seed[0] = 1; + return (uint32_t)(isc__random_pos++); #endif /* if FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ - while (seed[0] == 0 && seed[1] == 0 && seed[2] == 0 && seed[3] == 0) { - isc_entropy_get(seed, sizeof(seed)); + if (isc__random_pos == ISC_RANDOM_BUFSIZE) { + isc_random_buf(isc__random_pool, sizeof(isc__random_pool)); + isc__random_pos = 0; } - initialized = true; -} - -uint8_t -isc_random8(void) { - isc__random_initialize(); - return (uint8_t)next(); -} -uint16_t -isc_random16(void) { - isc__random_initialize(); - return (uint16_t)next(); -} - -uint32_t -isc_random32(void) { - isc__random_initialize(); - return next(); + return isc__random_pool[isc__random_pos++]; } void isc_random_buf(void *buf, size_t buflen) { - REQUIRE(buf != NULL); - REQUIRE(buflen > 0); - - int i; - uint32_t r; + REQUIRE(buflen == 0 || buf != NULL); - isc__random_initialize(); - - for (i = 0; i + sizeof(r) <= buflen; i += sizeof(r)) { - r = next(); - memmove((uint8_t *)buf + i, &r, sizeof(r)); + if (buf == NULL || buflen == 0) { + return; } - r = next(); - memmove((uint8_t *)buf + i, &r, buflen % sizeof(r)); - return; + + int r = uv_random(NULL, NULL, buf, buflen, 0, NULL); + UV_RUNTIME_CHECK(uv_random, r); } uint32_t isc_random_uniform(uint32_t limit) { - isc__random_initialize(); - /* * Daniel Lemire's nearly-divisionless unbiased bounded random numbers. * @@ -161,7 +90,7 @@ * integer part (upper 32 bits), and we will use the fraction part * (lower 32 bits) to determine whether or not we need to resample. */ - uint64_t num = (uint64_t)next() * (uint64_t)limit; + uint64_t num = (uint64_t)isc_random32() * (uint64_t)limit; /* * In the fast path, we avoid doing a division in most cases by * comparing the fraction part of `num` with the limit, which is @@ -213,7 +142,7 @@ * our valid range, it is superfluous, and we resample. */ while ((uint32_t)(num) < residue) { - num = (uint64_t)next() * (uint64_t)limit; + num = (uint64_t)isc_random32() * (uint64_t)limit; } } /* @@ -221,3 +150,5 @@ */ return (uint32_t)(num >> 32); } + +#endif /* HAVE_ARC4RANDOM && !defined(__linux__) */ diff -Nru bind9-9.20.11/lib/isc/uv.c bind9-9.20.15/lib/isc/uv.c --- bind9-9.20.11/lib/isc/uv.c 2025-07-04 09:42:08.440330639 +0000 +++ bind9-9.20.15/lib/isc/uv.c 2025-10-18 10:16:12.672734001 +0000 @@ -130,6 +130,21 @@ void isc__uv_initialize(void) { + /* + * Ensure the first 3 file descriptors are open + * otherwise, libuv may use one and trigger abort + * when closing it. + * + * See https://github.com/libuv/libuv/pull/4559 + */ + do { + int fd = open("/dev/null", O_RDWR, 0); + RUNTIME_CHECK(fd >= 0); + if (fd > STDERR_FILENO) { + close(fd); + break; + } + } while (true); #if UV_VERSION_HEX >= UV_VERSION(1, 38, 0) int r; isc_mem_create(&isc__uv_mctx); diff -Nru bind9-9.20.11/lib/isccc/Makefile.in bind9-9.20.15/lib/isccc/Makefile.in --- bind9-9.20.11/lib/isccc/Makefile.in 2025-07-04 09:43:11.541819200 +0000 +++ bind9-9.20.15/lib/isccc/Makefile.in 2025-10-18 10:17:04.755505762 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -74,6 +74,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -142,10 +144,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libisccc_ladir)" LTLIBRARIES = $(lib_LTLIBRARIES) @@ -395,8 +396,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -595,15 +598,13 @@ done clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libisccc.la: $(libisccc_la_OBJECTS) $(libisccc_la_DEPENDENCIES) $(EXTRA_libisccc_la_DEPENDENCIES) $(AM_V_CCLD)$(libisccc_la_LINK) -rpath $(libdir) $(libisccc_la_OBJECTS) $(libisccc_la_LIBADD) $(LIBS) @@ -623,7 +624,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -839,23 +840,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/libisccc_la-alist.Plo + -rm -f ./$(DEPDIR)/libisccc_la-alist.Plo -rm -f ./$(DEPDIR)/libisccc_la-base64.Plo -rm -f ./$(DEPDIR)/libisccc_la-cc.Plo -rm -f ./$(DEPDIR)/libisccc_la-ccmsg.Plo @@ -910,7 +911,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libisccc_la-alist.Plo + -rm -f ./$(DEPDIR)/libisccc_la-alist.Plo -rm -f ./$(DEPDIR)/libisccc_la-base64.Plo -rm -f ./$(DEPDIR)/libisccc_la-cc.Plo -rm -f ./$(DEPDIR)/libisccc_la-ccmsg.Plo @@ -967,3 +968,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/lib/isccfg/Makefile.in bind9-9.20.15/lib/isccfg/Makefile.in --- bind9-9.20.11/lib/isccfg/Makefile.in 2025-07-04 09:43:11.576820015 +0000 +++ bind9-9.20.15/lib/isccfg/Makefile.in 2025-10-18 10:17:04.789506283 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -74,6 +74,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -143,10 +145,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libisccfg_ladir)" LTLIBRARIES = $(lib_LTLIBRARIES) @@ -401,8 +402,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -601,15 +604,13 @@ done clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libisccfg.la: $(libisccfg_la_OBJECTS) $(libisccfg_la_DEPENDENCIES) $(EXTRA_libisccfg_la_DEPENDENCIES) $(AM_V_CCLD)$(libisccfg_la_LINK) -rpath $(libdir) $(libisccfg_la_OBJECTS) $(libisccfg_la_LIBADD) $(LIBS) @@ -631,7 +632,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -861,23 +862,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/libisccfg_la-aclconf.Plo + -rm -f ./$(DEPDIR)/libisccfg_la-aclconf.Plo -rm -f ./$(DEPDIR)/libisccfg_la-check.Plo -rm -f ./$(DEPDIR)/libisccfg_la-dnsconf.Plo -rm -f ./$(DEPDIR)/libisccfg_la-duration.Plo @@ -934,7 +935,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libisccfg_la-aclconf.Plo + -rm -f ./$(DEPDIR)/libisccfg_la-aclconf.Plo -rm -f ./$(DEPDIR)/libisccfg_la-check.Plo -rm -f ./$(DEPDIR)/libisccfg_la-dnsconf.Plo -rm -f ./$(DEPDIR)/libisccfg_la-duration.Plo @@ -993,3 +994,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/lib/isccfg/check.c bind9-9.20.15/lib/isccfg/check.c --- bind9-9.20.11/lib/isccfg/check.c 2025-07-04 09:42:08.443330710 +0000 +++ bind9-9.20.15/lib/isccfg/check.c 2025-10-18 10:16:12.675734048 +0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -1525,6 +1526,11 @@ if (obj != NULL) { bool bad_kasp = false; bool bad_name = false; + unsigned int kaspopts = (ISCCFG_KASPCONF_CHECK_KEYLIST | + ISCCFG_KASPCONF_LOG_ERRORS); + if (check_algorithms) { + kaspopts |= ISCCFG_KASPCONF_CHECK_ALGORITHMS; + } if (optlevel != optlevel_config && !cfg_obj_isstring(obj)) { bad_kasp = true; @@ -1553,9 +1559,8 @@ } ret = cfg_kasp_fromconfig( - kconfig, NULL, check_algorithms, - mctx, logctx, &kslist, &list, - &kasp); + kconfig, NULL, kaspopts, mctx, + logctx, &kslist, &list, &kasp); if (ret != ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) { result = ret; @@ -3021,33 +3026,33 @@ static isc_result_t check_keydir(const cfg_obj_t *config, const cfg_obj_t *zconfig, - dns_name_t *zname, const char *name, const char *keydir, - isc_symtab_t *keydirs, isc_log_t *logctx, isc_mem_t *mctx) { + dns_name_t *origin, const char *zname, const char *name, + const char *keydir, isc_symtab_t *keydirs, isc_log_t *logctx, + isc_mem_t *mctx, bool check_keys) { const char *dir = keydir; const cfg_listelt_t *element; isc_result_t ret, result = ISC_R_SUCCESS; - bool do_cleanup = false; - bool done = false; bool keystore = false; - const cfg_obj_t *kasps = NULL; dns_kasp_t *kasp = NULL, *kasp_next = NULL; + const cfg_obj_t *kaspobj = NULL; + const cfg_obj_t *obj = NULL; + dns_kasp_t *default_kasp = NULL; dns_kasplist_t kasplist; const cfg_obj_t *keystores = NULL; dns_keystore_t *ks = NULL, *ks_next = NULL; dns_keystorelist_t kslist; + isc_time_t timenow; + isc_stdtime_t now; + + timenow = isc_time_now(); + now = isc_time_seconds(&timenow); - /* If no dnssec-policy or key-store, use the dir (key-directory) */ (void)cfg_map_get(config, "dnssec-policy", &kasps); (void)cfg_map_get(config, "key-store", &keystores); - if (kasps == NULL || keystores == NULL) { - goto check; - } - ISC_LIST_INIT(kasplist); ISC_LIST_INIT(kslist); - do_cleanup = true; /* * Build the keystore list. @@ -3062,37 +3067,88 @@ (void)cfg_keystore_fromconfig(NULL, mctx, logctx, NULL, &kslist, NULL); /* - * Look for the dnssec-policy by name, which is the dnssec-policy - * for the zone in question. + * dnssec-policy "default". + */ + ret = cfg_kasp_builtinconfig(mctx, "default", &kslist, &kasplist, + &default_kasp); + if (ret != ISC_R_SUCCESS) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "failed to load the 'default' dnssec-policy: %s", + isc_result_totext(ret)); + result = ret; + goto check; + } + dns_kasp_freeze(default_kasp); + + /* + * dnssec-policy "insecure". + */ + ret = cfg_kasp_builtinconfig(mctx, "insecure", &kslist, &kasplist, + &kasp); + if (ret != ISC_R_SUCCESS) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "failed to load the 'insecure' dnssec-policy: %s", + isc_result_totext(ret)); + result = ret; + goto check; + } + dns_kasp_freeze(kasp); + dns_kasp_detach(&kasp); + + /* + * Configured dnssec-policy clauses. */ for (element = cfg_list_first(kasps); element != NULL; element = cfg_list_next(element)) { cfg_obj_t *kconfig = cfg_listelt_value(element); - const cfg_obj_t *kaspobj = NULL; + obj = NULL; if (!cfg_obj_istuple(kconfig)) { continue; } - kaspobj = cfg_tuple_get(kconfig, "name"); - if (strcmp(name, cfg_obj_asstring(kaspobj)) != 0) { - continue; + obj = cfg_tuple_get(kconfig, "name"); + ret = cfg_kasp_fromconfig(kconfig, default_kasp, 0, mctx, + logctx, &kslist, &kasplist, &kasp); + if (ret != ISC_R_SUCCESS) { + result = ret; + goto check; } - ret = cfg_kasp_fromconfig(kconfig, NULL, false, mctx, logctx, - &kslist, &kasplist, &kasp); - if (ret != ISC_R_SUCCESS) { - kasp = NULL; + if (strcmp(name, cfg_obj_asstring(obj)) == 0) { + kaspobj = obj; + dns_kasp_freeze(kasp); } - break; + dns_kasp_detach(&kasp); } - if (kasp == NULL) { + + /* + * Look for the dnssec-policy by name, which is the dnssec-policy + * for the zone in question. + */ + ret = dns_kasplist_find(&kasplist, name, &kasp); + if (ret != ISC_R_SUCCESS) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "no dnssec-policy found for zone '%s'", zname); + result = ISC_R_NOTFOUND; goto check; } + INSIST(kasp != NULL); + + if (kaspobj == NULL) { + kaspobj = kasps == NULL ? config : kasps; + } + + if (strcmp(name, "insecure") == 0 || strcmp(name, "default") == 0) { + ret = keydirexist(zconfig, "key-directory", origin, dir, name, + keydirs, logctx, mctx); + if (ret != ISC_R_SUCCESS) { + result = ret; + } + } /* Check key-stores of keys */ - dns_kasp_freeze(kasp); for (dns_kasp_key_t *kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; kkey = ISC_LIST_NEXT(kkey, link)) { @@ -3104,41 +3160,127 @@ ret = keydirexist(zconfig, keystore ? "key-store directory" : "key-directory", - zname, dir, name, keydirs, logctx, mctx); + origin, dir, name, keydirs, logctx, mctx); if (ret != ISC_R_SUCCESS) { result = ret; } } - dns_kasp_thaw(kasp); - done = true; -check: - if (!done) { - ret = keydirexist(zconfig, "key-directory", zname, dir, name, - keydirs, logctx, mctx); + if (check_keys) { + /* Find matching key files. */ + dns_dnsseckeylist_t keys; + int numkaspkeys = 0; + int numkeyfiles = 0; + + ISC_LIST_INIT(keys); + ret = dns_dnssec_findmatchingkeys(origin, kasp, keydir, &kslist, + now, mctx, &keys); if (ret != ISC_R_SUCCESS) { result = ret; } - } - if (do_cleanup) { - if (kasp != NULL) { - dns_kasp_detach(&kasp); + for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(keys); dkey != NULL; + dkey = ISC_LIST_NEXT(dkey, link)) + { + numkeyfiles++; + } + + for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(keys); dkey != NULL; + dkey = ISC_LIST_NEXT(dkey, link)) + { + bool found_match = false; + + dns_keymgr_key_init(dkey, kasp, now, numkeyfiles == 1); + + for (dns_kasp_key_t *kkey = + ISC_LIST_HEAD(dns_kasp_keys(kasp)); + kkey != NULL; kkey = ISC_LIST_NEXT(kkey, link)) + { + if (dns_kasp_key_match(kkey, dkey)) { + found_match = true; + break; + } + } + + if (!found_match) { + char keystr[DST_KEY_FORMATSIZE]; + dst_key_format(dkey->key, keystr, + sizeof(keystr)); + cfg_obj_log(kaspobj, logctx, ISC_LOG_ERROR, + "zone '%s': key file '%s' does not " + "match dnssec-policy %s", + zname, keystr, + dns_kasp_getname(kasp)); + result = ISC_R_NOTFOUND; + } + } + + for (dns_kasp_key_t *kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); + kkey != NULL; kkey = ISC_LIST_NEXT(kkey, link)) + { + bool found_match = false; + + numkaspkeys++; + + for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(keys); + dkey != NULL; dkey = ISC_LIST_NEXT(dkey, link)) + { + if (dns_kasp_key_match(kkey, dkey)) { + found_match = true; + break; + } + } + + if (!found_match) { + char keystr[DNS_KASP_KEY_FORMATSIZE]; + dns_kasp_key_format(kkey, keystr, + sizeof(keystr)); + + cfg_obj_log( + kaspobj, logctx, ISC_LOG_ERROR, + "zone '%s': no key file found matching " + "dnssec-policy %s key:'%s'", + zname, dns_kasp_getname(kasp), keystr); + result = ISC_R_NOTFOUND; + } + } + + if (numkaspkeys != numkeyfiles) { + cfg_obj_log(kaspobj, logctx, ISC_LOG_ERROR, + "zone '%s': wrong number of key files (%d, " + "expected %d)", + zname, numkeyfiles, numkaspkeys); + result = ISC_R_FAILURE; } - for (kasp = ISC_LIST_HEAD(kasplist); kasp != NULL; - kasp = kasp_next) + + dns_dnsseckey_t *dkey_next = NULL; + for (dns_dnsseckey_t *dkey = ISC_LIST_HEAD(keys); dkey != NULL; + dkey = dkey_next) { - kasp_next = ISC_LIST_NEXT(kasp, link); - ISC_LIST_UNLINK(kasplist, kasp, link); - dns_kasp_detach(&kasp); - } - for (ks = ISC_LIST_HEAD(kslist); ks != NULL; ks = ks_next) { - ks_next = ISC_LIST_NEXT(ks, link); - ISC_LIST_UNLINK(kslist, ks, link); - dns_keystore_detach(&ks); + dkey_next = ISC_LIST_NEXT(dkey, link); + ISC_LIST_UNLINK(keys, dkey, link); + dns_dnsseckey_destroy(mctx, &dkey); } } +check: + if (default_kasp != NULL) { + dns_kasp_detach(&default_kasp); + } + if (kasp != NULL) { + dns_kasp_detach(&kasp); + } + for (kasp = ISC_LIST_HEAD(kasplist); kasp != NULL; kasp = kasp_next) { + kasp_next = ISC_LIST_NEXT(kasp, link); + ISC_LIST_UNLINK(kasplist, kasp, link); + dns_kasp_detach(&kasp); + } + for (ks = ISC_LIST_HEAD(kslist); ks != NULL; ks = ks_next) { + ks_next = ISC_LIST_NEXT(ks, link); + ISC_LIST_UNLINK(kslist, ks, link); + dns_keystore_detach(&ks); + } + return result; } @@ -3147,7 +3289,8 @@ const cfg_obj_t *config, isc_symtab_t *symtab, isc_symtab_t *files, isc_symtab_t *keydirs, isc_symtab_t *inview, const char *viewname, dns_rdataclass_t defclass, - cfg_aclconfctx_t *actx, isc_log_t *logctx, isc_mem_t *mctx) { + unsigned int flags, cfg_aclconfctx_t *actx, isc_log_t *logctx, + isc_mem_t *mctx) { const char *znamestr; const char *typestr = NULL; const char *target = NULL; @@ -3170,6 +3313,7 @@ bool ddns = false; bool has_dnssecpolicy = false; bool kasp_inlinesigning = false; + bool check_keys = (flags & BIND_CHECK_KEYS) != 0; const void *clauses = NULL; const char *option = NULL; const char *kaspname = NULL; @@ -3995,8 +4139,9 @@ */ if (zname != NULL) { if (has_dnssecpolicy) { - tresult = check_keydir(config, zconfig, zname, kaspname, - dir, keydirs, logctx, mctx); + tresult = check_keydir(config, zconfig, zname, znamestr, + kaspname, dir, keydirs, logctx, + mctx, check_keys); } else { tresult = keydirexist(zconfig, "key-directory", zname, dir, kaspname, keydirs, logctx, @@ -5518,7 +5663,7 @@ tresult = check_zoneconf(zone, voptions, config, symtab, files, keydirs, inview, viewname, vclass, - actx, logctx, mctx); + flags, actx, logctx, mctx); if (tresult != ISC_R_SUCCESS) { result = ISC_R_FAILURE; } diff -Nru bind9-9.20.11/lib/isccfg/include/isccfg/check.h bind9-9.20.15/lib/isccfg/include/isccfg/check.h --- bind9-9.20.11/lib/isccfg/include/isccfg/check.h 2025-07-04 09:42:08.443330710 +0000 +++ bind9-9.20.15/lib/isccfg/include/isccfg/check.h 2025-10-18 10:16:12.675734048 +0000 @@ -41,6 +41,11 @@ * Check the dnssec-policy DNSSEC algorithms against those * supported by the crypto provider. */ +#define BIND_CHECK_KEYS 0x00000004 +/*%< + * Check the dnssec-policy DNSSEC keys against the key files + * in the key stores. + */ ISC_LANG_BEGINDECLS diff -Nru bind9-9.20.11/lib/isccfg/include/isccfg/kaspconf.h bind9-9.20.15/lib/isccfg/include/isccfg/kaspconf.h --- bind9-9.20.11/lib/isccfg/include/isccfg/kaspconf.h 2025-07-04 09:42:08.444330733 +0000 +++ bind9-9.20.15/lib/isccfg/include/isccfg/kaspconf.h 2025-10-18 10:16:12.675734048 +0000 @@ -17,6 +17,10 @@ #include +#define ISCCFG_KASPCONF_CHECK_ALGORITHMS 0x01 +#define ISCCFG_KASPCONF_CHECK_KEYLIST 0x02 +#define ISCCFG_KASPCONF_LOG_ERRORS 0x04 + /*** *** Functions ***/ @@ -25,7 +29,7 @@ isc_result_t cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, - bool check_algorithms, isc_mem_t *mctx, isc_log_t *logctx, + unsigned int options, isc_mem_t *mctx, isc_log_t *logctx, dns_keystorelist_t *keystorelist, dns_kasplist_t *kasplist, dns_kasp_t **kaspp); /*%< @@ -38,8 +42,16 @@ * * The 'keystorelist' is where to lookup key stores if KASP keys are using them. * - * If 'check_algorithms' is true then the dnssec-policy DNSSEC key - * algorithms are checked against those supported by the crypto provider. + * If 'options' has ISCCFG_KASPCONF_CHECK_ALGORITHMS set, then the dnssec-policy + * DNSSEC key algorithms are checked against those supported by the crypto + * provider. + * + * If 'options' has ISCCFG_KASPCONF_CHECK_KEYLIST set, then this function + * insists that the key list is not empty, unless the policy is "insecure" + * (then the key list must be empty). + * + * If 'options' has ISCCFG_KASPCONF_LOG_ERRORS set, then configuration errors + * and warnings are logged to the global logging context. * * Requires: * @@ -59,6 +71,30 @@ * *\li Other errors are possible. */ + +isc_result_t +cfg_kasp_builtinconfig(isc_mem_t *mctx, const char *name, + dns_keystorelist_t *keystorelist, + dns_kasplist_t *kasplist, dns_kasp_t **kaspp); +/*%< + * Create built-in KASP. + * + * If a 'kasplist' is provided, a lookup happens and if a KASP already exists + * with the same name, no new KASP is created, and no attach to 'kaspp' happens. + * + * Requires: + * + *\li 'mctx' is a valid memory context. + * + *\li kaspp != NULL && *kaspp == NULL + * + * Returns: + * + *\li #ISC_R_SUCCESS If creating and configuring the KASP succeeds. + *\li #ISC_R_EXISTS If 'kasplist' already has the default policy. + * + *\li Other errors are possible. + */ isc_result_t cfg_keystore_fromconfig(const cfg_obj_t *config, isc_mem_t *mctx, diff -Nru bind9-9.20.11/lib/isccfg/kaspconf.c bind9-9.20.15/lib/isccfg/kaspconf.c --- bind9-9.20.11/lib/isccfg/kaspconf.c 2025-07-04 09:42:08.444330733 +0000 +++ bind9-9.20.15/lib/isccfg/kaspconf.c 2025-10-18 10:16:12.676734063 +0000 @@ -112,8 +112,8 @@ */ static isc_result_t cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, - bool check_algorithms, isc_log_t *logctx, - bool offline_ksk, dns_keystorelist_t *keystorelist, + bool check_algorithms, bool log_errors, bool offline_ksk, + isc_log_t *logctx, dns_keystorelist_t *keystorelist, uint32_t ksk_min_lifetime, uint32_t zsk_min_lifetime) { isc_result_t result; dns_kasp_key_t *key = NULL; @@ -152,10 +152,14 @@ key->role |= DNS_KASP_KEY_ROLE_ZSK; } else if (strcmp(rolestr, "csk") == 0) { if (offline_ksk) { - cfg_obj_log( - config, logctx, ISC_LOG_ERROR, - "dnssec-policy: csk keys are not " - "allowed when offline-ksk is enabled"); + if (log_errors) { + cfg_obj_log(config, logctx, + ISC_LOG_ERROR, + "dnssec-policy: csk keys " + "are not " + "allowed when offline-ksk " + "is enabled"); + } result = ISC_R_FAILURE; goto cleanup; } @@ -173,14 +177,20 @@ result = dns_keystorelist_find(keystorelist, keydir, &key->keystore); if (result == ISC_R_NOTFOUND) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: keystore %s does not exist", - keydir); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: keystore %s does " + "not exist", + keydir); + } result = ISC_R_FAILURE; goto cleanup; } else if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: bad keystore %s", keydir); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: bad keystore %s", + keydir); + } result = ISC_R_FAILURE; goto cleanup; } @@ -193,9 +203,13 @@ } if (key->lifetime > 0) { if (key->lifetime < 30 * (24 * 3600)) { - cfg_obj_log(obj, logctx, ISC_LOG_WARNING, - "dnssec-policy: key lifetime is " - "shorter than 30 days"); + if (log_errors) { + cfg_obj_log(obj, logctx, + ISC_LOG_WARNING, + "dnssec-policy: key " + "lifetime is " + "shorter than 30 days"); + } } if ((key->role & DNS_KASP_KEY_ROLE_KSK) != 0 && key->lifetime <= ksk_min_lifetime) @@ -208,10 +222,14 @@ error = true; } if (error) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: key lifetime is " - "shorter than the time it takes to " - "do a rollover"); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: key " + "lifetime is " + "shorter than the time it " + "takes to " + "do a rollover"); + } result = ISC_R_FAILURE; goto cleanup; } @@ -223,9 +241,11 @@ result = dns_secalg_fromtext(&key->algorithm, (isc_textregion_t *)&alg); if (result != ISC_R_SUCCESS) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: bad algorithm %s", - alg.base); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: bad algorithm %s", + alg.base); + } result = DNS_R_BADALG; goto cleanup; } @@ -234,10 +254,13 @@ (key->algorithm == DNS_KEYALG_RSASHA1 || key->algorithm == DNS_KEYALG_NSEC3RSASHA1)) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: algorithm %s not supported " - "in FIPS mode", - alg.base); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: algorithm %s not " + "supported " + "in FIPS mode", + alg.base); + } result = DNS_R_BADALG; goto cleanup; } @@ -245,13 +268,31 @@ if (check_algorithms && !dst_algorithm_supported(key->algorithm)) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: algorithm %s not supported", - alg.base); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: algorithm %s not " + "supported", + alg.base); + } result = DNS_R_BADALG; goto cleanup; } + switch (key->algorithm) { + case DST_ALG_RSASHA1: + case DST_ALG_NSEC3RSASHA1: + if (log_errors) { + cfg_obj_log( + obj, logctx, ISC_LOG_WARNING, + "dnssec-policy: DNSSEC algorithm %s is " + "deprecated", + alg.base); + } + break; + default: + break; + } + obj = cfg_tuple_get(config, "length"); if (cfg_obj_isuint32(obj)) { uint32_t min, size; @@ -268,11 +309,16 @@ min = DNS_KEYALG_RSASHA512 ? 1024 : 512; } if (size < min || size > 4096) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: key with " - "algorithm %s has invalid " - "key length %u", - alg.base, size); + if (log_errors) { + cfg_obj_log(obj, logctx, + ISC_LOG_ERROR, + "dnssec-policy: " + "key with " + "algorithm %s has " + "invalid " + "key length %u", + alg.base, size); + } result = ISC_R_RANGE; goto cleanup; } @@ -281,11 +327,16 @@ case DNS_KEYALG_ECDSA384: case DNS_KEYALG_ED25519: case DNS_KEYALG_ED448: - cfg_obj_log(obj, logctx, ISC_LOG_WARNING, - "dnssec-policy: key algorithm %s " - "has predefined length; ignoring " - "length value %u", - alg.base, size); + if (log_errors) { + cfg_obj_log(obj, logctx, + ISC_LOG_WARNING, + "dnssec-policy: key " + "algorithm %s " + "has predefined length; " + "ignoring " + "length value %u", + alg.base, size); + } default: break; } @@ -299,25 +350,31 @@ obj = cfg_tuple_get(tagrange, "tag-min"); tag_min = cfg_obj_asuint32(obj); if (tag_min > 0xffff) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: tag-min " - "too big"); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: tag-min " + "too big"); + } result = ISC_R_RANGE; goto cleanup; } obj = cfg_tuple_get(tagrange, "tag-max"); tag_max = cfg_obj_asuint32(obj); if (tag_max > 0xffff) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: tag-max " - "too big"); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: tag-max " + "too big"); + } result = ISC_R_RANGE; goto cleanup; } if (tag_min >= tag_max) { - cfg_obj_log( - obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: tag-min >= tag_max"); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: tag-min >= " + "tag_max"); + } result = ISC_R_RANGE; goto cleanup; } @@ -337,7 +394,7 @@ static isc_result_t cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, - isc_log_t *logctx) { + bool log_errors, isc_log_t *logctx) { dns_kasp_key_t *kkey; unsigned int min_keysize = 4096; const cfg_obj_t *obj = NULL; @@ -374,18 +431,22 @@ if (badalg > 0) { char algstr[DNS_SECALG_FORMATSIZE]; dns_secalg_format((dns_secalg_t)badalg, algstr, sizeof(algstr)); - cfg_obj_log( - obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: cannot use nsec3 with algorithm '%s'", - algstr); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: cannot use nsec3 with " + "algorithm '%s'", + algstr); + } return DNS_R_NSEC3BADALG; } if (iter != DEFAULT_NSEC3PARAM_ITER) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: nsec3 iterations value %u " - "not allowed, must be zero", - iter); + if (log_errors) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: nsec3 iterations value %u " + "not allowed, must be zero", + iter); + } return DNS_R_NSEC3ITERRANGE; } @@ -401,9 +462,12 @@ saltlen = cfg_obj_asuint32(obj); } if (saltlen > 0xff) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "dnssec-policy: nsec3 salt length %u too high", - saltlen); + if (log_errors) { + cfg_obj_log( + obj, logctx, ISC_LOG_ERROR, + "dnssec-policy: nsec3 salt length %u too high", + saltlen); + } return DNS_R_NSEC3SALTRANGE; } @@ -412,7 +476,8 @@ } static isc_result_t -add_digest(dns_kasp_t *kasp, const cfg_obj_t *digest, isc_log_t *logctx) { +add_digest(dns_kasp_t *kasp, const cfg_obj_t *digest, bool log_errors, + isc_log_t *logctx) { isc_result_t result = ISC_R_SUCCESS; isc_textregion_t r; dns_dsdigest_t alg; @@ -422,16 +487,29 @@ r.length = strlen(str); result = dns_dsdigest_fromtext(&alg, &r); if (result != ISC_R_SUCCESS) { - cfg_obj_log(digest, logctx, ISC_LOG_ERROR, - "dnssec-policy: bad cds digest-type %s", str); + if (log_errors) { + cfg_obj_log(digest, logctx, ISC_LOG_ERROR, + "dnssec-policy: bad cds digest-type %s", + str); + } result = DNS_R_BADALG; } else if (!dst_ds_digest_supported(alg)) { - cfg_obj_log(digest, logctx, ISC_LOG_ERROR, - "dnssec-policy: unsupported cds " - "digest-type %s", - str); + if (log_errors) { + cfg_obj_log(digest, logctx, ISC_LOG_ERROR, + "dnssec-policy: unsupported cds " + "digest-type %s", + str); + } result = DST_R_UNSUPPORTEDALG; } else { + if (alg == DNS_DSDIGEST_SHA1) { + if (log_errors) { + cfg_obj_log(digest, logctx, ISC_LOG_WARNING, + "dnssec-policy: deprecated CDS " + "digest-type %s", + str); + } + } dns_kasp_adddigest(kasp, alg); } return result; @@ -439,7 +517,7 @@ isc_result_t cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, - bool check_algorithms, isc_mem_t *mctx, isc_log_t *logctx, + unsigned int options, isc_mem_t *mctx, isc_log_t *logctx, dns_keystorelist_t *keystorelist, dns_kasplist_t *kasplist, dns_kasp_t **kaspp) { isc_result_t result; @@ -460,7 +538,11 @@ uint32_t zonepropdelay = 0, parentpropdelay = 0; uint32_t ipub = 0, iret = 0; uint32_t ksk_min_lifetime = 0, zsk_min_lifetime = 0; - bool offline_ksk = false; + bool offline_ksk = false, manual_mode = false; + bool check_algorithms = (options & ISCCFG_KASPCONF_CHECK_ALGORITHMS) != + 0; + bool check_keylist = (options & ISCCFG_KASPCONF_CHECK_KEYLIST) != 0; + bool log_errors = (options & ISCCFG_KASPCONF_LOG_ERRORS) != 0; REQUIRE(config != NULL); REQUIRE(kaspp != NULL && *kaspp == NULL); @@ -474,10 +556,12 @@ result = dns_kasplist_find(kasplist, kaspname, &kasp); if (result == ISC_R_SUCCESS) { - cfg_obj_log( - config, logctx, ISC_LOG_ERROR, - "dnssec-policy: duplicately named policy found '%s'", - kaspname); + if (log_errors) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "dnssec-policy: duplicately named policy " + "found '%s'", + kaspname); + } dns_kasp_detach(&kasp); return ISC_R_EXISTS; } @@ -496,10 +580,8 @@ /* Now configure. */ INSIST(DNS_KASP_VALID(kasp)); - if (config != NULL) { - koptions = cfg_tuple_get(config, "options"); - maps[i++] = koptions; - } + koptions = cfg_tuple_get(config, "options"); + maps[i++] = koptions; maps[i] = NULL; /* Configuration: Signatures */ @@ -514,42 +596,51 @@ sigvalidity = get_duration(maps, "signatures-validity-dnskey", DNS_KASP_SIG_VALIDITY_DNSKEY); if (sigrefresh >= (sigvalidity * 0.9)) { - cfg_obj_log( - config, logctx, ISC_LOG_ERROR, - "dnssec-policy: policy '%s' signatures-refresh must be " - "at most 90%% of the signatures-validity-dnskey", - kaspname); + if (log_errors) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "dnssec-policy: policy '%s' " + "signatures-refresh must be " + "at most 90%% of the " + "signatures-validity-dnskey", + kaspname); + } result = ISC_R_FAILURE; } dns_kasp_setsigvalidity_dnskey(kasp, sigvalidity); if (sigjitter > sigvalidity) { - cfg_obj_log( - config, logctx, ISC_LOG_ERROR, - "dnssec-policy: policy '%s' signatures-jitter cannot " - "be larger than signatures-validity-dnskey", - kaspname); + if (log_errors) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "dnssec-policy: policy '%s' " + "signatures-jitter cannot " + "be larger than signatures-validity-dnskey", + kaspname); + } result = ISC_R_FAILURE; } sigvalidity = get_duration(maps, "signatures-validity", DNS_KASP_SIG_VALIDITY); if (sigrefresh >= (sigvalidity * 0.9)) { - cfg_obj_log( - config, logctx, ISC_LOG_ERROR, - "dnssec-policy: policy '%s' signatures-refresh must be " - "at most 90%% of the signatures-validity", - kaspname); + if (log_errors) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "dnssec-policy: policy '%s' " + "signatures-refresh must be " + "at most 90%% of the signatures-validity", + kaspname); + } result = ISC_R_FAILURE; } dns_kasp_setsigvalidity(kasp, sigvalidity); if (sigjitter > sigvalidity) { - cfg_obj_log( - config, logctx, ISC_LOG_ERROR, - "dnssec-policy: policy '%s' signatures-jitter cannot " - "be larger than signatures-validity", - kaspname); + if (log_errors) { + cfg_obj_log(config, logctx, ISC_LOG_ERROR, + "dnssec-policy: policy '%s' " + "signatures-jitter cannot " + "be larger than signatures-validity", + kaspname); + } result = ISC_R_FAILURE; } @@ -566,6 +657,13 @@ dns_kasp_setinlinesigning(kasp, true); } + obj = NULL; + (void)confget(maps, "manual-mode", &obj); + if (obj != NULL) { + manual_mode = cfg_obj_asboolean(obj); + } + dns_kasp_setmanualmode(kasp, manual_mode); + maxttl = get_duration(maps, "max-zone-ttl", DNS_KASP_ZONE_MAXTTL); dns_kasp_setzonemaxttl(kasp, maxttl); @@ -603,7 +701,7 @@ element = cfg_list_next(element)) { result = add_digest(kasp, cfg_listelt_value(element), - logctx); + log_errors, logctx); if (result != ISC_R_SUCCESS) { goto cleanup; } @@ -645,14 +743,16 @@ { cfg_obj_t *kobj = cfg_listelt_value(element); result = cfg_kaspkey_fromconfig( - kobj, kasp, check_algorithms, logctx, - offline_ksk, keystorelist, ksk_min_lifetime, - zsk_min_lifetime); + kobj, kasp, check_algorithms, log_errors, + offline_ksk, logctx, keystorelist, + ksk_min_lifetime, zsk_min_lifetime); if (result != ISC_R_SUCCESS) { - cfg_obj_log(kobj, logctx, ISC_LOG_ERROR, - "dnssec-policy: failed to " - "configure keys (%s)", - isc_result_totext(result)); + if (log_errors) { + cfg_obj_log(kobj, logctx, ISC_LOG_ERROR, + "dnssec-policy: failed to " + "configure keys (%s)", + isc_result_totext(result)); + } goto cleanup; } } @@ -687,19 +787,22 @@ if (role[i] != (DNS_KASP_KEY_ROLE_ZSK | DNS_KASP_KEY_ROLE_KSK)) { - cfg_obj_log(keys, logctx, ISC_LOG_ERROR, - "dnssec-policy: algorithm %zu " - "requires both KSK and ZSK roles", - i); + if (log_errors) { + cfg_obj_log(keys, logctx, ISC_LOG_ERROR, + "dnssec-policy: algorithm " + "%zu requires both KSK and " + "ZSK roles", + i); + } result = ISC_R_FAILURE; } - if (warn[i][0]) { + if (warn[i][0] && log_errors) { cfg_obj_log(keys, logctx, ISC_LOG_WARNING, "dnssec-policy: algorithm %zu has " "multiple keys with ZSK role", i); } - if (warn[i][1]) { + if (warn[i][1] && log_errors) { cfg_obj_log(keys, logctx, ISC_LOG_WARNING, "dnssec-policy: algorithm %zu has " "multiple keys with KSK role", @@ -742,20 +845,23 @@ keystorelist, DNS_KEYSTORE_KEYDIRECTORY, &new_key->keystore); if (result != ISC_R_SUCCESS) { - cfg_obj_log(config, logctx, ISC_LOG_ERROR, - "dnssec-policy: failed to " - "find keystore (%s)", - isc_result_totext(result)); + if (log_errors) { + cfg_obj_log(config, logctx, + ISC_LOG_ERROR, + "dnssec-policy: failed to " + "find keystore (%s)", + isc_result_totext(result)); + } goto cleanup; } dns_kasp_addkey(kasp, new_key); } } - if (strcmp(kaspname, "insecure") == 0) { + if (strcmp(kaspname, "insecure") == 0 && check_keylist) { /* "dnssec-policy insecure": key list must be empty */ INSIST(dns_kasp_keylist_empty(kasp)); - } else if (default_kasp != NULL) { + } else if (default_kasp != NULL && check_keylist) { /* There must be keys configured. */ INSIST(!(dns_kasp_keylist_empty(kasp))); } @@ -773,7 +879,8 @@ } } else { dns_kasp_setnsec3(kasp, true); - result = cfg_nsec3param_fromconfig(nsec3, kasp, logctx); + result = cfg_nsec3param_fromconfig(nsec3, kasp, log_errors, + logctx); if (result != ISC_R_SUCCESS) { goto cleanup; } @@ -794,6 +901,99 @@ /* Something bad happened, detach (destroys kasp) and return error. */ dns_kasp_detach(&kasp); return result; +} + +isc_result_t +cfg_kasp_builtinconfig(isc_mem_t *mctx, const char *name, + dns_keystorelist_t *keystorelist, + dns_kasplist_t *kasplist, dns_kasp_t **kaspp) { + isc_result_t result; + dns_kasp_t *kasp = NULL; + + REQUIRE(kaspp != NULL && *kaspp == NULL); + REQUIRE(strcmp(name, "default") == 0 || strcmp(name, "insecure") == 0); + + result = dns_kasplist_find(kasplist, name, &kasp); + if (result == ISC_R_SUCCESS) { + dns_kasp_detach(&kasp); + return ISC_R_EXISTS; + } + if (result != ISC_R_NOTFOUND) { + return result; + } + + /* No kasp with configured name was found in list, create new one. */ + INSIST(kasp == NULL); + dns_kasp_create(mctx, name, &kasp); + INSIST(kasp != NULL); + + /* Now configure. */ + INSIST(DNS_KASP_VALID(kasp)); + + /* Configuration: Signatures */ + dns_kasp_setsigjitter(kasp, parse_duration(DNS_KASP_SIG_JITTER)); + dns_kasp_setsigrefresh(kasp, parse_duration(DNS_KASP_SIG_REFRESH)); + dns_kasp_setsigvalidity_dnskey( + kasp, parse_duration(DNS_KASP_SIG_VALIDITY_DNSKEY)); + dns_kasp_setsigvalidity(kasp, parse_duration(DNS_KASP_SIG_VALIDITY)); + + /* Configuration: Zone settings */ + dns_kasp_setinlinesigning(kasp, true); + dns_kasp_setmanualmode(kasp, false); + dns_kasp_setzonemaxttl(kasp, parse_duration(DNS_KASP_ZONE_MAXTTL)); + dns_kasp_setzonepropagationdelay( + kasp, parse_duration(DNS_KASP_ZONE_PROPDELAY)); + + /* Configuration: Parent settings */ + dns_kasp_setdsttl(kasp, parse_duration(DNS_KASP_DS_TTL)); + dns_kasp_setparentpropagationdelay( + kasp, parse_duration(DNS_KASP_PARENT_PROPDELAY)); + + /* Configuration: Keys */ + dns_kasp_setofflineksk(kasp, false); + dns_kasp_setcdnskey(kasp, true); + dns_kasp_adddigest(kasp, DNS_DSDIGEST_SHA256); + dns_kasp_setdnskeyttl(kasp, parse_duration(DNS_KASP_KEY_TTL)); + dns_kasp_setpublishsafety(kasp, + parse_duration(DNS_KASP_PUBLISH_SAFETY)); + dns_kasp_setretiresafety(kasp, parse_duration(DNS_KASP_RETIRE_SAFETY)); + + dns_kasp_setpurgekeys(kasp, parse_duration(DNS_KASP_PURGE_KEYS)); + + if (strcmp(name, "default") == 0) { + dns_kasp_key_t *new_key = NULL; + dns_kasp_key_create(kasp, &new_key); + new_key->role |= DNS_KASP_KEY_ROLE_KSK; + new_key->role |= DNS_KASP_KEY_ROLE_ZSK; + new_key->lifetime = 0; + new_key->algorithm = DST_ALG_ECDSA256; + new_key->length = 256; + result = dns_keystorelist_find(keystorelist, + DNS_KEYSTORE_KEYDIRECTORY, + &new_key->keystore); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + dns_kasp_addkey(kasp, new_key); + } + + /* Configuration: Denial of existence */ + dns_kasp_setnsec3(kasp, false); + + /* Append it to the list for future lookups. */ + ISC_LIST_APPEND(*kasplist, kasp, link); + INSIST(!(ISC_LIST_EMPTY(*kasplist))); + + /* Success: Attach the kasp to the pointer and return. */ + dns_kasp_attach(kasp, kaspp); + + /* Don't detach as kasp is on '*kasplist' */ + return ISC_R_SUCCESS; + +cleanup: + /* Something bad happened, detach (destroys kasp) and return error. */ + dns_kasp_detach(&kasp); + return result; } isc_result_t diff -Nru bind9-9.20.11/lib/isccfg/namedconf.c bind9-9.20.15/lib/isccfg/namedconf.c --- bind9-9.20.11/lib/isccfg/namedconf.c 2025-07-04 09:42:08.445330756 +0000 +++ bind9-9.20.15/lib/isccfg/namedconf.c 2025-10-18 10:16:12.676734063 +0000 @@ -1450,8 +1450,9 @@ { "tcp-receive-buffer", &cfg_type_uint32, 0 }, { "tcp-send-buffer", &cfg_type_uint32, 0 }, { "tkey-dhkey", NULL, CFG_CLAUSEFLAG_ANCIENT }, - { "tkey-domain", &cfg_type_qstring, 0 }, - { "tkey-gssapi-credential", &cfg_type_qstring, 0 }, + { "tkey-domain", &cfg_type_qstring, CFG_CLAUSEFLAG_OBSOLETE }, + { "tkey-gssapi-credential", &cfg_type_qstring, + CFG_CLAUSEFLAG_DEPRECATED }, { "tkey-gssapi-keytab", &cfg_type_qstring, 0 }, { "transfer-message-size", &cfg_type_uint32, 0 }, { "transfers-in", &cfg_type_uint32, 0 }, @@ -1756,7 +1757,7 @@ * } [ recursive-only yes|no ] [ max-policy-ttl number ] * [ min-update-interval number ] * [ break-dnssec yes|no ] [ min-ns-dots number ] - * [ qname-wait-recurse yes|no ] + * [ qname-wait-recurse yes|no ] [ servfail-until-ready yes|no ] * [ nsip-enable yes|no ] [ nsdname-enable yes|no ] * [ dnsrps-enable yes|no ] * [ dnsrps-options { DNSRPS configuration string } ]; @@ -1979,6 +1980,7 @@ { "nsdname-wait-recurse", &cfg_type_boolean, 0 }, { "qname-wait-recurse", &cfg_type_boolean, 0 }, { "recursive-only", &cfg_type_boolean, 0 }, + { "servfail-until-ready", &cfg_type_boolean, 0 }, { "nsip-enable", &cfg_type_boolean, 0 }, { "nsdname-enable", &cfg_type_boolean, 0 }, #ifdef USE_DNSRPS @@ -2351,6 +2353,7 @@ { "dnskey-ttl", &cfg_type_duration, 0 }, { "inline-signing", &cfg_type_boolean, 0 }, { "keys", &cfg_type_kaspkeys, 0 }, + { "manual-mode", &cfg_type_boolean, 0 }, { "max-zone-ttl", &cfg_type_duration, 0 }, { "nsec3param", &cfg_type_nsec3, 0 }, { "offline-ksk", &cfg_type_boolean, 0 }, diff -Nru bind9-9.20.11/lib/ns/Makefile.in bind9-9.20.15/lib/ns/Makefile.in --- bind9-9.20.11/lib/ns/Makefile.in 2025-07-04 09:43:11.614820901 +0000 +++ bind9-9.20.15/lib/ns/Makefile.in 2025-10-18 10:17:04.827506865 +0000 @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.16.5 from Makefile.am. +# Makefile.in generated by automake 1.17 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2021 Free Software Foundation, Inc. +# Copyright (C) 1994-2024 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -77,6 +77,8 @@ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +am__rm_f = rm -f $(am__rm_f_notfound) +am__rm_rf = rm -rf $(am__rm_f_notfound) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -145,10 +147,9 @@ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ + { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \ } am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libns_ladir)" LTLIBRARIES = $(lib_LTLIBRARIES) @@ -404,8 +405,10 @@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ +am__rm_f_notfound = @am__rm_f_notfound@ am__tar = @am__tar@ am__untar = @am__untar@ +am__xargs_n = @am__xargs_n@ ax_pthread_config = @ax_pthread_config@ bindir = @bindir@ build = @build@ @@ -618,15 +621,13 @@ done clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + -$(am__rm_f) $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } + echo rm -f $${locs}; \ + $(am__rm_f) $${locs} libns.la: $(libns_la_OBJECTS) $(libns_la_DEPENDENCIES) $(EXTRA_libns_la_DEPENDENCIES) $(AM_V_CCLD)$(libns_la_LINK) -rpath $(libdir) $(libns_la_OBJECTS) $(libns_la_LIBADD) $(LIBS) @@ -652,7 +653,7 @@ $(am__depfiles_remade): @$(MKDIR_P) $(@D) - @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + @: >>$@ am--depfiles: $(am__depfiles_remade) @@ -910,23 +911,23 @@ mostlyclean-generic: clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + -$(am__rm_f) $(CLEANFILES) distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -$(am__rm_f) $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." - -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -$(am__rm_f) $(BUILT_SOURCES) clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -f ./$(DEPDIR)/libns_la-client.Plo + -rm -f ./$(DEPDIR)/libns_la-client.Plo -rm -f ./$(DEPDIR)/libns_la-hooks.Plo -rm -f ./$(DEPDIR)/libns_la-interfacemgr.Plo -rm -f ./$(DEPDIR)/libns_la-listenlist.Plo @@ -987,7 +988,7 @@ installcheck-am: maintainer-clean: maintainer-clean-am - -rm -f ./$(DEPDIR)/libns_la-client.Plo + -rm -f ./$(DEPDIR)/libns_la-client.Plo -rm -f ./$(DEPDIR)/libns_la-hooks.Plo -rm -f ./$(DEPDIR)/libns_la-interfacemgr.Plo -rm -f ./$(DEPDIR)/libns_la-listenlist.Plo @@ -1055,3 +1056,10 @@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: + +# Tell GNU make to disable its built-in pattern rules. +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% diff -Nru bind9-9.20.11/lib/ns/client.c bind9-9.20.15/lib/ns/client.c --- bind9-9.20.11/lib/ns/client.c 2025-07-04 09:42:08.446330780 +0000 +++ bind9-9.20.15/lib/ns/client.c 2025-10-18 10:16:12.677734079 +0000 @@ -916,10 +916,10 @@ sizeof(log_buf)); if (rrl_result != DNS_RRL_RESULT_OK) { /* - * Log dropped errors in the query category + * Log dropped errors in the query-errors category * so that they are not lost in silence. * Starts of rate-limited bursts are logged in - * NS_LOGCATEGORY_RRL. + * DNS_LOGCATEGORY_RRL. */ if (wouldlog) { ns_client_log(client, diff -Nru bind9-9.20.11/lib/ns/hooks.c bind9-9.20.15/lib/ns/hooks.c --- bind9-9.20.11/lib/ns/hooks.c 2025-07-04 09:42:08.446330780 +0000 +++ bind9-9.20.15/lib/ns/hooks.c 2025-10-18 10:16:12.677734079 +0000 @@ -224,6 +224,9 @@ isc_log_write(ns_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_HOOKS, ISC_LOG_INFO, "registering plugin '%s'", modpath); + CHECK(plugin->check_func(parameters, cfg, cfg_file, cfg_line, mctx, + lctx, actx)); + CHECK(plugin->register_func(parameters, cfg, cfg_file, cfg_line, mctx, lctx, actx, view->hooktable, &plugin->inst)); diff -Nru bind9-9.20.11/lib/ns/include/ns/query.h bind9-9.20.15/lib/ns/include/ns/query.h --- bind9-9.20.11/lib/ns/include/ns/query.h 2025-07-04 09:42:08.447330803 +0000 +++ bind9-9.20.15/lib/ns/include/ns/query.h 2025-10-18 10:16:12.678734095 +0000 @@ -174,7 +174,6 @@ #define NS_QUERYATTR_RRL_CHECKED 0x010000 #define NS_QUERYATTR_REDIRECT 0x020000 #define NS_QUERYATTR_ANSWERED 0x040000 -#define NS_QUERYATTR_STALEOK 0x080000 typedef struct query_ctx query_ctx_t; @@ -202,7 +201,6 @@ bool authoritative; /* authoritative query? */ bool want_restart; /* CNAME chain or other * restart needed */ - bool refresh_rrset; /* stale RRset refresh needed */ bool need_wildcardproof; /* wildcard proof needed */ bool nxrewrite; /* negative answer from RPZ */ bool findcoveringnsec; /* lookup covering NSEC */ diff -Nru bind9-9.20.11/lib/ns/include/ns/server.h bind9-9.20.15/lib/ns/include/ns/server.h --- bind9-9.20.11/lib/ns/include/ns/server.h 2025-07-04 09:42:08.447330803 +0000 +++ bind9-9.20.15/lib/ns/include/ns/server.h 2025-10-18 10:16:12.678734095 +0000 @@ -51,6 +51,7 @@ #define NS_SERVER_TRANSFERSTUCK 0x00020000U /*%< -T transferstuck */ #define NS_SERVER_LOGRESPONSES 0x00040000U /*%< log responses */ #define NS_SERVER_COOKIEALWAYSVALID 0x00080000U /*%< -T cookiealwaysvalid */ +#define NS_SERVER_RPZSLOW 0x00100000U /*%< -T rpzslow */ /*% * Type for callback function to get hostname. diff -Nru bind9-9.20.11/lib/ns/query.c bind9-9.20.15/lib/ns/query.c --- bind9-9.20.11/lib/ns/query.c 2025-07-04 09:42:08.449330850 +0000 +++ bind9-9.20.15/lib/ns/query.c 2025-10-18 10:16:12.681734141 +0000 @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -141,9 +142,6 @@ /*% Was the client already sent a response? */ #define QUERY_ANSWERED(q) (((q)->attributes & NS_QUERYATTR_ANSWERED) != 0) -/*% Does the query allow stale data in the response? */ -#define QUERY_STALEOK(q) (((q)->attributes & NS_QUERYATTR_STALEOK) != 0) - /*% Does the query wants to check for stale RRset due to a timeout? */ #define QUERY_STALETIMEOUT(q) (((q)->dboptions & DNS_DBFIND_STALETIMEOUT) != 0) @@ -212,6 +210,20 @@ } while (0) #define RESTORE(a, b) SAVE(a, b) +static atomic_uint_fast32_t last_rpznotready_log = 0; + +static bool +can_log_rpznotready(void) { + isc_stdtime_t last; + isc_stdtime_t now = isc_stdtime_now(); + last = atomic_exchange_relaxed(&last_rpznotready_log, now); + if (now != last) { + return true; + } + + return false; +} + static bool validate(ns_client_t *client, dns_db_t *db, dns_name_t *name, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset); @@ -512,9 +524,6 @@ static void query_addauth(query_ctx_t *qctx); -static void -query_clear_stale(ns_client_t *client); - /* * Increment query statistics counters. */ @@ -2292,10 +2301,6 @@ if ((rdataset->attributes & DNS_RDATASETATTR_REQUIRED) != 0) { mrdataset->attributes |= DNS_RDATASETATTR_REQUIRED; } - if ((rdataset->attributes & DNS_RDATASETATTR_STALE_ADDED) != 0) - { - mrdataset->attributes |= DNS_RDATASETATTR_STALE_ADDED; - } return; } else if (result == DNS_R_NXDOMAIN) { /* @@ -2499,7 +2504,8 @@ result = dns_rdata_tostruct(&rdata, &rrsig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_algorithm_supported(client->view->resolver, - name, rrsig.algorithm)) + &rrsig.signer, + rrsig.algorithm)) { char txt[DNS_NAME_FORMATSIZE + 32]; isc_buffer_t buffer; @@ -2830,6 +2836,59 @@ } static void +query_stale_refresh(ns_client_t *client, dns_name_t *qname, + dns_rdataset_t *rdataset) { + CTRACE(ISC_LOG_DEBUG(3), "query_stale_refresh"); + + bool stale_refresh_window = false; + bool stale_rrset = true; + + if (rdataset != NULL) { + stale_refresh_window = (STALE_WINDOW(rdataset) && + (client->query.dboptions & + DNS_DBFIND_STALEENABLED) != 0); + stale_rrset = STALE(rdataset); + } + + if (FETCH_RECTYPE_STALE_REFRESH(client) != NULL || + (client->query.dboptions & DNS_DBFIND_STALETIMEOUT) == 0 || + !stale_rrset || stale_refresh_window) + { + return; + } + + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + dns_name_format(qname, namebuf, sizeof(namebuf)); + dns_rdatatype_format(client->query.qtype, typebuf, sizeof(typebuf)); + isc_log_write(ns_lctx, NS_LOGCATEGORY_SERVE_STALE, NS_LOGMODULE_QUERY, + ISC_LOG_INFO, + "%s %s stale answer used, an attempt " + "to refresh the RRset will still be " + "made", + namebuf, typebuf); + + client->query.dboptions &= ~(DNS_DBFIND_STALETIMEOUT | + DNS_DBFIND_STALEOK | + DNS_DBFIND_STALEENABLED); + + fetch_and_forget(client, qname, client->query.qtype, + RECTYPE_STALE_REFRESH); +} + +static void +query_stale_refresh_ncache(ns_client_t *client) { + dns_name_t *qname; + + if (client->query.origqname != NULL) { + qname = client->query.origqname; + } else { + qname = client->query.qname; + } + query_stale_refresh(client, qname, NULL); +} + +static void query_prefetch(ns_client_t *client, dns_name_t *qname, dns_rdataset_t *rdataset) { CTRACE(ISC_LOG_DEBUG(3), "query_prefetch"); @@ -2839,6 +2898,8 @@ rdataset->ttl > client->view->prefetch_trigger || (rdataset->attributes & DNS_RDATASETATTR_PREFETCH) == 0) { + /* maybe refresh stale data */ + query_stale_refresh(client, qname, rdataset); return; } @@ -2847,30 +2908,8 @@ dns_rdataset_clearprefetch(rdataset); ns_stats_increment(client->manager->sctx->nsstats, ns_statscounter_prefetch); -} - -static void -query_stale_refresh(ns_client_t *client) { - dns_name_t *qname; - - CTRACE(ISC_LOG_DEBUG(3), "query_stale_refresh"); - if (FETCH_RECTYPE_STALE_REFRESH(client) != NULL) { - return; - } - - client->query.dboptions &= ~(DNS_DBFIND_STALETIMEOUT | - DNS_DBFIND_STALEOK | - DNS_DBFIND_STALEENABLED); - - if (client->query.origqname != NULL) { - qname = client->query.origqname; - } else { - qname = client->query.qname; - } - - fetch_and_forget(client, qname, client->query.qtype, - RECTYPE_STALE_REFRESH); + return; } static void @@ -4239,14 +4278,18 @@ bool resuming, dns_rdataset_t *ordataset, dns_rdataset_t *osigset) { dns_rpz_zones_t *rpzs; dns_rpz_st_t *st; - dns_rdataset_t *rdataset; + dns_rdataset_t *rdataset = NULL; dns_fixedname_t nsnamef; dns_name_t *nsname; - qresult_type_t qresult_type; + qresult_type_t qresult_type = qresult_type_done; dns_rpz_zbits_t zbits; isc_result_t result = ISC_R_SUCCESS; dns_rpz_have_t have; dns_rpz_popt_t popt; + bool first_time; + dns_rpz_num_t zones_registered; + dns_rpz_num_t zones_processed; + int rpz_ver; unsigned int options; #ifdef USE_DNSRPS @@ -4278,6 +4321,9 @@ } have = rpzs->have; popt = rpzs->p; + first_time = rpzs->first_time; + zones_registered = atomic_load_acquire(&rpzs->zones_registered); + zones_processed = atomic_load_acquire(&rpzs->zones_processed); rpz_ver = rpzs->rpz_ver; RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read); @@ -4325,6 +4371,23 @@ #endif /* ifdef USE_DNSRPS */ } + /* Check if the initial loading of RPZ is complete. */ + if (first_time && popt.servfail_until_ready && + zones_processed < zones_registered) + { + /* Do not pollute SERVFAIL cache */ + client->attributes |= NS_CLIENTATTR_NOSETFC; + + if (can_log_rpznotready()) { + rpz_log_fail(client, DNS_RPZ_INFO_LEVEL, NULL, + DNS_RPZ_TYPE_QNAME, + "RPZ servfail-until-ready", DNS_R_WAIT); + } + + st->m.policy = DNS_RPZ_POLICY_ERROR; + goto cleanup; + } + /* * There is nothing to rewrite if the main query failed. */ @@ -4374,8 +4437,6 @@ return ISC_R_SUCCESS; } - rdataset = NULL; - if ((st->state & (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) != (DNS_RPZ_DONE_CLIENT_IP | DNS_RPZ_DONE_QNAME)) { @@ -6068,19 +6129,19 @@ qctx->client->query.dboptions |= DNS_DBFIND_STALETIMEOUT; } - dboptions = qctx->client->query.dboptions; - if (!qctx->is_zone && qctx->findcoveringnsec && - (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname))) - { - dboptions |= DNS_DBFIND_COVERINGNSEC; - } - (void)dns_db_getservestalerefresh(qctx->client->view->cachedb, &stale_refresh); if (stale_refresh > 0 && dns_view_staleanswerenabled(qctx->client->view)) { - dboptions |= DNS_DBFIND_STALEENABLED; + qctx->client->query.dboptions |= DNS_DBFIND_STALEENABLED; + } + + dboptions = qctx->client->query.dboptions; + if (!qctx->is_zone && qctx->findcoveringnsec && + (qctx->type != dns_rdatatype_null || !dns_name_istat(rpzqname))) + { + dboptions |= DNS_DBFIND_COVERINGNSEC; } result = dns_db_findext(qctx->db, rpzqname, qctx->version, qctx->type, @@ -6235,14 +6296,6 @@ * Immediately return the stale answer, start a * resolver fetch to refresh the data in cache. */ - isc_log_write( - ns_lctx, NS_LOGCATEGORY_SERVE_STALE, - NS_LOGMODULE_QUERY, ISC_LOG_INFO, - "%s %s stale answer used, an attempt " - "to refresh the RRset will still be " - "made", - namebuf, typebuf); - qctx->refresh_rrset = STALE(qctx->rdataset); if (stale_found) { dns_ede_add( &qctx->client->edectx, ede, @@ -6255,16 +6308,6 @@ } } - if (stale_timeout && (answer_found || stale_found)) { - /* - * Mark RRsets that we are adding to the client message on a - * lookup during 'stale-answer-client-timeout', so we can - * clean it up if needed when we resume from recursion. - */ - qctx->client->query.attributes |= NS_QUERYATTR_STALEOK; - qctx->rdataset->attributes |= DNS_RDATASETATTR_STALE_ADDED; - } - result = query_gotanswer(qctx, result); cleanup: @@ -6272,60 +6315,6 @@ } /* - * Clear all rdatasets from the message that are in the given section and - * that have the 'attr' attribute set. - */ -static void -message_clearrdataset(dns_message_t *msg, unsigned int attr) { - unsigned int i; - dns_name_t *name, *next_name; - dns_rdataset_t *rds, *next_rds; - - /* - * Clean up name lists by calling the rdataset disassociate function. - */ - for (i = DNS_SECTION_ANSWER; i < DNS_SECTION_MAX; i++) { - name = ISC_LIST_HEAD(msg->sections[i]); - while (name != NULL) { - next_name = ISC_LIST_NEXT(name, link); - - rds = ISC_LIST_HEAD(name->list); - while (rds != NULL) { - next_rds = ISC_LIST_NEXT(rds, link); - if ((rds->attributes & attr) != attr) { - rds = next_rds; - continue; - } - ISC_LIST_UNLINK(name->list, rds, link); - INSIST(dns_rdataset_isassociated(rds)); - dns_rdataset_disassociate(rds); - isc_mempool_put(msg->rdspool, rds); - rds = next_rds; - } - - if (ISC_LIST_EMPTY(name->list)) { - ISC_LIST_UNLINK(msg->sections[i], name, link); - if (dns_name_dynamic(name)) { - dns_name_free(name, msg->mctx); - } - isc_mempool_put(msg->namepool, name); - } - - name = next_name; - } - } -} - -/* - * Clear any rdatasets from the client's message that were added on a lookup - * due to a client timeout. - */ -static void -query_clear_stale(ns_client_t *client) { - message_clearrdataset(client->message, DNS_RDATASETATTR_STALE_ADDED); -} - -/* * Event handler to resume processing a query after recursion, or when a * client timeout is triggered. If the query has timed out or been cancelled * or the system is shutting down, clean up and exit. If a client timeout is @@ -6356,6 +6345,7 @@ client->query.attributes |= NS_QUERYATTR_RECURSIONOK; } client->query.dboptions &= ~DNS_DBFIND_STALETIMEOUT; + client->query.dboptions &= ~DNS_DBFIND_STALEENABLED; LOCK(&client->query.fetchlock); INSIST(FETCH_RECTYPE_NORMAL(client) == resp->fetch || @@ -7234,7 +7224,7 @@ wouldlog, log_buf, sizeof(log_buf)); if (rrl_result != DNS_RRL_RESULT_OK) { /* - * Log dropped or slipped responses in the query + * Log dropped or slipped responses in the query-errors * category so that requests are not silently lost. * Starts of rate-limited bursts are logged in * DNS_LOGCATEGORY_RRL. @@ -7244,7 +7234,8 @@ * with other truncated responses in RespTruncated. */ if (wouldlog) { - ns_client_log(qctx->client, DNS_LOGCATEGORY_RRL, + ns_client_log(qctx->client, + NS_LOGCATEGORY_QUERY_ERRORS, NS_LOGMODULE_QUERY, DNS_RRL_LOG_DROP, "%s", log_buf); } @@ -7298,6 +7289,16 @@ return ISC_R_SUCCESS; } +static void +query_rpz_add_ede(query_ctx_t *qctx) { + if (qctx->rpz_st->m.rpz->ede != 0 && + qctx->rpz_st->m.rpz->ede != UINT16_MAX) + { + dns_ede_add(&qctx->client->edectx, qctx->rpz_st->m.rpz->ede, + NULL); + } +} + /*% * Do any RPZ rewriting that may be needed for this query. */ @@ -7450,6 +7451,8 @@ result = dns_rdata_tostruct(&rdata, &cname, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdata_reset(&rdata); + + query_rpz_add_ede(qctx); result = query_rpzcname(qctx, &cname.cname); if (result != ISC_R_SUCCESS) { return ISC_R_COMPLETE; @@ -7463,6 +7466,7 @@ * Add overriding CNAME from a named.conf * response-policy statement */ + query_rpz_add_ede(qctx); result = query_rpzcname(qctx, &qctx->rpz_st->m.rpz->cname); if (result != ISC_R_SUCCESS) { @@ -7475,12 +7479,7 @@ UNREACHABLE(); } - if (qctx->rpz_st->m.rpz->ede != 0 && - qctx->rpz_st->m.rpz->ede != UINT16_MAX) - { - dns_ede_add(&qctx->client->edectx, - qctx->rpz_st->m.rpz->ede, NULL); - } + query_rpz_add_ede(qctx); /* * Turn off DNSSEC because the results of a @@ -8207,24 +8206,6 @@ CALL_HOOK(NS_QUERY_ADDANSWER_BEGIN, qctx); - /* - * On normal lookups, clear any rdatasets that were added on a - * lookup due to stale-answer-client-timeout. Do not clear if we - * are going to refresh the RRset, because the stale contents are - * prioritized. - */ - if (QUERY_STALEOK(&qctx->client->query) && - !QUERY_STALETIMEOUT(&qctx->client->query) && !qctx->refresh_rrset) - { - CCTRACE(ISC_LOG_DEBUG(3), "query_clear_stale"); - query_clear_stale(qctx->client); - /* - * We can clear the attribute to prevent redundant clearing - * in subsequent lookups. - */ - qctx->client->query.attributes &= ~NS_QUERYATTR_STALEOK; - } - if (qctx->dns64) { result = query_dns64(qctx); qctx->noqname = NULL; @@ -8258,9 +8239,7 @@ query_filter64(qctx); ns_client_putrdataset(qctx->client, &qctx->rdataset); } else { - if (!qctx->is_zone && RECURSIONOK(qctx->client) && - !QUERY_STALETIMEOUT(&qctx->client->query)) - { + if (!qctx->is_zone && RECURSIONOK(qctx->client)) { query_prefetch(qctx->client, qctx->fname, qctx->rdataset); } @@ -10429,6 +10408,10 @@ } } + if (!qctx->is_zone && RECURSIONOK(qctx->client)) { + query_stale_refresh_ncache(qctx->client); + } + return query_nodata(qctx, result); cleanup: @@ -11830,20 +11813,6 @@ query_send(qctx->client); - if (qctx->refresh_rrset) { - /* - * If we reached this point then it means that we have found a - * stale RRset entry in cache and BIND is configured to allow - * queries to be answered with stale data if no active RRset - * is available, i.e. "stale-anwer-client-timeout 0". But, we - * still need to refresh the RRset. To prevent adding duplicate - * RRsets, clear the RRsets from the message before doing the - * refresh. - */ - message_clearrdataset(qctx->client->message, 0); - query_stale_refresh(qctx->client); - } - qctx->detach_client = true; return qctx->result; diff -Nru bind9-9.20.11/ltmain.sh bind9-9.20.15/ltmain.sh --- bind9-9.20.11/ltmain.sh 2025-07-04 09:43:08.239742250 +0000 +++ bind9-9.20.15/ltmain.sh 2025-10-18 10:16:59.647436241 +0000 @@ -2,11 +2,11 @@ ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in ## by inline-source v2019-02-19.15 -# libtool (GNU libtool) 2.4.7 +# libtool (GNU libtool) 2.5.4 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996-2019, 2021-2022 Free Software Foundation, Inc. +# Copyright (C) 1996-2019, 2021-2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -31,8 +31,8 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.7 Debian-2.4.7-7~deb12u1" -package_revision=2.4.7 +VERSION="2.5.4 Debian-2.5.4-4" +package_revision=2.5.4 ## ------ ## @@ -64,7 +64,7 @@ # libraries, which are installed to $pkgauxdir. # Set a version string for this script. -scriptversion=2019-02-19.15; # UTC +scriptversion=2024-12-01.17; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 @@ -72,11 +72,11 @@ # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Copyright (C) 2004-2019, 2021 Bootstrap Authors +# Copyright (C) 2004-2019, 2021, 2023-2024 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license -# , and GPL version 2 or later -# . You must apply one of +# , and GPL version 2 or later +# . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. @@ -143,7 +143,7 @@ ' IFS="$sp $nl" -# There are apparently some retarded systems that use ';' as a PATH separator! +# There are apparently some systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { @@ -572,15 +572,16 @@ # --------------------- # Append VALUE onto the existing contents of VAR. + # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is - # useable or anything else if it does not work. - if test -z "$_G_HAVE_PLUSEQ_OP" && \ - __PLUSEQ_TEST="a" && \ - __PLUSEQ_TEST+=" b" 2>/dev/null && \ - test "a b" = "$__PLUSEQ_TEST"; then - _G_HAVE_PLUSEQ_OP=yes - fi + # usable or anything else if it does not work. +if test -z "$_G_HAVE_PLUSEQ_OP" && \ + __PLUSEQ_TEST="a" && \ + __PLUSEQ_TEST+=" b" 2>/dev/null && \ + test "a b" = "$__PLUSEQ_TEST"; then + _G_HAVE_PLUSEQ_OP=yes +fi if test yes = "$_G_HAVE_PLUSEQ_OP" then @@ -727,7 +728,7 @@ # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. -# value retuned in "$func_basename_result" +# value returned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () @@ -885,7 +886,7 @@ # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. + # list in case some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done @@ -1524,11 +1525,11 @@ # This is free software. There is NO warranty; not even for # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # -# Copyright (C) 2010-2019, 2021 Bootstrap Authors +# Copyright (C) 2010-2019, 2021, 2023-2024 Bootstrap Authors # # This file is dual licensed under the terms of the MIT license -# , and GPL version 2 or later -# . You must apply one of +# , and GPL version 2 or later +# . You must apply one of # these licenses when using or redistributing this software or any of # the files within it. See the URLs above, or the file `LICENSE` # included in the Bootstrap distribution for the full license texts. @@ -2205,7 +2206,30 @@ # End: # Set a version string. -scriptversion='(GNU libtool) 2.4.7' +scriptversion='(GNU libtool) 2.5.4' + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + year=`date +%Y` + + cat < +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Originally written by Gordon Matzigkeit, 1996 +(See AUTHORS for complete contributor listing) +EOF + + exit $? +} # func_echo ARG... @@ -2228,18 +2252,6 @@ } -# func_warning ARG... -# ------------------- -# Libtool warnings are not categorized, so override funclib.sh -# func_warning with this simpler definition. -func_warning () -{ - $debug_cmd - - $warning_func ${1+"$@"} -} - - ## ---------------- ## ## Options parsing. ## ## ---------------- ## @@ -2251,19 +2263,23 @@ # Short help message in response to '-h'. usage_message="Options: - --config show all configuration variables - --debug enable verbose shell tracing - -n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --mode=MODE use operation mode MODE - --no-warnings equivalent to '-Wnone' - --preserve-dup-deps don't remove duplicate dependency libraries - --quiet, --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - -v, --verbose print more informational messages than default - --version print version information - -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] - -h, --help, --help-all print short, long, or detailed help message + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information + --finish use operation '--mode=finish' + --mode=MODE use operation mode MODE + --no-finish don't update shared library cache + --no-quiet, --no-silent print default informational messages + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --reorder-cache=DIRS reorder shared library cache for preferred DIRS + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. @@ -2296,13 +2312,13 @@ compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname $scriptversion Debian-2.4.7-7~deb12u1 + version: $progname $scriptversion Debian-2.5.4-4 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . -GNU libtool home page: . -General help using GNU software: ." +GNU libtool home page: . +General help using GNU software: ." exit 0 } @@ -2492,8 +2508,11 @@ opt_dry_run=false opt_help=false opt_mode= + opt_reorder_cache=false opt_preserve_dup_deps=false opt_quiet=false + opt_finishing=true + opt_warning= nonopt= preserve_args= @@ -2585,14 +2604,18 @@ clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error - *) func_error "invalid argument for $_G_opt" + *) func_error "invalid argument '$1' for $_G_opt" exit_cmd=exit - break ;; esac shift ;; + --no-finish) + opt_finishing=false + func_append preserve_args " $_G_opt" + ;; + --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" @@ -2608,6 +2631,24 @@ func_append preserve_args " $_G_opt" ;; + --reorder-cache) + opt_reorder_cache=true + shared_lib_dirs=$1 + if test -n "$shared_lib_dirs"; then + case $1 in + # Must begin with /: + /*) ;; + + # Catch anything else as an error (relative paths) + *) func_error "invalid argument '$1' for $_G_opt" + func_error "absolute paths are required for $_G_opt" + exit_cmd=exit + ;; + esac + fi + shift + ;; + --silent|--quiet) opt_quiet=: opt_verbose=false @@ -2644,6 +2685,18 @@ func_add_hook func_parse_options libtool_parse_options +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + if $opt_warning; then + $debug_cmd + $warning_func ${1+"$@"} + fi +} + # libtool_validate_options [ARG]... # --------------------------------- @@ -2660,10 +2713,10 @@ # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" - case $host in + case $host_os in # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 - *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + cygwin* | mingw* | windows* | pw32* | cegcc* | solaris2* | os2*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; @@ -2995,7 +3048,7 @@ # func_convert_core_file_wine_to_w32 ARG # Helper function used by file name conversion functions when $build is *nix, -# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# and $host is mingw, windows, cygwin, or some other w32 environment. Relies on a # correctly configured wine environment available, with the winepath program # in $build's $PATH. # @@ -3027,9 +3080,10 @@ # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. +# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. Assumes ARG has no leading or trailing path separator +# characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. @@ -3172,6 +3226,15 @@ # end func_convert_path_front_back_pathsep +# func_convert_delimited_path PATH ORIG_DELIMITER NEW_DELIMITER +# Replaces a delimiter for a given path. +func_convert_delimited_path () +{ + converted_path=`$ECHO "$1" | $SED "s#$2#$3#g"` +} +# end func_convert_delimited_path + + ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## @@ -3506,6 +3569,65 @@ } +# func_reorder_shared_lib_cache DIRS +# Reorder the shared library cache by unconfiguring previous shared library cache +# and configuring preferred search directories before previous search directories. +# Previous shared library cache: /usr/lib /usr/local/lib +# Preferred search directories: /tmp/testing +# Reordered shared library cache: /tmp/testing /usr/lib /usr/local/lib +func_reorder_shared_lib_cache () +{ + $debug_cmd + + case $host_os in + openbsd*) + get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` + func_convert_delimited_path "$get_search_directories" ':' '\ ' + save_search_directories=$converted_path + func_convert_delimited_path "$1" ':' '\ ' + + # Ensure directories exist + for dir in $converted_path; do + # Ensure each directory is an absolute path + case $dir in + /*) ;; + *) func_error "Directory '$dir' is not an absolute path" + exit $EXIT_FAILURE ;; + esac + # Ensure no trailing slashes + func_stripname '' '/' "$dir" + dir=$func_stripname_result + if test -d "$dir"; then + if test -n "$preferred_search_directories"; then + preferred_search_directories="$preferred_search_directories $dir" + else + preferred_search_directories=$dir + fi + else + func_error "Directory '$dir' does not exist" + exit $EXIT_FAILURE + fi + done + + PATH="$PATH:/sbin" ldconfig -U $save_search_directories + PATH="$PATH:/sbin" ldconfig -m $preferred_search_directories $save_search_directories + get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` + func_convert_delimited_path "$get_search_directories" ':' '\ ' + reordered_search_directories=$converted_path + + $ECHO "Original: $save_search_directories" + $ECHO "Reordered: $reordered_search_directories" + exit $EXIT_SUCCESS + ;; + *) + func_error "--reorder-cache is not supported for host_os=$host_os." + exit $EXIT_FAILURE + ;; + esac +} +# end func_reorder_shared_lib_cache + + # func_mode_compile arg... func_mode_compile () { @@ -3684,7 +3806,7 @@ # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) + cygwin* | mingw* | windows* | pw32* | os2* | cegcc*) pic_mode=default ;; esac @@ -4078,6 +4200,12 @@ fi +# If option '--reorder-cache', reorder the shared library cache and exit. +if $opt_reorder_cache; then + func_reorder_shared_lib_cache $shared_lib_dirs +fi + + # func_mode_execute arg... func_mode_execute () { @@ -4262,7 +4390,7 @@ fi fi - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs" && $opt_finishing; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. @@ -4287,6 +4415,12 @@ for libdir in $libdirs; do $ECHO " $libdir" done + if test "false" = "$opt_finishing"; then + echo + echo "NOTE: finish_cmds were not executed during testing, so you must" + echo "manually run ldconfig to add a given test directory, LIBDIR, to" + echo "the search path for generated executables." + fi echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" @@ -4523,8 +4657,15 @@ func_append dir "$objdir" if test -n "$relink_command"; then + # Strip any trailing slash from the destination. + func_stripname '' '/' "$libdir" + destlibdir=$func_stripname_result + + func_stripname '' '/' "$destdir" + s_destdir=$func_stripname_result + # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that @@ -4561,7 +4702,7 @@ 'exit $?' tstripme=$stripme case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= @@ -4674,7 +4815,7 @@ # Do a test to see if this is really a libtool program. case $host in - *cygwin* | *mingw*) + *cygwin* | *mingw* | *windows*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result @@ -4902,7 +5043,7 @@ $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; @@ -4914,7 +5055,7 @@ eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; @@ -4928,7 +5069,7 @@ func_basename "$dlprefile" name=$func_basename_result case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" @@ -4954,8 +5095,16 @@ eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + case $host in + i[3456]86-*-mingw32*) + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + ;; + *) + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/__nm_//' >> '$nlist'" + ;; + esac } else # not an import lib $opt_dry_run || { @@ -5103,7 +5252,7 @@ # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` @@ -5179,7 +5328,7 @@ *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || @@ -5446,7 +5595,7 @@ # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw +# incorporate the script contents within a cygwin/mingw/windows # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. @@ -5454,7 +5603,7 @@ # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is -# the $objdir directory. This is a cygwin/mingw-specific +# the $objdir directory. This is a cygwin/mingw/windows-specific # behavior. func_emit_wrapper () { @@ -5579,7 +5728,7 @@ " case $host in # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) + *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 @@ -5647,7 +5796,7 @@ file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done - # Usually 'no', except on cygwin/mingw when embedded into + # Usually 'no', except on cygwin/mingw/windows when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then @@ -5779,7 +5928,7 @@ #endif #include #include -#ifdef _MSC_VER +#if defined _WIN32 && !defined __GNUC__ # include # include # include @@ -5804,7 +5953,7 @@ /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ -int _putenv (const char *); +_CRTIMP int __cdecl _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ @@ -6002,7 +6151,7 @@ { EOF case $host in - *mingw* | *cygwin* ) + *mingw* | *windows* | *cygwin* ) # make stdout use "unix" line endings echo " setmode(1,_O_BINARY);" ;; @@ -6021,7 +6170,7 @@ { /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX namespace, but it is not one of the ones we know about and - have already dealt with, above (inluding dump-script), then + have already dealt with, above (including dump-script), then report an error. Otherwise, targets might begin to believe they are allowed to use options in the LTWRAPPER_OPTION_PREFIX namespace. The first time any user complains about this, we'll @@ -6105,7 +6254,7 @@ EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" { char* p; @@ -6147,7 +6296,7 @@ EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ newargz = prepare_spawn (newargz); @@ -6566,7 +6715,7 @@ EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). @@ -6741,7 +6890,7 @@ $debug_cmd case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra @@ -6765,6 +6914,7 @@ finalize_command=$nonopt compile_rpath= + compile_rpath_tail= finalize_rpath= compile_shlibpath= finalize_shlibpath= @@ -6805,10 +6955,12 @@ xrpath= perm_rpath= temp_rpath= + temp_rpath_tail= thread_safe=no vinfo= vinfo_number=no weak_libs= + rpath_arg= single_module=$wl-single_module func_infer_tag $base_compile @@ -7071,7 +7223,7 @@ case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) - func_fatal_error "only absolute run-paths are allowed" + func_fatal_error "argument to -rpath is not absolute: $arg" ;; esac if test rpath = "$prev"; then @@ -7247,7 +7399,7 @@ ;; esac case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; @@ -7267,7 +7419,7 @@ -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; @@ -7275,7 +7427,7 @@ # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; @@ -7295,7 +7447,7 @@ esac elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig* | *-*-midnightbsd*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -7318,7 +7470,8 @@ # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) + # -q