move listen-on correctness checks into check.c

errors in listen-on and listen-on-v6 can now be detected
by named-checkconf.
This commit is contained in:
Evan Hunt 2021-02-03 13:13:41 -08:00
parent fd763d7223
commit 957052eea5
7 changed files with 250 additions and 20 deletions

View 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);

View file

@ -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; };
};

View file

@ -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; };
};

View file

@ -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; };
};

View file

@ -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; };
};

View 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_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;