From: Colin Vidal Date: Tue, 25 Nov 2025 14:45:22 +0000 (+0100) Subject: check validity of key and tls in a server-list X-Git-Tag: v9.21.16~18^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2956e4fc45b3c2142a3351682d4200647448f193;p=thirdparty%2Fbind9.git check validity of key and tls in a server-list If a `key` or `tls` is associated to an IP address inside a server-list, only the `tls` existence in the configuration was checked. Also, if `key` or `tls` is associated to a named server-list inside a server-list, there was no check at all. Add the check for making sure a `key` is defined in the configuration, as well as the check for `key` and `tls` when used on a named server-list. --- diff --git a/bin/named/config.c b/bin/named/config.c index a3b75ef5936..32918feba69 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -359,7 +359,7 @@ getipandkeylist(in_port_t defport, in_port_t deftlsport, const cfg_obj_t *portobj = cfg_tuple_get(list, "port"); const cfg_obj_t *src4obj = cfg_tuple_get(list, "source"); const cfg_obj_t *src6obj = cfg_tuple_get(list, "source-v6"); - in_port_t port; + in_port_t port = (in_port_t)0; isc_sockaddr_t src4; isc_sockaddr_t src6; isc_result_t result = ISC_R_SUCCESS; diff --git a/lib/isccfg/check.c b/lib/isccfg/check.c index 6ff5b12a0bd..59d73b3030f 100644 --- a/lib/isccfg/check.c +++ b/lib/isccfg/check.c @@ -2423,6 +2423,96 @@ get_remoteservers_def(const char *name, const cfg_obj_t *cctx, return get_remotes(cctx, "masters", name, ret); } +static isc_result_t +validate_remotes_key(const cfg_obj_t *config, const cfg_obj_t *key) { + isc_result_t result = ISC_R_SUCCESS; + + if (cfg_obj_isstring(key)) { + const cfg_obj_t *keys = NULL; + const char *str = cfg_obj_asstring(key); + dns_fixedname_t fname; + dns_name_t *nm = dns_fixedname_initname(&fname); + bool found = false; + + result = dns_name_fromstring(nm, str, dns_rootname, 0, NULL); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(key, ISC_LOG_ERROR, + "'%s' is not a valid name", str); + } + + result = cfg_map_get(config, "key", &keys); + CFG_LIST_FOREACH(keys, elt) { + /* + * `key` are normalized TSIG which must be identified by + * a domain name, so this is needed. Otherwise, with a + * raw string comparison we could have: + * + * remote-servers { x.y.z.s key foo }; + * key foo. { + * ... + * }; + * + * This would otherwise fail, even though the key + * exists. + */ + const cfg_obj_t *foundkey = cfg_listelt_value(elt); + const char *foundkeystr = + cfg_obj_asstring(cfg_map_getname(foundkey)); + dns_fixedname_t foundfname; + dns_name_t *foundkeyname = + dns_fixedname_initname(&foundfname); + + result = dns_name_fromstring(foundkeyname, foundkeystr, + dns_rootname, 0, NULL); + + if (dns_name_equal(nm, foundkeyname)) { + found = true; + break; + } + } + + if (!found) { + cfg_obj_log(key, ISC_LOG_ERROR, + "key '%s' is not defined", + cfg_obj_asstring(key)); + result = ISC_R_FAILURE; + } + } + + return result; +} + +static isc_result_t +validate_remotes_tls(const cfg_obj_t *config, const cfg_obj_t *tls) { + isc_result_t result = ISC_R_SUCCESS; + + if (cfg_obj_isstring(tls)) { + const char *str = cfg_obj_asstring(tls); + dns_fixedname_t fname; + dns_name_t *nm = dns_fixedname_initname(&fname); + + result = dns_name_fromstring(nm, str, dns_rootname, 0, NULL); + if (result != ISC_R_SUCCESS) { + cfg_obj_log(tls, ISC_LOG_ERROR, + "'%s' is not a valid name", str); + } + + if (strcasecmp(str, "ephemeral") != 0) { + const cfg_obj_t *tlsmap = NULL; + + tlsmap = find_maplist(config, "tls", str); + if (tlsmap == NULL) { + cfg_obj_log(tls, ISC_LOG_ERROR, + "tls '%s' is not defined", + cfg_obj_asstring(tls)); + result = ISC_R_FAILURE; + } + } + } + + return result; +} + static isc_result_t validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *config, uint32_t *countp, isc_mem_t *mctx) { @@ -2454,53 +2544,19 @@ resume: key = cfg_tuple_get(cfg_listelt_value(element), "key"); tls = cfg_tuple_get(cfg_listelt_value(element), "tls"); + result = validate_remotes_key(config, key); + if (result != ISC_R_SUCCESS) { + goto out; + } + + result = validate_remotes_tls(config, tls); + if (result != ISC_R_SUCCESS) { + goto out; + } + if (cfg_obj_issockaddr(addr)) { count++; - if (cfg_obj_isstring(key)) { - const char *str = cfg_obj_asstring(key); - dns_fixedname_t fname; - dns_name_t *nm = dns_fixedname_initname(&fname); - tresult = dns_name_fromstring( - nm, str, dns_rootname, 0, NULL); - if (tresult != ISC_R_SUCCESS) { - cfg_obj_log(key, ISC_LOG_ERROR, - "'%s' is not a valid name", - str); - if (result == ISC_R_SUCCESS) { - result = tresult; - } - } - } - if (cfg_obj_isstring(tls)) { - const char *str = cfg_obj_asstring(tls); - dns_fixedname_t fname; - dns_name_t *nm = dns_fixedname_initname(&fname); - tresult = dns_name_fromstring( - nm, str, dns_rootname, 0, NULL); - if (tresult != ISC_R_SUCCESS) { - cfg_obj_log(tls, ISC_LOG_ERROR, - "'%s' is not a valid name", - str); - if (result == ISC_R_SUCCESS) { - result = tresult; - } - } - if (strcasecmp(str, "ephemeral") != 0) { - const cfg_obj_t *tlsmap = NULL; - - tlsmap = find_maplist(config, "tls", - str); - if (tlsmap == NULL) { - cfg_obj_log( - tls, ISC_LOG_ERROR, - "tls '%s' is not " - "defined", - cfg_obj_asstring(tls)); - result = ISC_R_FAILURE; - } - } - } continue; } listname = cfg_obj_asstring(addr); @@ -2534,11 +2590,14 @@ resume: element = stack[--pushed]; goto resume; } + + *countp = count; + +out: if (stack != NULL) { isc_mem_cput(mctx, stack, stackcount, sizeof(*stack)); } isc_symtab_destroy(&symtab); - *countp = count; return result; }