mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-13 20:00:01 -04:00
[9.20] fix: usr: Resolve "key defined in view is not found"
Commit `2956e4fc` hardened the `key` name check when used in `primaries` to reject the configuration if the key was not defined, rather than simply checking whether the key name was correctly formed. However, the key name check didn't include the view configuration, causing keys not to be recognized if they were defined inside the view and not at the global level. This regression is now fixed. Backport of MR !11588 Closes #5761 Merge branch 'backport-5761-key-view-9.20' into 'bind-9.20' See merge request isc-projects/bind9!11613
This commit is contained in:
commit
819fe45274
2 changed files with 94 additions and 55 deletions
27
bin/tests/system/checkconf/good-key-view.conf
Normal file
27
bin/tests/system/checkconf/good-key-view.conf
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||
*
|
||||
* SPDX-License-Identifier: MPL-2.0
|
||||
*
|
||||
* 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 https://mozilla.org/MPL/2.0/.
|
||||
*
|
||||
* See the COPYRIGHT file distributed with this work for additional
|
||||
* information regarding copyright ownership.
|
||||
*/
|
||||
|
||||
view aview {
|
||||
key akey {
|
||||
algorithm hmac-sha256;
|
||||
secret "9999abcd8765";
|
||||
};
|
||||
|
||||
zone "azone" {
|
||||
type secondary;
|
||||
file "azone.db";
|
||||
primaries {
|
||||
1.2.3.4 key "akey";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -87,8 +87,10 @@ static const cfg_obj_t *
|
|||
find_maplist(const cfg_obj_t *config, const char *listname, const char *name);
|
||||
|
||||
static isc_result_t
|
||||
validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *config,
|
||||
uint32_t *countp, isc_log_t *logctx, isc_mem_t *mctx);
|
||||
validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *voptions,
|
||||
const cfg_obj_t *config, uint32_t *countp, isc_log_t *logctx,
|
||||
isc_mem_t *mctx);
|
||||
|
||||
static void
|
||||
freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
|
||||
UNUSED(type);
|
||||
|
|
@ -2213,7 +2215,8 @@ check_remoteserverlist(const cfg_obj_t *cctx, const char *list,
|
|||
}
|
||||
|
||||
uint32_t dummy = 0;
|
||||
result = validate_remotes(obj, cctx, &dummy, logctx, mctx);
|
||||
result = validate_remotes(obj, NULL, cctx, &dummy, logctx,
|
||||
mctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -2578,17 +2581,58 @@ get_remoteservers_def(const char *name, const cfg_obj_t *cctx,
|
|||
return get_remotes(cctx, "masters", name, ret);
|
||||
}
|
||||
|
||||
static bool
|
||||
lookup_key(const cfg_obj_t *config, const dns_name_t *keyname) {
|
||||
const cfg_obj_t *keys = NULL;
|
||||
|
||||
if (config == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
(void)cfg_map_get(config, "key", &keys);
|
||||
for (const cfg_listelt_t *elt = cfg_list_first(keys); elt != NULL;
|
||||
elt = cfg_list_next(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);
|
||||
isc_result_t result = dns_name_fromstring(
|
||||
foundkeyname, foundkeystr, dns_rootname, 0, NULL);
|
||||
|
||||
if (result == ISC_R_SUCCESS &&
|
||||
dns_name_equal(keyname, foundkeyname))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
validate_remotes_key(const cfg_obj_t *config, const cfg_obj_t *key,
|
||||
isc_log_t *logctx) {
|
||||
validate_remotes_key(const cfg_obj_t *voptions, const cfg_obj_t *config,
|
||||
const cfg_obj_t *key, isc_log_t *logctx) {
|
||||
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) {
|
||||
|
|
@ -2596,47 +2640,14 @@ validate_remotes_key(const cfg_obj_t *config, const cfg_obj_t *key,
|
|||
"'%s' is not a valid name", str);
|
||||
}
|
||||
|
||||
result = cfg_map_get(config, "key", &keys);
|
||||
|
||||
for (const cfg_listelt_t *elt = cfg_list_first(keys);
|
||||
elt != NULL; elt = cfg_list_next(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 (!lookup_key(voptions, nm)) {
|
||||
if (!lookup_key(config, nm)) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"key '%s' is not defined",
|
||||
cfg_obj_asstring(key));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
cfg_obj_log(key, logctx, ISC_LOG_ERROR,
|
||||
"key '%s' is not defined",
|
||||
cfg_obj_asstring(key));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -2675,8 +2686,9 @@ validate_remotes_tls(const cfg_obj_t *config, const cfg_obj_t *tls,
|
|||
}
|
||||
|
||||
static isc_result_t
|
||||
validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *config,
|
||||
uint32_t *countp, isc_log_t *logctx, isc_mem_t *mctx) {
|
||||
validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *voptions,
|
||||
const cfg_obj_t *config, uint32_t *countp, isc_log_t *logctx,
|
||||
isc_mem_t *mctx) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_result_t tresult;
|
||||
uint32_t count = 0;
|
||||
|
|
@ -2709,7 +2721,7 @@ 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, logctx);
|
||||
result = validate_remotes_key(voptions, config, key, logctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -3776,8 +3788,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
}
|
||||
if (tresult == ISC_R_SUCCESS && donotify) {
|
||||
uint32_t count;
|
||||
tresult = validate_remotes(obj, config, &count, logctx,
|
||||
mctx);
|
||||
tresult = validate_remotes(obj, voptions, config,
|
||||
&count, logctx, mctx);
|
||||
if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
|
||||
{
|
||||
result = tresult;
|
||||
|
|
@ -3819,8 +3831,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
result = ISC_R_FAILURE;
|
||||
} else {
|
||||
uint32_t count;
|
||||
tresult = validate_remotes(obj, config, &count, logctx,
|
||||
mctx);
|
||||
tresult = validate_remotes(obj, voptions, config,
|
||||
&count, logctx, mctx);
|
||||
if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
|
||||
{
|
||||
result = tresult;
|
||||
|
|
@ -3872,8 +3884,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
(void)cfg_map_get(zoptions, "parental-agents", &obj);
|
||||
if (obj != NULL) {
|
||||
uint32_t count;
|
||||
tresult = validate_remotes(obj, config, &count, logctx,
|
||||
mctx);
|
||||
tresult = validate_remotes(obj, voptions, config,
|
||||
&count, logctx, mctx);
|
||||
if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
|
||||
{
|
||||
result = tresult;
|
||||
|
|
|
|||
Loading…
Reference in a new issue