mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-23 10:37:43 -04:00
fix: usr: Fix parsing bug in remote-servers with key or tls
The :any:`remote-servers` clause enable the following pattern using a named ``server-list``:
remote-servers a { 1.2.3.4; ... };
remote-servers b { a key foo; };
However, such configuration was wrongly rejected, with an "unexpected token 'foo'" error. Such configuration is now accepted.
Closes #5646
Merge branch '5646-fix-named-remote-servers-key-tls' into 'main'
See merge request isc-projects/bind9!11252
This commit is contained in:
commit
51af07cdee
13 changed files with 759 additions and 297 deletions
|
|
@ -329,40 +329,232 @@ named_config_getname(isc_mem_t *mctx, const cfg_obj_t *obj,
|
|||
static const char *remotesnames[4] = { "remote-servers", "parental-agents",
|
||||
"primaries", "masters" };
|
||||
|
||||
typedef struct {
|
||||
isc_sockaddr_t *addrs;
|
||||
size_t addrsallocated;
|
||||
|
||||
isc_sockaddr_t *sources;
|
||||
size_t sourcesallocated;
|
||||
|
||||
dns_name_t **keys;
|
||||
size_t keysallocated;
|
||||
|
||||
dns_name_t **tlss;
|
||||
size_t tlssallocated;
|
||||
|
||||
size_t count; /* common to addrs, sources, keys and tlss */
|
||||
|
||||
const char **seen;
|
||||
size_t seencount;
|
||||
size_t seenallocated;
|
||||
} getipandkeylist_state_t;
|
||||
|
||||
static isc_result_t
|
||||
getipandkeylist(in_port_t defport, in_port_t deftlsport,
|
||||
const cfg_obj_t *config, const cfg_obj_t *list,
|
||||
in_port_t listport, const cfg_obj_t *listkey,
|
||||
const cfg_obj_t *listtls, isc_mem_t *mctx,
|
||||
getipandkeylist_state_t *s) {
|
||||
const cfg_obj_t *addrlist = cfg_tuple_get(list, "addresses");
|
||||
const cfg_obj_t *portobj = cfg_tuple_get(list, "port");
|
||||
const cfg_obj_t *src4obj = cfg_tuple_get(list, "source");
|
||||
const cfg_obj_t *src6obj = cfg_tuple_get(list, "source-v6");
|
||||
in_port_t port = (in_port_t)0;
|
||||
isc_sockaddr_t src4;
|
||||
isc_sockaddr_t src6;
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
if (cfg_obj_isuint32(portobj)) {
|
||||
uint32_t val = cfg_obj_asuint32(portobj);
|
||||
if (val > UINT16_MAX) {
|
||||
cfg_obj_log(portobj, ISC_LOG_ERROR,
|
||||
"port '%u' out of range", val);
|
||||
return ISC_R_RANGE;
|
||||
}
|
||||
port = (in_port_t)val;
|
||||
} else if (listport > 0) {
|
||||
/*
|
||||
* No port in the current list, but it is a list named elsewhere
|
||||
* where the port is defined, i.e:
|
||||
*
|
||||
* remote-servers bar { 10.53.0.4; };
|
||||
* remote-servers foo port 5555 { bar; 10.54.0.3; };
|
||||
* ^^^
|
||||
*
|
||||
* The current list is the list `bar`, and the server
|
||||
* `10.53.0.4` has the port `5555` defined.
|
||||
*/
|
||||
port = listport;
|
||||
}
|
||||
|
||||
if (src4obj != NULL && cfg_obj_issockaddr(src4obj)) {
|
||||
src4 = *cfg_obj_assockaddr(src4obj);
|
||||
} else {
|
||||
isc_sockaddr_any(&src4);
|
||||
}
|
||||
|
||||
if (src6obj != NULL && cfg_obj_issockaddr(src6obj)) {
|
||||
src6 = *cfg_obj_assockaddr(src6obj);
|
||||
} else {
|
||||
isc_sockaddr_any6(&src6);
|
||||
}
|
||||
|
||||
for (const cfg_listelt_t *element = cfg_list_first(addrlist);
|
||||
element != NULL; element = cfg_list_next(element))
|
||||
{
|
||||
const cfg_obj_t *addr;
|
||||
const cfg_obj_t *key;
|
||||
const cfg_obj_t *tls;
|
||||
|
||||
skiplist:
|
||||
addr = cfg_tuple_get(cfg_listelt_value(element),
|
||||
"remoteselement");
|
||||
key = cfg_tuple_get(cfg_listelt_value(element), "key");
|
||||
tls = cfg_tuple_get(cfg_listelt_value(element), "tls");
|
||||
|
||||
/*
|
||||
* If this is not an address, this is the name of a nested list,
|
||||
* i.e.
|
||||
*
|
||||
* remote-servers nestedlist { 10.53.0.4; };
|
||||
* remote-servers list { nestedlist key foo; 10.54.0.6; };
|
||||
* ^^^^^^^^^^^^^^^^^^
|
||||
*
|
||||
* We are currently in the list `list`, and `addr` is the name
|
||||
* `nestedlist`, so we'll immediately recurse to process
|
||||
* `nestedlist` before processing the next element of `list`.
|
||||
*/
|
||||
if (!cfg_obj_issockaddr(addr)) {
|
||||
const char *listname = cfg_obj_asstring(addr);
|
||||
const cfg_obj_t *nestedlist = NULL;
|
||||
isc_result_t tresult;
|
||||
|
||||
for (size_t i = 0; i < s->seencount; i++) {
|
||||
if (strcasecmp(s->seen[i], listname) == 0) {
|
||||
element = cfg_list_next(element);
|
||||
goto skiplist;
|
||||
}
|
||||
}
|
||||
|
||||
grow_array(mctx, s->seen, s->seencount,
|
||||
s->seenallocated);
|
||||
s->seen[s->seencount] = listname;
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(remotesnames); i++) {
|
||||
tresult = named_config_getremotesdef(
|
||||
config, remotesnames[i], listname,
|
||||
&nestedlist);
|
||||
if (tresult == ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(addr, ISC_LOG_ERROR,
|
||||
"remote-servers \"%s\" not found",
|
||||
listname);
|
||||
return tresult;
|
||||
}
|
||||
|
||||
result = getipandkeylist(defport, deftlsport, config,
|
||||
nestedlist, port, key, tls,
|
||||
mctx, s);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
grow_array(mctx, s->addrs, s->count, s->addrsallocated);
|
||||
grow_array(mctx, s->keys, s->count, s->keysallocated);
|
||||
grow_array(mctx, s->tlss, s->count, s->tlssallocated);
|
||||
grow_array(mctx, s->sources, s->count, s->sourcesallocated);
|
||||
|
||||
s->addrs[s->count] = *cfg_obj_assockaddr(addr);
|
||||
|
||||
result = named_config_getname(mctx, key, &s->keys[s->count]);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* The `key` is not provided for this address, so, if we're
|
||||
* inside a named list, get the `key` provided at the point the
|
||||
* list is used.
|
||||
*/
|
||||
if (s->keys[s->count] == NULL && listkey != NULL) {
|
||||
result = named_config_getname(mctx, listkey,
|
||||
&s->keys[s->count]);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
result = named_config_getname(mctx, tls, &s->tlss[s->count]);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* The `tls` is not provided for this address, so, if we're
|
||||
* inside a named list, get the `tls` provided at the point the
|
||||
* named list is used.
|
||||
*/
|
||||
if (s->tlss[s->count] == NULL && listtls != NULL) {
|
||||
result = named_config_getname(mctx, listtls,
|
||||
&s->tlss[s->count]);
|
||||
}
|
||||
|
||||
/* If the port is unset, take it from one of the upper levels */
|
||||
if (isc_sockaddr_getport(&s->addrs[s->count]) == 0) {
|
||||
in_port_t addr_port = port;
|
||||
|
||||
/* If unset, use the default port or tls-port */
|
||||
if (addr_port == 0) {
|
||||
if (s->tlss[s->count] != NULL) {
|
||||
addr_port = deftlsport;
|
||||
} else {
|
||||
addr_port = defport;
|
||||
}
|
||||
}
|
||||
|
||||
isc_sockaddr_setport(&s->addrs[s->count], addr_port);
|
||||
}
|
||||
|
||||
switch (isc_sockaddr_pf(&s->addrs[s->count])) {
|
||||
case PF_INET:
|
||||
s->sources[s->count] = src4;
|
||||
break;
|
||||
case PF_INET6:
|
||||
s->sources[s->count] = src6;
|
||||
break;
|
||||
default:
|
||||
result = ISC_R_NOTIMPLEMENTED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
s->count++;
|
||||
}
|
||||
|
||||
out:
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
/*
|
||||
* Reaching this point without success means we were in the
|
||||
* middle of adding a new entry, so it needs to be counted for
|
||||
* correctly free `s.keys` and `s.tlss` (as they potentially
|
||||
* added a new element right before something fails)
|
||||
*/
|
||||
s->count++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
||||
isc_mem_t *mctx, dns_ipkeylist_t *ipkl) {
|
||||
uint32_t addrcount = 0, srccount = 0;
|
||||
uint32_t keycount = 0, tlscount = 0;
|
||||
uint32_t listcount = 0, l = 0, i = 0;
|
||||
uint32_t stackcount = 0, pushed = 0;
|
||||
isc_result_t result;
|
||||
const cfg_listelt_t *element;
|
||||
const cfg_obj_t *addrlist;
|
||||
const cfg_obj_t *portobj;
|
||||
const cfg_obj_t *src4obj;
|
||||
const cfg_obj_t *src6obj;
|
||||
in_port_t port = (in_port_t)0;
|
||||
in_port_t def_port;
|
||||
in_port_t def_tlsport;
|
||||
isc_sockaddr_t src4;
|
||||
isc_sockaddr_t src6;
|
||||
isc_sockaddr_t *addrs = NULL;
|
||||
isc_sockaddr_t *sources = NULL;
|
||||
dns_name_t **keys = NULL;
|
||||
dns_name_t **tlss = NULL;
|
||||
struct {
|
||||
const char *name;
|
||||
in_port_t port;
|
||||
isc_sockaddr_t *src4s;
|
||||
isc_sockaddr_t *src6s;
|
||||
} *lists = NULL;
|
||||
struct {
|
||||
const cfg_listelt_t *element;
|
||||
in_port_t port;
|
||||
isc_sockaddr_t src4;
|
||||
isc_sockaddr_t src6;
|
||||
} *stack = NULL;
|
||||
|
||||
REQUIRE(ipkl != NULL);
|
||||
REQUIRE(ipkl->count == 0);
|
||||
|
|
@ -385,222 +577,83 @@ named_config_getipandkeylist(const cfg_obj_t *config, const cfg_obj_t *list,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
newlist:
|
||||
addrlist = cfg_tuple_get(list, "addresses");
|
||||
portobj = cfg_tuple_get(list, "port");
|
||||
src4obj = cfg_tuple_get(list, "source");
|
||||
src6obj = cfg_tuple_get(list, "source-v6");
|
||||
|
||||
if (cfg_obj_isuint32(portobj)) {
|
||||
uint32_t val = cfg_obj_asuint32(portobj);
|
||||
if (val > UINT16_MAX) {
|
||||
cfg_obj_log(portobj, ISC_LOG_ERROR,
|
||||
"port '%u' out of range", val);
|
||||
result = ISC_R_RANGE;
|
||||
goto cleanup;
|
||||
}
|
||||
port = (in_port_t)val;
|
||||
/*
|
||||
* Process the (nested) list(s).
|
||||
*/
|
||||
getipandkeylist_state_t s = {};
|
||||
result = getipandkeylist(def_port, def_tlsport, config, list,
|
||||
(in_port_t)0, NULL, NULL, mctx, &s);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (src4obj != NULL && cfg_obj_issockaddr(src4obj)) {
|
||||
src4 = *cfg_obj_assockaddr(src4obj);
|
||||
} else {
|
||||
isc_sockaddr_any(&src4);
|
||||
shrink_array(mctx, s.addrs, s.count, s.addrsallocated);
|
||||
shrink_array(mctx, s.keys, s.count, s.keysallocated);
|
||||
shrink_array(mctx, s.tlss, s.count, s.tlssallocated);
|
||||
shrink_array(mctx, s.sources, s.count, s.sourcesallocated);
|
||||
|
||||
ipkl->addrs = s.addrs;
|
||||
ipkl->keys = s.keys;
|
||||
ipkl->tlss = s.tlss;
|
||||
ipkl->sources = s.sources;
|
||||
ipkl->count = s.count;
|
||||
|
||||
INSIST(s.addrsallocated == s.keysallocated);
|
||||
INSIST(s.addrsallocated == s.tlssallocated);
|
||||
INSIST(s.addrsallocated == s.sourcesallocated);
|
||||
ipkl->allocated = s.addrsallocated;
|
||||
|
||||
if (s.seen != NULL) {
|
||||
/*
|
||||
* `s.seen` is not shrinked (no point, as it's deleted right
|
||||
* away anyway), so we need to use `s.seenallocated` to
|
||||
* correctly free the array.
|
||||
*/
|
||||
isc_mem_cput(mctx, s.seen, s.seenallocated, sizeof(s.seen[0]));
|
||||
}
|
||||
|
||||
if (src6obj != NULL && cfg_obj_issockaddr(src6obj)) {
|
||||
src6 = *cfg_obj_assockaddr(src6obj);
|
||||
} else {
|
||||
isc_sockaddr_any6(&src6);
|
||||
}
|
||||
|
||||
element = cfg_list_first(addrlist);
|
||||
resume:
|
||||
for (; element != NULL; element = cfg_list_next(element)) {
|
||||
const cfg_obj_t *addr;
|
||||
const cfg_obj_t *key;
|
||||
const cfg_obj_t *tls;
|
||||
|
||||
addr = cfg_tuple_get(cfg_listelt_value(element),
|
||||
"remoteselement");
|
||||
key = cfg_tuple_get(cfg_listelt_value(element), "key");
|
||||
tls = cfg_tuple_get(cfg_listelt_value(element), "tls");
|
||||
|
||||
if (!cfg_obj_issockaddr(addr)) {
|
||||
const char *listname = cfg_obj_asstring(addr);
|
||||
isc_result_t tresult;
|
||||
uint32_t j;
|
||||
|
||||
/* Grow lists? */
|
||||
grow_array(mctx, lists, l, listcount);
|
||||
|
||||
/* Seen? */
|
||||
for (j = 0; j < l; j++) {
|
||||
if (strcasecmp(lists[j].name, listname) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j < l) {
|
||||
continue;
|
||||
}
|
||||
list = NULL;
|
||||
tresult = ISC_R_NOTFOUND;
|
||||
for (size_t n = 0; n < ARRAY_SIZE(remotesnames); n++) {
|
||||
tresult = named_config_getremotesdef(
|
||||
config, remotesnames[n], listname,
|
||||
&list);
|
||||
if (tresult == ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tresult == ISC_R_NOTFOUND) {
|
||||
cfg_obj_log(addr, ISC_LOG_ERROR,
|
||||
"remote-servers \"%s\" not found",
|
||||
listname);
|
||||
}
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
goto cleanup;
|
||||
}
|
||||
lists[l++].name = listname;
|
||||
/* Grow stack? */
|
||||
grow_array(mctx, stack, pushed, stackcount);
|
||||
/*
|
||||
* We want to resume processing this list on the
|
||||
* next element.
|
||||
*/
|
||||
stack[pushed].element = cfg_list_next(element);
|
||||
stack[pushed].port = port;
|
||||
stack[pushed].src4 = src4;
|
||||
stack[pushed].src6 = src6;
|
||||
pushed++;
|
||||
goto newlist;
|
||||
}
|
||||
|
||||
grow_array(mctx, addrs, i, addrcount);
|
||||
grow_array(mctx, keys, i, keycount);
|
||||
grow_array(mctx, tlss, i, tlscount);
|
||||
grow_array(mctx, sources, i, srccount);
|
||||
|
||||
addrs[i] = *cfg_obj_assockaddr(addr);
|
||||
|
||||
result = named_config_getname(mctx, key, &keys[i]);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
i++; /* Increment here so that cleanup on error works.
|
||||
*/
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
result = named_config_getname(mctx, tls, &tlss[i]);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
i++; /* Increment here so that cleanup on error works.
|
||||
*/
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* If the port is unset, take it from one of the upper levels */
|
||||
if (isc_sockaddr_getport(&addrs[i]) == 0) {
|
||||
in_port_t addr_port = port;
|
||||
|
||||
/* If unset, use the default port or tls-port */
|
||||
if (addr_port == 0) {
|
||||
if (tlss[i] != NULL) {
|
||||
addr_port = def_tlsport;
|
||||
} else {
|
||||
addr_port = def_port;
|
||||
}
|
||||
}
|
||||
|
||||
isc_sockaddr_setport(&addrs[i], addr_port);
|
||||
}
|
||||
|
||||
switch (isc_sockaddr_pf(&addrs[i])) {
|
||||
case PF_INET:
|
||||
sources[i] = src4;
|
||||
break;
|
||||
case PF_INET6:
|
||||
sources[i] = src6;
|
||||
break;
|
||||
default:
|
||||
i++; /* Increment here so that cleanup on error works.
|
||||
*/
|
||||
result = ISC_R_NOTIMPLEMENTED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
if (pushed != 0) {
|
||||
pushed--;
|
||||
element = stack[pushed].element;
|
||||
port = stack[pushed].port;
|
||||
src4 = stack[pushed].src4;
|
||||
src6 = stack[pushed].src6;
|
||||
goto resume;
|
||||
}
|
||||
|
||||
shrink_array(mctx, addrs, i, addrcount);
|
||||
shrink_array(mctx, keys, i, keycount);
|
||||
shrink_array(mctx, tlss, i, tlscount);
|
||||
shrink_array(mctx, sources, i, srccount);
|
||||
|
||||
if (lists != NULL) {
|
||||
isc_mem_cput(mctx, lists, listcount, sizeof(lists[0]));
|
||||
}
|
||||
if (stack != NULL) {
|
||||
isc_mem_cput(mctx, stack, stackcount, sizeof(stack[0]));
|
||||
}
|
||||
|
||||
INSIST(keycount == addrcount);
|
||||
INSIST(tlscount == addrcount);
|
||||
INSIST(srccount == addrcount);
|
||||
|
||||
ipkl->addrs = addrs;
|
||||
ipkl->keys = keys;
|
||||
ipkl->tlss = tlss;
|
||||
ipkl->sources = sources;
|
||||
ipkl->count = addrcount;
|
||||
ipkl->allocated = addrcount;
|
||||
|
||||
return ISC_R_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
if (addrs != NULL) {
|
||||
isc_mem_cput(mctx, addrs, addrcount, sizeof(addrs[0]));
|
||||
/*
|
||||
* Because we didn't shrinked the array back in this path, we need to
|
||||
* use `s.*allocated` to correctly free the allocated arrays.
|
||||
*/
|
||||
if (s.addrs != NULL) {
|
||||
isc_mem_cput(mctx, s.addrs, s.count, sizeof(s.addrs[0]));
|
||||
}
|
||||
if (keys != NULL) {
|
||||
for (size_t j = 0; j < i; j++) {
|
||||
if (keys[j] == NULL) {
|
||||
if (s.keys != NULL) {
|
||||
for (size_t i = 0; i < s.count; i++) {
|
||||
if (s.keys[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (dns_name_dynamic(keys[j])) {
|
||||
dns_name_free(keys[j], mctx);
|
||||
if (dns_name_dynamic(s.keys[i])) {
|
||||
dns_name_free(s.keys[i], mctx);
|
||||
}
|
||||
isc_mem_put(mctx, keys[j], sizeof(*keys[j]));
|
||||
isc_mem_put(mctx, s.keys[i], sizeof(*s.keys[i]));
|
||||
}
|
||||
isc_mem_cput(mctx, keys, keycount, sizeof(keys[0]));
|
||||
isc_mem_cput(mctx, s.keys, s.keysallocated, sizeof(s.keys[0]));
|
||||
}
|
||||
if (tlss != NULL) {
|
||||
for (size_t j = 0; j < i; j++) {
|
||||
if (tlss[j] == NULL) {
|
||||
if (s.tlss != NULL) {
|
||||
for (size_t i = 0; i < s.count; i++) {
|
||||
if (s.tlss[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (dns_name_dynamic(tlss[j])) {
|
||||
dns_name_free(tlss[j], mctx);
|
||||
if (dns_name_dynamic(s.tlss[i])) {
|
||||
dns_name_free(s.tlss[i], mctx);
|
||||
}
|
||||
isc_mem_put(mctx, tlss[j], sizeof(*tlss[j]));
|
||||
isc_mem_put(mctx, s.tlss[i], sizeof(*s.tlss[i]));
|
||||
}
|
||||
isc_mem_cput(mctx, tlss, tlscount, sizeof(tlss[0]));
|
||||
isc_mem_cput(mctx, s.tlss, s.tlssallocated, sizeof(s.tlss[0]));
|
||||
}
|
||||
if (sources != NULL) {
|
||||
isc_mem_cput(mctx, sources, srccount, sizeof(sources[0]));
|
||||
if (s.sources != NULL) {
|
||||
isc_mem_cput(mctx, s.sources, s.sourcesallocated,
|
||||
sizeof(s.sources[0]));
|
||||
}
|
||||
if (lists != NULL) {
|
||||
isc_mem_cput(mctx, lists, listcount, sizeof(lists[0]));
|
||||
}
|
||||
if (stack != NULL) {
|
||||
isc_mem_cput(mctx, stack, stackcount, sizeof(stack[0]));
|
||||
if (s.seen != NULL) {
|
||||
isc_mem_cput(mctx, s.seen, s.seenallocated, sizeof(s.seen[0]));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
15
bin/tests/system/checkconf/bad-remote-servers-key.conf
Normal file
15
bin/tests/system/checkconf/bad-remote-servers-key.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
remote-servers a { 1.2.3.4; };
|
||||
remote-servers d { a key foo; };
|
||||
15
bin/tests/system/checkconf/bad-remote-servers-tls.conf
Normal file
15
bin/tests/system/checkconf/bad-remote-servers-tls.conf
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
remote-servers a { 1.2.3.4; };
|
||||
remote-servers d { a tls foo; };
|
||||
27
bin/tests/system/checkconf/good-remote-servers-named.conf
Normal file
27
bin/tests/system/checkconf/good-remote-servers-named.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.
|
||||
*/
|
||||
|
||||
key foo {
|
||||
algorithm hmac-sha256;
|
||||
secret "9999abcd8765";
|
||||
};
|
||||
|
||||
tls bar {
|
||||
};
|
||||
|
||||
remote-servers a { 1.2.3.4; };
|
||||
remote-servers b { 1.2.3.4; };
|
||||
remote-servers c { 1.2.3.4; 5.6.7.8; ::1; };
|
||||
remote-servers d { a key foo; b tls bar; c key foo tls bar; };
|
||||
remote-servers e { a key foo.; };
|
||||
remote-servers f { b tls bar; };
|
||||
77
bin/tests/system/xfer-servers-list/ns1/named.conf.j2
Normal file
77
bin/tests/system/xfer-servers-list/ns1/named.conf.j2
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
listen-on port @PORT@ { 10.53.0.1; };
|
||||
transfer-source 10.53.0.1;
|
||||
pid-file "named.pid";
|
||||
recursion no;
|
||||
/*
|
||||
* Notifications are sent from 10.53.1.1. This, the `notify
|
||||
* explicit` and `also-notify` below, enables us to use specific TSIG
|
||||
* keys for notifications for each secondary server instead of using
|
||||
* the xfer TSIG key.
|
||||
*/
|
||||
notify-source 10.53.1.1;
|
||||
/*
|
||||
* The test. zone doesn't specify other NS, however this makes it clear
|
||||
* this NS must only notify from also-notify list.
|
||||
*/
|
||||
notify explicit;
|
||||
};
|
||||
|
||||
key xfrkey {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "9999abcd8765";
|
||||
};
|
||||
|
||||
key notifykey2 {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "2222abcd8765";
|
||||
};
|
||||
|
||||
key notifykey3 {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "3333abcd8765";
|
||||
};
|
||||
|
||||
key notifykey4 {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "4444abcd8765";
|
||||
};
|
||||
|
||||
remote-servers secondariesbis {
|
||||
10.53.0.4 port @PORT@; /* gets notifykey4 */
|
||||
};
|
||||
|
||||
remote-servers secondaries {
|
||||
10.53.0.3 port @PORT@ key notifykey3;
|
||||
secondariesbis key notifykey4;
|
||||
10.53.0.2 port @PORT@; /* gets notifykey2 */
|
||||
};
|
||||
|
||||
zone "test" {
|
||||
type primary;
|
||||
allow-transfer { key xfrkey; };
|
||||
also-notify { secondaries key notifykey2; };
|
||||
file "test.db";
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
23
bin/tests/system/xfer-servers-list/ns1/test.db.j2
Normal file
23
bin/tests/system/xfer-servers-list/ns1/test.db.j2
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
; 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.
|
||||
|
||||
{% set serial = serial | default(1) %}
|
||||
|
||||
$TTL 60
|
||||
test. IN SOA ns.test. op.test. (
|
||||
@serial@ ; serial
|
||||
100 ; refresh
|
||||
100 ; retry
|
||||
300 ; expire
|
||||
60 ; minimum
|
||||
)
|
||||
test. NS ns.test.
|
||||
ns.test. A 10.53.0.1
|
||||
48
bin/tests/system/xfer-servers-list/ns2/named.conf.j2
Normal file
48
bin/tests/system/xfer-servers-list/ns2/named.conf.j2
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
listen-on port @PORT@ { 10.53.0.2; };
|
||||
transfer-source 10.53.0.2;
|
||||
pid-file "named.pid";
|
||||
recursion no;
|
||||
};
|
||||
|
||||
key xfrkey {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "9999abcd8765";
|
||||
};
|
||||
|
||||
key notifykey2 {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "2222abcd8765";
|
||||
};
|
||||
|
||||
zone "test" {
|
||||
/*
|
||||
* Notify comes from a different IP address than the primary listening
|
||||
* address, and with a different key.
|
||||
*/
|
||||
allow-notify { key notifykey2; };
|
||||
type secondary;
|
||||
primaries { 10.53.0.1 port @PORT@ key xfrkey; };
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
48
bin/tests/system/xfer-servers-list/ns3/named.conf.j2
Normal file
48
bin/tests/system/xfer-servers-list/ns3/named.conf.j2
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
listen-on port @PORT@ { 10.53.0.3; };
|
||||
transfer-source 10.53.0.3;
|
||||
pid-file "named.pid";
|
||||
recursion no;
|
||||
};
|
||||
|
||||
key xfrkey {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "9999abcd8765";
|
||||
};
|
||||
|
||||
key notifykey3 {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "3333abcd8765";
|
||||
};
|
||||
|
||||
zone "test" {
|
||||
/*
|
||||
* Notify comes from a different IP address than the primary listening
|
||||
* address, and with a different key.
|
||||
*/
|
||||
allow-notify { key notifykey3; };
|
||||
type secondary;
|
||||
primaries { 10.53.0.1 port @PORT@ key xfrkey; };
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
48
bin/tests/system/xfer-servers-list/ns4/named.conf.j2
Normal file
48
bin/tests/system/xfer-servers-list/ns4/named.conf.j2
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
options {
|
||||
listen-on port @PORT@ { 10.53.0.4; };
|
||||
transfer-source 10.53.0.4;
|
||||
pid-file "named.pid";
|
||||
recursion no;
|
||||
};
|
||||
|
||||
key xfrkey {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "9999abcd8765";
|
||||
};
|
||||
|
||||
key notifykey4 {
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
secret "4444abcd8765";
|
||||
};
|
||||
|
||||
zone "test" {
|
||||
/*
|
||||
* Notify comes from a different IP address than the primary listening
|
||||
* address, and with a different key.
|
||||
*/
|
||||
allow-notify { key notifykey4; };
|
||||
type secondary;
|
||||
primaries { 10.53.0.1 port @PORT@ key xfrkey; };
|
||||
};
|
||||
|
||||
key rndc_key {
|
||||
secret "1234abcd8765";
|
||||
algorithm @DEFAULT_HMAC@;
|
||||
};
|
||||
|
||||
controls {
|
||||
inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
|
||||
};
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
# 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.
|
||||
|
||||
import re
|
||||
|
||||
import isctest
|
||||
|
||||
|
||||
def check_soa(ns, serial):
|
||||
msg = isctest.query.create("test.", "SOA")
|
||||
res = isctest.query.udp(msg, ns.ip)
|
||||
isctest.check.noerror(res)
|
||||
assert len(res.answer) == 1
|
||||
assert (
|
||||
res.answer[0].to_text()
|
||||
== f"test. 60 IN SOA ns.test. op.test. {serial} 100 100 300 60"
|
||||
)
|
||||
|
||||
|
||||
def wait_for_initial_xfrin(ns):
|
||||
with ns.watch_log_from_start() as watcher:
|
||||
watcher.wait_for_line("Transfer status: success")
|
||||
check_soa(ns, 1)
|
||||
|
||||
|
||||
def wait_for_sending_notify(ns1, ns, key_name):
|
||||
pattern = re.compile(
|
||||
f"zone test/IN: sending notify to {ns.ip}#[0-9]+ : TSIG \\({key_name}\\)"
|
||||
)
|
||||
with ns1.watch_log_from_start() as watcher:
|
||||
watcher.wait_for_line(pattern)
|
||||
|
||||
|
||||
def test_xfer_servers_list(ns1, ns2, ns3, ns4, templates):
|
||||
# First, wait for ns2, ns3 and ns4 to xfrin foo.fr and answer it
|
||||
wait_for_initial_xfrin(ns2)
|
||||
wait_for_initial_xfrin(ns3)
|
||||
wait_for_initial_xfrin(ns4)
|
||||
|
||||
# ns1 initially notifies the secondaries using the respectively configured keys
|
||||
# - 10.53.0.2 has the key defined where `secondaries` is used
|
||||
# - 10.53.0.3 has the key directly after its IP address
|
||||
# - 10.53.0.4 has the key defined where `secondariesbis` is used
|
||||
# (inside `secondaries`), so it uses this one instead of the one
|
||||
# defined where `secondaries` is used.
|
||||
# Because the order notification are sent doesn't matter here, we can't use wait_for_sequence
|
||||
seq = [(ns2, "notifykey2"), (ns3, "notifykey3"), (ns4, "notifykey4")]
|
||||
for ns, key_name in seq:
|
||||
wait_for_sending_notify(ns1, ns, key_name)
|
||||
|
||||
# Then, ns1 update foo.fr. It notifies ns2, ns3 and ns4 about it
|
||||
templates.render("ns1/test.db", {"serial": 2})
|
||||
with ns2.watch_log_from_here() as ns2_watcher, ns3.watch_log_from_here() as ns3_watcher, ns4.watch_log_from_here() as ns4_watcher:
|
||||
ns1.rndc("reload")
|
||||
ns2_watcher.wait_for_line("Transfer status: success")
|
||||
ns3_watcher.wait_for_line("Transfer status: success")
|
||||
ns4_watcher.wait_for_line("Transfer status: success")
|
||||
check_soa(ns2, 2)
|
||||
check_soa(ns3, 2)
|
||||
check_soa(ns4, 2)
|
||||
|
|
@ -110,15 +110,6 @@ dns_notify_queue(dns_notify_t *notify, bool startup);
|
|||
* 'notify' is a valid notify.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_notify_dequeue(dns_notify_t *notify, bool startup);
|
||||
/*%<
|
||||
* Dequeue notify.
|
||||
*
|
||||
* Requires:
|
||||
* 'notify' is a valid notify.
|
||||
*/
|
||||
|
||||
void
|
||||
dns_notify_find_address(dns_notify_t *notify);
|
||||
/*%<
|
||||
|
|
|
|||
|
|
@ -509,11 +509,6 @@ notify_queue(dns_notify_t *notify, bool startup, bool dequeue) {
|
|||
¬ify->rlevent);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_notify_dequeue(dns_notify_t *notify, bool startup) {
|
||||
return notify_queue(notify, startup, true);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
dns_notify_queue(dns_notify_t *notify, bool startup) {
|
||||
return notify_queue(notify, startup, false);
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@ keydirexist(const cfg_obj_t *zcgf, const char *optname, dns_name_t *zname,
|
|||
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);
|
||||
static void
|
||||
freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
|
||||
UNUSED(type);
|
||||
|
|
@ -2084,6 +2087,12 @@ check_remoteserverlist(const cfg_obj_t *cctx, const char *list,
|
|||
result = tresult;
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t dummy = 0;
|
||||
result = validate_remotes(obj, cctx, &dummy, mctx);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -2414,6 +2423,96 @@ get_remoteservers_def(const char *name, const cfg_obj_t *cctx,
|
|||
return get_remotes(cctx, "masters", name, ret);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
validate_remotes_key(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) {
|
||||
cfg_obj_log(key, ISC_LOG_ERROR,
|
||||
"'%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 (!found) {
|
||||
cfg_obj_log(key, ISC_LOG_ERROR,
|
||||
"key '%s' is not defined",
|
||||
cfg_obj_asstring(key));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
validate_remotes_tls(const cfg_obj_t *config, const cfg_obj_t *tls) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
|
||||
if (cfg_obj_isstring(tls)) {
|
||||
const char *str = cfg_obj_asstring(tls);
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *nm = dns_fixedname_initname(&fname);
|
||||
|
||||
result = dns_name_fromstring(nm, str, dns_rootname, 0, NULL);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(tls, ISC_LOG_ERROR,
|
||||
"'%s' is not a valid name", str);
|
||||
}
|
||||
|
||||
if (strcasecmp(str, "ephemeral") != 0) {
|
||||
const cfg_obj_t *tlsmap = NULL;
|
||||
|
||||
tlsmap = find_maplist(config, "tls", str);
|
||||
if (tlsmap == NULL) {
|
||||
cfg_obj_log(tls, ISC_LOG_ERROR,
|
||||
"tls '%s' is not defined",
|
||||
cfg_obj_asstring(tls));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
validate_remotes(const cfg_obj_t *obj, const cfg_obj_t *config,
|
||||
uint32_t *countp, isc_mem_t *mctx) {
|
||||
|
|
@ -2445,69 +2544,21 @@ 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);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = validate_remotes_tls(config, tls);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cfg_obj_issockaddr(addr)) {
|
||||
count++;
|
||||
if (cfg_obj_isstring(key)) {
|
||||
const char *str = cfg_obj_asstring(key);
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *nm = dns_fixedname_initname(&fname);
|
||||
tresult = dns_name_fromstring(
|
||||
nm, str, dns_rootname, 0, NULL);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(key, ISC_LOG_ERROR,
|
||||
"'%s' is not a valid name",
|
||||
str);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg_obj_isstring(tls)) {
|
||||
const char *str = cfg_obj_asstring(tls);
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *nm = dns_fixedname_initname(&fname);
|
||||
tresult = dns_name_fromstring(
|
||||
nm, str, dns_rootname, 0, NULL);
|
||||
if (tresult != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(tls, ISC_LOG_ERROR,
|
||||
"'%s' is not a valid name",
|
||||
str);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = tresult;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcasecmp(str, "ephemeral") != 0) {
|
||||
const cfg_obj_t *tlsmap = NULL;
|
||||
|
||||
tlsmap = find_maplist(config, "tls",
|
||||
str);
|
||||
if (tlsmap == NULL) {
|
||||
cfg_obj_log(
|
||||
tls, ISC_LOG_ERROR,
|
||||
"tls '%s' is not "
|
||||
"defined",
|
||||
cfg_obj_asstring(tls));
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!cfg_obj_isvoid(key)) {
|
||||
cfg_obj_log(key, ISC_LOG_ERROR, "unexpected token '%s'",
|
||||
cfg_obj_asstring(key));
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
if (!cfg_obj_isvoid(tls)) {
|
||||
cfg_obj_log(key, ISC_LOG_ERROR, "unexpected token '%s'",
|
||||
cfg_obj_asstring(tls));
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
}
|
||||
listname = cfg_obj_asstring(addr);
|
||||
symvalue.as_cpointer = addr;
|
||||
tresult = isc_symtab_define(symtab, listname, 1, symvalue,
|
||||
|
|
@ -2539,11 +2590,14 @@ resume:
|
|||
element = stack[--pushed];
|
||||
goto resume;
|
||||
}
|
||||
|
||||
*countp = count;
|
||||
|
||||
out:
|
||||
if (stack != NULL) {
|
||||
isc_mem_cput(mctx, stack, stackcount, sizeof(*stack));
|
||||
}
|
||||
isc_symtab_destroy(&symtab);
|
||||
*countp = count;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue