Gitweb:
https://git.exim.org/exim.git/commitdiff/8c2a478b1f6f8c3fb43317c1e6729b23a3b972b7
Commit: 8c2a478b1f6f8c3fb43317c1e6729b23a3b972b7
Parent: c8b050fd148ef06666c1f6feaa492d122f65e23e
Author: Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Jan 19 17:22:58 2020 +0000
Committer: Jeremy Harris <jgh146exb@???>
CommitDate: Mon Jan 20 16:44:49 2020 +0000
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 d65e4d9..ed00537 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 f5421a7..e214465 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 05afb24..3644ab5 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 f3fb290..631e0f2 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 ce621bb..da03933 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 4d42807..d66f928 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: