Compare commits

..

23 commits

Author SHA1 Message Date
Petr Menšík
58300b9839 Update to 9.16.40
https://downloads.isc.org/isc/bind9/9.16.40/RELEASE-NOTES-bind-9.16.40.html
2023-04-24 13:19:54 +02:00
Petr Menšík
92639ae70f Update to 9.16.38
https://downloads.isc.org/isc/bind9/9.16.38/doc/arm/html/notes.html#notes-for-bind-9-16-38
2023-02-25 01:54:00 +01:00
Petr Menšík
55ecf73675 Update to 9.16.37
Resolves: CVE-2022-3094 CVE-2022-3736 CVE-2022-3924

https://downloads.isc.org/isc/bind9/9.16.37/RELEASE-NOTES-bind-9.16.37.html
2023-01-28 11:57:48 +01:00
Petr Menšík
ccd4aaa109 Ensure isc_rwlocktype_t is defined always
Prevent issues in compilation after dns/zt.h change.
2023-01-16 22:00:46 +01:00
Petr Menšík
9c7d44bc8a Update to 9.16.36
https://downloads.isc.org/isc/bind9/9.16.36/doc/arm/html/notes.html#notes-for-bind-9-16-36

Feature Changes:

- The auto-dnssec option has been deprecated and will be removed in a future BIND 9.19.x
release. Please migrate to dnssec-policy. [GL #3667]
2023-01-16 19:28:05 +01:00
Petr Menšík
d0e0bd6b49 Update to 9.16.35
https://downloads.isc.org/isc/bind9/9.16.35/doc/arm/html/notes.html#notes-for-bind-9-16-35
2022-11-21 16:00:46 +01:00
Petr Menšík
19eff7d339 fixup! Update to 9.16.33 2022-09-22 17:51:52 +02:00
Petr Menšík
15f733ffc3 Update to 9.16.33
Resolves: CVE-2022-2795 CVE-2022-3080 CVE-2022-38178 CVE-2022-38177
2022-09-22 14:57:06 +02:00
Petr Menšík
30ac5135b3 Skip some parts in netmgr unittest
Attempt to make test less likely to fail randomly.
2022-09-01 21:29:25 +02:00
Petr Menšík
fcf5c315c9 Update to 9.16.32 2022-08-31 12:15:40 +02:00
Petr Menšík
d9556ddf55 Update to 9.16.31
https://downloads.isc.org/isc/bind9/9.16.31/doc/arm/html/notes.html#notes-for-bind-9-16-31
2022-08-03 21:02:06 +02:00
Petr Menšík
82c5a16a04 fixup! Update to 9.16.30 (#2097312) 2022-06-20 16:59:25 +02:00
Petr Menšík
1be0b2277b Update to 9.16.30 (#2097312)
https://downloads.isc.org/isc/bind9/9.16.30/doc/arm/html/notes.html#notes-for-bind-9-16-30
2022-06-20 16:43:54 +02:00
Petr Menšík
a7c4124c55 Correct failing test
Prevent failures of netmgr_test. Enable unit tests again, since issue
with kyua seems to be fixed.

Resolves: rhbz#2088125
2022-05-27 21:26:14 +02:00
Petr Menšík
038ac626e2 Update to 9.16.29
Previously, CDS and CDNSKEY DELETE records were removed from
the zone when configured with the auto-dnssec maintain; option.
This has been fixed. [GL #2931]

https://downloads.isc.org/isc/bind9/9.16.29/doc/arm/html/notes.html#notes-for-bind-9-16-29

Resolves: rhbz#2087920
2022-05-27 21:26:14 +02:00
Petr Menšík
edcae64e28 Reeanble unit tests 2022-05-27 21:26:14 +02:00
Petr Menšík
80d31db91c Parse again timeout and attempts from resolv.conf
Resolves rhbz#2087156
2022-05-27 21:26:14 +02:00
Petr Menšík
7a6a893e0c Update to 9.16.28 (#2076941)
https://downloads.isc.org/isc/bind9/9.16.28/doc/arm/html/notes.html#notes-for-bind-9-16-28
2022-04-21 16:42:16 +02:00
Petr Menšík
8e186e2674 Upgrade to 9.16.27 (#2055120)
https://downloads.isc.org/isc/bind9/9.16.27/doc/arm/html/notes.html#notes-for-bind-9-16-27

Resolves: CVE-2021-25220 CVE-2022-0396
2022-03-18 12:46:02 +01:00
Petr Menšík
78371e3b8c Replace downstream change with upstream proposal
bind-dyndb-ldap requires sending from custom spawned thread to main
named threads. Change queue type to locked variant, which would not
crash when isc_send_task() is called from dyndb worker thread.

Related: rhbz#2048235
2022-03-18 12:46:02 +01:00
Petr Menšík
6032990be4 Renumber native PKCS11 patches to beginning
Allow all subsequent patches with higher number to be added to normal
common list of patches. Make just initial patches special.

Ensure all patch chunks use -p1 prefix.
2022-03-18 12:46:00 +01:00
Petr Menšík
4734ec9b83 Switch to %autosetup
Renumber high numbered patches to two digits patch. It does not really
matter for autosetup. Simplify applying of new patches.

Remove threaded patch, would not be required by new release.
2022-03-18 12:45:44 +01:00
Petr Menšík
fea96eafb7 Remove unused patches 2022-03-18 12:31:58 +01:00
65 changed files with 5497 additions and 13043 deletions

80
.gitignore vendored
View file

@ -166,8 +166,6 @@ bind-9.7.2b1.tar.gz
/bind-9.16.24.tar.xz.asc
/bind-9.16.25.tar.xz
/bind-9.16.25.tar.xz.asc
/bind-9.16.26.tar.xz
/bind-9.16.26.tar.xz.asc
/bind-9.16.27.tar.xz
/bind-9.16.27.tar.xz.asc
/bind-9.16.28.tar.xz
@ -176,65 +174,19 @@ bind-9.7.2b1.tar.gz
/bind-9.16.29.tar.xz.asc
/bind-9.16.30.tar.xz
/bind-9.16.30.tar.xz.asc
/bind-9.18.0.tar.xz
/bind-9.18.0.tar.xz.asc
/bind-9.18.1.tar.xz
/bind-9.18.1.tar.xz.asc
/bind-9.18.2.tar.xz
/bind-9.18.2.tar.xz.asc
/bind-9.18.3.tar.xz
/bind-9.18.3.tar.xz.asc
/bind-9.18.4.tar.xz
/bind-9.18.4.tar.xz.asc
/bind-9.18.5.tar.xz
/bind-9.18.5.tar.xz.asc
/bind-9.18.6.tar.xz
/bind-9.18.6.tar.xz.asc
/bind-9.18.7.tar.xz
/bind-9.18.7.tar.xz.asc
/bind-9.18.8.tar.xz
/bind-9.18.8.tar.xz.asc
/bind-9.18.9.tar.xz
/bind-9.18.9.tar.xz.asc
/bind-9.18.10.tar.xz
/bind-9.18.10.tar.xz.asc
/bind-9.18.11.tar.xz
/bind-9.18.11.tar.xz.asc
/bind-9.18.12.tar.xz
/bind-9.18.12.tar.xz.asc
/bind-9.18.13.tar.xz
/bind-9.18.13.tar.xz.asc
/bind-9.18.14.tar.xz
/bind-9.18.14.tar.xz.asc
/bind-9.18.15.tar.xz
/bind-9.18.15.tar.xz.asc
/bind-9.18.16.tar.xz
/bind-9.18.16.tar.xz.asc
/bind-9.18.17.tar.xz
/bind-9.18.17.tar.xz.asc
/bind-9.18.18.tar.xz
/bind-9.18.18.tar.xz.asc
/bind-9.18.19.tar.xz
/bind-9.18.19.tar.xz.asc
/bind-9.18.20.tar.xz
/bind-9.18.20.tar.xz.asc
/bind-9.18.21.tar.xz
/bind-9.18.21.tar.xz.asc
/bind-9.18.24.tar.xz
/bind-9.18.24.tar.xz.asc
/bind-9.18.26.tar.xz
/bind-9.18.26.tar.xz.asc
/bind-9.18.28.tar.xz
/bind-9.18.28.tar.xz.asc
/bind-9.18.29.tar.xz
/bind-9.18.29.tar.xz.asc
/bind-9.18.30.tar.xz
/bind-9.18.30.tar.xz.asc
/bind-9.18.31.tar.xz
/bind-9.18.31.tar.xz.asc
/bind-9.18.32.tar.xz
/bind-9.18.32.tar.xz.asc
/bind-9.18.33.tar.xz
/bind-9.18.33.tar.xz.asc
/bind-9.18.*.tar.xz
/bind-9.18.*.tar.xz.asc
/bind-9.16.31.tar.xz
/bind-9.16.31.tar.xz.asc
/bind-9.16.32.tar.xz
/bind-9.16.32.tar.xz.asc
/bind-9.16.33.tar.xz
/bind-9.16.33.tar.xz.asc
/bind-9.16.35.tar.xz
/bind-9.16.35.tar.xz.asc
/bind-9.16.36.tar.xz
/bind-9.16.36.tar.xz.asc
/bind-9.16.37.tar.xz
/bind-9.16.37.tar.xz.asc
/bind-9.16.38.tar.xz
/bind-9.16.38.tar.xz.asc
/bind-9.16.40.tar.xz
/bind-9.16.40.tar.xz.asc

View file

@ -1,61 +0,0 @@
From 31bd3a0996a85c0fced0c6ace3da1241b30dc397 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Thu, 30 Apr 2026 17:28:40 +0200
Subject: [PATCH] Use variable PROGRAM_SUFFIX in install target
--program-suffix is handled by configure itself. But some makefile rules
need to know it by a special value. Provide that to make multiple
versions installable together on a single system.
---
Makefile.top | 1 +
bin/check/Makefile.am | 6 +++---
bin/confgen/Makefile.am | 6 +++---
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/Makefile.top b/Makefile.top
index e186d15..91c076b 100644
--- a/Makefile.top
+++ b/Makefile.top
@@ -14,6 +14,7 @@ AM_CPPFLAGS = \
AM_LDFLAGS = \
$(STD_LDFLAGS)
LDADD =
+PROGRAM_SUFFIX =
if HOST_MACOS
AM_LDFLAGS += \
diff --git a/bin/check/Makefile.am b/bin/check/Makefile.am
index 8f63c35..36f232c 100644
--- a/bin/check/Makefile.am
+++ b/bin/check/Makefile.am
@@ -27,8 +27,8 @@ LDADD += \
bin_PROGRAMS = named-checkconf named-checkzone
install-exec-hook:
- ln -f $(DESTDIR)$(bindir)/named-checkzone \
- $(DESTDIR)$(bindir)/named-compilezone
+ ln -f $(DESTDIR)$(bindir)/named-checkzone$(PROGRAM_SUFFIX) \
+ $(DESTDIR)$(bindir)/named-compilezone$(PROGRAM_SUFFIX)
uninstall-hook:
- -rm -f $(DESTDIR)$(bindir)/named-compilezone
+ -rm -f $(DESTDIR)$(bindir)/named-compilezone$(PROGRAM_SUFFIX)
diff --git a/bin/confgen/Makefile.am b/bin/confgen/Makefile.am
index c1dca43..fe86dd7 100644
--- a/bin/confgen/Makefile.am
+++ b/bin/confgen/Makefile.am
@@ -23,8 +23,8 @@ libconfgen_la_SOURCES = \
sbin_PROGRAMS = tsig-keygen rndc-confgen
install-exec-hook:
- ln -f $(DESTDIR)$(sbindir)/tsig-keygen \
- $(DESTDIR)$(sbindir)/ddns-confgen
+ ln -f $(DESTDIR)$(sbindir)/tsig-keygen$(PROGRAM_SUFFIX) \
+ $(DESTDIR)$(sbindir)/ddns-confgen$(PROGRAM_SUFFIX)
uninstall-hook:
- -rm -f $(DESTDIR)$(sbindir)/ddns-confgen
+ -rm -f $(DESTDIR)$(sbindir)/ddns-confgen$(PROGRAM_SUFFIX)
--
2.54.0

View file

@ -14,13 +14,6 @@ More details about upstream project can be found on their
only upstream sources and packaging instructions for
[Fedora Project](https://fedoraproject.org).
Any rebase requires to be built together with
[bind-dyndb-ldap](https://src.fedoraproject.org/rpms/bind-dyndb-ldap/) to prevent conflict
at installation of [freeipa-server-dns](https://src.fedoraproject.org/rpms/freeipa).
Stable bodhi updates are checked, but rawhide are not checked explicitly.
Symbol of libraries in *bind-libs* changes with every minor version change of bind,
therefore they break any package dependent on bind-libs.
## Subpackages
The package contains several subpackages, some of them can be disabled on rebuild.
@ -28,11 +21,15 @@ The package contains several subpackages, some of them can be disabled on rebuil
* **bind** -- *named* daemon providing DNS server
* **bind-utils** -- set of tools to analyse DNS responses or update entries (dig, host)
* **bind-doc** -- documentation for current bind, *BIND 9 Administrator Reference Manual*.
* **bind-libs** -- Shared libraries used by some others programs
* **bind-devel** -- Development headers for libs. Can be disabled by `--without DEVEL`
* **bind-license** -- Shared license for all packages but bind-export-libs.
* **bind-pkcs11** -- *named* daemon built with native PKCS#11 support. Can be disabled by `--without PKCS11`.
* **bind-libs** and **bind-libs-lite** -- Shared libraries used by some others programs
* **bind-devel** -- Development headers for libs.
* **bind-dlz-\*** -- Dynamic loadable [DLZ plugins](http://bind-dlz.sourceforge.net/) with support for external databases
## Optional features
* *GSSTSIG* -- Support for Kerberos authentication in BIND.
* *LMDB* -- Support for dynamic database for managing runtime added zones. Provides faster removal of added zone with much less overhead. But requires lmdb linked to base libs.
* *DLZ* -- Support for dynamic loaded modules providing support for features *bind-sdb* provides, but only small module is required.

View file

@ -0,0 +1,541 @@
From 1cbffe7e8b5bced9134abbae23a2a20c83d39a6a Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Thu, 21 Jan 2021 10:46:20 +0100
Subject: [PATCH] Enable custom pkcs11 native build
Share common parts like libisc, libcc and others. But provide native
pkcs11 libraries as a new copy of libdns and libns.
---
bin/Makefile.in | 2 +-
bin/confgen/Makefile.in | 2 +-
bin/dnssec-pkcs11/Makefile.in | 39 +++++++++++++++++---------------
bin/named-pkcs11/Makefile.in | 31 +++++++++++++------------
configure.ac | 19 ++++++++++++++++
lib/Makefile.in | 2 +-
lib/dns-pkcs11/Makefile.in | 22 +++++++++---------
lib/dns-pkcs11/tests/Makefile.in | 8 +++----
lib/ns-pkcs11/Makefile.in | 26 ++++++++++-----------
lib/ns-pkcs11/tests/Makefile.in | 12 +++++-----
make/includes.in | 7 ++++++
11 files changed, 100 insertions(+), 70 deletions(-)
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 9ad7f62..094775a 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -11,7 +11,7 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
-SUBDIRS = named rndc dig delv dnssec tools nsupdate check confgen \
+SUBDIRS = named named-pkcs11 rndc dig delv dnssec dnssec-pkcs11 tools nsupdate check confgen \
@NZD_TOOLS@ @PYTHON_TOOLS@ @PKCS11_TOOLS@ plugins tests
TARGETS =
diff --git a/bin/confgen/Makefile.in b/bin/confgen/Makefile.in
index c126bf3..1b7512d 100644
--- a/bin/confgen/Makefile.in
+++ b/bin/confgen/Makefile.in
@@ -22,7 +22,7 @@ VERSION=@BIND9_VERSION@
CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \
${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES}
-CDEFINES = @USE_PKCS11@
+CDEFINES =
CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
diff --git a/bin/dnssec-pkcs11/Makefile.in b/bin/dnssec-pkcs11/Makefile.in
index ace0e5a..e0f6a00 100644
--- a/bin/dnssec-pkcs11/Makefile.in
+++ b/bin/dnssec-pkcs11/Makefile.in
@@ -15,18 +15,18 @@ VERSION=@BIND9_VERSION@
@BIND9_MAKE_INCLUDES@
-CINCLUDES = ${DNS_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
+CINCLUDES = ${DNS_PKCS11_INCLUDES} ${ISC_INCLUDES} ${ISCCFG_INCLUDES} \
${OPENSSL_CFLAGS}
-CDEFINES = -DVERSION=\"${VERSION}\" -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\"
+CDEFINES = -DVERSION=\"${VERSION}\" -DNAMED_CONFFILE=\"${sysconfdir}/named.conf\" -DUSE_PKCS11=1
CWARNINGS =
-DNSLIBS = ../../lib/dns/libdns.@A@ @NO_LIBTOOL_DNSLIBS@
+DNSLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@ @NO_LIBTOOL_DNSLIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCLIBS = ../../lib/isc/libisc.@A@ @NO_LIBTOOL_ISCLIBS@
ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ @NO_LIBTOOL_ISCLIBS@
-DNSDEPLIBS = ../../lib/dns/libdns.@A@
+DNSDEPLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
@@ -36,12 +36,15 @@ LIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @LIBS@
NOSYMLIBS = ${DNSLIBS} ${ISCCFGLIBS} ${ISCNOSYMLIBS} @LIBS@
+# Add suffix to all targets
+EXEEXT = -pkcs11@EXEEXT@
+
# Alphabetically
-TARGETS = dnssec-cds@EXEEXT@ dnssec-dsfromkey@EXEEXT@ \
- dnssec-importkey@EXEEXT@ dnssec-keyfromlabel@EXEEXT@ \
- dnssec-keygen@EXEEXT@ dnssec-revoke@EXEEXT@ \
- dnssec-settime@EXEEXT@ dnssec-signzone@EXEEXT@ \
- dnssec-verify@EXEEXT@
+TARGETS = dnssec-cds${EXEEXT} dnssec-dsfromkey${EXEEXT} \
+ dnssec-importkey${EXEEXT} dnssec-keyfromlabel${EXEEXT} \
+ dnssec-keygen${EXEEXT} dnssec-revoke${EXEEXT} \
+ dnssec-settime${EXEEXT} dnssec-signzone${EXEEXT} \
+ dnssec-verify${EXEEXT}
OBJS = dnssectool.@O@
@@ -52,19 +55,19 @@ SRCS = dnssec-cds.c dnssec-dsfromkey.c dnssec-importkey.c \
@BIND9_MAKE_RULES@
-dnssec-cds@EXEEXT@: dnssec-cds.@O@ ${OBJS} ${DEPLIBS}
+dnssec-cds-pkcs11@EXEEXT@: dnssec-cds.@O@ ${OBJS} ${DEPLIBS}
export BASEOBJS="dnssec-cds.@O@ ${OBJS}"; \
${FINALBUILDCMD}
-dnssec-dsfromkey@EXEEXT@: dnssec-dsfromkey.@O@ ${OBJS} ${DEPLIBS}
+dnssec-dsfromkey-pkcs11@EXEEXT@: dnssec-dsfromkey.@O@ ${OBJS} ${DEPLIBS}
export BASEOBJS="dnssec-dsfromkey.@O@ ${OBJS}"; \
${FINALBUILDCMD}
-dnssec-keyfromlabel@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS}
+dnssec-keyfromlabel-pkcs11@EXEEXT@: dnssec-keyfromlabel.@O@ ${OBJS} ${DEPLIBS}
export BASEOBJS="dnssec-keyfromlabel.@O@ ${OBJS}"; \
${FINALBUILDCMD}
-dnssec-keygen@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS}
+dnssec-keygen-pkcs11@EXEEXT@: dnssec-keygen.@O@ ${OBJS} ${DEPLIBS}
export BASEOBJS="dnssec-keygen.@O@ ${OBJS}"; \
${FINALBUILDCMD}
@@ -72,7 +75,7 @@ dnssec-signzone.@O@: dnssec-signzone.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
-c ${srcdir}/dnssec-signzone.c
-dnssec-signzone@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS}
+dnssec-signzone-pkcs11@EXEEXT@: dnssec-signzone.@O@ ${OBJS} ${DEPLIBS}
export BASEOBJS="dnssec-signzone.@O@ ${OBJS}"; \
${FINALBUILDCMD}
@@ -80,19 +83,19 @@ dnssec-verify.@O@: dnssec-verify.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} -DVERSION=\"${VERSION}\" \
-c ${srcdir}/dnssec-verify.c
-dnssec-verify@EXEEXT@: dnssec-verify.@O@ ${OBJS} ${DEPLIBS}
+dnssec-verify-pkcs11@EXEEXT@: dnssec-verify.@O@ ${OBJS} ${DEPLIBS}
export BASEOBJS="dnssec-verify.@O@ ${OBJS}"; \
${FINALBUILDCMD}
-dnssec-revoke@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS}
+dnssec-revoke-pkcs11@EXEEXT@: dnssec-revoke.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
dnssec-revoke.@O@ ${OBJS} ${LIBS}
-dnssec-settime@EXEEXT@: dnssec-settime.@O@ ${OBJS} ${DEPLIBS}
+dnssec-settime-pkcs11@EXEEXT@: dnssec-settime.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
dnssec-settime.@O@ ${OBJS} ${LIBS}
-dnssec-importkey@EXEEXT@: dnssec-importkey.@O@ ${OBJS} ${DEPLIBS}
+dnssec-importkey-pkcs11@EXEEXT@: dnssec-importkey.@O@ ${OBJS} ${DEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
dnssec-importkey.@O@ ${OBJS} ${LIBS}
diff --git a/bin/named-pkcs11/Makefile.in b/bin/named-pkcs11/Makefile.in
index debb906..ecfdb6c 100644
--- a/bin/named-pkcs11/Makefile.in
+++ b/bin/named-pkcs11/Makefile.in
@@ -37,13 +37,14 @@ DBDRIVER_LIBS =
DLZ_DRIVER_DIR = ${top_srcdir}/contrib/dlz/drivers
-DLZDRIVER_OBJS = @DLZ_DRIVER_OBJS@
-DLZDRIVER_SRCS = @DLZ_DRIVER_SRCS@
-DLZDRIVER_INCLUDES = @DLZ_DRIVER_INCLUDES@
-DLZDRIVER_LIBS = @DLZ_DRIVER_LIBS@
+# Skip building on PKCS11 variant
+DLZDRIVER_OBJS =
+DLZDRIVER_SRCS =
+DLZDRIVER_INCLUDES =
+DLZDRIVER_LIBS =
CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \
- ${NS_INCLUDES} ${DNS_INCLUDES} \
+ ${NS_PKCS11_INCLUDES} ${DNS_PKCS11_INCLUDES} \
${BIND9_INCLUDES} ${ISCCFG_INCLUDES} ${ISCCC_INCLUDES} \
${ISC_INCLUDES} ${DLZDRIVER_INCLUDES} \
${DBDRIVER_INCLUDES} \
@@ -56,24 +57,24 @@ CINCLUDES = -I${srcdir}/include -I${srcdir}/unix/include -I. \
${LIBXML2_CFLAGS} \
${MAXMINDDB_CFLAGS}
-CDEFINES = @CONTRIB_DLZ@
+CDEFINES =
CWARNINGS =
-DNSLIBS = ../../lib/dns/libdns.@A@ @NO_LIBTOOL_DNSLIBS@
+DNSLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@ @NO_LIBTOOL_DNSLIBS@
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCLIBS = ../../lib/isccc/libisccc.@A@
ISCLIBS = ../../lib/isc/libisc.@A@ @NO_LIBTOOL_ISCLIBS@
ISCNOSYMLIBS = ../../lib/isc/libisc-nosymtbl.@A@ @NO_LIBTOOL_ISCLIBS@
BIND9LIBS = ../../lib/bind9/libbind9.@A@
-NSLIBS = ../../lib/ns/libns.@A@
+NSLIBS = ../../lib/ns-pkcs11/libns-pkcs11.@A@
-DNSDEPLIBS = ../../lib/dns/libdns.@A@
+DNSDEPLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@
ISCCFGDEPLIBS = ../../lib/isccfg/libisccfg.@A@
ISCCCDEPLIBS = ../../lib/isccc/libisccc.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
BIND9DEPLIBS = ../../lib/bind9/libbind9.@A@
-NSDEPLIBS = ../../lib/ns/libns.@A@
+NSDEPLIBS = ../../lib/ns-pkcs11/libns-pkcs11.@A@
DEPLIBS = ${NSDEPLIBS} ${DNSDEPLIBS} ${BIND9DEPLIBS} \
${ISCCFGDEPLIBS} ${ISCCCDEPLIBS} ${ISCDEPLIBS}
@@ -93,7 +94,7 @@ NOSYMLIBS = ${NSLIBS} ${DNSLIBS} ${BIND9LIBS} \
SUBDIRS = unix
-TARGETS = named@EXEEXT@
+TARGETS = named-pkcs11@EXEEXT@
GEOIP2LINKOBJS = geoip.@O@
@@ -151,7 +152,7 @@ server.@O@: server.c
-DPRODUCT=\"${PRODUCT}\" \
-DVERSION=\"${VERSION}\" -c ${srcdir}/server.c
-named@EXEEXT@: ${OBJS} ${DEPLIBS}
+named-pkcs11@EXEEXT@: ${OBJS} ${DEPLIBS}
export MAKE_SYMTABLE="yes"; \
export BASEOBJS="${OBJS} ${UOBJS}"; \
${FINALBUILDCMD}
@@ -170,11 +171,11 @@ statschannel.@O@: bind9.xsl.h
installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${sbindir}
-install:: named@EXEEXT@ installdirs
- ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named@EXEEXT@ ${DESTDIR}${sbindir}
+install:: named-pkcs11@EXEEXT@ installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_PROGRAM} named-pkcs11@EXEEXT@ ${DESTDIR}${sbindir}
uninstall::
- ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${sbindir}/named@EXEEXT@
+ ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${sbindir}/named-pkcs11@EXEEXT@
@DLZ_DRIVER_RULES@
diff --git a/configure.ac b/configure.ac
index e405eaf..efaa5a7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1269,12 +1269,14 @@ AC_SUBST(USE_GSSAPI)
AC_SUBST(DST_GSSAPI_INC)
AC_SUBST(DNS_GSSAPI_LIBS)
DNS_CRYPTO_LIBS="$DNS_GSSAPI_LIBS"
+DNS_CRYPTO_PK11_LIBS="$DNS_GSSAPI_LIBS $DNS_CRYPTO_PK11_LIBS"
#
# Applications linking with libdns also need to link with these libraries.
#
AC_SUBST(DNS_CRYPTO_LIBS)
+AC_SUBST(DNS_CRYPTO_PK11_LIBS)
#
# was --with-lmdb specified?
@@ -2345,6 +2347,8 @@ AC_SUBST(BIND9_DNS_BUILDINCLUDE)
AC_SUBST(BIND9_NS_BUILDINCLUDE)
AC_SUBST(BIND9_BIND9_BUILDINCLUDE)
AC_SUBST(BIND9_IRS_BUILDINCLUDE)
+AC_SUBST(BIND9_DNS_PKCS11_BUILDINCLUDE)
+AC_SUBST(BIND9_NS_PKCS11_BUILDINCLUDE)
if test "X$srcdir" != "X"; then
BIND9_ISC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isc/include"
BIND9_ISCCC_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/isccc/include"
@@ -2353,6 +2357,8 @@ if test "X$srcdir" != "X"; then
BIND9_NS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/ns/include"
BIND9_BIND9_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/bind9/include"
BIND9_IRS_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/irs/include"
+ BIND9_DNS_PKCS11_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/dns-pkcs11/include"
+ BIND9_NS_PKCS11_BUILDINCLUDE="-I${BIND9_TOP_BUILDDIR}/lib/ns-pkcs11/include"
else
BIND9_ISC_BUILDINCLUDE=""
BIND9_ISCCC_BUILDINCLUDE=""
@@ -2361,6 +2367,8 @@ else
BIND9_NS_BUILDINCLUDE=""
BIND9_BIND9_BUILDINCLUDE=""
BIND9_IRS_BUILDINCLUDE=""
+ BIND9_DNS_PKCS11_BUILDINCLUDE=""
+ BIND9_NS_PKCS11_BUILDINCLUDE=""
fi
AC_SUBST_FILE(BIND9_MAKE_INCLUDES)
@@ -2816,8 +2824,11 @@ AC_CONFIG_FILES([
bin/delv/Makefile
bin/dig/Makefile
bin/dnssec/Makefile
+ bin/dnssec-pkcs11/Makefile
bin/named/Makefile
bin/named/unix/Makefile
+ bin/named-pkcs11/Makefile
+ bin/named-pkcs11/unix/Makefile
bin/nsupdate/Makefile
bin/pkcs11/Makefile
bin/plugins/Makefile
@@ -2879,6 +2890,10 @@ AC_CONFIG_FILES([
lib/dns/include/dns/Makefile
lib/dns/include/dst/Makefile
lib/dns/tests/Makefile
+ lib/dns-pkcs11/Makefile
+ lib/dns-pkcs11/include/Makefile
+ lib/dns-pkcs11/include/dns/Makefile
+ lib/dns-pkcs11/include/dst/Makefile
lib/irs/Makefile
lib/irs/include/Makefile
lib/irs/include/irs/Makefile
@@ -2911,6 +2926,10 @@ AC_CONFIG_FILES([
lib/ns/include/Makefile
lib/ns/include/ns/Makefile
lib/ns/tests/Makefile
+ lib/ns-pkcs11/Makefile
+ lib/ns-pkcs11/include/Makefile
+ lib/ns-pkcs11/include/ns/Makefile
+ lib/ns-pkcs11/tests/Makefile
make/Makefile
make/mkdep
unit/unittest.sh
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 833964e..058ba2f 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -15,7 +15,7 @@ top_srcdir = @top_srcdir@
# Attempt to disable parallel processing.
.NOTPARALLEL:
.NO_PARALLEL:
-SUBDIRS = isc isccc dns ns isccfg bind9 irs
+SUBDIRS = isc isccc dns dns-pkcs11 ns ns-pkcs11 isccfg bind9 irs
TARGETS =
@BIND9_MAKE_RULES@
diff --git a/lib/dns-pkcs11/Makefile.in b/lib/dns-pkcs11/Makefile.in
index 58bda3c..d6a45df 100644
--- a/lib/dns-pkcs11/Makefile.in
+++ b/lib/dns-pkcs11/Makefile.in
@@ -22,7 +22,7 @@ VERSION=@BIND9_VERSION@
@BIND9_MAKE_INCLUDES@
-CINCLUDES = -I. -I${top_srcdir}/lib/dns -Iinclude ${DNS_INCLUDES} \
+CINCLUDES = -I. -I${top_srcdir}/lib/dns-pkcs11 -Iinclude ${DNS_PKCS11_INCLUDES} \
${ISC_INCLUDES} \
${FSTRM_CFLAGS} \
${OPENSSL_CFLAGS} @DST_GSSAPI_INC@ \
@@ -32,7 +32,7 @@ CINCLUDES = -I. -I${top_srcdir}/lib/dns -Iinclude ${DNS_INCLUDES} \
${LMDB_CFLAGS} \
${MAXMINDDB_CFLAGS}
-CDEFINES = @USE_GSSAPI@
+CDEFINES = @USE_GSSAPI@ @USE_PKCS11@
CWARNINGS =
@@ -135,15 +135,15 @@ version.@O@: version.c
-DMAPAPI=\"${MAPAPI}\" \
-c ${srcdir}/version.c
-libdns.@SA@: ${OBJS}
+libdns-pkcs11.@SA@: ${OBJS}
${AR} ${ARFLAGS} $@ ${OBJS}
${RANLIB} $@
-libdns.la: ${OBJS}
+libdns-pkcs11.la: ${OBJS}
${LIBTOOL_MODE_LINK} \
- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns.la -rpath ${libdir} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libdns-pkcs11.la -rpath ${libdir} \
-release "${VERSION}" \
- ${OBJS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ ${LIBS}
+ ${OBJS} ${ISCLIBS} @DNS_CRYPTO_PK11_LIBS@ ${LIBS}
include: gen
${MAKE} include/dns/enumtype.h
@@ -174,22 +174,22 @@ gen: gen.c
${BUILD_CPPFLAGS} ${BUILD_LDFLAGS} -o $@ ${srcdir}/gen.c \
${BUILD_LIBS} ${LFS_LIBS}
-timestamp: include libdns.@A@
+timestamp: include libdns-pkcs11.@A@
touch timestamp
-testdirs: libdns.@A@
+testdirs: libdns-pkcs11.@A@
installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
install:: timestamp installdirs
- ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libdns.@A@ ${DESTDIR}${libdir}
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libdns-pkcs11.@A@ ${DESTDIR}${libdir}
uninstall::
- ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${libdir}/libdns.@A@
+ ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${libdir}/libdns-pkcs11.@A@
clean distclean::
- rm -f libdns.@A@ timestamp
+ rm -f libdns-pkcs11.@A@ timestamp
rm -f gen code.h include/dns/enumtype.h include/dns/enumclass.h
rm -f include/dns/rdatastruct.h
rm -f dnstap.pb-c.c dnstap.pb-c.h
diff --git a/lib/dns-pkcs11/tests/Makefile.in b/lib/dns-pkcs11/tests/Makefile.in
index da91394..aadb73f 100644
--- a/lib/dns-pkcs11/tests/Makefile.in
+++ b/lib/dns-pkcs11/tests/Makefile.in
@@ -15,15 +15,15 @@ VERSION=@BIND9_VERSION@
@BIND9_MAKE_INCLUDES@
-CINCLUDES = -I. -Iinclude ${DNS_INCLUDES} ${ISC_INCLUDES} \
+CINCLUDES = -I. -Iinclude ${DNS_PKCS11_INCLUDES} ${ISC_INCLUDES} \
${FSTRM_CFLAGS} ${OPENSSL_CFLAGS} \
${PROTOBUF_C_CFLAGS} ${MAXMINDDB_CFLAGS} @CMOCKA_CFLAGS@
-CDEFINES = -DTESTS="\"${top_builddir}/lib/dns/tests/\""
+CDEFINES = @USE_PKCS11@ -DTESTS="\"${top_builddir}/lib/dns-pkcs11/tests/\""
ISCLIBS = ../../isc/libisc.@A@ @NO_LIBTOOL_ISCLIBS@
ISCDEPLIBS = ../../isc/libisc.@A@
-DNSLIBS = ../libdns.@A@ @NO_LIBTOOL_DNSLIBS@
-DNSDEPLIBS = ../libdns.@A@
+DNSLIBS = ../libdns-pkcs11.@A@ @NO_LIBTOOL_DNSLIBS@
+DNSDEPLIBS = ../libdns-pkcs11.@A@
LIBS = @LIBS@ @CMOCKA_LIBS@
diff --git a/lib/ns-pkcs11/Makefile.in b/lib/ns-pkcs11/Makefile.in
index bc683ce..7a9d2f2 100644
--- a/lib/ns-pkcs11/Makefile.in
+++ b/lib/ns-pkcs11/Makefile.in
@@ -16,12 +16,12 @@ VERSION=@BIND9_VERSION@
@BIND9_MAKE_INCLUDES@
-CINCLUDES = -I. -I${top_srcdir}/lib/ns -Iinclude \
- ${NS_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} \
+CINCLUDES = -I. -I${top_srcdir}/lib/ns-pkcs11 -Iinclude \
+ ${NS_PKCS11_INCLUDES} ${DNS_PKCS11_INCLUDES} ${ISC_INCLUDES} \
${OPENSSL_CFLAGS} @DST_GSSAPI_INC@ \
${FSTRM_CFLAGS}
-CDEFINES = -DNAMED_PLUGINDIR=\"${plugindir}\"
+CDEFINES = @USE_PKCS11@ -DNAMED_PLUGINDIR=\"${plugindir}\"
CWARNINGS =
@@ -29,9 +29,9 @@ ISCLIBS = ../../lib/isc/libisc.@A@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
-DNSLIBS = ../../lib/dns/libdns.@A@ @NO_LIBTOOL_DNSLIBS@
+DNSLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@ @NO_LIBTOOL_DNSLIBS@
-DNSDEPLIBS = ../../lib/dns/libdns.@A@
+DNSDEPLIBS = ../../lib/dns-pkcs11/libdns-pkcs11.@A@
LIBS = @LIBS@
@@ -60,28 +60,28 @@ version.@O@: version.c
-DMAJOR=\"${MAJOR}\" \
-c ${srcdir}/version.c
-libns.@SA@: ${OBJS}
+libns-pkcs11.@SA@: ${OBJS}
${AR} ${ARFLAGS} $@ ${OBJS}
${RANLIB} $@
-libns.la: ${OBJS}
+libns-pkcs11.la: ${OBJS}
${LIBTOOL_MODE_LINK} \
- ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libns.la -rpath ${libdir} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libns-pkcs11.la -rpath ${libdir} \
-release "${VERSION}" \
- ${OBJS} ${ISCLIBS} ${DNSLIBS} @DNS_CRYPTO_LIBS@ ${LIBS}
+ ${OBJS} ${ISCLIBS} ${DNSLIBS} @DNS_CRYPTO_PK11_LIBS@ ${LIBS}
-timestamp: libns.@A@
+timestamp: libns-pkcs11.@A@
touch timestamp
installdirs:
$(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
install:: timestamp installdirs
- ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libns.@A@ \
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_LIBRARY} libns-pkcs11.@A@ \
${DESTDIR}${libdir}
uninstall::
- ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${libdir}/libns.@A@
+ ${LIBTOOL_MODE_UNINSTALL} rm -f ${DESTDIR}${libdir}/libns-pkcs11.@A@
clean distclean::
- rm -f libns.@A@ timestamp
+ rm -f libns-pkcs11.@A@ timestamp
diff --git a/lib/ns-pkcs11/tests/Makefile.in b/lib/ns-pkcs11/tests/Makefile.in
index 4c3e694..c1b6d99 100644
--- a/lib/ns-pkcs11/tests/Makefile.in
+++ b/lib/ns-pkcs11/tests/Makefile.in
@@ -17,17 +17,17 @@ VERSION=@BIND9_VERSION@
WRAP_OPTIONS = -Wl,--wrap=isc__nmhandle_detach -Wl,--wrap=isc__nmhandle_attach
-CINCLUDES = -I. -Iinclude ${NS_INCLUDES} ${DNS_INCLUDES} ${ISC_INCLUDES} \
+CINCLUDES = -I. -Iinclude ${NS_PKCS11_INCLUDES} ${DNS_PKCS11_INCLUDES} ${ISC_INCLUDES} \
${OPENSSL_CFLAGS} \
@CMOCKA_CFLAGS@
-CDEFINES = -DTESTS="\"${top_builddir}/lib/ns/tests/\"" -DNAMED_PLUGINDIR=\"${plugindir}\"
+CDEFINES = -DTESTS="\"${top_builddir}/lib/ns-pkcs11/tests/\"" -DNAMED_PLUGINDIR=\"${plugindir}\" @USE_PKCS11@
ISCLIBS = ../../isc/libisc.@A@ @NO_LIBTOOL_ISCLIBS@
ISCDEPLIBS = ../../isc/libisc.@A@
-DNSLIBS = ../../dns/libdns.@A@ @NO_LIBTOOL_DNSLIBS@
-DNSDEPLIBS = ../../dns/libdns.@A@
-NSLIBS = ../libns.@A@
-NSDEPLIBS = ../libns.@A@
+DNSLIBS = ../../dns-pkcs11/libdns-pkcs11.@A@ @NO_LIBTOOL_DNSLIBS@
+DNSDEPLIBS = ../../dns-pkcs11/libdns-pkcs11.@A@
+NSLIBS = ../libns-pkcs11.@A@
+NSDEPLIBS = ../libns-pkcs11.@A@
LIBS = @LIBS@ @CMOCKA_LIBS@
diff --git a/make/includes.in b/make/includes.in
index b8317d3..b73b0c4 100644
--- a/make/includes.in
+++ b/make/includes.in
@@ -39,3 +39,10 @@ BIND9_INCLUDES = @BIND9_BIND9_BUILDINCLUDE@ \
TEST_INCLUDES = \
-I${top_srcdir}/lib/tests/include
+
+DNS_PKCS11_INCLUDES = @BIND9_DNS_PKCS11_BUILDINCLUDE@ \
+ -I${top_srcdir}/lib/dns-pkcs11/include
+
+NS_PKCS11_INCLUDES = @BIND9_NS_PKCS11_BUILDINCLUDE@ \
+ -I${top_srcdir}/lib/ns-pkcs11/include
+
--
2.31.1

648
bind-9.11-fips-tests.patch Normal file
View file

@ -0,0 +1,648 @@
From e1e46c06d7d7611b415a5c3c479f51bf7a202e1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Thu, 2 Aug 2018 23:46:45 +0200
Subject: [PATCH] FIPS tests changes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Squashed commit of the following:
commit 09e5eb48698d4fef2fc1031870de86c553b6bfaa
Author: Petr Menšík <pemensik@redhat.com>
Date: Wed Mar 7 20:35:13 2018 +0100
Fix nsupdate test. Do not use md5 by default for rndc, skip gracefully md5 if not available.
commit ab303db70082db76ecf36493d0b82ef3e8750cad
Author: Petr Menšík <pemensik@redhat.com>
Date: Wed Mar 7 18:11:10 2018 +0100
Changed root key to be RSASHA256
Change bad trusted key to be the same algorithm.
commit 88ab07c0e14cc71247e1f9d11a1ea832b64c1ee8
Author: Petr Menšík <pemensik@redhat.com>
Date: Wed Mar 7 16:56:17 2018 +0100
Change used key to not use hmac-md5
Fix upforwd test, do not use hmac-md5
commit aec891571626f053acfb4d0a247240cbc21a84e9
Author: Petr Menšík <pemensik@redhat.com>
Date: Wed Mar 7 15:54:11 2018 +0100
Increase bitsize of DSA key to pass FIPS 140-2 mode.
commit bca8e164fa0d9aff2f946b8b4eb0f1f7e0bf6696
Author: Petr Menšík <pemensik@redhat.com>
Date: Wed Mar 7 15:41:08 2018 +0100
Fix tsig and rndc tests for disabled md5
Use hmac-sha256 instead of hmac-md5.
commit 0d314c1ab6151aa13574a21ad22f28d3b7f42a67
Author: Petr Menšík <pemensik@redhat.com>
Date: Wed Mar 7 13:21:00 2018 +0100
Add md5 availability detection to featuretest
commit f389a918803e2853e4b55fed62765dc4a492e34f
Author: Petr Menšík <pemensik@redhat.com>
Date: Wed Mar 7 10:44:23 2018 +0100
Change tests to not use hmac-md5 algorithms if not required
Use hmac-sha256 instead of default hmac-md5 for allow-query
---
bin/tests/system/acl/ns2/named1.conf.in | 4 +--
bin/tests/system/acl/ns2/named2.conf.in | 4 +--
bin/tests/system/acl/ns2/named3.conf.in | 6 ++--
bin/tests/system/acl/ns2/named4.conf.in | 4 +--
bin/tests/system/acl/ns2/named5.conf.in | 4 +--
bin/tests/system/acl/tests.sh | 30 +++++++++----------
.../system/allow-query/ns2/named10.conf.in | 2 +-
.../system/allow-query/ns2/named11.conf.in | 4 +--
.../system/allow-query/ns2/named12.conf.in | 2 +-
.../system/allow-query/ns2/named30.conf.in | 2 +-
.../system/allow-query/ns2/named31.conf.in | 4 +--
.../system/allow-query/ns2/named32.conf.in | 2 +-
.../system/allow-query/ns2/named40.conf.in | 4 +--
bin/tests/system/allow-query/tests.sh | 18 +++++------
bin/tests/system/checkconf/bad-tsig.conf | 2 +-
bin/tests/system/checkconf/good.conf | 2 +-
bin/tests/system/notify/ns5/named.conf.in | 6 ++--
bin/tests/system/notify/tests.sh | 6 ++--
bin/tests/system/nsupdate/ns1/named.conf.in | 2 +-
bin/tests/system/nsupdate/ns2/named.conf.in | 2 +-
bin/tests/system/nsupdate/tests.sh | 4 +--
bin/tests/system/upforwd/ns1/named.conf.in | 2 +-
bin/tests/system/upforwd/tests.sh | 2 +-
23 files changed, 59 insertions(+), 59 deletions(-)
diff --git a/bin/tests/system/acl/ns2/named1.conf.in b/bin/tests/system/acl/ns2/named1.conf.in
index 745048a..93cb411 100644
--- a/bin/tests/system/acl/ns2/named1.conf.in
+++ b/bin/tests/system/acl/ns2/named1.conf.in
@@ -35,12 +35,12 @@ options {
};
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/acl/ns2/named2.conf.in b/bin/tests/system/acl/ns2/named2.conf.in
index 21aa991..78e71cc 100644
--- a/bin/tests/system/acl/ns2/named2.conf.in
+++ b/bin/tests/system/acl/ns2/named2.conf.in
@@ -35,12 +35,12 @@ options {
};
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/acl/ns2/named3.conf.in b/bin/tests/system/acl/ns2/named3.conf.in
index 3208c92..bed6325 100644
--- a/bin/tests/system/acl/ns2/named3.conf.in
+++ b/bin/tests/system/acl/ns2/named3.conf.in
@@ -35,17 +35,17 @@ options {
};
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key three {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/acl/ns2/named4.conf.in b/bin/tests/system/acl/ns2/named4.conf.in
index 14e82ed..a22cafe 100644
--- a/bin/tests/system/acl/ns2/named4.conf.in
+++ b/bin/tests/system/acl/ns2/named4.conf.in
@@ -35,12 +35,12 @@ options {
};
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/acl/ns2/named5.conf.in b/bin/tests/system/acl/ns2/named5.conf.in
index f43f33c..f4a865a 100644
--- a/bin/tests/system/acl/ns2/named5.conf.in
+++ b/bin/tests/system/acl/ns2/named5.conf.in
@@ -37,12 +37,12 @@ options {
};
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/acl/tests.sh b/bin/tests/system/acl/tests.sh
index 19e5c8f..f334f14 100644
--- a/bin/tests/system/acl/tests.sh
+++ b/bin/tests/system/acl/tests.sh
@@ -24,14 +24,14 @@ echo_i "testing basic ACL processing"
# key "one" should fail
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.1 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
# any other key should be fine
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
copy_setports ns2/named2.conf.in ns2/named.conf
@@ -41,18 +41,18 @@ sleep 5
# prefix 10/8 should fail
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.1 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
# any other address should work, as long as it sends key "one"
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 127.0.0.1 axfr -y two:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 127.0.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 127.0.0.1 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 127.0.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
echo_i "testing nested ACL processing"
@@ -64,31 +64,31 @@ sleep 5
# should succeed
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.2 axfr -y two:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
# should succeed
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.2 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
# should succeed
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
# should succeed
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
# but only one or the other should fail
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 127.0.0.1 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 127.0.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
t=`expr $t + 1`
@@ -110,31 +110,31 @@ sleep 5
# should succeed
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.2 axfr -y two:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
# should succeed
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.1 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 && { echo_i "test $t failed" ; status=1; }
# should fail
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.2 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.2 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
# should fail
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.1 axfr -y two:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.1 axfr -y hmac-sha256:two:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
# should fail
t=`expr $t + 1`
$DIG $DIGOPTS tsigzone. \
- @10.53.0.2 -b 10.53.0.3 axfr -y one:1234abcd8765 > dig.out.${t}
+ @10.53.0.2 -b 10.53.0.3 axfr -y hmac-sha256:one:1234abcd8765 > dig.out.${t}
grep "^;" dig.out.${t} > /dev/null 2>&1 || { echo_i "test $t failed" ; status=1; }
echo_i "testing allow-query-on ACL processing"
diff --git a/bin/tests/system/allow-query/ns2/named10.conf.in b/bin/tests/system/allow-query/ns2/named10.conf.in
index b91d19a..7d777c2 100644
--- a/bin/tests/system/allow-query/ns2/named10.conf.in
+++ b/bin/tests/system/allow-query/ns2/named10.conf.in
@@ -12,7 +12,7 @@
*/
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/allow-query/ns2/named11.conf.in b/bin/tests/system/allow-query/ns2/named11.conf.in
index 308c4ca..00f6f40 100644
--- a/bin/tests/system/allow-query/ns2/named11.conf.in
+++ b/bin/tests/system/allow-query/ns2/named11.conf.in
@@ -12,12 +12,12 @@
*/
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234efgh8765";
};
diff --git a/bin/tests/system/allow-query/ns2/named12.conf.in b/bin/tests/system/allow-query/ns2/named12.conf.in
index 6b0fe55..491e514 100644
--- a/bin/tests/system/allow-query/ns2/named12.conf.in
+++ b/bin/tests/system/allow-query/ns2/named12.conf.in
@@ -12,7 +12,7 @@
*/
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/allow-query/ns2/named30.conf.in b/bin/tests/system/allow-query/ns2/named30.conf.in
index aefc474..7c06596 100644
--- a/bin/tests/system/allow-query/ns2/named30.conf.in
+++ b/bin/tests/system/allow-query/ns2/named30.conf.in
@@ -12,7 +12,7 @@
*/
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/allow-query/ns2/named31.conf.in b/bin/tests/system/allow-query/ns2/named31.conf.in
index 27eccc2..eecb990 100644
--- a/bin/tests/system/allow-query/ns2/named31.conf.in
+++ b/bin/tests/system/allow-query/ns2/named31.conf.in
@@ -12,12 +12,12 @@
*/
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234efgh8765";
};
diff --git a/bin/tests/system/allow-query/ns2/named32.conf.in b/bin/tests/system/allow-query/ns2/named32.conf.in
index adbb203..744d122 100644
--- a/bin/tests/system/allow-query/ns2/named32.conf.in
+++ b/bin/tests/system/allow-query/ns2/named32.conf.in
@@ -12,7 +12,7 @@
*/
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/allow-query/ns2/named40.conf.in b/bin/tests/system/allow-query/ns2/named40.conf.in
index 364f94b..9518f82 100644
--- a/bin/tests/system/allow-query/ns2/named40.conf.in
+++ b/bin/tests/system/allow-query/ns2/named40.conf.in
@@ -16,12 +16,12 @@ acl accept { 10.53.0.2; };
acl badaccept { 10.53.0.1; };
key one {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234abcd8765";
};
key two {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "1234efgh8765";
};
diff --git a/bin/tests/system/allow-query/tests.sh b/bin/tests/system/allow-query/tests.sh
index 41c7bb7..9d121b3 100644
--- a/bin/tests/system/allow-query/tests.sh
+++ b/bin/tests/system/allow-query/tests.sh
@@ -184,7 +184,7 @@ rndc_reload ns2 10.53.0.2
echo_i "test $n: key allowed - query allowed"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.normal.example' dig.out.ns2.$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -197,7 +197,7 @@ rndc_reload ns2 10.53.0.2
echo_i "test $n: key not allowed - query refused"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1
grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -210,7 +210,7 @@ rndc_reload ns2 10.53.0.2
echo_i "test $n: key disallowed - query refused"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -343,7 +343,7 @@ rndc_reload ns2 10.53.0.2
echo_i "test $n: views key allowed - query allowed"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.normal.example' dig.out.ns2.$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -356,7 +356,7 @@ rndc_reload ns2 10.53.0.2
echo_i "test $n: views key not allowed - query refused"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:two:1234efgh8765 a.normal.example a > dig.out.ns2.$n || ret=1
grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -369,7 +369,7 @@ rndc_reload ns2 10.53.0.2
echo_i "test $n: views key disallowed - query refused"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.normal.example a > dig.out.ns2.$n || ret=1
grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.normal.example' dig.out.ns2.$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -502,7 +502,7 @@ status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "test $n: zone key allowed - query allowed"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.keyallow.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.keyallow.example a > dig.out.ns2.$n || ret=1
grep 'status: NOERROR' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.keyallow.example' dig.out.ns2.$n > /dev/null || ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -512,7 +512,7 @@ status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "test $n: zone key not allowed - query refused"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y two:1234efgh8765 a.keyallow.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:two:1234efgh8765 a.keyallow.example a > dig.out.ns2.$n || ret=1
grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.keyallow.example' dig.out.ns2.$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
@@ -522,7 +522,7 @@ status=`expr $status + $ret`
n=`expr $n + 1`
echo_i "test $n: zone key disallowed - query refused"
ret=0
-$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y one:1234abcd8765 a.keydisallow.example a > dig.out.ns2.$n || ret=1
+$DIG $DIGOPTS @10.53.0.2 -b 10.53.0.2 -y hmac-sha256:one:1234abcd8765 a.keydisallow.example a > dig.out.ns2.$n || ret=1
grep 'status: REFUSED' dig.out.ns2.$n > /dev/null || ret=1
grep '^a.keydisallow.example' dig.out.ns2.$n > /dev/null && ret=1
if [ $ret != 0 ]; then echo_i "failed"; fi
diff --git a/bin/tests/system/checkconf/bad-tsig.conf b/bin/tests/system/checkconf/bad-tsig.conf
index 4af25b0..9f202d5 100644
--- a/bin/tests/system/checkconf/bad-tsig.conf
+++ b/bin/tests/system/checkconf/bad-tsig.conf
@@ -13,7 +13,7 @@
/* Bad secret */
key "badtsig" {
- algorithm hmac-md5;
+ algorithm hmac-sha256;
secret "jEdD+BPKg==";
};
diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf
index 0ecdb68..90b8ab3 100644
--- a/bin/tests/system/checkconf/good.conf
+++ b/bin/tests/system/checkconf/good.conf
@@ -284,6 +284,6 @@ dyndb "name" "library.so" {
system;
};
key "mykey" {
- algorithm "hmac-md5";
+ algorithm "hmac-sha256";
secret "qwertyuiopasdfgh";
};
diff --git a/bin/tests/system/notify/ns5/named.conf.in b/bin/tests/system/notify/ns5/named.conf.in
index 5cab276..d4a7bf3 100644
--- a/bin/tests/system/notify/ns5/named.conf.in
+++ b/bin/tests/system/notify/ns5/named.conf.in
@@ -12,17 +12,17 @@
*/
key "a" {
- algorithm "hmac-md5";
+ algorithm "hmac-sha256";
secret "aaaaaaaaaaaaaaaaaaaa";
};
key "b" {
- algorithm "hmac-md5";
+ algorithm "hmac-sha256";
secret "bbbbbbbbbbbbbbbbbbbb";
};
key "c" {
- algorithm "hmac-md5";
+ algorithm "hmac-sha256";
secret "cccccccccccccccccccc";
};
diff --git a/bin/tests/system/notify/tests.sh b/bin/tests/system/notify/tests.sh
index c02654e..0453a87 100644
--- a/bin/tests/system/notify/tests.sh
+++ b/bin/tests/system/notify/tests.sh
@@ -214,16 +214,16 @@ ret=0
$NSUPDATE << EOF
server 10.53.0.5 ${PORT}
zone x21
-key a aaaaaaaaaaaaaaaaaaaa
+key hmac-sha256:a aaaaaaaaaaaaaaaaaaaa
update add added.x21 0 in txt "test string"
send
EOF
for i in 1 2 3 4 5 6 7 8 9
do
- $DIG $DIGOPTS added.x21. -y b:bbbbbbbbbbbbbbbbbbbb @10.53.0.5 \
+ $DIG $DIGOPTS added.x21. -y hmac-sha256:b:bbbbbbbbbbbbbbbbbbbb @10.53.0.5 \
txt > dig.out.b.ns5.test$n || ret=1
- $DIG $DIGOPTS added.x21. -y c:cccccccccccccccccccc @10.53.0.5 \
+ $DIG $DIGOPTS added.x21. -y hmac-sha256:c:cccccccccccccccccccc @10.53.0.5 \
txt > dig.out.c.ns5.test$n || ret=1
grep "test string" dig.out.b.ns5.test$n > /dev/null &&
grep "test string" dig.out.c.ns5.test$n > /dev/null &&
diff --git a/bin/tests/system/nsupdate/ns1/named.conf.in b/bin/tests/system/nsupdate/ns1/named.conf.in
index a5cc36d..7bb8923 100644
--- a/bin/tests/system/nsupdate/ns1/named.conf.in
+++ b/bin/tests/system/nsupdate/ns1/named.conf.in
@@ -40,7 +40,7 @@ controls {
};
key altkey {
- algorithm hmac-md5;
+ algorithm hmac-sha512;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/nsupdate/ns2/named.conf.in b/bin/tests/system/nsupdate/ns2/named.conf.in
index f1a1735..da2b3d1 100644
--- a/bin/tests/system/nsupdate/ns2/named.conf.in
+++ b/bin/tests/system/nsupdate/ns2/named.conf.in
@@ -34,7 +34,7 @@ controls {
};
key altkey {
- algorithm hmac-md5;
+ algorithm hmac-sha512;
secret "1234abcd8765";
};
diff --git a/bin/tests/system/nsupdate/tests.sh b/bin/tests/system/nsupdate/tests.sh
index 3f8b1b4..f203b38 100755
--- a/bin/tests/system/nsupdate/tests.sh
+++ b/bin/tests/system/nsupdate/tests.sh
@@ -878,7 +878,7 @@ fi
n=$((n + 1))
ret=0
echo_i "check TSIG key algorithms (nsupdate -y) ($n)"
-for alg in md5 sha1 sha224 sha256 sha384 sha512; do
+for alg in $ALGS; do
secret=$(sed -n 's/.*secret "\(.*\)";.*/\1/p' ns1/${alg}.key)
$NSUPDATE -y "hmac-${alg}:${alg}-key:$secret" <<END > /dev/null || ret=1
server 10.53.0.1 ${PORT}
@@ -887,7 +887,7 @@ send
END
done
sleep 2
-for alg in md5 sha1 sha224 sha256 sha384 sha512; do
+for alg in $ALGS; do
$DIG $DIGOPTS +short @10.53.0.1 ${alg}.keytests.nil | grep 10.10.10.50 > /dev/null 2>&1 || ret=1
done
if [ $ret -ne 0 ]; then
diff --git a/bin/tests/system/upforwd/ns1/named.conf.in b/bin/tests/system/upforwd/ns1/named.conf.in
index c2b57dd..cb13aa1 100644
--- a/bin/tests/system/upforwd/ns1/named.conf.in
+++ b/bin/tests/system/upforwd/ns1/named.conf.in
@@ -12,7 +12,7 @@
*/
key "update.example." {
- algorithm "hmac-md5";
+ algorithm "hmac-sha256";
secret "c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K";
};
diff --git a/bin/tests/system/upforwd/tests.sh b/bin/tests/system/upforwd/tests.sh
index 35c5588..7d08a24 100644
--- a/bin/tests/system/upforwd/tests.sh
+++ b/bin/tests/system/upforwd/tests.sh
@@ -81,7 +81,7 @@ if [ $ret != 0 ] ; then echo_i "failed"; status=`expr $status + $ret`; fi
echo_i "updating zone (signed) ($n)"
ret=0
-$NSUPDATE -y update.example:c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K -- - <<EOF || ret=1
+$NSUPDATE -y ${DEFAULT_HMAC}:update.example:c3Ryb25nIGVub3VnaCBmb3IgYSBtYW4gYnV0IG1hZGUgZm9yIGEgd29tYW4K -- - <<EOF || ret=1
local 10.53.0.1
server 10.53.0.3 ${PORT}
update add updated.example. 600 A 10.10.10.1
--
2.40.0

View file

@ -0,0 +1,58 @@
From 1241f2005d08673c28a595c5a6cd61350b95a929 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 2 Jan 2018 18:13:07 +0100
Subject: [PATCH] Fix pkcs11 variants atf tests
Add dns-pkcs11 tests Makefile to configure
Add pkcs11 Kyuafile, fix dh_test to pass in pkcs11 mode
---
configure.ac | 1 +
lib/Kyuafile | 2 ++
lib/dns-pkcs11/tests/dh_test.c | 3 ++-
3 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index d80ae31..0fb9328 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3090,6 +3090,7 @@ AC_CONFIG_FILES([
lib/dns-pkcs11/include/Makefile
lib/dns-pkcs11/include/dns/Makefile
lib/dns-pkcs11/include/dst/Makefile
+ lib/dns-pkcs11/tests/Makefile
lib/irs/Makefile
lib/irs/include/Makefile
lib/irs/include/irs/Makefile
diff --git a/lib/Kyuafile b/lib/Kyuafile
index 39ce986..037e5ef 100644
--- a/lib/Kyuafile
+++ b/lib/Kyuafile
@@ -2,8 +2,10 @@ syntax(2)
test_suite('bind9')
include('dns/Kyuafile')
+include('dns-pkcs11/Kyuafile')
include('irs/Kyuafile')
include('isc/Kyuafile')
include('isccc/Kyuafile')
include('isccfg/Kyuafile')
include('ns/Kyuafile')
+include('ns-pkcs11/Kyuafile')
diff --git a/lib/dns-pkcs11/tests/dh_test.c b/lib/dns-pkcs11/tests/dh_test.c
index 934e8fd..658d1af 100644
--- a/lib/dns-pkcs11/tests/dh_test.c
+++ b/lib/dns-pkcs11/tests/dh_test.c
@@ -87,7 +87,8 @@ dh_computesecret(void **state) {
result = dst_key_computesecret(key, key, &buf);
assert_int_equal(result, DST_R_NOTPRIVATEKEY);
result = key->func->computesecret(key, key, &buf);
- assert_int_equal(result, DST_R_COMPUTESECRETFAILURE);
+ /* PKCS11 variant gives different result, accept both */
+ assert_true(result == DST_R_COMPUTESECRETFAILURE || result == DST_R_INVALIDPRIVATEKEY);
dst_key_free(&key);
}
--
2.20.1

29
bind-9.11-rh1666814.patch Normal file
View file

@ -0,0 +1,29 @@
From d05d116da39c0a5c580ceaac6ba069899b82c5a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Wed, 16 Jan 2019 16:27:33 +0100
Subject: [PATCH] Fix possible crash when loading corrupted file
Some values passes internal triggers by coincidence. Fix the check and
check also first_node_offset before even passing it further.
---
lib/dns/rbt.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c
index 5aee5f6..7f2c2d2 100644
--- a/lib/dns/rbt.c
+++ b/lib/dns/rbt.c
@@ -945,7 +945,9 @@ dns_rbt_deserialize_tree(void *base_address, size_t filesize,
rbt->root = (dns_rbtnode_t *)((char *)base_address + header_offset +
header->first_node_offset);
- if ((header->nodecount * sizeof(dns_rbtnode_t)) > filesize) {
+ if ((header->nodecount * sizeof(dns_rbtnode_t)) > filesize
+ || header->first_node_offset > filesize) {
+
result = ISC_R_INVALIDFILE;
goto cleanup;
}
--
2.31.1

View file

@ -0,0 +1,83 @@
From e6ab9c67f0a14adc23c1067e03a106da1b1651b7 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Fri, 18 Oct 2019 21:30:52 +0200
Subject: [PATCH] Move USE_PKCS11 and USE_OPENSSL out of config.h
Building two variants with the same common code requires to unset
USE_PKCS11 on part of build. That is not possible with config.h value.
Move it as normal define to CDEFINES.
---
bin/confgen/Makefile.in | 2 +-
configure.ac | 8 ++++++--
lib/dns/dst_internal.h | 12 +++++++++---
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/bin/confgen/Makefile.in b/bin/confgen/Makefile.in
index 1b7512d..c126bf3 100644
--- a/bin/confgen/Makefile.in
+++ b/bin/confgen/Makefile.in
@@ -22,7 +22,7 @@ VERSION=@BIND9_VERSION@
CINCLUDES = -I${srcdir}/include ${ISC_INCLUDES} ${ISCCC_INCLUDES} \
${ISCCFG_INCLUDES} ${DNS_INCLUDES} ${BIND9_INCLUDES}
-CDEFINES =
+CDEFINES = @USE_PKCS11@
CWARNINGS =
ISCCFGLIBS = ../../lib/isccfg/libisccfg.@A@
diff --git a/configure.ac b/configure.ac
index f5483fe..08a7d8a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -935,10 +935,14 @@ AC_SUBST([PKCS11_TEST])
AC_SUBST([PKCS11_TOOLS])
AC_SUBST([PKCS11_MANS])
+USE_PKCS11='-DUSE_PKCS11=0'
+USE_OPENSSL='-DUSE_OPENSSL=0'
AC_SUBST([CRYPTO])
AS_CASE([$CRYPTO],
- [pkcs11],[AC_DEFINE([USE_PKCS11], [1], [define if PKCS11 is used for Public-Key Cryptography])],
- [AC_DEFINE([USE_OPENSSL], [1], [define if OpenSSL is used for Public-Key Cryptography])])
+ [pkcs11],[USE_PKCS11='-DUSE_PKCS11=1'],
+ [USE_OPENSSL='-DUSE_OPENSSL=1'])
+AC_SUBST(USE_PKCS11)
+AC_SUBST(USE_OPENSSL)
# preparation for automake
# AM_CONDITIONAL([PKCS11_TOOLS], [test "$with_native_pkcs11" = "yes"])
diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h
index 2c3b4a3..55e9dc4 100644
--- a/lib/dns/dst_internal.h
+++ b/lib/dns/dst_internal.h
@@ -38,6 +38,13 @@
#include <isc/stdtime.h>
#include <isc/types.h>
+#ifndef USE_PKCS11
+#define USE_PKCS11 0
+#endif
+#ifndef USE_OPENSSL
+#define USE_OPENSSL (! USE_PKCS11)
+#endif
+
#if USE_PKCS11
#include <pk11/pk11.h>
#include <pk11/site.h>
@@ -116,11 +123,10 @@ struct dst_key {
void *generic;
dns_gss_ctx_id_t gssctx;
DH *dh;
-#if USE_OPENSSL
- EVP_PKEY *pkey;
-#endif /* if USE_OPENSSL */
#if USE_PKCS11
pk11_object_t *pkey;
+#else
+ EVP_PKEY *pkey;
#endif /* if USE_PKCS11 */
dst_hmac_key_t *hmac_key;
} keydata; /*%< pointer to key in crypto pkg fmt */
--
2.26.2

View file

@ -1,4 +1,4 @@
From 402403b4bbb4f603693378e86b6c97997ccb0401 Mon Sep 17 00:00:00 2001
From 3a161af91bffcd457586ab466e32ac8484028763 Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Wed, 17 Jun 2020 23:17:13 +0200
Subject: [PATCH] Update man named with Red Hat specifics
@ -6,15 +6,15 @@ Subject: [PATCH] Update man named with Red Hat specifics
This is almost unmodified text and requires revalidation. Some of those
statements are no longer correct.
---
bin/named/named.rst | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
bin/named/named.rst | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/bin/named/named.rst b/bin/named/named.rst
index ea440b2..fa51984 100644
index 6fd8f87..3cd6350 100644
--- a/bin/named/named.rst
+++ b/bin/named/named.rst
@@ -212,6 +212,47 @@ Files
|named_pid|
@@ -228,6 +228,41 @@ Files
``/var/run/named/named.pid``
The default process-id file.
+Notes
@ -24,7 +24,7 @@ index ea440b2..fa51984 100644
+
+By default, Red Hat ships BIND with the most secure SELinux policy
+that will not prevent normal BIND operation and will prevent exploitation
+of all known BIND security vulnerabilities . See the selinux(8) man page
+of all known BIND security vulnerabilities. See the selinux(8) man page
+for information about SElinux.
+
+It is not necessary to run named in a chroot environment if the Red Hat
@ -34,33 +34,27 @@ index ea440b2..fa51984 100644
+
+*With this extra security comes some restrictions:*
+
+By default, the SELinux policy does not allow named to write any master
+zone database files. Only the root user may create files in the $ROOTDIR/var/named
+zone database file directory (the options { "directory" } option), where
+$ROOTDIR is set in /etc/sysconfig/named.
+By default, the SELinux policy does not allow named to write outside directory
+/var/named. That directory used to be read-only for named, but write access is
+enabled by default now.
+
+The "named" group must be granted read privelege to
+these files in order for named to be enabled to read them.
+Any file updated by named must be writeable by named user or named group.
+
+Any file created in the zone database file directory is automatically assigned
+the SELinux file context *named_zone_t* .
+
+By default, SELinux prevents any role from modifying *named_zone_t* files; this
+means that files in the zone database directory cannot be modified by dynamic
+DNS (DDNS) updates or zone transfers.
+
+The Red Hat BIND distribution and SELinux policy creates three directories where
+named is allowed to create and modify files: */var/named/slaves*, */var/named/dynamic*
+*/var/named/data*. By placing files you want named to modify, such as
+slave or DDNS updateable zone files and database / statistics dump files in
+these directories, named will work normally and no further operator action is
+required. Files in these directories are automatically assigned the '*named_cache_t*'
+file context, which SELinux allows named to write.
+
+named were allowed to create and modify files: */var/named/slaves*, */var/named/dynamic*
+*/var/named/data*. The service is able to write and file under */var/named* with appropriate
+permissions. They are used for better organisation of zones and backward compatibility.
+Files in these directories are automatically assigned the '*named_cache_t*'
+file context, which SELinux always allows named to write.
+
See Also
~~~~~~~~
--
2.34.1
2.26.2

View file

@ -0,0 +1,113 @@
From 7270604440268bb17b39ae734ff33003a67c8343 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 20 Jul 2021 19:34:42 +0200
Subject: [PATCH] Check parsed resconf values
Add 'attempts' check, fix 'ndots' data. Create a bunch of verification
functions and check parsed values, not just return codes.
---
lib/irs/tests/resconf_test.c | 46 ++++++++++++++++++--
lib/irs/tests/testdata/options-attempts.conf | 10 +++++
lib/irs/tests/testdata/options-ndots.conf | 2 +-
3 files changed, 54 insertions(+), 4 deletions(-)
create mode 100644 lib/irs/tests/testdata/options-attempts.conf
diff --git a/lib/irs/tests/resconf_test.c b/lib/irs/tests/resconf_test.c
index 6951758..ce94345 100644
--- a/lib/irs/tests/resconf_test.c
+++ b/lib/irs/tests/resconf_test.c
@@ -45,6 +45,43 @@ setup_test() {
assert_return_code(chdir(TESTS), 0);
}
+static isc_result_t
+check_number(unsigned int n, unsigned int expected) {
+ return ((n == expected) ? ISC_R_SUCCESS : ISC_R_BADNUMBER);
+}
+
+static isc_result_t
+check_attempts(irs_resconf_t *resconf) {
+ return (check_number(irs_resconf_getattempts(resconf), 4));
+}
+
+static isc_result_t
+check_timeout(irs_resconf_t *resconf) {
+ return (check_number(irs_resconf_gettimeout(resconf), 1));
+}
+
+static isc_result_t
+check_ndots(irs_resconf_t *resconf) {
+ return (check_number(irs_resconf_getndots(resconf), 2));
+}
+
+static isc_result_t
+check_options(irs_resconf_t *resconf) {
+ if (irs_resconf_getattempts(resconf) != 3) {
+ return ISC_R_BADNUMBER; /* default value only */
+ }
+
+ if (irs_resconf_getndots(resconf) != 2) {
+ return ISC_R_BADNUMBER;
+ }
+
+ if (irs_resconf_gettimeout(resconf) != 1) {
+ return ISC_R_BADNUMBER;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
/* test irs_resconf_load() */
static void
irs_resconf_load_test(void **state) {
@@ -64,15 +101,18 @@ irs_resconf_load_test(void **state) {
ISC_R_SUCCESS },
{ "testdata/nameserver-v6-scoped.conf", ISC_R_SUCCESS, NULL,
ISC_R_SUCCESS },
+ { "testdata/options-attempts.conf", ISC_R_SUCCESS,
+ check_attempts, ISC_R_SUCCESS },
{ "testdata/options-debug.conf", ISC_R_SUCCESS, NULL,
ISC_R_SUCCESS },
- { "testdata/options-ndots.conf", ISC_R_SUCCESS, NULL,
+ { "testdata/options-ndots.conf", ISC_R_SUCCESS, check_ndots,
ISC_R_SUCCESS },
- { "testdata/options-timeout.conf", ISC_R_SUCCESS, NULL,
+ { "testdata/options-timeout.conf", ISC_R_SUCCESS, check_timeout,
ISC_R_SUCCESS },
{ "testdata/options-unknown.conf", ISC_R_SUCCESS, NULL,
ISC_R_SUCCESS },
- { "testdata/options.conf", ISC_R_SUCCESS, NULL, ISC_R_SUCCESS },
+ { "testdata/options.conf", ISC_R_SUCCESS, check_options,
+ ISC_R_SUCCESS },
{ "testdata/options-bad-ndots.conf", ISC_R_RANGE, NULL,
ISC_R_SUCCESS },
{ "testdata/options-empty.conf", ISC_R_UNEXPECTEDEND, NULL,
diff --git a/lib/irs/tests/testdata/options-attempts.conf b/lib/irs/tests/testdata/options-attempts.conf
new file mode 100644
index 0000000..4538643
--- /dev/null
+++ b/lib/irs/tests/testdata/options-attempts.conf
@@ -0,0 +1,10 @@
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# 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 attempts:4
diff --git a/lib/irs/tests/testdata/options-ndots.conf b/lib/irs/tests/testdata/options-ndots.conf
index 5d18d26..f37c712 100644
--- a/lib/irs/tests/testdata/options-ndots.conf
+++ b/lib/irs/tests/testdata/options-ndots.conf
@@ -9,4 +9,4 @@
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
-option ndots:2
+options ndots:2
--
2.35.3

View file

@ -0,0 +1,203 @@
From b0e79979672935ff07bf23703c675ee788940c59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 22 Jun 2021 16:35:46 +0200
Subject: [PATCH] Parse 'timeout' and 'attempts' from resolv.conf
It was supported by lwres in BIND 9.11, and is still mentioned in
the manual page. Restore support for it by adding it to libirs.
---
bin/dig/dighost.c | 13 ++++++-
lib/irs/include/irs/resconf.h | 20 +++++++++++
lib/irs/resconf.c | 64 ++++++++++++++++++++++++++++-------
3 files changed, 84 insertions(+), 13 deletions(-)
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 0222454..274e894 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -133,7 +133,7 @@ int sendcount = 0;
int recvcount = 0;
int sockcount = 0;
int ndots = -1;
-int tries = 3;
+int tries = -1;
int lookup_counter = 0;
static char servercookie[256];
@@ -1330,6 +1330,17 @@ setup_system(bool ipv4only, bool ipv6only) {
ndots = irs_resconf_getndots(resconf);
debug("ndots is %d.", ndots);
}
+ if (timeout == 0) {
+ timeout = irs_resconf_gettimeout(resconf);
+ debug("timeout is %d.", timeout);
+ }
+ if (tries == -1) {
+ tries = irs_resconf_getattempts(resconf);
+ if (tries == 0) {
+ tries = 3;
+ }
+ debug("retries is %d.", tries);
+ }
/* If user doesn't specify server use nameservers from resolv.conf. */
if (ISC_LIST_EMPTY(server_list)) {
diff --git a/lib/irs/include/irs/resconf.h b/lib/irs/include/irs/resconf.h
index 424b795..74fc84a 100644
--- a/lib/irs/include/irs/resconf.h
+++ b/lib/irs/include/irs/resconf.h
@@ -113,6 +113,26 @@ irs_resconf_getndots(irs_resconf_t *conf);
*\li 'conf' is a valid resconf object.
*/
+unsigned int
+irs_resconf_getattempts(irs_resconf_t *conf);
+/*%<
+ * Return the 'attempts' value stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
+unsigned int
+irs_resconf_gettimeout(irs_resconf_t *conf);
+/*%<
+ * Return the 'timeout' value stored in 'conf'.
+ *
+ * Requires:
+ *
+ *\li 'conf' is a valid resconf object.
+ */
+
ISC_LANG_ENDDECLS
#endif /* IRS_RESCONF_H */
diff --git a/lib/irs/resconf.c b/lib/irs/resconf.c
index 096064b..dd51d71 100644
--- a/lib/irs/resconf.c
+++ b/lib/irs/resconf.c
@@ -80,6 +80,13 @@
#define RESCONFMAXLINELEN 256U /*%< max size of a line */
#define RESCONFMAXSORTLIST 10U /*%< max 10 */
+#define CHECK(op) \
+ do { \
+ result = (op); \
+ if (result != ISC_R_SUCCESS) \
+ goto cleanup; \
+ } while (0)
+
/*!
* configuration data structure
*/
@@ -114,6 +121,10 @@ struct irs_resconf {
uint8_t resdebug;
/*%< set to n in 'options ndots:n' */
uint8_t ndots;
+ /*%< set to n in 'options attempts:n' */
+ uint8_t attempts;
+ /*%< set to n in 'options timeout:n' */
+ uint8_t timeout;
};
static isc_result_t
@@ -176,8 +187,8 @@ eatwhite(FILE *fp) {
*/
static int
getword(FILE *fp, char *buffer, size_t size) {
+ char *p = NULL;
int ch;
- char *p;
REQUIRE(buffer != NULL);
REQUIRE(size > 0U);
@@ -457,11 +468,26 @@ resconf_parsesortlist(irs_resconf_t *conf, FILE *fp) {
return (ISC_R_SUCCESS);
}
+static isc_result_t
+resconf_optionnumber(const char *word, uint8_t *number) {
+ char *p;
+ long n;
+
+ n = strtol(word, &p, 10);
+ if (*p != '\0') { /* Bad string. */
+ return (ISC_R_UNEXPECTEDTOKEN);
+ }
+ if (n < 0 || n > 0xff) { /* Out of range. */
+ return (ISC_R_RANGE);
+ }
+ *number = n;
+ return (ISC_R_SUCCESS);
+}
+
static isc_result_t
resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
int delim;
- long ndots;
- char *p;
+ isc_result_t result = ISC_R_SUCCESS;
char word[RESCONFMAXLINELEN];
delim = getword(fp, word, sizeof(word));
@@ -473,14 +499,11 @@ resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
if (strcmp("debug", word) == 0) {
conf->resdebug = 1;
} else if (strncmp("ndots:", word, 6) == 0) {
- ndots = strtol(word + 6, &p, 10);
- if (*p != '\0') { /* Bad string. */
- return (ISC_R_UNEXPECTEDTOKEN);
- }
- if (ndots < 0 || ndots > 0xff) { /* Out of range. */
- return (ISC_R_RANGE);
- }
- conf->ndots = (uint8_t)ndots;
+ CHECK(resconf_optionnumber(word + 6, &conf->ndots));
+ } else if (strncmp("attempts:", word, 9) == 0) {
+ CHECK(resconf_optionnumber(word + 9, &conf->attempts));
+ } else if (strncmp("timeout:", word, 8) == 0) {
+ CHECK(resconf_optionnumber(word + 8, &conf->timeout));
}
if (delim == EOF || delim == '\n') {
@@ -490,7 +513,8 @@ resconf_parseoption(irs_resconf_t *conf, FILE *fp) {
}
}
- return (ISC_R_SUCCESS);
+cleanup:
+ return (result);
}
static isc_result_t
@@ -532,6 +556,8 @@ irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp) {
conf->sortlistnxt = 0;
conf->resdebug = 0;
conf->ndots = 1;
+ conf->attempts = 3;
+ conf->timeout = 0;
for (i = 0; i < RESCONFMAXSEARCH; i++) {
conf->search[i] = NULL;
}
@@ -687,3 +713,17 @@ irs_resconf_getndots(irs_resconf_t *conf) {
return ((unsigned int)conf->ndots);
}
+
+unsigned int
+irs_resconf_getattempts(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return ((unsigned int)conf->attempts);
+}
+
+unsigned int
+irs_resconf_gettimeout(irs_resconf_t *conf) {
+ REQUIRE(IRS_RESCONF_VALID(conf));
+
+ return ((unsigned int)conf->timeout);
+}
--
2.35.3

View file

@ -1,854 +0,0 @@
From 2a4786b0edde59274f682c9bd4ae4026c2d08218 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Wed, 1 Jul 2026 22:56:02 -0700
Subject: [PATCH] add isctest.mark method for ecdsa_deterinistic
This checks support for ECDSA deterministic mode in the cryptography
library.
(cherry picked from commit 6e44151466864d3dd783a20da83d01028781d3e2)
(cherry picked from commit dc3f52388427f4f94087d984d5a2088b925810e2)
Reproducer for #5874 NSEC3 impersonation
LLM generated.
(cherry picked from commit f3e2eb333be3ac636f745aa13cfb8d9ee8af87d8)
(cherry picked from commit 35e3d49d2222c13786a06021c7ed583d2a656e51)
Update reproducer #5874
Update the llm generated reproducer:
- Move server.py into ans1/ans.py
- Remove unnecessary named.conf configuration options
- Add comments describing the steps (copied from GL issue)
- Rename system test
(cherry picked from commit c1321fef165a2ef8c2bff971901c58941e8e694c)
(cherry picked from commit 833dd3b230b92596074e8da15b12298f46c939f2)
---
bin/tests/system/chain/ans3/ans.py | 10 +-
bin/tests/system/chain/ans4/ans.py | 8 +-
bin/tests/system/cookie/ans9/ans.py | 7 +-
bin/tests/system/digdelv/ans8/ans.py | 7 +-
bin/tests/system/dnssec/ans10/ans.py | 11 +-
bin/tests/system/forward/ans11/ans.py | 12 +-
bin/tests/system/isctest/mark.py | 12 +
.../system/nsec3_impersonation/ans1/ans.py | 280 ++++++++++++++++++
.../nsec3_impersonation/ns2/named.conf.j2 | 33 +++
.../tests_nsec3_impersonation.py | 152 ++++++++++
bin/tests/system/qmin/ans2/ans.py | 11 +-
bin/tests/system/qmin/ans3/ans.py | 11 +-
bin/tests/system/qmin/ans4/ans.py | 11 +-
bin/tests/system/resolver/ans10/ans.py | 12 +-
14 files changed, 529 insertions(+), 48 deletions(-)
create mode 100644 bin/tests/system/nsec3_impersonation/ans1/ans.py
create mode 100644 bin/tests/system/nsec3_impersonation/ns2/named.conf.j2
create mode 100644 bin/tests/system/nsec3_impersonation/tests_nsec3_impersonation.py
diff --git a/bin/tests/system/chain/ans3/ans.py b/bin/tests/system/chain/ans3/ans.py
index 0a031c1145..7c54c3c51a 100644
--- a/bin/tests/system/chain/ans3/ans.py
+++ b/bin/tests/system/chain/ans3/ans.py
@@ -19,10 +19,10 @@ import sys
import signal
import socket
import select
-from datetime import datetime, timedelta
-import functools
-import dns, dns.message, dns.query
+import dns
+import dns.message
+import dns.query
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -173,9 +173,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/chain/ans4/ans.py b/bin/tests/system/chain/ans4/ans.py
index c969117368..de536b25bd 100755
--- a/bin/tests/system/chain/ans4/ans.py
+++ b/bin/tests/system/chain/ans4/ans.py
@@ -22,7 +22,9 @@ import select
from datetime import datetime, timedelta
import functools
-import dns, dns.message, dns.query
+import dns
+import dns.message
+import dns.query
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -371,9 +373,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/cookie/ans9/ans.py b/bin/tests/system/cookie/ans9/ans.py
index 3b0f82cc1d..2710386d74 100644
--- a/bin/tests/system/cookie/ans9/ans.py
+++ b/bin/tests/system/cookie/ans9/ans.py
@@ -15,9 +15,6 @@ import sys
import signal
import socket
import select
-from datetime import datetime, timedelta
-import time
-import functools
import dns
import dns.edns
@@ -257,9 +254,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/digdelv/ans8/ans.py b/bin/tests/system/digdelv/ans8/ans.py
index 3e18edc1cc..1896a2bafc 100644
--- a/bin/tests/system/digdelv/ans8/ans.py
+++ b/bin/tests/system/digdelv/ans8/ans.py
@@ -17,7 +17,8 @@ import socket
import select
import struct
-import dns, dns.message
+import dns
+import dns.message
from dns.rcode import *
modes = [
@@ -109,9 +110,9 @@ hung_conns = []
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/dnssec/ans10/ans.py b/bin/tests/system/dnssec/ans10/ans.py
index 84bf0a2642..46af72a147 100644
--- a/bin/tests/system/dnssec/ans10/ans.py
+++ b/bin/tests/system/dnssec/ans10/ans.py
@@ -16,10 +16,11 @@ import signal
import socket
import select
from datetime import datetime, timedelta
-import time
-import functools
-import dns, dns.message, dns.query, dns.flags
+import dns
+import dns.message
+import dns.query
+import dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -140,9 +141,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/forward/ans11/ans.py b/bin/tests/system/forward/ans11/ans.py
index 00b5895f76..d5b8a5b037 100644
--- a/bin/tests/system/forward/ans11/ans.py
+++ b/bin/tests/system/forward/ans11/ans.py
@@ -16,11 +16,11 @@ import signal
import socket
import select
import struct
-from datetime import datetime, timedelta
-import time
-import functools
-import dns, dns.message, dns.query, dns.flags
+import dns
+import dns.message
+import dns.query
+import dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -192,9 +192,9 @@ hung_conns = []
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/isctest/mark.py b/bin/tests/system/isctest/mark.py
index 53860a806c..098af5acfc 100644
--- a/bin/tests/system/isctest/mark.py
+++ b/bin/tests/system/isctest/mark.py
@@ -88,3 +88,15 @@ softhsm2_environment = pytest.mark.skipif(
),
reason="SOFTHSM2_CONF and SOFTHSM2_MODULE environmental variables must be set and pkcs11-tool and softhsm2-util tools present",
)
+
+ecdsa_deterministic = False
+try:
+ from cryptography.hazmat.backends import default_backend
+
+ ecdsa_deterministic = default_backend().ecdsa_deterministic_supported()
+except Exception: # pylint: disable=broad-except
+ pass
+
+with_ecdsa_deterministic = pytest.mark.skipif(
+ not ecdsa_deterministic, reason="ECDSA deterministic signing is not supported"
+)
diff --git a/bin/tests/system/nsec3_impersonation/ans1/ans.py b/bin/tests/system/nsec3_impersonation/ans1/ans.py
new file mode 100644
index 0000000000..177e79c195
--- /dev/null
+++ b/bin/tests/system/nsec3_impersonation/ans1/ans.py
@@ -0,0 +1,280 @@
+#!/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 collections.abc import AsyncGenerator
+from dataclasses import dataclass
+from pathlib import Path
+
+import json
+
+from cryptography.hazmat.primitives import serialization
+
+import dns.dnssec
+import dns.flags
+import dns.message
+import dns.name
+import dns.rcode
+import dns.rdata
+import dns.rdataclass
+import dns.rdatatype
+import dns.rrset
+
+from isctest.asyncserver import (
+ AsyncDnsServer,
+ DnsResponseSend,
+ QueryContext,
+ ResponseHandler,
+)
+
+TTL = 300
+TLD = "tld.test."
+APEX_HASH = "1B40241KFORIOG780N4IKSCRLVETPCTQ"
+ATTACKER = f"{APEX_HASH.lower()}.{TLD}"
+VICTIM = f"victim.{TLD}"
+AUTH_IP = "10.53.0.1"
+
+
+@dataclass(frozen=True)
+class Key:
+ zone: dns.name.Name
+ private_key: object
+ dnskey: dns.rdata.Rdata
+ ds: dns.rdata.Rdata
+
+
+def name(text: str) -> dns.name.Name:
+ return dns.name.from_text(text)
+
+
+def load_keys() -> dict[str, Key]:
+ path = Path(__file__).resolve().parent / "keys.json"
+ with path.open(encoding="utf-8") as keys_file:
+ raw_keys = json.load(keys_file)
+
+ keys = {}
+ for zone, raw_key in raw_keys.items():
+ private_key = serialization.load_pem_private_key(
+ raw_key["private_pem"].encode("ascii"),
+ password=None,
+ )
+ dnskey = dns.rdata.from_text(
+ dns.rdataclass.IN, dns.rdatatype.DNSKEY, raw_key["dnskey"]
+ )
+ ds = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.DS, raw_key["ds"])
+ keys[zone] = Key(name(zone), private_key, dnskey, ds)
+
+ return keys
+
+
+def rrset(owner: str, rdtype: dns.rdatatype.RdataType, *rdatas: str) -> dns.rrset.RRset:
+ return dns.rrset.from_text(owner, TTL, dns.rdataclass.IN, rdtype, *rdatas)
+
+
+def rrset_from_rdata(owner: str, rdata: dns.rdata.Rdata) -> dns.rrset.RRset:
+ return dns.rrset.from_rdata(name(owner), TTL, rdata)
+
+
+def rrsig_rrset(covered: dns.rrset.RRset, signer: Key) -> dns.rrset.RRset:
+ rrsig = dns.dnssec.sign(
+ covered,
+ signer.private_key,
+ signer.zone,
+ signer.dnskey,
+ lifetime=86400,
+ verify=True,
+ )
+ return dns.rrset.from_rdata(covered.name, covered.ttl, rrsig)
+
+
+def add_signed(
+ section: list[dns.rrset.RRset], covered: dns.rrset.RRset, signer: Key
+) -> None:
+ section.append(covered)
+ section.append(rrsig_rrset(covered, signer))
+
+
+def dnskey_rrset(zone: str, zone_key: Key) -> dns.rrset.RRset:
+ return rrset_from_rdata(zone, zone_key.dnskey)
+
+
+def ds_rrset(zone: str, zone_key: Key) -> dns.rrset.RRset:
+ return rrset_from_rdata(zone, zone_key.ds)
+
+
+def soa_rrset(zone: str) -> dns.rrset.RRset:
+ return rrset(
+ zone,
+ dns.rdatatype.SOA,
+ f"ns.{zone} hostmaster.{zone} 1 3600 600 86400 300",
+ )
+
+
+def ns_rrset(zone: str, ns_target: str) -> dns.rrset.RRset:
+ return rrset(zone, dns.rdatatype.NS, ns_target)
+
+
+def glue_rrset(ns_target: str, address: str) -> dns.rrset.RRset:
+ return rrset(ns_target, dns.rdatatype.A, address)
+
+
+def answer_dnskey(response: dns.message.Message, zone: str, zone_key: Key) -> None:
+ add_signed(response.answer, dnskey_rrset(zone, zone_key), zone_key)
+
+
+def answer_soa(response: dns.message.Message, zone: str, zone_key: Key) -> None:
+ add_signed(response.answer, soa_rrset(zone), zone_key)
+
+
+def answer_ns(
+ response: dns.message.Message, zone: str, ns_target: str, zone_key: Key
+) -> None:
+ add_signed(response.answer, ns_rrset(zone, ns_target), zone_key)
+
+
+class SignedResponseHandler(ResponseHandler):
+ def __init__(self, keys: dict[str, Key]) -> None:
+ self.keys = keys
+
+ async def get_responses(
+ self, qctx: QueryContext
+ ) -> AsyncGenerator[DnsResponseSend, None]:
+ qctx.prepare_new_response(with_zone_data=False)
+ qctx.response.flags |= dns.flags.AA
+ qctx.response.set_rcode(dns.rcode.NOERROR)
+ self.respond(qctx)
+ yield DnsResponseSend(qctx.response, authoritative=True)
+
+ def respond(self, qctx: QueryContext) -> None:
+ raise NotImplementedError
+
+
+def child_nsec3_rrset() -> dns.rrset.RRset:
+ rdata = dns.rdata.from_text(
+ dns.rdataclass.IN,
+ dns.rdatatype.NSEC3,
+ f"1 0 0 - {APEX_HASH} NS SOA RRSIG DNSKEY NSEC3PARAM",
+ )
+ return dns.rrset.from_rdata(name(f"{APEX_HASH}.{TLD}"), TTL, rdata)
+
+
+def forged_nxdomain(response: dns.message.Message, keys: dict[str, Key]) -> None:
+ response.set_rcode(dns.rcode.NXDOMAIN)
+
+ add_signed(response.authority, soa_rrset(TLD), keys[TLD])
+
+ # The owner name derives zone "tld.test.", but the RRSIG signer is the
+ # malicious child zone "1b40241kforiog780n4ikscrlvetpctq.tld.test.".
+ add_signed(response.authority, child_nsec3_rrset(), keys[ATTACKER])
+
+
+class VictimForgedNxdomainHandler(SignedResponseHandler):
+ """
+ This serves the forged response for the victim's domain.
+ """
+
+ def match(self, qctx: QueryContext) -> bool:
+ return qctx.qname == name(VICTIM) and qctx.qtype == dns.rdatatype.A
+
+ def respond(self, qctx: QueryContext) -> None:
+ forged_nxdomain(qctx.response, self.keys)
+
+
+class ChildDsHandler(SignedResponseHandler):
+ """
+ This will spoof the response for the malicious zone when qtype is DS.
+ It is actually a validly signed DS response.
+ """
+
+ def match(self, qctx: QueryContext) -> bool:
+ return qctx.qname == name(ATTACKER) and qctx.qtype == dns.rdatatype.DS
+
+ def respond(self, qctx: QueryContext) -> None:
+ response = qctx.response
+ zone = ATTACKER
+ child_key = self.keys[ATTACKER]
+ parent_key = self.keys[TLD]
+
+ add_signed(response.answer, ds_rrset(zone, child_key), parent_key)
+
+
+class AttackerZoneHandler(SignedResponseHandler):
+ """
+ Acts as the malicious authoritative name server. The zone being served
+ is the hashed label of the parent zone (tld.test). This will respond
+ for all queries qtype SOA, DNSKEY, NS at the apex. Any names below
+ the apex are answered with an NXDOMAIN with no NSEC or NSEC3 present.
+ """
+
+ def match(self, qctx: QueryContext) -> bool:
+ return qctx.qname.is_subdomain(name(ATTACKER))
+
+ def respond(self, qctx: QueryContext) -> None:
+ if qctx.qname == name(ATTACKER):
+ if qctx.qtype == dns.rdatatype.DNSKEY:
+ answer_dnskey(qctx.response, ATTACKER, self.keys[ATTACKER])
+ elif qctx.qtype == dns.rdatatype.SOA:
+ answer_soa(qctx.response, ATTACKER, self.keys[ATTACKER])
+ else:
+ answer_ns(
+ qctx.response, ATTACKER, f"ns.{ATTACKER}", self.keys[ATTACKER]
+ )
+ qctx.response.additional.append(glue_rrset(f"ns.{ATTACKER}", AUTH_IP))
+ return
+
+ qctx.response.set_rcode(dns.rcode.NXDOMAIN)
+ add_signed(qctx.response.authority, soa_rrset(ATTACKER), self.keys[ATTACKER])
+
+
+class TldZoneHandler(SignedResponseHandler):
+ """
+ Acts as the TLD who is being used in the attack, but is not a standard
+ name server. It only responds with validly signed records for DNSKEY, SOA
+ and NS on the apex. Any names below the apex are answered with an NXDOMAIN
+ with no NSEC or NSEC3 present.
+
+ If we turn this into a regular name server than the attack won't work.
+ The attack assumes that the adversary can inject these responses on-path.
+ """
+
+ def match(self, qctx: QueryContext) -> bool:
+ return qctx.qname.is_subdomain(name(TLD))
+
+ def respond(self, qctx: QueryContext) -> None:
+ if qctx.qname == name(TLD):
+ if qctx.qtype == dns.rdatatype.DNSKEY:
+ answer_dnskey(qctx.response, TLD, self.keys[TLD])
+ elif qctx.qtype == dns.rdatatype.SOA:
+ answer_soa(qctx.response, TLD, self.keys[TLD])
+ else:
+ answer_ns(qctx.response, TLD, "ns.tld.test.", self.keys[TLD])
+ qctx.response.additional.append(glue_rrset("ns.tld.test.", AUTH_IP))
+ return
+
+ qctx.response.set_rcode(dns.rcode.NXDOMAIN)
+ add_signed(qctx.response.authority, soa_rrset(TLD), self.keys[TLD])
+
+
+def main() -> None:
+ keys = load_keys()
+ server = AsyncDnsServer(default_aa=True)
+ server.install_response_handlers(
+ VictimForgedNxdomainHandler(keys),
+ ChildDsHandler(keys),
+ AttackerZoneHandler(keys),
+ TldZoneHandler(keys),
+ )
+ server.run()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/tests/system/nsec3_impersonation/ns2/named.conf.j2 b/bin/tests/system/nsec3_impersonation/ns2/named.conf.j2
new file mode 100644
index 0000000000..2c9b0bba9e
--- /dev/null
+++ b/bin/tests/system/nsec3_impersonation/ns2/named.conf.j2
@@ -0,0 +1,33 @@
+// 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";
+};
+
+zone "tld.test" {
+ type static-stub;
+ server-addresses { 10.53.0.1; };
+};
+
+trust-anchors {
+ tld.test. static-key 257 3 13 "@TLD_DNSKEY@";
+};
diff --git a/bin/tests/system/nsec3_impersonation/tests_nsec3_impersonation.py b/bin/tests/system/nsec3_impersonation/tests_nsec3_impersonation.py
new file mode 100644
index 0000000000..bd9bd275b6
--- /dev/null
+++ b/bin/tests/system/nsec3_impersonation/tests_nsec3_impersonation.py
@@ -0,0 +1,152 @@
+#!/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 pathlib import Path
+
+import json
+
+from cryptography.hazmat.primitives import serialization
+from cryptography.hazmat.primitives.asymmetric import ec
+
+import dns.dnssec
+import dns.flags
+import dns.name
+import dns.rdataclass
+import dns.rdatatype
+import pytest
+
+import isctest
+import isctest.mark
+
+APEX_HASH = "1B40241KFORIOG780N4IKSCRLVETPCTQ"
+ATTACKER = f"{APEX_HASH.lower()}.tld.test."
+VICTIM = "victim.tld.test."
+AUTH = "10.53.0.1"
+RESOLVER = "10.53.0.2"
+
+pytestmark = [
+ isctest.mark.with_ecdsa_deterministic,
+ pytest.mark.extra_artifacts(
+ [
+ "ans*/ans.run",
+ "ans*/keys.json",
+ ]
+ ),
+]
+
+
+def _make_key(zone):
+ private_key = ec.generate_private_key(ec.SECP256R1())
+ dnskey = dns.dnssec.make_dnskey(
+ private_key.public_key(),
+ algorithm="ECDSAP256SHA256",
+ flags=257,
+ )
+ ds = dns.dnssec.make_ds(dns.name.from_text(zone), dnskey, "SHA256")
+ private_pem = private_key.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.PKCS8,
+ encryption_algorithm=serialization.NoEncryption(),
+ ).decode("ascii")
+ return {
+ "private_pem": private_pem,
+ "dnskey": dnskey.to_text(),
+ "ds": ds.to_text(),
+ }
+
+
+def bootstrap():
+ zones = ["tld.test.", ATTACKER]
+ keys = {zone: _make_key(zone) for zone in zones}
+
+ Path("ans1/keys.json").write_text(json.dumps(keys, indent=2), encoding="ascii")
+
+ tld_dnskey = "".join(keys["tld.test."]["dnskey"].split()[3:])
+ return {"TLD_DNSKEY": tld_dnskey}
+
+
+def check_dnskey_response(zone):
+ query = isctest.query.create(zone, "DNSKEY")
+ response = isctest.query.tcp(query, AUTH)
+
+ isctest.check.noerror(response)
+ assert response.flags & dns.flags.AA
+ assert (
+ response.get_rrset(
+ response.answer,
+ dns.name.from_text(zone),
+ dns.rdataclass.IN,
+ dns.rdatatype.DNSKEY,
+ )
+ is not None
+ ), response
+
+
+def check_ds_response(zone):
+ query = isctest.query.create(zone, "DS")
+ response = isctest.query.tcp(query, AUTH)
+
+ isctest.check.noerror(response)
+ assert response.flags & dns.flags.AA
+ assert (
+ response.get_rrset(
+ response.answer,
+ dns.name.from_text(zone),
+ dns.rdataclass.IN,
+ dns.rdatatype.DS,
+ )
+ is not None
+ ), response
+
+
+def test_attack_responses():
+ check_dnskey_response("tld.test.")
+ check_dnskey_response(ATTACKER)
+ check_ds_response(ATTACKER)
+
+ query = isctest.query.create(VICTIM, "A")
+ response = isctest.query.tcp(query, AUTH)
+
+ isctest.check.nxdomain(response)
+ assert response.flags & dns.flags.AA
+
+ nsec3_owner = dns.name.from_text(f"{APEX_HASH}.tld.test.")
+ nsec3 = response.get_rrset(
+ response.authority,
+ nsec3_owner,
+ dns.rdataclass.IN,
+ dns.rdatatype.NSEC3,
+ )
+ rrsig = response.get_rrset(
+ response.authority,
+ nsec3_owner,
+ dns.rdataclass.IN,
+ dns.rdatatype.RRSIG,
+ covers=dns.rdatatype.NSEC3,
+ )
+
+ assert nsec3 is not None, response
+ assert rrsig is not None, response
+ assert rrsig[0].signer == dns.name.from_text(ATTACKER)
+
+
+def test_nsec3_impersonation():
+ """
+ Reproducer for #5874:
+ F-006 DNSSEC Validation Bypass NSEC3 Apex Hash Label Parent Impersonation
+ """
+ query = isctest.query.create(VICTIM, "A")
+ response = isctest.query.tcp(query, RESOLVER)
+
+ isctest.check.noadflag(response)
+ isctest.check.servfail(response)
diff --git a/bin/tests/system/qmin/ans2/ans.py b/bin/tests/system/qmin/ans2/ans.py
index d372c2003b..9343fbc8ef 100755
--- a/bin/tests/system/qmin/ans2/ans.py
+++ b/bin/tests/system/qmin/ans2/ans.py
@@ -15,11 +15,12 @@ import sys
import signal
import socket
import select
-from datetime import datetime, timedelta
import time
-import functools
-import dns, dns.message, dns.query, dns.flags
+import dns
+import dns.message
+import dns.query
+import dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -432,9 +433,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/qmin/ans3/ans.py b/bin/tests/system/qmin/ans3/ans.py
index b5ae73c3fa..4e7250790f 100755
--- a/bin/tests/system/qmin/ans3/ans.py
+++ b/bin/tests/system/qmin/ans3/ans.py
@@ -15,11 +15,12 @@ import sys
import signal
import socket
import select
-from datetime import datetime, timedelta
import time
-import functools
-import dns, dns.message, dns.query, dns.flags
+import dns
+import dns.message
+import dns.query
+import dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -261,9 +262,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/qmin/ans4/ans.py b/bin/tests/system/qmin/ans4/ans.py
index 517217aec1..2d5556daff 100755
--- a/bin/tests/system/qmin/ans4/ans.py
+++ b/bin/tests/system/qmin/ans4/ans.py
@@ -15,11 +15,12 @@ import sys
import signal
import socket
import select
-from datetime import datetime, timedelta
import time
-import functools
-import dns, dns.message, dns.query, dns.flags
+import dns
+import dns.message
+import dns.query
+import dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -320,9 +321,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
diff --git a/bin/tests/system/resolver/ans10/ans.py b/bin/tests/system/resolver/ans10/ans.py
index 6e95dbbfc6..d637c63e5a 100644
--- a/bin/tests/system/resolver/ans10/ans.py
+++ b/bin/tests/system/resolver/ans10/ans.py
@@ -15,11 +15,11 @@ import sys
import signal
import socket
import select
-from datetime import datetime, timedelta
-import time
-import functools
-import dns, dns.message, dns.query, dns.flags
+import dns
+import dns.message
+import dns.query
+import dns.flags
from dns.rdatatype import *
from dns.rdataclass import *
from dns.rcode import *
@@ -128,9 +128,9 @@ else:
while running:
try:
inputready, outputready, exceptready = select.select(input, [], [])
- except select.error as e:
+ except select.error:
break
- except socket.error as e:
+ except socket.error:
break
except KeyboardInterrupt:
break
--
2.55.0

View file

@ -1,67 +0,0 @@
From 608026780a43abe5b23a9af3af21808369032158 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Thu, 21 May 2026 14:41:55 -0700
Subject: [PATCH] Check NSEC3 signer matches the owning zone
When validating NSEC3 records, reject any signature whose signer field
does not match the zone owning the NSEC3.
This ensures that a child zone cannot impersonate its parent and forge
NXDOMAIN responses for sibling domains.
Fixes: isc-projects/bind9#5874
(cherry picked from commit 6e5066bb1f0f12d090e8707adb7d6ccf74f8012b)
(cherry picked from commit c9cb6a5e24e43489cf3fd4d4cc2193b6a74499cb)
---
lib/dns/dnssec.c | 19 +++++++++++++++++--
lib/isc/result.c | 2 +-
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index b12529b5d5..9b9b1f2bb2 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -424,10 +424,25 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
}
/*
- * NS, SOA and DNSKEY records are signed by their owner.
- * DS records are signed by the parent.
+ * NS, SOA and DNSKEY records are signed by their owners.
+ * NSEC3 records are signed by the apex, exactly one level up
+ * from their owner names.
+ * DS records are signed by the parent zone.
*/
switch (set->type) {
+ case dns_rdatatype_nsec3: {
+ dns_name_t apex = DNS_NAME_INITEMPTY;
+ labels = dns_name_countlabels(name);
+ if (labels <= 1) {
+ inc_stat(dns_dnssecstats_fail);
+ return DNS_R_INVALIDNSEC3;
+ }
+ dns_name_split(name, labels - 1, NULL, &apex);
+ if (!dns_name_equal(&apex, &sig.signer)) {
+ inc_stat(dns_dnssecstats_fail);
+ return DNS_R_SIGINVALID;
+ }
+ } break;
case dns_rdatatype_ns:
case dns_rdatatype_soa:
case dns_rdatatype_dnskey:
diff --git a/lib/isc/result.c b/lib/isc/result.c
index 83e8cfeed7..b76c3d1f7b 100644
--- a/lib/isc/result.c
+++ b/lib/isc/result.c
@@ -198,7 +198,7 @@ static const char *description[ISC_R_NRESULTS] = {
[DNS_R_COVERINGNSEC] = "covering NSEC record returned",
[DNS_R_MXISADDRESS] = "MX is an address",
[DNS_R_DUPLICATE] = "duplicate query",
- [DNS_R_INVALIDNSEC3] = "invalid NSEC3 owner name (wildcard)",
+ [DNS_R_INVALIDNSEC3] = "invalid NSEC3 owner name",
[DNS_R_NOTPRIMARY] = "not primary",
[DNS_R_BROKENCHAIN] = "broken trust chain",
[DNS_R_EXPIRED] = "expired",
--
2.55.0

View file

@ -1,320 +0,0 @@
From a4ce4c0ce5b8d7630417730dc1b98bf554e0801f Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 19 May 2026 10:44:04 +1000
Subject: [PATCH] Check that dns_name_fromwire honours the active region
When reading DNS records from the wire the active region of the
source buffer is set to the end of the current record. dns_name_fromwire
should fail if it attempts to read past this setting.
(cherry picked from commit 3ed821d68b15fe4e6288e3054397d6bce7e65968)
(cherry picked from commit d413c9ac2e29a728531354a69c8c8234c01b7d1e)
Check that a short PRIVATEDNS record is rejected
A bug in dns_name_fromwire meant that short PRIVATEDNS key
records where being accepted. Test that this is no longer
the case.
(cherry picked from commit f48d48027384d8c2210b5ce9e3eac7af101ead3d)
(cherry picked from commit 19ac8b8e46aeb0a15e217bc7bdf485b31b87d9b4)
POC for PRIVATEDNS DNSKEY overrun not being detected
Construct a DNS message where a PRIVATEDNS DNSKEY identifier
overruns the record boundary by 3 byte so that the label ends
at the end of the compression pointer for the next record. The
next type is less than 256 so the next octet is 00 terminating
the identifier name. The transfered zone is then written to
disk using master-format text triggering the assertion when the
truncated identier is discovered.
Note this test will produce a false result in versions of
BIND that do not check the PRIVATEDNS identifier as it looks
for the error message when the transfer is aborted.
(cherry picked from commit 9ce3bce8bc8b4e9c6a9b1e84b5849c33eb27830e)
(cherry picked from commit 8e066d3fc369e3346f22bb5cfb67a7ab08a74034)
---
bin/tests/system/xfer/ans9/ans.py | 142 ++++++++++++++++++++++++
bin/tests/system/xfer/ns6/named.conf.in | 9 ++
bin/tests/system/xfer/tests.sh | 16 +++
tests/dns/name_test.c | 30 +++++
tests/dns/rdata_test.c | 21 ++++
5 files changed, 218 insertions(+)
create mode 100644 bin/tests/system/xfer/ans9/ans.py
diff --git a/bin/tests/system/xfer/ans9/ans.py b/bin/tests/system/xfer/ans9/ans.py
new file mode 100644
index 0000000000..a9e73953ee
--- /dev/null
+++ b/bin/tests/system/xfer/ans9/ans.py
@@ -0,0 +1,142 @@
+"""
+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 collections.abc import AsyncGenerator
+
+import dns.name
+import dns.rcode
+import dns.rdatatype
+import dns.rrset
+
+from isctest.asyncserver import (
+ ControllableAsyncDnsServer,
+ DnsResponseSend,
+ DomainHandler,
+ QueryContext,
+ ResponseAction,
+ ToggleResponsesCommand,
+)
+
+
+class AXFRServer(DomainHandler):
+ """
+ Yield SOA and AXFR responses. Every new AXFR response increments the SOA
+ version.
+ """
+
+ domains = ["xfr-and-reconfig", "private-dns-overrun"]
+
+ def __init__(self) -> None:
+ super().__init__()
+ self.soa_version = 0
+
+ async def get_responses(
+ self, qctx: QueryContext
+ ) -> AsyncGenerator[ResponseAction, None]:
+ # This is oversimplified because I am lazy - we are appending the SOA
+ # RRset to the ANSWER section for _every_ QTYPE. named is only
+ # expected to send a SOA query over UDP and then an AXFR query over
+ # TCP. Responses to both of those start with a SOA RRset in the ANSWER
+ # section :-)
+ soa_message = qctx.response
+ soa_rrset = dns.rrset.from_text(
+ qctx.qname,
+ 300,
+ qctx.qclass,
+ dns.rdatatype.SOA,
+ f". . {self.soa_version} 0 0 0 0",
+ )
+ soa_message.answer.append(soa_rrset)
+
+ yield DnsResponseSend(soa_message)
+
+ if qctx.qtype == dns.rdatatype.SOA:
+ # If QTYPE=SOA, the SOA record is the complete response.
+ return
+
+ if qctx.qtype != dns.rdatatype.AXFR:
+ # If QTYPE=AXFR, we will continue cramming RRsets into the ANSWER
+ # section of a subsequent DNS message below.
+ #
+ # If QTYPE was not SOA or AXFR, abort. Yeah, we just sent a broken
+ # response by yielding DnsResponseSend() with a SOA RRset in the
+ # ANSWER section above. We will have to carry that burden for the
+ # rest of our lives.
+ return
+
+ # Send just the obligatory NS RRset at zone apex in the next message.
+ # This is stupidly inefficient, but makes looping below simpler as we
+ # will already have been done with the mandatory stuff by then.
+ ns_message = qctx.prepare_new_response()
+ ns_rrset = dns.rrset.from_text(
+ qctx.qname, 300, qctx.qclass, dns.rdatatype.NS, "."
+ )
+ ns_message.answer.append(ns_rrset)
+
+ yield DnsResponseSend(ns_message)
+
+ # Generate the AXFR with a txt rrset.
+ txt_message = qctx.prepare_new_response()
+ txt_rrset = dns.rrset.from_text(
+ qctx.qname,
+ 300,
+ qctx.qclass,
+ dns.rdatatype.TXT,
+ "foo bar",
+ )
+ txt_message.answer.append(txt_rrset)
+
+ yield DnsResponseSend(txt_message)
+
+ if qctx.qname == dns.name.from_text("private-dns-overrun"):
+ # A message where the malformed DNSKEY algorithm identifier
+ # finishes on a 00 byte in the next record. Assumes the
+ # next record starts with a compression pointer which is
+ # followed by the type which starts with 00.
+
+ # Generate malformed PRIVATE DNS DNSKEY
+ dnskey_message = qctx.prepare_new_response()
+ dnskey_rrset = dns.rrset.from_text(
+ qctx.qname,
+ 300,
+ qctx.qclass,
+ dns.rdatatype.DNSKEY,
+ "\\# 12 00 00 00 fd 09 00 00 00 00 00 00 00",
+ )
+ dnskey_message.answer.append(dnskey_rrset)
+ # Generate well formed PRIVATE DNS DNSKEY
+ dnskey_rrset = dns.rrset.from_text(
+ qctx.qname,
+ 300,
+ qctx.qclass,
+ dns.rdatatype.DNSKEY,
+ "\\# 12 00 00 00 fd 06 00 00 00 00 00 00 00",
+ )
+ dnskey_message.answer.append(dnskey_rrset)
+
+ yield DnsResponseSend(dnskey_message)
+
+ # Finish the AXFR transaction by sending the second SOA RRset.
+ yield DnsResponseSend(soa_message)
+
+ # This makes sure that the next SOA request causes a new zone transfer
+ self.soa_version += 1
+
+
+if __name__ == "__main__":
+ server = ControllableAsyncDnsServer(
+ default_aa=True, default_rcode=dns.rcode.NOERROR
+ )
+ server.install_control_command(ToggleResponsesCommand())
+ server.install_response_handler(AXFRServer())
+ server.run()
diff --git a/bin/tests/system/xfer/ns6/named.conf.in b/bin/tests/system/xfer/ns6/named.conf.in
index 142383c89a..63809448f0 100644
--- a/bin/tests/system/xfer/ns6/named.conf.in
+++ b/bin/tests/system/xfer/ns6/named.conf.in
@@ -83,3 +83,12 @@ zone "ixfr-too-big" {
primaries { 10.53.0.1; };
file "ixfr-too-big.bk";
};
+
+# GL#6004
+zone "private-dns-overrun" {
+ type secondary;
+ primaries { 10.53.0.9; };
+ file "private-dns-overrun.bk";
+ masterfile-format text; # force bug to be exercised
+ request-ixfr no; # ans9 supports only axfr
+};
diff --git a/bin/tests/system/xfer/tests.sh b/bin/tests/system/xfer/tests.sh
index a2c0adbc28..e08be175b7 100755
--- a/bin/tests/system/xfer/tests.sh
+++ b/bin/tests/system/xfer/tests.sh
@@ -622,5 +622,21 @@ if [ $tmp -eq 0 ]; then
fi
status=$((status + tmp))
+# def test_malformed_private_dns_identifier_overrun(ns6):
+# isctest.log.info(
+# "Check that a malformed PRIVATEDNS DNSKEY which overruns the record is rejected"
+# )
+# with ns6.watch_log_from_start(timeout=60) as watcher_transfer_completed:
+# watcher_transfer_completed.wait_for_line(
+# "zone private-dns-overrun/IN: zone transfer finished: unexpected end of input"
+# )
+n=$((n + 1))
+echo_i "Check that a malformed PRIVATEDNS DNSKEY which overruns the record is rejected ($n)"
+tmp=0
+nextpartreset ns6/named.run
+retry 60 wait_for_message "zone private-dns-overrun/IN: zone transfer finished: unexpected end of input" || tmp=1
+if test $tmp != 0; then echo_i "failed"; fi
+status=$((status + tmp))
+
echo_i "exit status: $status"
[ $status -eq 0 ] || exit 1
diff --git a/tests/dns/name_test.c b/tests/dns/name_test.c
index fb34dcace1..95f6598eb8 100644
--- a/tests/dns/name_test.c
+++ b/tests/dns/name_test.c
@@ -335,6 +335,35 @@ ISC_RUN_TEST_IMPL(fromregion) {
assert_false(dns_name_isabsolute(&name));
}
+ISC_RUN_TEST_IMPL(fromwire) {
+ dns_decompress_t dctx;
+ dns_fixedname_t fixed;
+ dns_name_t *name = dns_fixedname_initname(&fixed);
+ isc_buffer_t b;
+ unsigned char source[] = { 0x03, 'o', 'n', 'e', 0x00, 0x03,
+ 't', 'w', 'o', 0x00, 0x05, 't',
+ 'h', 'r', 'e', 'e', 0x00 };
+ isc_result_t result;
+
+ isc_buffer_init(&b, source, sizeof(source));
+ isc_buffer_add(&b, sizeof(source));
+ isc_buffer_setactive(&b, 10); /* names 'one.' and 'two.' */
+
+ /*
+ * We should only be able to read two names from the buffer
+ * as the active region has been set to cover only the first
+ * two.
+ */
+ dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
+ dns_decompress_setmethods(&dctx, DNS_COMPRESS_NONE);
+ result = dns_name_fromwire(name, &b, &dctx, 0, NULL);
+ assert_int_equal(result, ISC_R_SUCCESS);
+ result = dns_name_fromwire(name, &b, &dctx, 0, NULL);
+ assert_int_equal(result, ISC_R_SUCCESS);
+ result = dns_name_fromwire(name, &b, &dctx, 0, NULL);
+ assert_int_not_equal(result, ISC_R_SUCCESS);
+}
+
/* is trust-anchor-telemetry test */
ISC_RUN_TEST_IMPL(istat) {
dns_fixedname_t fixed;
@@ -778,6 +807,7 @@ ISC_TEST_LIST_START
ISC_TEST_ENTRY(fullcompare)
ISC_TEST_ENTRY(compression)
ISC_TEST_ENTRY(fromregion)
+ISC_TEST_ENTRY(fromwire)
ISC_TEST_ENTRY(istat)
ISC_TEST_ENTRY(init)
ISC_TEST_ENTRY(invalidate)
diff --git a/tests/dns/rdata_test.c b/tests/dns/rdata_test.c
index 6354819d10..7f0df6e046 100644
--- a/tests/dns/rdata_test.c
+++ b/tests/dns/rdata_test.c
@@ -2199,6 +2199,27 @@ ISC_RUN_TEST_IMPL(key) {
check_rdata(NULL, wire_ok, NULL, false, dns_rdataclass_in,
dns_rdatatype_key, sizeof(dns_rdata_key_t));
+
+ /*
+ * A valid PRIVATEDNS record with an active region shorter than the
+ * actual record length. A bug in dns_name_fromwire meant that this
+ * was previously accepted.
+ */
+ dns_decompress_t dctx;
+ unsigned char key[] = { 0x00, 0x00, 0x00, 253, 0x07, 'e', 'x',
+ 'a', 'm', 'p', 'l', 'e', 0x00 };
+ unsigned char buf[sizeof(key)];
+ isc_buffer_t source, target;
+ isc_result_t result;
+
+ isc_buffer_init(&source, key, sizeof(key));
+ isc_buffer_add(&source, sizeof(key));
+ isc_buffer_setactive(&source, sizeof(key) - 1);
+ isc_buffer_init(&target, buf, sizeof(buf));
+ dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
+ result = dns_rdata_fromwire(NULL, dns_rdataclass_in, dns_rdatatype_key,
+ &source, &dctx, 0, &target);
+ assert_int_not_equal(result, ISC_R_SUCCESS);
}
/*
--
2.55.0

View file

@ -1,54 +0,0 @@
From 7596cbc240b0492461943f7c34d040fb66a7554c Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 19 May 2026 15:00:17 +1000
Subject: [PATCH] Fix the yaml query zone name code in dnstap-read
When the buffer to read the query zone name was constructed
isc_buffer_setactive was not called. This is now needed as
dns_name_fromwire is being corrected to check the active region.
(cherry picked from commit a25522c28c46655a81d2bf1d96374c81d834b157)
(cherry picked from commit a5f1a9d0d2ec021618924b14202ac96ead8299c1)
Fix dns_name_fromwire to honour the active region
dns_name_fromwire was not honouring the source buffer's active
region when reading names from the wire. This allowed malformed
records to be accepted when they shouldn't have been. This has
been corrected.
(cherry picked from commit 7c4f07a7ef6b571073327b02209df7f75b9363ff)
(cherry picked from commit e73b70a64453e7d97a11cb5f0afe8bb02d34aaf8)
---
bin/tools/dnstap-read.c | 1 +
lib/dns/name.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/bin/tools/dnstap-read.c b/bin/tools/dnstap-read.c
index a1d0243a1a..bb78ae12b1 100644
--- a/bin/tools/dnstap-read.c
+++ b/bin/tools/dnstap-read.c
@@ -298,6 +298,7 @@ print_yaml(dns_dtdata_t *dt) {
isc_buffer_init(&b, m->query_zone.data, m->query_zone.len);
isc_buffer_add(&b, m->query_zone.len);
+ isc_buffer_setactive(&b, m->query_zone.len);
dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
result = dns_name_fromwire(name, &b, &dctx, 0, NULL);
diff --git a/lib/dns/name.c b/lib/dns/name.c
index cc0e30e5b5..2ce868a2ba 100644
--- a/lib/dns/name.c
+++ b/lib/dns/name.c
@@ -1833,7 +1833,7 @@ dns_name_fromwire(dns_name_t *const name, isc_buffer_t *const source,
* The amount of the source we consumed is set once.
*/
const uint8_t *const source_buf = isc_buffer_base(source);
- const uint8_t *const source_max = isc_buffer_used(source);
+ const uint8_t *const source_max = isc_buffer_active(source);
const uint8_t *const start = isc_buffer_current(source);
const uint8_t *marker = start;
const uint8_t *cursor = start;
--
2.55.0

View file

@ -1,69 +0,0 @@
From cde8bb21e09205a7bd1f41fd07ed011fc80d8d71 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Fri, 10 Apr 2026 10:24:06 +1000
Subject: [PATCH] Fix TTL extraction from A/AAAA record
(cherry picked from commit 89c86e338db2492b92e6618c586f146c6928dc6d)
(cherry picked from commit adc8285d23e2eac6ec463f5dbc5a9596fdd36c60)
Check rpz name too long wildcard CNAME expansion handling
(cherry picked from commit 9345394e2097031b55b3ef34ceaadf5a7ebbeef2)
(cherry picked from commit 095b11f20f911f5b8059bdc349b256d6c64ece30)
---
bin/tests/system/rpz/ns2/tld2.db | 2 ++
bin/tests/system/rpz/ns4/tld4.db | 2 ++
bin/tests/system/rpz/tests.sh | 7 +++++--
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/bin/tests/system/rpz/ns2/tld2.db b/bin/tests/system/rpz/ns2/tld2.db
index c6f2556db5..c091ee27b7 100644
--- a/bin/tests/system/rpz/ns2/tld2.db
+++ b/bin/tests/system/rpz/ns2/tld2.db
@@ -123,3 +123,5 @@ a7-1 A 192.168.7.1
a7-2 A 192.168.7.2
TXT "a7-2 tld2 text"
+
+*.wild A 192.168.9.1
diff --git a/bin/tests/system/rpz/ns4/tld4.db b/bin/tests/system/rpz/ns4/tld4.db
index fca419c6dd..8accd76baf 100644
--- a/bin/tests/system/rpz/ns4/tld4.db
+++ b/bin/tests/system/rpz/ns4/tld4.db
@@ -59,6 +59,8 @@ a3-6.tld2 A 56.56.56.56
a3-7.sub1.tld2 A 57.57.57.57
+*.wild.sub1.tld2 A 57.57.57.57
+
a3-8.tld2 A 58.58.58.58
a3-9.sub9.tld2 A 59.59.59.59
diff --git a/bin/tests/system/rpz/tests.sh b/bin/tests/system/rpz/tests.sh
index 87e4118ca3..5297437694 100644
--- a/bin/tests/system/rpz/tests.sh
+++ b/bin/tests/system/rpz/tests.sh
@@ -391,7 +391,7 @@ addr() {
digcmd $2 >$DIGNM
#ckalive "$2" "server crashed by 'dig $2'" || return 1
ADDR_ESC=$(echo "$ADDR" | sed -e 's/\./\\./g')
- ADDR_TTL=$(sed -n -e "s/^[-.a-z0-9]\{1,\}[ ]*\([0-9]*\) IN AA* ${ADDR_ESC}\$/\1/p" $DIGNM)
+ ADDR_TTL=$(sed -n -e "s/^[-.a-z0-9]\{1,\}[ ]*\([0-9]*\)[ ]IN[ ]AA*[ ]${ADDR_ESC}\$/\1/p" $DIGNM)
if test -z "$ADDR_TTL"; then
setret "'dig $2' wrong; no address $ADDR record in $DIGNM"
return 0
@@ -516,7 +516,10 @@ nochange TCP a3-9.tld2 # 33 tcp-only
here x.servfail <<'EOF' # 34 qname-wait-recurse yes
;; status: SERVFAIL, x
EOF
-addr 35.35.35.35 "x.servfail @$ns5" # 35 qname-wait-recurse no
+addr 35.35.35.35 "x.servfail @$ns5" # 35 qname-wait-recurse no
+here aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.wild.sub1.tld2 <<'EOF' # 36 wildcard CNAME name to long
+ ;; status: YXDOMAIN, x
+EOF
end_group
ckstats $ns3 test1 ns3 22
ckstats $ns5 test1 ns5 1
--
2.55.0

View file

@ -1,31 +0,0 @@
From 49f4cc4e93f14f1d5b6a472124e6aa457167fede Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Fri, 10 Apr 2026 10:26:14 +1000
Subject: [PATCH] Properly handle rpz name to long wildcard expansion
Previously a self referential CNAME and the original address
record were returned. We now return a YXDOMAIN response.
(cherry picked from commit cfc4c4f69870ce492deaaa429453563d1621ded3)
(cherry picked from commit dc328a199f96222e0c30cc20b7b795bfc2c9b2e4)
---
lib/ns/query.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lib/ns/query.c b/lib/ns/query.c
index d3a10be9ba..3bd7daf79c 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -7591,7 +7591,8 @@ query_rpzcname(query_ctx_t *qctx, dns_name_t *cname) {
qctx->fname, NULL);
if (result == DNS_R_NAMETOOLONG) {
client->message->rcode = dns_rcode_yxdomain;
- } else if (result != ISC_R_SUCCESS) {
+ }
+ if (result != ISC_R_SUCCESS) {
return result;
}
} else {
--
2.55.0

View file

@ -1,280 +0,0 @@
From d7e1f4495d6bac8c29b332e04e9b27140339375b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= <ondrej@sury.org>
Date: Tue, 23 Jun 2026 10:59:38 +0200
Subject: [PATCH] Make the dns_slabheaders in the cache reference counted
Instead of only reference counting the enclosing qpcnode, add the
reference counting directly to the slabheaders. The reference is
incremented when an rdataset is bound to the header and decremented when
the rdataset is disassociated, so a stale slabheader can be removed from
the node's down chain as soon as its own reference count reaches zero,
instead of waiting for the whole qpcnode to become unreferenced.
Building on that, clean up the ancient headers eagerly: mark_ancient()
is made idempotent, releases the header's own (container) reference and
reaps the stale headers from the node's down chain as soon as their
references reach zero. A header evicted over the per-name type limit is
expired only after the new rdataset has been bound, so the bind's
increment always precedes mark_ancient()'s decrement.
Because a header can now be reclaimed independently of its node, the
rdataset iterators must keep the header they are positioned on alive:
each iterator takes a reference on its current header and releases it
when it advances or is destroyed. Iteration otherwise stays lazy and
re-reads the node on every step, so it still observes records added to
the node while the iterator is live, as zone signing requires.
The slab headers are shared with the zone databases, so the matching
increment is added to every bind path. The noqname/closest proofs hand
out rdatasets backed by bare slabs that have no header, so they are
given a separate dns_rdataproof_rdatasetmethods that leaves the
reference count untouched.
(cherry picked from commit 2dabf117e1264fd13fb33096f87e78a039fd1c6c)
(cherry picked from commit 231b1ca3edfb26389e1af39181aa6b4413e87ec4)
---
bin/tests/system/reclimit/tests.sh | 4 +-
lib/dns/include/dns/rdataslab.h | 1 +
lib/dns/rbtdb.c | 77 +++++++++++++++++++++++++-----
3 files changed, 69 insertions(+), 13 deletions(-)
diff --git a/bin/tests/system/reclimit/tests.sh b/bin/tests/system/reclimit/tests.sh
index c15225488f..55ccac7759 100644
--- a/bin/tests/system/reclimit/tests.sh
+++ b/bin/tests/system/reclimit/tests.sh
@@ -338,13 +338,13 @@ echo_i "checking that NXDOMAIN names over the max-types-per-name limit don't get
# Query for 10 NXDOMAIN types
for ntype in $(seq 65270 65279); do
- check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR big SOA 0 || ret=1
+ check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR big SOA 120 || ret=1
done
# Wait at least 1 second
sleep 1
# Query for 10 NXDOMAIN types again - these should not be cached
for ntype in $(seq 65270 65279); do
- check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR big SOA 0 || ret=1
+ check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR big SOA 120 || ret=1
done
if [ $ret -ne 0 ]; then echo_i "failed"; fi
diff --git a/lib/dns/include/dns/rdataslab.h b/lib/dns/include/dns/rdataslab.h
index 5729c004ca..6bd3b5997d 100644
--- a/lib/dns/include/dns/rdataslab.h
+++ b/lib/dns/include/dns/rdataslab.h
@@ -44,6 +44,7 @@
#include <stdbool.h>
#include <isc/lang.h>
+#include <isc/refcount.h>
#include <dns/types.h>
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 62bc97d783..0b8547950f 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -158,6 +158,7 @@ struct noqname {
};
typedef struct rdatasetheader {
+ isc_refcount_t references;
/*%
* Locked by the owning node's lock.
*/
@@ -1447,6 +1448,7 @@ init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h) {
h->heap_index = 0;
atomic_init(&h->attributes, 0);
atomic_init(&h->last_refresh_fail_ts, 0);
+ isc_refcount_init(&h->references, 1);
STATIC_ASSERT(sizeof(h->attributes) == 2,
"The .attributes field of rdatasetheader_t needs to be "
@@ -1559,6 +1561,9 @@ rollback_node(dns_rbtnode_t *node, rbtdb_serial_t serial) {
}
}
+static void
+clean_stale_headers(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *top);
+
static void
mark_header_ancient(dns_rbtdb_t *rbtdb, rdatasetheader_t *header) {
uint_least16_t attributes = atomic_load_acquire(&header->attributes);
@@ -1584,8 +1589,12 @@ mark_header_ancient(dns_rbtdb_t *rbtdb, rdatasetheader_t *header) {
update_rrsetstats(rbtdb, header->type, attributes, false);
header->node->dirty = 1;
+ isc_refcount_decrement(&header->references);
+
/* Increment the stats counter for the ancient RRtype. */
update_rrsetstats(rbtdb, header->type, newattributes, true);
+
+ clean_stale_headers(rbtdb, rbtdb->common.mctx, header);
}
static void
@@ -1621,12 +1630,19 @@ static void
clean_stale_headers(dns_rbtdb_t *rbtdb, isc_mem_t *mctx,
rdatasetheader_t *top) {
rdatasetheader_t *d, *down_next;
+ rdatasetheader_t *down_parent = top;
for (d = top->down; d != NULL; d = down_next) {
down_next = d->down;
- free_rdataset(rbtdb, mctx, d);
+ d->next = down_parent;
+
+ if (isc_refcount_current(&d->references) == 0) {
+ free_rdataset(rbtdb, mctx, d);
+ down_parent->down = down_next;
+ } else {
+ down_parent = d;
+ }
}
- top->down = NULL;
}
static void
@@ -1642,6 +1658,7 @@ clean_cache_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
for (current = node->data; current != NULL; current = top_next) {
top_next = current->next;
clean_stale_headers(rbtdb, mctx, current);
+ INSIST(current->down == NULL);
/*
* If current is nonexistent, ancient, or stale and
* we are not keeping stale, we can clean it up.
@@ -3114,6 +3131,8 @@ bind_rdataset(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, rdatasetheader_t *header,
return;
}
+ isc_refcount_increment(&header->references);
+
dns__rbtnode_acquire(rbtdb, node, locktype);
INSIST(rdataset->methods == NULL); /* We must be disassociated. */
@@ -6307,6 +6326,7 @@ add32(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, const dns_name_t *nodename,
bool header_nx;
bool newheader_nx;
bool merge;
+ bool do_expireheader = false;
dns_rdatatype_t rdtype, covers;
rbtdb_rdatatype_t negtype, sigtype;
dns_trust_t trust;
@@ -6856,6 +6876,7 @@ find_header:
}
if (IS_CACHE(rbtdb) && overmaxtype(rbtdb, ntypes)) {
+ do_expireheader = true;
if (expireheader == NULL) {
expireheader = newheader;
}
@@ -6869,15 +6890,6 @@ find_header:
*/
expireheader = newheader;
}
-
- set_ttl(rbtdb, expireheader, 0);
- mark_header_ancient(rbtdb, expireheader);
- /*
- * FIXME: In theory, we should mark the RRSIG
- * and the header at the same time, but there is
- * no direct link between those two header, so
- * we would have to check the whole list again.
- */
}
}
}
@@ -6901,6 +6913,15 @@ find_header:
isc_rwlocktype_write, addedrdataset);
}
+ /*
+ * We need to delay the expiration of the header until we are bound to
+ * it to prevent decrement-then-increment on the header references.
+ */
+ if (do_expireheader) {
+ set_ttl(rbtdb, expireheader, 0);
+ mark_header_ancient(rbtdb, expireheader);
+ }
+
return ISC_R_SUCCESS;
}
@@ -8692,6 +8713,12 @@ rdataset_disassociate(dns_rdataset_t *rdataset) {
dns_db_t *db = rdataset->private1;
dns_dbnode_t *node = rdataset->private2;
+ if (rdataset->methods == &rdataset_methods) {
+ rdatasetheader_t *header = rdataset->private3;
+ header--;
+ isc_refcount_decrement(&header->references);
+ }
+
detachnode(db, &node);
}
@@ -8806,6 +8833,11 @@ rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
dns_dbnode_t *cloned_node = NULL;
attachnode(db, node, &cloned_node);
+ if (source->methods == &rdataset_methods) {
+ rdatasetheader_t *header = source->private3;
+ header--;
+ isc_refcount_increment(&header->references);
+ }
INSIST(!ISC_LINK_LINKED(target, link));
*target = *source;
ISC_LINK_INIT(target, link);
@@ -8969,6 +9001,11 @@ rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
rbtiterator = (rbtdb_rdatasetiter_t *)(*iteratorp);
+ if (rbtiterator->current != NULL) {
+ isc_refcount_decrement(&rbtiterator->current->references);
+ rbtiterator->current = NULL;
+ }
+
if (rbtiterator->common.version != NULL) {
closeversion(rbtiterator->common.db,
&rbtiterator->common.version, false);
@@ -9046,9 +9083,18 @@ rdatasetiter_first(dns_rdatasetiter_t *iterator) {
}
}
+ if (header != NULL) {
+ isc_refcount_increment0(&header->references);
+ }
+
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_read);
+ if (rbtiterator->current != NULL) {
+ isc_refcount_decrement(&rbtiterator->current->references);
+ rbtiterator->current = NULL;
+ }
+
rbtiterator->current = header;
if (header == NULL) {
@@ -9140,9 +9186,18 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) {
}
}
+ if (header != NULL) {
+ isc_refcount_increment0(&header->references);
+ }
+
NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
isc_rwlocktype_read);
+ if (rbtiterator->current != NULL) {
+ isc_refcount_decrement(&rbtiterator->current->references);
+ rbtiterator->current = NULL;
+ }
+
rbtiterator->current = header;
if (header == NULL) {
--
2.55.0

View file

@ -1,144 +0,0 @@
From b08e0876639ab9f3dae3813202861fd1098f2611 Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 14 Apr 2026 13:46:22 +1000
Subject: [PATCH] Test RRSIG record parsing
In particular test that labels and signer fields are consistent.
(cherry picked from commit 5a95e64731afe63d348d272cc4d3b2f9847150c2)
(cherry picked from commit 19e496ca260b6a756ae1378e8ebcbdb666b7d9ed)
---
tests/dns/rdata_test.c | 110 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 110 insertions(+)
diff --git a/tests/dns/rdata_test.c b/tests/dns/rdata_test.c
index 7f0df6e046..c704d98ed1 100644
--- a/tests/dns/rdata_test.c
+++ b/tests/dns/rdata_test.c
@@ -2504,6 +2504,115 @@ ISC_RUN_TEST_IMPL(rkey) {
dns_rdatatype_rkey, sizeof(dns_rdata_rkey_t));
}
+ISC_RUN_TEST_IMPL(rrsig) {
+ text_ok_t text_ok[] = {
+ TEXT_VALID("SOA 8 0 86400 20260426170000 20260413160000 54393 "
+ ". "
+ "tFbcoVP8MnpecUquJ/aj+XeNgV7ts9GSHVkXaXRJrJ/"
+ "TEkOZApVG0F6E "
+ "9sYpxGk2ItweLL43ujioGj0HWwZDRR+vbur+O/"
+ "dIdheiig1VvU+9HXLi "
+ "QOViY9Kc64ixdyJhYCC5K+bO1qsHxd+"
+ "KJXOaxyHbqchYkDFy4PL6qftE "
+ "VaLkueRgjXgOsq/"
+ "NxvCXDgAa5xy0+3Sl0myxIs8rJ5KeXfJQFe7qxgaw "
+ "VjJsJTKw8neOTw2rQfLaigWu2LIWw+"
+ "IyVrLjZJdLqGkiLBGd1w4X3U12 "
+ "fFxoY3eqzNgBEtduoGKPZ/"
+ "NpP9cuKJORJ18283aV8hR4WO91VR0q1zcM jLwqUg=="),
+ /* labels too short for signer */
+ TEXT_INVALID("SOA 8 0 86400 20260426170000 20260413160000 "
+ "54393 example. "
+ "tFbcoVP8MnpecUquJ/aj+XeNgV7ts9GSHVkXaXRJrJ/"
+ "TEkOZApVG0F6E "
+ "9sYpxGk2ItweLL43ujioGj0HWwZDRR+vbur+O/"
+ "dIdheiig1VvU+9HXLi "
+ "QOViY9Kc64ixdyJhYCC5K+bO1qsHxd+"
+ "KJXOaxyHbqchYkDFy4PL6qftE "
+ "VaLkueRgjXgOsq/"
+ "NxvCXDgAa5xy0+3Sl0myxIs8rJ5KeXfJQFe7qxgaw "
+ "VjJsJTKw8neOTw2rQfLaigWu2LIWw+"
+ "IyVrLjZJdLqGkiLBGd1w4X3U12 "
+ "fFxoY3eqzNgBEtduoGKPZ/"
+ "NpP9cuKJORJ18283aV8hR4WO91VR0q1zcM jLwqUg=="),
+ /*
+ * Sentinel.
+ */
+ TEXT_SENTINEL()
+ };
+ wire_ok_t wire_ok[] = {
+ WIRE_VALID(0x00, 0x06, 0x08, 0x00, 0x00, 0x01, 0x51, 0x80, 0x69,
+ 0xee, 0x44, 0x90, 0x69, 0xdd, 0x13, 0x00, 0xd4, 0x79,
+ 0x00, 0xb4, 0x56, 0xdc, 0xa1, 0x53, 0xfc, 0x32, 0x7a,
+ 0x5e, 0x71, 0x4a, 0xae, 0x27, 0xf6, 0xa3, 0xf9, 0x77,
+ 0x8d, 0x81, 0x5e, 0xed, 0xb3, 0xd1, 0x92, 0x1d, 0x59,
+ 0x17, 0x69, 0x74, 0x49, 0xac, 0x9f, 0xd3, 0x12, 0x43,
+ 0x99, 0x02, 0x95, 0x46, 0xd0, 0x5e, 0x84, 0xf6, 0xc6,
+ 0x29, 0xc4, 0x69, 0x36, 0x22, 0xdc, 0x1e, 0x2c, 0xbe,
+ 0x37, 0xba, 0x38, 0xa8, 0x1a, 0x3d, 0x07, 0x5b, 0x06,
+ 0x43, 0x45, 0x1f, 0xaf, 0x6e, 0xea, 0xfe, 0x3b, 0xf7,
+ 0x48, 0x76, 0x17, 0xa2, 0x8a, 0x0d, 0x55, 0xbd, 0x4f,
+ 0xbd, 0x1d, 0x72, 0xe2, 0x40, 0xe5, 0x62, 0x63, 0xd2,
+ 0x9c, 0xeb, 0x88, 0xb1, 0x77, 0x22, 0x61, 0x60, 0x20,
+ 0xb9, 0x2b, 0xe6, 0xce, 0xd6, 0xab, 0x07, 0xc5, 0xdf,
+ 0x8a, 0x25, 0x73, 0x9a, 0xc7, 0x21, 0xdb, 0xa9, 0xc8,
+ 0x58, 0x90, 0x31, 0x72, 0xe0, 0xf2, 0xfa, 0xa9, 0xfb,
+ 0x44, 0x55, 0xa2, 0xe4, 0xb9, 0xe4, 0x60, 0x8d, 0x78,
+ 0x0e, 0xb2, 0xaf, 0xcd, 0xc6, 0xf0, 0x97, 0x0e, 0x00,
+ 0x1a, 0xe7, 0x1c, 0xb4, 0xfb, 0x74, 0xa5, 0xd2, 0x6c,
+ 0xb1, 0x22, 0xcf, 0x2b, 0x27, 0x92, 0x9e, 0x5d, 0xf2,
+ 0x50, 0x15, 0xee, 0xea, 0xc6, 0x06, 0xb0, 0x56, 0x32,
+ 0x6c, 0x25, 0x32, 0xb0, 0xf2, 0x77, 0x8e, 0x4f, 0x0d,
+ 0xab, 0x41, 0xf2, 0xda, 0x8a, 0x05, 0xae, 0xd8, 0xb2,
+ 0x16, 0xc3, 0xe2, 0x32, 0x56, 0xb2, 0xe3, 0x64, 0x97,
+ 0x4b, 0xa8, 0x69, 0x22, 0x2c, 0x11, 0x9d, 0xd7, 0x0e,
+ 0x17, 0xdd, 0x4d, 0x76, 0x7c, 0x5c, 0x68, 0x63, 0x77,
+ 0xaa, 0xcc, 0xd8, 0x01, 0x12, 0xd7, 0x6e, 0xa0, 0x62,
+ 0x8f, 0x67, 0xf3, 0x69, 0x3f, 0xd7, 0x2e, 0x28, 0x93,
+ 0x91, 0x27, 0x5f, 0x36, 0xf3, 0x76, 0x95, 0xf2, 0x14,
+ 0x78, 0x58, 0xef, 0x75, 0x55, 0x1d, 0x2a, 0xd7, 0x37,
+ 0x0c, 0x8c, 0xbc, 0x2a, 0x52),
+ /* labels too short for signer */
+ WIRE_INVALID(
+ 0x00, 0x06, 0x08, 0x00, 0x00, 0x01, 0x51, 0x80, 0x69,
+ 0xee, 0x44, 0x90, 0x69, 0xdd, 0x13, 0x00, 0xd4, 0x79,
+ 0x07, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x00,
+ 0xb4, 0x56, 0xdc, 0xa1, 0x53, 0xfc, 0x32, 0x7a, 0x5e,
+ 0x71, 0x4a, 0xae, 0x27, 0xf6, 0xa3, 0xf9, 0x77, 0x8d,
+ 0x81, 0x5e, 0xed, 0xb3, 0xd1, 0x92, 0x1d, 0x59, 0x17,
+ 0x69, 0x74, 0x49, 0xac, 0x9f, 0xd3, 0x12, 0x43, 0x99,
+ 0x02, 0x95, 0x46, 0xd0, 0x5e, 0x84, 0xf6, 0xc6, 0x29,
+ 0xc4, 0x69, 0x36, 0x22, 0xdc, 0x1e, 0x2c, 0xbe, 0x37,
+ 0xba, 0x38, 0xa8, 0x1a, 0x3d, 0x07, 0x5b, 0x06, 0x43,
+ 0x45, 0x1f, 0xaf, 0x6e, 0xea, 0xfe, 0x3b, 0xf7, 0x48,
+ 0x76, 0x17, 0xa2, 0x8a, 0x0d, 0x55, 0xbd, 0x4f, 0xbd,
+ 0x1d, 0x72, 0xe2, 0x40, 0xe5, 0x62, 0x63, 0xd2, 0x9c,
+ 0xeb, 0x88, 0xb1, 0x77, 0x22, 0x61, 0x60, 0x20, 0xb9,
+ 0x2b, 0xe6, 0xce, 0xd6, 0xab, 0x07, 0xc5, 0xdf, 0x8a,
+ 0x25, 0x73, 0x9a, 0xc7, 0x21, 0xdb, 0xa9, 0xc8, 0x58,
+ 0x90, 0x31, 0x72, 0xe0, 0xf2, 0xfa, 0xa9, 0xfb, 0x44,
+ 0x55, 0xa2, 0xe4, 0xb9, 0xe4, 0x60, 0x8d, 0x78, 0x0e,
+ 0xb2, 0xaf, 0xcd, 0xc6, 0xf0, 0x97, 0x0e, 0x00, 0x1a,
+ 0xe7, 0x1c, 0xb4, 0xfb, 0x74, 0xa5, 0xd2, 0x6c, 0xb1,
+ 0x22, 0xcf, 0x2b, 0x27, 0x92, 0x9e, 0x5d, 0xf2, 0x50,
+ 0x15, 0xee, 0xea, 0xc6, 0x06, 0xb0, 0x56, 0x32, 0x6c,
+ 0x25, 0x32, 0xb0, 0xf2, 0x77, 0x8e, 0x4f, 0x0d, 0xab,
+ 0x41, 0xf2, 0xda, 0x8a, 0x05, 0xae, 0xd8, 0xb2, 0x16,
+ 0xc3, 0xe2, 0x32, 0x56, 0xb2, 0xe3, 0x64, 0x97, 0x4b,
+ 0xa8, 0x69, 0x22, 0x2c, 0x11, 0x9d, 0xd7, 0x0e, 0x17,
+ 0xdd, 0x4d, 0x76, 0x7c, 0x5c, 0x68, 0x63, 0x77, 0xaa,
+ 0xcc, 0xd8, 0x01, 0x12, 0xd7, 0x6e, 0xa0, 0x62, 0x8f,
+ 0x67, 0xf3, 0x69, 0x3f, 0xd7, 0x2e, 0x28, 0x93, 0x91,
+ 0x27, 0x5f, 0x36, 0xf3, 0x76, 0x95, 0xf2, 0x14, 0x78,
+ 0x58, 0xef, 0x75, 0x55, 0x1d, 0x2a, 0xd7, 0x37, 0x0c,
+ 0x8c, 0xbc, 0x2a, 0x52),
+
+ WIRE_SENTINEL()
+ };
+ check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
+ dns_rdatatype_rrsig, sizeof(dns_rdata_rrsig_t));
+}
+
ISC_RUN_TEST_IMPL(resinfo) {
text_ok_t text_ok[] = {
TEXT_VALID_CHANGED("qnamemin exterr=15,16,17 "
@@ -3357,6 +3466,7 @@ ISC_TEST_ENTRY(nsec3)
ISC_TEST_ENTRY(nxt)
ISC_TEST_ENTRY(resinfo)
ISC_TEST_ENTRY(rkey)
+ISC_TEST_ENTRY(rrsig)
ISC_TEST_ENTRY(sshfp)
ISC_TEST_ENTRY(wallet)
ISC_TEST_ENTRY(wks)
--
2.55.0

View file

@ -1,267 +0,0 @@
From 7a8a1f74c742e98fb5e105b013e7c2bd7af4a76c Mon Sep 17 00:00:00 2001
From: Mark Andrews <marka@isc.org>
Date: Tue, 14 Apr 2026 15:14:06 +1000
Subject: [PATCH] Don't sign out of zone records in dnssec-signzone
dnssec-signzone was signing extraneous records that were not within
the namespace of the zone. This no longer occurs.
(cherry picked from commit e45c9af7051421fd370f20ba8325199c606223fd)
Don't sign out of zone records in dnssec-signzone
dnssec-signzone was signing extraneous records that were not within
the namespace of the zone. This no longer occurs.
(cherry picked from commit e45c9af7051421fd370f20ba8325199c606223fd)
(cherry picked from commit 1a4986e2533f87e80eb21da3f06708d335aff1e2)
Invalid signed wildcard records were being accepted
An RRSIG whose Labels field indicates fewer labels than its signer
name requires was being accepted. When such a record covers a
wildcard, the validator reconstructs a wildcard owner name above the
signer's zone and caches it as secure. RFC 8198 cache synthesis
(synth-from-dnssec) then serves that forged wildcard for unrelated
names, poisoning the cache.
These records are now rejected, both when an RRSIG is parsed and when
its signature is verified.
(cherry picked from commit 084ca5ee10515e461d46b63df9660b8394bc7de9)
(cherry picked from commit 15089066b15f826d7487c3d160b5872820f84b83)
---
bin/dnssec/dnssec-signzone.c | 5 ++++
lib/dns/dnssec.c | 43 +++++++++++++++++++++++---------
lib/dns/rdata/generic/rrsig_46.c | 37 ++++++++++++++++++++-------
3 files changed, 64 insertions(+), 21 deletions(-)
diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c
index 73855e6284..9e3a48a592 100644
--- a/bin/dnssec/dnssec-signzone.c
+++ b/bin/dnssec/dnssec-signzone.c
@@ -1643,6 +1643,11 @@ assignwork(isc_task_t *task, isc_task_t *worker) {
dns_db_detachnode(gdb, &node);
goto next;
}
+ if (!dns_name_issubdomain(name, gorigin)) {
+ dumpnode(name, node);
+ dns_db_detachnode(gdb, &node);
+ goto next;
+ }
/*
* Sort the zone data from the glue and out-of-zone data.
* For NSEC zones nodes with zone data have NSEC records.
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index c7e922437c..b12529b5d5 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -130,11 +130,11 @@ dns_dnssec_keyfromrdata(const dns_name_t *name, const dns_rdata_t *rdata,
isc_buffer_t b;
isc_region_t r;
- INSIST(name != NULL);
- INSIST(rdata != NULL);
- INSIST(mctx != NULL);
- INSIST(key != NULL);
- INSIST(*key == NULL);
+ REQUIRE(name != NULL);
+ REQUIRE(rdata != NULL);
+ REQUIRE(mctx != NULL);
+ REQUIRE(key != NULL);
+ REQUIRE(*key == NULL);
REQUIRE(rdata->type == dns_rdatatype_key ||
rdata->type == dns_rdatatype_dnskey);
@@ -187,12 +187,14 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_result_t ret;
isc_buffer_t *databuf = NULL;
char data[256 + 8];
+ unsigned int labels;
unsigned int sigsize;
dns_fixedname_t fnewname;
dns_fixedname_t fsigner;
REQUIRE(name != NULL);
- REQUIRE(dns_name_countlabels(name) <= 255);
+ labels = dns_name_countlabels(name);
+ REQUIRE(labels <= 255 && labels > 0);
REQUIRE(set != NULL);
REQUIRE(key != NULL);
REQUIRE(inception != NULL);
@@ -221,7 +223,7 @@ dns_dnssec_sign(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
sig.covered = set->type;
sig.algorithm = dst_key_alg(key);
- sig.labels = dns_name_countlabels(name) - 1;
+ sig.labels = labels - 1;
if (dns_name_iswildcard(name)) {
sig.labels--;
}
@@ -365,10 +367,13 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_result_t ret;
unsigned char data[300];
dst_context_t *ctx = NULL;
- int labels = 0;
+ unsigned int labels;
+ unsigned int siglabels;
bool downcase = false;
REQUIRE(name != NULL);
+ labels = dns_name_countlabels(name);
+ REQUIRE(labels > 0);
REQUIRE(set != NULL);
REQUIRE(key != NULL);
REQUIRE(mctx != NULL);
@@ -383,6 +388,21 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
return DNS_R_SIGINVALID;
}
+ /*
+ * The RRSIG labels field can't indicate fewer labels than the
+ * signer. Also the labels shouldn't be greater than that of
+ * the owner name.
+ *
+ * sig.labels doesn't include the root label, so add 1 to account
+ * for it.
+ */
+ siglabels = sig.labels + 1;
+ if (siglabels < dns_name_countlabels(&sig.signer) || siglabels > labels)
+ {
+ inc_stat(dns_dnssecstats_fail);
+ return DNS_R_SIGINVALID;
+ }
+
if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
inc_stat(dns_dnssecstats_fail);
return DNS_R_SIGINVALID;
@@ -449,10 +469,9 @@ again:
* If the name is an expanded wildcard, use the wildcard name.
*/
dns_fixedname_init(&fnewname);
- labels = dns_name_countlabels(name) - 1;
RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname),
NULL) == ISC_R_SUCCESS);
- if (labels - sig.labels > 0) {
+ if (labels > siglabels) {
dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1,
NULL, dns_fixedname_name(&fnewname));
}
@@ -463,7 +482,7 @@ again:
* Create an envelope for each rdata: <name|type|class|ttl>.
*/
isc_buffer_init(&envbuf, data, sizeof(data));
- if (labels - sig.labels > 0) {
+ if (labels > siglabels) {
isc_buffer_putuint8(&envbuf, 1);
isc_buffer_putuint8(&envbuf, '*');
memmove(data + 2, r.base, r.length);
@@ -559,7 +578,7 @@ cleanup_struct:
inc_stat(dns_dnssecstats_fail);
}
- if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
+ if (ret == ISC_R_SUCCESS && labels > siglabels) {
if (wild != NULL) {
RUNTIME_CHECK(dns_name_concatenate(
dns_wildcardname,
diff --git a/lib/dns/rdata/generic/rrsig_46.c b/lib/dns/rdata/generic/rrsig_46.c
index 10bc039e93..4cf4259c2b 100644
--- a/lib/dns/rdata/generic/rrsig_46.c
+++ b/lib/dns/rdata/generic/rrsig_46.c
@@ -23,12 +23,12 @@
static isc_result_t
fromtext_rrsig(ARGS_FROMTEXT) {
isc_token_t token;
- unsigned char c;
+ unsigned char alg, labels;
long i;
dns_rdatatype_t covered;
- char *e;
+ char *e = NULL;
isc_result_t result;
- dns_name_t name;
+ dns_name_t signer;
isc_buffer_t buffer;
uint32_t time_signed, time_expire;
@@ -61,8 +61,8 @@ fromtext_rrsig(ARGS_FROMTEXT) {
*/
RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
false));
- RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
- RETERR(mem_tobuffer(target, &c, 1));
+ RETTOK(dns_secalg_fromtext(&alg, &token.value.as_textregion));
+ RETERR(mem_tobuffer(target, &alg, 1));
/*
* Labels.
@@ -72,8 +72,8 @@ fromtext_rrsig(ARGS_FROMTEXT) {
if (token.value.as_ulong > 0xffU) {
RETTOK(ISC_R_RANGE);
}
- c = (unsigned char)token.value.as_ulong;
- RETERR(mem_tobuffer(target, &c, 1));
+ labels = (unsigned char)token.value.as_ulong;
+ RETERR(mem_tobuffer(target, &labels, 1));
/*
* Original ttl.
@@ -144,12 +144,20 @@ fromtext_rrsig(ARGS_FROMTEXT) {
*/
RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
false));
- dns_name_init(&name, NULL);
+ dns_name_init(&signer, NULL);
buffer_fromregion(&buffer, &token.value.as_region);
if (origin == NULL) {
origin = dns_rootname;
}
- RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
+ RETTOK(dns_name_fromtext(&signer, &buffer, origin, options, target));
+
+ /*
+ * (RRSIG labels doesn't include the root label, so add one
+ * to normalize it before checking against the signer.)
+ */
+ if ((unsigned int)(labels + 1) < dns_name_countlabels(&signer)) {
+ RETTOK(ISC_R_RANGE);
+ }
/*
* Sig.
@@ -278,6 +286,7 @@ static isc_result_t
fromwire_rrsig(ARGS_FROMWIRE) {
isc_region_t sr;
dns_name_t name;
+ unsigned char labels;
REQUIRE(type == dns_rdatatype_rrsig);
@@ -300,6 +309,8 @@ fromwire_rrsig(ARGS_FROMWIRE) {
return ISC_R_UNEXPECTEDEND;
}
+ labels = sr.base[3];
+
isc_buffer_forward(source, 18);
RETERR(mem_tobuffer(target, sr.base, 18));
@@ -309,6 +320,14 @@ fromwire_rrsig(ARGS_FROMWIRE) {
dns_name_init(&name, NULL);
RETERR(dns_name_fromwire(&name, source, dctx, options, target));
+ /*
+ * (RRSIG labels doesn't include the root label, so add one
+ * to normalize it before checking against the signer.)
+ */
+ if ((unsigned int)(labels + 1) < dns_name_countlabels(&name)) {
+ RETERR(DNS_R_FORMERR);
+ }
+
/*
* Sig.
*/
--
2.55.0

View file

@ -1,435 +0,0 @@
From a31296b120efc985fb1fc3c932882e965156473b Mon Sep 17 00:00:00 2001
From: Colin Vidal <colin@isc.org>
Date: Mon, 15 Jun 2026 11:34:08 +0200
Subject: [PATCH] Reproducer for #5946 (assertion in some CNAME/DNAME queries)
Add a system test reproducing the issue reported by #5946, which
is also CVE-2026-12617. There are two scenarios:
- A client send queries for a DNAME and A record to the resolver (ns3),
and the authoritative server (ans2) responds positively to the A query
but delay the DNAME response and respond later negatively;
- A client send queries for a CNAME and A record to the resolver (ns3),
and the authoritative server (ans2) responds positively to the A query
but delay the CNAME response and respond later with a self-referential
CNAME.
The test does not check the results of the queries, however, it expects
the resolver to correctly handle those and do not assert.
(cherry picked from commit e88271f2e584010157b068cc998dd76451273562)
(cherry picked from commit bb92832fb6ae899bee7206c2d8966258461c2f71)
Stabilize timing in the cname_dname_negcache test
The #5946 reproducer relied on ans2 answering the negative DNAME/CNAME
query a fixed second after receiving it, racing that delay against the
resolver's per-query timeout. When the timeout fired first -- which
happens under load, most notably under ThreadSanitizer, where named is
slowed but ans2 (wall-clock) is not -- the resolver dropped the late
answer, never processed the negative response, and the watched SOA never
appeared, so the test timed out. This made it flaky on the
security-bind-9.20 CI. Merely shortening the fixed delay would trade
that for the opposite, worse failure: the negative answer arriving
before the positive one is cached, silently not exercising the bug.
Release the negative answer based on the resolver's progress instead of
a wall-clock deadline: hold it until ans2 has sent the positive answer
(a shared event), then wait a short settle for the resolver to cache it.
Both queries traverse the same delegation, so any latency reaching ans2
shifts the positive send and the negative fetch's deadline together and
cancels out; only the settle, kept well under MINIMUM_QUERY_TIMEOUT
(301 ms), has to fit inside the per-query timeout.
Verified that the stabilized test still triggers the
INSIST(namereln == dns_namereln_subdomain) assertion when the resolver
fix is reverted.
Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 738456d91564526e6f15c3858b4c809cd6749e1e)
(cherry picked from commit 0c20ee4e8e68999ca617434cde65dd3808f57d8c)
Split cname_dname_negcache into per-scenario modules
The DNAME and CNAME scenarios shared a single module, hence a single
module-scoped ns3 (the framework sets servers up per module, not per
test function). test_dname_negcache cached foo.test. DNAME bar.test.;
when test_cname_negcache ran next against the same resolver,
cname.foo.test. was DNAME-mapped to cname.bar.test., so the resolver
never queried ans2 for the self-referential CNAME and that half of the
bug was never exercised. The hardcoded, unanchored "foo.test." watcher
still matched test_dname's leftover SOA, so test_cname passed without
testing anything -- the CNAME assertion had no coverage.
Give each scenario its own module so each gets a fresh server set, and
anchor the watcher to the queried name so a test cannot pass on an
unrelated record.
With the resolver fix reverted, each module now independently triggers
its own assertion:
DNAME query.c INSIST(namereln == dns_namereln_subdomain)
CNAME query.c INSIST(qctx->rdataset == NULL || qctx->qtype == dname)
Assisted-by: Claude:claude-opus-4-8
(cherry picked from commit 3ef0b8d04a1653407cfb9ee88772ae18689b1318)
(cherry picked from commit 887124315f03a006c4dc76e48ae3d0d8aac3c407)
---
.../system/cname_dname_negcache/ans2/ans.py | 148 ++++++++++++++++++
.../system/cname_dname_negcache/common.py | 46 ++++++
.../cname_dname_negcache/ns1/bar.test.db | 5 +
.../cname_dname_negcache/ns1/named.conf.j2 | 24 +++
.../system/cname_dname_negcache/ns1/root.db | 6 +
.../system/cname_dname_negcache/ns1/test.db | 8 +
.../cname_dname_negcache/ns3/named.conf.j2 | 11 ++
.../tests_cname_negcache.py | 16 ++
.../tests_dname_negcache.py | 16 ++
9 files changed, 280 insertions(+)
create mode 100644 bin/tests/system/cname_dname_negcache/ans2/ans.py
create mode 100644 bin/tests/system/cname_dname_negcache/common.py
create mode 100644 bin/tests/system/cname_dname_negcache/ns1/bar.test.db
create mode 100644 bin/tests/system/cname_dname_negcache/ns1/named.conf.j2
create mode 100644 bin/tests/system/cname_dname_negcache/ns1/root.db
create mode 100644 bin/tests/system/cname_dname_negcache/ns1/test.db
create mode 100644 bin/tests/system/cname_dname_negcache/ns3/named.conf.j2
create mode 100644 bin/tests/system/cname_dname_negcache/tests_cname_negcache.py
create mode 100644 bin/tests/system/cname_dname_negcache/tests_dname_negcache.py
diff --git a/bin/tests/system/cname_dname_negcache/ans2/ans.py b/bin/tests/system/cname_dname_negcache/ans2/ans.py
new file mode 100644
index 0000000000..392fe1e088
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/ans2/ans.py
@@ -0,0 +1,148 @@
+"""
+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 collections.abc import AsyncGenerator
+
+import asyncio
+
+from dns import name, rcode, rdataclass, rdatatype, rrset
+
+from isctest.asyncserver import (
+ AsyncDnsServer,
+ DnsResponseSend,
+ QnameQtypeHandler,
+ QueryContext,
+ StaticResponseHandler,
+)
+
+# The attack relies on the resolver caching the positive CNAME/DNAME answer
+# *before* it processes the negative answer for the same name. The negative
+# answer must therefore be held back until the positive one has been sent, but
+# released again while the negative fetch is still waiting for it.
+#
+# Releasing it at a fixed wall-clock delay (the original approach) is racy: the
+# delay must be larger than the time it takes the resolver to cache the
+# positive answer, yet smaller than the resolver's per-query timeout. Under
+# load -- most notably ThreadSanitizer, which slows down `named` but not this
+# (wall-clock) server -- those bounds can be violated in either direction,
+# making the test either time out (#5946 CI failures) or, worse, silently stop
+# exercising the bug.
+#
+# Instead, gate the negative answer on an event set right after the positive
+# answer is sent. Both queries traverse the same delegation, so any latency in
+# reaching this server shifts the positive send and the negative fetch's
+# deadline together and cancels out; only the small settle below has to fit
+# inside the per-query timeout.
+#
+# _SETTLE must be longer than the few milliseconds the resolver needs to cache
+# the positive answer, and shorter than MINIMUM_QUERY_TIMEOUT (301 ms in
+# lib/dns/resolver.c) so the in-flight negative fetch has not given up yet.
+_SETTLE = 0.1
+
+_dname_positive_sent = asyncio.Event()
+_cname_positive_sent = asyncio.Event()
+
+
+async def _hold_until_positive_cached(positive_sent: asyncio.Event) -> None:
+ await positive_sent.wait()
+ await asyncio.sleep(_SETTLE)
+
+
+def build_rrset(
+ qname: name.Name | str,
+ rtype: rdatatype.RdataType,
+ rdata: str,
+ ttl: int = 300,
+) -> rrset.RRset:
+ return rrset.from_text(qname, ttl, rdataclass.IN, rtype, rdata)
+
+
+class FooTestNsHandler(QnameQtypeHandler, StaticResponseHandler):
+ qnames = ["foo.test."]
+ qtypes = [rdatatype.NS]
+ answer = [build_rrset("foo.test.", rdatatype.NS, "ns.foo.test.")]
+ additional = [build_rrset("ns.foo.test.", rdatatype.A, "10.53.0.2")]
+
+
+class DelayedDnameNegHandler(QnameQtypeHandler, StaticResponseHandler):
+ qnames = ["foo.test."]
+ qtypes = [rdatatype.DNAME]
+ authority = [
+ build_rrset(
+ "foo.test.",
+ rdatatype.SOA,
+ "ns.test. op.ns.test. 2081509183 86400 3600 3600000 300",
+ )
+ ]
+
+ async def get_responses(
+ self, qctx: QueryContext
+ ) -> AsyncGenerator[DnsResponseSend, None]:
+ await _hold_until_positive_cached(_dname_positive_sent)
+ async for response in super().get_responses(qctx):
+ yield response
+
+
+class DnamePosHandler(QnameQtypeHandler, StaticResponseHandler):
+ qnames = ["a.foo.test."]
+ qtypes = [rdatatype.A]
+ answer = [
+ build_rrset("foo.test.", rdatatype.DNAME, "bar.test."),
+ build_rrset("a.foo.test.", rdatatype.CNAME, "a.bar.test."),
+ ]
+
+ async def get_responses(
+ self, qctx: QueryContext
+ ) -> AsyncGenerator[DnsResponseSend, None]:
+ async for response in super().get_responses(qctx):
+ yield response
+ _dname_positive_sent.set()
+
+
+class CnameHandler(QnameQtypeHandler):
+ qnames = ["cname.foo.test."]
+ qtypes = [rdatatype.CNAME, rdatatype.A]
+ answer = [build_rrset("cname.foo.test.", rdatatype.CNAME, "cname.foo.test.")]
+ authority = [
+ build_rrset(
+ "cname.foo.test.",
+ rdatatype.SOA,
+ "ns.test. op.ns.test. 2081509183 86400 3600 3600000 300",
+ )
+ ]
+
+ async def get_responses(
+ self, qctx: QueryContext
+ ) -> AsyncGenerator[DnsResponseSend, None]:
+ if qctx.qtype == rdatatype.CNAME:
+ await _hold_until_positive_cached(_cname_positive_sent)
+ qctx.prepare_new_response(with_zone_data=False)
+ qctx.response.authority.extend(self.authority)
+ yield DnsResponseSend(qctx.response, authoritative=True)
+ else:
+ qctx.prepare_new_response(with_zone_data=False)
+ qctx.response.answer.extend(self.answer)
+ yield DnsResponseSend(qctx.response, authoritative=True)
+ _cname_positive_sent.set()
+
+
+def main() -> None:
+ server = AsyncDnsServer(default_aa=True, default_rcode=rcode.NOERROR)
+ server.install_response_handlers(
+ FooTestNsHandler(), DelayedDnameNegHandler(), DnamePosHandler(), CnameHandler()
+ )
+ server.run()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/tests/system/cname_dname_negcache/common.py b/bin/tests/system/cname_dname_negcache/common.py
new file mode 100644
index 0000000000..397cfdfa3d
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/common.py
@@ -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.
+
+from os import environ
+from re import compile as Re
+from re import escape
+from socket import AF_INET, SOCK_DGRAM, socket
+
+import isctest
+
+
+def run_attack(ns, name1, type1, name2, type2):
+ msg1 = isctest.query.create(name1, type1, cd=True)
+ msg2 = isctest.query.create(name2, type2, cd=True)
+ port = int(environ["PORT"])
+
+ with socket(AF_INET, SOCK_DGRAM) as sock:
+ # The order the requests go out doesn't matter. What is important is
+ # that the first query starts recursion before the second query returns
+ # the answer, and the second query returns the answer before the first
+ # query returns the answer. (So, when the NOERROR/NODATA comes back from
+ # the first query, the cache is queried and we get the positive response
+ # cached from the second query attached to the fresp rdataset of the
+ # response of the first query.)
+ # That ordering is enforced by ans2, which holds back the negative
+ # answer to the first query until it has answered the second one (see
+ # ans2/ans.py); the resolver must not crash while reconciling them.
+ sock.sendto(msg1.to_wire(), (ns.ip, port))
+ sock.sendto(msg2.to_wire(), (ns.ip, port))
+
+ # The second query comes back immediately, the resolver caches the DNAME.
+ # The first query comes back shortly after, once ans2 has released the
+ # negative answer, and should not crash the server. Wait for the negative
+ # SOA for this specific name (not just any foo.test. one) so the test cannot
+ # pass on an unrelated record.
+ soa = Re(rf"(?<![\w.]){escape(name1)}.*IN\s+SOA\s+ns\.test\.\s+op\.ns\.test\.")
+ with ns.watch_log_from_start(timeout=15) as watcher:
+ watcher.wait_for_sequence([soa])
diff --git a/bin/tests/system/cname_dname_negcache/ns1/bar.test.db b/bin/tests/system/cname_dname_negcache/ns1/bar.test.db
new file mode 100644
index 0000000000..840b9c3a2c
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/ns1/bar.test.db
@@ -0,0 +1,5 @@
+$TTL 300
+bar.test. IN SOA ns.bar.test. hostmaster.bar.test. 1 600 600 1200 600
+bar.test. NS ns.bar.test.
+ns A 10.53.0.1
+a A 10.0.0.1
diff --git a/bin/tests/system/cname_dname_negcache/ns1/named.conf.j2 b/bin/tests/system/cname_dname_negcache/ns1/named.conf.j2
new file mode 100644
index 0000000000..d72dd1181d
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/ns1/named.conf.j2
@@ -0,0 +1,24 @@
+options {
+ query-source address @ns.ip@;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { @ns.ip@; };
+ listen-on-v6 { none; };
+ recursion no;
+ dnssec-validation no;
+};
+
+zone "." {
+ type primary;
+ file "root.db";
+};
+
+zone "test." {
+ type primary;
+ file "test.db";
+};
+
+zone "bar.test." {
+ type primary;
+ file "bar.test.db";
+};
diff --git a/bin/tests/system/cname_dname_negcache/ns1/root.db b/bin/tests/system/cname_dname_negcache/ns1/root.db
new file mode 100644
index 0000000000..c456c45b9d
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/ns1/root.db
@@ -0,0 +1,6 @@
+$TTL 300
+. IN SOA ns. hostmaster. 1 600 600 1200 600
+. NS a.root-servers.nil.
+a.root-servers.nil. A 10.53.0.1
+test NS ns.test
+ns.test A 10.53.0.1
diff --git a/bin/tests/system/cname_dname_negcache/ns1/test.db b/bin/tests/system/cname_dname_negcache/ns1/test.db
new file mode 100644
index 0000000000..acb68e00f8
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/ns1/test.db
@@ -0,0 +1,8 @@
+$TTL 300
+test. IN SOA ns.test. hostmaster.test. 1 600 600 1200 600
+test. NS ns.test.
+ns A 10.53.0.1
+bar NS ns.bar
+ns.bar A 10.53.0.1
+foo NS ns.foo
+ns.foo A 10.53.0.2
diff --git a/bin/tests/system/cname_dname_negcache/ns3/named.conf.j2 b/bin/tests/system/cname_dname_negcache/ns3/named.conf.j2
new file mode 100644
index 0000000000..197d72756b
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/ns3/named.conf.j2
@@ -0,0 +1,11 @@
+options {
+ query-source address @ns.ip@;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { @ns.ip@; };
+ listen-on-v6 { none; };
+ recursion yes;
+ dnssec-validation no;
+};
+
+{% include "_common/root.hint.conf" %}
diff --git a/bin/tests/system/cname_dname_negcache/tests_cname_negcache.py b/bin/tests/system/cname_dname_negcache/tests_cname_negcache.py
new file mode 100644
index 0000000000..a546d29109
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/tests_cname_negcache.py
@@ -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.
+
+from cname_dname_negcache.common import run_attack
+
+
+def test_cname_negcache(ns3):
+ run_attack(ns3, "cname.foo.test.", "CNAME", "cname.foo.test.", "A")
diff --git a/bin/tests/system/cname_dname_negcache/tests_dname_negcache.py b/bin/tests/system/cname_dname_negcache/tests_dname_negcache.py
new file mode 100644
index 0000000000..41a80b4e05
--- /dev/null
+++ b/bin/tests/system/cname_dname_negcache/tests_dname_negcache.py
@@ -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.
+
+from cname_dname_negcache.common import run_attack
+
+
+def test_dname_negcache(ns3):
+ run_attack(ns3, "foo.test.", "DNAME", "a.foo.test.", "A")
--
2.55.0

View file

@ -1,280 +0,0 @@
From 3138886f3767c0a6b933fd147c5465472209bac6 Mon Sep 17 00:00:00 2001
From: Colin Vidal <colin@isc.org>
Date: Thu, 18 Jun 2026 18:17:05 +0200
Subject: [PATCH] Do not assert in some CNAME/DNAME queries
Fix a `named` crash because of a fail assertion for certains types of
CNAME and DNAME queries:
- If a client queries for a DNAME and A record to the resolver, and the
authoritative server responds positively to the A query but delay the
DNAME response and respond later negatively;
- If a client queries for a CNAME and A record to the resolver, and the
authoritative server responds positively to the A query but delay the
CNAME response and respond later with a self-referential CNAME.
The first scenario consists of sending two queries: `foo.test./DNAME`
and `a.foo.test./A`. The authoritative server delays the answer for
`foo.test./DNAME` but immediately answers the DNAME record for the
second query: `foo.test. DNAME bar.test.`. The resolver caches it,
follows the DNAME, and resolves `a.bar.test./A`. The authoritative
server eventually answers negatively for `foo.test./DNAME`
(NOERROR/NODATA, with only an SOA in the authority section). The
resolver pulls out the previously cached rdataset (because it has a
higher trust level than the received negative answer), and wrongly (this
is the first bug) sets the result to `DNS_R_DNAME` instead of
`ISC_R_SUCCESS`. The code in `ns/query.c` that handles the resolver
result interprets this as "this is a non-DNAME query and we got a DNAME
rdataset, so follow the chain". It goes into the `query_dname()`
function, which asserts that the qname is a subdomain of the owner name
in the rdataset. That assertion fails because the qname (`foo.test.`) is
exactly equal to the owner name of the DNAME (`foo.test.`), rather than
being a subdomain of it. `DNS_R_DNAME` must only be set when the qtype
is something other than DNAME and the resolver has obtained a DNAME that
needs to be followed.
The second scenario consists of sending two queries:
`cname.foo.test./CNAME` and `cname.foo.test./A`. The authoritative
server delays the answer for `cname.foo.test./CNAME` but immediately
answers the CNAME record for the second query: `cname.foo.test. CNAME
cname.foo.test.`. Note that the CNAME is self-referential. The resolver
caches it and sets the result code to `DNS_R_CNAME`. Then `ns/query.c`
interprets this as "this is a non-CNAME query and we got a CNAME
rdataset, so follow the chain" (which is correct in this case; however,
because the CNAME rdataset is self-referential, the resolver responds
with SERVFAIL, which is expected). The authoritative server eventually
answers negatively for `cname.foo.test./CNAME`. The resolver then pulls
out the previously cached CNAME rdataset (obtained from the A answer,
even though it was self-referential, the resolver cached it) and wrongly
sets the result to `DNS_R_CNAME` (this is the second bug). As noted
above, `ns/query.c` interprets this as "this is a non-CNAME query and we
got a CNAME rdataset, so follow the chain". The internals here are
slightly more subtle: it first goes into `query_cname()` and sets the
CNAME rdataset in the message answer section, then restarts the query to
follow the CNAME. The restart retrieves the CNAME rdataset from the
cache directly (without going to the resolver), and this time the query
context result is `ISC_R_SUCCESS` (since it was found) and
`qctx->rdataset` points to the same CNAME again (as it is
self-referential), so it goes directly into the
`query_prepresponse()/query_respond()` flow, which attempts to add the
rdataset to the message answer again. However, this fails because the
rdataset is already in the message, and the assertion which expects that
operation to succeed fails (due to `qctx->rdataset` being set to `NULL`
when ownership of the rdataset was transferred). `DNS_R_CNAME` must only
be set when the qtype is something other than CNAME and the resolver has
obtained a CNAME that needs to be followed.
In both cases, the correct answer from the resolver should have been
`ISC_R_SUCCESS` (instead of respectively `DNS_R_DNAME` and
`DNS_R_CNAME`) becuase the rdataset that has been looked up was found.
(cherry picked from commit 773d46d58c693047a5945c8fe40512edd0ac214e)
(cherry picked from commit c740c37689f234e21a9b0ef760471ef2cf1133f5)
---
lib/dns/resolver.c | 137 ++++++++++++++++++++-------------------------
1 file changed, 60 insertions(+), 77 deletions(-)
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index edc9c207e1..1f8b5058d1 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -692,10 +692,10 @@ fctx_destroy(fetchctx_t *fctx, bool exiting);
static void
send_shutdown_events(dns_resolver_t *res);
static isc_result_t
-ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl,
- dns_ttl_t maxttl, bool optout, bool secure,
- dns_rdataset_t *ardataset, isc_result_t *eresultp);
+ncache_adderesult(fetchctx_t *fctx, dns_message_t *message, dns_dbnode_t *node,
+ dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
+ bool optout, bool secure, dns_rdataset_t *ardataset,
+ isc_result_t *eresultp);
static void
validated(isc_task_t *task, isc_event_t *event);
static void
@@ -5563,6 +5563,46 @@ has_000_label(dns_rdataset_t *nsecset) {
return false;
}
+/*
+ * After a (non-error) negative-cache add, 'rdataset' is bound to whatever
+ * rdataset the cache authoritatively holds for the queried name and type.
+ * Map that to the result code the fetch should report:
+ *
+ * - A negative cache entry (the one we just added, or a pre-existing one):
+ * DNS_R_NCACHENXDOMAIN or DNS_R_NCACHENXRRSET, depending on NXDOMAIN vs
+ * NODATA.
+ *
+ * - A positive rdataset that was already cached at higher trust, which
+ * caused our negative entry to be discarded (e.g. a CNAME or DNAME cached
+ * by a concurrent query): ISC_R_SUCCESS, because that cached positive
+ * answer is what gets returned. Note the specific case for CNAME and
+ * DNAME *if* the query type is not the same as the rdataset type. There
+ * is a chain to follow *only* if the query type doesn't ask for the CNAME
+ * or the DNAME.
+ */
+static isc_result_t
+fctx_setresult(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ if (NEGATIVE(rdataset)) {
+ result = NXDOMAIN(rdataset) ? DNS_R_NCACHENXDOMAIN
+ : DNS_R_NCACHENXRRSET;
+ } else if (result == ISC_R_SUCCESS && rdataset->type != fctx->type) {
+ switch (rdataset->type) {
+ case dns_rdatatype_cname:
+ result = DNS_R_CNAME;
+ break;
+ case dns_rdatatype_dname:
+ result = DNS_R_DNAME;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return result;
+}
+
/*
* The validator has finished.
*/
@@ -5836,8 +5876,7 @@ validated(isc_task_t *task, isc_event_t *event) {
ttl = 0;
}
- result = ncache_adderesult(message, fctx->cache, node, covers,
- now, fctx->res->view->minncachettl,
+ result = ncache_adderesult(fctx, message, node, covers, now,
ttl, vevent->optout, vevent->secure,
ardataset, &eresult);
if (result != ISC_R_SUCCESS) {
@@ -6081,23 +6120,7 @@ answer_response:
*/
INSIST(hevent->rdataset != NULL);
if (dns_rdataset_isassociated(hevent->rdataset)) {
- if (NEGATIVE(hevent->rdataset)) {
- INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
- eresult == DNS_R_NCACHENXRRSET);
- } else if (eresult == ISC_R_SUCCESS &&
- hevent->rdataset->type != fctx->type)
- {
- switch (hevent->rdataset->type) {
- case dns_rdatatype_cname:
- eresult = DNS_R_CNAME;
- break;
- case dns_rdatatype_dname:
- eresult = DNS_R_DNAME;
- break;
- default:
- break;
- }
- }
+ eresult = fctx_setresult(fctx, hevent->rdataset);
}
hevent->result = eresult;
@@ -6747,24 +6770,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_message_t *message,
* event->result.
*/
if (dns_rdataset_isassociated(event->rdataset)) {
- if (NEGATIVE(event->rdataset)) {
- INSIST(eresult ==
- DNS_R_NCACHENXDOMAIN ||
- eresult == DNS_R_NCACHENXRRSET);
- } else if (eresult == ISC_R_SUCCESS &&
- event->rdataset->type != fctx->type)
- {
- switch (event->rdataset->type) {
- case dns_rdatatype_cname:
- eresult = DNS_R_CNAME;
- break;
- case dns_rdatatype_dname:
- eresult = DNS_R_DNAME;
- break;
- default:
- break;
- }
- }
+ eresult = fctx_setresult(fctx, event->rdataset);
}
event->result = eresult;
if (adbp != NULL && *adbp != NULL) {
@@ -6833,12 +6839,14 @@ cache_message(fetchctx_t *fctx, dns_message_t *message,
* eresult.
*/
static isc_result_t
-ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
- dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t minttl,
- dns_ttl_t maxttl, bool optout, bool secure,
- dns_rdataset_t *ardataset, isc_result_t *eresultp) {
+ncache_adderesult(fetchctx_t *fctx, dns_message_t *message, dns_dbnode_t *node,
+ dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
+ bool optout, bool secure, dns_rdataset_t *ardataset,
+ isc_result_t *eresultp) {
isc_result_t result;
dns_rdataset_t rdataset;
+ dns_db_t *cache = fctx->cache;
+ dns_ttl_t minttl = fctx->res->view->minncachettl;
if (ardataset == NULL) {
dns_rdataset_init(&rdataset);
@@ -6854,37 +6862,13 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
}
if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
/*
- * If the cache now contains a negative entry and we
- * care about whether it is DNS_R_NCACHENXDOMAIN or
- * DNS_R_NCACHENXRRSET then extract it.
+ * The cache settled successfully (DNS_R_UNCHANGED means our
+ * negative entry was discarded in favour of existing
+ * higher-trust data). Either way 'ardataset' is now bound to
+ * the rdataset the cache holds for this name and type; derive
+ * the result code from it.
*/
- if (NEGATIVE(ardataset)) {
- /*
- * The cache data is a negative cache entry.
- */
- if (NXDOMAIN(ardataset)) {
- *eresultp = DNS_R_NCACHENXDOMAIN;
- } else {
- *eresultp = DNS_R_NCACHENXRRSET;
- }
- } else {
- /*
- * The attempt to add a negative cache entry
- * was rejected. Set *eresultp to reflect
- * the type of the dataset being returned.
- */
- switch (ardataset->type) {
- case dns_rdatatype_cname:
- *eresultp = DNS_R_CNAME;
- break;
- case dns_rdatatype_dname:
- *eresultp = DNS_R_DNAME;
- break;
- default:
- *eresultp = ISC_R_SUCCESS;
- break;
- }
- }
+ *eresultp = fctx_setresult(fctx, ardataset);
result = ISC_R_SUCCESS;
}
if (ardataset == &rdataset && dns_rdataset_isassociated(ardataset)) {
@@ -7029,8 +7013,7 @@ ncache_message(fetchctx_t *fctx, dns_message_t *message,
ttl = 0;
}
- result = ncache_adderesult(message, fctx->cache, node, covers, now,
- fctx->res->view->minncachettl, ttl, false,
+ result = ncache_adderesult(fctx, message, node, covers, now, ttl, false,
false, ardataset, &eresult);
if (result != ISC_R_SUCCESS) {
goto unlock;
--
2.55.0

View file

@ -1,416 +0,0 @@
From 89e950d215e9922e5af6e3c69b9d6a8750346bb6 Mon Sep 17 00:00:00 2001
From: Alessio Podda <alessio@isc.org>
Date: Fri, 12 Jun 2026 11:16:01 +0200
Subject: [PATCH] Reproducer for #5985 addnoqname mismatch
LLM generated.
(cherry picked from commit 5f4de929b3e4749b6e32c51660be11c47c2514e6)
(cherry picked from commit 0cf010c153518f1f9831e201891ecba8d8ba65e1)
Update reproducer #5985
Update the llm generated reproducer:
- Move server.py into ans/ans1.py
- Remove unncessary named.conf configuration options
- Add comments describing the steps
- Rename system test
(cherry picked from commit fd539807829dd7d2eb76c8b503083f5d84fec6f0)
(cherry picked from commit 6c0e599ea85c0c53a4af09742e64e193da089bb4)
---
.../dnssec_findnoqname_mismatch/ans1/ans.py | 207 ++++++++++++++++++
.../ns2/named.conf.j2 | 33 +++
.../tests_findnoqname_mismatch.py | 126 +++++++++++
3 files changed, 366 insertions(+)
create mode 100644 bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py
create mode 100644 bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2
create mode 100644 bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py
diff --git a/bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py b/bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py
new file mode 100644
index 0000000000..b36fc831c8
--- /dev/null
+++ b/bin/tests/system/dnssec_findnoqname_mismatch/ans1/ans.py
@@ -0,0 +1,207 @@
+#!/usr/bin/python3
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+
+from collections.abc import AsyncGenerator
+from dataclasses import dataclass
+from datetime import datetime, timedelta, timezone
+from pathlib import Path
+
+import base64
+import json
+
+from cryptography.hazmat.primitives import serialization
+
+import dns.dnssec
+import dns.flags
+import dns.message
+import dns.name
+import dns.rdata
+import dns.rdataclass
+import dns.rcode
+import dns.rdatatype
+import dns.rrset
+
+from isctest.asyncserver import (
+ AsyncDnsServer,
+ DnsResponseSend,
+ QueryContext,
+ ResponseHandler,
+)
+
+TTL = 300
+ZONE = "f217.test."
+CHILD = f"evil.{ZONE}"
+ATTACK = f"www.{CHILD}"
+NSEC_OWNER = f"00000000.{CHILD}"
+NSEC_NEXT = f"zzz.{CHILD}"
+FORGED_A = "192.0.2.217"
+
+
+@dataclass(frozen=True)
+class Key:
+ zone: dns.name.Name
+ private_key: object
+ dnskey: dns.rdata.Rdata
+
+
+def name(text: str) -> dns.name.Name:
+ return dns.name.from_text(text)
+
+
+def load_key() -> Key:
+ path = Path(__file__).resolve().parent / "keys.json"
+ with path.open(encoding="utf-8") as keys_file:
+ raw_key = json.load(keys_file)[ZONE]
+
+ private_key = serialization.load_pem_private_key(
+ raw_key["private_pem"].encode("ascii"),
+ password=None,
+ )
+ dnskey = dns.rdata.from_text(
+ dns.rdataclass.IN, dns.rdatatype.DNSKEY, raw_key["dnskey"]
+ )
+ return Key(name(ZONE), private_key, dnskey)
+
+
+def rrset(owner: str, rdtype: dns.rdatatype.RdataType, *rdatas: str) -> dns.rrset.RRset:
+ return dns.rrset.from_text(owner, TTL, dns.rdataclass.IN, rdtype, *rdatas)
+
+
+def rrset_from_rdata(owner: str, rdata: dns.rdata.Rdata) -> dns.rrset.RRset:
+ return dns.rrset.from_rdata(name(owner), TTL, rdata)
+
+
+def add_signed(
+ section: list[dns.rrset.RRset], covered: dns.rrset.RRset, signer: Key
+) -> None:
+ rrsig = dns.dnssec.sign(
+ covered,
+ signer.private_key,
+ signer.zone,
+ signer.dnskey,
+ lifetime=86400,
+ verify=True,
+ )
+ section.append(covered)
+ section.append(dns.rrset.from_rdata(covered.name, covered.ttl, rrsig))
+
+
+def soa_rrset(zone: str) -> dns.rrset.RRset:
+ return rrset(
+ zone,
+ dns.rdatatype.SOA,
+ f"ns.{ZONE} hostmaster.{ZONE} 1 7200 3600 1209600 300",
+ )
+
+
+def garbage_rrsig(
+ owner: str, covered: dns.rdatatype.RdataType, labels: int, signer: str
+) -> dns.rrset.RRset:
+ now = datetime.now(timezone.utc)
+ inception = (now - timedelta(hours=1)).strftime("%Y%m%d%H%M%S")
+ expiration = (now + timedelta(days=1)).strftime("%Y%m%d%H%M%S")
+ signature = base64.b64encode(bytes(64)).decode("ascii")
+ text = (
+ f"{dns.rdatatype.to_text(covered)} 13 {labels} {TTL} "
+ f"{expiration} {inception} 12345 {signer} {signature}"
+ )
+ rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.RRSIG, text)
+ return dns.rrset.from_rdata(name(owner), TTL, rdata)
+
+
+def add_ds_denial(response: dns.message.Message, key: Key) -> None:
+ add_signed(response.authority, soa_rrset(ZONE), key)
+ nsec = rrset(CHILD, dns.rdatatype.NSEC, f"ns.{ZONE} NS RRSIG NSEC")
+ add_signed(response.authority, nsec, key)
+
+
+def add_attack_answer(response: dns.message.Message) -> None:
+ """
+ Crafted authoritative response to <q>.evil.f217.hack./A
+
+ ;; ANSWER
+ <q>.evil.f217.hack. 300 IN A 192.0.2.217
+ <q>.evil.f217.hack. 300 IN RRSIG A 13 1 300 <exp> <inc> 12345 evil.f217.hack. <base64 of 64×0x00>
+ ^^^ Labels = 1, qname has 4 labels, wildcard heuristic fires
+
+ ;; AUTHORITY (single owner, three rdatasets in this wire order)
+ 00000000.evil.f217.hack. 300 IN NSEC zzz.evil.f217.hack. A RRSIG NSEC
+ 00000000.evil.f217.hack. 300 IN RRSIG NSEC 13 4 300 <exp> <inc> 12345 evil.f217.hack. <base64 of 64×0x00>
+ 00000000.evil.f217.hack. 300 IN NSEC3 1 0 0 - VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV A RRSIG
+ """
+ # A + RRSIG
+ response.answer.append(rrset(ATTACK, dns.rdatatype.A, FORGED_A))
+ response.answer.append(garbage_rrsig(ATTACK, dns.rdatatype.A, 1, CHILD))
+ # NSEC
+ nsec = rrset(
+ NSEC_OWNER,
+ dns.rdatatype.NSEC,
+ f"{NSEC_NEXT} A RRSIG NSEC",
+ )
+ response.authority.append(nsec)
+ # RRSIG(NSEC)
+ response.authority.append(
+ garbage_rrsig(
+ NSEC_OWNER,
+ dns.rdatatype.NSEC,
+ len(name(NSEC_OWNER).labels) - 1,
+ CHILD,
+ )
+ )
+ # NSEC3
+ nsec3 = rrset(
+ NSEC_OWNER,
+ dns.rdatatype.NSEC3,
+ "1 0 0 - VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV A RRSIG",
+ )
+ response.authority.append(nsec3)
+
+
+class RuntimeCheckHandler(ResponseHandler):
+ def __init__(self, key: Key) -> None:
+ self.key = key
+ self.zone = name(ZONE)
+ self.child = name(CHILD)
+ self.attack = name(ATTACK)
+
+ def match(self, qctx: QueryContext) -> bool:
+ return qctx.qname.is_subdomain(self.zone)
+
+ async def get_responses(
+ self, qctx: QueryContext
+ ) -> AsyncGenerator[DnsResponseSend, None]:
+ qctx.prepare_new_response(with_zone_data=False)
+ qctx.response.flags |= dns.flags.AA
+ qctx.response.set_rcode(dns.rcode.NOERROR)
+
+ if qctx.qname == self.zone and qctx.qtype == dns.rdatatype.DNSKEY:
+ add_signed(
+ qctx.response.answer,
+ rrset_from_rdata(ZONE, self.key.dnskey),
+ self.key,
+ )
+ elif qctx.qname == self.zone and qctx.qtype == dns.rdatatype.SOA:
+ add_signed(qctx.response.answer, soa_rrset(ZONE), self.key)
+ elif qctx.qname == self.child and qctx.qtype == dns.rdatatype.DS:
+ add_ds_denial(qctx.response, self.key)
+ elif qctx.qname == self.child and qctx.qtype == dns.rdatatype.DNSKEY:
+ qctx.response.authority.append(soa_rrset(CHILD))
+ elif qctx.qname == self.attack and qctx.qtype == dns.rdatatype.A:
+ add_attack_answer(qctx.response)
+ else:
+ add_signed(qctx.response.authority, soa_rrset(ZONE), self.key)
+
+ yield DnsResponseSend(qctx.response, authoritative=True)
+
+
+def main() -> None:
+ server = AsyncDnsServer(default_aa=True)
+ server.install_response_handlers(RuntimeCheckHandler(load_key()))
+ server.run()
+
+
+if __name__ == "__main__":
+ main()
diff --git a/bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2 b/bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2
new file mode 100644
index 0000000000..f4fbd8a617
--- /dev/null
+++ b/bin/tests/system/dnssec_findnoqname_mismatch/ns2/named.conf.j2
@@ -0,0 +1,33 @@
+// 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";
+};
+
+zone "f217.test" {
+ type static-stub;
+ server-addresses { 10.53.0.1; };
+};
+
+trust-anchors {
+ f217.test. static-key 257 3 13 "@ZONE_DNSKEY@";
+};
diff --git a/bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py b/bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py
new file mode 100644
index 0000000000..f3e332a360
--- /dev/null
+++ b/bin/tests/system/dnssec_findnoqname_mismatch/tests_findnoqname_mismatch.py
@@ -0,0 +1,126 @@
+#!/usr/bin/python3
+
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# SPDX-License-Identifier: MPL-2.0
+
+from pathlib import Path
+
+import json
+
+from cryptography.hazmat.primitives import serialization
+from cryptography.hazmat.primitives.asymmetric import ec
+
+import dns.dnssec
+import dns.name
+import dns.rdataclass
+import dns.rdatatype
+import pytest
+
+import isctest
+import isctest.mark
+
+ZONE = "f217.test."
+CHILD = f"evil.{ZONE}"
+ATTACK = f"www.{CHILD}"
+NSEC_OWNER = f"00000000.{CHILD}"
+FORGED_A = "192.0.2.217"
+AUTH = "10.53.0.1"
+RESOLVER = "10.53.0.2"
+
+pytestmark = [
+ isctest.mark.with_ecdsa_deterministic,
+ pytest.mark.extra_artifacts(
+ [
+ "ans1/ans.run",
+ "ans1/keys.json",
+ ]
+ ),
+]
+
+
+def _make_key():
+ private_key = ec.generate_private_key(ec.SECP256R1())
+ dnskey = dns.dnssec.make_dnskey(
+ private_key.public_key(),
+ algorithm="ECDSAP256SHA256",
+ flags=257,
+ )
+ private_pem = private_key.private_bytes(
+ encoding=serialization.Encoding.PEM,
+ format=serialization.PrivateFormat.PKCS8,
+ encryption_algorithm=serialization.NoEncryption(),
+ ).decode("ascii")
+ return {
+ "private_pem": private_pem,
+ "dnskey": dnskey.to_text(),
+ }
+
+
+def bootstrap():
+ keys = {ZONE: _make_key()}
+ Path("ans1/keys.json").write_text(json.dumps(keys, indent=2), encoding="ascii")
+ zone_dnskey = "".join(keys[ZONE]["dnskey"].split()[3:])
+ return {"ZONE_DNSKEY": zone_dnskey}
+
+
+def _query(server, qname, qtype):
+ query = isctest.query.create(qname, qtype)
+ return isctest.query.tcp(query, server, attempts=1, timeout=5)
+
+
+def _rrset(response, section, owner, rdtype, covers=None):
+ if covers is None:
+ return response.get_rrset(
+ section, dns.name.from_text(owner), dns.rdataclass.IN, rdtype
+ )
+ return response.get_rrset(
+ section,
+ dns.name.from_text(owner),
+ dns.rdataclass.IN,
+ rdtype,
+ covers=covers,
+ )
+
+
+def _has_a(response, section, owner, address):
+ rrset = _rrset(response, section, owner, dns.rdatatype.A)
+ return rrset is not None and any(rdata.address == address for rdata in rrset)
+
+
+def _check_rrsig(response, section, owner, rdtype, signer, labels=None):
+ rrsig = _rrset(response, section, owner, dns.rdatatype.RRSIG, covers=rdtype)
+ assert rrsig is not None, response.to_text()
+ assert rrsig[0].signer == dns.name.from_text(signer), response.to_text()
+ if labels is not None:
+ assert rrsig[0].labels == labels, response.to_text()
+
+
+def test_malicious_findnoqname_addnoqname_mismatch():
+ response = _query(AUTH, ATTACK, "A")
+ isctest.check.noerror(response)
+ assert _has_a(response, response.answer, ATTACK, FORGED_A), response.to_text()
+ _check_rrsig(response, response.answer, ATTACK, dns.rdatatype.A, CHILD, labels=1)
+
+ # Has NSEC
+ assert _rrset(response, response.authority, NSEC_OWNER, dns.rdatatype.NSEC)
+ _check_rrsig(response, response.authority, NSEC_OWNER, dns.rdatatype.NSEC, CHILD)
+ # Has NSEC3
+ assert _rrset(response, response.authority, NSEC_OWNER, dns.rdatatype.NSEC3)
+ assert (
+ _rrset(
+ response,
+ response.authority,
+ NSEC_OWNER,
+ dns.rdatatype.RRSIG,
+ covers=dns.rdatatype.NSEC3,
+ )
+ is None
+ )
+
+
+def test_resolver_findnoqname_addnoqname_mismatch():
+ # Send one trigger query
+ _query(RESOLVER, ATTACK, "A")
+ response = _query(RESOLVER, ZONE, "SOA")
+ isctest.check.noerror(response)
--
2.55.0

View file

@ -1,158 +0,0 @@
From 895cac04332d85489ddf881b28e18e9956f6e348 Mon Sep 17 00:00:00 2001
From: Evan Hunt <each@isc.org>
Date: Wed, 13 May 2026 20:45:57 -0700
Subject: [PATCH] dns_rdataset_addnoqname() could find unsigned NSEC/NSEC3
The dns_rdatalist addnoqname() implementation searches for the first
NSEC or NSEC3 record in a message, then for the first RRSIG covering
that type in the same message. Previously, if no RRSIG for the type was
found, the function accepted the unsigned record. Now, it will instead
continue searching until an NSEC or NSEC3 that does have a matching
signature is found.
When this function is called from validated() in resolver.c, a
non-success return code is now treated as an error instead of triggering
an assertion failure.
Fixes: isc-projects/bind9#5985
(cherry picked from commit 57cba571ee31311e54d8a11cb38094d439f04e09)
(cherry picked from commit 48f5aa5fb3746d6194edcc57e8792a8b3cc3b454)
---
lib/dns/rbtdb.c | 10 +++++++---
lib/dns/rdatalist.c | 33 ++++++++++++++++-----------------
lib/dns/resolver.c | 4 +++-
lib/ns/query.c | 3 +--
4 files changed, 27 insertions(+), 23 deletions(-)
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 0b8547950f..c922df557b 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -6946,7 +6946,7 @@ delegating_type(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
static isc_result_t
addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
uint32_t maxrrperset, dns_rdataset_t *rdataset) {
- struct noqname *noqname;
+ struct noqname *noqname = NULL;
isc_mem_t *mctx = rbtdb->common.mctx;
dns_name_t name;
dns_rdataset_t neg, negsig;
@@ -6958,7 +6958,9 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
dns_rdataset_init(&negsig);
result = dns_rdataset_getnoqname(rdataset, &name, &neg, &negsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (result != ISC_R_SUCCESS) {
+ goto cleanup;
+ }
noqname = isc_mem_get(mctx, sizeof(*noqname));
dns_name_init(&noqname->name, NULL);
@@ -6984,7 +6986,9 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
cleanup:
dns_rdataset_disassociate(&neg);
dns_rdataset_disassociate(&negsig);
- free_noqname(mctx, &noqname);
+ if (noqname != NULL) {
+ free_noqname(mctx, &noqname);
+ }
return result;
}
diff --git a/lib/dns/rdatalist.c b/lib/dns/rdatalist.c
index 98036f9cb3..2cca8d64be 100644
--- a/lib/dns/rdatalist.c
+++ b/lib/dns/rdatalist.c
@@ -192,6 +192,7 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const dns_name_t *name) {
dns_rdataset_t *neg = NULL;
dns_rdataset_t *negsig = NULL;
dns_rdataset_t *rdset;
+ dns_rdataset_t *sigset;
dns_ttl_t ttl;
REQUIRE(rdataset != NULL);
@@ -199,30 +200,27 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const dns_name_t *name) {
for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL;
rdset = ISC_LIST_NEXT(rdset, link))
{
- if (rdset->rdclass != rdataset->rdclass) {
- continue;
- }
- if (rdset->type == dns_rdatatype_nsec ||
- rdset->type == dns_rdatatype_nsec3)
+ if (rdset->rdclass != rdataset->rdclass ||
+ (rdset->type != dns_rdatatype_nsec &&
+ rdset->type != dns_rdatatype_nsec3))
{
- neg = rdset;
+ continue;
}
- }
- if (neg == NULL) {
- return ISC_R_NOTFOUND;
- }
- for (rdset = ISC_LIST_HEAD(name->list); rdset != NULL;
- rdset = ISC_LIST_NEXT(rdset, link))
- {
- if (rdset->type == dns_rdatatype_rrsig &&
- rdset->covers == neg->type)
+ for (sigset = ISC_LIST_HEAD(name->list); sigset != NULL;
+ sigset = ISC_LIST_NEXT(sigset, link))
{
- negsig = rdset;
+ if (sigset->type == dns_rdatatype_rrsig &&
+ sigset->covers == rdset->type)
+ {
+ neg = rdset;
+ negsig = sigset;
+ break;
+ }
}
}
- if (negsig == NULL) {
+ if (neg == NULL || negsig == NULL) {
return ISC_R_NOTFOUND;
}
/*
@@ -238,6 +236,7 @@ isc__rdatalist_addnoqname(dns_rdataset_t *rdataset, const dns_name_t *name) {
rdataset->ttl = neg->ttl = negsig->ttl = ttl;
rdataset->attributes |= DNS_RDATASETATTR_NOQNAME;
rdataset->private6 = name;
+
return ISC_R_SUCCESS;
}
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 1f8b5058d1..059ce53a9e 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -5893,7 +5893,9 @@ validated(isc_task_t *task, isc_event_t *event) {
result = dns_rdataset_addnoqname(
vevent->rdataset,
vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (result != ISC_R_SUCCESS) {
+ goto noanswer_response;
+ }
INSIST(vevent->sigrdataset != NULL);
vevent->sigrdataset->ttl = vevent->rdataset->ttl;
if (vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER] != NULL) {
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 3bd7daf79c..2a2ba1daba 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -7953,8 +7953,7 @@ query_addnoqnameproof(query_ctx_t *qctx) {
goto cleanup;
}
- result = dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ CHECK(dns_rdataset_getnoqname(qctx->noqname, fname, neg, negsig));
query_addrrset(qctx, &fname, &neg, &negsig, dbuf,
DNS_SECTION_AUTHORITY);
--
2.55.0

View file

@ -1,445 +0,0 @@
From eaa35628f4a201049295a8944f4d28e8a1013199 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ayd=C4=B1n=20Mercan?= <aydin@isc.org>
Date: Wed, 6 May 2026 16:54:57 +0300
Subject: [PATCH] Add system test for out-of-zone nsec dnssec bypass
A malicious zone with out-of-zone NSEC entries can get a DNSSEC
validating resolver's cache to cover the victim zone for non-existence
and prevent nameserver queries without DNSSEC failure.
Test for this case with an `evil.test` zone that tries to cover the
`victim.test` zone.
(cherry picked from commit 654f9773c0af59965c343bdfeb096b3dffe9dd53)
(cherry picked from commit c969ad2c17b43dd999e358bfeb280d3df6fab822)
---
.../system/dnssec_bypass/ns1/named.conf.j2 | 31 ++++
bin/tests/system/dnssec_bypass/ns1/root.db | 19 +++
bin/tests/system/dnssec_bypass/ns1/test.db | 23 +++
.../system/dnssec_bypass/ns2/named.conf.j2 | 26 +++
bin/tests/system/dnssec_bypass/ns2/victim.db | 18 +++
bin/tests/system/dnssec_bypass/ns3/evil.db | 23 +++
.../system/dnssec_bypass/ns3/named.conf.j2 | 26 +++
.../system/dnssec_bypass/ns4/named.conf.j2 | 35 ++++
.../system/dnssec_bypass/tests_bypass.py | 152 ++++++++++++++++++
9 files changed, 353 insertions(+)
create mode 100644 bin/tests/system/dnssec_bypass/ns1/named.conf.j2
create mode 100644 bin/tests/system/dnssec_bypass/ns1/root.db
create mode 100644 bin/tests/system/dnssec_bypass/ns1/test.db
create mode 100644 bin/tests/system/dnssec_bypass/ns2/named.conf.j2
create mode 100644 bin/tests/system/dnssec_bypass/ns2/victim.db
create mode 100644 bin/tests/system/dnssec_bypass/ns3/evil.db
create mode 100644 bin/tests/system/dnssec_bypass/ns3/named.conf.j2
create mode 100644 bin/tests/system/dnssec_bypass/ns4/named.conf.j2
create mode 100644 bin/tests/system/dnssec_bypass/tests_bypass.py
diff --git a/bin/tests/system/dnssec_bypass/ns1/named.conf.j2 b/bin/tests/system/dnssec_bypass/ns1/named.conf.j2
new file mode 100644
index 0000000000..59ced1831a
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns1/named.conf.j2
@@ -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.
+ */
+
+options {
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.1; };
+ listen-on-v6 { none; };
+ recursion no;
+ dnssec-validation no;
+};
+
+zone "test." {
+ type primary;
+ file "test.db.signed";
+};
+
+zone "." {
+ type primary;
+ file "root.db.signed";
+};
diff --git a/bin/tests/system/dnssec_bypass/ns1/root.db b/bin/tests/system/dnssec_bypass/ns1/root.db
new file mode 100644
index 0000000000..8d98a0456c
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns1/root.db
@@ -0,0 +1,19 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; SPDX-License-Identifier: MPL-2.0
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, you can obtain one at https://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 3600
+. IN SOA a.nil. a.nil. 1 3600 600 86400 300
+. IN NS a.root-servers.nil.
+
+a.root-servers.nil. IN A 10.53.0.1
+
+test. IN NS ns1.test.
+ns1.test. IN A 10.53.0.1
diff --git a/bin/tests/system/dnssec_bypass/ns1/test.db b/bin/tests/system/dnssec_bypass/ns1/test.db
new file mode 100644
index 0000000000..6efcd95e42
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns1/test.db
@@ -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.
+
+$ORIGIN test.
+$TTL 3600
+
+@ IN SOA a a 1 3600 600 86400 300
+ IN NS ns1.test.
+ns1 IN A 10.53.0.1
+
+evil IN NS ns1.evil
+ns1.evil IN A 10.53.0.3
+
+victim IN NS ns1.victim
+ns1.victim IN A 10.53.0.2
diff --git a/bin/tests/system/dnssec_bypass/ns2/named.conf.j2 b/bin/tests/system/dnssec_bypass/ns2/named.conf.j2
new file mode 100644
index 0000000000..e81cee7cac
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns2/named.conf.j2
@@ -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.
+ */
+
+options {
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.2; };
+ listen-on-v6 { none; };
+ recursion no;
+ dnssec-validation no;
+};
+
+zone "victim.test." {
+ type primary;
+ file "victim.db.signed";
+};
diff --git a/bin/tests/system/dnssec_bypass/ns2/victim.db b/bin/tests/system/dnssec_bypass/ns2/victim.db
new file mode 100644
index 0000000000..edcc234322
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns2/victim.db
@@ -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.
+
+$ORIGIN victim.test.
+$TTL 3600
+
+@ IN SOA ns1 hostmaster 1 3600 600 86400 2147483647
+ IN NS ns1
+
+ns1 IN A 10.53.0.2
diff --git a/bin/tests/system/dnssec_bypass/ns3/evil.db b/bin/tests/system/dnssec_bypass/ns3/evil.db
new file mode 100644
index 0000000000..618f9d3e85
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns3/evil.db
@@ -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.
+
+$ORIGIN evil.test.
+$TTL 300
+
+@ IN SOA ns1 hostmaster 1 3600 600 86400 300
+ IN NS ns1
+; Try to poison the victim zone in a resolver cache.
+; If admitted, the aggressive NSEC cache will accept a range such as
+; [evil.test, b.victim.test) and will cause the victim nameserver to
+; be never queried.
+ IN NSEC b.victim.test. NS SOA RRSIG NSEC DNSKEY
+
+ns1 IN A 10.53.0.3
diff --git a/bin/tests/system/dnssec_bypass/ns3/named.conf.j2 b/bin/tests/system/dnssec_bypass/ns3/named.conf.j2
new file mode 100644
index 0000000000..17d3e18e4e
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns3/named.conf.j2
@@ -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.
+ */
+
+options {
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.3; };
+ listen-on-v6 { none; };
+ recursion no;
+ dnssec-validation no;
+};
+
+zone "evil.test." {
+ type primary;
+ file "evil.db.signed";
+};
diff --git a/bin/tests/system/dnssec_bypass/ns4/named.conf.j2 b/bin/tests/system/dnssec_bypass/ns4/named.conf.j2
new file mode 100644
index 0000000000..039695d9b7
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/ns4/named.conf.j2
@@ -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.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 yes;
+ dnssec-validation yes;
+ synth-from-dnssec yes;
+};
+
+trust-anchors {
+ @root.domain@ @root.type@ @root.contents@;
+};
+
+zone "." {
+ type hint;
+ file "../../_common/root.hint";
+};
diff --git a/bin/tests/system/dnssec_bypass/tests_bypass.py b/bin/tests/system/dnssec_bypass/tests_bypass.py
new file mode 100644
index 0000000000..c41bb7e016
--- /dev/null
+++ b/bin/tests/system/dnssec_bypass/tests_bypass.py
@@ -0,0 +1,152 @@
+# 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 datetime, timedelta, timezone
+
+import shutil
+
+from cryptography.hazmat.primitives.asymmetric import ec
+
+import dns.dnssec
+import dns.name
+import dns.rdataclass
+import dns.rdataset
+import dns.rdatatype
+import dns.rrset
+import dns.zone
+
+from isctest.run import EnvCmd
+
+import isctest
+
+TTL = 3600
+
+
+def bootstrap():
+ keygen = EnvCmd("KEYGEN", "-q -a ECDSA256")
+ signer = EnvCmd("SIGNER", "-S -g -O full")
+
+ def sign_regular_zone(ns: str, zone: str, database: str) -> isctest.kasp.Key:
+ isctest.log.info(f"{zone}: generate keys")
+ keygen(zone, cwd=ns).out.strip()
+ ksk = keygen(f"-f KSK {zone}", cwd=ns).out.strip()
+
+ isctest.log.info(f"{zone}: sign zone")
+ signer(f"-o {zone} {database}", cwd=ns)
+
+ if ns != "ns1":
+ shutil.copy(f"{ns}/dsset-{zone}", f"ns1/dsset-{zone}")
+ shutil.copy(f"{ns}/{ksk}.key", f"ns1/{ksk}.key")
+
+ return isctest.kasp.Key(ksk, keydir=ns)
+
+ # dnssec-signzone and `dns.dnssec.sign_zone` correctly disregard the invalid
+ # NSEC entries when signing the zone. However, for this test we actualy *want*
+ # to serve invalid yet signed zones. To accomplish this we sign the zone and then
+ # replace the correct entries with the faulty ones accompanied by its RRSIG.
+ #
+ # TODO(aydin): move this to `isctest` to sign broken zones
+ def sign_rogue_zone(ns: str, zone: str, database: str) -> None:
+ # Read zone.
+ origin = dns.name.from_text(zone)
+ data = dns.zone.from_file(f"{ns}/{database}", origin=origin, relativize=False)
+
+ # Get key for signing.
+ isctest.log.info(f"{zone}: generate keys")
+ private_key = ec.generate_private_key(ec.SECP256R1())
+ dnskey = dns.dnssec.make_dnskey(
+ public_key=private_key.public_key(),
+ algorithm=dns.dnssec.Algorithm.ECDSAP256SHA256,
+ flags=257,
+ )
+
+ # Sign zone.
+ isctest.log.info(f"{zone}: sign zone")
+ now = datetime.now(timezone.utc)
+ inception = now - timedelta(hours=1)
+ expiration = now + timedelta(days=30)
+
+ for name, node in data.nodes.items():
+ owner = name.derelativize(origin)
+ rdatasets = list(node.rdatasets)
+
+ for rdataset in rdatasets:
+ rrset = dns.rrset.RRset(owner, rdataset.rdclass, rdataset.rdtype)
+ rrset.update(rdataset)
+
+ rrsig = dns.dnssec.sign(
+ rrset=rrset,
+ private_key=private_key,
+ signer=origin,
+ dnskey=dnskey,
+ inception=inception,
+ expiration=expiration,
+ deterministic=False,
+ )
+
+ rdataset = dns.rdataset.Rdataset(rrset.rdclass, dns.rdatatype.RRSIG)
+ rdataset.add(rrsig, rrset.ttl)
+ node.replace_rdataset(rdataset)
+
+ # Sign DNSKEY RRset.
+ dnskey_rrset = dns.rrset.RRset(origin, dns.rdataclass.IN, dns.rdatatype.DNSKEY)
+ dnskey_rrset.add(dnskey, ttl=TTL)
+
+ apex_node = data.nodes[origin]
+ apex_node.replace_rdataset(dnskey_rrset)
+
+ rrsig = dns.dnssec.sign(
+ rrset=dnskey_rrset,
+ private_key=private_key,
+ signer=origin,
+ dnskey=dnskey,
+ inception=inception,
+ expiration=expiration,
+ deterministic=False,
+ )
+ rdataset = dns.rdataset.Rdataset(rrset.rdclass, dns.rdatatype.RRSIG)
+ rdataset.add(rrsig, dnskey_rrset.ttl)
+ apex_node.replace_rdataset(rdataset)
+
+ # Output zone.
+ data.to_file(f"{ns}/{database}.signed", relativize=False)
+
+ # Output DS.
+ ds = dns.dnssec.make_ds(name=origin, key=dnskey, algorithm="SHA256")
+ with open(f"ns1/dsset-{zone}", "w", encoding="utf-8") as f:
+ f.write(f"{zone} {TTL} IN DS {ds.to_text()}\n")
+
+ sign_rogue_zone("ns3", "evil.test.", "evil.db")
+ sign_regular_zone("ns2", "victim.test.", "victim.db")
+ sign_regular_zone("ns1", "test.", "test.db")
+ root_ksk = sign_regular_zone("ns1", ".", "root.db")
+
+ return {
+ "root": root_ksk.into_ta("static-key"),
+ }
+
+
+def test_out_of_zone_nsec(ns4):
+ isctest.log.info("trying to poison aggressive nsec cache")
+ msg = isctest.query.create("nx.evil.test", "A")
+ res = isctest.query.tcp(msg, ns4.ip)
+ isctest.check.noadflag(res)
+
+ isctest.log.info("query victim from recursive")
+ msg = isctest.query.create("victim.test", "SOA")
+ res = isctest.query.tcp(msg, ns4.ip, attempts=1)
+ isctest.check.noerror(res)
+ isctest.check.adflag(res)
+ isctest.check.rr_count_eq(res.answer, 2)
+
+ isctest.log.info("checking for query history on victim nameserver")
+ with open("ns2/named.run", "r", encoding="utf-8") as f:
+ assert "(victim.test): query 'victim.test/SOA/IN' approved" in f.read()
--
2.55.0

View file

@ -1,277 +0,0 @@
From 72967445f37a01d28b4ecb0e8f907e22fddd5087 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ayd=C4=B1n=20Mercan?= <aydin@isc.org>
Date: Thu, 7 May 2026 18:59:20 +0300
Subject: [PATCH] Reject out-of-zone NSEC next owner names
When verifying DNSSEC records, make sure that a next owner name of
an NSEC record is a subdomain of the signer field.
This follows the specification RFC 4034, section 4.1.1:
Owner names of RRsets for which the given zone is not authoritative
(such as glue records) MUST NOT be listed in the Next Domain Name
unless at least one authoritative RRset exists at the same owner
name.
While the above paragraph is intended for glue records, it also
applies to out-of-zone data.
(cherry picked from commit 4065512d25b71605b9502bb69dfb903776d35aa9)
(cherry picked from commit 058023c66f11d78590d4aa8c4f98946c4c965e21)
change dns_nsec_requiredtypespresent to dns_nsec_is_legal
Change `dns_nsec_requiredtypespresent` to `dns_nsec_is_legal` as a
function for checking multiple NSEC validity rules.
Currently we now additionally check for out-of-zone NSEC entries.
(cherry picked from commit be2a6a497312469890b552907d039d2de0b44ccc)
(cherry picked from commit f751e19a30d107f04c2f644aff9f8dab8fed03ab)
---
lib/dns/dnssec.c | 13 ++++++++++
lib/dns/include/dns/dnssec.h | 6 +++++
lib/dns/include/dns/nsec.h | 18 ++++++++++----
lib/dns/nsec.c | 17 ++++++++++---
lib/dns/resolver.c | 48 ++++++++++++++++++++++++++++++++++--
lib/ns/query.c | 6 ++---
6 files changed, 94 insertions(+), 14 deletions(-)
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index 9b9b1f2bb2..5acaea9ecb 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -357,8 +357,10 @@ isc_result_t
dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
bool ignoretime, unsigned int maxbits, isc_mem_t *mctx,
dns_rdata_t *sigrdata, dns_name_t *wild) {
+ dns_rdata_nsec_t nsec;
dns_rdata_rrsig_t sig;
dns_fixedname_t fnewname;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
isc_region_t r;
isc_buffer_t envbuf;
dns_rdata_t *rdatas;
@@ -464,6 +466,17 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
}
break;
}
+ /*
+ * Check for out of zone NSEC entries.
+ */
+ if (set->type == dns_rdatatype_nsec) {
+ RETERR(dns_rdataset_first(set));
+ dns_rdataset_current(set, &rdata);
+ RETERR(dns_rdata_tostruct(&rdata, &nsec, NULL));
+ if (!dns_name_issubdomain(&nsec.next, &sig.signer)) {
+ return DNS_R_NOVALIDNSEC;
+ }
+ }
again:
ret = dst_context_create(key, mctx, DNS_LOGCATEGORY_DNSSEC, false,
diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h
index cb8fd9dc20..2be11b9144 100644
--- a/lib/dns/include/dns/dnssec.h
+++ b/lib/dns/include/dns/dnssec.h
@@ -151,6 +151,9 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
* this record, as this requires a resolver or database.
* If 'ignoretime' is true, temporal validity will not be checked.
*
+ * If 'set' is of type NSEC, this function also verifies that the
+ * Next Name is a subdomain of the Signer's Name from 'sigrdata'.
+ *
* 'maxbits' specifies the maximum number of rsa exponent bits accepted.
*
* Requires:
@@ -173,6 +176,9 @@ dns_dnssec_verify(const dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
*\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data (either
* it is not a zone key or its flags prevent
* authentication)
+ *
+ *\li #DNS_R_NOVALIDNSEC - the NSEC rdata is not valid
+ *\li #DNS_R_KEYUNAUTHORIZED - the key cannot sign this data
*\li DST_R_*
*/
diff --git a/lib/dns/include/dns/nsec.h b/lib/dns/include/dns/nsec.h
index 50df8e45f1..1e71bf14e8 100644
--- a/lib/dns/include/dns/nsec.h
+++ b/lib/dns/include/dns/nsec.h
@@ -119,13 +119,21 @@ dns_nsec_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
*/
bool
-dns_nsec_requiredtypespresent(dns_rdataset_t *rdataset);
-/*
- * Return true if all the NSEC records in rdataset have both
- * NSEC and RRSIG present.
+dns_nsec_is_legal(dns_rdataset_t *rdataset, const dns_name_t *name);
+/**<
+ * \brief
+ * Validates a rdataset of type NSEC.
*
- * Requires:
+ * This functions checks for the following in the given rdataset:
+ * \li All NSEC records have both NSEC and RRSIG present
+ * \li All NSEC entries are under the `name`
+ *
+ * \par Requires:
* \li rdataset to be a NSEC rdataset.
+ * \li `name` is a valid dns_name_t
+ *
+ * \retval true if all the checks pass
+ * \retval false otherwise
*/
ISC_LANG_ENDDECLS
diff --git a/lib/dns/nsec.c b/lib/dns/nsec.c
index 80ee8d7d58..5abcce5f7f 100644
--- a/lib/dns/nsec.c
+++ b/lib/dns/nsec.c
@@ -21,6 +21,7 @@
#include <isc/util.h>
#include <dns/db.h>
+#include <dns/name.h>
#include <dns/nsec.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
@@ -497,8 +498,9 @@ dns_nsec_noexistnodata(dns_rdatatype_t type, const dns_name_t *name,
}
bool
-dns_nsec_requiredtypespresent(dns_rdataset_t *nsecset) {
- dns_rdataset_t rdataset;
+dns_nsec_is_legal(dns_rdataset_t *nsecset, const dns_name_t *name) {
+ dns_rdataset_t rdataset = DNS_RDATASET_INIT;
+ dns_rdata_nsec_t nsec;
isc_result_t result;
bool found = false;
@@ -513,12 +515,19 @@ dns_nsec_requiredtypespresent(dns_rdataset_t *nsecset) {
{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdataset_current(&rdataset, &rdata);
- if (!dns_nsec_typepresent(&rdata, dns_rdatatype_nsec) ||
- !dns_nsec_typepresent(&rdata, dns_rdatatype_rrsig))
+
+ /* must never fail */
+ result = dns_rdata_tostruct(&rdata, &nsec, NULL);
+ INSIST(result == ISC_R_SUCCESS);
+
+ if (!dns_name_issubdomain(&nsec.next, name) ||
+ !dns_nsec_typepresent(&rdata, dns_rdatatype_rrsig) ||
+ !dns_nsec_typepresent(&rdata, dns_rdatatype_nsec))
{
dns_rdataset_disassociate(&rdataset);
return false;
}
+
found = true;
}
dns_rdataset_disassociate(&rdataset);
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 059ce53a9e..eac67f7a19 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -65,7 +65,9 @@
#include <dns/rootns.h>
#include <dns/stats.h>
#include <dns/tsig.h>
+#include <dns/types.h>
#include <dns/validator.h>
+#include <dns/view.h>
#include <dns/zone.h>
/* Detailed logging of fctx attach/detach */
@@ -5603,6 +5605,36 @@ fctx_setresult(fetchctx_t *fctx, dns_rdataset_t *rdataset) {
return result;
}
+static bool
+get_and_check_signer_name(dns_name_t *signer, dns_rdataset_t *sigrdataset) {
+ dns_rdata_rrsig_t rrsig;
+ isc_result_t result;
+ dns_rdata_t rdata;
+
+ if (dns_rdataset_first(sigrdataset) != ISC_R_SUCCESS) {
+ return false;
+ }
+
+ rdata = (dns_rdata_t)DNS_RDATA_INIT;
+ dns_rdataset_current(sigrdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
+ INSIST(result == ISC_R_SUCCESS);
+ dns_name_copy(&rrsig.signer, signer);
+
+ while (dns_rdataset_next(sigrdataset) == ISC_R_SUCCESS) {
+ rdata = (dns_rdata_t)DNS_RDATA_INIT;
+ dns_rdataset_current(sigrdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
+ INSIST(result == ISC_R_SUCCESS);
+
+ if (!dns_name_equal(signer, &rrsig.signer)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
/*
* The validator has finished.
*/
@@ -5633,6 +5665,8 @@ validated(isc_task_t *task, isc_event_t *event) {
dns_fixedname_t fwild;
dns_name_t *wild = NULL;
dns_message_t *message = NULL;
+ dns_fixedname_t fsigner;
+ dns_name_t *signer = NULL;
UNUSED(task); /* for now */
@@ -6021,10 +6055,20 @@ answer_response:
}
/*
- * Don't cache NSEC if missing NSEC or RRSIG types.
+ * Don't cache if all the RRSIGs don't have the same
+ * signer.
+ */
+ signer = dns_fixedname_initname(&fsigner);
+ if (!get_and_check_signer_name(signer, sigrdataset)) {
+ continue;
+ }
+
+ /*
+ * Don't cache NSEC if missing NSEC or RRSIG
+ * types.
*/
if (rdataset->type == dns_rdatatype_nsec &&
- !dns_nsec_requiredtypespresent(rdataset))
+ !dns_nsec_is_legal(rdataset, signer))
{
continue;
}
diff --git a/lib/ns/query.c b/lib/ns/query.c
index 2a2ba1daba..8bbcd7ff30 100644
--- a/lib/ns/query.c
+++ b/lib/ns/query.c
@@ -10370,10 +10370,10 @@ query_coveringnsec(query_ctx_t *qctx) {
}
/*
- * If NSEC or RRSIG are missing from the type map
- * reject the NSEC RRset.
+ * Check that the NSEC entry is legal.
+ * (NSEC + RRSIG present and the entry isn't out-of-zone)
*/
- if (!dns_nsec_requiredtypespresent(qctx->rdataset)) {
+ if (!dns_nsec_is_legal(qctx->rdataset, signer)) {
goto cleanup;
}
--
2.55.0

View file

@ -1,76 +0,0 @@
From 12f50726b6bd8f6b3ed6709695e0f6893bc865c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Tue, 16 Sep 2025 11:46:03 +0200
Subject: [PATCH] Fix expectations on idna system test
IDNA tests always redirect output into the file. That means its
behaviour has changed and is now processing IDN input by default and
just disables IDN output by default.
New behaviour when redirected is the same as +idnin +noidnout, but does
not fail hard on input errors.
---
bin/tests/system/idna/tests.sh | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/bin/tests/system/idna/tests.sh b/bin/tests/system/idna/tests.sh
index 398b7e1..37f02b1 100644
--- a/bin/tests/system/idna/tests.sh
+++ b/bin/tests/system/idna/tests.sh
@@ -194,7 +194,7 @@ idna_enabled_test() {
# Note that ASCII characters are converted to lower-case.
text="Checking valid non-ASCII label"
- idna_test "$text" "" "München" "M\195\188nchen."
+ idna_test "$text" "" "München" "xn--mnchen-3ya."
idna_test "$text" "+noidnin +noidnout" "München" "M\195\188nchen."
idna_test "$text" "+noidnin +idnout" "München" "M\195\188nchen."
idna_test "$text" "+idnin +noidnout" "München" "xn--mnchen-3ya."
@@ -218,7 +218,7 @@ idna_enabled_test() {
# for the valid U-label.
text="Checking that non-transitional IDNA processing is used"
- idna_test "$text" "" "faß.de" "fa\195\159.de."
+ idna_test "$text" "" "faß.de" "xn--fa-hia.de."
idna_test "$text" "+noidnin +noidnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+noidnin +idnout" "faß.de" "fa\195\159.de."
idna_test "$text" "+idnin +noidnout" "faß.de" "xn--fa-hia.de."
@@ -228,7 +228,7 @@ idna_enabled_test() {
# onto the Greek sigma character ("σ") in IDNA2003.
text="Second check that non-transitional IDNA processing is used"
- idna_test "$text" "" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
+ idna_test "$text" "" "βόλος.com" "xn--nxasmm1c.com."
idna_test "$text" "+noidnin +noidnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+noidnin +idnout" "βόλος.com" "\206\178\207\140\206\187\206\191\207\130.com."
idna_test "$text" "+idnin +noidnout" "βόλος.com" "xn--nxasmm1c.com."
@@ -288,7 +288,7 @@ idna_enabled_test() {
idna_test "$text" "" "xn--xx" "xn--xx."
idna_test "$text" "+noidnin +noidnout" "xn--xx" "xn--xx."
idna_fail "$text" "+noidnin +idnout" "xn--xx"
- idna_fail "$text" "+idnin +noidnout" "xn--xx"
+ idna_test "$text" "+idnin +noidnout" "xn--xx" "xn--xx."
idna_fail "$text" "+idnin +idnout" "xn--xx"
# Fake A-label - the string does not translate to anything.
@@ -297,7 +297,7 @@ idna_enabled_test() {
idna_test "$text" "" "xn--ahahah" "xn--ahahah."
idna_test "$text" "+noidnin +noidnout" "xn--ahahah" "xn--ahahah."
idna_fail "$text" "+noidnin +idnout" "xn--ahahah"
- idna_fail "$text" "+idnin +noidnout" "xn--ahahah"
+ idna_test "$text" "+idnin +noidnout" "xn--ahahah" "xn--ahahah."
idna_fail "$text" "+idnin +idnout" "xn--ahahah"
# Too long a label. The punycode string is too long (at 64 characters).
@@ -324,7 +324,7 @@ idna_enabled_test() {
# The +[no]idnout options should not have any effect on the test.
text="Checking invalid input U-label"
- idna_test "$text" "" "√.com" "\226\136\154.com."
+ idna_test "$text" "" "√.com" "xn--19g.com."
idna_test "$text" "+noidnin +noidnout" "√.com" "\226\136\154.com."
idna_test "$text" "+noidnin +idnout" "√.com" "\226\136\154.com."
idna_test "$text" "+idnin +noidnout" "√.com" "xn--19g.com."
--
2.51.0

View file

@ -1,98 +0,0 @@
From fcc50604359a05e24003f3ff51c3812d8f307814 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Wed, 6 Nov 2024 21:29:47 +0100
Subject: [PATCH] Allow always IDN input in dig
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Even when stdout is non-interactive terminal, allow unicode characters
to be encoded into ACE form. Still disable IDN output, but unless
+noidnin or IDN_DISABLE=1 env is detected, consider input as locale
defined name.
Provides more isolated change, which issue #3527 introduced similar
behavior into 9.19 with more changes.
Ignore input IDN errors when stdout is not terminal
Attempt to prevent visible regressions when enabling IDN on input
always. Instead of new hard failures preventing IDN decoding of input
name just use original input.
Should make the change backward compatible. When on interactive terminal
behave the same way as before and emit hard errors. Become more
forgiving in scripts where stdout leads to script. Decoding output is
not enabled there and if input decoding fails, just use input as it was.
Change dig manual +idnin
Note in manual IDN input is always enabled. But it silently ignores
errors when stdout is not a terminal to prevent regressions.
Signed-off-by: Petr Menšík <pemensik@redhat.com>
---
bin/dig/dig.rst | 5 ++---
bin/dig/dighost.c | 16 ++++++++++++----
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/bin/dig/dig.rst b/bin/dig/dig.rst
index 88b0a40307..e2bf3764d3 100644
--- a/bin/dig/dig.rst
+++ b/bin/dig/dig.rst
@@ -453,9 +453,8 @@ abbreviation is unambiguous; for example, :option:`+cd` is equivalent to
This option processes [or does not process] IDN domain names on input. This requires
``IDN SUPPORT`` to have been enabled at compile time.
- The default is to process IDN input when standard output is a tty.
- The IDN processing on input is disabled when :program:`dig` output is redirected
- to files, pipes, and other non-tty file descriptors.
+ The default is to process IDN input. The input IDN processing errors are ignored
+ when :program:`dig` output is redirected to files, pipes, and other non-tty file descriptors.
.. option:: +idnout, +noidnout
diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 0f8ac1335c..1307346192 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -604,7 +604,7 @@ dig_lookup_t *
make_empty_lookup(void) {
dig_lookup_t *looknew;
#ifdef HAVE_LIBIDN2
- bool idn_allowed = isatty(1) ? (getenv("IDN_DISABLE") == NULL) : false;
+ bool idn_allowed = (getenv("IDN_DISABLE") == NULL);
#endif /* HAVE_LIBIDN2 */
debug("make_empty_lookup()");
@@ -623,7 +623,7 @@ make_empty_lookup(void) {
.badcookie = true,
#ifdef HAVE_LIBIDN2
.idnin = idn_allowed,
- .idnout = idn_allowed,
+ .idnout = isatty(1) && idn_allowed,
#endif /* HAVE_LIBIDN2 */
.udpsize = -1,
.edns = -1,
@@ -4871,8 +4871,16 @@ idn_locale_to_ace(const char *src, char *dst, size_t dstlen) {
res = idn2_to_ascii_lz(src, &ascii_src, IDN2_TRANSITIONAL);
}
if (res != IDN2_OK) {
- fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnin",
- src, idn2_strerror(res));
+ if (isatty(1)) {
+ fatal("'%s' is not a legal IDNA2008 name (%s), use +noidnin",
+ src, idn2_strerror(res));
+ } else {
+ /* In case of non-terminal output silently ignore errors
+ * in IDN input decoding. */
+ (void)strlcpy(dst, src, dstlen);
+ resetlocale(LC_ALL);
+ return;
+ }
}
/*
--
2.50.1

View file

@ -1,54 +0,0 @@
From 3f686891729c7d39d879e8b5bb1aa17d874d265d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Thu, 19 Jun 2025 19:51:43 +0200
Subject: [PATCH] Limit number of additional records fetched
Limit number of started fetches for additional zone instead of doing
none. Keep limit of NS filled with additional records, but present at
least some if possible.
Might help broken implementations relying on receiving addresses in the
response for NS query in authoritative zone.
---
lib/dns/rdataset.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c
index 532e49a..bfa8e37 100644
--- a/lib/dns/rdataset.c
+++ b/lib/dns/rdataset.c
@@ -581,6 +581,7 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
size_t limit) {
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
+ size_t n = 0;
/*
* For each rdata in rdataset, call 'add' for each name and type in the
@@ -590,10 +591,6 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
REQUIRE(DNS_RDATASET_VALID(rdataset));
REQUIRE((rdataset->attributes & DNS_RDATASETATTR_QUESTION) == 0);
- if (limit != 0 && dns_rdataset_count(rdataset) > limit) {
- return DNS_R_TOOMANYRECORDS;
- }
-
result = dns_rdataset_first(rdataset);
if (result != ISC_R_SUCCESS) {
return result;
@@ -603,7 +600,11 @@ dns_rdataset_additionaldata(dns_rdataset_t *rdataset,
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_additionaldata(&rdata, owner_name, add, arg);
if (result == ISC_R_SUCCESS) {
- result = dns_rdataset_next(rdataset);
+ if (limit != 0 && ++n >= limit) {
+ result = DNS_R_TOOMANYRECORDS;
+ } else {
+ result = dns_rdataset_next(rdataset);
+ }
}
dns_rdata_reset(&rdata);
} while (result == ISC_R_SUCCESS);
--
2.50.1

View file

@ -1,897 +0,0 @@
From 5bd1369eb7781ad2b349b99f783a7ed07fb7d6ac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Thu, 13 Feb 2025 13:20:28 +0100
Subject: [PATCH] Backport OpenSSL 3 provider support
Use gist of 451edf324281d30fbbe5669223dcea331670847c and
5fd6cfc625aa84005618236f4cd699c07367a3dc upstream commits, but do not do
significant rebase together. Move engine loading of EVP_PKEY from label to
openssl_link and copy provider variant from newer.
Remove legacy RSA calls from _fromlabel to separate engine handling
code. Make rsa_check accepting EVP_PKEY pair only and use conditional
compilation to verify them. Move checking of max exponent bits to
rsa_check too, because it is done from all usages anyway.
Use rsa_check_legacy in places where bit checking is not necessary.
Fix keyfromlabel to not use engine parameter for provider keys
- Rework key checks to not require 'engine' tag, private key
is valid with 'label' tag alone
- Fix _fromlabel() functions to work with engine == NULL
- Update dst__openssl_fromlabel_engine() to do provider lookup
only when engine is not set
(cherry picked from commit de486d0ec5d5642ddb1820a1269f5406a2bb1c64)
Use dst_key_t label to signal isprivate property as a downstream
alternative to upstream commit 74361b0b6e5a6b17ebeea6afe1ca990395d7a6dd.
That would require additional heavier changes.
Downstream change:
Move RSA bits check to legacy, let it use rsa_check for newer
rsabigexponent tests got broken by this change.
---
lib/dns/dst_openssl.h | 4 +
lib/dns/dst_parse.c | 21 ++---
lib/dns/openssl_link.c | 161 +++++++++++++++++++++++++++-----
lib/dns/openssldh_link.c | 5 +
lib/dns/opensslecdsa_link.c | 109 +++++++++++-----------
lib/dns/openssleddsa_link.c | 40 +++-----
lib/dns/opensslrsa_link.c | 181 ++++++++++++++----------------------
7 files changed, 296 insertions(+), 225 deletions(-)
diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h
index 819af0f..cd386c0 100644
--- a/lib/dns/dst_openssl.h
+++ b/lib/dns/dst_openssl.h
@@ -64,4 +64,8 @@ ENGINE *
dst__openssl_getengine(const char *engine);
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
+isc_result_t
+dst__openssl_fromlabel(int key_base_id, const char *engine, const char *label,
+ const char *pin, EVP_PKEY **ppub, EVP_PKEY **ppriv);
+
ISC_LANG_ENDDECLS
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c
index a353b86..7f3fe51 100644
--- a/lib/dns/dst_parse.c
+++ b/lib/dns/dst_parse.c
@@ -195,10 +195,9 @@ check_rsa(const dst_private_t *priv, bool external) {
mask = (1ULL << TAG_SHIFT) - 1;
- if (have[TAG_RSA_ENGINE & mask]) {
+ if (have[TAG_RSA_LABEL & mask]) {
ok = have[TAG_RSA_MODULUS & mask] &&
- have[TAG_RSA_PUBLICEXPONENT & mask] &&
- have[TAG_RSA_LABEL & mask];
+ have[TAG_RSA_PUBLICEXPONENT & mask];
} else {
ok = have[TAG_RSA_MODULUS & mask] &&
have[TAG_RSA_PUBLICEXPONENT & mask] &&
@@ -259,11 +258,9 @@ check_ecdsa(const dst_private_t *priv, bool external) {
mask = (1ULL << TAG_SHIFT) - 1;
- if (have[TAG_ECDSA_ENGINE & mask]) {
- ok = have[TAG_ECDSA_LABEL & mask];
- } else {
- ok = have[TAG_ECDSA_PRIVATEKEY & mask];
- }
+ ok = have[TAG_ECDSA_LABEL & mask] ||
+ have[TAG_ECDSA_PRIVATEKEY & mask];
+
return ok ? 0 : -1;
}
@@ -295,11 +292,9 @@ check_eddsa(const dst_private_t *priv, bool external) {
mask = (1ULL << TAG_SHIFT) - 1;
- if (have[TAG_EDDSA_ENGINE & mask]) {
- ok = have[TAG_EDDSA_LABEL & mask];
- } else {
- ok = have[TAG_EDDSA_PRIVATEKEY & mask];
- }
+ ok = have[TAG_EDDSA_LABEL & mask] ||
+ have[TAG_EDDSA_PRIVATEKEY & mask];
+
return ok ? 0 : -1;
}
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
index e3a89f4..2495be4 100644
--- a/lib/dns/openssl_link.c
+++ b/lib/dns/openssl_link.c
@@ -44,6 +44,9 @@
#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
#include <openssl/engine.h>
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/store.h>
+#endif
#include "openssl_shim.h"
@@ -51,6 +54,12 @@
static ENGINE *e = NULL;
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
+#define DST_RET(a) \
+ { \
+ result = a; \
+ goto cleanup; \
+ }
+
static void
enable_fips_mode(void) {
#ifdef HAVE_FIPS_MODE
@@ -70,32 +79,28 @@ enable_fips_mode(void) {
isc_result_t
dst__openssl_init(const char *engine) {
- isc_result_t result = ISC_R_SUCCESS;
-
enable_fips_mode();
-#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
if (engine != NULL && *engine == '\0') {
engine = NULL;
}
- if (engine != NULL) {
- e = ENGINE_by_id(engine);
- if (e == NULL) {
- result = DST_R_NOENGINE;
- goto cleanup_rm;
- }
- if (!ENGINE_init(e)) {
- result = DST_R_NOENGINE;
- goto cleanup_rm;
- }
- /* This will init the engine. */
- if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
- result = DST_R_NOENGINE;
- goto cleanup_init;
- }
+ if (engine == NULL) {
+ return (ISC_R_SUCCESS);
}
+#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
+ e = ENGINE_by_id(engine);
+ if (e == NULL) {
+ goto cleanup_rm;
+ }
+ if (!ENGINE_init(e)) {
+ goto cleanup_rm;
+ }
+ /* This will init the engine. */
+ if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
+ goto cleanup_init;
+ }
return ISC_R_SUCCESS;
cleanup_init:
ENGINE_finish(e);
@@ -105,10 +110,8 @@ cleanup_rm:
}
e = NULL;
ERR_clear_error();
-#else
- UNUSED(engine);
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
- return result;
+ return (DST_R_NOENGINE);
}
void
@@ -220,4 +223,120 @@ dst__openssl_getengine(const char *engine) {
}
#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
+static isc_result_t
+dst__openssl_fromlabel_engine(int key_base_id, const char *engine,
+ const char *label,
+ EVP_PKEY **ppub, EVP_PKEY **ppriv) {
+#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
+ isc_result_t result = ISC_R_SUCCESS;
+ ENGINE *e = NULL;
+ EVP_PKEY *pkey = NULL, *pubpkey = NULL;
+
+ UNUSED(key_base_id);
+
+ e = dst__openssl_getengine(engine);
+ if (e == NULL) {
+ DST_RET(dst__openssl_toresult(DST_R_NOENGINE));
+ }
+
+ pubpkey = ENGINE_load_public_key(e, label, NULL, NULL);
+ if (pubpkey == NULL) {
+ DST_RET(dst__openssl_toresult2("ENGINE_load_public_key",
+ DST_R_OPENSSLFAILURE));
+ }
+ if (EVP_PKEY_get_base_id(pubpkey) != key_base_id) {
+ DST_RET(DST_R_BADKEYTYPE);
+ }
+ pkey = ENGINE_load_private_key(e, label, NULL, NULL);
+ if (pkey == NULL) {
+ DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
+ DST_R_OPENSSLFAILURE));
+ }
+ if (EVP_PKEY_base_id(pkey) != key_base_id) {
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ }
+ *ppub = pubpkey;
+ *ppriv = pkey;
+cleanup:
+ return result;
+#else
+ UNUSED(key_base_id);
+ UNUSED(engine);
+ UNUSED(label);
+ UNUSED(ppub);
+ UNUSED(ppriv);
+ return DST_R_NOENGINE;
+#endif
+}
+
+
+static isc_result_t
+dst__openssl_fromlabel_provider(int key_base_id, const char *label, const char *pin,
+ EVP_PKEY **ppub, EVP_PKEY **ppriv) {
+ UNUSED(pin);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+ isc_result_t result = DST_R_OPENSSLFAILURE;
+ OSSL_STORE_CTX *ctx = NULL;
+
+
+ ctx = OSSL_STORE_open(label, NULL, NULL, NULL, NULL);
+ if (!ctx) {
+ DST_RET(dst__openssl_toresult2("OSSL_STORE_open_ex",
+ DST_R_OPENSSLFAILURE));
+ }
+
+ while (!OSSL_STORE_eof(ctx)) {
+ OSSL_STORE_INFO *info = OSSL_STORE_load(ctx);
+ if (info == NULL) {
+ continue;
+ }
+ switch (OSSL_STORE_INFO_get_type(info)) {
+ case OSSL_STORE_INFO_PKEY:
+ if (*ppriv != NULL) {
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ }
+ *ppriv = OSSL_STORE_INFO_get1_PKEY(info);
+ if (EVP_PKEY_get_base_id(*ppriv) != key_base_id) {
+ DST_RET(DST_R_BADKEYTYPE);
+ }
+ break;
+ case OSSL_STORE_INFO_PUBKEY:
+ if (*ppub != NULL) {
+ DST_RET(DST_R_INVALIDPUBLICKEY);
+ }
+ *ppub = OSSL_STORE_INFO_get1_PUBKEY(info);
+ if (EVP_PKEY_get_base_id(*ppub) != key_base_id) {
+ DST_RET(DST_R_BADKEYTYPE);
+ }
+ break;
+ }
+ OSSL_STORE_INFO_free(info);
+ }
+ if (*ppriv != NULL && *ppub != NULL) {
+ result = ISC_R_SUCCESS;
+ }
+cleanup:
+ OSSL_STORE_close(ctx);
+ return result;
+#else
+ UNUSED(key_base_id);
+ UNUSED(label);
+ UNUSED(ppub);
+ UNUSED(ppriv);
+ return (DST_R_OPENSSLFAILURE);
+#endif
+}
+
+isc_result_t
+dst__openssl_fromlabel(int key_base_id, const char *engine, const char *label,
+ const char *pin, EVP_PKEY **ppub, EVP_PKEY **ppriv) {
+ if (engine == NULL) {
+ return (dst__openssl_fromlabel_provider(key_base_id, label,
+ pin, ppub, ppriv));
+ }
+
+ return (dst__openssl_fromlabel_engine(key_base_id, engine, label,
+ ppub, ppriv));
+}
+
/*! \file */
diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c
index a4ba0f7..38345e6 100644
--- a/lib/dns/openssldh_link.c
+++ b/lib/dns/openssldh_link.c
@@ -610,6 +610,11 @@ err:
static bool
openssldh_isprivate(const dst_key_t *key) {
+ if (key->label != NULL) {
+ /* assume that _fromlabel will not pass without loading private key,
+ * but for non-exportable key cannot get d value on the object. */
+ return true;
+ }
#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000
DH *dh = key->keydata.dh;
const BIGNUM *priv_key = NULL;
diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c
index af45fdc..8b49b5d 100644
--- a/lib/dns/opensslecdsa_link.c
+++ b/lib/dns/opensslecdsa_link.c
@@ -617,6 +617,12 @@ opensslecdsa_isprivate(const dst_key_t *key) {
return false;
}
+ if (key->label != NULL) {
+ /* assume that _fromlabel will not pass without loading private key,
+ * but for non-exportable key cannot get d value on the object. */
+ return true;
+ }
+
#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000
eckey = EVP_PKEY_get1_EC_KEY(pkey);
@@ -916,7 +922,7 @@ cleanup:
#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000
static isc_result_t
-ecdsa_check(EC_KEY *eckey, EC_KEY *pubeckey) {
+ecdsa_check_legacy(EC_KEY *eckey, EC_KEY *pubeckey) {
const EC_POINT *pubkey;
pubkey = EC_KEY_get0_public_key(eckey);
@@ -937,9 +943,42 @@ ecdsa_check(EC_KEY *eckey, EC_KEY *pubeckey) {
return ISC_R_FAILURE;
}
+
+static isc_result_t
+ecdsa_check(EVP_PKEY **pkey, EVP_PKEY *pubpkey, int group_nid) {
+ isc_result_t result = ISC_R_FAILURE;
+ EC_KEY *eckey;
+ EC_KEY *pubeckey;
+
+ eckey = EVP_PKEY_get1_EC_KEY(*pkey);
+ if (eckey == NULL) {
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ }
+ if (EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)) != group_nid) {
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ }
+
+ pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey);
+ if (pubeckey == NULL) {
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ }
+ if (EC_GROUP_get_curve_name(EC_KEY_get0_group(pubeckey)) != group_nid) {
+ DST_RET(DST_R_INVALIDPUBLICKEY);
+ }
+
+ CHECK(ecdsa_check_legacy(eckey, pubeckey));
+cleanup:
+ if (pubeckey != NULL) {
+ EC_KEY_free(pubeckey);
+ }
+ if (eckey != NULL) {
+ EC_KEY_free(eckey);
+ }
+ return result;
+}
#else
static isc_result_t
-ecdsa_check(EVP_PKEY **pkey, EVP_PKEY *pubpkey) {
+ecdsa_check(EVP_PKEY **pkey, EVP_PKEY *pubpkey, int group_nid) {
isc_result_t result = ISC_R_FAILURE;
int status;
size_t pkey_len = 0;
@@ -954,6 +993,8 @@ ecdsa_check(EVP_PKEY **pkey, EVP_PKEY *pubpkey) {
EVP_PKEY_CTX *ctx = NULL;
EVP_PKEY *pkey_new = NULL;
+ UNUSED(group_nid);
+
/* Check if `pkey` has a public key. */
status = EVP_PKEY_get_octet_string_param(*pkey, OSSL_PKEY_PARAM_PUB_KEY,
NULL, 0, &pkey_len);
@@ -1267,7 +1308,7 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
pubeckey = EVP_PKEY_get1_EC_KEY(pub->keydata.pkey);
}
- if (ecdsa_check(eckey, pubeckey) != ISC_R_SUCCESS) {
+ if (ecdsa_check_legacy(eckey, pubeckey) != ISC_R_SUCCESS) {
DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
}
@@ -1276,7 +1317,7 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
}
#else
if (ecdsa_check(&key->keydata.pkey,
- pub == NULL ? NULL : pub->keydata.pkey) !=
+ pub == NULL ? NULL : pub->keydata.pkey, NID_undef) !=
ISC_R_SUCCESS)
{
DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
@@ -1309,11 +1350,7 @@ cleanup:
static isc_result_t
opensslecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
const char *pin) {
-#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
isc_result_t result = ISC_R_SUCCESS;
- ENGINE *e;
- EC_KEY *eckey = NULL;
- EC_KEY *pubeckey = NULL;
int group_nid;
EVP_PKEY *pkey = NULL;
EVP_PKEY *pubpkey = NULL;
@@ -1323,13 +1360,9 @@ opensslecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
UNUSED(pin);
- if (engine == NULL || label == NULL) {
+ if (label == NULL) {
return DST_R_NOENGINE;
}
- e = dst__openssl_getengine(engine);
- if (e == NULL) {
- DST_RET(DST_R_NOENGINE);
- }
if (key->key_alg == DST_ALG_ECDSA256) {
group_nid = NID_X9_62_prime256v1;
@@ -1337,48 +1370,27 @@ opensslecdsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
group_nid = NID_secp384r1;
}
- /* Load private key. */
- pkey = ENGINE_load_private_key(e, label, NULL, NULL);
- if (pkey == NULL) {
- DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
- DST_R_OPENSSLFAILURE));
- }
+ CHECK(dst__openssl_fromlabel(EVP_PKEY_EC, engine, label, pin,
+ &pubpkey, &pkey));
+
/* Check base id, group nid */
if (EVP_PKEY_base_id(pkey) != EVP_PKEY_EC) {
DST_RET(DST_R_INVALIDPRIVATEKEY);
}
- eckey = EVP_PKEY_get1_EC_KEY(pkey);
- if (eckey == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
- if (EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)) != group_nid) {
- DST_RET(DST_R_INVALIDPRIVATEKEY);
- }
-
- /* Load public key. */
- pubpkey = ENGINE_load_public_key(e, label, NULL, NULL);
- if (pubpkey == NULL) {
- DST_RET(dst__openssl_toresult2("ENGINE_load_public_key",
- DST_R_OPENSSLFAILURE));
- }
/* Check base id, group nid */
if (EVP_PKEY_base_id(pubpkey) != EVP_PKEY_EC) {
DST_RET(DST_R_INVALIDPUBLICKEY);
}
- pubeckey = EVP_PKEY_get1_EC_KEY(pubpkey);
- if (pubeckey == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
- if (EC_GROUP_get_curve_name(EC_KEY_get0_group(pubeckey)) != group_nid) {
- DST_RET(DST_R_INVALIDPUBLICKEY);
- }
- if (ecdsa_check(eckey, pubeckey) != ISC_R_SUCCESS) {
+ if (ecdsa_check(&pkey, pubpkey, group_nid) != ISC_R_SUCCESS) {
DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
}
+ if (engine != NULL)
+ key->engine = isc_mem_strdup(key->mctx, engine);
+ else
+ key->engine = NULL;
key->label = isc_mem_strdup(key->mctx, label);
- key->engine = isc_mem_strdup(key->mctx, engine);
key->key_size = EVP_PKEY_bits(pkey);
key->keydata.pkey = pkey;
pkey = NULL;
@@ -1390,21 +1402,8 @@ cleanup:
if (pkey != NULL) {
EVP_PKEY_free(pkey);
}
- if (pubeckey != NULL) {
- EC_KEY_free(pubeckey);
- }
- if (eckey != NULL) {
- EC_KEY_free(eckey);
- }
return result;
-#else
- UNUSED(key);
- UNUSED(engine);
- UNUSED(label);
- UNUSED(pin);
- return DST_R_NOENGINE;
-#endif /* !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
}
static dst_func_t opensslecdsa_functions = {
diff --git a/lib/dns/openssleddsa_link.c b/lib/dns/openssleddsa_link.c
index 6301db4..08d505b 100644
--- a/lib/dns/openssleddsa_link.c
+++ b/lib/dns/openssleddsa_link.c
@@ -362,6 +362,12 @@ openssleddsa_isprivate(const dst_key_t *key) {
return false;
}
+ if (key->label != NULL) {
+ /* assume that _fromlabel will not pass without loading private key,
+ * but for non-exportable key cannot get d value on the object. */
+ return true;
+ }
+
/* Must have a buffer to actually check if there is a private key. */
if (EVP_PKEY_get_raw_private_key(pkey, buf, &len) == 1) {
return true;
@@ -591,9 +597,7 @@ cleanup:
static isc_result_t
openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
const char *pin) {
-#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
isc_result_t result;
- ENGINE *e;
EVP_PKEY *pkey = NULL, *pubpkey = NULL;
int baseid = EVP_PKEY_NONE;
@@ -616,28 +620,17 @@ openssleddsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
return ISC_R_NOTIMPLEMENTED;
}
- if (engine == NULL) {
- return DST_R_NOENGINE;
- }
- e = dst__openssl_getengine(engine);
- if (e == NULL) {
- return DST_R_NOENGINE;
- }
- pkey = ENGINE_load_private_key(e, label, NULL, NULL);
- if (pkey == NULL) {
- return dst__openssl_toresult2("ENGINE_load_private_key",
- ISC_R_NOTFOUND);
- }
- if (EVP_PKEY_base_id(pkey) != baseid) {
- DST_RET(DST_R_INVALIDPRIVATEKEY);
- }
+ DST_RET(dst__openssl_fromlabel(baseid, engine, label, pin,
+ &pubpkey, &pkey));
- pubpkey = ENGINE_load_public_key(e, label, NULL, NULL);
- if (eddsa_check(pkey, pubpkey) != ISC_R_SUCCESS) {
+ if (EVP_PKEY_base_id(pkey) != baseid) {
DST_RET(DST_R_INVALIDPRIVATEKEY);
}
- key->engine = isc_mem_strdup(key->mctx, engine);
+ if (engine != NULL)
+ key->engine = isc_mem_strdup(key->mctx, engine);
+ else
+ key->engine = NULL;
key->label = isc_mem_strdup(key->mctx, label);
key->key_size = EVP_PKEY_bits(pkey);
key->keydata.pkey = pkey;
@@ -652,13 +645,6 @@ cleanup:
EVP_PKEY_free(pkey);
}
return result;
-#else /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
- UNUSED(key);
- UNUSED(engine);
- UNUSED(label);
- UNUSED(pin);
- return DST_R_NOENGINE;
-#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
}
static dst_func_t openssleddsa_functions = {
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c
index b92e1bf..12210e8 100644
--- a/lib/dns/opensslrsa_link.c
+++ b/lib/dns/opensslrsa_link.c
@@ -545,6 +545,12 @@ opensslrsa_isprivate(const dst_key_t *key) {
return false;
}
+ if (key->label != NULL) {
+ /* assume that _fromlabel will not pass without loading private key,
+ * but for non-exportable key cannot get d value on the object. */
+ return true;
+ }
+
#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000
rsa = EVP_PKEY_get1_RSA(pkey);
INSIST(rsa != NULL);
@@ -995,7 +1001,7 @@ cleanup:
#if OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000
static isc_result_t
-rsa_check(RSA *rsa, RSA *pub) {
+rsa_check_legacy(RSA *rsa, RSA *pub) {
const BIGNUM *n1 = NULL, *n2 = NULL;
const BIGNUM *e1 = NULL, *e2 = NULL;
BIGNUM *n = NULL, *e = NULL;
@@ -1050,6 +1056,46 @@ rsa_check(RSA *rsa, RSA *pub) {
return ISC_R_SUCCESS;
}
+
+static isc_result_t
+rsa_check(EVP_PKEY *pkey, EVP_PKEY *pubpkey) {
+ isc_result_t ret = ISC_R_FAILURE;
+ RSA *rsa = NULL, *pubrsa = NULL;
+ const BIGNUM *ex = NULL;
+
+ pubrsa = EVP_PKEY_get1_RSA(pubpkey);
+ if (pubrsa == NULL) {
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ }
+
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ if (rsa == NULL) {
+ DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ }
+
+ ret = rsa_check_legacy(rsa, pubrsa);
+ if (ret != ISC_R_SUCCESS) {
+ DST_RET(ret);
+ }
+
+ RSA_get0_key(rsa, NULL, &ex, NULL);
+
+ if (ex == NULL) {
+ DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
+ }
+ if (BN_num_bits(ex) > RSA_MAX_PUBEXP_BITS) {
+ DST_RET(ISC_R_RANGE);
+ }
+
+err:
+ if (rsa != NULL) {
+ RSA_free(rsa);
+ }
+ if (pubrsa != NULL) {
+ RSA_free(pubrsa);
+ }
+ return ret;
+}
#else
static isc_result_t
rsa_check(EVP_PKEY *pkey, EVP_PKEY *pubpkey) {
@@ -1097,6 +1143,10 @@ rsa_check(EVP_PKEY *pkey, EVP_PKEY *pubpkey) {
}
}
+ if (BN_num_bits(e1) > RSA_MAX_PUBEXP_BITS) {
+ DST_RET(ISC_R_RANGE);
+ }
+
if (EVP_PKEY_eq(pkey, pubpkey) == 1) {
DST_RET(ISC_R_SUCCESS);
}
@@ -1119,6 +1169,10 @@ cleanup:
}
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */
+static isc_result_t
+opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
+ const char *pin);
+
static isc_result_t
opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
dst_private_t priv;
@@ -1131,12 +1185,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
OSSL_PARAM *params = NULL;
EVP_PKEY_CTX *ctx = NULL;
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */
-#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
- const BIGNUM *ex = NULL;
- ENGINE *ep = NULL;
- const char *engine = NULL;
-#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
isc_mem_t *mctx = NULL;
+ const char *engine = NULL;
const char *label = NULL;
EVP_PKEY *pkey = NULL;
BIGNUM *n = NULL, *e = NULL, *d = NULL;
@@ -1190,46 +1240,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
* See if we can fetch it.
*/
if (label != NULL) {
-#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
- if (engine == NULL) {
- DST_RET(DST_R_NOENGINE);
- }
- ep = dst__openssl_getengine(engine);
- if (ep == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_NOENGINE));
- }
- pkey = ENGINE_load_private_key(ep, label, NULL, NULL);
- if (pkey == NULL) {
- DST_RET(dst__openssl_toresult2("ENGINE_load_private_"
- "key",
- ISC_R_NOTFOUND));
- }
- key->engine = isc_mem_strdup(key->mctx, engine);
- key->label = isc_mem_strdup(key->mctx, label);
-
- rsa = EVP_PKEY_get1_RSA(pkey);
- if (rsa == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
- if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) {
- DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
- }
- RSA_get0_key(rsa, NULL, &ex, NULL);
-
- if (ex == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
- }
- if (BN_num_bits(ex) > RSA_MAX_PUBEXP_BITS) {
- DST_RET(ISC_R_RANGE);
- }
-
- key->key_size = EVP_PKEY_bits(pkey);
- key->keydata.pkey = pkey;
- pkey = NULL;
- DST_RET(ISC_R_SUCCESS);
-#else /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
- DST_RET(DST_R_NOENGINE);
-#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
+ DST_RET(opensslrsa_fromlabel(key, engine, label, NULL));
}
for (i = 0; i < priv.nelements; i++) {
@@ -1318,9 +1329,14 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
BN_clear_free(iqmp);
}
}
- if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) {
+ if (rsa_check_legacy(rsa, pubrsa) != ISC_R_SUCCESS) {
DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
}
+
+ if (BN_num_bits(e) > RSA_MAX_PUBEXP_BITS) {
+ DST_RET(ISC_R_RANGE);
+ }
+
#else
bld = OSSL_PARAM_BLD_new();
if (bld == NULL) {
@@ -1387,17 +1403,9 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
- if (rsa_check(pkey, pub != NULL ? pub->keydata.pkey : NULL) !=
- ISC_R_SUCCESS)
- {
- DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
- }
+ CHECK(rsa_check(pkey, pub != NULL ? pub->keydata.pkey : NULL));
#endif /* OPENSSL_VERSION_NUMBER < 0x30000000L || OPENSSL_API_LEVEL < 30000 */
- if (BN_num_bits(e) > RSA_MAX_PUBEXP_BITS) {
- DST_RET(ISC_R_RANGE);
- }
-
key->key_size = BN_num_bits(n);
key->keydata.pkey = pkey;
pkey = NULL;
@@ -1461,69 +1469,31 @@ cleanup:
static isc_result_t
opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
const char *pin) {
-#if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000
- ENGINE *e = NULL;
isc_result_t result = ISC_R_SUCCESS;
EVP_PKEY *pkey = NULL, *pubpkey = NULL;
- RSA *rsa = NULL, *pubrsa = NULL;
- const BIGNUM *ex = NULL;
UNUSED(pin);
- if (engine == NULL) {
- DST_RET(DST_R_NOENGINE);
- }
- e = dst__openssl_getengine(engine);
- if (e == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_NOENGINE));
- }
+ CHECK(dst__openssl_fromlabel(EVP_PKEY_RSA, engine, label, pin,
+ &pubpkey, &pkey));
+ CHECK(rsa_check(pkey, pubpkey));
- pubpkey = ENGINE_load_public_key(e, label, NULL, NULL);
- if (pubpkey == NULL) {
- DST_RET(dst__openssl_toresult2("ENGINE_load_public_key",
- DST_R_OPENSSLFAILURE));
- }
- pubrsa = EVP_PKEY_get1_RSA(pubpkey);
- if (pubrsa == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
-
- pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL) {
- DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
+ DST_RET(dst__openssl_toresult2("dst__openssl_fromlabel",
DST_R_OPENSSLFAILURE));
}
- key->engine = isc_mem_strdup(key->mctx, engine);
+ if (engine != NULL)
+ key->engine = isc_mem_strdup(key->mctx, engine);
+ else
+ key->engine = NULL;
key->label = isc_mem_strdup(key->mctx, label);
- rsa = EVP_PKEY_get1_RSA(pkey);
- if (rsa == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
- if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS) {
- DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
- }
- RSA_get0_key(rsa, NULL, &ex, NULL);
-
- if (ex == NULL) {
- DST_RET(dst__openssl_toresult(DST_R_INVALIDPRIVATEKEY));
- }
- if (BN_num_bits(ex) > RSA_MAX_PUBEXP_BITS) {
- DST_RET(ISC_R_RANGE);
- }
-
key->key_size = EVP_PKEY_bits(pkey);
key->keydata.pkey = pkey;
pkey = NULL;
cleanup:
- if (rsa != NULL) {
- RSA_free(rsa);
- }
- if (pubrsa != NULL) {
- RSA_free(pubrsa);
- }
if (pkey != NULL) {
EVP_PKEY_free(pkey);
}
@@ -1531,13 +1501,6 @@ cleanup:
EVP_PKEY_free(pubpkey);
}
return result;
-#else /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
- UNUSED(key);
- UNUSED(engine);
- UNUSED(label);
- UNUSED(pin);
- return DST_R_NOENGINE;
-#endif /* if !defined(OPENSSL_NO_ENGINE) && OPENSSL_API_LEVEL < 30000 */
}
static dst_func_t opensslrsa_functions = {
--
2.52.0

View file

@ -1,75 +0,0 @@
From 0f3a398fe813189c5dd56b0367a72c7b3f19504b Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Wed, 14 Sep 2022 13:06:24 +0200
Subject: [PATCH] Disable some often failing tests
Make those tests skipped in default build, when CI=true environment is
set. It is not clear why they fail mostly on COPR, but they do fail
often.
---
tests/isc/netmgr_test.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/tests/isc/netmgr_test.c b/tests/isc/netmgr_test.c
index 94e4bf7..7f9629c 100644
--- a/tests/isc/netmgr_test.c
+++ b/tests/isc/netmgr_test.c
@@ -1567,13 +1567,13 @@ stream_half_recv_half_send(void **state __attribute__((unused))) {
/* TCP */
ISC_RUN_TEST_IMPL(tcp_noop) { stream_noop(state); }
-ISC_RUN_TEST_IMPL(tcp_noresponse) { stream_noresponse(state); }
+ISC_RUN_TEST_IMPL(tcp_noresponse) { SKIP_IN_CI; stream_noresponse(state); }
ISC_RUN_TEST_IMPL(tcp_timeout_recovery) { stream_timeout_recovery(state); }
ISC_RUN_TEST_IMPL(tcp_recv_one) { stream_recv_one(state); }
-ISC_RUN_TEST_IMPL(tcp_recv_two) { stream_recv_two(state); }
+ISC_RUN_TEST_IMPL(tcp_recv_two) { SKIP_IN_CI; stream_recv_two(state); }
ISC_RUN_TEST_IMPL(tcp_recv_send) {
SKIP_IN_CI;
@@ -1623,6 +1623,7 @@ ISC_RUN_TEST_IMPL(tcp_recv_one_quota) {
}
ISC_RUN_TEST_IMPL(tcp_recv_two_quota) {
+ SKIP_IN_CI;
atomic_store(&check_listener_quota, true);
stream_recv_two(state);
}
@@ -1836,6 +1837,7 @@ ISC_RUN_TEST_IMPL(tcpdns_recv_two) {
isc_result_t result = ISC_R_SUCCESS;
isc_nmsocket_t *listen_sock = NULL;
+ SKIP_IN_CI;
atomic_store(&nsends, 2);
result = isc_nm_listentcpdns(listen_nm, &tcp_listen_addr,
@@ -2095,6 +2097,7 @@ ISC_RUN_TEST_IMPL(tls_recv_one) {
}
ISC_RUN_TEST_IMPL(tls_recv_two) {
+ SKIP_IN_CI;
stream_use_TLS = true;
stream_recv_two(state);
}
@@ -2160,6 +2163,7 @@ ISC_RUN_TEST_IMPL(tls_recv_one_quota) {
}
ISC_RUN_TEST_IMPL(tls_recv_two_quota) {
+ SKIP_IN_CI;
stream_use_TLS = true;
atomic_store(&check_listener_quota, true);
stream_recv_two(state);
@@ -2395,6 +2399,7 @@ ISC_RUN_TEST_IMPL(tlsdns_recv_two) {
isc_result_t result = ISC_R_SUCCESS;
isc_nmsocket_t *listen_sock = NULL;
+ SKIP_IN_CI;
atomic_store(&nsends, 2);
result = isc_nm_listentlsdns(listen_nm, &tcp_listen_addr,
--
2.37.2

View file

@ -1,114 +0,0 @@
From c5c756ce2ac4c1563d024428e148ca27c7721f71 Mon Sep 17 00:00:00 2001
From: Aram Sargsyan <aram@isc.org>
Date: Wed, 21 Sep 2022 15:05:11 +0000
Subject: [PATCH 2/3] Document nsupdate options related to DoT
Add documentation for the newly implemented DoT feature of the
nsupdate program.
(cherry picked from commit bd8299d7b501234263a6aee98049f879b1c700b7)
---
bin/nsupdate/nsupdate.rst | 48 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/bin/nsupdate/nsupdate.rst b/bin/nsupdate/nsupdate.rst
index 81bb4815cf4..f1ab5c76fa7 100644
--- a/bin/nsupdate/nsupdate.rst
+++ b/bin/nsupdate/nsupdate.rst
@@ -19,7 +19,7 @@ nsupdate - dynamic DNS update utility
Synopsis
~~~~~~~~
-:program:`nsupdate` [**-d**] [**-D**] [**-i**] [**-L** level] [ [**-g**] | [**-o**] | [**-l**] | [**-y** [hmac:]keyname:secret] | [**-k** keyfile] ] [**-t** timeout] [**-u** udptimeout] [**-r** udpretries] [**-v**] [**-T**] [**-P**] [**-V**] [ [**-4**] | [**-6**] ] [filename]
+:program:`nsupdate` [**-d**] [**-D**] [**-i**] [**-L** level] [ [**-g**] | [**-o**] | [**-l**] | [**-y** [hmac:]keyname:secret] | [**-k** keyfile] ] [ [**-S**] [**-K** tlskeyfile] [**-E** tlscertfile] [**-A** tlscafile] [**-H** tlshostname] [-O] ] [**-t** timeout] [**-u** udptimeout] [**-r** udpretries] [**-v**] [**-T**] [**-P**] [**-V**] [ [**-4**] | [**-6**] ] [filename]
Description
~~~~~~~~~~~
@@ -71,6 +71,15 @@ Options
This option sets use of IPv6 only.
+.. option:: -A tlscafile
+
+ This option specifies the file of the certificate authorities (CA) certificates
+ (in PEM format) in order to verify the remote server TLS certificate when
+ using DNS-over-TLS (DoT), to achieve Strict or Mutual TLS. When used, it will
+ override the certificates from the global certificates store, which are
+ otherwise used by default when :option:`-S` is enabled. This option can not
+ be used in conjuction with :option:`-O`, and it implies :option:`-S`.
+
.. option:: -C
Overrides the default `resolv.conf` file. This is only intended for testing.
@@ -84,10 +93,23 @@ Options
This option sets extra debug mode.
+.. option:: -E tlscertfile
+
+ This option sets the certificate(s) file for authentication for the
+ DNS-over-TLS (DoT) transport to the remote server. The certificate
+ chain file is expected to be in PEM format. This option implies :option:`-S`,
+ and can only be used with :option:`-K`.
+
.. option:: -g
This option enables standard GSS-TSIG mode.
+.. option:: -H tlshostname
+
+ This option makes :program:`nsupdate` use the provided hostname during remote
+ server TLS certificate verification. Otherwise, the DNS server name
+ is used. This option implies :option:`-S`.
+
.. option:: -i
This option forces interactive mode, even when standard input is not a terminal.
@@ -104,6 +126,13 @@ Options
key used to authenticate Dynamic DNS update requests. In this case,
the key specified is not an HMAC-MD5 key.
+.. option:: -K tlskeyfile
+
+ This option sets the key file for authenticated encryption for the
+ DNS-over-TLS (DoT) transport with the remote server. The private key file is
+ expected to be in PEM format. This option implies :option:`-S`, and can only
+ be used with :option:`-E`.
+
.. option:: -l
This option sets local-host only mode, which sets the server address to localhost
@@ -123,6 +152,14 @@ Options
This option enables a non-standards-compliant variant of GSS-TSIG
used by Windows 2000.
+.. option:: -O
+
+ This option enables Opportunistic TLS. When used, the remote peer's TLS
+ certificate will not be verified. This option should be used for debugging
+ purposes only, and it is not recommended to use it in production. This
+ option can not be used in conjuction with :option:`-A`, and it implies
+ :option:`-S`.
+
.. option:: -p port
This option sets the port to use for connections to a name server. The default is
@@ -138,6 +175,15 @@ Options
This option sets the number of UDP retries. The default is 3. If zero, only one update
request is made.
+.. option:: -S
+
+ This option indicates whether to use DNS-over-TLS (DoT) when querying
+ name servers specified by ``server servername port`` syntax in the input
+ file, and the primary server discovered through a SOA request. When the
+ :option:`-K` and :option:`-E` options are used, then the specified TLS
+ client certificate and private key pair are used for authentication
+ (Mutual TLS). This option implies :option:`-v`.
+
.. option:: -t timeout
This option sets the maximum time an update request can take before it is aborted. The
--
2.47.0

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,45 +0,0 @@
From 32f203d4e3c711cde5b1546a054be42b16436822 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20Men=C5=A1=C3=ADk?= <pemensik@redhat.com>
Date: Fri, 17 Jul 2026 19:42:39 +0200
Subject: [PATCH] Support program suffixes of tsig-confgen and ddns-confgen
Suffixes different than .exe are used on Fedora. But those commands
require exact names only. Allow switching between two variants only from
prefix. That should work on all platforms. It should support also names
like tsig-confgen-9.18 or tsig-confgen-9.20.
The same case applies to named-checkzone and named-compilezone.
---
bin/check/named-checkzone.c | 2 +-
bin/confgen/tsig-keygen.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/bin/check/named-checkzone.c b/bin/check/named-checkzone.c
index ae8feafc8c..5a1f712463 100644
--- a/bin/check/named-checkzone.c
+++ b/bin/check/named-checkzone.c
@@ -137,7 +137,7 @@ main(int argc, char **argv) {
}
#define PROGCMP(X) \
- (strcasecmp(prog_name, X) == 0 || strcasecmp(prog_name, X ".exe") == 0)
+ (strncasecmp(prog_name, X, strlen(X)) == 0)
if (PROGCMP("named-checkzone")) {
progmode = progmode_check;
diff --git a/bin/confgen/tsig-keygen.c b/bin/confgen/tsig-keygen.c
index f0d2f9a245..9b13312b5b 100644
--- a/bin/confgen/tsig-keygen.c
+++ b/bin/confgen/tsig-keygen.c
@@ -113,7 +113,7 @@ main(int argc, char **argv) {
}
#define PROGCMP(X) \
- (strcasecmp(progname, X) == 0 || strcasecmp(progname, X ".exe") == 0)
+ (strncasecmp(progname, X, strlen(X)) == 0)
if (PROGCMP("tsig-keygen")) {
progmode = progmode_keygen;
--
2.54.0

View file

@ -1,28 +1,30 @@
From 13348a5fc64387bf53ef450688e181100d0ceddb Mon Sep 17 00:00:00 2001
From: Petr Mensik <pemensik@redhat.com>
Date: Thu, 12 Dec 2024 15:56:13 +0100
Subject: [PATCH] Harden named service build flags
---
bin/named/Makefile.am | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/bin/named/Makefile.am b/bin/named/Makefile.am
index 57a023b..b832e9c 100644
--- a/bin/named/Makefile.am
+++ b/bin/named/Makefile.am
@@ -33,7 +33,10 @@ endif HAVE_LIBXML2
diff --git a/bin/named/Makefile.in b/bin/named/Makefile.in
index eb622d1..37053a7 100644
--- a/bin/named/Makefile.in
+++ b/bin/named/Makefile.in
@@ -117,8 +117,12 @@ SRCS = builtin.c config.c control.c \
tkeyconf.c tsigconf.c zoneconf.c \
${DLZDRIVER_SRCS} ${DBDRIVER_SRCS}
AM_CPPFLAGS += \
-DNAMED_LOCALSTATEDIR=\"${localstatedir}\" \
- -DNAMED_SYSCONFDIR=\"${sysconfdir}\"
+ -DNAMED_SYSCONFDIR=\"${sysconfdir}\" \
+ -fpie
+EXT_CFLAGS = -fpie
+
+AM_LDFLAGS += -pie -Wl,-z,relro,-z,now,-z,nodlopen,-z,noexecstack
@BIND9_MAKE_RULES@
sbin_PROGRAMS = named
+LDFLAGS += -pie -Wl,-z,relro,-z,now,-z,nodlopen,-z,noexecstack
+
main.@O@: main.c
${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
-DVERSION=\"${VERSION}\" \
diff --git a/bin/named/unix/Makefile.in b/bin/named/unix/Makefile.in
index fd9ca8d..f1c102c 100644
--- a/bin/named/unix/Makefile.in
+++ b/bin/named/unix/Makefile.in
@@ -11,6 +11,8 @@ srcdir = @srcdir@
VPATH = @srcdir@
top_srcdir = @top_srcdir@
--
2.47.1
+EXT_CFLAGS = -fpie
+
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I${srcdir}/include -I${srcdir}/../include \

53
bind-9.5-dlz-64bit.patch Normal file
View file

@ -0,0 +1,53 @@
diff --git a/contrib/dlz/config.dlz.in b/contrib/dlz/config.dlz.in
index 47525af..eefe3c3 100644
--- a/contrib/dlz/config.dlz.in
+++ b/contrib/dlz/config.dlz.in
@@ -17,6 +17,13 @@
#
dlzdir='${DLZ_DRIVER_DIR}'
+AC_MSG_CHECKING([for target libdir])
+AC_RUN_IFELSE([int main(void) {exit((sizeof(void *) == 8) ? 0 : 1);}],
+ [target_lib=lib64],
+ [target_lib=lib],
+)
+AC_MSG_RESULT(["$target_lib"])
+
#
# Private autoconf macro to simplify configuring drivers:
#
@@ -292,9 +299,9 @@ case "$use_dlz_bdb" in
then
break
fi
- elif test -f "$dd/lib/lib${d}.so"
+ elif test -f "$dd/${target_lib}/lib${d}.so"
then
- dlz_bdb_libs="-L${dd}/lib -l${d}"
+ dlz_bdb_libs="-L${dd}/${target_lib} -l${d}"
break
fi
done
@@ -396,7 +403,7 @@ case "$use_dlz_ldap" in
*)
DLZ_ADD_DRIVER(LDAP, dlz_ldap_driver,
[-I$use_dlz_ldap/include],
- [-L$use_dlz_ldap/lib -lldap -llber])
+ [-L$use_dlz_ldap/${target_lib} -lldap -llber])
AC_MSG_RESULT(
[using LDAP from $use_dlz_ldap/lib and $use_dlz_ldap/include])
@@ -432,11 +439,11 @@ then
odbcdirs="/usr /usr/local /usr/pkg"
for d in $odbcdirs
do
- if test -f $d/include/sql.h -a -f $d/lib/libodbc.a
+ if test -f $d/include/sql.h -a -f $d/${target_lib}/libodbc.a
then
use_dlz_odbc=$d
dlz_odbc_include="-I$use_dlz_odbc/include"
- dlz_odbc_libs="-L$use_dlz_odbc/lib -lodbc"
+ dlz_odbc_libs="-L$use_dlz_odbc/${target_lib} -lodbc"
break
fi
done

View file

@ -0,0 +1,31 @@
diff -up bind-9.10.1b1/contrib/dlz/config.dlz.in.libdb bind-9.10.1b1/contrib/dlz/config.dlz.in
--- bind-9.10.1b1/contrib/dlz/config.dlz.in.libdb 2014-08-04 12:33:09.320735111 +0200
+++ bind-9.10.1b1/contrib/dlz/config.dlz.in 2014-08-04 12:41:46.888241910 +0200
@@ -263,7 +263,7 @@ case "$use_dlz_bdb" in
# Check other locations for includes.
# Order is important (sigh).
- bdb_incdirs="/db53 /db51 /db48 /db47 /db46 /db45 /db44 /db43 /db42 /db41 /db4 /db"
+ bdb_incdirs="/db53 /db51 /db48 /db47 /db46 /db45 /db44 /db43 /db42 /db41 /db4 /libdb /db"
# include a blank element first
for d in "" $bdb_incdirs
do
@@ -288,16 +288,9 @@ case "$use_dlz_bdb" in
bdb_libnames="db53 db-5.3 db51 db-5.1 db48 db-4.8 db47 db-4.7 db46 db-4.6 db45 db-4.5 db44 db-4.4 db43 db-4.3 db42 db-4.2 db41 db-4.1 db"
for d in $bdb_libnames
do
- if test "$dd" = "/usr"
+ if test -f "$dd/${target_lib}/lib${d}.so"
then
- AC_CHECK_LIB($d, db_create, dlz_bdb_libs="-l${d}")
- if test $dlz_bdb_libs != "yes"
- then
- break
- fi
- elif test -f "$dd/${target_lib}/lib${d}.so"
- then
- dlz_bdb_libs="-L${dd}/${target_lib} -l${d}"
+ dlz_bdb_libs="-L${dd}/${target_lib}/libdb -l${d}"
break
fi
done

View file

@ -1,38 +0,0 @@
# vim: ft=conf:
# TODO: these definitions are in different form in rpm spec %files chroot section
# find a way to have it defined only once
#defattr(0664,root,named,-)
c /var/named/chroot/dev/null 0664 root named - 1:3
c /var/named/chroot/dev/random 0664 root named - 1:8
c /var/named/chroot/dev/urandom 0664 root named - 1:9
c /var/named/chroot/dev/zero 0664 root named - 1:5
#defattr(0640,root,named,0750)
d /var/named/chroot 0750 root named -
d /var/named/chroot/dev 0750 root named -
d /var/named/chroot/etc 0750 root named -
d /var/named/chroot/etc/named 0750 root named -
d /var/named/chroot/etc/pki 0750 root named -
d /var/named/chroot/etc/pki/dnssec-keys 0750 root named -
d /var/named/chroot/etc/crypto-policies 0750 root named -
d /var/named/chroot/etc/crypto-policies/back-ends 0750 root named -
d /var/named/chroot/var 0750 root named -
d /var/named/chroot/run 0750 root named -
#defattr(-,root,root,-)
d /var/named/chroot/usr - root root -
d /var/named/chroot/usr/lib64 - root root -
d /var/named/chroot/usr/lib64/bind - root root -
d /var/named/chroot/usr/lib64/named - root root -
d /var/named/chroot/usr/share/GeoIP - root root -
d /var/named/chroot/usr/share/named - root root -
d /var/named/chroot/proc - root root -
d /var/named/chroot/proc/sys - root root -
d /var/named/chroot/proc/sys/net - root root -
d /var/named/chroot/proc/sys/net/ipv4 - root root -
#defattr(0660,root,named,01770)
d /var/named/chroot/var/named 01770 root named -
#defattr(0660,named,named,0770)
d /var/named/chroot/var/tmp 0770 named named -
d /var/named/chroot/var/log 0770 named named -
#defattr(-,named,named,-)
d /var/named/chroot/run/named - named named -
L /var/named/chroot/var/run - named named - ../run

4177
bind.spec

File diff suppressed because it is too large Load diff

View file

@ -1,10 +1 @@
# vim: ft=conf:
d /run/named 0755 named named -
d /var/named 01770 root named -
d /var/named/slaves 0770 named named -
d /var/named/data 0770 named named -
d /var/named/dynamic 0770 named named -
L /var/named/named.ca 0640 named named - ../../../etc/named.ca
L /var/named/named.localhost 0640 named named - ../../../usr/share/named/named.localhost
L /var/named/named.loopback 0640 named named - ../../../usr/share/named/named.loopback
L /var/named/named.empty 0640 named named - ../../../usr/share/named/named.empty

34
bind93-rh490837.patch Normal file
View file

@ -0,0 +1,34 @@
diff --git a/lib/isc/lex.c b/lib/isc/lex.c
index cd44fe3..5b7c539 100644
--- a/lib/isc/lex.c
+++ b/lib/isc/lex.c
@@ -27,6 +27,8 @@
#include <isc/string.h>
#include <isc/util.h>
+#include "../errno2result.h"
+
typedef struct inputsource {
isc_result_t result;
bool is_file;
@@ -422,7 +424,7 @@ isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
#endif /* if defined(HAVE_FLOCKFILE) && defined(HAVE_GETC_UNLOCKED) */
if (c == EOF) {
if (ferror(stream)) {
- source->result = ISC_R_IOERROR;
+ source->result = isc__errno2result(errno);
result = source->result;
goto done;
}
diff --git a/lib/isc/unix/errno2result.c b/lib/isc/unix/errno2result.c
index e3e2644..5e58600 100644
--- a/lib/isc/unix/errno2result.c
+++ b/lib/isc/unix/errno2result.c
@@ -37,6 +37,7 @@ isc___errno2result(int posixerrno, bool dolog, const char *file,
case EINVAL: /* XXX sometimes this is not for files */
case ENAMETOOLONG:
case EBADF:
+ case EISDIR:
return (ISC_R_INVALIDFILE);
case ENOENT:
return (ISC_R_FILENOTFOUND);

31
bind97-rh645544.patch Normal file
View file

@ -0,0 +1,31 @@
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 31549c6..65a14b6 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -1762,7 +1762,7 @@ log_edns(fetchctx_t *fctx) {
*/
dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"success resolving '%s' (in '%s'?) after %s", fctx->info,
domainbuf, fctx->reason);
}
@@ -5298,7 +5298,7 @@ log_lame(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo) {
dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf));
isc_sockaddr_format(&addrinfo->sockaddr, addrbuf, sizeof(addrbuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_LAME_SERVERS,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"lame server resolving '%s' (in '%s'?): %s", namebuf,
domainbuf, addrbuf);
}
@@ -5316,7 +5316,7 @@ log_formerr(fetchctx_t *fctx, const char *format, ...) {
isc_sockaddr_format(&fctx->addrinfo->sockaddr, nsbuf, sizeof(nsbuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_NOTICE,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(1),
"DNS format error from %s resolving %s for %s: %s", nsbuf,
fctx->info, fctx->clientstr, msgbuf);
}

3190
changelog

File diff suppressed because it is too large Load diff

View file

@ -1,252 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: GPGTools - http://gpgtools.org
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
=MkGo
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -146,30 +146,6 @@ mEVyesjYoV40tDCG73qLtfehhV/iARDMCfnZGyGYIZdDBL+tZTNeLKVDIUi/R3x9
OmpEl8ZuCuYltyEsJnCF/rQBVMgcTOmsMu6CMx+qT3kC8iGtHqkUT2ufpKISahTn
e329FQjClEWwBHkr0T4K80Z0REjSo6UBtio73IOCxXe0RqO37L/qgo8xKZbLxy86
857PRWJhgbw169FJ2kR5p+M5d/g/MUeYnigvWlORW5LyrFg6RnZ1ZbULZI80QhHN
aSFf/w020HBsLCkzWA/XM6MO2ifJTSn8NpkCDQRkSjCrARAApLUMHAbmxUMWLgDQ
apRZBwWXriEyIVqA/SIy1PyWPPFXqs3LZ5Kn5Gw1WO8PfzkPZNtccGmNLjujIoRB
qR41nV5zxcpS896SujBoYl80A4F4v9Op9i2pFeI9r9acFcUDjbGWBqNro4EfRcJN
Ctkd9+pl3TUvFX06QCTxmmHy3M81SW3b4NWI+jia1cKjCd+qBFBgKWdjSMBeVTBC
R9eKqsBQ1UJql2bRzc8pReS+TYCeEbhaOCvUCCKCwGtsSUOW726iNB/4zR4OOuQV
B9ORufwed+E/RXa8N08/l5O96uXG0krJtOVm0/qQcXOaKxiDo6djnAgCdjFK5zaj
7594wqbI7de58alWb/egqIhjBTgk+/cO+epZ05qx5SoJZL7ny2ottrfS2cBqP4g1
SIt1sYl9ImHmJkNrNDy0s25nE9Nga6OfRqVbwnwot4ouTGwj0oZsCjw+gWjDdztH
1fUWSnlA8jaX9/RZG2wKt9dI+Tp/U4d5dyTb8lIIzzgtAzDmDfPxwwT0rxAAL13A
gDkJ0AzXA4WTOxb/JE2yfCz//kt7n8SYM//LixL4VAB7e/wnfZBhTq0OFpaPjFU0
h/k0dc40AqcUuK3lSSjQr3KTzRHtjz8qtN4DFSuyZac83QSVtWE1rFKjS8bl3XHC
kFFRJ2dMt2WRSkLOYNiTGbYLvmEAEQEAAbQwQW5kcmVpIFBhdmVsIChDb2RlLVNp
Z25pbmcgS2V5KSA8YW5kcmVpQGlzYy5vcmc+iQJOBBMBCgA4FiEE2mo1COZypJ3T
gq/ZW49NkbiO2QkFAmRKMKsCGwMFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ
W49NkbiO2QnQZw//XCpeqT0z/sqtu4FYWwYLz1OvWqhe+uA45f9BccnNSVkGFa7w
3hlLQC/FLUIx2cVy9AluJBP29iQge/bCcXnzo/QvCbhe/4lCTxhr7nsBe1bWpuNI
4Pl+cQxZQBwcz74zZ1jjaaQOqm3XtdZxeKNfCQmNvz389UZEk2m8K6qJD23fy20V
n5Y2C502UuP3MitbYKBxBSbs+Auwy1evz/prQ9VeD4Nv3Zr+jWbWFW+dSDC8jkrX
cGdwWrUQ51QD8VBB9lPWPGY6yTbRmacr4AlVSo2DAfyjHRrGHigRF/VAD5p1+u2g
3UFLJaEyujfzwU1kG4+zQCWZ2W2UBOekklq/yefxEY5vU1/Lad7vQhBmogQNF21T
FvLUE6ez7XNsdMZStDPiT8OoTyFZYLRM4yw5rWKw+1mICBv7NV82YD/8hoMoZPyX
2tNRTXv2MZ6qD++0dMCIZNEyFTB344srvQSyJ7K7vwxulc7iFWngRA8oe6JkAhH4
B0yNq1FJm6jIL41S2FmnDL3DlfAdKWapBqzgqkv+X5DQBaTlG9a4BcSsdMJgU/Yx
dD03YsKhDtEWTqBmmEamR1K1CgCC3mOJfsHB5z+Qhdraz2hMr00EQrD5lnpLLpcF
rYWoilvVlRy7Y7U5wfhY4074L2ZfB+yElKsvtfGKJX/8g+eJdeRuII+hjEc=
=NX7P
aSFf/w020HBsLCkzWA/XM6MO2ifJTSn8Ng==
=C1ed
-----END PGP PUBLIC KEY BLOCK-----

View file

@ -8,5 +8,5 @@ After=named-setup-rndc.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/libexec/%{name}/setup-named-chroot.sh /var/named/chroot on /etc/named-chroot.files
ExecStop=/usr/libexec/%{name}/setup-named-chroot.sh /var/named/chroot off /etc/named-chroot.files
ExecStart=/usr/libexec/setup-named-chroot.sh /var/named/chroot on /etc/named-chroot.files
ExecStop=/usr/libexec/setup-named-chroot.sh /var/named/chroot off /etc/named-chroot.files

View file

@ -3,7 +3,6 @@
# if they are missing or empty in target directory.
/etc/localtime
/etc/named.root.key
/etc/named.ca
/etc/named.conf
/etc/named.rfc1912.zones
/etc/rndc.conf
@ -17,8 +16,9 @@
/etc/named
/usr/lib64/bind
/usr/lib/bind
/usr/lib64/named
/usr/lib/named
/usr/share/GeoIP
/usr/share/named
/run/named
/proc/sys/net/ipv4/ip_local_port_range
# Warning: the order is important

View file

@ -12,21 +12,19 @@ After=network.target
[Service]
Type=forking
Environment=OPTIONS=
Environment=NAMEDCONF=/etc/named.conf
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=/var/named/chroot/run/named/named.pid
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then %{_bindir}/named-checkconf%{program_suffix} -t /var/named/chroot -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi'
ExecStart=%{_sbindir}/named%{program_suffix} -u named -c ${NAMEDCONF} -t /var/named/chroot $OPTIONS
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -t /var/named/chroot -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi'
ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} -t /var/named/chroot $OPTIONS
ExecReload=/bin/sh -c 'if %{_sbindir}/rndc%{program_suffix} null > /dev/null 2>&1; then %{_sbindir}/rndc%{program_suffix} reload; else %{_bindir}/kill -HUP $MAINPID; fi'
ExecReload=/bin/sh -c 'if /usr/sbin/rndc null > /dev/null 2>&1; then /usr/sbin/rndc reload; else /bin/kill -HUP $MAINPID; fi'
ExecStop=/bin/sh -c '%{_sbindir}/rndc%{program_suffix} stop > /dev/null 2>&1 || %{_bindir}/kill -TERM $MAINPID'
ExecStop=/bin/sh -c '/usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'
PrivateTmp=false
Restart=on-abnormal
[Install]
WantedBy=multi-user.target

26
named-pkcs11.service Normal file
View file

@ -0,0 +1,26 @@
[Unit]
Description=Berkeley Internet Name Domain (DNS) with native PKCS#11
Wants=nss-lookup.target
Wants=named-setup-rndc.service
Before=nss-lookup.target
After=network.target
After=named-setup-rndc.service
[Service]
Type=forking
Environment=NAMEDCONF=/etc/named.conf
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=/run/named/named.pid
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi'
ExecStart=/usr/sbin/named-pkcs11 -u named -c ${NAMEDCONF} $OPTIONS
ExecReload=/bin/sh -c 'if /usr/sbin/rndc null > /dev/null 2>&1; then /usr/sbin/rndc reload; else /bin/kill -HUP $MAINPID; fi'
ExecStop=/bin/sh -c '/usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'
PrivateTmp=true
[Install]
WantedBy=multi-user.target

View file

@ -4,4 +4,4 @@ Description=Generate rndc key for BIND (DNS)
[Service]
Type=oneshot
ExecStart=/usr/libexec/%{name}/generate-rndc-key.sh
ExecStart=/usr/libexec/generate-rndc-key.sh

View file

@ -51,7 +51,7 @@ logging {
zone "." IN {
type hint;
file "/etc/named.ca";
file "named.ca";
};
include "/etc/named.rfc1912.zones";

View file

@ -2,9 +2,11 @@
missingok
su named named
create 0644 named named
notifempty
postrotate
/usr/bin/systemctl reload named.service > /dev/null 2>&1 || true
/usr/bin/systemctl reload named-chroot.service > /dev/null 2>&1 || true
/usr/bin/systemctl reload named-sdb.service > /dev/null 2>&1 || true
/usr/bin/systemctl reload named-sdb-chroot.service > /dev/null 2>&1 || true
/usr/bin/systemctl reload named-pkcs11.service > /dev/null 2>&1 || true
endscript
}

View file

@ -1,5 +1,4 @@
// named.rfc1912.zones:
// vim: ft=named:
//
// Provided by Red Hat caching-nameserver package
//
@ -17,30 +16,30 @@
zone "localhost.localdomain" IN {
type primary;
file "/usr/share/named/named.localhost";
file "named.localhost";
allow-update { none; };
};
zone "localhost" IN {
type primary;
file "/usr/share/named/named.localhost";
file "named.localhost";
allow-update { none; };
};
zone "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" IN {
type primary;
file "/usr/share/named/named.loopback";
file "named.loopback";
allow-update { none; };
};
zone "1.0.0.127.in-addr.arpa" IN {
type primary;
file "/usr/share/named/named.loopback";
file "named.loopback";
allow-update { none; };
};
zone "0.in-addr.arpa" IN {
type primary;
file "/usr/share/named/named.empty";
file "named.empty";
allow-update { none; };
};

View file

@ -1,92 +1,61 @@
; This file holds the information on root name servers needed to
; initialize cache of Internet domain name servers
; (e.g. reference this file in the "cache . <file>"
; configuration file of BIND domain name servers).
;
; This file is made available by InterNIC
; under anonymous FTP as
; file /domain/named.cache
; on server FTP.INTERNIC.NET
; -OR- RS.INTERNIC.NET
;
; last update: December 20, 2023
; related version of root zone: 2023122001
;
; FORMERLY NS.INTERNIC.NET
;
. 3600000 NS A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET. 3600000 A 198.41.0.4
A.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:ba3e::2:30
;
; FORMERLY NS1.ISI.EDU
;
. 3600000 NS B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET. 3600000 A 170.247.170.2
B.ROOT-SERVERS.NET. 3600000 AAAA 2801:1b8:10::b
;
; FORMERLY C.PSI.NET
;
. 3600000 NS C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET. 3600000 A 192.33.4.12
C.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2::c
;
; FORMERLY TERP.UMD.EDU
;
. 3600000 NS D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET. 3600000 A 199.7.91.13
D.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2d::d
;
; FORMERLY NS.NASA.GOV
;
. 3600000 NS E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET. 3600000 A 192.203.230.10
E.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:a8::e
;
; FORMERLY NS.ISC.ORG
;
. 3600000 NS F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET. 3600000 A 192.5.5.241
F.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:2f::f
;
; FORMERLY NS.NIC.DDN.MIL
;
. 3600000 NS G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET. 3600000 A 192.112.36.4
G.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:12::d0d
;
; FORMERLY AOS.ARL.ARMY.MIL
;
. 3600000 NS H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET. 3600000 A 198.97.190.53
H.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:1::53
;
; FORMERLY NIC.NORDU.NET
;
. 3600000 NS I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET. 3600000 A 192.36.148.17
I.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fe::53
;
; OPERATED BY VERISIGN, INC.
;
. 3600000 NS J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET. 3600000 A 192.58.128.30
J.ROOT-SERVERS.NET. 3600000 AAAA 2001:503:c27::2:30
;
; OPERATED BY RIPE NCC
;
. 3600000 NS K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET. 3600000 A 193.0.14.129
K.ROOT-SERVERS.NET. 3600000 AAAA 2001:7fd::1
;
; OPERATED BY ICANN
;
. 3600000 NS L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET. 3600000 A 199.7.83.42
L.ROOT-SERVERS.NET. 3600000 AAAA 2001:500:9f::42
;
; OPERATED BY WIDE
;
. 3600000 NS M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET. 3600000 A 202.12.27.33
M.ROOT-SERVERS.NET. 3600000 AAAA 2001:dc3::35
; End of file
; <<>> DiG 9.11.3-RedHat-9.11.3-3.fc27 <<>> +bufsize=1200 +norec @a.root-servers.net
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46900
;; flags: qr aa; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 27
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1472
;; QUESTION SECTION:
;. IN NS
;; ANSWER SECTION:
. 518400 IN NS a.root-servers.net.
. 518400 IN NS b.root-servers.net.
. 518400 IN NS c.root-servers.net.
. 518400 IN NS d.root-servers.net.
. 518400 IN NS e.root-servers.net.
. 518400 IN NS f.root-servers.net.
. 518400 IN NS g.root-servers.net.
. 518400 IN NS h.root-servers.net.
. 518400 IN NS i.root-servers.net.
. 518400 IN NS j.root-servers.net.
. 518400 IN NS k.root-servers.net.
. 518400 IN NS l.root-servers.net.
. 518400 IN NS m.root-servers.net.
;; ADDITIONAL SECTION:
a.root-servers.net. 518400 IN A 198.41.0.4
b.root-servers.net. 518400 IN A 199.9.14.201
c.root-servers.net. 518400 IN A 192.33.4.12
d.root-servers.net. 518400 IN A 199.7.91.13
e.root-servers.net. 518400 IN A 192.203.230.10
f.root-servers.net. 518400 IN A 192.5.5.241
g.root-servers.net. 518400 IN A 192.112.36.4
h.root-servers.net. 518400 IN A 198.97.190.53
i.root-servers.net. 518400 IN A 192.36.148.17
j.root-servers.net. 518400 IN A 192.58.128.30
k.root-servers.net. 518400 IN A 193.0.14.129
l.root-servers.net. 518400 IN A 199.7.83.42
m.root-servers.net. 518400 IN A 202.12.27.33
a.root-servers.net. 518400 IN AAAA 2001:503:ba3e::2:30
b.root-servers.net. 518400 IN AAAA 2001:500:200::b
c.root-servers.net. 518400 IN AAAA 2001:500:2::c
d.root-servers.net. 518400 IN AAAA 2001:500:2d::d
e.root-servers.net. 518400 IN AAAA 2001:500:a8::e
f.root-servers.net. 518400 IN AAAA 2001:500:2f::f
g.root-servers.net. 518400 IN AAAA 2001:500:12::d0d
h.root-servers.net. 518400 IN AAAA 2001:500:1::53
i.root-servers.net. 518400 IN AAAA 2001:7fe::53
j.root-servers.net. 518400 IN AAAA 2001:503:c27::2:30
k.root-servers.net. 518400 IN AAAA 2001:7fd::1
l.root-servers.net. 518400 IN AAAA 2001:500:9f::42
m.root-servers.net. 518400 IN AAAA 2001:dc3::35
;; Query time: 24 msec
;; SERVER: 198.41.0.4#53(198.41.0.4)
;; WHEN: Thu Apr 05 15:57:34 CEST 2018
;; MSG SIZE rcvd: 811

View file

@ -10,9 +10,4 @@ trust-anchors {
# managed key database will be trusted and maintained
# automatically.
. initial-ds 20326 8 2 "E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D";
# This key (38696) will be pre-published in the root zone in 2025
# and is scheduled to begin signing in late 2026. At that time,
# servers which were already using the old key (20326) should roll
# seamlessly to this new one via RFC 5011 rollover.
. initial-ds 38696 8 2 "683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16";
};

6
named.rwtab Normal file
View file

@ -0,0 +1,6 @@
dirs /var/named
files /var/named/named.ca
files /var/named/named.empty
files /var/named/named.localhost
files /var/named/named.loopback

25
named.service Normal file
View file

@ -0,0 +1,25 @@
[Unit]
Description=Berkeley Internet Name Domain (DNS)
Wants=nss-lookup.target
Wants=named-setup-rndc.service
Before=nss-lookup.target
After=named-setup-rndc.service
After=network.target
[Service]
Type=forking
Environment=NAMEDCONF=/etc/named.conf
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=/run/named/named.pid
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then /usr/sbin/named-checkconf -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi'
ExecStart=/usr/sbin/named -u named -c ${NAMEDCONF} $OPTIONS
ExecReload=/bin/sh -c 'if /usr/sbin/rndc null > /dev/null 2>&1; then /usr/sbin/rndc reload; else /bin/kill -HUP $MAINPID; fi'
ExecStop=/bin/sh -c '/usr/sbin/rndc stop > /dev/null 2>&1 || /bin/kill -TERM $MAINPID'
PrivateTmp=true
[Install]
WantedBy=multi-user.target

View file

@ -1,28 +0,0 @@
[Unit]
Description=Berkeley Internet Name Domain (DNS)
Wants=nss-lookup.target
Wants=named-setup-rndc.service
Before=nss-lookup.target
After=named-setup-rndc.service
After=network.target
[Service]
Type=forking
Environment=OPTIONS=
Environment=NAMEDCONF=/etc/named.conf
EnvironmentFile=-/etc/sysconfig/named
Environment=KRB5_KTNAME=/etc/named.keytab
PIDFile=/run/named/named.pid
ExecStartPre=/bin/bash -c 'if [ ! "$DISABLE_ZONE_CHECKING" == "yes" ]; then %{_sbindir}/named-checkconf%{program_suffix} -z "$NAMEDCONF"; else echo "Checking of zone files is disabled"; fi'
ExecStart=%{_sbindir}/named%{program_suffix} -u named -c ${NAMEDCONF} $OPTIONS
ExecReload=/bin/sh -c 'if %{_sbindir}/rndc%{program_suffix} null > /dev/null 2>&1; then %{_sbindir}/rndc%{program_suffix} reload; else %{_bindir}/kill -HUP $MAINPID; fi'
ExecStop=/bin/sh -c '%{_sbindir}/rndc%{program_suffix} stop > /dev/null 2>&1 || %{_bindir}/kill -TERM $MAINPID'
PrivateTmp=true
Restart=on-abnormal
[Install]
WantedBy=multi-user.target

View file

@ -1,3 +0,0 @@
#Type Name ID GECOS Home directory Shell
u named 25 "Named" /var/named /sbin/nologin
g named 25

View file

@ -1,10 +1,6 @@
summary: Test plan with all beakerlib tests
environment+:
PACKAGE: bind
discover:
how: fmf
url: https://gitlab.com/redhat/centos-stream/tests/bind.git
url: https://src.fedoraproject.org/tests/bind.git
execute:
how: tmt
context:
component: bind

View file

@ -1,11 +1,7 @@
summary: Public (Fedora) Tier1 beakerlib tests
environment+:
PACKAGE: bind
discover:
how: fmf
url: https://gitlab.com/redhat/centos-stream/tests/bind.git
url: https://src.fedoraproject.org/tests/bind.git
filter: 'tier: 1'
execute:
how: tmt
context:
component: bind

View file

@ -10,7 +10,7 @@ usage()
echo 'Usage: setup-named-chroot.sh ROOTDIR <on|off> [chroot.files]'
}
if ! [ "$#" -ge 2 -a "$#" -le 3 ]; then
if ! [ "$#" -ge 2 ] && [ "$#" -le 3 ]; then
echo 'Wrong number of arguments'
usage
exit 1
@ -34,9 +34,9 @@ dev_create()
DEVNAME="$ROOTDIR/dev/$1"
shift
if ! [ -e "$DEVNAME" ]; then
/bin/mknod -m 0664 "$DEVNAME" $@
/bin/mknod -m 0664 "$DEVNAME" "$@"
/bin/chgrp named "$DEVNAME"
if [ -x /usr/sbin/selinuxenabled -a -x /sbin/restorecon ]; then
if [ -x /usr/sbin/selinuxenabled ] && [ -x /sbin/restorecon ]; then
/usr/sbin/selinuxenabled && /sbin/restorecon "$DEVNAME" > /dev/null || :
fi
fi
@ -78,7 +78,7 @@ mount_chroot_conf()
else
# Mount source is a directory. Mount it only if directory in chroot is
# empty.
if [ -e "$all" ] && [ `ls -1A $ROOTDIR$all | wc -l` -eq 0 ]; then
if [ -e "$all" ] && [ `ls -1A "$ROOTDIR$all" | wc -l` -eq 0 ]; then
mount --bind --make-private "$all" "$ROOTDIR$all"
fi
fi

View file

@ -1,2 +1,2 @@
SHA512 (bind-9.18.50.tar.xz) = 5ae70c95f19868f41fd609bf34a908c38769401ee5b89e4782b94081032a579c00ba9010b2feb2789a95cfd12289cfe250e6488b3b47ff666bfa8cd7edf74d43
SHA512 (bind-9.18.50.tar.xz.asc) = 41df6df786cd33055a3fd6632ffd2968d6600e314140c547bba3452ec9f7726f44df27c3bd53a5a937ad11407d7391641e0b7b1aff7ebf87f25c65e2a76707b6
SHA512 (bind-9.16.40.tar.xz) = accf37a608f4e632ff61c8ac42d157fb9d94a791ad686ac1641286b017198d2a7b19613b62d9f7b1e5a14d6bb13fc307ce74fd6f415521e430a62fca7e8245f9
SHA512 (bind-9.16.40.tar.xz.asc) = 1659fd2d3c723cbf0c4deafcf16790b59719220fb500894934ed7c9a38f72ccc9df8823621e1fbdbb1358d989f947f54368c42c8c0e5f5eb78802c31a1abdb06

View file

@ -1,2 +1 @@
. 3600 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexTBAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq7HrxRixHlFlExOLAJr5emLvN7SWXgnLh4+B5xQlNVz8Og8kvArMtNROxVQuCaSnIDdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLrjyBxWezF0jLHwVN8efS3rCj/EWgvIWgb9tarpVUDK/b58Da+sqqls3eNbuv7pr+eoZG+SrDK6nWeL3c6H5Apxz7LjVc1uTIdsIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6+cn8HFRm+2hM8AnXGXws9555KrUB5qihylGa8subX2Nn6UwNR1AkUTV74bU=
. 3600 IN DNSKEY 257 3 8 AwEAAa96jeuknZlaeSrvyAJj6ZHv28hhOKkx3rLGXVaC6rXTsDc449/cidltpkyGwCJNnOAlFNKF2jBosZBU5eeHspaQWOmOElZsjICMQMC3aeHbGiShvZsx4wMYSjH8e7Vrhbu6irwCzVBApESjbUdpWWmEnhathWu1jo+siFUiRAAxm9qyJNg/wOZqqzL/dL/q8PkcRU5oUKEpUge71M3ej2/7CPqpdVwuMoTvoB+ZOT4YeGyxMvHmbrxlFzGOHOijtzN+u1TQNatX2XBuzZNQ1K+s2CXkPIZo7s6JgZyvaBevYtxPvYLw4z9mR7K2vaF18UYH9Z9GNUUeayffKC73PYc=