diff --git a/bin/named/server.c b/bin/named/server.c index a49fbf4bea..cf9fe130e9 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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)); } diff --git a/lib/dns/forward.c b/lib/dns/forward.c index 8750569c5d..ef05529d83 100644 --- a/lib/dns/forward.c +++ b/lib/dns/forward.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -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)); diff --git a/lib/dns/include/dns/forward.h b/lib/dns/include/dns/forward.h index f43fce789d..1733fdb232 100644 --- a/lib/dns/include/dns/forward.h +++ b/lib/dns/include/dns/forward.h @@ -25,6 +25,7 @@ ISC_LANG_BEGINDECLS struct dns_forwarder { isc_sockaddr_t addr; + dns_name_t *tlsname; ISC_LINK(dns_forwarder_t) link; };