diff --git a/bin/named/server.c b/bin/named/server.c index ae72b80985..02e09b13f6 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -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 index 0000000000..1d63d9765a --- /dev/null +++ b/bin/tests/system/checkconf/bad-doh-1.conf @@ -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 index 0000000000..3f6d991c67 --- /dev/null +++ b/bin/tests/system/checkconf/bad-doh-2.conf @@ -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 index 0000000000..ff697ef578 --- /dev/null +++ b/bin/tests/system/checkconf/bad-doh-3.conf @@ -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 index 0000000000..5df1acacc6 --- /dev/null +++ b/bin/tests/system/checkconf/bad-dot-1.conf @@ -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; }; +}; diff --git a/bin/tests/system/checkconf/good-dot-global.conf b/bin/tests/system/checkconf/good-dot-1.conf similarity index 100% rename from bin/tests/system/checkconf/good-dot-global.conf rename to bin/tests/system/checkconf/good-dot-1.conf diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 67f2f96642..d514936be0 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -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_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx, - optlevel_t optlevel) { +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_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;