From: Aram Sargsyan Date: Thu, 8 Dec 2022 10:57:37 +0000 (+0000) Subject: Add 'tls' configuration support for the 'forwarders' option X-Git-Tag: v9.19.10~23^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e1dd86aa075608ba05c1e9d5703d8c9823ff95e0;p=thirdparty%2Fbind9.git 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'. --- diff --git a/bin/tests/system/checkconf/bad-forwarders-dot-badtls-1.conf b/bin/tests/system/checkconf/bad-forwarders-dot-badtls-1.conf new file mode 100644 index 00000000000..68c1f144ed1 --- /dev/null +++ b/bin/tests/system/checkconf/bad-forwarders-dot-badtls-1.conf @@ -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; }; +}; diff --git a/bin/tests/system/checkconf/bad-forwarders-dot-badtls-2.conf b/bin/tests/system/checkconf/bad-forwarders-dot-badtls-2.conf new file mode 100644 index 00000000000..d95af2d5e53 --- /dev/null +++ b/bin/tests/system/checkconf/bad-forwarders-dot-badtls-2.conf @@ -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; }; +}; diff --git a/bin/tests/system/checkconf/good-forwarders-dot.conf b/bin/tests/system/checkconf/good-forwarders-dot.conf new file mode 100644 index 00000000000..0d9bfa329c5 --- /dev/null +++ b/bin/tests/system/checkconf/good-forwarders-dot.conf @@ -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; }; +}; diff --git a/bin/tests/system/checkconf/good.conf.in b/bin/tests/system/checkconf/good.conf.in index f67d7172a33..84a08eefe1e 100644 --- a/bin/tests/system/checkconf/good.conf.in +++ b/bin/tests/system/checkconf/good.conf.in @@ -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; }; diff --git a/doc/man/named.conf.5in b/doc/man/named.conf.5in index ce1d817a1bd..ea9e2b86c4c 100644 --- a/doc/man/named.conf.5in +++ b/doc/man/named.conf.5in @@ -126,7 +126,7 @@ options { allow\-transfer [ port ] [ transport ] { ; ... }; allow\-update { ; ... }; allow\-update\-forwarding { ; ... }; - also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; answer\-cookie ; attach\-cache ; auth\-nxdomain ; @@ -136,7 +136,7 @@ options { avoid\-v6\-udp\-ports { ; ... }; // deprecated bindkeys\-file ; blackhole { ; ... }; - catalog\-zones { zone [ default\-primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone\-directory ] [ in\-memory ] [ min\-update\-interval ]; ... }; + catalog\-zones { zone [ default\-primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone\-directory ] [ in\-memory ] [ min\-update\-interval ]; ... }; check\-dup\-records ( fail | warn | ignore ); check\-integrity ; check\-mx ( fail | warn | ignore ); @@ -193,7 +193,7 @@ options { fetches\-per\-zone [ ( drop | fail ) ]; flush\-zones\-on\-shutdown ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; fstrm\-set\-buffer\-hint ; // not configured fstrm\-set\-flush\-timeout ; // not configured fstrm\-set\-input\-queue\-size ; // not configured @@ -259,15 +259,15 @@ options { notify ( explicit | master\-only | primary\-only | ); notify\-delay ; notify\-rate ; - notify\-source ( | * ) ; - notify\-source\-v6 ( | * ) ; + notify\-source ( | * ); + notify\-source\-v6 ( | * ); notify\-to\-soa ; nsec3\-test\-zone ; // test only nta\-lifetime ; nta\-recheck ; nxdomain\-redirect ; - parental\-source ( | * ) ; - parental\-source\-v6 ( | * ) ; + parental\-source ( | * ); + parental\-source\-v6 ( | * ); pid\-file ( | none ); port ; preferred\-glue ; @@ -349,8 +349,8 @@ options { tls\-port ; transfer\-format ( many\-answers | one\-answer ); transfer\-message\-size ; - transfer\-source ( | * ) ; - transfer\-source\-v6 ( | * ) ; + transfer\-source ( | * ); + transfer\-source\-v6 ( | * ); transfers\-in ; transfers\-out ; transfers\-per\-ns ; @@ -369,11 +369,11 @@ options { zone\-statistics ( full | terse | none | ); }; -parental\-agents [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times +parental\-agents [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times plugin ( query ) [ { } ]; // may occur multiple times -primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times +primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times server { bogus ; @@ -382,8 +382,8 @@ server { edns\-version ; keys ; max\-udp\-size ; - notify\-source ( | * ) ; - notify\-source\-v6 ( | * ) ; + notify\-source ( | * ); + notify\-source\-v6 ( | * ); padding ; provide\-ixfr ; query\-source [ address ] ( | * ); @@ -396,8 +396,8 @@ server { tcp\-keepalive ; tcp\-only ; transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( | * ) ; - transfer\-source\-v6 ( | * ) ; + transfer\-source ( | * ); + transfer\-source\-v6 ( | * ); transfers ; }; // may occur multiple times @@ -433,11 +433,11 @@ view [ ] { allow\-transfer [ port ] [ transport ] { ; ... }; allow\-update { ; ... }; allow\-update\-forwarding { ; ... }; - also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; attach\-cache ; auth\-nxdomain ; auto\-dnssec ( allow | maintain | off ); // deprecated - catalog\-zones { zone [ default\-primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone\-directory ] [ in\-memory ] [ min\-update\-interval ]; ... }; + catalog\-zones { zone [ default\-primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone\-directory ] [ in\-memory ] [ min\-update\-interval ]; ... }; check\-dup\-records ( fail | warn | ignore ); check\-integrity ; check\-mx ( fail | warn | ignore ); @@ -491,7 +491,7 @@ view [ ] { fetches\-per\-server [ ( drop | fail ) ]; fetches\-per\-zone [ ( drop | fail ) ]; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; ipv4only\-contact ; ipv4only\-enable ; ipv4only\-server ; @@ -540,15 +540,15 @@ view [ ] { nocookie\-udp\-size ; notify ( explicit | master\-only | primary\-only | ); notify\-delay ; - notify\-source ( | * ) ; - notify\-source\-v6 ( | * ) ; + notify\-source ( | * ); + notify\-source\-v6 ( | * ); notify\-to\-soa ; nsec3\-test\-zone ; // test only nta\-lifetime ; nta\-recheck ; nxdomain\-redirect ; - parental\-source ( | * ) ; - parental\-source\-v6 ( | * ) ; + parental\-source ( | * ); + parental\-source\-v6 ( | * ); plugin ( query ) [ { } ]; // may occur multiple times preferred\-glue ; prefetch [ ]; @@ -595,8 +595,8 @@ view [ ] { edns\-version ; keys ; max\-udp\-size ; - notify\-source ( | * ) ; - notify\-source\-v6 ( | * ) ; + notify\-source ( | * ); + notify\-source\-v6 ( | * ); padding ; provide\-ixfr ; query\-source [ address ] ( | * ); @@ -609,8 +609,8 @@ view [ ] { tcp\-keepalive ; tcp\-only ; transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( | * ) ; - transfer\-source\-v6 ( | * ) ; + transfer\-source ( | * ); + transfer\-source\-v6 ( | * ); transfers ; }; // may occur multiple times servfail\-ttl ; @@ -627,8 +627,8 @@ view [ ] { suppress\-initial\-notify ; // obsolete synth\-from\-dnssec ; transfer\-format ( many\-answers | one\-answer ); - transfer\-source ( | * ) ; - transfer\-source\-v6 ( | * ) ; + transfer\-source ( | * ); + transfer\-source\-v6 ( | * ); trust\-anchor\-telemetry ; // experimental trust\-anchors { ( static\-key | initial\-key | static\-ds | initial\-ds ) ; ... }; // may occur multiple times trusted\-keys { ; ... }; // may occur multiple times, deprecated @@ -659,7 +659,7 @@ zone [ ] { allow\-query\-on { ; ... }; allow\-transfer [ port ] [ transport ] { ; ... }; allow\-update { ; ... }; - also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; auto\-dnssec ( allow | maintain | off ); // deprecated check\-dup\-records ( fail | warn | ignore ); check\-integrity ; @@ -682,7 +682,7 @@ zone [ ] { dnssec\-update\-mode ( maintain | no\-resign ); file ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; inline\-signing ; ixfr\-from\-differences ; journal ; @@ -697,13 +697,13 @@ zone [ ] { max\-zone\-ttl ( unlimited | ); // deprecated notify ( explicit | master\-only | primary\-only | ); notify\-delay ; - notify\-source ( | * ) ; - notify\-source\-v6 ( | * ) ; + notify\-source ( | * ); + notify\-source\-v6 ( | * ); notify\-to\-soa ; nsec3\-test\-zone ; // test only - parental\-agents [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; - parental\-source ( | * ) ; - parental\-source\-v6 ( | * ) ; + parental\-agents [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + parental\-source ( | * ); + parental\-source\-v6 ( | * ); serial\-update\-method ( date | increment | unixtime ); sig\-signing\-nodes ; sig\-signing\-signatures ; @@ -731,7 +731,7 @@ zone [ ] { allow\-query\-on { ; ... }; allow\-transfer [ port ] [ transport ] { ; ... }; allow\-update\-forwarding { ; ... }; - also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; auto\-dnssec ( allow | maintain | off ); // deprecated check\-names ( fail | warn | ignore ); database ; @@ -744,7 +744,7 @@ zone [ ] { dnssec\-update\-mode ( maintain | no\-resign ); file ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; inline\-signing ; ixfr\-from\-differences ; journal ; @@ -765,22 +765,22 @@ zone [ ] { multi\-master ; notify ( explicit | master\-only | primary\-only | ); notify\-delay ; - notify\-source ( | * ) ; - notify\-source\-v6 ( | * ) ; + notify\-source ( | * ); + notify\-source\-v6 ( | * ); notify\-to\-soa ; nsec3\-test\-zone ; // test only - parental\-agents [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; - parental\-source ( | * ) ; - parental\-source\-v6 ( | * ) ; - primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + parental\-agents [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + parental\-source ( | * ); + parental\-source\-v6 ( | * ); + primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; request\-expire ; request\-ixfr ; sig\-signing\-nodes ; sig\-signing\-signatures ; sig\-signing\-type ; sig\-validity\-interval [ ]; - transfer\-source ( | * ) ; - transfer\-source\-v6 ( | * ) ; + transfer\-source ( | * ); + transfer\-source\-v6 ( | * ); try\-tcp\-refresh ; update\-check\-ksk ; zero\-no\-soa\-ttl ; @@ -803,7 +803,7 @@ zone [ ] { allow\-query\-on { ; ... }; allow\-transfer [ port ] [ transport ] { ; ... }; allow\-update\-forwarding { ; ... }; - also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also\-notify [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; check\-names ( fail | warn | ignore ); database ; file ; @@ -825,13 +825,13 @@ zone [ ] { multi\-master ; notify ( explicit | master\-only | primary\-only | ); notify\-delay ; - notify\-source ( | * ) ; - notify\-source\-v6 ( | * ) ; - primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + notify\-source ( | * ); + notify\-source\-v6 ( | * ); + primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; request\-expire ; request\-ixfr ; - transfer\-source ( | * ) ; - transfer\-source\-v6 ( | * ) ; + transfer\-source ( | * ); + transfer\-source\-v6 ( | * ); try\-tcp\-refresh ; zero\-no\-soa\-ttl ; zone\-statistics ( full | terse | none | ); @@ -850,7 +850,7 @@ zone [ ] { type forward; delegation\-only ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; }; .ft P @@ -888,7 +888,7 @@ zone [ ] { masterfile\-style ( full | relative ); max\-records ; max\-zone\-ttl ( unlimited | ); // deprecated - primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; zone\-statistics ( full | terse | none | ); }; @@ -906,7 +906,7 @@ zone [ ] { allow\-query { ; ... }; allow\-query\-on { ; ... }; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; max\-records ; server\-addresses { ( | ); ... }; server\-names { ; ... }; @@ -932,7 +932,7 @@ zone [ ] { dialup ( notify | notify\-passive | passive | refresh | ); file ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; masterfile\-format ( raw | text ); masterfile\-style ( full | relative ); max\-records ; @@ -943,9 +943,9 @@ zone [ ] { min\-refresh\-time ; min\-retry\-time ; multi\-master ; - primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; - transfer\-source ( | * ) ; - transfer\-source\-v6 ( | * ) ; + primaries [ port ] [ source ( | * ) ] [ source\-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + transfer\-source ( | * ); + transfer\-source\-v6 ( | * ); zone\-statistics ( full | terse | none | ); }; diff --git a/doc/misc/forward.zoneopt b/doc/misc/forward.zoneopt index 211a0901b92..6c5f38b013c 100644 --- a/doc/misc/forward.zoneopt +++ b/doc/misc/forward.zoneopt @@ -2,5 +2,5 @@ zone [ ] { type forward; delegation-only ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; }; diff --git a/doc/misc/mirror.zoneopt b/doc/misc/mirror.zoneopt index 467a78dc1e1..cc9dbaa446b 100644 --- a/doc/misc/mirror.zoneopt +++ b/doc/misc/mirror.zoneopt @@ -5,7 +5,7 @@ zone [ ] { allow-query-on { ; ... }; allow-transfer [ port ] [ transport ] { ; ... }; allow-update-forwarding { ; ... }; - also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; check-names ( fail | warn | ignore ); database ; file ; @@ -27,13 +27,13 @@ zone [ ] { multi-master ; notify ( explicit | master-only | primary-only | ); notify-delay ; - notify-source ( | * ) ; - notify-source-v6 ( | * ) ; - primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + notify-source ( | * ); + notify-source-v6 ( | * ); + primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; request-expire ; request-ixfr ; - transfer-source ( | * ) ; - transfer-source-v6 ( | * ) ; + transfer-source ( | * ); + transfer-source-v6 ( | * ); try-tcp-refresh ; zero-no-soa-ttl ; zone-statistics ( full | terse | none | ); diff --git a/doc/misc/options b/doc/misc/options index 9064b2b598c..e6e8d67816e 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -69,7 +69,7 @@ options { allow-transfer [ port ] [ transport ] { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; - also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; answer-cookie ; attach-cache ; auth-nxdomain ; @@ -79,7 +79,7 @@ options { avoid-v6-udp-ports { ; ... }; // deprecated bindkeys-file ; blackhole { ; ... }; - catalog-zones { zone [ default-primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone-directory ] [ in-memory ] [ min-update-interval ]; ... }; + catalog-zones { zone [ default-primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone-directory ] [ in-memory ] [ min-update-interval ]; ... }; check-dup-records ( fail | warn | ignore ); check-integrity ; check-mx ( fail | warn | ignore ); @@ -136,7 +136,7 @@ options { fetches-per-zone [ ( drop | fail ) ]; flush-zones-on-shutdown ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; fstrm-set-buffer-hint ; // not configured fstrm-set-flush-timeout ; // not configured fstrm-set-input-queue-size ; // not configured @@ -202,15 +202,15 @@ options { notify ( explicit | master-only | primary-only | ); notify-delay ; notify-rate ; - notify-source ( | * ) ; - notify-source-v6 ( | * ) ; + notify-source ( | * ); + notify-source-v6 ( | * ); notify-to-soa ; nsec3-test-zone ; // test only nta-lifetime ; nta-recheck ; nxdomain-redirect ; - parental-source ( | * ) ; - parental-source-v6 ( | * ) ; + parental-source ( | * ); + parental-source-v6 ( | * ); pid-file ( | none ); port ; preferred-glue ; @@ -292,8 +292,8 @@ options { tls-port ; transfer-format ( many-answers | one-answer ); transfer-message-size ; - transfer-source ( | * ) ; - transfer-source-v6 ( | * ) ; + transfer-source ( | * ); + transfer-source-v6 ( | * ); transfers-in ; transfers-out ; transfers-per-ns ; @@ -312,11 +312,11 @@ options { zone-statistics ( full | terse | none | ); }; -parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times +parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times plugin ( query ) [ { } ]; // may occur multiple times -primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times +primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; // may occur multiple times server { bogus ; @@ -325,8 +325,8 @@ server { edns-version ; keys ; max-udp-size ; - notify-source ( | * ) ; - notify-source-v6 ( | * ) ; + notify-source ( | * ); + notify-source-v6 ( | * ); padding ; provide-ixfr ; query-source [ address ] ( | * ); @@ -339,8 +339,8 @@ server { tcp-keepalive ; tcp-only ; transfer-format ( many-answers | one-answer ); - transfer-source ( | * ) ; - transfer-source-v6 ( | * ) ; + transfer-source ( | * ); + transfer-source-v6 ( | * ); transfers ; }; // may occur multiple times @@ -376,11 +376,11 @@ view [ ] { allow-transfer [ port ] [ transport ] { ; ... }; allow-update { ; ... }; allow-update-forwarding { ; ... }; - also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; attach-cache ; auth-nxdomain ; auto-dnssec ( allow | maintain | off ); // deprecated - catalog-zones { zone [ default-primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone-directory ] [ in-memory ] [ min-update-interval ]; ... }; + catalog-zones { zone [ default-primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... } ] [ zone-directory ] [ in-memory ] [ min-update-interval ]; ... }; check-dup-records ( fail | warn | ignore ); check-integrity ; check-mx ( fail | warn | ignore ); @@ -434,7 +434,7 @@ view [ ] { fetches-per-server [ ( drop | fail ) ]; fetches-per-zone [ ( drop | fail ) ]; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; ipv4only-contact ; ipv4only-enable ; ipv4only-server ; @@ -483,15 +483,15 @@ view [ ] { nocookie-udp-size ; notify ( explicit | master-only | primary-only | ); notify-delay ; - notify-source ( | * ) ; - notify-source-v6 ( | * ) ; + notify-source ( | * ); + notify-source-v6 ( | * ); notify-to-soa ; nsec3-test-zone ; // test only nta-lifetime ; nta-recheck ; nxdomain-redirect ; - parental-source ( | * ) ; - parental-source-v6 ( | * ) ; + parental-source ( | * ); + parental-source-v6 ( | * ); plugin ( query ) [ { } ]; // may occur multiple times preferred-glue ; prefetch [ ]; @@ -538,8 +538,8 @@ view [ ] { edns-version ; keys ; max-udp-size ; - notify-source ( | * ) ; - notify-source-v6 ( | * ) ; + notify-source ( | * ); + notify-source-v6 ( | * ); padding ; provide-ixfr ; query-source [ address ] ( | * ); @@ -552,8 +552,8 @@ view [ ] { tcp-keepalive ; tcp-only ; transfer-format ( many-answers | one-answer ); - transfer-source ( | * ) ; - transfer-source-v6 ( | * ) ; + transfer-source ( | * ); + transfer-source-v6 ( | * ); transfers ; }; // may occur multiple times servfail-ttl ; @@ -570,8 +570,8 @@ view [ ] { suppress-initial-notify ; // obsolete synth-from-dnssec ; transfer-format ( many-answers | one-answer ); - transfer-source ( | * ) ; - transfer-source-v6 ( | * ) ; + transfer-source ( | * ); + transfer-source-v6 ( | * ); trust-anchor-telemetry ; // experimental trust-anchors { ( static-key | initial-key | static-ds | initial-ds ) ; ... }; // may occur multiple times trusted-keys { ; ... }; // may occur multiple times, deprecated diff --git a/doc/misc/primary.zoneopt b/doc/misc/primary.zoneopt index 85fc3a36ed4..f0d3a93b752 100644 --- a/doc/misc/primary.zoneopt +++ b/doc/misc/primary.zoneopt @@ -4,7 +4,7 @@ zone [ ] { allow-query-on { ; ... }; allow-transfer [ port ] [ transport ] { ; ... }; allow-update { ; ... }; - also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; auto-dnssec ( allow | maintain | off ); // deprecated check-dup-records ( fail | warn | ignore ); check-integrity ; @@ -27,7 +27,7 @@ zone [ ] { dnssec-update-mode ( maintain | no-resign ); file ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; inline-signing ; ixfr-from-differences ; journal ; @@ -42,13 +42,13 @@ zone [ ] { max-zone-ttl ( unlimited | ); // deprecated notify ( explicit | master-only | primary-only | ); notify-delay ; - notify-source ( | * ) ; - notify-source-v6 ( | * ) ; + notify-source ( | * ); + notify-source-v6 ( | * ); notify-to-soa ; nsec3-test-zone ; // test only - parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; - parental-source ( | * ) ; - parental-source-v6 ( | * ) ; + parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + parental-source ( | * ); + parental-source-v6 ( | * ); serial-update-method ( date | increment | unixtime ); sig-signing-nodes ; sig-signing-signatures ; diff --git a/doc/misc/redirect.zoneopt b/doc/misc/redirect.zoneopt index 94e104d444e..c0bee863fb5 100644 --- a/doc/misc/redirect.zoneopt +++ b/doc/misc/redirect.zoneopt @@ -8,6 +8,6 @@ zone [ ] { masterfile-style ( full | relative ); max-records ; max-zone-ttl ( unlimited | ); // deprecated - primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; zone-statistics ( full | terse | none | ); }; diff --git a/doc/misc/secondary.zoneopt b/doc/misc/secondary.zoneopt index cbddd65be88..c4de3866a7d 100644 --- a/doc/misc/secondary.zoneopt +++ b/doc/misc/secondary.zoneopt @@ -5,7 +5,7 @@ zone [ ] { allow-query-on { ; ... }; allow-transfer [ port ] [ transport ] { ; ... }; allow-update-forwarding { ; ... }; - also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + also-notify [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; auto-dnssec ( allow | maintain | off ); // deprecated check-names ( fail | warn | ignore ); database ; @@ -18,7 +18,7 @@ zone [ ] { dnssec-update-mode ( maintain | no-resign ); file ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; inline-signing ; ixfr-from-differences ; journal ; @@ -39,22 +39,22 @@ zone [ ] { multi-master ; notify ( explicit | master-only | primary-only | ); notify-delay ; - notify-source ( | * ) ; - notify-source-v6 ( | * ) ; + notify-source ( | * ); + notify-source-v6 ( | * ); notify-to-soa ; nsec3-test-zone ; // test only - parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; - parental-source ( | * ) ; - parental-source-v6 ( | * ) ; - primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + parental-agents [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + parental-source ( | * ); + parental-source-v6 ( | * ); + primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; request-expire ; request-ixfr ; sig-signing-nodes ; sig-signing-signatures ; sig-signing-type ; sig-validity-interval [ ]; - transfer-source ( | * ) ; - transfer-source-v6 ( | * ) ; + transfer-source ( | * ); + transfer-source-v6 ( | * ); try-tcp-refresh ; update-check-ksk ; zero-no-soa-ttl ; diff --git a/doc/misc/static-stub.zoneopt b/doc/misc/static-stub.zoneopt index 58fd0ce9eb5..85c158fbcbd 100644 --- a/doc/misc/static-stub.zoneopt +++ b/doc/misc/static-stub.zoneopt @@ -3,7 +3,7 @@ zone [ ] { allow-query { ; ... }; allow-query-on { ; ... }; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; max-records ; server-addresses { ( | ); ... }; server-names { ; ... }; diff --git a/doc/misc/stub.zoneopt b/doc/misc/stub.zoneopt index 0c37eefef8c..ab1e49e1897 100644 --- a/doc/misc/stub.zoneopt +++ b/doc/misc/stub.zoneopt @@ -8,7 +8,7 @@ zone [ ] { dialup ( notify | notify-passive | passive | refresh | ); file ; forward ( first | only ); - forwarders [ port ] { ( | ) [ port ]; ... }; + forwarders [ port ] [ tls ] { ( | ) [ port ] [ tls ]; ... }; masterfile-format ( raw | text ); masterfile-style ( full | relative ); max-records ; @@ -19,8 +19,8 @@ zone [ ] { min-refresh-time ; min-retry-time ; multi-master ; - primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; - transfer-source ( | * ) ; - transfer-source-v6 ( | * ) ; + primaries [ port ] [ source ( | * ) ] [ source-v6 ( | * ) ] { ( | [ port ] | [ port ] ) [ key ] [ tls ]; ... }; + transfer-source ( | * ); + transfer-source-v6 ( | * ); zone-statistics ( full | terse | none | ); }; diff --git a/lib/bind9/check.c b/lib/bind9/check.c index ec18d66f4e8..48cb90c6e27 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -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; } diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index c4f2d863628..f790cd4377f 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -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); /*%< diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index 3b19a5f4eff..7cbcf7f4706 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -169,14 +169,18 @@ struct cfg_rep { struct cfg_obj { const cfg_type_t *type; union { - uint32_t uint32; - uint64_t uint64; - isc_textregion_t string; /*%< null terminated, too */ - bool boolean; - cfg_map_t map; - cfg_list_t list; - cfg_obj_t **tuple; - isc_sockaddr_t sockaddr; + uint32_t uint32; + uint64_t uint64; + isc_textregion_t string; /*%< null terminated, too */ + bool boolean; + cfg_map_t map; + 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); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 898b03a6f5f..2e92d2d4875 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -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", - cfg_parse_bracketed_list, - cfg_print_bracketed_list, - cfg_doc_bracketed_list, - &cfg_rep_list, - &cfg_type_sockaddr }; +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_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; diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 6fc3e809472..f70665675ed 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -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 @@ -3320,14 +3396,17 @@ cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type) { n++; POST(n); } - cfg_print_cstr(pctx, " ) "); + cfg_print_cstr(pctx, " )"); if ((*flagp & CFG_ADDR_PORTOK) != 0) { if ((*flagp & CFG_ADDR_WILDOK) != 0) { - cfg_print_cstr(pctx, "[ port ( | * ) ]"); + cfg_print_cstr(pctx, " [ port ( | * ) ]"); } else { - cfg_print_cstr(pctx, "[ port ]"); + cfg_print_cstr(pctx, " [ port ]"); } } + if ((*flagp & CFG_ADDR_TLSOK) != 0) { + cfg_print_cstr(pctx, " [ tls ]"); + } } 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;