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.

(cherry picked from commit 2956e4fc45)
This commit is contained in:
Colin Vidal 2025-11-25 15:45:22 +01:00
parent b260f7be90
commit 9e8994d853
2 changed files with 111 additions and 47 deletions

View file

@ -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;

View file

@ -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;
}