diff --git a/bin/named/server.c b/bin/named/server.c index 842277d46a..4995e47fef 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -8479,6 +8479,7 @@ load_configuration(const char *filename, named_server_t *server, const cfg_obj_t *kasps; dns_kasp_t *kasp = NULL; dns_kasp_t *kasp_next = NULL; + dns_kasp_t *default_kasp = NULL; dns_kasplist_t tmpkasplist, kasplist; const cfg_obj_t *views; dns_view_t *view = NULL; @@ -9205,10 +9206,10 @@ load_configuration(const char *filename, named_server_t *server, (void)configure_session_key(maps, server, named_g_mctx, first_time); /* - * Create the DNSSEC key and signing policies (KASP). + * Create the built-in kasp policies ("default", "insecure"). */ kasps = NULL; - (void)cfg_map_get(config, "dnssec-policy", &kasps); + (void)cfg_map_get(named_g_config, "dnssec-policy", &kasps); for (element = cfg_list_first(kasps); element != NULL; element = cfg_list_next(element)) { @@ -9218,25 +9219,31 @@ load_configuration(const char *filename, named_server_t *server, named_g_lctx, &kasplist, &kasp)); INSIST(kasp != NULL); dns_kasp_freeze(kasp); + if (strcmp(dns_kasp_getname(kasp), "default") == 0) { + dns_kasp_attach(kasp, &default_kasp); + } dns_kasp_detach(&kasp); } + INSIST(default_kasp != NULL); + /* - * Create the built-in kasp policies ("default", "insecure"). + * Create the DNSSEC key and signing policies (KASP). */ - kasp = NULL; - CHECK(cfg_kasp_fromconfig(NULL, "default", named_g_mctx, named_g_lctx, - &kasplist, &kasp)); - INSIST(kasp != NULL); - dns_kasp_freeze(kasp); - dns_kasp_detach(&kasp); - - kasp = NULL; - CHECK(cfg_kasp_fromconfig(NULL, "insecure", named_g_mctx, named_g_lctx, - &kasplist, &kasp)); - INSIST(kasp != NULL); - dns_kasp_freeze(kasp); - dns_kasp_detach(&kasp); + kasps = NULL; + (void)cfg_map_get(config, "dnssec-policy", &kasps); + for (element = cfg_list_first(kasps); element != NULL; + element = cfg_list_next(element)) + { + cfg_obj_t *kconfig = cfg_listelt_value(element); + kasp = NULL; + CHECK(cfg_kasp_fromconfig(kconfig, default_kasp, named_g_mctx, + named_g_lctx, &kasplist, &kasp)); + INSIST(kasp != NULL); + dns_kasp_freeze(kasp); + dns_kasp_detach(&kasp); + } + dns_kasp_detach(&default_kasp); tmpkasplist = server->kasplist; server->kasplist = kasplist; kasplist = tmpkasplist; diff --git a/lib/isccfg/include/isccfg/kaspconf.h b/lib/isccfg/include/isccfg/kaspconf.h index f7df0fbf5f..65e73e0137 100644 --- a/lib/isccfg/include/isccfg/kaspconf.h +++ b/lib/isccfg/include/isccfg/kaspconf.h @@ -26,14 +26,15 @@ ISC_LANG_BEGINDECLS isc_result_t -cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, - isc_log_t *logctx, dns_kasplist_t *kasplist, - dns_kasp_t **kaspp); +cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, + isc_mem_t *mctx, isc_log_t *logctx, + dns_kasplist_t *kasplist, dns_kasp_t **kaspp); /*%< - * Create and configure a KASP. If 'config' is NULL, a built-in configuration - * is used, referred to by 'name'. If a 'kasplist' is provided, a lookup - * happens and if a KASP already exists with the same name, no new KASP is - * created, and no attach to 'kaspp' happens. + * Create and configure a KASP. If 'default_kasp' is not NULL, the built-in + * default configuration is used to set values that are not explicitly set in + * the policy. If a 'kasplist' is provided, a lookup happens and if a KASP + * already exists with the same name, no new KASP is created, and no attach to + * 'kaspp' happens. * * Requires: * diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index db99ebbae3..932466aad7 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -311,9 +311,9 @@ cfg_nsec3param_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, } isc_result_t -cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, - isc_log_t *logctx, dns_kasplist_t *kasplist, - dns_kasp_t **kaspp) { +cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, + isc_mem_t *mctx, isc_log_t *logctx, + dns_kasplist_t *kasplist, dns_kasp_t **kaspp) { isc_result_t result; const cfg_obj_t *maps[2]; const cfg_obj_t *koptions = NULL; @@ -336,6 +336,9 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, kaspname = cfg_obj_asstring(cfg_tuple_get(config, "name")); INSIST(kaspname != NULL); + cfg_obj_log(config, logctx, ISC_LOG_DEBUG(1), + "dnssec-policy: load policy '%s'", kaspname); + result = dns_kasplist_find(kasplist, kaspname, &kasp); if (result == ISC_R_SUCCESS) { @@ -456,7 +459,6 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, goto cleanup; } } - INSIST(!(dns_kasp_keylist_empty(kasp))); dns_kasp_freeze(kasp); for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL; kkey = ISC_LIST_NEXT(kkey, link)) @@ -509,23 +511,56 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, const char *name, isc_mem_t *mctx, if (result != ISC_R_SUCCESS) { goto cleanup; } - } else if (strcmp(kaspname, "insecure") == 0) { - /* "dnssec-policy insecure": key list must be empty */ - INSIST(strcmp(kaspname, "insecure") == 0); - INSIST(dns_kasp_keylist_empty(kasp)); - } else { - /* No keys clause configured, use the "default". */ - result = cfg_kaspkey_fromconfig(NULL, kasp, logctx, 0, 0); - if (result != ISC_R_SUCCESS) { - goto cleanup; + } else if (default_kasp && strcmp(kaspname, "insecure") != 0) { + dns_kasp_key_t *key, *new_key; + + /* + * If there are no specific keys configured in the policy, + * inherit from the default policy (except for the built-in + * "insecure" policy). + */ + for (key = ISC_LIST_HEAD(dns_kasp_keys(default_kasp)); + key != NULL; key = ISC_LIST_NEXT(key, link)) + { + /* Create a new key reference. */ + new_key = NULL; + result = dns_kasp_key_create(kasp, &new_key); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + if (dns_kasp_key_ksk(key)) { + new_key->role |= DNS_KASP_KEY_ROLE_KSK; + } + if (dns_kasp_key_zsk(key)) { + new_key->role |= DNS_KASP_KEY_ROLE_ZSK; + } + new_key->lifetime = dns_kasp_key_lifetime(key); + new_key->algorithm = dns_kasp_key_algorithm(key); + new_key->length = dns_kasp_key_size(key); + dns_kasp_addkey(kasp, new_key); } + } + + if (strcmp(kaspname, "insecure") == 0) { + /* "dnssec-policy insecure": key list must be empty */ + INSIST(dns_kasp_keylist_empty(kasp)); + } else if (default_kasp != NULL) { + /* There must be keys configured. */ INSIST(!(dns_kasp_keylist_empty(kasp))); } /* Configuration: NSEC3 */ (void)confget(maps, "nsec3param", &nsec3); if (nsec3 == NULL) { - dns_kasp_setnsec3(kasp, false); + if (default_kasp != NULL && dns_kasp_nsec3(default_kasp)) { + dns_kasp_setnsec3param( + kasp, dns_kasp_nsec3iter(default_kasp), + (dns_kasp_nsec3flags(default_kasp) == 0x01), + dns_kasp_nsec3saltlen(default_kasp)); + } else { + dns_kasp_setnsec3(kasp, false); + } } else { dns_kasp_setnsec3(kasp, true); result = cfg_nsec3param_fromconfig(nsec3, kasp, logctx);