minimal fix for missing key/tls in named remote-servers

The following case

   remote-servers foo { 10.53.0.5; };
   remote-servers bar { foo key fookey; };

did not work: the `fookey` was silently ignored. No matter how `bar` was
used, the server `10.53.0.5` wouldn't be contacted using the TSIG key
`fookey`. The problem is the same the for `tls` property.

The reason of the problem was that when `named_config_getipandkeylist()`
reached a named server-list (here, `foo`), it modified the current
context in order to immediately process what is inside `foo`, but forgot
to look at the fields `key` and `tls`, to associate those with `foo`
addresses.

Fix the problem by wrapping the `key` and `tls` from the "caller" list
inside the existing `lists` struct which is used to figure out if a
list is already processed or not. That way, the `key` and `tls` values
can be read when adding the addresses of the nested list.
This commit is contained in:
Colin Vidal 2025-11-25 10:16:13 +01:00
parent 9c96c38268
commit e732a8d25a

View file

@ -353,9 +353,8 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
dns_name_t **tlss = NULL;
struct {
const char *name;
in_port_t port;
isc_sockaddr_t *src4s;
isc_sockaddr_t *src6s;
dns_name_t *key;
dns_name_t *tls;
} *lists = NULL;
struct {
const cfg_listelt_t *element;
@ -462,7 +461,20 @@ resume:
result = tresult;
goto cleanup;
}
lists[l++].name = listname;
lists[l].name = listname;
result = named_config_getname(mctx, key, &lists[l].key);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
result = named_config_getname(mctx, tls, &lists[l].tls);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
l++;
/* Grow stack? */
grow_array(mctx, stack, pushed, stackcount);
/*
@ -491,6 +503,12 @@ resume:
goto cleanup;
}
if (keys[i] == NULL && lists != NULL && lists[l-1].key != NULL) {
keys[i] = isc_mem_get(mctx, sizeof(*keys[i]));
dns_name_init(keys[i]);
dns_name_dup(lists[l-1].key, mctx, keys[i]);
}
result = named_config_getname(mctx, tls, &tlss[i]);
if (result != ISC_R_SUCCESS) {
i++; /* Increment here so that cleanup on error works.
@ -498,6 +516,12 @@ resume:
goto cleanup;
}
if (tlss[i] == NULL && lists != NULL && lists[l-1].tls != NULL) {
tlss[i] = isc_mem_get(mctx, sizeof(*tlss[i]));
dns_name_init(tlss[i]);
dns_name_dup(lists[l-1].tls, mctx, tlss[i]);
}
/* If the port is unset, take it from one of the upper levels */
if (isc_sockaddr_getport(&addrs[i]) == 0) {
in_port_t addr_port = port;
@ -536,6 +560,7 @@ resume:
port = stack[pushed].port;
src4 = stack[pushed].src4;
src6 = stack[pushed].src6;
l--;
goto resume;
}
@ -545,6 +570,23 @@ resume:
shrink_array(mctx, sources, i, srccount);
if (lists != NULL) {
for (size_t j = 0; j < listcount; j++) {
if (lists[j].key != NULL) {
if (dns_name_dynamic(lists[j].key)) {
dns_name_free(lists[j].key, mctx);
}
isc_mem_put(mctx, lists[j].key,
sizeof(*lists[j].key));
}
if (lists[j].tls != NULL) {
if (dns_name_dynamic(lists[j].tls)) {
dns_name_free(lists[j].tls, mctx);
}
isc_mem_put(mctx, lists[j].tls,
sizeof(*lists[j].tls));
}
}
isc_mem_cput(mctx, lists, listcount, sizeof(lists[0]));
}
if (stack != NULL) {
@ -596,6 +638,23 @@ cleanup:
isc_mem_cput(mctx, sources, srccount, sizeof(sources[0]));
}
if (lists != NULL) {
for (size_t j = 0; j < listcount; j++) {
if (lists[j].key != NULL) {
if (dns_name_dynamic(lists[j].key)) {
dns_name_free(lists[j].key, mctx);
}
isc_mem_put(mctx, lists[j].key,
sizeof(*lists[j].key));
}
if (lists[j].tls != NULL) {
if (dns_name_dynamic(lists[j].tls)) {
dns_name_free(lists[j].tls, mctx);
}
isc_mem_put(mctx, lists[j].tls,
sizeof(*lists[j].tls));
}
}
isc_mem_cput(mctx, lists, listcount, sizeof(lists[0]));
}
if (stack != NULL) {