]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3701. [func] named-checkconf can now suppress the printing of
authorMark Andrews <marka@isc.org>
Fri, 10 Jan 2014 05:56:36 +0000 (16:56 +1100)
committerMark Andrews <marka@isc.org>
Fri, 10 Jan 2014 06:45:38 +0000 (17:45 +1100)
                        shared secrets by specifying '-x'. [RT #34465]

(cherry picked from commit ff6de396a93b9b73a37173059a595f3d295b57cb)

CHANGES
bin/check/named-checkconf.c
bin/check/named-checkconf.docbook
bin/tests/system/checkconf/good.conf
bin/tests/system/checkconf/tests.sh
lib/isccfg/include/isccfg/cfg.h
lib/isccfg/include/isccfg/grammar.h
lib/isccfg/namedconf.c
lib/isccfg/parser.c
lib/isccfg/win32/libisccfg.def

diff --git a/CHANGES b/CHANGES
index be8637675da485d74a6e124f24a11be539ed8a53..a062b0ffdd2b9e7e75f484d8b98a4126d0dcc44b 100644 (file)
--- 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]
+
 3698.  [cleanup]       Replaced all uses of memcpy() with memmove().
                        [RT #35120]
 
index 52c89f0c0f23c13326fac1dd97a6e442693c8ed9..eb3e02faf6cac23fc5a3067f85ee820b7cdd40c1 100644 (file)
@@ -480,10 +480,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++;
@@ -510,6 +511,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;
@@ -532,6 +537,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)
@@ -572,7 +582,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);
index 9535e28430cfdcb5203d787e25530510159dea07..42fea7f42eef05758e2f922cf49e227351d67568 100644 (file)
@@ -60,6 +60,7 @@
       <arg><option>-t <replaceable class="parameter">directory</replaceable></option></arg>
       <arg choice="req">filename</arg>
       <arg><option>-p</option></arg>
+      <arg><option>-x</option></arg>
       <arg><option>-z</option></arg>
     </cmdsynopsis>
   </refsynopsisdiv>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term>-x</term>
+        <listitem>
+          <para>
+           When printing the configuration files in canonical
+            form, obscure shared secrets by replacing them with
+            strings of question marks ('?'). This allows the
+            contents of <filename>named.conf</filename> and related
+            files to be shared &mdash; for example, when submitting
+            bug reports &mdash; without compromising private data.
+            This option cannot be used without <option>-p</option>.
+          </para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term>-z</term>
         <listitem>
index f591aa5afdd64f5a531eead9226722382c45f20d..246e19378f33fb7c60ac00261d228cf120810405 100644 (file)
@@ -98,3 +98,7 @@ view "second" {
        dnssec-lookaside "." trust-anchor "dlv.isc.org.";
        dnssec-validation auto;
 };
+key "mykey" {
+       algorithm "hmac-md5";
+       secret "qwertyuiopasdfgh";
+};
index f626ef1da2c684b702f35ee2229454f2d4b5dc1b..1b27c6f164093209bfa7d99642364b39b53a5c3d 100644 (file)
@@ -34,17 +34,24 @@ 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 handles a known bad config"
+echo "I: checking that named-checkconf -x removes secrets"
 ret=0
-$CHECKCONF bad.conf > /dev/null 2>&1 && ret=1
-if [ $? != 1 ]; then echo "I:failed"; ret=1; fi
+# 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`
 
-echo "I: checking that named-checkconf handles a known bad tsig secret"
-ret=0
-$CHECKCONF badtsig.conf > /dev/null 2>&1
-if [ $? != 1 ]; then echo "I:failed"; ret=1; fi
-status=`expr $status + $ret`
+for bad in bad*.conf
+do
+       ret=0
+       echo "I: checking that named-checkconf detects error in $bad"
+       $CHECKCONF $bad > /dev/null 2>&1
+       if [ $? != 1 ]; then echo "I:failed"; ret=1; fi
+       status=`expr $status + $ret`
+done
 
 echo "I: checking that named-checkconf -z catches missing hint file"
 ret=0
index b21a3d86babc6f5ea1f67242285bcfe6d9cba217..3971bd75c64f6535da75f01f56fb71976944ca82 100644 (file)
@@ -380,10 +380,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
index 2d7080c24c40054ed16fb4901e3e33a35d02de8b..18d15bb95a1ebba7fce0a2613bafbcce730fcb7b 100644 (file)
@@ -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. */
@@ -266,6 +267,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_netaddr;
 LIBISCCFG_EXTERNAL_DATA extern cfg_type_t cfg_type_netaddr4;
@@ -313,6 +315,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);
 
index 92a4c406c36d81eb373033ed3ab20412d0dbcba1..6a7cfb40b6e526c227961d2bcbc0d3ff5b26ff2f 100644 (file)
@@ -1637,7 +1637,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 }
 };
 
index 9428e0284f8096b3b33ff12f90c4905d44fd9b69..1708344e06074c35688e17987b11213819b2f1d8 100644 (file)
@@ -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
  */
@@ -2480,5 +2525,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);
 }
index 98abbcf8e25f3966fd559ec36442243cff09f53d..95cdcc782b300b842d61049897d6f85a3bdc86d9 100644 (file)
@@ -42,6 +42,7 @@ cfg_parser_create
 cfg_parser_destroy
 cfg_parser_setcallback
 cfg_print
+cfg_printx
 cfg_tuple_get
 
 ; Exported Data