From f9a3fcddba223133019368e7cd6d51449fc54e7b Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Thu, 1 Apr 2021 22:44:31 +0200 Subject: Introduce main config option allow_insecure_tainted_data This option is deprecated already now. (cherry picked from commit ec06d64532e4952fc36429f73e0222d26997ef7c) --- src/src/EDITME | 7 ++++++ src/src/config.h.defaults | 2 ++ src/src/functions.h | 54 ++++++++++++++++++++++++++++++++++++----------- src/src/globals.c | 10 +++++++++ src/src/globals.h | 4 ++++ src/src/macros.h | 3 +++ src/src/readconf.c | 3 +++ 7 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/src/EDITME b/src/src/EDITME index 8cd34e8be..f4329fabf 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -748,6 +748,13 @@ FIXED_NEVER_USERS=root # WHITELIST_D_MACROS=TLS:SPOOL +# The next setting enables a main config option +# "allow_insecure_tainted_data" to turn taint failures into warnings. +# Though this option is new, it is deprecated already now, and will be +# ignored in future releases of Exim. It is meant as mitigation for +# upgrading old (possibly insecure) configurations to more secure ones. +ALLOW_INSECURE_TAINTED_DATA=yes + #------------------------------------------------------------------------------ # Exim has support for the AUTH (authentication) extension of the SMTP # protocol, as defined by RFC 2554. If you don't know what SMTP authentication diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index e233fb3e5..877cc7bc4 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -17,6 +17,8 @@ Do not put spaces between # and the 'define'. #define ALT_CONFIG_PREFIX #define TRUSTED_CONFIG_LIST +#define ALLOW_INSECURE_TAINTED_DATA + #define APPENDFILE_MODE 0600 #define APPENDFILE_DIRECTORY_MODE 0700 #define APPENDFILE_LOCKFILE_MODE 0600 diff --git a/src/src/functions.h b/src/src/functions.h index 4212c3328..27c298cfa 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -1125,20 +1125,50 @@ if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec); /******************************************************************************/ /* Taint-checked file opens */ +static inline uschar * +is_tainted2(const void *p, int lflags, const uschar* fmt, ...) +{ +va_list ap; +uschar *msg; +rmark mark; + +if (!is_tainted(p)) + return NULL; + +mark = store_mark(); +va_start(ap, fmt); +msg = string_from_gstring(string_vformat(NULL, SVFMT_TAINT_NOCHK|SVFMT_EXTEND, fmt, ap)); +va_end(ap); + +#ifdef ALLOW_INSECURE_TAINTED_DATA +if (allow_insecure_tainted_data) + { + if LOGGING(tainted) log_write(0, LOG_MAIN, "Warning: %s", msg); + store_reset(mark); + return NULL; + } +#endif + +if (lflags) log_write(0, lflags, "%s", msg); +return msg; /* no store_reset(), as the message might be used afterwards and Exim + is expected to exit anyway, so we do not care about the leaked + storage */ +} static inline int exim_open2(const char *pathname, int flags) { -if (!is_tainted(pathname)) return open(pathname, flags); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return open(pathname, flags); errno = EACCES; return -1; } + static inline int exim_open(const char *pathname, int flags, mode_t mode) { -if (!is_tainted(pathname)) return open(pathname, flags, mode); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return open(pathname, flags, mode); errno = EACCES; return -1; } @@ -1146,16 +1176,16 @@ return -1; static inline int exim_openat(int dirfd, const char *pathname, int flags) { -if (!is_tainted(pathname)) return openat(dirfd, pathname, flags); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return openat(dirfd, pathname, flags); errno = EACCES; return -1; } static inline int exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode) { -if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return openat(dirfd, pathname, flags, mode); errno = EACCES; return -1; } @@ -1164,8 +1194,8 @@ return -1; static inline FILE * exim_fopen(const char *pathname, const char *mode) { -if (!is_tainted(pathname)) return fopen(pathname, mode); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname); +if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname)) + return fopen(pathname, mode); errno = EACCES; return NULL; } @@ -1173,8 +1203,8 @@ return NULL; static inline DIR * exim_opendir(const uschar * name) { -if (!is_tainted(name)) return opendir(CCS name); -log_write(0, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name); +if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name)) + return opendir(CCS name); errno = EACCES; return NULL; } diff --git a/src/src/globals.c b/src/src/globals.c index e96586048..9e68aaca8 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -98,6 +98,10 @@ int sqlite_lock_timeout = 5; BOOL move_frozen_messages = FALSE; #endif +#ifdef ALLOW_INSECURE_TAINTED_DATA +BOOL allow_insecure_tainted_data = FALSE; +#endif + /* These variables are outside the #ifdef because it keeps the code less cluttered in several places (e.g. during logging) if we can always refer to them. Also, the tls_ variables are now always visible. Note that these are @@ -1055,6 +1059,9 @@ int log_default[] = { /* for initializing log_selector */ Li_size_reject, Li_skip_delivery, Li_smtp_confirmation, +#ifdef ALLOW_INSECURE_TAINTED_DATA + Li_tainted, +#endif Li_tls_certificate_verified, Li_tls_cipher, -1 @@ -1124,6 +1131,9 @@ bit_table log_options[] = { /* must be in alphabetical order, BIT_TABLE(L, smtp_protocol_error), BIT_TABLE(L, smtp_syntax_error), BIT_TABLE(L, subject), +#ifdef ALLOW_INSECURE_TAINTED_DATA + BIT_TABLE(L, tainted), +#endif BIT_TABLE(L, tls_certificate_verified), BIT_TABLE(L, tls_cipher), BIT_TABLE(L, tls_peerdn), diff --git a/src/src/globals.h b/src/src/globals.h index 937cce776..657e6c706 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -77,6 +77,10 @@ extern int sqlite_lock_timeout; /* Internal lock waiting timeout */ extern BOOL move_frozen_messages; /* Get them out of the normal directory */ #endif +#ifdef ALLOW_INSECURE_TAINTED_DATA +extern BOOL allow_insecure_tainted_data; +#endif + /* These variables are outside the #ifdef because it keeps the code less cluttered in several places (e.g. during logging) if we can always refer to them. Also, the tls_ variables are now always visible. */ diff --git a/src/src/macros.h b/src/src/macros.h index f8987d604..ccdcc451f 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -491,6 +491,9 @@ enum logbit { Li_smtp_mailauth, Li_smtp_no_mail, Li_subject, +#ifdef ALLOW_INSECURE_TAINTED_DATA + Li_tainted, +#endif Li_tls_certificate_verified, Li_tls_cipher, Li_tls_peerdn, diff --git a/src/src/readconf.c b/src/src/readconf.c index ae36fa0c5..34ebf8769 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -68,6 +68,9 @@ static optionlist optionlist_config[] = { { "add_environment", opt_stringptr, {&add_environment} }, { "admin_groups", opt_gidlist, {&admin_groups} }, { "allow_domain_literals", opt_bool, {&allow_domain_literals} }, +#ifdef ALLOW_INSECURE_TAINTED_DATA + { "allow_insecure_tainted_data", opt_bool, {&allow_insecure_tainted_data} }, +#endif { "allow_mx_to_ip", opt_bool, {&allow_mx_to_ip} }, { "allow_utf8_domains", opt_bool, {&allow_utf8_domains} }, { "auth_advertise_hosts", opt_stringptr, {&auth_advertise_hosts} }, -- cgit v1.2.3 From 8fc13e4adcdf5d0cec382c401ce72592569084fe Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Thu, 1 Apr 2021 22:45:03 +0200 Subject: search (cherry picked from commit b71d675f695c2cf17357b190476129535d5f446c) --- src/src/search.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/src/search.c b/src/src/search.c index 421d9c789..81d1d20f9 100644 --- a/src/src/search.c +++ b/src/src/search.c @@ -392,12 +392,8 @@ lookup_info *lk = lookup_list[search_type]; uschar keybuffer[256]; int old_pool = store_pool; -if (filename && is_tainted(filename)) - { - log_write(0, LOG_MAIN|LOG_PANIC, - "Tainted filename for search: '%s'", filename); +if (filename && is_tainted2(filename, LOG_MAIN|LOG_PANIC, "Tainted filename for search: '%s'", filename)) return NULL; - } /* Change to the search store pool and remember our reset point */ @@ -714,7 +710,7 @@ if (opts) /* Arrange to put this database at the top of the LRU chain if it is a type that opens real files. */ -if ( open_top != (tree_node *)handle +if ( open_top != (tree_node *)handle && lookup_list[t->name[0]-'0']->type == lookup_absfile) { search_cache *c = (search_cache *)(t->data.ptr); -- cgit v1.2.3 From 2382cd3e81838709abd3b0c1b410f65274d90e25 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 28 Mar 2021 10:49:49 +0200 Subject: dbstuff (cherry picked from commit 35b11dd0e52b5ac176849f807cca8898bcaf0c3d) --- src/src/dbstuff.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/src/dbstuff.h b/src/src/dbstuff.h index 8a8a5fb67..2f00dffb4 100644 --- a/src/src/dbstuff.h +++ b/src/src/dbstuff.h @@ -640,11 +640,9 @@ after reading data. */ : (flags) == O_RDWR ? "O_RDWR" \ : (flags) == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT" \ : "??"); \ - if (is_tainted(name) || is_tainted(dirname)) \ - { \ - log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted"); \ + if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB file not permitted", name) \ + || is_tainted2(dirname, LOG_MAIN|LOG_PANIC, "Tainted name '%s' for DB directory not permitted", dirname)) \ *dbpp = NULL; \ - } \ else \ { EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); } \ DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", *dbpp); \ -- cgit v1.2.3 From ace68726852d08deec815a37f369a4e31be77813 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 28 Mar 2021 10:50:14 +0200 Subject: acl (cherry picked from commit 44fd80ad8abcd885fc1c8dbb294fc2140e4ef481) --- src/src/acl.c | 45 +++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/src/acl.c b/src/src/acl.c index f358516a1..56d7468c1 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -3702,20 +3702,22 @@ for (; cb; cb = cb->next) #endif case ACLC_QUEUE: - if (is_tainted(arg)) { - *log_msgptr = string_sprintf("Tainted name '%s' for queue not permitted", - arg); - return ERROR; - } - if (Ustrchr(arg, '/')) - { - *log_msgptr = string_sprintf( - "Directory separator not permitted in queue name: '%s'", arg); - return ERROR; + uschar *m; + if (m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg)) + { + *log_msgptr = m; + return ERROR; + } + if (Ustrchr(arg, '/')) + { + *log_msgptr = string_sprintf( + "Directory separator not permitted in queue name: '%s'", arg); + return ERROR; + } + queue_name = string_copy_perm(arg, FALSE); + break; } - queue_name = string_copy_perm(arg, FALSE); - break; case ACLC_RATELIMIT: rc = acl_ratelimit(arg, where, log_msgptr); @@ -4088,25 +4090,14 @@ while (isspace(*ss)) ss++; acl_text = ss; -#ifdef notyet_taintwarn if ( !f.running_in_test_harness && is_tainted2(acl_text, LOG_MAIN|LOG_PANIC, - "attempt to use tainted ACL text \"%s\"", acl_text)) + "Tainted ACL text \"%s\"", acl_text)) { /* Avoid leaking info to an attacker */ *log_msgptr = US"internal configuration error"; return ERROR; } -#else -if (is_tainted(acl_text) && !f.running_in_test_harness) - { - log_write(0, LOG_MAIN|LOG_PANIC, - "attempt to use tainted ACL text \"%s\"", acl_text); - /* Avoid leaking info to an attacker */ - *log_msgptr = US"internal configuration error"; - return ERROR; - } -#endif /* Handle the case of a string that does not contain any spaces. Look for a named ACL among those read from the configuration, or a previously read file. @@ -4131,6 +4122,12 @@ if (Ustrchr(ss, ' ') == NULL) else if (*ss == '/') { struct stat statbuf; + if (is_tainted2(ss, LOG_MAIN|LOG_PANIC, "Tainted ACL file name '%s'", ss)) + { + /* Avoid leaking info to an attacker */ + *log_msgptr = US"internal configuration error"; + return ERROR; + } if ((fd = Uopen(ss, O_RDONLY, 0)) < 0) { *log_msgptr = string_sprintf("failed to open ACL file \"%s\": %s", ss, -- cgit v1.2.3 From 4a2bd5dc2f157c50b7e4e7491eac1c930efd2100 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 28 Mar 2021 10:58:46 +0200 Subject: parse (cherry picked from commit 7eeeb6f26af05322814ecc77c87f09c72ab2216a) --- src/src/parse.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/src/parse.c b/src/src/parse.c index fa3395206..e70dabd58 100644 --- a/src/src/parse.c +++ b/src/src/parse.c @@ -1415,12 +1415,8 @@ for (;;) return FF_ERROR; } - if (is_tainted(filename)) - { - *error = string_sprintf("Tainted name '%s' for included file not permitted\n", - filename); + if (*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)) return FF_ERROR; - } /* Check file name if required */ -- cgit v1.2.3 From e8b8b133c685e7b09f672016d117c7d8b49e70b1 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 28 Mar 2021 10:59:46 +0200 Subject: rda (cherry picked from commit a6da9c67acaee699616516be141d600cc178a633) --- src/src/rda.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/src/rda.c b/src/src/rda.c index fb3714ea2..3b458430a 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -179,10 +179,8 @@ struct stat statbuf; /* Reading a file is a form of expansion; we wish to deny attackers the capability to specify the file name. */ -if (is_tainted(filename)) +if (*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename)) { - *error = string_sprintf("Tainted name '%s' for file read not permitted\n", - filename); *yield = FF_ERROR; return NULL; } -- cgit v1.2.3 From f7509ba6fb5e1033c1406b87f057c9c48a217d27 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 28 Mar 2021 11:06:27 +0200 Subject: autoreply (cherry picked from commit 26de37d8960da80473866fb59b9dfd10a5761538) --- src/src/transports/autoreply.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 865abbf4f..ed99de4c6 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -404,14 +404,15 @@ recipient cache. */ if (oncelog && *oncelog && to) { + uschar *m; time_t then = 0; - if (is_tainted(oncelog)) + if (m = is_tainted2(oncelog, 0, "Tainted '%s' (once file for %s transport)" + " not permitted", oncelog, tblock->name)) { addr->transport_return = DEFER; addr->basic_errno = EACCES; - addr->message = string_sprintf("Tainted '%s' (once file for %s transport)" - " not permitted", oncelog, tblock->name); + addr->message = m; goto END_OFF; } @@ -515,13 +516,14 @@ if (oncelog && *oncelog && to) if (then != 0 && (once_repeat_sec <= 0 || now - then < once_repeat_sec)) { + uschar *m; int log_fd; - if (is_tainted(logfile)) + if (m = is_tainted2(logfile, 0, "Tainted '%s' (logfile for %s transport)" + " not permitted", logfile, tblock->name)) { addr->transport_return = DEFER; addr->basic_errno = EACCES; - addr->message = string_sprintf("Tainted '%s' (logfile for %s transport)" - " not permitted", logfile, tblock->name); + addr->message = m; goto END_OFF; } @@ -548,12 +550,13 @@ if (oncelog && *oncelog && to) /* We are going to send a message. Ensure any requested file is available. */ if (file) { - if (is_tainted(file)) + uschar *m; + if (m = is_tainted2(file, 0, "Tainted '%s' (file for %s transport)" + " not permitted", file, tblock->name)) { addr->transport_return = DEFER; addr->basic_errno = EACCES; - addr->message = string_sprintf("Tainted '%s' (file for %s transport)" - " not permitted", file, tblock->name); + addr->message = m; return FALSE; } if (!(ff = Ufopen(file, "rb")) && !ob->file_optional) -- cgit v1.2.3 From dbac5a049acbe645a816b4a5e895c5be0de53483 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Fri, 2 Apr 2021 17:30:27 +0200 Subject: pipe (cherry picked from commit f9628406706112be459adb3f121db8e6cf282c2d) --- src/src/transports/pipe.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 1cb574ee7..929681422 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -592,13 +592,16 @@ if (!cmd || !*cmd) tblock->name); return FALSE; } -if (is_tainted(cmd)) + +{ uschar *m; +if (m = is_tainted2(cmd, 0, "Tainted '%s' (command " + "for %s transport) not permitted", cmd, tblock->name)) { - addr->message = string_sprintf("Tainted '%s' (command " - "for %s transport) not permitted", cmd, tblock->name); addr->transport_return = PANIC; + addr->message = m; return FALSE; } +} /* When a pipe is set up by a filter file, there may be values for $thisaddress and numerical the variables in existence. These are passed in -- cgit v1.2.3 From f7da81e789e2f20b00f46f07260488f337984b84 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Wed, 31 Mar 2021 23:12:44 +0200 Subject: deliver (cherry picked from commit 2fee91ae42e974c21202e0b5e17185f6a87bf8af) --- src/src/deliver.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/src/deliver.c b/src/src/deliver.c index 4e472ebe6..a6f68825c 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -5550,10 +5550,11 @@ FILE * fp = NULL; if (!s || !*s) log_write(0, LOG_MAIN|LOG_PANIC, "Failed to expand %s: '%s'\n", varname, filename); -else if (*s != '/' || is_tainted(s)) - log_write(0, LOG_MAIN|LOG_PANIC, - "%s is not %s after expansion: '%s'\n", - varname, *s == '/' ? "untainted" : "absolute", s); +else if (*s != '/') + log_write(0, LOG_MAIN|LOG_PANIC, "%s is not absolute after expansion: '%s'\n", + varname, s); +else if (is_tainted2(s, LOG_MAIN|LOG_PANIC, "Tainted %s after expansion: '%s'\n", varname, s)) + ; else if (!(fp = Ufopen(s, "rb"))) log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for %s " "message texts: %s", s, reason, strerror(errno)); @@ -6160,12 +6161,13 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) { uschar *tmp = expand_string(tpname); address_file = address_pipe = NULL; + uschar *m; if (!tmp) p->message = string_sprintf("failed to expand \"%s\" as a " "system filter transport name", tpname); - if (is_tainted(tmp)) - p->message = string_sprintf("attempt to used tainted value '%s' for" - "transport '%s' as a system filter", tmp, tpname); + if (is_tainted2(tmp, 0, m = string_sprintf("Tainted values '%s' " + "for transport '%s' as a system filter", tmp, tpname))) + p->message = m; tpname = tmp; } else -- cgit v1.2.3 From f7c791b769a3a5395d92d29d27aa58f9d442373c Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Thu, 1 Apr 2021 21:28:59 +0200 Subject: directory (cherry picked from commit 5f41e800ce9cc7ad154047298914df955e905bf4) --- src/src/directory.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/src/directory.c b/src/src/directory.c index f54a781b7..3273eb89b 100644 --- a/src/src/directory.c +++ b/src/src/directory.c @@ -44,8 +44,8 @@ uschar c = 1; struct stat statbuf; uschar * path; -if (is_tainted(name)) - { p = US"create"; path = US name; errno = ERRNO_TAINT; goto bad; } +if (is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted path '%s' for new directory", name)) + { p = US"create"; path = US name; errno = EACCES; goto bad; } if (parent) { -- cgit v1.2.3 From 0fa46a83a55054c65ffc539405f62bf86aac5b44 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Thu, 1 Apr 2021 21:33:50 +0200 Subject: expand (cherry picked from commit c02ea85f525ff256d78e084d6f76fe3032fd52e1) --- src/src/expand.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/src/expand.c b/src/src/expand.c index 989e97b84..0ae2aea92 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -4483,13 +4483,13 @@ DEBUG(D_expand) f.expand_string_forcedfail = FALSE; expand_string_message = US""; -if (is_tainted(string)) +{ uschar *m; +if (m = is_tainted2(string, LOG_MAIN|LOG_PANIC, "Tainted string '%s' in expansion", s)) { - expand_string_message = - string_sprintf("attempt to expand tainted string '%s'", s); - log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message); + expand_string_message = m; goto EXPAND_FAILED; } +} while (*s) { -- cgit v1.2.3 From ec7e44dc9134307d74afa4b07f09afbdd019282c Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Thu, 1 Apr 2021 21:36:12 +0200 Subject: lf_sqlperform (cherry picked from commit 9810dfc25d8b9687b46e57963a3ac30bf5c9b2c9) --- src/src/lookups/lf_sqlperform.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c index ad1df29d1..eda3089e2 100644 --- a/src/src/lookups/lf_sqlperform.c +++ b/src/src/lookups/lf_sqlperform.c @@ -102,11 +102,13 @@ if (Ustrncmp(query, "servers", 7) == 0) } } - if (is_tainted(server)) - { - *errmsg = string_sprintf("%s server \"%s\" is tainted", name, server); + { uschar *m; + if (m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) + { + *errmsg = m; return DEFER; } + } rc = (*fn)(ss+1, server, result, errmsg, &defer_break, do_cache, opts); if (rc != DEFER || defer_break) return rc; @@ -158,11 +160,13 @@ else server = ele; } - if (is_tainted(server)) + { uschar *m; + if (is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) { - *errmsg = string_sprintf("%s server \"%s\" is tainted", name, server); + *errmsg = m; return DEFER; } + } rc = (*fn)(query, server, result, errmsg, &defer_break, do_cache, opts); if (rc != DEFER || defer_break) return rc; -- cgit v1.2.3 From ee4924bc711f54a751448fb5cee5ec4fc9c96196 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Fri, 2 Apr 2021 08:36:24 +0200 Subject: rf_get_transport (cherry picked from commit 015fff57c854184f8bce61476c46a2830a97daf8) --- src/src/routers/rf_get_transport.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/src/routers/rf_get_transport.c b/src/src/routers/rf_get_transport.c index 4a43818ff..32bde9ec3 100644 --- a/src/src/routers/rf_get_transport.c +++ b/src/src/routers/rf_get_transport.c @@ -66,10 +66,8 @@ if (expandable) "\"%s\" in %s router: %s", tpname, router_name, expand_string_message); return FALSE; } - if (is_tainted(ss)) + if (is_tainted2(ss, LOG_MAIN|LOG_PANIC, "Tainted tainted value '%s' from '%s' for transport", ss, tpname)) { - log_write(0, LOG_MAIN|LOG_PANIC, - "attempt to use tainted value '%s' from '%s' for transport", ss, tpname); addr->basic_errno = ERRNO_BADTRANSPORT; /* Avoid leaking info to an attacker */ addr->message = US"internal configuration error"; -- cgit v1.2.3 From 951b668a191ef510a4e27d8204c5fa82ca957a07 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sat, 3 Apr 2021 10:54:22 +0200 Subject: deliver (cherry picked from commit 2bafe3fc82cf62f0c21f939f5891b8d067f3abc7) --- src/src/deliver.c | 5 +++-- test/paniclog/0608 | 2 +- test/stderr/0608 | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/src/deliver.c b/src/src/deliver.c index a6f68825c..b5530bcf7 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -6165,9 +6165,10 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) if (!tmp) p->message = string_sprintf("failed to expand \"%s\" as a " "system filter transport name", tpname); - if (is_tainted2(tmp, 0, m = string_sprintf("Tainted values '%s' " - "for transport '%s' as a system filter", tmp, tpname))) + { uschar *m; + if (m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname)) p->message = m; + } tpname = tmp; } else diff --git a/test/paniclog/0608 b/test/paniclog/0608 index 0cf96cfdc..aa9fc2b48 100644 --- a/test/paniclog/0608 +++ b/test/paniclog/0608 @@ -3,6 +3,6 @@ 2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' -2017-07-30 18:51:05.712 10HmbA-0005vi-00 bounce_message_file is not untainted after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' 2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0608.nonexist.tmpl for warning message texts: No such file or directory diff --git a/test/stderr/0608 b/test/stderr/0608 index 0cf96cfdc..aa9fc2b48 100644 --- a/test/stderr/0608 +++ b/test/stderr/0608 @@ -3,6 +3,6 @@ 2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' -2017-07-30 18:51:05.712 10HmbA-0005vi-00 bounce_message_file is not untainted after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' 2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0608.nonexist.tmpl for warning message texts: No such file or directory -- cgit v1.2.3 From 18d243312bf3a23bd0f464fac44797e2720e03ec Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Thu, 1 Apr 2021 21:42:38 +0200 Subject: smtp_out (cherry picked from commit b9b967cca71a4da51506f8ba596b9ae40cfcef57) --- src/src/smtp_out.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index f103c2752..4e8c44869 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -53,11 +53,8 @@ if (!(expint = expand_string(istring))) return FALSE; } -if (is_tainted(expint)) +if (is_tainted2(expint, LOG_MAIN|LOG_PANIC, "Tainted value '%s' from '%s' for interface", expint, istring)) { - log_write(0, LOG_MAIN|LOG_PANIC, - "attempt to use tainted value '%s' from '%s' for interface", - expint, istring); addr->transport_return = PANIC; addr->message = string_sprintf("failed to expand \"interface\" " "option for %s: configuration error", msg); @@ -472,7 +469,7 @@ if (ob->socks_proxy) { int sock = socks_sock_connect(sc->host, sc->host_af, port, sc->interface, sc->tblock, ob->connect_timeout); - + if (sock >= 0) { if (early_data && early_data->data && early_data->len) -- cgit v1.2.3 From 16c884a4818594069253de460bf9926f69d50fe5 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Thu, 1 Apr 2021 22:02:27 +0200 Subject: smtp (cherry picked from commit 8b7d4ba8903ace7e3e3db70343798a5a0b7cea23) --- src/src/transports/smtp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 264ebc094..e2b2250ad 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -5092,11 +5092,8 @@ if (!hostlist || (ob->hosts_override && ob->hosts)) else if (ob->hosts_randomize) s = expanded_hosts = string_copy(s); - if (is_tainted(s)) + if (is_tainted2(s, LOG_MAIN|LOG_PANIC, "Tainted host list '%s' from '%s' in transport %s", s, ob->hosts, tblock->name)) { - log_write(0, LOG_MAIN|LOG_PANIC, - "attempt to use tainted host list '%s' from '%s' in transport %s", - s, ob->hosts, tblock->name); /* Avoid leaking info to an attacker */ addrlist->message = US"internal configuration error"; addrlist->transport_return = PANIC; -- cgit v1.2.3 From 368ecb000c58995c5f61443d45d43942f1f431d0 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sat, 3 Apr 2021 09:29:13 +0200 Subject: update doc (cherry picked from commit 77cc1ad3058e4ef7ae82adb914ccff0be9fe2c8b) --- doc/doc-docbook/spec.xfpt | 29 +++++++++++++++++++++++++++++ doc/doc-txt/NewStuff | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index c59468716..05d8e6ed1 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -239,6 +239,14 @@ failure report bounce message + + de-tainting + tainting, de-tainting + + + detainting + tainting, de-tainting + dialup intermittently connected hosts @@ -9606,6 +9614,8 @@ reasons, and expansion of data deriving from the sender (&"tainted data"&) .new is not permitted (including acessing a file using a tainted name). +The main config option &%allow_insecure_tainted_data%& can be used as +mitigation during uprades to more secure configurations. .wen .new @@ -14590,6 +14600,7 @@ listed in more than one group. .section "Miscellaneous" "SECID96" .table2 .row &%add_environment%& "environment variables" +.row &%allow_insecure_tainted_data%& "turn taint errors into warnings" .row &%bi_command%& "to run for &%-bi%& command line option" .row &%debug_store%& "do extra internal checks" .row &%disable_ipv6%& "do no IPv6 processing" @@ -15201,6 +15212,18 @@ domains (defined in the named domain list &%local_domains%& in the default configuration). This &"magic string"& matches the domain literal form of all the local host's IP addresses. +.new +.option allow_insecure_tainted_data main boolean false +.cindex "de-tainting" +.oindex "allow_insecure_tainted_data" +The handling of tainted data may break older (pre 4.94) configurations. +Setting this option to "true" turns taint errors (which result in a temporary +message rejection) into warnings. This option is meant as mitigation only +and deprecated already today. Future releases of Exim may ignore it. +The &%taint%& log selector can be used to suppress even the warnings. +.wen + + .option allow_mx_to_ip main boolean false .cindex "MX record" "pointing to IP address" @@ -38750,6 +38773,7 @@ selection marked by asterisks: &` smtp_protocol_error `& SMTP protocol errors &` smtp_syntax_error `& SMTP syntax errors &` subject `& contents of &'Subject:'& on <= lines +&`*taint `& taint errors or warnings &`*tls_certificate_verified `& certificate verification status &`*tls_cipher `& TLS cipher suite on <= and => lines &` tls_peerdn `& TLS peer DN on <= and => lines @@ -39145,6 +39169,11 @@ using a CA trust anchor, &`CV=dane`& if using a DNS trust anchor, and &`CV=no`& if not. .next +.cindex "log" "Taint warnings" +&%taint%&: Log warnings about tainted data. This selector can't be +turned of if &%allow_insecure_tainted_data%& is false (which is the +default). +.next .cindex "log" "TLS cipher" .cindex "TLS" "logging cipher" &%tls_cipher%&: When a message is sent or received over an encrypted diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 46a69c1d7..0ef9ab25e 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -56,6 +56,51 @@ Version 4.95 16. Main option "hosts_require_helo", requiring HELO or EHLO before MAIL. +Version 4.95 +------------ + + 1. The fast-ramp two phase queue run support, previously experimental, is + now supported by default. + + 2. The native SRS support, previously experimental, is now supported. It is + not built unless specified in the Local/Makefile. + + 3. TLS resumption support, previously experimental, is now supported and + included in default builds. + + 4. Single-key LMDB lookups, previously experimental, are now supported. + The support is not built unless specified in the Local/Makefile. + + 5. Option "message_linelength_limit" on the smtp transport to enforce (by + default) the RFC 998 character limit. + + 6. An option to ignore the cache on a lookup. + + 7. Quota checking during reception (i.e. at SMTP time) for appendfile- + transport-managed quotas. + + 8. Sqlite lookups accept a "file=" option to specify a per-operation + db file, replacing the previous prefix to the SQL string (which had + issues when the SQL used tainted values). + + 9. Lsearch lookups accept a "ret=full" option, to return both the portion + of the line matching the key, and the remainder. + +10. A command-line option to have a daemon not create a notifier socket. + +11. Faster TLS startup. When various configuration options contain no + expandable elements, the information can be preloaded and cached rather + than the provious behaviour of always loading at startup time for every + connection. This helps particularly for the CA bundle. + +12. Proxy Protocol Timeout is configurable via "proxy_protocol_timeout" + main config option. + +13. Option "smtp_accept_msx_per_connection" is now expanded. + +13. A main config option "allow_insecure_tainted_data" allows to turn + taint errors into warnings. + Version 4.94 ------------ -- cgit v1.2.3 From 331817e995b05793ec840476fac67e8f7c638a47 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Mon, 5 Apr 2021 16:06:24 +0200 Subject: testsuite: add 0990 for allow_insecure_tainted_data (cherry picked from commit 56213337357265eb42c40dd04a22f6ac433b9e81) --- test/aux-fixed/0990/example.com | 1 + test/confs/0990 | 2 ++ test/scripts/0990-Allow-Tainted-Data/0990 | 7 +++++++ test/scripts/0990-Allow-Tainted-Data/REQUIRES | 1 + test/stderr/0990 | 3 +++ test/stdout/0990 | 4 ++++ 6 files changed, 18 insertions(+) create mode 100644 test/aux-fixed/0990/example.com create mode 100644 test/confs/0990 create mode 100644 test/scripts/0990-Allow-Tainted-Data/0990 create mode 100644 test/scripts/0990-Allow-Tainted-Data/REQUIRES create mode 100644 test/stderr/0990 create mode 100644 test/stdout/0990 diff --git a/test/aux-fixed/0990/example.com b/test/aux-fixed/0990/example.com new file mode 100644 index 000000000..b5860744c --- /dev/null +++ b/test/aux-fixed/0990/example.com @@ -0,0 +1 @@ +hans diff --git a/test/confs/0990 b/test/confs/0990 new file mode 100644 index 000000000..076a39914 --- /dev/null +++ b/test/confs/0990 @@ -0,0 +1,2 @@ +# this is the default +allow_insecure_tainted_data = ALLOW_TAINTED diff --git a/test/scripts/0990-Allow-Tainted-Data/0990 b/test/scripts/0990-Allow-Tainted-Data/0990 new file mode 100644 index 000000000..87cf4c009 --- /dev/null +++ b/test/scripts/0990-Allow-Tainted-Data/0990 @@ -0,0 +1,7 @@ +# Allow insecure tainted data +exim -DALLOW_TAINTED=no -f hans@example.com -be +${lookup{$sender_address_local_part}lsearch{DIR/aux-fixed/0990/$sender_address_domain}{yes}{no}} +**** +exim -DALLOW_TAINTED=yes -f hans@example.com -be +${lookup{$sender_address_local_part}lsearch{DIR/aux-fixed/0990/$sender_address_domain}{yes}{no}} +**** diff --git a/test/scripts/0990-Allow-Tainted-Data/REQUIRES b/test/scripts/0990-Allow-Tainted-Data/REQUIRES new file mode 100644 index 000000000..5fabbded0 --- /dev/null +++ b/test/scripts/0990-Allow-Tainted-Data/REQUIRES @@ -0,0 +1 @@ +feature _OPT_MAIN_ALLOW_INSECURE_TAINTED_DATA diff --git a/test/stderr/0990 b/test/stderr/0990 new file mode 100644 index 000000000..3feb126f7 --- /dev/null +++ b/test/stderr/0990 @@ -0,0 +1,3 @@ +1999-03-02 09:44:33 Tainted filename for search: 'TESTSUITE/aux-fixed/0990/example.com' +1999-03-02 09:44:33 Warning: Tainted filename for search: 'TESTSUITE/aux-fixed/0990/example.com' +1999-03-02 09:44:33 Warning: Tainted filename 'TESTSUITE/aux-fixed/0990/example.com' diff --git a/test/stdout/0990 b/test/stdout/0990 new file mode 100644 index 000000000..5a4290afd --- /dev/null +++ b/test/stdout/0990 @@ -0,0 +1,4 @@ +> Failed: (null) +> +> yes +> -- cgit v1.2.3 From 07343a5b1968f4f5e41664c15fd636bdb6a6cc48 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Mon, 12 Apr 2021 09:19:21 +0200 Subject: tidy log.c (cherry picked from commit 0327b6460eec64da6b0c1543c7e9b3d0f8cb9294) (cherry picked from commit 8021b95c2e266861aba29c97b4bb90dc6f7637a2) --- src/src/log.c | 97 +++++++++++++++++++++++++++-------------------------------- 1 file changed, 44 insertions(+), 53 deletions(-) diff --git a/src/src/log.c b/src/src/log.c index e22fc4fdf..f1051234a 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -487,62 +487,53 @@ people want, I hope. */ ok = string_format(buffer, sizeof(buffer), CS file_path, log_names[type]); -/* Save the name of the mainlog for rollover processing. Without a datestamp, -it gets statted to see if it has been cycled. With a datestamp, the datestamp -will be compared. The static slot for saving it is the same size as buffer, -and the text has been checked above to fit, so this use of strcpy() is OK. */ - -if (type == lt_main) +switch (type) { - Ustrcpy(mainlog_name, buffer); - if (string_datestamp_offset > 0) - mainlog_datestamp = mainlog_name + string_datestamp_offset; - } - -/* Ditto for the reject log */ - -else if (type == lt_reject) - { - Ustrcpy(rejectlog_name, buffer); - if (string_datestamp_offset > 0) - rejectlog_datestamp = rejectlog_name + string_datestamp_offset; - } - -/* and deal with the debug log (which keeps the datestamp, but does not -update it) */ - -else if (type == lt_debug) - { - Ustrcpy(debuglog_name, buffer); - if (tag) - { - /* this won't change the offset of the datestamp */ - ok2 = string_format(buffer, sizeof(buffer), "%s%s", - debuglog_name, tag); - if (ok2) - Ustrcpy(debuglog_name, buffer); - } - } - -/* Remove any datestamp if this is the panic log. This is rare, so there's no -need to optimize getting the datestamp length. We remove one non-alphanumeric -char afterwards if at the start, otherwise one before. */ - -else if (string_datestamp_offset >= 0) - { - uschar * from = buffer + string_datestamp_offset; - uschar * to = from + string_datestamp_length; + case lt_main: + /* Save the name of the mainlog for rollover processing. Without a datestamp, + it gets statted to see if it has been cycled. With a datestamp, the datestamp + will be compared. The static slot for saving it is the same size as buffer, + and the text has been checked above to fit, so this use of strcpy() is OK. */ + Ustrcpy(mainlog_name, buffer); + if (string_datestamp_offset > 0) + mainlog_datestamp = mainlog_name + string_datestamp_offset; + case lt_reject: + /* Ditto for the reject log */ + Ustrcpy(rejectlog_name, buffer); + if (string_datestamp_offset > 0) + rejectlog_datestamp = rejectlog_name + string_datestamp_offset; + case lt_debug: + /* and deal with the debug log (which keeps the datestamp, but does not + update it) */ + Ustrcpy(debuglog_name, buffer); + if (tag) + { + /* this won't change the offset of the datestamp */ + ok2 = string_format(buffer, sizeof(buffer), "%s%s", + debuglog_name, tag); + if (ok2) + Ustrcpy(debuglog_name, buffer); + } + default: + /* Remove any datestamp if this is the panic log. This is rare, so there's no + need to optimize getting the datestamp length. We remove one non-alphanumeric + char afterwards if at the start, otherwise one before. */ + if (string_datestamp_offset >= 0) + { + uschar * from = buffer + string_datestamp_offset; + uschar * to = from + string_datestamp_length; - if (from == buffer || from[-1] == '/') - { - if (!isalnum(*to)) to++; - } - else - if (!isalnum(from[-1])) from--; + if (from == buffer || from[-1] == '/') + { + if (!isalnum(*to)) to++; + } + else + if (!isalnum(from[-1])) from--; - /* This copy is ok, because we know that to is a substring of from. But - due to overlap we must use memmove() not Ustrcpy(). */ - memmove(from, to, Ustrlen(to)+1); + /* This copy is ok, because we know that to is a substring of from. But + due to overlap we must use memmove() not Ustrcpy(). */ + memmove(from, to, Ustrlen(to)+1); + } } /* If the file name is too long, it is an unrecoverable disaster */ -- cgit v1.2.3 From 060cf1e3c9a0a6960b771cdff6f0a5a2ca9b114c Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Fri, 23 Apr 2021 17:40:40 +0200 Subject: Silence compiler (cherry picked from commit 2c9869d0622cc690b424cc74166d4a8393017ece) --- src/src/acl.c | 2 +- src/src/deliver.c | 3 +-- src/src/expand.c | 6 +++++- src/src/functions.h | 2 +- src/src/lookups/lf_sqlperform.c | 4 ++-- src/src/parse.c | 2 +- src/src/rda.c | 2 +- src/src/transports/autoreply.c | 12 ++++++------ src/src/transports/pipe.c | 4 ++-- 9 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/src/acl.c b/src/src/acl.c index 56d7468c1..1bf118764 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -3704,7 +3704,7 @@ for (; cb; cb = cb->next) case ACLC_QUEUE: { uschar *m; - if (m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg)) + if ((m = is_tainted2(arg, 0, "Tainted name '%s' for queue not permitted", arg))) { *log_msgptr = m; return ERROR; diff --git a/src/src/deliver.c b/src/src/deliver.c index b5530bcf7..f9f674643 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -6161,12 +6161,11 @@ else if (system_filter && process_recipients != RECIP_FAIL_TIMEOUT) { uschar *tmp = expand_string(tpname); address_file = address_pipe = NULL; - uschar *m; if (!tmp) p->message = string_sprintf("failed to expand \"%s\" as a " "system filter transport name", tpname); { uschar *m; - if (m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname)) + if ((m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname))) p->message = m; } tpname = tmp; diff --git a/src/src/expand.c b/src/src/expand.c index 0ae2aea92..4fb935528 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -4484,7 +4484,7 @@ f.expand_string_forcedfail = FALSE; expand_string_message = US""; { uschar *m; -if (m = is_tainted2(string, LOG_MAIN|LOG_PANIC, "Tainted string '%s' in expansion", s)) +if ((m = is_tainted2(string, LOG_MAIN|LOG_PANIC, "Tainted string '%s' in expansion", s))) { expand_string_message = m; goto EXPAND_FAILED; @@ -7645,10 +7645,12 @@ while (*s) /* Manually track tainting, as we deal in individual chars below */ if (is_tainted(sub)) + { if (yield->s && yield->ptr) gstring_rebuffer(yield); else yield->s = store_get(yield->size = Ustrlen(sub), TRUE); + } /* Check the UTF-8, byte-by-byte */ @@ -8209,6 +8211,7 @@ that is a bad idea, because expand_string_message is in dynamic store. */ EXPAND_FAILED: if (left) *left = s; DEBUG(D_expand) + { DEBUG(D_noutf8) { debug_printf_indent("|failed to expand: %s\n", string); @@ -8228,6 +8231,7 @@ DEBUG(D_expand) if (f.expand_string_forcedfail) debug_printf_indent(UTF8_UP_RIGHT "failure was forced\n"); } + } if (resetok_p && !resetok) *resetok_p = FALSE; expand_level--; return NULL; diff --git a/src/src/functions.h b/src/src/functions.h index 27c298cfa..6029ab4b1 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -1126,7 +1126,7 @@ if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec); /******************************************************************************/ /* Taint-checked file opens */ static inline uschar * -is_tainted2(const void *p, int lflags, const uschar* fmt, ...) +is_tainted2(const void *p, int lflags, const char* fmt, ...) { va_list ap; uschar *msg; diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c index eda3089e2..38b7c2ad3 100644 --- a/src/src/lookups/lf_sqlperform.c +++ b/src/src/lookups/lf_sqlperform.c @@ -103,7 +103,7 @@ if (Ustrncmp(query, "servers", 7) == 0) } { uschar *m; - if (m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) + if ((m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server))) { *errmsg = m; return DEFER; @@ -161,7 +161,7 @@ else } { uschar *m; - if (is_tainted2(server, 0, "Tainted %s server '%s'", name, server)) + if ((m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server))) { *errmsg = m; return DEFER; diff --git a/src/src/parse.c b/src/src/parse.c index e70dabd58..896d00f30 100644 --- a/src/src/parse.c +++ b/src/src/parse.c @@ -1415,7 +1415,7 @@ for (;;) return FF_ERROR; } - if (*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)) + if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename))) return FF_ERROR; /* Check file name if required */ diff --git a/src/src/rda.c b/src/src/rda.c index 3b458430a..a12e5de29 100644 --- a/src/src/rda.c +++ b/src/src/rda.c @@ -179,7 +179,7 @@ struct stat statbuf; /* Reading a file is a form of expansion; we wish to deny attackers the capability to specify the file name. */ -if (*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename)) +if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for file read not permitted\n", filename))) { *yield = FF_ERROR; return NULL; diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index ed99de4c6..80c7c0db0 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -407,8 +407,8 @@ if (oncelog && *oncelog && to) uschar *m; time_t then = 0; - if (m = is_tainted2(oncelog, 0, "Tainted '%s' (once file for %s transport)" - " not permitted", oncelog, tblock->name)) + if ((m = is_tainted2(oncelog, 0, "Tainted '%s' (once file for %s transport)" + " not permitted", oncelog, tblock->name))) { addr->transport_return = DEFER; addr->basic_errno = EACCES; @@ -518,8 +518,8 @@ if (oncelog && *oncelog && to) { uschar *m; int log_fd; - if (m = is_tainted2(logfile, 0, "Tainted '%s' (logfile for %s transport)" - " not permitted", logfile, tblock->name)) + if ((m = is_tainted2(logfile, 0, "Tainted '%s' (logfile for %s transport)" + " not permitted", logfile, tblock->name))) { addr->transport_return = DEFER; addr->basic_errno = EACCES; @@ -551,8 +551,8 @@ if (oncelog && *oncelog && to) if (file) { uschar *m; - if (m = is_tainted2(file, 0, "Tainted '%s' (file for %s transport)" - " not permitted", file, tblock->name)) + if ((m = is_tainted2(file, 0, "Tainted '%s' (file for %s transport)" + " not permitted", file, tblock->name))) { addr->transport_return = DEFER; addr->basic_errno = EACCES; diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c index 929681422..da49307b1 100644 --- a/src/src/transports/pipe.c +++ b/src/src/transports/pipe.c @@ -594,8 +594,8 @@ if (!cmd || !*cmd) } { uschar *m; -if (m = is_tainted2(cmd, 0, "Tainted '%s' (command " - "for %s transport) not permitted", cmd, tblock->name)) +if ((m = is_tainted2(cmd, 0, "Tainted '%s' (command " + "for %s transport) not permitted", cmd, tblock->name))) { addr->transport_return = PANIC; addr->message = m; -- cgit v1.2.3 From 28d2eab1414ef8d20ff0fde7026aa52fd01ef795 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Fri, 23 Apr 2021 22:41:57 +0200 Subject: Do not close the (main)_log, if we do not see a chance to open it again. The process doing local deliveries runs as an unprivileged user. If this process needs to log failures or warnings (as caused by the is_tainting2() function), it can't re-open the main_log and just exits. (cherry picked from commit 235c7030ee9ee1c1aad507786506a470b580bfe2) --- src/src/log.c | 84 ++++++++++++++++++++--------------------- src/src/transports/appendfile.c | 11 ++++++ 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/src/log.c b/src/src/log.c index f1051234a..90373adf0 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -701,18 +701,36 @@ return total_written; } - -static void -set_file_path(void) +void +set_file_path(BOOL *multiple) { +uschar *s; int sep = ':'; /* Fixed separator - outside use */ -uschar *t; -const uschar *tt = US LOG_FILE_PATH; -while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE))) +uschar *ss = *log_file_path ? log_file_path : LOG_FILE_PATH; + +logging_mode = 0; +while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) { - if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue; - file_path = string_copy(t); - break; + if (Ustrcmp(s, "syslog") == 0) + logging_mode |= LOG_MODE_SYSLOG; + else if (logging_mode & LOG_MODE_FILE) /* we know a file already */ + { + if (multiple) *multiple = TRUE; + } + else + { + logging_mode |= LOG_MODE_FILE; + + /* If a non-empty path is given, use it */ + + if (*s) + file_path = string_copy(s); + + /* If the path is empty, we want to use the first non-empty, non- + syslog item in LOG_FILE_PATH, if there is one, since the value of + log_file_path may have been set at runtime. If there is no such item, + use the ultimate default in the spool directory. */ + } } } @@ -720,7 +738,11 @@ while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE))) void mainlog_close(void) { -if (mainlogfd < 0) return; +/* avoid closing it if it is closed already or if we do not see a chance +to open the file mainlog later again */ +if (mainlogfd < 0 /* already closed */ + || !(geteuid() == 0 || geteuid() == exim_uid)) + return; (void)close(mainlogfd); mainlogfd = -1; mainlog_inode = 0; @@ -835,38 +857,7 @@ if (!path_inspected) /* If nothing has been set, don't waste effort... the default values for the statics are file_path="" and logging_mode = LOG_MODE_FILE. */ - if (*log_file_path) - { - int sep = ':'; /* Fixed separator - outside use */ - uschar *s; - const uschar *ss = log_file_path; - - logging_mode = 0; - while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) - { - if (Ustrcmp(s, "syslog") == 0) - logging_mode |= LOG_MODE_SYSLOG; - else if (logging_mode & LOG_MODE_FILE) - multiple = TRUE; - else - { - logging_mode |= LOG_MODE_FILE; - - /* If a non-empty path is given, use it */ - - if (*s) - file_path = string_copy(s); - - /* If the path is empty, we want to use the first non-empty, non- - syslog item in LOG_FILE_PATH, if there is one, since the value of - log_file_path may have been set at runtime. If there is no such item, - use the ultimate default in the spool directory. */ - - else - set_file_path(); /* Empty item in log_file_path */ - } /* First non-syslog item in log_file_path */ - } /* Scan of log_file_path */ - } + if (*log_file_path) set_file_path(&multiple); /* If no modes have been selected, it is a major disaster */ @@ -1484,7 +1475,7 @@ if (opts) resulting in certain setup not having been done. Hack this for now so we do not segfault; note that nondefault log locations will not work */ -if (!*file_path) set_file_path(); +if (!*file_path) set_file_path(NULL); open_log(&fd, lt_debug, tag_name); @@ -1506,5 +1497,12 @@ debug_file = NULL; unlink_log(lt_debug); } +void +open_logs(const char *m) +{ +set_file_path(NULL); +open_log(&mainlogfd, lt_main, 0); +open_log(&rejectlogfd, lt_reject, 0); +} /* End of log.c */ diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index 139f9a3ef..da2618790 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -174,6 +174,9 @@ Arguments: Returns: OK, FAIL, or DEFER */ +void +openlogs(); + static int appendfile_transport_setup(transport_instance *tblock, address_item *addrlist, transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg) @@ -183,6 +186,14 @@ appendfile_transport_options_block *ob = uschar *q = ob->quota; double default_value = 0.0; +addrlist = addrlist; /* Keep picky compilers happy */ +dummy = dummy; +uid = uid; +gid = gid; + +/* we can't wait until we're not privileged anymore */ +open_logs("appendfile"); + if (ob->expand_maildir_use_size_file) ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file, US"`maildir_use_size_file` in transport", tblock->name); -- cgit v1.2.3 From b6b4b129892a99747a586e5d4acb68fe7176ab4b Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 25 Apr 2021 18:58:35 +0200 Subject: Silence the compiler (cherry picked from commit 33d5b8e8e4c2f23b4e834e3a095e3c9dd9f0686b) --- src/src/log.c | 4 ++-- src/src/transports/appendfile.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/src/log.c b/src/src/log.c index 90373adf0..dff7d3211 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -706,7 +706,7 @@ set_file_path(BOOL *multiple) { uschar *s; int sep = ':'; /* Fixed separator - outside use */ -uschar *ss = *log_file_path ? log_file_path : LOG_FILE_PATH; +const uschar *ss = *log_file_path ? log_file_path : US LOG_FILE_PATH; logging_mode = 0; while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) @@ -1498,7 +1498,7 @@ unlink_log(lt_debug); } void -open_logs(const char *m) +open_logs(void) { set_file_path(NULL); open_log(&mainlogfd, lt_main, 0); diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c index da2618790..5d957b62e 100644 --- a/src/src/transports/appendfile.c +++ b/src/src/transports/appendfile.c @@ -175,7 +175,7 @@ Returns: OK, FAIL, or DEFER */ void -openlogs(); +open_logs(void); static int appendfile_transport_setup(transport_instance *tblock, address_item *addrlist, @@ -192,7 +192,7 @@ uid = uid; gid = gid; /* we can't wait until we're not privileged anymore */ -open_logs("appendfile"); +open_logs(); if (ob->expand_maildir_use_size_file) ob->maildir_use_size_file = expand_check_condition(ob->expand_maildir_use_size_file, -- cgit v1.2.3 From 77b478579a0029def01d1b3a4ea591eac447832a Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 25 Apr 2021 10:17:57 +0200 Subject: testsuite: adjust 622 for taintwarn (cherry picked from commit 460aac0eb9a289af1ab0f32a242a27dab851fa18) --- test/log/0622 | 99 ++++++++++++++++++++++++++++-------------------------- test/paniclog/0608 | 2 +- test/stderr/0608 | 2 +- 3 files changed, 53 insertions(+), 50 deletions(-) diff --git a/test/log/0622 b/test/log/0622 index d433cbd0a..02f447001 100644 --- a/test/log/0622 +++ b/test/log/0622 @@ -22,51 +22,54 @@ 1999-03-02 09:44:33 10HmbB-0005vi-00 -> d@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbE-0005vi-00" 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed -******** SERVER ******** -1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D -1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L S=sss id=E10HmaX-0005vi-00@myhost.test.ex for A@test.ex -1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmaY-0005vi-00 Completed -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L S=sss id=E10HmaX-0005vi-00@myhost.test.ex for B@test.ex E@test.ex F@test.ex -1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed -1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L S=sss id=E10HmaX-0005vi-00@myhost.test.ex for C@test.ex D@test.ex -1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbA-0005vi-00 Completed -1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT -1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L- S=sss id=E10HmbB-0005vi-00@myhost.test.ex for A@test.ex -1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbC-0005vi-00 Completed -1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT -1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again -1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L- S=sss id=E10HmbB-0005vi-00@myhost.test.ex for B@test.ex E@test.ex F@test.ex -1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbD-0005vi-00 Completed -1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT -1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) -1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L- S=sss id=E10HmbB-0005vi-00@myhost.test.ex for C@test.ex D@test.ex -1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: R=server -1999-03-02 09:44:33 10HmbE-0005vi-00 Completed -1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT +2017-07-30 18:51:05.712 10HmbH-0005vi-00 <= <> R=10HmaY-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbH-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbH-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmaY-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for e@test.ex +2017-07-30 18:51:05.712 10HmaZ-0005vi-00 ** e@test.ex: Unrouteable address +2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' + +2017-07-30 18:51:05.712 10HmbI-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbI-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbI-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for f@test.ex +2017-07-30 18:51:05.712 10HmbA-0005vi-00 ** f@test.ex: Unrouteable address +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0622.CALLER@myhost.test.ex' + +2017-07-30 18:51:05.712 10HmbJ-0005vi-00 <= <> R=10HmbA-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbJ-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbJ-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbK-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for g@test.ex +2017-07-30 18:51:05.712 10HmbK-0005vi-00 ** g@test.ex: Unrouteable address +2017-07-30 18:51:05.712 10HmbL-0005vi-00 <= <> R=10HmbK-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbL-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbL-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbK-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbM-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_p@test.ex +2017-07-30 18:51:05.712 10HmbM-0005vi-00 == delay_p@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbN-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_q@test.ex +2017-07-30 18:51:05.712 10HmbN-0005vi-00 == delay_q@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_r@test.ex +2017-07-30 18:51:05.712 10HmbB-0005vi-00 == delay_r@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbO-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_s@test.ex +2017-07-30 18:51:05.712 10HmbO-0005vi-00 == delay_s@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbM-0005vi-00 == delay_p@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbP-0005vi-00 <= <> R=10HmbM-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbP-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbP-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbN-0005vi-00 == delay_q@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbQ-0005vi-00 <= <> R=10HmbN-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbQ-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbQ-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbB-0005vi-00 == delay_r@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0622.nonexist.tmpl for warning message texts: No such file or directory +2017-07-30 18:51:05.712 10HmbR-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbR-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbR-0005vi-00 Completed +2017-07-30 18:51:05.712 10HmbO-0005vi-00 == delay_s@test.ex R=delay defer (-1): deliberate for test purposes +2017-07-30 18:51:05.712 10HmbS-0005vi-00 <= <> R=10HmbO-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex +2017-07-30 18:51:05.712 10HmbS-0005vi-00 => CALLER R=bounces T=savebounce +2017-07-30 18:51:05.712 10HmbS-0005vi-00 Completed diff --git a/test/paniclog/0608 b/test/paniclog/0608 index aa9fc2b48..7fe86905a 100644 --- a/test/paniclog/0608 +++ b/test/paniclog/0608 @@ -3,6 +3,6 @@ 2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' -2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0622.CALLER@myhost.test.ex' 2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0608.nonexist.tmpl for warning message texts: No such file or directory diff --git a/test/stderr/0608 b/test/stderr/0608 index aa9fc2b48..7fe86905a 100644 --- a/test/stderr/0608 +++ b/test/stderr/0608 @@ -3,6 +3,6 @@ 2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' -2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0622.CALLER@myhost.test.ex' 2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0608.nonexist.tmpl for warning message texts: No such file or directory -- cgit v1.2.3 From 0103b34645278151851c31cf1c1976150d907bb4 Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sun, 20 Jun 2021 19:02:59 +0200 Subject: Revert "testsuite: adjust 622 for taintwarn" This reverts commit 7ab3a6cd7fe7b033b5e267617f3be8a99b33db31. --- test/log/0622 | 99 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/test/log/0622 b/test/log/0622 index 02f447001..d433cbd0a 100644 --- a/test/log/0622 +++ b/test/log/0622 @@ -22,54 +22,51 @@ 1999-03-02 09:44:33 10HmbB-0005vi-00 -> d@test.ex R=client T=send_to_server H=127.0.0.1 [127.0.0.1] C="250 OK id=10HmbE-0005vi-00" 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbH-0005vi-00 <= <> R=10HmaY-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbH-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbH-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmaY-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for e@test.ex -2017-07-30 18:51:05.712 10HmaZ-0005vi-00 ** e@test.ex: Unrouteable address -2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' - -2017-07-30 18:51:05.712 10HmbI-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbI-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbI-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for f@test.ex -2017-07-30 18:51:05.712 10HmbA-0005vi-00 ** f@test.ex: Unrouteable address -2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0622.CALLER@myhost.test.ex' - -2017-07-30 18:51:05.712 10HmbJ-0005vi-00 <= <> R=10HmbA-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbJ-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbJ-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbA-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbK-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for g@test.ex -2017-07-30 18:51:05.712 10HmbK-0005vi-00 ** g@test.ex: Unrouteable address -2017-07-30 18:51:05.712 10HmbL-0005vi-00 <= <> R=10HmbK-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbL-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbL-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbK-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbM-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_p@test.ex -2017-07-30 18:51:05.712 10HmbM-0005vi-00 == delay_p@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbN-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_q@test.ex -2017-07-30 18:51:05.712 10HmbN-0005vi-00 == delay_q@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbB-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_r@test.ex -2017-07-30 18:51:05.712 10HmbB-0005vi-00 == delay_r@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbO-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for delay_s@test.ex -2017-07-30 18:51:05.712 10HmbO-0005vi-00 == delay_s@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbM-0005vi-00 == delay_p@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbP-0005vi-00 <= <> R=10HmbM-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbP-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbP-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbN-0005vi-00 == delay_q@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbQ-0005vi-00 <= <> R=10HmbN-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbQ-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbQ-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbB-0005vi-00 == delay_r@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0622.nonexist.tmpl for warning message texts: No such file or directory -2017-07-30 18:51:05.712 10HmbR-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbR-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbR-0005vi-00 Completed -2017-07-30 18:51:05.712 10HmbO-0005vi-00 == delay_s@test.ex R=delay defer (-1): deliberate for test purposes -2017-07-30 18:51:05.712 10HmbS-0005vi-00 <= <> R=10HmbO-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex -2017-07-30 18:51:05.712 10HmbS-0005vi-00 => CALLER R=bounces T=savebounce -2017-07-30 18:51:05.712 10HmbS-0005vi-00 Completed +******** SERVER ******** +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port PORT_D +1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L S=sss id=E10HmaX-0005vi-00@myhost.test.ex for A@test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L S=sss id=E10HmaX-0005vi-00@myhost.test.ex for B@test.ex E@test.ex F@test.ex +1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmaZ-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed +1999-03-02 09:44:33 10HmbA-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L S=sss id=E10HmaX-0005vi-00@myhost.test.ex for C@test.ex D@test.ex +1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbA-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbA-0005vi-00 Completed +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT +1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 10HmbC-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L- S=sss id=E10HmbB-0005vi-00@myhost.test.ex for A@test.ex +1999-03-02 09:44:33 10HmbC-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbC-0005vi-00 Completed +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT +1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 H=localhost (myhost.test.ex) [127.0.0.1] F= temporarily rejected RCPT : 452 4.5.3 Try again +1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L- S=sss id=E10HmbB-0005vi-00@myhost.test.ex for B@test.ex E@test.ex F@test.ex +1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbD-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbD-0005vi-00 Completed +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT +1999-03-02 09:44:33 SMTP connection from [127.0.0.1] (TCP/IP connection count = 1) +1999-03-02 09:44:33 10HmbE-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtp L- S=sss id=E10HmbB-0005vi-00@myhost.test.ex for C@test.ex D@test.ex +1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbE-0005vi-00 => :blackhole: R=server +1999-03-02 09:44:33 10HmbE-0005vi-00 Completed +1999-03-02 09:44:33 SMTP connection from localhost (myhost.test.ex) [127.0.0.1] closed by QUIT -- cgit v1.2.3 From f94ca3e3ed2bc5a68ac54c5487e0216ea8db8470 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 15 May 2021 13:37:04 +0200 Subject: Fix logging with empty element in log_file_path (Bug 2733) (cherry picked from commit e19790f7707cc901435849e78d20f249056c16b5) --- src/src/log.c | 82 +++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 27 deletions(-) diff --git a/src/src/log.c b/src/src/log.c index dff7d3211..4cb161ac0 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -288,8 +288,11 @@ if (fd < 0 && errno == ENOENT) uschar *lastslash = Ustrrchr(name, '/'); *lastslash = 0; created = directory_make(NULL, name, LOG_DIRECTORY_MODE, FALSE); - DEBUG(D_any) debug_printf("%s log directory %s\n", - created ? "created" : "failed to create", name); + DEBUG(D_any) + if (created) + debug_printf("created log directory %s\n", name); + else + debug_printf("failed to create log directory %s: %s\n", name, strerror(errno)); *lastslash = '/'; if (created) fd = Uopen(name, flags, LOG_MODE); } @@ -494,17 +497,24 @@ switch (type) it gets statted to see if it has been cycled. With a datestamp, the datestamp will be compared. The static slot for saving it is the same size as buffer, and the text has been checked above to fit, so this use of strcpy() is OK. */ + Ustrcpy(mainlog_name, buffer); if (string_datestamp_offset > 0) mainlog_datestamp = mainlog_name + string_datestamp_offset; + break; + case lt_reject: /* Ditto for the reject log */ + Ustrcpy(rejectlog_name, buffer); if (string_datestamp_offset > 0) rejectlog_datestamp = rejectlog_name + string_datestamp_offset; + break; + case lt_debug: /* and deal with the debug log (which keeps the datestamp, but does not update it) */ + Ustrcpy(debuglog_name, buffer); if (tag) { @@ -514,10 +524,13 @@ switch (type) if (ok2) Ustrcpy(debuglog_name, buffer); } + break; + default: /* Remove any datestamp if this is the panic log. This is rare, so there's no need to optimize getting the datestamp length. We remove one non-alphanumeric char afterwards if at the start, otherwise one before. */ + if (string_datestamp_offset >= 0) { uschar * from = buffer + string_datestamp_offset; @@ -534,6 +547,7 @@ switch (type) due to overlap we must use memmove() not Ustrcpy(). */ memmove(from, to, Ustrlen(to)+1); } + break; } /* If the file name is too long, it is an unrecoverable disaster */ @@ -547,9 +561,7 @@ if (!ok) *fd = log_open_as_exim(buffer); if (*fd >= 0) - { return; - } euid = geteuid(); @@ -701,6 +713,10 @@ return total_written; } +/* Pull the file out of the configured or the compiled-in list. +Called for an empty log_file_path element, for debug logging activation +when file_path has not previously been set, and from the appenfile transport setup. */ + void set_file_path(BOOL *multiple) { @@ -708,30 +724,42 @@ uschar *s; int sep = ':'; /* Fixed separator - outside use */ const uschar *ss = *log_file_path ? log_file_path : US LOG_FILE_PATH; -logging_mode = 0; -while ((s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE))) - { - if (Ustrcmp(s, "syslog") == 0) - logging_mode |= LOG_MODE_SYSLOG; - else if (logging_mode & LOG_MODE_FILE) /* we know a file already */ +if (*ss) + for (logging_mode = 0; + s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE); ) { - if (multiple) *multiple = TRUE; - } - else - { - logging_mode |= LOG_MODE_FILE; + if (Ustrcmp(s, "syslog") == 0) + logging_mode |= LOG_MODE_SYSLOG; + else if (!(logging_mode & LOG_MODE_FILE)) /* no file yet */ + { + /* If a non-empty path is given, use it */ + + if (*s) + file_path = string_copy(s); - /* If a non-empty path is given, use it */ + /* If handling the config option, and the element is empty, we want to use + the first non-empty, non-syslog item in LOG_FILE_PATH, if there is one, + since the value of log_file_path may have been set at runtime. If there is + no such item, use the ultimate default in the spool directory. */ - if (*s) - file_path = string_copy(s); + else if (*log_file_path && LOG_FILE_PATH[0]) + { + ss = US LOG_FILE_PATH; + continue; + } - /* If the path is empty, we want to use the first non-empty, non- - syslog item in LOG_FILE_PATH, if there is one, since the value of - log_file_path may have been set at runtime. If there is no such item, - use the ultimate default in the spool directory. */ + logging_mode |= LOG_MODE_FILE; + } + else + if (multiple) *multiple = TRUE; } - } + else + logging_mode = LOG_MODE_FILE; + +/* Set up the ultimate default if necessary. */ + +if (logging_mode & LOG_MODE_FILE && !*file_path) + file_path = string_sprintf("%s/log/%%slog", spool_directory); } @@ -865,11 +893,8 @@ if (!path_inspected) die(US"Neither syslog nor file logging set in log_file_path", US"Unexpected logging failure"); - /* Set up the ultimate default if necessary. Then revert to the old store - pool, and record that we've sorted out the path. */ + /* Revert to the old store pool, and record that we've sorted out the path. */ - if (logging_mode & LOG_MODE_FILE && !file_path[0]) - file_path = string_sprintf("%s/log/%%slog", spool_directory); store_pool = old_pool; path_inspected = TRUE; @@ -1223,6 +1248,7 @@ if (flags & LOG_PANIC) if (logging_mode & LOG_MODE_FILE) { + if (!*file_path) set_file_path(NULL); panic_recurseflag = TRUE; open_log(&paniclogfd, lt_panic, NULL); /* Won't return on failure */ panic_recurseflag = FALSE; @@ -1497,10 +1523,12 @@ debug_file = NULL; unlink_log(lt_debug); } +/* Called from the appendfile transport setup. */ void open_logs(void) { set_file_path(NULL); +if (!(logging_mode & LOG_MODE_FILE)) return; open_log(&mainlogfd, lt_main, 0); open_log(&rejectlogfd, lt_reject, 0); } -- cgit v1.2.3 From 7a33a3fc2c1ae4df30eaabaf25fc59e2d6ab5d6c Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Sat, 15 May 2021 13:40:46 +0200 Subject: Fix logging with build-time config and empty elements (Closes 2733) (cherry picked from commit 66392b270e3a6c8202e4626d43bbc9b77545ae23) --- src/src/log.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/src/src/log.c b/src/src/log.c index 4cb161ac0..1b77f98fa 100644 --- a/src/src/log.c +++ b/src/src/log.c @@ -455,7 +455,7 @@ return fd; it does not exist. This may be called recursively on failure, in order to open the panic log. -The directory is in the static variable file_path. This is static so that it +The directory is in the static variable file_path. This is static so that the work of sorting out the path is done just once per Exim process. Exim is normally configured to avoid running as root wherever possible, the log @@ -732,34 +732,32 @@ if (*ss) logging_mode |= LOG_MODE_SYSLOG; else if (!(logging_mode & LOG_MODE_FILE)) /* no file yet */ { - /* If a non-empty path is given, use it */ - - if (*s) - file_path = string_copy(s); - - /* If handling the config option, and the element is empty, we want to use - the first non-empty, non-syslog item in LOG_FILE_PATH, if there is one, - since the value of log_file_path may have been set at runtime. If there is - no such item, use the ultimate default in the spool directory. */ - - else if (*log_file_path && LOG_FILE_PATH[0]) - { - ss = US LOG_FILE_PATH; - continue; - } - logging_mode |= LOG_MODE_FILE; + if (*s) file_path = string_copy(s); /* If a non-empty path is given, use it */ } - else - if (multiple) *multiple = TRUE; + else if (multiple) *multiple = TRUE; } - else - logging_mode = LOG_MODE_FILE; +else + logging_mode = LOG_MODE_FILE; /* Set up the ultimate default if necessary. */ if (logging_mode & LOG_MODE_FILE && !*file_path) - file_path = string_sprintf("%s/log/%%slog", spool_directory); + if (LOG_FILE_PATH[0]) + { + /* If we still do not have a file_path, we take + the first non-empty, non-syslog item in LOG_FILE_PATH, if there is + one. If there is no such item, use the ultimate default in the + spool directory. */ + + for (ss = US LOG_FILE_PATH; + s = string_nextinlist(&ss, &sep, log_buffer, LOG_BUFFER_SIZE);) + { + if (*s != '/') continue; + file_path = string_copy(s); + } + } + else file_path = string_sprintf("%s/log/%%slog", spool_directory); } @@ -882,10 +880,9 @@ if (!path_inspected) store_pool = POOL_PERM; - /* If nothing has been set, don't waste effort... the default values for the - statics are file_path="" and logging_mode = LOG_MODE_FILE. */ - - if (*log_file_path) set_file_path(&multiple); + /* make sure that we have a valid log file path in "file_path", + the open_log() later relies on it */ + set_file_path(&multiple); /* If no modes have been selected, it is a major disaster */ -- cgit v1.2.3 From 305c0579ab4286b464c2cd589843a7e60f59dfaf Mon Sep 17 00:00:00 2001 From: "Heiko Schlittermann (HS12-RIPE)" Date: Wed, 16 Jun 2021 22:22:50 +0200 Subject: Testsuite: Fix 608 --- test/log/0608 | 2 +- test/paniclog/0608 | 2 +- test/stderr/0608 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/log/0608 b/test/log/0608 index 5331ae48f..d0130a6a9 100644 --- a/test/log/0608 +++ b/test/log/0608 @@ -35,7 +35,7 @@ 2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Completed 2017-07-30 18:51:05.712 10HmbA-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss for f@test.ex 2017-07-30 18:51:05.712 10HmbA-0005vi-00 ** f@test.ex: Unrouteable address -2017-07-30 18:51:05.712 10HmbA-0005vi-00 bounce_message_file is not untainted after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' 2017-07-30 18:51:05.712 10HmbJ-0005vi-00 <= <> R=10HmbA-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@myhost.test.ex 2017-07-30 18:51:05.712 10HmbJ-0005vi-00 => CALLER R=bounces T=savebounce diff --git a/test/paniclog/0608 b/test/paniclog/0608 index 7fe86905a..aa9fc2b48 100644 --- a/test/paniclog/0608 +++ b/test/paniclog/0608 @@ -3,6 +3,6 @@ 2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' -2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0622.CALLER@myhost.test.ex' +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' 2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0608.nonexist.tmpl for warning message texts: No such file or directory diff --git a/test/stderr/0608 b/test/stderr/0608 index 7fe86905a..aa9fc2b48 100644 --- a/test/stderr/0608 +++ b/test/stderr/0608 @@ -3,6 +3,6 @@ 2017-07-30 18:51:05.712 10HmaZ-0005vi-00 Failed to expand bounce_message_file: '$acl_m_unset' -2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0622.CALLER@myhost.test.ex' +2017-07-30 18:51:05.712 10HmbA-0005vi-00 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex' 2017-07-30 18:51:05.712 10HmbB-0005vi-00 Failed to open TESTSUITE/aux-fixed/0608.nonexist.tmpl for warning message texts: No such file or directory -- cgit v1.2.3