From eba3278e52b96f0dacc66a13c4db81a52605f7c3 Mon Sep 17 00:00:00 2001 From: Artem Boldariev Date: Thu, 26 Aug 2021 15:07:20 +0300 Subject: [PATCH] Add isc_nm_xfr_allowed() function The intention of having this function is to have a predicate to check if a zone transfer could be performed over the given handle. In most cases we can assume that we can do zone transfers over any stream transport except DoH, but this assumption will not work for zone transfers over DoT (XoT), as the RFC9103 requires ALPN to happen, which might not be the case for all deployments of DoT. --- lib/isc/include/isc/netmgr.h | 9 +++++++++ lib/isc/netmgr/netmgr-int.h | 10 ++++++++++ lib/isc/netmgr/netmgr.c | 24 ++++++++++++++++++++++++ lib/isc/netmgr/tlsdns.c | 23 +++++++++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/lib/isc/include/isc/netmgr.h b/lib/isc/include/isc/netmgr.h index b198713092..3134294696 100644 --- a/lib/isc/include/isc/netmgr.h +++ b/lib/isc/include/isc/netmgr.h @@ -597,6 +597,15 @@ isc_nm_bad_request(isc_nmhandle_t *handle); * \li 'handle' is a valid netmgr handle object. */ +bool +isc_nm_xfr_allowed(isc_nmhandle_t *handle); +/*%< + * Check if it is possible to do a zone transfer over the given handle. + * + * Requires: + * \li 'handle' is a valid connection handle. + */ + void isc_nm_task_enqueue(isc_nm_t *mgr, isc_task_t *task, int threadid); /*%< diff --git a/lib/isc/netmgr/netmgr-int.h b/lib/isc/netmgr/netmgr-int.h index 963476b64c..8fc2b4fcd1 100644 --- a/lib/isc/netmgr/netmgr-int.h +++ b/lib/isc/netmgr/netmgr-int.h @@ -1580,6 +1580,16 @@ isc__nm_async_tlsdnsread(isc__networker_t *worker, isc__netievent_t *ev0); * Callback handlers for asynchronous TLSDNS events. */ +bool +isc__nm_tlsdns_xfr_allowed(isc_nmsocket_t *sock); +/*%< + * Check if it is possible to do a zone transfer over the given TLSDNS + * socket. + * + * Requires: + * \li 'sock' is a valid TLSDNS socket. + */ + #if HAVE_LIBNGHTTP2 void isc__nm_tls_send(isc_nmhandle_t *handle, const isc_region_t *region, diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index b67a94e246..8aa9acb7d3 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -3394,6 +3394,30 @@ isc_nm_bad_request(isc_nmhandle_t *handle) { } } +bool +isc_nm_xfr_allowed(isc_nmhandle_t *handle) { + isc_nmsocket_t *sock; + + REQUIRE(VALID_NMHANDLE(handle)); + REQUIRE(VALID_NMSOCK(handle->sock)); + + sock = handle->sock; + + switch (sock->type) { + case isc_nm_tcpdnssocket: + return (true); + case isc_nm_tlsdnssocket: + return (isc__nm_tlsdns_xfr_allowed(sock)); + default: + return (false); + } + + INSIST(0); + ISC_UNREACHABLE(); + + return (false); +} + #ifdef NETMGR_TRACE /* * Dump all active sockets in netmgr. We output to stderr diff --git a/lib/isc/netmgr/tlsdns.c b/lib/isc/netmgr/tlsdns.c index 165d8be2e9..0d2828d4bf 100644 --- a/lib/isc/netmgr/tlsdns.c +++ b/lib/isc/netmgr/tlsdns.c @@ -2029,3 +2029,26 @@ isc__nm_async_tlsdnscancel(isc__networker_t *worker, isc__netievent_t *ev0) { isc__nm_failed_read_cb(sock, ISC_R_EOF, false); } + +/* Zone transfers/updates over TLS are allowed only when "dot" ALPN + * was negotiated. + * + * Per the XoT spec, we must also check that the TLS version is >= + * 1.3. The check could be added here. However, we still need to + * support platforms where no cryptographic library with TLSv1.3 + * support is available. As a result of this we cannot be too strict + * regarding the minimal TLS protocol version in order to make it + * possible to do encrypted zone transfers over TLSv1.2, as it would + * not be right to leave users on these platforms without means for + * encrypted zone transfers using BIND only. + * + * The ones requiring strict compatibility with the specification + * could disable TLSv1.2 in the configuration file. + */ +bool +isc__nm_tlsdns_xfr_allowed(isc_nmsocket_t *sock) { + REQUIRE(VALID_NMSOCK(sock)); + REQUIRE(sock->type == isc_nm_tlsdnssocket); + + return (sock->tls.alpn_negotiated); +}