]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
minimal fix for missing `key`/`tls` in named `remote-servers`
authorColin Vidal <colin@isc.org>
Tue, 25 Nov 2025 09:16:13 +0000 (10:16 +0100)
committerColin Vidal <colin@isc.org>
Fri, 28 Nov 2025 08:10:53 +0000 (09:10 +0100)
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.

bin/named/config.c

index 05c832798a1af82f1856056f03f9077be30158dd..6e0c835bc30b755ea5e3959045b14a182a415ce4 100644 (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) {