]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
move listen-on correctness checks into check.c
authorEvan Hunt <each@isc.org>
Wed, 3 Feb 2021 21:13:41 +0000 (13:13 -0800)
committerEvan Hunt <each@isc.org>
Wed, 17 Feb 2021 00:24:35 +0000 (16:24 -0800)
errors in listen-on and listen-on-v6 can now be detected
by named-checkconf.

bin/named/server.c
bin/tests/system/checkconf/bad-doh-1.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-doh-2.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-doh-3.conf [new file with mode: 0644]
bin/tests/system/checkconf/bad-dot-1.conf [new file with mode: 0644]
bin/tests/system/checkconf/good-dot-1.conf [moved from bin/tests/system/checkconf/good-dot-global.conf with 100% similarity]
lib/bind9/check.c

index ae72b8098565947ce9d1c5c64e7a577f0d030707..02e09b13f632b43206a2440302e043bb5f3b9874 100644 (file)
@@ -11106,18 +11106,11 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                const char *httpname = cfg_obj_asstring(httpobj);
 
                if (!do_tls && !no_tls) {
-                       cfg_obj_log(httpobj, named_g_lctx, ISC_LOG_ERROR,
-                                   "http must specify a 'tls' "
-                                   "statement, 'tls ephemeral', or "
-                                   "'tls none'");
                        return (ISC_R_FAILURE);
                }
 
                http_server = find_maplist(config, "http", httpname);
                if (http_server == NULL) {
-                       cfg_obj_log(httpobj, named_g_lctx, ISC_LOG_ERROR,
-                                   "http '%s' is not defined",
-                                   cfg_obj_asstring(httpobj));
                        return (ISC_R_FAILURE);
                }
 
