From 8c2a478b1f6f8c3fb43317c1e6729b23a3b972b7 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 19 Jan 2020 17:22:58 +0000 Subject: [PATCH] Support "hide" on named-list definition lines --- doc/doc-docbook/spec.xfpt | 13 ++++++++++++ doc/doc-txt/NewStuff | 13 +++++++----- src/src/readconf.c | 43 +++++++++++++++++++++++---------------- src/src/structs.h | 7 ++++--- test/confs/0572 | 1 + test/stdout/0572 | 2 ++ 6 files changed, 54 insertions(+), 25 deletions(-) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index d65e4d950..ed0053777 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -8300,6 +8300,19 @@ domainlist dom2 = !a.b : *.b where &'x.y'& does not match. It's best to avoid negation altogether in referenced lists if you can. +.new +.cindex "hiding named list values" +.cindex "named lists" "hiding value of" +Some named list definitions may contain sensitive data, for example, passwords for +accessing databases. To stop non-admin users from using the &%-bP%& command +line option to read these values, you can precede the definition with the +word &"hide"&. For example: +.code +hide domainlist filter_for_domains = ldap;PASS=secret ldap::/// ... +.endd +.wen + + Named lists may have a performance advantage. When Exim is routing an address or checking an incoming message, it caches the result of tests on named lists. So, if you have a setting such as diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index f5421a7f2..e21446533 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -17,16 +17,19 @@ Version 4.94 3. A msg:defer event. - 4. Client-side support in the gsasl authenticator. Tested against the plaintext - driver for PLAIN; only against itself for SCRAM-SHA-1 and SCRAM-SHA-1-PLUS - methods. + 4. Client-side support in the gsasl authenticator. Tested against the + plaintext driver for PLAIN; only against itself for SCRAM-SHA-1 and + SCRAM-SHA-1-PLUS methods. - 5. Server-side support in the gsasl authenticator for encrypted passwords, as an - alternate for the existing plaintext. + 5. Server-side support in the gsasl authenticator for encrypted passwords, as + an alternate for the existing plaintext. 6. Variable $local_part_verified, set by the router check_local_part condition with untainted data. + 7. Named-list definitions can now be prefixed "hide" so that "-bP" commands do + not output the content. Previously this could only be done on options. + Version 4.93 ------------ diff --git a/src/src/readconf.c b/src/src/readconf.c index 05afb2464..3644ab53e 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -2753,12 +2753,13 @@ if (!type) for (int i = 0; i < 4; i++) if ((t = tree_search(*(anchors[i]), name+1))) { + namedlist_block * nb = t->data.ptr; + const uschar * s = nb->hide ? hidden : nb->string; found = TRUE; if (no_labels) - printf("%s\n", ((namedlist_block *)(t->data.ptr))->string); + printf("%s\n", s); else - printf("%slist %s = %s\n", types[i], name+1, - ((namedlist_block *)(t->data.ptr))->string); + printf("%slist %s = %s\n", types[i], name+1, s); } if (!found) @@ -2979,18 +2980,19 @@ Arguments: s the text of the option line, starting immediately after the name of the list type tname the name of the list type, for messages + hide do not output value on "-bP" Returns: nothing */ static void read_named_list(tree_node **anchorp, int *numberp, int max, uschar *s, - uschar *tname) + uschar *tname, BOOL hide) { BOOL forcecache = FALSE; uschar *ss; tree_node *t; -namedlist_block *nb = store_get(sizeof(namedlist_block), FALSE); +namedlist_block * nb = store_get(sizeof(namedlist_block), FALSE); if (Ustrncmp(s, "_cache", 6) == 0) { @@ -3020,6 +3022,7 @@ if (!tree_insertnode(anchorp, t)) t->data.ptr = nb; nb->number = *numberp; *numberp += 1; +nb->hide = hide; if (*s++ != '=') log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "missing '=' after \"%s\"", t->name); @@ -3278,28 +3281,36 @@ a macro definition. */ while ((s = get_config_line())) { + BOOL hide; + uschar * t; + if (config_lineno == 1 && Ustrstr(s, "\xef\xbb\xbf") == s) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "found unexpected BOM (Byte Order Mark)"); - if (isupper(s[0])) - { if (!macro_read_assignment(s)) exim_exit(EXIT_FAILURE, US""); } + if (isupper(*s)) + { + if (!macro_read_assignment(s)) exim_exit(EXIT_FAILURE, US""); + continue; + } + + t = (hide = Ustrncmp(s, "hide", 4) == 0 && isspace(s[4])) ? s + 5 : s; - else if (Ustrncmp(s, "domainlist", 10) == 0) + if (Ustrncmp(t, "domainlist", 10) == 0) read_named_list(&domainlist_anchor, &domainlist_count, - MAX_NAMED_LIST, s+10, US"domain list"); + MAX_NAMED_LIST, t+10, US"domain list", hide); - else if (Ustrncmp(s, "hostlist", 8) == 0) + else if (Ustrncmp(t, "hostlist", 8) == 0) read_named_list(&hostlist_anchor, &hostlist_count, - MAX_NAMED_LIST, s+8, US"host list"); + MAX_NAMED_LIST, t+8, US"host list", hide); - else if (Ustrncmp(s, US"addresslist", 11) == 0) + else if (Ustrncmp(t, US"addresslist", 11) == 0) read_named_list(&addresslist_anchor, &addresslist_count, - MAX_NAMED_LIST, s+11, US"address list"); + MAX_NAMED_LIST, t+11, US"address list", hide); - else if (Ustrncmp(s, US"localpartlist", 13) == 0) + else if (Ustrncmp(t, US"localpartlist", 13) == 0) read_named_list(&localpartlist_anchor, &localpartlist_count, - MAX_NAMED_LIST, s+13, US"local part list"); + MAX_NAMED_LIST, t+13, US"local part list", hide); else (void) readconf_handle_option(s, optionlist_config, optionlist_config_size, @@ -4275,10 +4286,8 @@ log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "local_scan() options not supported: " uschar *p; while ((p = get_config_line())) - { (void) readconf_handle_option(p, local_scan_options, local_scan_options_count, NULL, US"local_scan option \"%s\" unknown"); - } #endif } diff --git a/src/src/structs.h b/src/src/structs.h index f3fb290c6..631e0f263 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -886,9 +886,10 @@ typedef struct namedlist_cacheblock { /* Structure for holding data for an entry in a named list */ typedef struct namedlist_block { - const uschar *string; /* the list string */ - namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ - int number; /* the number of the list for caching */ + const uschar *string; /* the list string */ + namedlist_cacheblock *cache_data; /* cached domain_data or localpart_data */ + int number:31; /* the number of the list for caching */ + BOOL hide:1; /* -bP does not display value */ } namedlist_block; /* Structures for Access Control Lists */ diff --git a/test/confs/0572 b/test/confs/0572 index ce621bb31..da03933e4 100644 --- a/test/confs/0572 +++ b/test/confs/0572 @@ -11,6 +11,7 @@ primary_hostname = myhost.test.ex log_selector = +outgoing_port domainlist local_domains = test.ex : *.test.ex +hide domainlist hidden_domains = test.ex : *.test.ex acl_smtp_rcpt = accept diff --git a/test/stdout/0572 b/test/stdout/0572 index 4d428078f..d66f928d4 100644 --- a/test/stdout/0572 +++ b/test/stdout/0572 @@ -93,6 +93,7 @@ chunking_advertise_hosts = primary_hostname = myhost.test.ex log_selector = +outgoing_port domainlist local_domains = test.ex : *.test.ex +hide domainlist hidden_domains = test.ex : *.test.ex acl_smtp_rcpt = accept begin routers @@ -135,6 +136,7 @@ chunking_advertise_hosts = primary_hostname = myhost.test.ex log_selector = +outgoing_port domainlist local_domains = test.ex : *.test.ex +hide domainlist hidden_domains = test.ex : *.test.ex acl_smtp_rcpt = accept begin routers my_main_router: -- 2.30.2