]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
check validity of key and tls in a server-list
authorColin Vidal <colin@isc.org>
Tue, 25 Nov 2025 14:45:22 +0000 (15:45 +0100)
committerColin Vidal <colin@isc.org>
Fri, 28 Nov 2025 08:10:54 +0000 (09:10 +0100)
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.

bin/named/config.c
lib/isccfg/check.c

index a3b75ef5936df039fd6a8a84e5517c6bdb235a5f..32918feba692b7b36d9fefc428403619a2f3f960 100644 (file)
@@ -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;
index 6ff5b12a0bdbbb42762dfa3ad0ed70ffb48bdc2d..59d73b3030ff305f92ba4b2d476f06cf6165c73a 100644 (file)
@@ -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;
 }