+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]
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++;
printf(VERSION "\n");
exit(0);
+ case 'x':
+ flags |= CFG_PRINTER_XKEY;
+ break;
+
case 'z':
load_zones = ISC_TRUE;
docheckmx = ISC_FALSE;
}
}
+ 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)
}
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);
<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 — for example, when submitting
+ bug reports — without compromising private data.
+ This option cannot be used without <option>-p</option>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term>-z</term>
<listitem>
dnssec-lookaside "." trust-anchor "dlv.isc.org.";
dnssec-validation auto;
};
+key "mykey" {
+ algorithm "hmac-md5";
+ secret "qwertyuiopasdfgh";
+};
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
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
void (*f)(void *closure, const char *text, int textlen);
void *closure;
int indent;
+ int flags;
};
/*% A clause definition. */
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;
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);
static cfg_clausedef_t
key_clauses[] = {
{ "algorithm", &cfg_type_astring, 0 },
- { "secret", &cfg_type_astring, 0 },
+ { "secret", &cfg_type_sstring, 0 },
{ NULL, NULL, 0 }
};
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
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;
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,
&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
*/
pctx.f = f;
pctx.closure = closure;
pctx.indent = 0;
+ pctx.flags = 0;
cfg_doc_obj(&pctx, type);
}
cfg_parser_destroy
cfg_parser_setcallback
cfg_print
+cfg_printx
cfg_tuple_get
; Exported Data