From c315e5cfead876251ee4ff5600ee67303b2729a4 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Fri, 4 Jun 2004 02:31:43 +0000 Subject: [PATCH] 1648. [func] Update dnssec-lookaside named.conf syntax to support multiple dnssec-lookaside namespaces (not yet implemented). --- CHANGES | 4 +- bin/named/server.c | 46 ++++-- bin/tests/system/dlv/ns5/named.conf | 4 +- bin/tests/system/dnssec/ns6/named.conf | 4 +- doc/arm/Bv9ARM-book.xml | 14 +- doc/misc/options | 4 +- lib/bind9/check.c | 193 ++++++++++++++----------- lib/isccfg/namedconf.c | 27 +++- 8 files changed, 189 insertions(+), 107 deletions(-) diff --git a/CHANGES b/CHANGES index a8cb739253..4e9bac6183 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ 1649. [placeholder] rt11206 -1648. [placeholder] rt11439 +1648. [func] Update dnssec-lookaside named.conf syntax to support + multiple dnssec-lookaside namespaces (not yet + implemented). 1647. [placeholder] rt11445 diff --git a/bin/named/server.c b/bin/named/server.c index 0e6320c6e2..a391ceff17 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.426 2004/05/14 00:51:52 marka Exp $ */ +/* $Id: server.c,v 1.427 2004/06/04 02:31:40 marka Exp $ */ #include @@ -1171,14 +1171,42 @@ configure_view(dns_view_t *view, cfg_obj_t *config, cfg_obj_t *vconfig, obj = NULL; result = ns_config_get(maps, "dnssec-lookaside", &obj); if (result == ISC_R_SUCCESS) { - const char *dlv; - isc_buffer_t b; - dlv = cfg_obj_asstring(obj); - isc_buffer_init(&b, dlv, strlen(dlv)); - isc_buffer_add(&b, strlen(dlv)); - CHECK(dns_name_fromtext(dns_fixedname_name(&view->dlv_fixed), - &b, dns_rootname, ISC_TRUE, NULL)); - view->dlv = dns_fixedname_name(&view->dlv_fixed); + for (element = cfg_list_first(obj); + element != NULL; + element = cfg_list_next(element)) + { + const char *str; + isc_buffer_t b; + dns_name_t *dlv; + + obj = cfg_listelt_value(element); +#if 0 + dns_fixedname_t fixed; + dns_name_t *name; + + /* + * When we support multiple dnssec-lookaside + * entries this is how to find the domain to be + * checked. XXXMPA + */ + dns_fixedname_init(&fixed); + name = dns_fixedname_name(&fixed); + str = cfg_obj_asstring(cfg_tuple_get(obj, + "domain")); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + CHECK(dns_name_fromtext(name, &b, dns_rootname, + ISC_TRUE, NULL)); +#endif + str = cfg_obj_asstring(cfg_tuple_get(obj, + "trust-anchor")); + isc_buffer_init(&b, str, strlen(str)); + isc_buffer_add(&b, strlen(str)); + dlv = dns_fixedname_name(&view->dlv_fixed); + CHECK(dns_name_fromtext(dlv, &b, dns_rootname, + ISC_TRUE, NULL)); + view->dlv = dns_fixedname_name(&view->dlv_fixed); + } } else view->dlv = NULL; diff --git a/bin/tests/system/dlv/ns5/named.conf b/bin/tests/system/dlv/ns5/named.conf index 70f7d422dd..ebe0cb426a 100644 --- a/bin/tests/system/dlv/ns5/named.conf +++ b/bin/tests/system/dlv/ns5/named.conf @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.2 2004/05/14 04:58:23 marka Exp $ */ +/* $Id: named.conf,v 1.3 2004/06/04 02:31:41 marka Exp $ */ /* * Choose a keyname that is unlikely to clash with any real key names. @@ -58,7 +58,7 @@ options { recursion yes; notify yes; dnssec-enable yes; - dnssec-lookaside "dlv.utld"; + dnssec-lookaside "." trust-anchor "dlv.utld"; }; zone "." { type hint; file "hints"; }; diff --git a/bin/tests/system/dnssec/ns6/named.conf b/bin/tests/system/dnssec/ns6/named.conf index b5eca59ee7..4fcd5894b4 100644 --- a/bin/tests/system/dnssec/ns6/named.conf +++ b/bin/tests/system/dnssec/ns6/named.conf @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: named.conf,v 1.6 2004/03/10 02:19:54 marka Exp $ */ +/* $Id: named.conf,v 1.7 2004/06/04 02:31:41 marka Exp $ */ // NS6 @@ -32,7 +32,7 @@ options { notify yes; disable-algorithms . { DSA; }; dnssec-enable yes; - dnssec-lookaside dlv; + dnssec-lookaside . trust-anchor dlv; }; zone "." { diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index 2bebda5b53..6df8cd1565 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -2,7 +2,7 @@ - + BIND 9 Administrator Reference Manual @@ -2758,7 +2758,7 @@ statement in the named.conf file: use-id-pool yes_or_no; maintain-ixfr-base yes_or_no; dnssec-enable yes_or_no; - dnssec-lookaside domain; + dnssec-lookaside domain trust-anchor domain; dnssec-must-be-secure domain yes_or_no; forward ( only | first ); forwarders { ip_addr port ip_port ; ip_addr port ip_port ; ... }; @@ -2985,10 +2985,12 @@ Only the most specific will be applied. When set dnssec-lookaside provides the validator with an alternate method to validate DNSKEY records at the -top of a zone. When set the domain specified by -dnssec-lookaside is appended to DNSKEY's -name and a DLV record is looked up. If the DLV record validates -a DNSKEY (similarly to the way a DS record does) the DNSKEY RRset is deemed to be trusted. +top of a zone. When a DNSKEY is at or below a domain specified by the +deepest dnssec-lookaside, and the normal dnssec validation +has left the key untrusted, the trust-anchor will be append to the key +name and a DLV record will be looked up to see if it can validate the +key. If the DLV record validates a DNSKEY (similarly to the way a DS +record does) the DNSKEY RRset is deemed to be trusted. dnssec-must-be-secure diff --git a/doc/misc/options b/doc/misc/options index 8eec93f4ca..f77e4940c5 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -82,7 +82,7 @@ options { root-delegation-only [ exclude { ; ... } ]; disable-algorithms { ; ... }; dnssec-enable ; - dnssec-lookaside ; + dnssec-lookaside trust-anchor ; dnssec-must-be-secure ; allow-query { ; ... }; allow-transfer { ; ... }; @@ -262,7 +262,7 @@ view { root-delegation-only [ exclude { ; ... } ]; disable-algorithms { ; ... }; dnssec-enable ; - dnssec-lookaside ; + dnssec-lookaside trust-anchor ; dnssec-must-be-secure ; allow-query { ; ... }; allow-transfer { ; ... }; diff --git a/lib/bind9/check.c b/lib/bind9/check.c index b4b205c507..2bca8ab5be 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: check.c,v 1.46 2004/05/17 05:37:41 marka Exp $ */ +/* $Id: check.c,v 1.47 2004/06/04 02:31:43 marka Exp $ */ #include @@ -279,6 +279,39 @@ disabled_algorithms(cfg_obj_t *disabled, isc_log_t *logctx) { return (result); } +static isc_result_t +nameexist(cfg_obj_t *obj, const char *name, int value, isc_symtab_t *symtab, + const char *fmt, isc_log_t *logctx, isc_mem_t *mctx) +{ + char *key; + const char *file; + unsigned int line; + isc_result_t result; + isc_symvalue_t symvalue; + + key = isc_mem_strdup(mctx, name); + if (key == NULL) + return (ISC_R_NOMEMORY); + symvalue.as_pointer = obj; + result = isc_symtab_define(symtab, key, value, symvalue, + isc_symexists_reject); + if (result == ISC_R_EXISTS) { + RUNTIME_CHECK(isc_symtab_lookup(symtab, key, value, + &symvalue) == ISC_R_SUCCESS); + file = cfg_obj_file(symvalue.as_pointer); + line = cfg_obj_line(symvalue.as_pointer); + + if (file == NULL) + file = ""; + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, fmt, key, file, line); + isc_mem_free(mctx, key); + result = ISC_R_EXISTS; + } else if (result != ISC_R_SUCCESS) { + isc_mem_free(mctx, key); + } + return (result); +} + static isc_result_t mustbesecure(cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx, isc_mem_t *mctx) @@ -290,9 +323,6 @@ mustbesecure(cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx, dns_name_t *name; isc_buffer_t b; isc_result_t result = ISC_R_SUCCESS; - isc_result_t tresult; - isc_symvalue_t symvalue; - char *key; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); @@ -300,42 +330,16 @@ mustbesecure(cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx, str = cfg_obj_asstring(obj); isc_buffer_init(&b, str, strlen(str)); isc_buffer_add(&b, strlen(str)); - tresult = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); - if (tresult != ISC_R_SUCCESS) { + result = dns_name_fromtext(name, &b, dns_rootname, ISC_FALSE, NULL); + if (result != ISC_R_SUCCESS) { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "bad domain name '%s'", str); - result = tresult; } else { - dns_name_format(name, namebuf, sizeof(namebuf)); - key = isc_mem_strdup(mctx, namebuf); - if (key == NULL) - return (ISC_R_NOMEMORY); - symvalue.as_pointer = secure; - tresult = isc_symtab_define(symtab, key, 1, symvalue, - isc_symexists_reject); - if (tresult == ISC_R_EXISTS) { - const char *file; - unsigned int line; - - RUNTIME_CHECK(isc_symtab_lookup(symtab, key, 1, - &symvalue) == ISC_R_SUCCESS); - isc_mem_free(mctx, key); - file = cfg_obj_file(symvalue.as_pointer); - line = cfg_obj_line(symvalue.as_pointer); - - if (file == NULL) - file = ""; - - cfg_obj_log(secure, logctx, ISC_LOG_ERROR, - "dnssec-must-be-secure '%s': already " - "exists previous definition: %s:%u", - namebuf, file, line); - result = tresult; - } else if (tresult != ISC_R_SUCCESS) { - isc_mem_free(mctx, key); - result = tresult; - } + result = nameexist(secure, namebuf, 1, symtab, + "dnssec-must-be-secure '%s': already " + "exists previous definition: %s:%u", + logctx, mctx); } return (result); } @@ -353,6 +357,7 @@ check_options(cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) { unsigned int i; cfg_obj_t *obj = NULL; cfg_listelt_t *element; + isc_symtab_t *symtab = NULL; static intervaltable intervals[] = { { "cleaning-interval", 60, 28 * 24 * 60 }, /* 28 days */ @@ -458,21 +463,70 @@ check_options(cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) { obj = NULL; (void)cfg_map_get(options, "dnssec-lookaside", &obj); if (obj != NULL) { - dns_fixedname_t fixedname; - const char *dlv; - isc_buffer_t b; - - dlv = cfg_obj_asstring(obj); - dns_fixedname_init(&fixedname); - isc_buffer_init(&b, dlv, strlen(dlv)); - isc_buffer_add(&b, strlen(dlv)); - tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b, - dns_rootname, ISC_TRUE, NULL); - if (tresult != ISC_R_SUCCESS) { - cfg_obj_log(obj, logctx, ISC_LOG_ERROR, - "bad domain name '%s'", dlv); + tresult = isc_symtab_create(mctx, 100, freekey, mctx, + ISC_TRUE, &symtab); + if (tresult != ISC_R_SUCCESS) result = tresult; + for (element = cfg_list_first(obj); + element != NULL; + element = cfg_list_next(element)) + { + dns_fixedname_t fixedname; + dns_name_t *name; + const char *dlv; + isc_buffer_t b; + + obj = cfg_listelt_value(element); + + dlv = cfg_obj_asstring(cfg_tuple_get(obj, "domain")); + dns_fixedname_init(&fixedname); + name = dns_fixedname_name(&fixedname); + isc_buffer_init(&b, dlv, strlen(dlv)); + isc_buffer_add(&b, strlen(dlv)); + tresult = dns_name_fromtext(name, &b, dns_rootname, + ISC_TRUE, NULL); + if (tresult != ISC_R_SUCCESS) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "bad domain name '%s'", dlv); + result = tresult; + } + if (symtab != NULL) { + tresult = nameexist(obj, dlv, 1, symtab, + "dnssec-lookaside '%s': " + "already exists previous " + "definition: %s:%u", + logctx, mctx); + if (tresult != ISC_R_SUCCESS && + result == ISC_R_SUCCESS) + result = tresult; + } + /* + * XXXMPA to be removed when multiple lookaside + * namespaces are supported. + */ + if (!dns_name_equal(dns_rootname, name)) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "dnssec-lookaside '%s': " + "non-root not yet supported", dlv); + if (result == ISC_R_SUCCESS) + result = ISC_R_FAILURE; + } + dlv = cfg_obj_asstring(cfg_tuple_get(obj, + "trust-anchor")); + dns_fixedname_init(&fixedname); + isc_buffer_init(&b, dlv, strlen(dlv)); + isc_buffer_add(&b, strlen(dlv)); + tresult = dns_name_fromtext(name, &b, dns_rootname, + ISC_TRUE, NULL); + if (tresult != ISC_R_SUCCESS) { + cfg_obj_log(obj, logctx, ISC_LOG_ERROR, + "bad domain name '%s'", dlv); + if (result == ISC_R_SUCCESS) + result = tresult; + } } + if (symtab != NULL) + isc_symtab_destroy(&symtab); } /* @@ -643,7 +697,6 @@ check_zoneconf(cfg_obj_t *zconfig, cfg_obj_t *config, isc_symtab_t *symtab, unsigned int ztype; cfg_obj_t *zoptions; cfg_obj_t *obj = NULL; - isc_symvalue_t symvalue; isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; unsigned int i; @@ -758,48 +811,22 @@ check_zoneconf(cfg_obj_t *zconfig, cfg_obj_t *config, isc_symtab_t *symtab, dns_fixedname_init(&fixedname); isc_buffer_init(&b, zname, strlen(zname)); isc_buffer_add(&b, strlen(zname)); - result = dns_name_fromtext(dns_fixedname_name(&fixedname), &b, + tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b, dns_rootname, ISC_TRUE, NULL); if (result != ISC_R_SUCCESS) { cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, "zone '%s': is not a valid name", zname); - result = ISC_R_FAILURE; + tresult = ISC_R_FAILURE; } else { char namebuf[DNS_NAME_FORMATSIZE]; - char *key; dns_name_format(dns_fixedname_name(&fixedname), namebuf, sizeof(namebuf)); - key = isc_mem_strdup(mctx, namebuf); - if (key == NULL) - return (ISC_R_NOMEMORY); - symvalue.as_pointer = zconfig; - tresult = isc_symtab_define(symtab, key, - ztype == HINTZONE ? 1 : 2, - symvalue, isc_symexists_reject); - if (tresult == ISC_R_EXISTS) { - const char *file; - unsigned int line; - - RUNTIME_CHECK(isc_symtab_lookup(symtab, key, - ztype == HINTZONE ? 1 : 2, - &symvalue) == ISC_R_SUCCESS); - isc_mem_free(mctx, key); - file = cfg_obj_file(symvalue.as_pointer); - line = cfg_obj_line(symvalue.as_pointer); - - if (file == NULL) - file = ""; - cfg_obj_log(zconfig, logctx, ISC_LOG_ERROR, - "zone '%s': already exists " - "previous definition: %s:%u", - zname, file, line); - result = ISC_R_FAILURE; - } else if (tresult != ISC_R_SUCCESS) { - isc_mem_free(mctx, key); - - return (tresult); - } + tresult = nameexist(zconfig, namebuf, ztype == HINTZONE ? 1 : 2, + symtab, "zone '%s': already exists " + "previous definition: %s:%u", logctx, mctx); + if (tresult != ISC_R_SUCCESS) + result = tresult; } /* diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 5460253c0f..759e199b3e 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: namedconf.c,v 1.33 2004/04/15 23:40:27 marka Exp $ */ +/* $Id: namedconf.c,v 1.34 2004/06/04 02:31:43 marka Exp $ */ #include @@ -658,6 +658,28 @@ static cfg_type_t cfg_type_mustbesecure = { &cfg_rep_tuple, mustbesecure_fields }; +/* + * dnssec-lookaside + */ + +static keyword_type_t trustanchor_kw = { "trust-anchor", &cfg_type_astring }; + +static cfg_type_t cfg_type_trustanchor = { + "trust-anchor", parse_keyvalue, print_keyvalue, doc_keyvalue, + &cfg_rep_string, &trustanchor_kw +}; + +static cfg_tuplefielddef_t lookaside_fields[] = { + { "domain", &cfg_type_astring, 0 }, + { "trust-anchor", &cfg_type_trustanchor, 0 }, + { NULL, NULL, 0 } +}; + +static cfg_type_t cfg_type_lookaside = { + "lookaside", cfg_parse_tuple, cfg_print_tuple, cfg_doc_tuple, + &cfg_rep_tuple, lookaside_fields +}; + /* * Clauses that can be found within the 'view' statement, * with defaults in the 'options' statement. @@ -703,7 +725,7 @@ view_clauses[] = { { "disable-algorithms", &cfg_type_disablealgorithm, CFG_CLAUSEFLAG_MULTI }, { "dnssec-enable", &cfg_type_boolean, 0 }, - { "dnssec-lookaside", &cfg_type_astring, 0 }, + { "dnssec-lookaside", &cfg_type_lookaside, CFG_CLAUSEFLAG_MULTI }, { "dnssec-must-be-secure", &cfg_type_mustbesecure, CFG_CLAUSEFLAG_MULTI }, { NULL, NULL, 0 } @@ -1201,6 +1223,7 @@ controls_clauses[] = { CFG_CLAUSEFLAG_MULTI|CFG_CLAUSEFLAG_NOTIMP }, { NULL, NULL, 0 } }; + static cfg_clausedef_t * controls_clausesets[] = { controls_clauses,