]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Allow named-checkconf to selectively check dnssec-policy algorithms
authorMark Andrews <marka@isc.org>
Thu, 25 Aug 2022 06:47:34 +0000 (16:47 +1000)
committerMark Andrews <marka@isc.org>
Mon, 3 Apr 2023 02:15:57 +0000 (12:15 +1000)
There are times where you want named-checkconf to check whether the
dnssec-policies should be constrained by the cryptographic algorithms
supported by the operation system or to just accept all possible
algorithms.  This provides a mechanism to make that selection.

bin/check/named-checkconf.c
bin/check/named-checkconf.rst
bin/dnssec/dnssec-keygen.c
bin/named/server.c
lib/isccfg/check.c
lib/isccfg/include/isccfg/check.h
lib/isccfg/include/isccfg/kaspconf.h
lib/isccfg/kaspconf.c

index 42efae4ddbeeb9721cc5c907e497c0ae524a2844..f7c165ea612b132ad5b9679db134f5e19cdd2a20 100644 (file)
@@ -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;
        }
index a15a4c64ea837c30f38ff036617b8dfd44559ba7..41dad390fadd03a3b74c1a19d93319ca419227b7 100644 (file)
@@ -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.
index 8edd836fb1fca98ac88ad2c47cb3cfc925998655..461701fbc9cf343f6410e8d7ad0258a0df678871 100644 (file)
@@ -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",
index a1e5467ab9f931874aafe8eb1fc95b5c76d08c9d..4534cbf994aaaea2297d77c79d8b3e40b71b1606 100644 (file)
@@ -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) {
index 4dc7172e266fa5abd00c4f267eb16401336fef4a..dc7936e8db032d852863d04ea01189772b017f26 100644 (file)
@@ -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;
index b96e9f50e50d947a4247e59fdd75ad1b7b2f0c4b..aa38a8c4b5710eba60eebcc226ed501f3edb31a0 100644 (file)
 #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
index 7b1e075fefb4faa04484c10927ed817034ed8c29..744a3276955eedf894eb93b093f2e752efcffec3 100644 (file)
@@ -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.
index 2b9eeb5c153e90c819fda492554bf28e30807eb4..4e384e0470f4a3e698870190ca79bbdb1df00cef 100644 (file)
@@ -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;
                        }