mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
Add 'tls' configuration support for the 'forwarders' option
A 'tls' statement can be specified both for individual addresses and for the whole list (as a default value when an individual address doesn't have its own 'tls' set), just as it was done before for the 'port' value. Create a new function 'print_rawqstring()' to print a string residing in a 'isc_textregion_t' type parameter. Create a new function 'copy_string()' to copy a string from a 'cfg_obj_t' object into a 'isc_textregion_t'.
This commit is contained in:
25
bin/tests/system/checkconf/bad-forwarders-dot-badtls-1.conf
Normal file
25
bin/tests/system/checkconf/bad-forwarders-dot-badtls-1.conf
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
tls test-tls {
|
||||
protocols { TLSv1.2; };
|
||||
ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384";
|
||||
prefer-server-ciphers yes;
|
||||
};
|
||||
|
||||
# Bad: trying to use a TLS profile that has not been specified (another-tls).
|
||||
zone "example" {
|
||||
type forward;
|
||||
forward only;
|
||||
forwarders port 5300 tls test-tls { 10.53.0.1; 10.53.0.2 port 5301 tls another-tls; };
|
||||
};
|
25
bin/tests/system/checkconf/bad-forwarders-dot-badtls-2.conf
Normal file
25
bin/tests/system/checkconf/bad-forwarders-dot-badtls-2.conf
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
tls test-tls {
|
||||
protocols { TLSv1.2; };
|
||||
ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384";
|
||||
prefer-server-ciphers yes;
|
||||
};
|
||||
|
||||
# Bad: trying to use a TLS profile that has not been specified (another-tls).
|
||||
zone "example" {
|
||||
type forward;
|
||||
forward only;
|
||||
forwarders port 5300 tls another-tls { 10.53.0.1; 10.53.0.2 port 5301 tls test-tls; };
|
||||
};
|
29
bin/tests/system/checkconf/good-forwarders-dot.conf
Normal file
29
bin/tests/system/checkconf/good-forwarders-dot.conf
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
tls test-tls {
|
||||
protocols { TLSv1.2; };
|
||||
ciphers "HIGH:!kRSA:!aNULL:!eNULL:!RC4:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!SHA1:!SHA256:!SHA384";
|
||||
prefer-server-ciphers yes;
|
||||
};
|
||||
|
||||
tls another-tls {
|
||||
protocols { TLSv1.2; };
|
||||
session-tickets no;
|
||||
};
|
||||
|
||||
zone "example" {
|
||||
type forward;
|
||||
forward only;
|
||||
forwarders port 5300 tls test-tls { 10.53.0.1; 10.53.0.2 port 5301 tls another-tls; };
|
||||
};
|
@@ -118,8 +118,8 @@ view "second" {
|
||||
zone "example2" {
|
||||
type static-stub;
|
||||
forward only;
|
||||
forwarders {
|
||||
10.53.0.4;
|
||||
forwarders tls "ephemeral" {
|
||||
10.53.0.4 port 8053 tls "ephemeral";
|
||||
};
|
||||
zone-statistics no;
|
||||
};
|
||||
|
@@ -193,7 +193,7 @@ options {
|
||||
fetches\-per\-zone <integer> [ ( drop | fail ) ];
|
||||
flush\-zones\-on\-shutdown <boolean>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
fstrm\-set\-buffer\-hint <integer>; // not configured
|
||||
fstrm\-set\-flush\-timeout <integer>; // not configured
|
||||
fstrm\-set\-input\-queue\-size <integer>; // not configured
|
||||
@@ -491,7 +491,7 @@ view <string> [ <class> ] {
|
||||
fetches\-per\-server <integer> [ ( drop | fail ) ];
|
||||
fetches\-per\-zone <integer> [ ( drop | fail ) ];
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
ipv4only\-contact <string>;
|
||||
ipv4only\-enable <boolean>;
|
||||
ipv4only\-server <string>;
|
||||
@@ -682,7 +682,7 @@ zone <string> [ <class> ] {
|
||||
dnssec\-update\-mode ( maintain | no\-resign );
|
||||
file <quoted_string>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
inline\-signing <boolean>;
|
||||
ixfr\-from\-differences <boolean>;
|
||||
journal <quoted_string>;
|
||||
@@ -744,7 +744,7 @@ zone <string> [ <class> ] {
|
||||
dnssec\-update\-mode ( maintain | no\-resign );
|
||||
file <quoted_string>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
inline\-signing <boolean>;
|
||||
ixfr\-from\-differences <boolean>;
|
||||
journal <quoted_string>;
|
||||
@@ -850,7 +850,7 @@ zone <string> [ <class> ] {
|
||||
type forward;
|
||||
delegation\-only <boolean>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
};
|
||||
|
||||
.ft P
|
||||
@@ -906,7 +906,7 @@ zone <string> [ <class> ] {
|
||||
allow\-query { <address_match_element>; ... };
|
||||
allow\-query\-on { <address_match_element>; ... };
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
max\-records <integer>;
|
||||
server\-addresses { ( <ipv4_address> | <ipv6_address> ); ... };
|
||||
server\-names { <string>; ... };
|
||||
@@ -932,7 +932,7 @@ zone <string> [ <class> ] {
|
||||
dialup ( notify | notify\-passive | passive | refresh | <boolean> );
|
||||
file <quoted_string>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
masterfile\-format ( raw | text );
|
||||
masterfile\-style ( full | relative );
|
||||
max\-records <integer>;
|
||||
|
@@ -2,5 +2,5 @@ zone <string> [ <class> ] {
|
||||
type forward;
|
||||
delegation-only <boolean>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
};
|
||||
|
@@ -136,7 +136,7 @@ options {
|
||||
fetches-per-zone <integer> [ ( drop | fail ) ];
|
||||
flush-zones-on-shutdown <boolean>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
fstrm-set-buffer-hint <integer>; // not configured
|
||||
fstrm-set-flush-timeout <integer>; // not configured
|
||||
fstrm-set-input-queue-size <integer>; // not configured
|
||||
@@ -434,7 +434,7 @@ view <string> [ <class> ] {
|
||||
fetches-per-server <integer> [ ( drop | fail ) ];
|
||||
fetches-per-zone <integer> [ ( drop | fail ) ];
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
ipv4only-contact <string>;
|
||||
ipv4only-enable <boolean>;
|
||||
ipv4only-server <string>;
|
||||
|
@@ -27,7 +27,7 @@ zone <string> [ <class> ] {
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
file <quoted_string>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
inline-signing <boolean>;
|
||||
ixfr-from-differences <boolean>;
|
||||
journal <quoted_string>;
|
||||
|
@@ -18,7 +18,7 @@ zone <string> [ <class> ] {
|
||||
dnssec-update-mode ( maintain | no-resign );
|
||||
file <quoted_string>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
inline-signing <boolean>;
|
||||
ixfr-from-differences <boolean>;
|
||||
journal <quoted_string>;
|
||||
|
@@ -3,7 +3,7 @@ zone <string> [ <class> ] {
|
||||
allow-query { <address_match_element>; ... };
|
||||
allow-query-on { <address_match_element>; ... };
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
max-records <integer>;
|
||||
server-addresses { ( <ipv4_address> | <ipv6_address> ); ... };
|
||||
server-names { <string>; ... };
|
||||
|
@@ -8,7 +8,7 @@ zone <string> [ <class> ] {
|
||||
dialup ( notify | notify-passive | passive | refresh | <boolean> );
|
||||
file <quoted_string>;
|
||||
forward ( first | only );
|
||||
forwarders [ port <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ]; ... };
|
||||
forwarders [ port <integer> ] [ tls <string> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ tls <string> ]; ... };
|
||||
masterfile-format ( raw | text );
|
||||
masterfile-style ( full | relative );
|
||||
max-records <integer>;
|
||||
|
@@ -80,6 +80,10 @@ fileexist(const cfg_obj_t *obj, isc_symtab_t *symtab, bool writeable,
|
||||
static isc_result_t
|
||||
keydirexist(const cfg_obj_t *zcgf, const char *dir, const char *kaspnamestr,
|
||||
isc_symtab_t *symtab, isc_log_t *logctx, isc_mem_t *mctx);
|
||||
|
||||
static const cfg_obj_t *
|
||||
find_maplist(const cfg_obj_t *config, const char *listname, const char *name);
|
||||
|
||||
static void
|
||||
freekey(char *key, unsigned int type, isc_symvalue_t value, void *userarg) {
|
||||
UNUSED(type);
|
||||
@@ -272,10 +276,38 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) {
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_forward(const cfg_obj_t *options, const cfg_obj_t *global,
|
||||
isc_log_t *logctx) {
|
||||
validate_tls(const cfg_obj_t *config, const cfg_obj_t *obj, isc_log_t *logctx,
|
||||
const char *str) {
|
||||
dns_fixedname_t fname;
|
||||
dns_name_t *nm = dns_fixedname_initname(&fname);
|
||||
isc_result_t result = dns_name_fromstring(nm, str, 0, NULL);
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"'%s' is not a valid name", str);
|
||||
return (result);
|
||||
}
|
||||
|
||||
if (strcasecmp(str, "ephemeral") != 0) {
|
||||
const cfg_obj_t *tlsmap = find_maplist(config, "tls", str);
|
||||
|
||||
if (tlsmap == NULL) {
|
||||
cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
|
||||
"tls '%s' is not defined", str);
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
static isc_result_t
|
||||
check_forward(const cfg_obj_t *config, const cfg_obj_t *options,
|
||||
const cfg_obj_t *global, isc_log_t *logctx) {
|
||||
const cfg_obj_t *forward = NULL;
|
||||
const cfg_obj_t *forwarders = NULL;
|
||||
const cfg_obj_t *faddresses = NULL;
|
||||
const cfg_listelt_t *element;
|
||||
|
||||
(void)cfg_map_get(options, "forward", &forward);
|
||||
(void)cfg_map_get(options, "forwarders", &forwarders);
|
||||
@@ -294,6 +326,37 @@ check_forward(const cfg_obj_t *options, const cfg_obj_t *global,
|
||||
"no matching 'forwarders' statement");
|
||||
return (ISC_R_FAILURE);
|
||||
}
|
||||
if (forwarders != NULL) {
|
||||
isc_result_t result = ISC_R_SUCCESS;
|
||||
const cfg_obj_t *tlspobj = cfg_tuple_get(forwarders, "tls");
|
||||
|
||||
if (tlspobj != NULL && cfg_obj_isstring(tlspobj)) {
|
||||
const char *tls = cfg_obj_asstring(tlspobj);
|
||||
if (tls != NULL) {
|
||||
result = validate_tls(config, tlspobj, logctx,
|
||||
tls);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
faddresses = cfg_tuple_get(forwarders, "addresses");
|
||||
for (element = cfg_list_first(faddresses); element != NULL;
|
||||
element = cfg_list_next(element))
|
||||
{
|
||||
const cfg_obj_t *forwarder = cfg_listelt_value(element);
|
||||
const char *tls = cfg_obj_getsockaddrtls(forwarder);
|
||||
if (tls != NULL) {
|
||||
result = validate_tls(config, faddresses,
|
||||
logctx, tls);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
return (result);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
@@ -3601,7 +3664,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
|
||||
(void)cfg_map_get(goptions, "forwarders", &obj);
|
||||
}
|
||||
}
|
||||
if (check_forward(zoptions, obj, logctx) != ISC_R_SUCCESS) {
|
||||
if (check_forward(config, zoptions, obj, logctx) != ISC_R_SUCCESS) {
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
||||
@@ -5293,7 +5356,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
|
||||
/*
|
||||
* Check that forwarding is reasonable.
|
||||
*/
|
||||
if (opts != NULL && check_forward(opts, NULL, logctx) != ISC_R_SUCCESS)
|
||||
if (opts != NULL &&
|
||||
check_forward(config, opts, NULL, logctx) != ISC_R_SUCCESS)
|
||||
{
|
||||
result = ISC_R_FAILURE;
|
||||
}
|
||||
|
@@ -392,6 +392,12 @@ cfg_obj_issockaddr(const cfg_obj_t *obj);
|
||||
* Return true iff 'obj' is a socket address.
|
||||
*/
|
||||
|
||||
bool
|
||||
cfg_obj_issockaddrtls(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
* Return true iff 'obj' is a socket address with an optional tls configuration.
|
||||
*/
|
||||
|
||||
const isc_sockaddr_t *
|
||||
cfg_obj_assockaddr(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
@@ -399,13 +405,27 @@ cfg_obj_assockaddr(const cfg_obj_t *obj);
|
||||
*
|
||||
* Requires:
|
||||
* \li 'obj' points to a valid configuration object of a socket address
|
||||
* type.
|
||||
* type, or of a socket address type with an optional tls configuration.
|
||||
*
|
||||
* Returns:
|
||||
* \li A pointer to a sockaddr. The sockaddr must be copied by the caller
|
||||
* if necessary.
|
||||
*/
|
||||
|
||||
const char *
|
||||
cfg_obj_getsockaddrtls(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
* Returns the TLS value of a configuration object representing a
|
||||
* socket address.
|
||||
*
|
||||
* Requires:
|
||||
* \li 'obj' points to a valid configuration object of a
|
||||
* socket address type.
|
||||
*
|
||||
* Returns:
|
||||
* \li TLS value associated with a sockaddr, or NULL.
|
||||
*/
|
||||
|
||||
bool
|
||||
cfg_obj_isnetprefix(const cfg_obj_t *obj);
|
||||
/*%<
|
||||
|
@@ -177,6 +177,10 @@ struct cfg_obj {
|
||||
cfg_list_t list;
|
||||
cfg_obj_t **tuple;
|
||||
isc_sockaddr_t sockaddr;
|
||||
struct {
|
||||
isc_sockaddr_t sockaddr;
|
||||
isc_textregion_t tls;
|
||||
} sockaddrtls;
|
||||
cfg_netprefix_t netprefix;
|
||||
isccfg_duration_t duration;
|
||||
} value;
|
||||
@@ -266,6 +270,7 @@ struct cfg_parser {
|
||||
#define CFG_ADDR_V6OK 0x00000004
|
||||
#define CFG_ADDR_WILDOK 0x00000008
|
||||
#define CFG_ADDR_PORTOK 0x00000010
|
||||
#define CFG_ADDR_TLSOK 0x00000020
|
||||
#define CFG_ADDR_MASK (CFG_ADDR_V6OK | CFG_ADDR_V4OK)
|
||||
/*@}*/
|
||||
|
||||
@@ -281,6 +286,7 @@ extern cfg_rep_t cfg_rep_map;
|
||||
extern cfg_rep_t cfg_rep_list;
|
||||
extern cfg_rep_t cfg_rep_tuple;
|
||||
extern cfg_rep_t cfg_rep_sockaddr;
|
||||
extern cfg_rep_t cfg_rep_sockaddrtls;
|
||||
extern cfg_rep_t cfg_rep_netprefix;
|
||||
extern cfg_rep_t cfg_rep_void;
|
||||
extern cfg_rep_t cfg_rep_fixedpoint;
|
||||
@@ -304,6 +310,7 @@ extern cfg_type_t cfg_type_bracketed_text;
|
||||
extern cfg_type_t cfg_type_optional_bracketed_text;
|
||||
extern cfg_type_t cfg_type_keyref;
|
||||
extern cfg_type_t cfg_type_sockaddr;
|
||||
extern cfg_type_t cfg_type_sockaddrtls;
|
||||
extern cfg_type_t cfg_type_netaddr;
|
||||
extern cfg_type_t cfg_type_netaddr4;
|
||||
extern cfg_type_t cfg_type_netaddr4wild;
|
||||
@@ -372,6 +379,10 @@ cfg_parse_rawport(cfg_parser_t *pctx, unsigned int flags, in_port_t *port);
|
||||
isc_result_t
|
||||
cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_sockaddrtls(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret);
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_boolean(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret);
|
||||
|
||||
|
@@ -89,8 +89,8 @@ cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type);
|
||||
static cfg_type_t cfg_type_acl;
|
||||
static cfg_type_t cfg_type_bracketed_namesockaddrkeylist;
|
||||
static cfg_type_t cfg_type_bracketed_netaddrlist;
|
||||
static cfg_type_t cfg_type_bracketed_sockaddrlist;
|
||||
static cfg_type_t cfg_type_bracketed_sockaddrnameportlist;
|
||||
static cfg_type_t cfg_type_bracketed_sockaddrtlslist;
|
||||
static cfg_type_t cfg_type_bracketed_http_endpoint_list;
|
||||
static cfg_type_t cfg_type_controls;
|
||||
static cfg_type_t cfg_type_controls_sockaddr;
|
||||
@@ -285,11 +285,12 @@ static cfg_type_t cfg_type_namesockaddrkeylist = {
|
||||
|
||||
/*%
|
||||
* A list of socket addresses with an optional default port, as used
|
||||
* in the 'listen-on' option. E.g., "{ 10.0.0.1; 1::2 port 69; }"
|
||||
* in the 'forwarders' option. E.g., "{ 10.0.0.1; 1::2 port 69; }"
|
||||
*/
|
||||
static cfg_tuplefielddef_t portiplist_fields[] = {
|
||||
{ "port", &cfg_type_optional_port, 0 },
|
||||
{ "addresses", &cfg_type_bracketed_sockaddrlist, 0 },
|
||||
{ "tls", &cfg_type_optional_tls, 0 },
|
||||
{ "addresses", &cfg_type_bracketed_sockaddrtlslist, 0 },
|
||||
{ NULL, NULL, 0 }
|
||||
};
|
||||
static cfg_type_t cfg_type_portiplist = { "portiplist", cfg_parse_tuple,
|
||||
@@ -732,12 +733,14 @@ static cfg_type_t cfg_type_bracketed_netaddrlist = { "bracketed_netaddrlist",
|
||||
&cfg_rep_list,
|
||||
&cfg_type_netaddr };
|
||||
|
||||
static cfg_type_t cfg_type_bracketed_sockaddrlist = { "bracketed_sockaddrlist",
|
||||
static cfg_type_t cfg_type_bracketed_sockaddrtlslist = {
|
||||
"bracketed_sockaddrtlslist",
|
||||
cfg_parse_bracketed_list,
|
||||
cfg_print_bracketed_list,
|
||||
cfg_doc_bracketed_list,
|
||||
&cfg_rep_list,
|
||||
&cfg_type_sockaddr };
|
||||
&cfg_type_sockaddrtls
|
||||
};
|
||||
|
||||
static const char *autodnssec_enums[] = { "allow", "maintain", "off", NULL };
|
||||
static cfg_type_t cfg_type_autodnssec = {
|
||||
@@ -1085,7 +1088,7 @@ static cfg_type_t cfg_type_portrange = { "portrange", parse_portrange,
|
||||
NULL, cfg_doc_terminal,
|
||||
NULL, NULL };
|
||||
|
||||
static cfg_type_t cfg_type_bracketed_portlist = { "bracketed_sockaddrlist",
|
||||
static cfg_type_t cfg_type_bracketed_portlist = { "bracketed_portlist",
|
||||
cfg_parse_bracketed_list,
|
||||
cfg_print_bracketed_list,
|
||||
cfg_doc_bracketed_list,
|
||||
@@ -3169,6 +3172,7 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
in_port_t port = 0;
|
||||
unsigned int have_address = 0;
|
||||
unsigned int have_port = 0;
|
||||
unsigned int have_tls = 0;
|
||||
const unsigned int *flagp = type->of;
|
||||
|
||||
if ((*flagp & CFG_ADDR_V4OK) != 0) {
|
||||
@@ -3201,7 +3205,12 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
CHECK(cfg_parse_rawport(pctx, CFG_ADDR_WILDOK,
|
||||
&port));
|
||||
have_port++;
|
||||
} else if (have_port == 0 && have_address == 0) {
|
||||
} else if (strcasecmp(TOKEN_STRING(pctx), "tls") == 0) {
|
||||
/* We do not expect TLS here, not parsing. */
|
||||
++have_tls;
|
||||
} else if (have_port == 0 && have_tls == 0 &&
|
||||
have_address == 0)
|
||||
{
|
||||
return (cfg_parse_sockaddr(pctx, type, ret));
|
||||
} else {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
@@ -3213,12 +3222,18 @@ parse_querysource(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_address > 1 || have_port > 1 || have_address + have_port == 0)
|
||||
{
|
||||
cfg_parser_error(pctx, 0, "expected one address and/or port");
|
||||
return (ISC_R_UNEXPECTEDTOKEN);
|
||||
}
|
||||
|
||||
if (have_tls > 0) {
|
||||
cfg_parser_error(pctx, 0, "unexpected tls");
|
||||
return (ISC_R_UNEXPECTEDTOKEN);
|
||||
}
|
||||
|
||||
CHECK(cfg_create_obj(pctx, &cfg_type_querysource, &obj));
|
||||
isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
|
||||
*ret = obj;
|
||||
|
@@ -119,6 +119,12 @@ create_string(cfg_parser_t *pctx, const char *contents, const cfg_type_t *type,
|
||||
static void
|
||||
free_string(cfg_parser_t *pctx, cfg_obj_t *obj);
|
||||
|
||||
static void
|
||||
copy_string(cfg_parser_t *pctx, const cfg_obj_t *obj, isc_textregion_t *dst);
|
||||
|
||||
static void
|
||||
free_sockaddrtls(cfg_parser_t *pctx, cfg_obj_t *obj);
|
||||
|
||||
static isc_result_t
|
||||
create_map(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **objp);
|
||||
|
||||
@@ -164,6 +170,7 @@ cfg_rep_t cfg_rep_map = { "map", free_map };
|
||||
cfg_rep_t cfg_rep_list = { "list", free_list };
|
||||
cfg_rep_t cfg_rep_tuple = { "tuple", free_tuple };
|
||||
cfg_rep_t cfg_rep_sockaddr = { "sockaddr", free_noop };
|
||||
cfg_rep_t cfg_rep_sockaddrtls = { "sockaddrtls", free_sockaddrtls };
|
||||
cfg_rep_t cfg_rep_netprefix = { "netprefix", free_noop };
|
||||
cfg_rep_t cfg_rep_void = { "void", free_noop };
|
||||
cfg_rep_t cfg_rep_fixedpoint = { "fixedpoint", free_noop };
|
||||
@@ -1511,17 +1518,22 @@ cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
}
|
||||
|
||||
static void
|
||||
print_qstring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
print_rawqstring(cfg_printer_t *pctx, const isc_textregion_t string) {
|
||||
cfg_print_cstr(pctx, "\"");
|
||||
for (size_t i = 0; i < obj->value.string.length; i++) {
|
||||
if (obj->value.string.base[i] == '"') {
|
||||
for (size_t i = 0; i < string.length; i++) {
|
||||
if (string.base[i] == '"') {
|
||||
cfg_print_cstr(pctx, "\\");
|
||||
}
|
||||
cfg_print_chars(pctx, &obj->value.string.base[i], 1);
|
||||
cfg_print_chars(pctx, (const char *)&string.base[i], 1);
|
||||
}
|
||||
cfg_print_cstr(pctx, "\"");
|
||||
}
|
||||
|
||||
static void
|
||||
print_qstring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
print_rawqstring(pctx, obj->value.string);
|
||||
}
|
||||
|
||||
static void
|
||||
print_sstring(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
cfg_print_cstr(pctx, "\"");
|
||||
@@ -1542,6 +1554,27 @@ free_string(cfg_parser_t *pctx, cfg_obj_t *obj) {
|
||||
obj->value.string.length + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_string(cfg_parser_t *pctx, const cfg_obj_t *obj, isc_textregion_t *dst) {
|
||||
if (dst->base != NULL) {
|
||||
INSIST(dst->length != 0);
|
||||
isc_mem_put(pctx->mctx, dst->base, dst->length + 1);
|
||||
}
|
||||
dst->length = obj->value.string.length;
|
||||
dst->base = isc_mem_get(pctx->mctx, dst->length + 1);
|
||||
memmove(dst->base, obj->value.string.base, dst->length);
|
||||
dst->base[dst->length] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
free_sockaddrtls(cfg_parser_t *pctx, cfg_obj_t *obj) {
|
||||
if (obj->value.sockaddrtls.tls.base != NULL) {
|
||||
INSIST(obj->value.sockaddrtls.tls.length != 0);
|
||||
isc_mem_put(pctx->mctx, obj->value.sockaddrtls.tls.base,
|
||||
obj->value.sockaddrtls.tls.length + 1);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
cfg_obj_isstring(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL);
|
||||
@@ -3211,9 +3244,11 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags,
|
||||
in_port_t port = 0;
|
||||
cfg_obj_t *obj = NULL;
|
||||
int have_port = 0;
|
||||
int have_tls = 0;
|
||||
|
||||
CHECK(cfg_create_obj(pctx, type, &obj));
|
||||
CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr));
|
||||
|
||||
for (;;) {
|
||||
CHECK(cfg_peektoken(pctx, 0));
|
||||
if (pctx->token.type == isc_tokentype_string) {
|
||||
@@ -3229,6 +3264,17 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags,
|
||||
CHECK(cfg_gettoken(pctx, 0)); /* read "port" */
|
||||
CHECK(cfg_parse_rawport(pctx, flags, &port));
|
||||
++have_port;
|
||||
} else if ((flags & CFG_ADDR_TLSOK) != 0 &&
|
||||
strcasecmp(TOKEN_STRING(pctx), "tls") == 0)
|
||||
{
|
||||
cfg_obj_t *tls = NULL;
|
||||
|
||||
CHECK(cfg_gettoken(pctx, 0)); /* read "tls" */
|
||||
CHECK(cfg_parse_astring(pctx, NULL, &tls));
|
||||
copy_string(pctx, tls,
|
||||
&obj->value.sockaddrtls.tls);
|
||||
CLEANUP_OBJ(tls);
|
||||
++have_tls;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -3236,11 +3282,17 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type, int flags,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_port > 1) {
|
||||
cfg_parser_error(pctx, 0, "expected at most one port");
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
if (have_tls > 1) {
|
||||
cfg_parser_error(pctx, 0, "expected at most one tls");
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
|
||||
*ret = obj;
|
||||
@@ -3257,6 +3309,12 @@ cfg_type_t cfg_type_sockaddr = { "sockaddr", cfg_parse_sockaddr,
|
||||
cfg_print_sockaddr, cfg_doc_sockaddr,
|
||||
&cfg_rep_sockaddr, &sockaddr_flags };
|
||||
|
||||
static unsigned int sockaddrtls_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK |
|
||||
CFG_ADDR_PORTOK | CFG_ADDR_TLSOK;
|
||||
cfg_type_t cfg_type_sockaddrtls = { "sockaddrtls", cfg_parse_sockaddrtls,
|
||||
cfg_print_sockaddr, cfg_doc_sockaddr,
|
||||
&cfg_rep_sockaddrtls, &sockaddrtls_flags };
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret) {
|
||||
@@ -3271,6 +3329,20 @@ cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
return (parse_sockaddrsub(pctx, &cfg_type_sockaddr, *flagp, ret));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_sockaddrtls(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
cfg_obj_t **ret) {
|
||||
const unsigned int *flagp;
|
||||
|
||||
REQUIRE(pctx != NULL);
|
||||
REQUIRE(type != NULL);
|
||||
REQUIRE(ret != NULL && *ret == NULL);
|
||||
|
||||
flagp = type->of;
|
||||
|
||||
return (parse_sockaddrsub(pctx, &cfg_type_sockaddrtls, *flagp, ret));
|
||||
}
|
||||
|
||||
void
|
||||
cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
isc_netaddr_t netaddr;
|
||||
@@ -3288,6 +3360,10 @@ cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
cfg_print_cstr(pctx, " port ");
|
||||
cfg_print_rawuint(pctx, port);
|
||||
}
|
||||
if (obj->value.sockaddrtls.tls.base != NULL) {
|
||||
cfg_print_cstr(pctx, " tls ");
|
||||
print_rawqstring(pctx, obj->value.sockaddrtls.tls);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3328,6 +3404,9 @@ cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
cfg_print_cstr(pctx, " [ port <integer> ]");
|
||||
}
|
||||
}
|
||||
if ((*flagp & CFG_ADDR_TLSOK) != 0) {
|
||||
cfg_print_cstr(pctx, " [ tls <string> ]");
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -3336,12 +3415,26 @@ cfg_obj_issockaddr(const cfg_obj_t *obj) {
|
||||
return (obj->type->rep == &cfg_rep_sockaddr);
|
||||
}
|
||||
|
||||
bool
|
||||
cfg_obj_issockaddrtls(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL);
|
||||
return (obj->type->rep == &cfg_rep_sockaddrtls);
|
||||
}
|
||||
|
||||
const isc_sockaddr_t *
|
||||
cfg_obj_assockaddr(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_sockaddr);
|
||||
REQUIRE(obj != NULL);
|
||||
REQUIRE(obj->type->rep == &cfg_rep_sockaddr ||
|
||||
obj->type->rep == &cfg_rep_sockaddrtls);
|
||||
return (&obj->value.sockaddr);
|
||||
}
|
||||
|
||||
const char *
|
||||
cfg_obj_getsockaddrtls(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_sockaddrtls);
|
||||
return (obj->value.sockaddrtls.tls.base);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
cfg_gettoken(cfg_parser_t *pctx, int options) {
|
||||
isc_result_t result;
|
||||
@@ -3626,12 +3719,10 @@ cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
REQUIRE(ret != NULL && *ret == NULL);
|
||||
|
||||
obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t));
|
||||
|
||||
obj->type = type;
|
||||
obj->file = current_file(pctx);
|
||||
obj->line = pctx->line;
|
||||
obj->pctx = pctx;
|
||||
|
||||
*obj = (cfg_obj_t){ .type = type,
|
||||
.file = current_file(pctx),
|
||||
.line = pctx->line,
|
||||
.pctx = pctx };
|
||||
isc_refcount_init(&obj->references, 1);
|
||||
|
||||
*ret = obj;
|
||||
|
Reference in New Issue
Block a user