diff --git a/CHANGES b/CHANGES index 62deca9857..e9b8717d13 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +3701. [func] named-checkconf can now suppress the printing of + shared secrets by specifying '-x'. [RT #34465] + 3700. [func] Allow access to subgroups of XML statistics via special URLs http://:/xml/v3/server, /zones, /net, /tasks, /mem, and /status. [RT #35115] diff --git a/bin/check/named-checkconf.c b/bin/check/named-checkconf.c index 6f52a6629c..9c4e6ee5a8 100644 --- a/bin/check/named-checkconf.c +++ b/bin/check/named-checkconf.c @@ -482,10 +482,11 @@ main(int argc, char **argv) { isc_entropy_t *ectx = NULL; isc_boolean_t load_zones = ISC_FALSE; isc_boolean_t print = ISC_FALSE; + unsigned int flags = 0; isc_commandline_errprint = ISC_FALSE; - while ((c = isc_commandline_parse(argc, argv, "dhjt:pvz")) != EOF) { + while ((c = isc_commandline_parse(argc, argv, "dhjt:pvxz")) != EOF) { switch (c) { case 'd': debug++; @@ -512,6 +513,10 @@ main(int argc, char **argv) { printf(VERSION "\n"); exit(0); + case 'x': + flags |= CFG_PRINTER_XKEY; + break; + case 'z': load_zones = ISC_TRUE; docheckmx = ISC_FALSE; @@ -534,6 +539,11 @@ main(int argc, char **argv) { } } + if (((flags & CFG_PRINTER_XKEY) != 0) && !print) { + fprintf(stderr, "%s: -x cannot be used without -p\n", program); + exit(1); + } + if (isc_commandline_index + 1 < argc) usage(); if (argv[isc_commandline_index] != NULL) @@ -574,7 +584,7 @@ main(int argc, char **argv) { } if (print && exit_status == 0) - cfg_print(config, output, NULL); + cfg_printx(config, flags, output, NULL); cfg_obj_destroy(parser, &config); cfg_parser_destroy(&parser); diff --git a/bin/check/named-checkconf.docbook b/bin/check/named-checkconf.docbook index 9535e28430..42fea7f42e 100644 --- a/bin/check/named-checkconf.docbook +++ b/bin/check/named-checkconf.docbook @@ -60,6 +60,7 @@ filename + @@ -129,6 +130,21 @@ + + -x + + + When printing the configuration files in canonical + form, obscure shared secrets by replacing them with + strings of question marks ('?'). This allows the + contents of named.conf and related + files to be shared — for example, when submitting + bug reports — without compromising private data. + This option cannot be used without . + + + + -z diff --git a/bin/tests/system/checkconf/good.conf b/bin/tests/system/checkconf/good.conf index f30798713f..948dceb34a 100644 --- a/bin/tests/system/checkconf/good.conf +++ b/bin/tests/system/checkconf/good.conf @@ -126,3 +126,7 @@ view "third" { }; }; }; +key "mykey" { + algorithm "hmac-md5"; + secret "qwertyuiopasdfgh"; +}; diff --git a/bin/tests/system/checkconf/tests.sh b/bin/tests/system/checkconf/tests.sh index 5f59881134..39cfb1da29 100644 --- a/bin/tests/system/checkconf/tests.sh +++ b/bin/tests/system/checkconf/tests.sh @@ -34,6 +34,16 @@ cmp good.conf.in good.conf.out || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I: checking that named-checkconf -x removes secrets" +ret=0 +# ensure there is a secret and that it is not the check string. +grep 'secret "' good.conf.in > /dev/null || ret=1 +grep 'secret "????????????????"' good.conf.in > /dev/null 2>&1 && ret=1 +$CHECKCONF -p -x good.conf.in | grep -v '^good.conf.in:' > good.conf.out 2>&1 || ret=1 +grep 'secret "????????????????"' good.conf.out > /dev/null 2>&1 || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + for bad in bad*.conf do ret=0 diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h index 567bd30e04..fe15e44ba5 100644 --- a/lib/isccfg/include/isccfg/cfg.h +++ b/lib/isccfg/include/isccfg/cfg.h @@ -406,10 +406,20 @@ void cfg_print(const cfg_obj_t *obj, void (*f)(void *closure, const char *text, int textlen), void *closure); +void +cfg_printx(const cfg_obj_t *obj, unsigned int flags, + void (*f)(void *closure, const char *text, int textlen), + void *closure); + +#define CFG_PRINTER_XKEY 0x1 /* '?' out shared keys. */ + /*%< * Print the configuration object 'obj' by repeatedly calling the * function 'f', passing 'closure' and a region of text starting * at 'text' and comprising 'textlen' characters. + * + * If CFG_PRINTER_XKEY the contents of shared keys will be obscured + * by replacing them with question marks ('?') */ void diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index f4ad604236..0784ada04b 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -86,6 +86,7 @@ struct cfg_printer { void (*f)(void *closure, const char *text, int textlen); void *closure; int indent; + int flags; }; /*% A clause definition. */ @@ -271,6 +272,7 @@ LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_uint64; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_qstring; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_astring; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_ustring; +LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sstring; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddr; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_sockaddrdscp; LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr; @@ -319,6 +321,9 @@ cfg_print_ustring(cfg_printer_t *pctx, const cfg_obj_t *obj); isc_result_t cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); +isc_result_t +cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret); + isc_result_t cfg_parse_rawaddr(cfg_parser_t *pctx, unsigned int flags, isc_netaddr_t *na); diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 6fb13699fc..225cdf0137 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1773,7 +1773,7 @@ static cfg_type_t cfg_type_dynamically_loadable_zones_opts = { static cfg_clausedef_t key_clauses[] = { { "algorithm", &cfg_type_astring, 0 }, - { "secret", &cfg_type_astring, 0 }, + { "secret", &cfg_type_sstring, 0 }, { NULL, NULL, 0 } }; diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 49496bc4c7..145205202e 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -182,15 +182,23 @@ void cfg_print(const cfg_obj_t *obj, void (*f)(void *closure, const char *text, int textlen), void *closure) +{ + cfg_printx(obj, 0, f, closure); +} + +void +cfg_printx(const cfg_obj_t *obj, unsigned int flags, + void (*f)(void *closure, const char *text, int textlen), + void *closure) { cfg_printer_t pctx; pctx.f = f; pctx.closure = closure; pctx.indent = 0; + pctx.flags = flags; obj->type->print(&pctx, obj); } - /* Tuples. */ isc_result_t @@ -762,6 +770,22 @@ cfg_parse_astring(cfg_parser_t *pctx, const cfg_type_t *type, return (result); } +isc_result_t +cfg_parse_sstring(cfg_parser_t *pctx, const cfg_type_t *type, + cfg_obj_t **ret) +{ + isc_result_t result; + UNUSED(type); + + CHECK(cfg_getstringtoken(pctx)); + return (create_string(pctx, + TOKEN_STRING(pctx), + &cfg_type_sstring, + ret)); + cleanup: + return (result); +} + isc_boolean_t cfg_is_enum(const char *s, const char *const *enums) { const char * const *p; @@ -818,6 +842,18 @@ print_qstring(cfg_printer_t *pctx, const cfg_obj_t *obj) { cfg_print_chars(pctx, "\"", 1); } +static void +print_sstring(cfg_printer_t *pctx, const cfg_obj_t *obj) { + cfg_print_chars(pctx, "\"", 1); + if ((pctx->flags & CFG_PRINTER_XKEY) != 0) { + unsigned int len = obj->value.string.length; + while (len-- > 0) + cfg_print_chars(pctx, "?", 1); + } else + cfg_print_ustring(pctx, obj); + cfg_print_chars(pctx, "\"", 1); +} + static void free_string(cfg_parser_t *pctx, cfg_obj_t *obj) { isc_mem_put(pctx->mctx, obj->value.string.base, @@ -854,6 +890,15 @@ cfg_type_t cfg_type_astring = { &cfg_rep_string, NULL }; +/* + * Any string (quoted or unquoted); printed with quotes. + * If CFG_PRINTER_XKEY is set when printing the string will be '?' out. + */ +cfg_type_t cfg_type_sstring = { + "string", cfg_parse_sstring, print_sstring, cfg_doc_terminal, + &cfg_rep_string, NULL +}; + /* * Booleans */ @@ -2555,5 +2600,6 @@ cfg_print_grammar(const cfg_type_t *type, pctx.f = f; pctx.closure = closure; pctx.indent = 0; + pctx.flags = 0; cfg_doc_obj(&pctx, type); } diff --git a/lib/isccfg/win32/libisccfg.def b/lib/isccfg/win32/libisccfg.def index c9b9a9127f..7367d3d0dd 100644 --- a/lib/isccfg/win32/libisccfg.def +++ b/lib/isccfg/win32/libisccfg.def @@ -44,6 +44,7 @@ cfg_parser_create cfg_parser_destroy cfg_parser_setcallback cfg_print +cfg_printx cfg_tuple_get ; Exported Data