@@ -11169,10 +11162,6 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                }
        } else {
                if (cfg_obj_asuint32(portobj) >= UINT16_MAX) {
-                       cfg_obj_log(portobj, named_g_lctx, ISC_LOG_ERROR,
-                                   "port value '%u' is out of range",
-
-                                   cfg_obj_asuint32(portobj));
                        return (ISC_R_RANGE);
                }
                port = (in_port_t)cfg_obj_asuint32(portobj);
@@ -11183,9 +11172,6 @@ listenelt_fromconfig(const cfg_obj_t *listener, const cfg_obj_t *config,
                dscp = named_g_dscp;
        } else {
                if (cfg_obj_asuint32(dscpobj) > 63) {
-                       cfg_obj_log(dscpobj, named_g_lctx, ISC_LOG_ERROR,
-                                   "dscp value '%u' is out of range",
-                                   cfg_obj_asuint32(dscpobj));
                        return (ISC_R_RANGE);
                }
                dscp = (isc_dscp_t)cfg_obj_asuint32(dscpobj);
diff --git a/bin/tests/system/checkconf/bad-doh-1.conf b/bin/tests/system/checkconf/bad-doh-1.conf
new file mode 100644 (file)
index 0000000..1d63d97
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+       key-file "key.pem";
+       cert-file "cert.pem";
+};
+
+http local-http-server {
+       endpoints { "/dns-query"; };
+};
+
+# undefined 'tls' specification
+options {
+       listen-on port 8080 http local-http-server tls unknown { 10.53.0.1; };
+};
diff --git a/bin/tests/system/checkconf/bad-doh-2.conf b/bin/tests/system/checkconf/bad-doh-2.conf
new file mode 100644 (file)
index 0000000..3f6d991
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+tls local-tls {
+       key-file "key.pem";
+       cert-file "cert.pem";
+};
+
+# undefined 'http' specification
+options {
+       listen-on port 8080 http unknown tls local-tls { 10.53.0.1; };
+};
diff --git a/bin/tests/system/checkconf/bad-doh-3.conf b/bin/tests/system/checkconf/bad-doh-3.conf
new file mode 100644 (file)
index 0000000..ff697ef
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+http local-http-server {
+       endpoints { "/dns-query"; };
+};
+
+# no 'tls' specification
+options {
+       listen-on port 8080 http unknown { 10.53.0.1; };
+};
diff --git a/bin/tests/system/checkconf/bad-dot-1.conf b/bin/tests/system/checkconf/bad-dot-1.conf
new file mode 100644 (file)
index 0000000..5df1aca
--- /dev/null
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+# undefined 'tls' specification
+options {
+       listen-on port 853 tls local-tls { 10.53.0.1; };
+};
index 67f2f96642fd5b5ddbab3e2588834ca653312dcb..d514936be08dd51b13677a19081932c6882ceebd 100644 (file)
@@ -896,9 +896,146 @@ kasp_name_allowed(const cfg_listelt_t *element) {
        return (true);
 }
 
+static const cfg_obj_t *
+find_maplist(const cfg_obj_t *config, const char *listname, const char *name) {
+       isc_result_t result;
+       const cfg_obj_t *maplist = NULL;
+       const cfg_listelt_t *elt = NULL;
+
+       REQUIRE(config != NULL);
+       REQUIRE(name != NULL);
+
+       result = cfg_map_get(config, listname, &maplist);
+       if (result != ISC_R_SUCCESS) {
+               return (NULL);
+       }
+
+       for (elt = cfg_list_first(maplist); elt != NULL;
+            elt = cfg_list_next(elt)) {
+               const cfg_obj_t *map = cfg_listelt_value(elt);
+               if (strcasecmp(cfg_obj_asstring(cfg_map_getname(map)), name) ==
+                   0) {
+                       return (map);
+               }
+       }
+
+       return (NULL);
+}
+
+static isc_result_t
+check_listener(const cfg_obj_t *listener, const cfg_obj_t *config,
+              cfg_aclconfctx_t *actx, isc_log_t *logctx, isc_mem_t *mctx) {
+       isc_result_t tresult, result = ISC_R_SUCCESS;
+       const cfg_obj_t *ltup = NULL;
+       const cfg_obj_t *tlsobj = NULL, *httpobj = NULL;
+       const cfg_obj_t *portobj = NULL, *dscpobj = NULL;
+       const cfg_obj_t *http_server = NULL;
+       bool do_tls = false, no_tls = false;
+       dns_acl_t *acl = NULL;
+
+       ltup = cfg_tuple_get(listener, "tuple");
+       RUNTIME_CHECK(ltup != NULL);
+
+       tlsobj = cfg_tuple_get(ltup, "tls");
+       if (tlsobj != NULL && cfg_obj_isstring(tlsobj)) {
+               const char *tlsname = cfg_obj_asstring(tlsobj);
+
+               if (strcasecmp(tlsname, "none") == 0) {
+                       no_tls = true;
+               } else if (strcasecmp(tlsname, "ephemeral") == 0) {
+                       do_tls = true;
+               } else {
+                       const cfg_obj_t *tlsmap = NULL;
+
+                       do_tls = true;
+
+                       tlsmap = find_maplist(config, "tls", tlsname);
+                       if (tlsmap == NULL) {
+                               cfg_obj_log(tlsobj, logctx, ISC_LOG_ERROR,
+                                           "tls '%s' is not defined",
+                                           cfg_obj_asstring(tlsobj));
+                               result = ISC_R_FAILURE;
+                       }
+               }
+       }
+
+       httpobj = cfg_tuple_get(ltup, "http");
+       if (httpobj != NULL && cfg_obj_isstring(httpobj)) {
+               const char *httpname = cfg_obj_asstring(httpobj);
+
+               if (!do_tls && !no_tls) {
+                       cfg_obj_log(httpobj, logctx, ISC_LOG_ERROR,
+                                   "http must specify a 'tls' "
+                                   "statement, 'tls ephemeral', or "
+                                   "'tls none'");
+                       result = ISC_R_FAILURE;
+               }
+
+               http_server = find_maplist(config, "http", httpname);
+               if (http_server == NULL) {
+                       cfg_obj_log(httpobj, logctx, ISC_LOG_ERROR,
+                                   "http '%s' is not defined",
+                                   cfg_obj_asstring(httpobj));
+                       result = ISC_R_FAILURE;
+               }
+       }
+
+       portobj = cfg_tuple_get(ltup, "port");
+       if (cfg_obj_isuint32(portobj) &&
+           cfg_obj_asuint32(portobj) >= UINT16_MAX) {
+               cfg_obj_log(portobj, logctx, ISC_LOG_ERROR,
+                           "port value '%u' is out of range",
+
+                           cfg_obj_asuint32(portobj));
+               if (result == ISC_R_SUCCESS) {
+                       result = ISC_R_RANGE;
+               }
+       }
+
+       dscpobj = cfg_tuple_get(ltup, "dscp");
+       if (cfg_obj_isuint32(dscpobj) && cfg_obj_asuint32(dscpobj) > 63) {
+               cfg_obj_log(dscpobj, logctx, ISC_LOG_ERROR,
+                           "dscp value '%u' is out of range",
+                           cfg_obj_asuint32(dscpobj));
+               if (result == ISC_R_SUCCESS) {
+                       result = ISC_R_RANGE;
+               }
+       }
+
+       tresult = cfg_acl_fromconfig(cfg_tuple_get(listener, "acl"), config,
+                                    logctx, actx, mctx, 0, &acl);
+       if (result == ISC_R_SUCCESS) {
+               result = tresult;
+       }
+
+       if (acl != NULL) {
+               dns_acl_detach(&acl);
+       }
+
+       return (result);
+}
+
 static isc_result_t
-check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
-             optlevel_t optlevel) {
+check_listeners(const cfg_obj_t *list, const cfg_obj_t *config,
+               cfg_aclconfctx_t *actx, isc_log_t *logctx, isc_mem_t *mctx) {
+       isc_result_t tresult, result = ISC_R_SUCCESS;
+       const cfg_listelt_t *elt = NULL;
+
+       for (elt = cfg_list_first(list); elt != NULL; elt = cfg_list_next(elt))
+       {
+               const cfg_obj_t *obj = cfg_listelt_value(elt);
+               tresult = check_listener(obj, config, actx, logctx, mctx);
+               if (result == ISC_R_SUCCESS) {
+                       result = tresult;
+               }
+       }
+
+       return (result);
+}
+
+static isc_result_t
+check_options(const cfg_obj_t *options, const cfg_obj_t *config,
+             isc_log_t *logctx, isc_mem_t *mctx, optlevel_t optlevel) {
        isc_result_t result = ISC_R_SUCCESS;
        isc_result_t tresult;
        unsigned int i;
@@ -911,6 +1048,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
        uint32_t lifetime = 3600;
        bool has_dnssecpolicy = false;
        const char *ccalg = "siphash24";
+       cfg_aclconfctx_t *actx = NULL;
 
        /*
         * { "name", scale, value }
@@ -1666,6 +1804,32 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
                }
        }
 
+       cfg_aclconfctx_create(mctx, &actx);
+
+       obj = NULL;
+       (void)cfg_map_get(options, "listen-on", &obj);
+       if (obj != NULL) {
+               INSIST(config != NULL);
+               tresult = check_listeners(obj, config, actx, logctx, mctx);
+               if (result == ISC_R_SUCCESS) {
+                       result = tresult;
+               }
+       }
+
+       obj = NULL;
+       (void)cfg_map_get(options, "listen-on-v6", &obj);
+       if (obj != NULL) {
+               INSIST(config != NULL);
+               tresult = check_listeners(obj, config, actx, logctx, mctx);
+               if (result == ISC_R_SUCCESS) {
+                       result = tresult;
+               }
+       }
+
+       if (actx != NULL) {
+               cfg_aclconfctx_detach(&actx);
+       }
+
        return (result);
 }
 
@@ -3043,7 +3207,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
        /*
         * Check various options.
         */
-       tresult = check_options(zoptions, logctx, mctx, optlevel_zone);
+       tresult = check_options(zoptions, config, logctx, mctx, optlevel_zone);
        if (tresult != ISC_R_SUCCESS) {
                result = tresult;
        }
@@ -4529,9 +4693,11 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
         * Check options.
         */
        if (voptions != NULL) {
-               tresult = check_options(voptions, logctx, mctx, optlevel_view);
+               tresult = check_options(voptions, NULL, logctx, mctx,
+                                       optlevel_view);
        } else {
-               tresult = check_options(config, logctx, mctx, optlevel_config);
+               tresult = check_options(config, config, logctx, mctx,
+                                       optlevel_config);
        }
        if (tresult != ISC_R_SUCCESS) {
                result = tresult;
@@ -4870,7 +5036,7 @@ bind9_check_namedconf(const cfg_obj_t *config, bool check_plugins,
 
        (void)cfg_map_get(config, "options", &options);
 
-       if (options != NULL && check_options(options, logctx, mctx,
+       if (options != NULL && check_options(options, config, logctx, mctx,
                                             optlevel_options) != ISC_R_SUCCESS)
        {
                result = ISC_R_FAILURE;