[exim-cvs] Support "hide" on named-list definition lines

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Support "hide" on named-list definition lines
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: