mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
fix: usr: Resolve "key defined in view is not found"
A recent change in `2956e4fc45b3c2142a3351682d4200647448f193` hardened the `key` name check when used in `primaries` to immediately reject the configuration if the key was not defined (rather than only checking whether the key name was correctly formed). However, the change introduced a regression that prevented the use of a `key` defined in a view. This is now fixed. Merge branch '5761-key-view' into 'main' See merge request isc-projects/bind9!11588
This commit is contained in:
commit
0d5f47e3ec
2 changed files with 88 additions and 47 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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -85,8 +85,8 @@ 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_mem_t *mctx);
|
||||
validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *voptions,
|
||||
const cfg_obj_t *config, uint32_t *countp, isc_mem_t *mctx);
|
||||
static void
|
||||
freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
|
||||
UNUSED(type);
|
||||
|
|
@ -2093,7 +2093,7 @@ check_remoteserverlist(const cfg_obj_t *cctx, const char *list,
|
|||
}
|
||||
|
||||
uint32_t dummy = 0;
|
||||
result = validate_remotes(obj, cctx, &dummy, mctx);
|
||||
result = validate_remotes(obj, NULL, cctx, &dummy, mctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -2423,16 +2423,56 @@ 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);
|
||||
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);
|
||||
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) {
|
||||
validate_remotes_key(const cfg_obj_t *voptions, 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) {
|
||||
|
|
@ -2440,43 +2480,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);
|
||||
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 (!lookup_key(voptions, nm)) {
|
||||
if (!lookup_key(config, nm)) {
|
||||
cfg_obj_log(key, ISC_LOG_ERROR,
|
||||
"key '%s' is not defined",
|
||||
cfg_obj_asstring(key));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
cfg_obj_log(key, ISC_LOG_ERROR,
|
||||
"key '%s' is not defined",
|
||||
cfg_obj_asstring(key));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -2514,8 +2525,8 @@ 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_mem_t *mctx) {
|
||||
validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *voptions,
|
||||
const cfg_obj_t *config, uint32_t *countp, isc_mem_t *mctx) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
isc_result_t tresult;
|
||||
uint32_t count = 0;
|
||||
|
|
@ -2544,7 +2555,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);
|
||||
result = validate_remotes_key(voptions, config, key);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -3680,7 +3691,8 @@ isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
}
|
||||
if (obj != NULL && donotify) {
|
||||
uint32_t count;
|
||||
tresult = validate_remotes(obj, config, &count, mctx);
|
||||
tresult = validate_remotes(obj, voptions, config,
|
||||
&count, mctx);
|
||||
if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
|
||||
{
|
||||
result = tresult;
|
||||
|
|
@ -3766,7 +3778,8 @@ isccfg_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, mctx);
|
||||
tresult = validate_remotes(obj, voptions, config,
|
||||
&count, mctx);
|
||||
if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
|
||||
{
|
||||
result = tresult;
|
||||
|
|
@ -3791,7 +3804,8 @@ isccfg_check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
|||
"parental-agents", &obj);
|
||||
if (obj != NULL) {
|
||||
uint32_t count;
|
||||
tresult = validate_remotes(obj, config, &count, mctx);
|
||||
tresult = validate_remotes(obj, voptions, config,
|
||||
&count, mctx);
|
||||
if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS)
|
||||
{
|
||||
result = tresult;
|
||||
|
|
|
|||
Loading…
Reference in a new issue