diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c index 42efae4ddb..f7c165ea61 100644 --- a/bin/check/named-checkconf.c +++ b/bin/check/named-checkconf.c @@ -44,8 +44,6 @@ static const char *program = "named-checkconf"; -static bool loadplugins = true; - isc_log_t *logc = NULL; #define CHECK(r) \ @@ -62,7 +60,7 @@ usage(void); static void usage(void) { fprintf(stderr, - "usage: %s [-chijlvz] [-p [-x]] [-t directory] " + "usage: %s [-achijlvz] [-p [-x]] [-t directory] " "[named.conf]\n", program); exit(1); @@ -599,13 +597,14 @@ main(int argc, char **argv) { bool print = false; bool nodeprecate = false; unsigned int flags = 0; + unsigned int checkflags = BIND_CHECK_PLUGINS | BIND_CHECK_ALGORITHMS; isc_commandline_errprint = false; /* * Process memory debugging argument first. */ -#define CMDLINE_FLAGS "cdhijlm:t:pvxz" +#define CMDLINE_FLAGS "acdhijlm:t:pvxz" while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) { switch (c) { case 'm': @@ -632,8 +631,12 @@ main(int argc, char **argv) { while ((c = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != EOF) { switch (c) { + case 'a': + checkflags &= ~BIND_CHECK_ALGORITHMS; + break; + case 'c': - loadplugins = false; + checkflags &= ~BIND_CHECK_PLUGINS; break; case 'd': @@ -735,7 +738,7 @@ main(int argc, char **argv) { exit(1); } - result = isccfg_check_namedconf(config, loadplugins, logc, mctx); + result = isccfg_check_namedconf(config, checkflags, logc, mctx); if (result != ISC_R_SUCCESS) { exit_status = 1; } diff --git a/bin/check/named-checkconf.rst b/bin/check/named-checkconf.rst index a15a4c64ea..41dad390fa 100644 --- a/bin/check/named-checkconf.rst +++ b/bin/check/named-checkconf.rst @@ -21,7 +21,7 @@ named-checkconf - named configuration file syntax checking tool Synopsis ~~~~~~~~ -:program:`named-checkconf` [**-chjlvz**] [**-p** [**-x** ]] [**-t** directory] {filename} +:program:`named-checkconf` [**-achjlvz**] [**-p** [**-x** ]] [**-t** directory] {filename} Description ~~~~~~~~~~~ @@ -41,6 +41,13 @@ explicitly. Options ~~~~~~~ +.. option:: -a + + Don't check the `dnssec-policy`'s DNSSEC key algorithms against + those supported by the crypto provider. This is useful when checking + a `named.conf` intended to be run on another machine with possibly a + different set of supported DNSSEC key algorithms. + .. option:: -h This option prints the usage summary and exits. diff --git a/bin/dnssec/dnssec-keygen.c b/bin/dnssec/dnssec-keygen.c index 8edd836fb1..461701fbc9 100644 --- a/bin/dnssec/dnssec-keygen.c +++ b/bin/dnssec/dnssec-keygen.c @@ -275,7 +275,7 @@ kasp_from_conf(cfg_obj_t *config, isc_mem_t *mctx, const char *name, continue; } - result = cfg_kasp_fromconfig(kconfig, NULL, mctx, lctx, + result = cfg_kasp_fromconfig(kconfig, NULL, true, mctx, lctx, &kasplist, &kasp); if (result != ISC_R_SUCCESS) { fatal("failed to configure dnssec-policy '%s': %s", diff --git a/bin/named/server.c b/bin/named/server.c index a1e5467ab9..4534cbf994 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -8366,8 +8366,8 @@ load_configuration(const char *filename, named_server_t *server, * checked later when the modules are actually loaded and * registered.) */ - result = isccfg_check_namedconf(config, false, named_g_lctx, - named_g_mctx); + result = isccfg_check_namedconf(config, BIND_CHECK_ALGORITHMS, + named_g_lctx, named_g_mctx); if (result != ISC_R_SUCCESS) { goto cleanup_config; } @@ -9034,7 +9034,7 @@ load_configuration(const char *filename, named_server_t *server, cfg_obj_t *kconfig = cfg_listelt_value(element); kasp = NULL; - result = cfg_kasp_fromconfig(kconfig, default_kasp, + result = cfg_kasp_fromconfig(kconfig, default_kasp, true, named_g_mctx, named_g_lctx, &kasplist, &kasp); if (result != ISC_R_SUCCESS) { @@ -9063,7 +9063,7 @@ load_configuration(const char *filename, named_server_t *server, { cfg_obj_t *kconfig = cfg_listelt_value(element); kasp = NULL; - result = cfg_kasp_fromconfig(kconfig, default_kasp, + result = cfg_kasp_fromconfig(kconfig, default_kasp, true, named_g_mctx, named_g_lctx, &kasplist, &kasp); if (result != ISC_R_SUCCESS) { diff --git a/lib/isccfg/check.c b/lib/isccfg/check.c index 4dc7172e26..dc7936e8db 100644 --- a/lib/isccfg/check.c +++ b/lib/isccfg/check.c @@ -1152,7 +1152,8 @@ check_port(const cfg_obj_t *options, isc_log_t *logctx, const char *type, static isc_result_t check_options(const cfg_obj_t *options, const cfg_obj_t *config, - isc_log_t *logctx, isc_mem_t *mctx, optlevel_t optlevel) { + bool check_algorithms, isc_log_t *logctx, isc_mem_t *mctx, + optlevel_t optlevel) { isc_result_t result = ISC_R_SUCCESS; isc_result_t tresult; unsigned int i; @@ -1328,9 +1329,9 @@ check_options(const cfg_obj_t *options, const cfg_obj_t *config, continue; } - ret = cfg_kasp_fromconfig(kconfig, NULL, - mctx, logctx, - &list, &kasp); + ret = cfg_kasp_fromconfig( + kconfig, NULL, check_algorithms, + mctx, logctx, &list, &kasp); if (ret != ISC_R_SUCCESS) { if (result == ISC_R_SUCCESS) { result = ret; @@ -3789,7 +3790,8 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions, /* * Check various options. */ - tresult = check_options(zoptions, config, logctx, mctx, optlevel_zone); + tresult = check_options(zoptions, config, false, logctx, mctx, + optlevel_zone); if (tresult != ISC_R_SUCCESS) { result = tresult; } @@ -5205,7 +5207,7 @@ check_dnstap(const cfg_obj_t *voptions, const cfg_obj_t *config, static isc_result_t check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, const char *viewname, dns_rdataclass_t vclass, - isc_symtab_t *files, isc_symtab_t *keydirs, bool check_plugins, + isc_symtab_t *files, isc_symtab_t *keydirs, unsigned int flags, isc_symtab_t *inview, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *zones = NULL; const cfg_obj_t *view_tkeys = NULL, *global_tkeys = NULL; @@ -5225,6 +5227,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, bool autovalidation = false; unsigned int tflags = 0, dflags = 0; int i; + bool check_plugins = (flags & BIND_CHECK_PLUGINS) != 0; + bool check_algorithms = (flags & BIND_CHECK_ALGORITHMS) != 0; /* * Get global options block @@ -5420,7 +5424,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, check_keys[1] = global_tkeys; for (i = 0; i < 2; i++) { if (check_keys[i] != NULL) { - unsigned int flags = 0; + unsigned int taflags = 0; for (element = cfg_list_first(check_keys[i]); element != NULL; element = cfg_list_next(element)) @@ -5433,14 +5437,14 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, { obj = cfg_listelt_value(element2); tresult = check_trust_anchor( - obj, false, &flags, logctx); + obj, false, &taflags, logctx); if (tresult != ISC_R_SUCCESS) { result = tresult; } } } - if ((flags & ROOT_KSK_STATIC) != 0) { + if ((taflags & ROOT_KSK_STATIC) != 0) { cfg_obj_log(check_keys[i], logctx, ISC_LOG_WARNING, "trusted-keys entry for the root " @@ -5450,7 +5454,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, "or initial-ds instead."); } - tflags |= flags; + tflags |= taflags; } } @@ -5477,7 +5481,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, check_keys[1] = global_ta; for (i = 0; i < 2; i++) { if (check_keys[i] != NULL) { - unsigned int flags = 0; + unsigned int taflags = 0; for (element = cfg_list_first(check_keys[i]); element != NULL; element = cfg_list_next(element)) @@ -5490,14 +5494,14 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, { obj = cfg_listelt_value(element2); tresult = check_trust_anchor( - obj, true, &flags, logctx); + obj, true, &taflags, logctx); if (tresult != ISC_R_SUCCESS) { result = tresult; } } } - if ((flags & ROOT_KSK_STATIC) != 0) { + if ((taflags & ROOT_KSK_STATIC) != 0) { cfg_obj_log(check_keys[i], logctx, ISC_LOG_WARNING, "static entry for the root " @@ -5507,8 +5511,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, "or initial-ds instead."); } - if ((flags & ROOT_KSK_2010) != 0 && - (flags & ROOT_KSK_2017) == 0) + if ((taflags & ROOT_KSK_2010) != 0 && + (taflags & ROOT_KSK_2017) == 0) { cfg_obj_log(check_keys[i], logctx, ISC_LOG_WARNING, @@ -5517,7 +5521,7 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, "the updated 2017 key"); } - dflags |= flags; + dflags |= taflags; } } @@ -5556,11 +5560,11 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions, * Check options. */ if (voptions != NULL) { - tresult = check_options(voptions, NULL, logctx, mctx, - optlevel_view); + tresult = check_options(voptions, NULL, check_algorithms, + logctx, mctx, optlevel_view); } else { - tresult = check_options(config, config, logctx, mctx, - optlevel_config); + tresult = check_options(config, config, check_algorithms, + logctx, mctx, optlevel_config); } if (tresult != ISC_R_SUCCESS) { result = tresult; @@ -5876,7 +5880,7 @@ check_controls(const cfg_obj_t *config, isc_log_t *logctx, isc_mem_t *mctx) { } isc_result_t -isccfg_check_namedconf(const cfg_obj_t *config, bool check_plugins, +isccfg_check_namedconf(const cfg_obj_t *config, unsigned int flags, isc_log_t *logctx, isc_mem_t *mctx) { const cfg_obj_t *options = NULL; const cfg_obj_t *views = NULL; @@ -5888,14 +5892,16 @@ isccfg_check_namedconf(const cfg_obj_t *config, bool check_plugins, isc_symtab_t *files = NULL; isc_symtab_t *keydirs = NULL; isc_symtab_t *inview = NULL; + bool check_algorithms = (flags & BIND_CHECK_ALGORITHMS) != 0; static const char *builtin[] = { "localhost", "localnets", "any", "none" }; (void)cfg_map_get(config, "options", &options); - if (options != NULL && check_options(options, config, logctx, mctx, - optlevel_options) != ISC_R_SUCCESS) + if (options != NULL && + check_options(options, config, check_algorithms, logctx, mctx, + optlevel_options) != ISC_R_SUCCESS) { result = ISC_R_FAILURE; } @@ -5966,8 +5972,8 @@ isccfg_check_namedconf(const cfg_obj_t *config, bool check_plugins, if (views == NULL) { tresult = check_viewconf(config, NULL, NULL, dns_rdataclass_in, - files, keydirs, check_plugins, inview, - logctx, mctx); + files, keydirs, flags, inview, logctx, + mctx); if (result == ISC_R_SUCCESS && tresult != ISC_R_SUCCESS) { result = ISC_R_FAILURE; } @@ -6058,8 +6064,8 @@ isccfg_check_namedconf(const cfg_obj_t *config, bool check_plugins, } if (tresult == ISC_R_SUCCESS) { tresult = check_viewconf(config, voptions, key, vclass, - files, keydirs, check_plugins, - inview, logctx, mctx); + files, keydirs, flags, inview, + logctx, mctx); } if (tresult != ISC_R_SUCCESS) { result = ISC_R_FAILURE; diff --git a/lib/isccfg/include/isccfg/check.h b/lib/isccfg/include/isccfg/check.h index b96e9f50e5..aa38a8c4b5 100644 --- a/lib/isccfg/include/isccfg/check.h +++ b/lib/isccfg/include/isccfg/check.h @@ -32,10 +32,20 @@ #define MAX_MAX_NCACHE_TTL 7 * 24 * 3600 #endif /* MAX_MAX_NCACHE_TTL */ +#define BIND_CHECK_PLUGINS 0x00000001 +/*%< + * Check the plugin configuration. + */ +#define BIND_CHECK_ALGORITHMS 0x00000002 +/*%< + * Check the dnssec-policy DNSSEC algorithms against those + * supported by the crypto provider. + */ + ISC_LANG_BEGINDECLS isc_result_t -isccfg_check_namedconf(const cfg_obj_t *config, bool check_plugins, +isccfg_check_namedconf(const cfg_obj_t *config, unsigned int flags, isc_log_t *logctx, isc_mem_t *mctx); /*%< * Check the syntactic validity of a configuration parse tree generated from diff --git a/lib/isccfg/include/isccfg/kaspconf.h b/lib/isccfg/include/isccfg/kaspconf.h index 7b1e075fef..744a327695 100644 --- a/lib/isccfg/include/isccfg/kaspconf.h +++ b/lib/isccfg/include/isccfg/kaspconf.h @@ -25,7 +25,7 @@ ISC_LANG_BEGINDECLS isc_result_t cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, - isc_mem_t *mctx, isc_log_t *logctx, + bool check_algorithms, isc_mem_t *mctx, isc_log_t *logctx, dns_kasplist_t *kasplist, dns_kasp_t **kaspp); /*%< * Create and configure a KASP. If 'default_kasp' is not NULL, the built-in @@ -34,6 +34,9 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, * already exists with the same name, no new KASP is created, and no attach to * 'kaspp' happens. * + * If 'check_algorithms' is true then the dnssec-policy DNSSEC key + * algorithms are checked against those supported by the crypto provider. + * * Requires: * *\li 'name' is either NULL, or a valid C string. diff --git a/lib/isccfg/kaspconf.c b/lib/isccfg/kaspconf.c index 2b9eeb5c15..4e384e0470 100644 --- a/lib/isccfg/kaspconf.c +++ b/lib/isccfg/kaspconf.c @@ -94,8 +94,8 @@ get_duration(const cfg_obj_t **maps, const char *option, const char *dfl) { */ static isc_result_t cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, - isc_log_t *logctx, uint32_t ksk_min_lifetime, - uint32_t zsk_min_lifetime) { + bool check_algorithms, isc_log_t *logctx, + uint32_t ksk_min_lifetime, uint32_t zsk_min_lifetime) { isc_result_t result; dns_kasp_key_t *key = NULL; @@ -171,7 +171,7 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, goto cleanup; } - if (isc_fips_mode() && + if (check_algorithms && isc_fips_mode() && (key->algorithm == DNS_KEYALG_RSASHA1 || key->algorithm == DNS_KEYALG_NSEC3RSASHA1)) { @@ -183,7 +183,9 @@ cfg_kaspkey_fromconfig(const cfg_obj_t *config, dns_kasp_t *kasp, goto cleanup; } - if (!dst_algorithm_supported(key->algorithm)) { + if (check_algorithms && + !dst_algorithm_supported(key->algorithm)) + { cfg_obj_log(obj, logctx, ISC_LOG_ERROR, "dnssec-policy: algorithm %s not supported", alg.base); @@ -351,7 +353,7 @@ add_digest(dns_kasp_t *kasp, const cfg_obj_t *digest, isc_log_t *logctx) { isc_result_t cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, - isc_mem_t *mctx, isc_log_t *logctx, + bool check_algorithms, 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]; @@ -507,9 +509,9 @@ cfg_kasp_fromconfig(const cfg_obj_t *config, dns_kasp_t *default_kasp, element = cfg_list_next(element)) { cfg_obj_t *kobj = cfg_listelt_value(element); - result = cfg_kaspkey_fromconfig(kobj, kasp, logctx, - ksk_min_lifetime, - zsk_min_lifetime); + result = cfg_kaspkey_fromconfig( + kobj, kasp, check_algorithms, logctx, + ksk_min_lifetime, zsk_min_lifetime); if (result != ISC_R_SUCCESS) { goto cleanup; }