From 25b2c6ad96cc36baa2f043cb257f130b5eb0c583 Mon Sep 17 00:00:00 2001 From: Artem Boldariev Date: Thu, 26 Aug 2021 16:06:42 +0300 Subject: [PATCH] Require "dot" ALPN token for zone transfer requests over DoT (XoT) This commit makes BIND verify that zone transfers are allowed to be done over the underlying connection. Currently, it makes sense only for DoT, but the code is deliberately made to be protocol-agnostic. --- lib/isc/include/isc/netmgr.h | 3 +++ lib/isc/netmgr/netmgr.c | 8 ++++++++ lib/ns/query.c | 10 ++++++++++ 3 files changed, 21 insertions(+) diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index 3134294696..ceefd5e20f 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -488,6 +488,9 @@ isc_nm_tlsdnsconnect(isc_nm_t *mgr, isc_sockaddr_t *local, isc_sockaddr_t *peer, * 'cb'. */ +bool +isc_nm_is_tlsdns_handle(isc_nmhandle_t *handle); + #if HAVE_LIBNGHTTP2 #define ISC_NM_HTTP_DEFAULT_PATH "/dns-query" diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 8aa9acb7d3..80a2224edf 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -3418,6 +3418,14 @@ isc_nm_xfr_allowed(isc_nmhandle_t *handle) { return (false); } +bool +isc_nm_is_tlsdns_handle(isc_nmhandle_t *handle) { + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(VALID_NMSOCK(handle->sock)); + + return (handle->sock->type == isc_nm_tlsdnssocket); +} + #ifdef NETMGR_TRACE /* * Dump all active sockets in netmgr. We output to stderr diff --git a/lib/ns/query.c b/lib/ns/query.c index e5bbb3df1a..4002433ebf 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -12054,6 +12054,16 @@ ns_query_start(ns_client_t *client, isc_nmhandle_t *handle) { return; } #endif + if (isc_nm_is_tlsdns_handle(handle) && + !isc_nm_xfr_allowed(handle)) { + /* Currently this code is here for DoT, which + * has more complex requirements for zone + * transfers compared to + * other stream protocols. See RFC9103 for + * the details. */ + query_error(client, DNS_R_REFUSED, __LINE__); + return; + } ns_xfr_start(client, rdataset->type); return; case dns_rdatatype_maila: