Support "hide" on named-list definition lines
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 19 Jan 2020 17:22:58 +0000 (17:22 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Mon, 20 Jan 2020 16:44:49 +0000 (16:44 +0000)
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/readconf.c
src/src/structs.h
test/confs/0572
test/stdout/0572

index d65e4d9507da30e07187139084485f69e24de39d..ed00537775249c74760fd5f22747073dd6995ad9 100644 (file)
@@ -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
index f5421a7f2ac2de08bba9b82228a046f19db7bf7f..e21446533bae5d18439600f531d1588a0429b076 100644 (file)
@@ -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
 ------------
index 05afb246438d637cf3d2eeef21e72621d59811ce..3644ab53e5d116e9d3e94b8d451e3b85968f2a53 100644 (file)
@@ -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
 }
 
index f3fb290c6d1cec6c966b5d6bfbef0a350b01dce4..631e0f263a37c5e9848b88608251a160c913b75a 100644 (file)
@@ -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 */
index ce621bb31053e4ed7203a9d2c99f110cfd838292..da03933e485fee766181e342a85f83708bc49930 100644 (file)
@@ -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
 
 
index 4d428078f3cc70ede0514e057cfdac98c1079ca8..d66f928d42dfb8f77af7970aa043772ca4f49a5d 100644 (file)
@@ -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: