]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Load and validate the configured TLS transport for forwarders
authorAram Sargsyan <aram@isc.org>
Thu, 8 Dec 2022 14:17:24 +0000 (14:17 +0000)
committerAram Sargsyan <aram@isc.org>
Fri, 20 Jan 2023 14:45:30 +0000 (14:45 +0000)
Add support for loading and validating the 'tls' parameter from
the forwarders' configuration.

This prepares ground for adding support to forward queries to
DoT-enabled upstream servers.

bin/named/server.c
lib/dns/forward.c
lib/dns/include/dns/forward.h

index a49fbf4bea5e082dd0f76465463825e70e051f7d..cf9fe130e9d661033a0a35f87225bb240f01a3d3 100644 (file)
@@ -447,6 +447,9 @@ static isc_result_t
 configure_newzones(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig,
                   cfg_aclconfctx_t *actx);
 
+static const cfg_obj_t *
+find_maplist(const cfg_obj_t *config, const char *listname, const char *name);
+
 static isc_result_t
 add_keydata_zone(dns_view_t *view, const char *directory, isc_mem_t *mctx);
 
@@ -6204,11 +6207,44 @@ cleanup:
        return (result);
 }
 
+static isc_result_t
+validate_tls(const cfg_obj_t *config, dns_view_t *view, const cfg_obj_t *obj,
+            isc_log_t *logctx, const char *str, dns_name_t **name) {
+       dns_fixedname_t fname;
+       dns_name_t *nm = dns_fixedname_initname(&fname);
+       isc_result_t result = dns_name_fromstring(nm, str, 0, NULL);
+
+       if (result != ISC_R_SUCCESS) {
+               cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                           "'%s' is not a valid name", str);
+               return (result);
+       }
+
+       if (strcasecmp(str, "ephemeral") != 0) {
+               const cfg_obj_t *tlsmap = find_maplist(config, "tls", str);
+
+               if (tlsmap == NULL) {
+                       cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+                                   "tls '%s' is not defined", str);
+                       return (ISC_R_FAILURE);
+               }
+       }
+
+       if (name != NULL && *name == NULL) {
+               *name = isc_mem_get(view->mctx, sizeof(dns_name_t));
+               dns_name_init(*name, NULL);
+               dns_name_dup(nm, view->mctx, *name);
+       }
+
+       return (ISC_R_SUCCESS);
+}
+
 static isc_result_t
 configure_forward(const cfg_obj_t *config, dns_view_t *view,
                  const dns_name_t *origin, const cfg_obj_t *forwarders,
                  const cfg_obj_t *forwardtype) {
        const cfg_obj_t *portobj = NULL;
+       const cfg_obj_t *tlspobj = NULL;
        const cfg_obj_t *faddresses = NULL;
        const cfg_listelt_t *element = NULL;
        dns_fwdpolicy_t fwdpolicy = dns_fwdpolicy_none;
@@ -6216,6 +6252,8 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
        dns_forwarder_t *fwd = NULL;
        isc_result_t result;
        in_port_t port;
+       in_port_t tls_port;
+       const char *tls = NULL;
 
        ISC_LIST_INIT(fwdlist);
 
@@ -6223,6 +6261,7 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
         * Determine which port to send forwarded requests to.
         */
        CHECKM(named_config_getport(config, "port", &port), "port");
+       CHECKM(named_config_getport(config, "tls-port", &tls_port), "tls-port");
 
        if (forwarders != NULL) {
                portobj = cfg_tuple_get(forwarders, "port");
@@ -6234,7 +6273,24 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
                                            "port '%u' out of range", val);
                                return (ISC_R_RANGE);
                        }
-                       port = (in_port_t)val;
+                       port = tls_port = (in_port_t)val;
+               }
+       }
+
+       /*
+        * TLS value for forwarded requests.
+        */
+       if (forwarders != NULL) {
+               tlspobj = cfg_tuple_get(forwarders, "tls");
+               if (cfg_obj_isstring(tlspobj)) {
+                       tls = cfg_obj_asstring(tlspobj);
+                       if (tls != NULL) {
+                               result = validate_tls(config, view, tlspobj,
+                                                     named_g_lctx, tls, NULL);
+                               if (result != ISC_R_SUCCESS) {
+                                       return (result);
+                               }
+                       }
                }
        }
 
@@ -6247,10 +6303,28 @@ configure_forward(const cfg_obj_t *config, dns_view_t *view,
             element = cfg_list_next(element))
        {
                const cfg_obj_t *forwarder = cfg_listelt_value(element);
+               const char *cur_tls = NULL;
+
                fwd = isc_mem_get(view->mctx, sizeof(dns_forwarder_t));
+               fwd->tlsname = NULL;
+               cur_tls = cfg_obj_getsockaddrtls(forwarder);
+               if (cur_tls == NULL) {
+                       cur_tls = tls;
+               }
+               if (cur_tls != NULL) {
+                       result = validate_tls(config, view, faddresses,
+                                             named_g_lctx, cur_tls,
+                                             &fwd->tlsname);
+                       if (result != ISC_R_SUCCESS) {
+                               isc_mem_put(view->mctx, fwd,
+                                           sizeof(dns_forwarder_t));
+                               goto cleanup;
+                       }
+               }
                fwd->addr = *cfg_obj_assockaddr(forwarder);
                if (isc_sockaddr_getport(&fwd->addr) == 0) {
-                       isc_sockaddr_setport(&fwd->addr, port);
+                       isc_sockaddr_setport(&fwd->addr,
+                                            cur_tls != NULL ? tls_port : port);
                }
                ISC_LINK_INIT(fwd, link);
                ISC_LIST_APPEND(fwdlist, fwd, link);
@@ -6300,6 +6374,11 @@ cleanup:
        while (!ISC_LIST_EMPTY(fwdlist)) {
                fwd = ISC_LIST_HEAD(fwdlist);
                ISC_LIST_UNLINK(fwdlist, fwd, link);
+               if (fwd->tlsname != NULL) {
+                       dns_name_free(fwd->tlsname, view->mctx);
+                       isc_mem_put(view->mctx, fwd->tlsname,
+                                   sizeof(dns_name_t));
+               }
                isc_mem_put(view->mctx, fwd, sizeof(dns_forwarder_t));
        }
 
index 8750569c5ddb5b055d205e3c1007ceccb13ec921..ef05529d832a274fa3d03d831134d587d1ff37a7 100644 (file)
@@ -20,6 +20,7 @@
 #include <isc/util.h>
 
 #include <dns/forward.h>
+#include <dns/name.h>
 #include <dns/rbt.h>
 #include <dns/types.h>
 
@@ -84,6 +85,15 @@ dns_fwdtable_addfwd(dns_fwdtable_t *fwdtable, const dns_name_t *name,
        {
                nfwd = isc_mem_get(fwdtable->mctx, sizeof(*nfwd));
                *nfwd = *fwd;
+
+               if (fwd->tlsname != NULL) {
+                       nfwd->tlsname = isc_mem_get(fwdtable->mctx,
+                                                   sizeof(*nfwd->tlsname));
+                       dns_name_init(nfwd->tlsname, NULL);
+                       dns_name_dup(fwd->tlsname, fwdtable->mctx,
+                                    nfwd->tlsname);
+               }
+
                ISC_LINK_INIT(nfwd, link);
                ISC_LIST_APPEND(forwarders->fwdrs, nfwd, link);
        }
@@ -103,6 +113,11 @@ cleanup:
        while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
                fwd = ISC_LIST_HEAD(forwarders->fwdrs);
                ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
+               if (fwd->tlsname != NULL) {
+                       dns_name_free(fwd->tlsname, fwdtable->mctx);
+                       isc_mem_put(fwdtable->mctx, fwd->tlsname,
+                                   sizeof(*fwd->tlsname));
+               }
                isc_mem_put(fwdtable->mctx, fwd, sizeof(*fwd));
        }
        isc_mem_put(fwdtable->mctx, forwarders, sizeof(*forwarders));
@@ -126,8 +141,8 @@ dns_fwdtable_add(dns_fwdtable_t *fwdtable, const dns_name_t *name,
             sa = ISC_LIST_NEXT(sa, link))
        {
                fwd = isc_mem_get(fwdtable->mctx, sizeof(*fwd));
-               fwd->addr = *sa;
-               ISC_LINK_INIT(fwd, link);
+               *fwd = (dns_forwarder_t){ .addr = *sa,
+                                         .link = ISC_LINK_INITIALIZER };
                ISC_LIST_APPEND(forwarders->fwdrs, fwd, link);
        }
        forwarders->fwdpolicy = fwdpolicy;
@@ -211,6 +226,11 @@ auto_detach(void *data, void *arg) {
        while (!ISC_LIST_EMPTY(forwarders->fwdrs)) {
                fwd = ISC_LIST_HEAD(forwarders->fwdrs);
                ISC_LIST_UNLINK(forwarders->fwdrs, fwd, link);
+               if (fwd->tlsname != NULL) {
+                       dns_name_free(fwd->tlsname, fwdtable->mctx);
+                       isc_mem_put(fwdtable->mctx, fwd->tlsname,
+                                   sizeof(*fwd->tlsname));
+               }
                isc_mem_put(fwdtable->mctx, fwd, sizeof(*fwd));
        }
        isc_mem_put(fwdtable->mctx, forwarders, sizeof(*forwarders));
index f43fce789d04c68ae5fb86b352c1afb84fffca2b..1733fdb232772292ca25c0e7b3d53099615d7d15 100644 (file)
@@ -25,6 +25,7 @@ ISC_LANG_BEGINDECLS
 
 struct dns_forwarder {
        isc_sockaddr_t addr;
+       dns_name_t    *tlsname;
        ISC_LINK(dns_forwarder_t) link;
 };