diff --git a/bin/named/config.c b/bin/named/config.c index fbc0d3dd31..e247557b0b 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -623,7 +623,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 a2c605bd77..0999c740d5 100644 --- a/lib/isccfg/check.c +++ b/lib/isccfg/check.c @@ -2578,6 +2578,102 @@ 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_log_t *logctx) { + 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, logctx, ISC_LOG_ERROR, + "'%s' is not a valid name", str); + } + + result = cfg_map_get(config, "key", &keys); + + for (const cfg_listelt_t *elt = cfg_list_first(keys); + elt != NULL; elt = cfg_list_next(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, logctx, 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_log_t *logctx) { + 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, logctx, 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, logctx, 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_log_t *logctx, isc_mem_t *mctx) { @@ -2613,54 +2709,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, logctx); + if (result != ISC_R_SUCCESS) { + goto out; + } + + result = validate_remotes_tls(config, tls, logctx); + 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, logctx, 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, logctx, 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, logctx, - ISC_LOG_ERROR, - "tls '%s' is not " - "defined", - cfg_obj_asstring(tls)); - result = ISC_R_FAILURE; - } - } - } continue; } listname = cfg_obj_asstring(addr); @@ -2694,11 +2755,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; }