summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-docbook/spec.xfpt28
-rw-r--r--doc/doc-txt/ChangeLog3
-rw-r--r--src/src/EDITME7
-rw-r--r--src/src/acl.c38
-rw-r--r--src/src/config.h.defaults2
-rw-r--r--src/src/dbstuff.h6
-rw-r--r--src/src/deliver.c16
-rw-r--r--src/src/directory.c4
-rw-r--r--src/src/expand.c212
-rw-r--r--src/src/functions.h54
-rw-r--r--src/src/globals.c10
-rw-r--r--src/src/globals.h4
-rw-r--r--src/src/log.c130
-rw-r--r--src/src/lookups/lf_sqlperform.c14
-rw-r--r--src/src/macros.h3
-rw-r--r--src/src/parse.c6
-rw-r--r--src/src/rda.c4
-rw-r--r--src/src/readconf.c3
-rw-r--r--src/src/routers/rf_get_transport.c4
-rw-r--r--src/src/search.c8
-rw-r--r--src/src/smtp_out.c7
-rw-r--r--src/src/transports/appendfile.c11
-rw-r--r--src/src/transports/autoreply.c21
-rw-r--r--src/src/transports/pipe.c9
-rw-r--r--src/src/transports/smtp.c5
-rw-r--r--test/aux-fixed/0990/example.com1
-rw-r--r--test/confs/09902
-rw-r--r--test/log/06082
-rw-r--r--test/paniclog/06082
-rw-r--r--test/scripts/0990-Allow-Tainted-Data/09907
-rw-r--r--test/scripts/0990-Allow-Tainted-Data/REQUIRES1
-rw-r--r--test/stderr/06082
-rw-r--r--test/stderr/09903
-rw-r--r--test/stderr/262024
-rw-r--r--test/stdout/09904
35 files changed, 259 insertions, 398 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 6ede1dc95..1bc63bff3 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -240,14 +240,6 @@
<see><emphasis>bounce message</emphasis></see>
</indexterm>
<indexterm role="concept">
- <primary>de-tainting</primary>
- <see><emphasis>tainting, de-tainting</emphasis></see>
-</indexterm>
-<indexterm role="concept">
- <primary>detainting</primary>
- <see><emphasis>tainting, de-tainting</emphasis></see>
-</indexterm>
-<indexterm role="concept">
<primary>dialup</primary>
<see><emphasis>intermittently connected hosts</emphasis></see>
</indexterm>
@@ -9628,8 +9620,6 @@ reasons,
.cindex expansion "tainted data"
and expansion of data deriving from the sender (&"tainted data"&)
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.
Common ways of obtaining untainted equivalents of variables with
tainted values
@@ -14609,7 +14599,6 @@ 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"
@@ -15223,17 +15212,6 @@ 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.
-.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.
-
-
-
.option allow_mx_to_ip main boolean false
.cindex "MX record" "pointing to IP address"
It appears that more and more DNS zone administrators are breaking the rules
@@ -38901,7 +38879,6 @@ 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
@@ -39295,11 +39272,6 @@ 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/ChangeLog b/doc/doc-txt/ChangeLog
index 282b14f6f..02943dd99 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -89,6 +89,9 @@ JH/20 When built with NDBM for hints DB's check for nonexistence of a name
file.pag and file.dir files would be created in that directory's
parent.
+JH/21 Remove the "allow_insecure_tainted_data" main config option and the
+ "taint" log_selector. These were previously deprecated.
+
Exim version 4.95
-----------------
diff --git a/src/src/EDITME b/src/src/EDITME
index a950662e6..d21a45eda 100644
--- a/src/src/EDITME
+++ b/src/src/EDITME
@@ -745,13 +745,6 @@ 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/acl.c b/src/src/acl.c
index fa1172331..46615ce24 100644
--- a/src/src/acl.c
+++ b/src/src/acl.c
@@ -3885,22 +3885,20 @@ for (; cb; cb = cb->next)
#endif
case ACLC_QUEUE:
+ if (is_tainted(arg))
{
- 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;
+ *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;
+ }
+ queue_name = string_copy_perm(arg, FALSE);
+ break;
case ACLC_RATELIMIT:
rc = acl_ratelimit(arg, where, log_msgptr);
@@ -4277,10 +4275,10 @@ while (isspace(*ss)) ss++;
acl_text = ss;
-if ( !f.running_in_test_harness
- && is_tainted2(acl_text, LOG_MAIN|LOG_PANIC,
- "Tainted ACL text \"%s\"", acl_text))
+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;
@@ -4309,12 +4307,6 @@ 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,
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index 65d33ac24..8a3de3f58 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -17,8 +17,6 @@ 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/dbstuff.h b/src/src/dbstuff.h
index b28db1867..510fe4f36 100644
--- a/src/src/dbstuff.h
+++ b/src/src/dbstuff.h
@@ -522,9 +522,11 @@ after reading data. */
: (flags) == O_RDWR ? "O_RDWR" \
: (flags) == (O_RDWR|O_CREAT) ? "O_RDWR|O_CREAT" \
: "??"); \
- 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)) \
+ if (is_tainted(name) || is_tainted(dirname)) \
+ { \
+ log_write(0, LOG_MAIN|LOG_PANIC, "Tainted name for DB file not permitted"); \
*dbpp = NULL; \
+ } \
else \
{ EXIM_DBOPEN__(name, dirname, flags, mode, dbpp); } \
DEBUG(D_hints_lookup) debug_printf_indent("returned from EXIM_DBOPEN: %p\n", *dbpp); \
diff --git a/src/src/deliver.c b/src/src/deliver.c
index 8322a367c..5c60e3ff5 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -5545,11 +5545,10 @@ FILE * fp = NULL;
if (!s || !*s)
log_write(0, LOG_MAIN|LOG_PANIC,
"Failed to expand %s: '%s'\n", varname, filename);
-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 (*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 (!(fp = Ufopen(s, "rb")))
log_write(0, LOG_MAIN|LOG_PANIC, "Failed to open %s for %s "
"message texts: %s", s, reason, strerror(errno));
@@ -6159,10 +6158,9 @@ 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);
- { uschar *m;
- if ((m = is_tainted2(tmp, 0, "Tainted values '%s' " "for transport '%s' as a system filter", tmp, tpname)))
- p->message = m;
- }
+ if (is_tainted(tmp))
+ p->message = string_sprintf("attempt to used tainted value '%s' for"
+ "transport '%s' as a system filter", tmp, tpname);
tpname = tmp;
}
else
diff --git a/src/src/directory.c b/src/src/directory.c
index 11bf7338b..5363cd405 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_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted path '%s' for new directory", name))
- { p = US"create"; path = US name; errno = EACCES; goto bad; }
+if (is_tainted(name))
+ { p = US"create"; path = US name; errno = ERRNO_TAINT; goto bad; }
if (parent)
{
diff --git a/src/src/expand.c b/src/src/expand.c
index 900026f07..9b315b42b 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -444,9 +444,9 @@ enum vtypes {
vtype_pspace, /* partition space; value is T/F for spool/log */
vtype_pinodes, /* partition inodes; value is T/F for spool/log */
vtype_cert /* SSL certificate */
- #ifndef DISABLE_DKIM
+#ifndef DISABLE_DKIM
,vtype_dkim /* Lookup of value in DKIM signature */
- #endif
+#endif
};
/* Type for main variable table */
@@ -583,9 +583,9 @@ static var_entry var_table[] = {
{ "interface_address", vtype_stringptr, &interface_address },
{ "interface_port", vtype_int, &interface_port },
{ "item", vtype_stringptr, &iterate_item },
- #ifdef LOOKUP_LDAP
+#ifdef LOOKUP_LDAP
{ "ldap_dn", vtype_stringptr, &eldap_dn },
- #endif
+#endif
{ "load_average", vtype_load_avg, NULL },
{ "local_part", vtype_stringptr, &deliver_localpart },
{ "local_part_data", vtype_stringptr, &deliver_localpart_data },
@@ -4498,13 +4498,13 @@ expand_level++;
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 (is_tainted(string))
{
- expand_string_message = m;
+ expand_string_message =
+ string_sprintf("attempt to expand tainted string '%s'", s);
+ log_write(0, LOG_MAIN|LOG_PANIC, "%s", expand_string_message);
goto EXPAND_FAILED;
}
-}
while (*s)
{
@@ -7198,14 +7198,14 @@ NOT_ITEM: ;
}
case EOP_MD5:
- #ifndef DISABLE_TLS
+#ifndef DISABLE_TLS
if (vp && *(void **)vp->value)
{
uschar * cp = tls_cert_fprt_md5(*(void **)vp->value);
yield = string_cat(yield, cp);
}
else
- #endif
+#endif
{
md5 base;
uschar digest[16];
@@ -7217,14 +7217,14 @@ NOT_ITEM: ;
break;
case EOP_SHA1:
- #ifndef DISABLE_TLS
+#ifndef DISABLE_TLS
if (vp && *(void **)vp->value)
{
uschar * cp = tls_cert_fprt_sha1(*(void **)vp->value);
yield = string_cat(yield, cp);
}
else
- #endif
+#endif
{
hctx h;
uschar digest[20];
@@ -7237,7 +7237,7 @@ NOT_ITEM: ;
case EOP_SHA2:
case EOP_SHA256:
- #ifdef EXIM_HAVE_SHA2
+#ifdef EXIM_HAVE_SHA2
if (vp && *(void **)vp->value)
if (c == EOP_SHA256)
yield = string_cat(yield, tls_cert_fprt_sha256(*(void **)vp->value));
@@ -7264,13 +7264,13 @@ NOT_ITEM: ;
while (b.len-- > 0)
yield = string_fmt_append(yield, "%02X", *b.data++);
}
- #else
+#else
expand_string_message = US"sha256 only supported with TLS";
- #endif
+#endif
break;
case EOP_SHA3:
- #ifdef EXIM_HAVE_SHA3
+#ifdef EXIM_HAVE_SHA3
{
hctx h;
blob b;
@@ -7293,10 +7293,10 @@ NOT_ITEM: ;
yield = string_fmt_append(yield, "%02X", *b.data++);
}
break;
- #else
+#else
expand_string_message = US"sha3 only supported with GnuTLS 3.5.0 + or OpenSSL 1.1.1 +";
goto EXPAND_FAILED;
- #endif
+#endif
/* Convert hex encoding to base64 encoding */
@@ -7629,106 +7629,104 @@ NOT_ITEM: ;
else if (opt)
sub = NULL;
- if (!sub)
- {
- expand_string_message = string_sprintf(
- "\"%s\" unrecognized after \"${quote_%s\"", /*}*/
- opt, arg);
- goto EXPAND_FAILED;
- }
+ if (!sub)
+ {
+ expand_string_message = string_sprintf(
+ "\"%s\" unrecognized after \"${quote_%s\"", /*}*/
+ opt, arg);
+ goto EXPAND_FAILED;
+ }
- yield = string_cat(yield, sub);
- break;
- }
+ yield = string_cat(yield, sub);
+ break;
+ }
- /* rx quote sticks in \ before any non-alphameric character so that
- the insertion works in a regular expression. */
+ /* rx quote sticks in \ before any non-alphameric character so that
+ the insertion works in a regular expression. */
- case EOP_RXQUOTE:
- {
- uschar *t = sub - 1;
- while (*(++t) != 0)
- {
- if (!isalnum(*t))
- yield = string_catn(yield, US"\\", 1);
- yield = string_catn(yield, t, 1);
- }
- break;
- }
+ case EOP_RXQUOTE:
+ {
+ uschar *t = sub - 1;
+ while (*(++t) != 0)
+ {
+ if (!isalnum(*t))
+ yield = string_catn(yield, US"\\", 1);
+ yield = string_catn(yield, t, 1);
+ }
+ break;
+ }
- /* RFC 2047 encodes, assuming headers_charset (default ISO 8859-1) as
- prescribed by the RFC, if there are characters that need to be encoded */
+ /* RFC 2047 encodes, assuming headers_charset (default ISO 8859-1) as
+ prescribed by the RFC, if there are characters that need to be encoded */
- case EOP_RFC2047:
- yield = string_cat(yield,
- parse_quote_2047(sub, Ustrlen(sub), headers_charset,
- FALSE));
- break;
+ case EOP_RFC2047:
+ yield = string_cat(yield,
+ parse_quote_2047(sub, Ustrlen(sub), headers_charset,
+ FALSE));
+ break;
- /* RFC 2047 decode */
+ /* RFC 2047 decode */
- case EOP_RFC2047D:
- {
- int len;
- uschar *error;
- uschar *decoded = rfc2047_decode(sub, check_rfc2047_length,
- headers_charset, '?', &len, &error);
- if (error)
- {
- expand_string_message = error;
- goto EXPAND_FAILED;
- }
- yield = string_catn(yield, decoded, len);
- break;
- }
+ case EOP_RFC2047D:
+ {
+ int len;
+ uschar *error;
+ uschar *decoded = rfc2047_decode(sub, check_rfc2047_length,
+ headers_charset, '?', &len, &error);
+ if (error)
+ {
+ expand_string_message = error;
+ goto EXPAND_FAILED;
+ }
+ yield = string_catn(yield, decoded, len);
+ break;
+ }
- /* from_utf8 converts UTF-8 to 8859-1, turning non-existent chars into
- underscores */
+ /* from_utf8 converts UTF-8 to 8859-1, turning non-existent chars into
+ underscores */
- case EOP_FROM_UTF8:
- {
- uschar * buff = store_get(4, is_tainted(sub));
- while (*sub)
- {
- int c;
- GETUTF8INC(c, sub);
- if (c > 255) c = '_';
- buff[0] = c;
- yield = string_catn(yield, buff, 1);
- }
- break;
- }
+ case EOP_FROM_UTF8:
+ {
+ uschar * buff = store_get(4, is_tainted(sub));
+ while (*sub)
+ {
+ int c;
+ GETUTF8INC(c, sub);
+ if (c > 255) c = '_';
+ buff[0] = c;
+ yield = string_catn(yield, buff, 1);
+ }
+ break;
+ }
- /* replace illegal UTF-8 sequences by replacement character */
+ /* replace illegal UTF-8 sequences by replacement character */
- #define UTF8_REPLACEMENT_CHAR US"?"
+ #define UTF8_REPLACEMENT_CHAR US"?"
- case EOP_UTF8CLEAN:
- {
- int seq_len = 0, index = 0;
- int bytes_left = 0;
- long codepoint = -1;
- int complete;
- uschar seq_buff[4]; /* accumulate utf-8 here */
+ case EOP_UTF8CLEAN:
+ {
+ int seq_len = 0, index = 0;
+ int bytes_left = 0;
+ long codepoint = -1;
+ int complete;
+ uschar seq_buff[4]; /* accumulate utf-8 here */
- /* Manually track tainting, as we deal in individual chars below */
+ /* 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), is_tainted(sub));
- }
+ 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 */
+ /* Check the UTF-8, byte-by-byte */
- while (*sub)
- {
- complete = 0;
- uschar c = *sub++;
+ while (*sub)
+ {
+ complete = 0;
+ uschar c = *sub++;
- if (bytes_left)
+ if (bytes_left)
{
if ((c & 0xc0) != 0x80)
/* wrong continuation byte; invalidate all bytes */
@@ -7800,7 +7798,7 @@ NOT_ITEM: ;
break;
}
- #ifdef SUPPORT_I18N
+#ifdef SUPPORT_I18N
case EOP_UTF8_DOMAIN_TO_ALABEL:
{
uschar * error = NULL;
@@ -7861,7 +7859,7 @@ NOT_ITEM: ;
yield = string_cat(yield, s);
break;
}
- #endif /* EXPERIMENTAL_INTERNATIONAL */
+#endif /* EXPERIMENTAL_INTERNATIONAL */
/* escape turns all non-printing characters into escape sequences. */
@@ -7937,13 +7935,13 @@ NOT_ITEM: ;
case EOP_STR2B64:
case EOP_BASE64:
{
- #ifndef DISABLE_TLS
+#ifndef DISABLE_TLS
uschar * s = vp && *(void **)vp->value
? tls_cert_der_b64(*(void **)vp->value)
: b64encode(CUS sub, Ustrlen(sub));
- #else
+#else
uschar * s = b64encode(CUS sub, Ustrlen(sub));
- #endif
+#endif
yield = string_cat(yield, s);
break;
}
@@ -8290,7 +8288,6 @@ 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);
@@ -8310,7 +8307,6 @@ 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 c03f88304..e4d9b1a58 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -1135,50 +1135,20 @@ 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 char* 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_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
- return open(pathname, flags);
+if (!is_tainted(pathname)) return open(pathname, flags);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
errno = EACCES;
return -1;
}
-
static inline int
exim_open(const char *pathname, int flags, mode_t mode)
{
-if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
- return open(pathname, flags, mode);
+if (!is_tainted(pathname)) return open(pathname, flags, mode);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
errno = EACCES;
return -1;
}
@@ -1186,16 +1156,16 @@ return -1;
static inline int
exim_openat(int dirfd, const char *pathname, int flags)
{
-if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
- return openat(dirfd, pathname, flags);
+if (!is_tainted(pathname)) return openat(dirfd, pathname, flags);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
errno = EACCES;
return -1;
}
static inline int
exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
{
-if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
- return openat(dirfd, pathname, flags, mode);
+if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
errno = EACCES;
return -1;
}
@@ -1204,8 +1174,8 @@ return -1;
static inline FILE *
exim_fopen(const char *pathname, const char *mode)
{
-if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
- return fopen(pathname, mode);
+if (!is_tainted(pathname)) return fopen(pathname, mode);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
errno = EACCES;
return NULL;
}
@@ -1213,8 +1183,8 @@ return NULL;
static inline DIR *
exim_opendir(const uschar * name)
{
-if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name))
- return opendir(CCS name);
+if (!is_tainted(name)) return opendir(CCS name);
+log_write(0, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name);
errno = EACCES;
return NULL;
}
diff --git a/src/src/globals.c b/src/src/globals.c
index 7e50867b2..012c637dd 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -98,10 +98,6 @@ 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,9 +1051,6 @@ 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
@@ -1127,9 +1120,6 @@ 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 de4670a81..02fcc9f33 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -77,10 +77,6 @@ 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/log.c b/src/src/log.c
index 8bdb244bd..7a73b154a 100644
--- a/src/src/log.c
+++ b/src/src/log.c
@@ -288,11 +288,8 @@ if (fd < 0 && errno == ENOENT)
uschar *lastslash = Ustrrchr(name, '/');
*lastslash = 0;
created = directory_make(NULL, name, LOG_DIRECTORY_MODE, FALSE);
- 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));
+ DEBUG(D_any) debug_printf("%s log directory %s\n",
+ created ? "created" : "failed to create", name);
*lastslash = '/';
if (created) fd = Uopen(name, flags, LOG_MODE);
}
@@ -455,7 +452,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
+The directory is in the static variable file_path. This is static so that it
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
@@ -497,7 +494,6 @@ 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;
@@ -505,7 +501,6 @@ switch (type)
case lt_reject:
/* Ditto for the reject log */
-
Ustrcpy(rejectlog_name, buffer);
if (string_datestamp_offset > 0)
rejectlog_datestamp = rejectlog_name + string_datestamp_offset;
@@ -514,14 +509,9 @@ switch (type)
case lt_debug:
/* and deal with the debug log (which keeps the datestamp, but does not
update it) */
-
Ustrcpy(debuglog_name, buffer);
if (tag)
{
- if (is_tainted(tag))
- die(US"exim: tainted tag for debug log filename",
- US"Logging failure; please try later");
-
/* this won't change the offset of the datestamp */
ok2 = string_format(buffer, sizeof(buffer), "%s%s",
debuglog_name, tag);
@@ -534,7 +524,6 @@ switch (type)
/* 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;
@@ -715,62 +704,26 @@ 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)
+static void
+set_file_path(void)
{
-uschar *s;
int sep = ':'; /* Fixed separator - outside use */
-const uschar *ss = *log_file_path ? log_file_path : US LOG_FILE_PATH;
-
-if (*ss)
- for (logging_mode = 0;
- 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)) /* no file yet */
- {
- 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
- logging_mode = LOG_MODE_FILE;
-
-/* Set up the ultimate default if necessary. */
-
-if (logging_mode & LOG_MODE_FILE && !*file_path)
- 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);
+uschar *t;
+const uschar *tt = US LOG_FILE_PATH;
+while ((t = string_nextinlist(&tt, &sep, log_buffer, LOG_BUFFER_SIZE)))
+ {
+ if (Ustrcmp(t, "syslog") == 0 || t[0] == 0) continue;
+ file_path = string_copy(t);
+ break;
+ }
}
void
mainlog_close(void)
{
-/* 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;
+if (mainlogfd < 0) return;
(void)close(mainlogfd);
mainlogfd = -1;
mainlog_inode = 0;
@@ -882,9 +835,41 @@ if (!path_inspected)
store_pool = POOL_PERM;
- /* 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 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 no modes have been selected, it is a major disaster */
@@ -892,8 +877,11 @@ if (!path_inspected)
die(US"Neither syslog nor file logging set in log_file_path",
US"Unexpected logging failure");
- /* Revert to the old store pool, and record that we've sorted out the path. */
+ /* Set up the ultimate default if necessary. Then 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;
@@ -1252,7 +1240,6 @@ 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;
@@ -1507,7 +1494,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(NULL);
+if (!*file_path) set_file_path();
open_log(&debug_fd, lt_debug, tag_name);
@@ -1531,14 +1518,5 @@ debug_fd = -1;
if (kill) 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);
-}
/* End of log.c */
diff --git a/src/src/lookups/lf_sqlperform.c b/src/src/lookups/lf_sqlperform.c
index b9de0a1c8..3204e1256 100644
--- a/src/src/lookups/lf_sqlperform.c
+++ b/src/src/lookups/lf_sqlperform.c
@@ -102,13 +102,11 @@ if (Ustrncmp(query, "servers", 7) == 0)
}
}
- { uschar *m;
- if ((m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server)))
- {
- *errmsg = m;
+ if (is_tainted(server))
+ {
+ *errmsg = string_sprintf("%s server \"%s\" is tainted", name, server);
return DEFER;
}
- }
rc = (*fn)(ss+1, server, result, errmsg, &defer_break, do_cache, opts);
if (rc != DEFER || defer_break) return rc;
@@ -160,13 +158,11 @@ else
server = ele;
}
- { uschar *m;
- if ((m = is_tainted2(server, 0, "Tainted %s server '%s'", name, server)))
+ if (is_tainted(server))
{
- *errmsg = m;
+ *errmsg = string_sprintf("%s server \"%s\" is tainted", name, server);
return DEFER;
}
- }
rc = (*fn)(query, server, result, errmsg, &defer_break, do_cache, opts);
if (rc != DEFER || defer_break) return rc;
diff --git a/src/src/macros.h b/src/src/macros.h
index 5e26a7bce..92f2cc08f 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -492,9 +492,6 @@ 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/parse.c b/src/src/parse.c
index e30b80527..cf673e716 100644
--- a/src/src/parse.c
+++ b/src/src/parse.c
@@ -1414,8 +1414,12 @@ for (;;)
return FF_ERROR;
}
- if ((*error = is_tainted2(filename, 0, "Tainted name '%s' for included file not permitted\n", filename)))
+ if (is_tainted(filename))
+ {
+ *error = string_sprintf("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 0ffc61c77..dba2e20fb 100644
--- a/src/src/rda.c
+++ b/src/src/rda.c
@@ -179,8 +179,10 @@ 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 (is_tainted(filename))
{
+ *error = string_sprintf("Tainted name '%s' for file read not permitted\n",
+ filename);
*yield = FF_ERROR;
return NULL;
}
diff --git a/src/src/readconf.c b/src/src/readconf.c
index bbc13879c..763a0c5f0 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -68,9 +68,6 @@ 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} },
diff --git a/src/src/routers/rf_get_transport.c b/src/src/routers/rf_get_transport.c
index ce81345e7..3883a7698 100644
--- a/src/src/routers/rf_get_transport.c
+++ b/src/src/routers/rf_get_transport.c
@@ -67,8 +67,10 @@ if (expandable)
"\"%s\" in %s router: %s", tpname, router_name, expand_string_message);
return FALSE;
}
- if (is_tainted2(ss, LOG_MAIN|LOG_PANIC, "Tainted tainted value '%s' from '%s' for transport", ss, tpname))
+ if (is_tainted(ss))
{
+ 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";
diff --git a/src/src/search.c b/src/src/search.c
index 63a1f91de..d93397f09 100644
--- a/src/src/search.c
+++ b/src/src/search.c
@@ -390,8 +390,12 @@ lookup_info *lk = lookup_list[search_type];
uschar keybuffer[256];
int old_pool = store_pool;
-if (filename && is_tainted2(filename, LOG_MAIN|LOG_PANIC, "Tainted filename for search: '%s'", filename))
+if (filename && is_tainted(filename))
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC,
+ "Tainted filename for search: '%s'", filename);
return NULL;
+ }
/* Change to the search store pool and remember our reset point */
@@ -708,7 +712,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);
diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c
index fc1e6cecd..06f6ce29c 100644
--- a/src/src/smtp_out.c
+++ b/src/src/smtp_out.c
@@ -53,8 +53,11 @@ if (!(expint = expand_string(istring)))
return FALSE;
}
-if (is_tainted2(expint, LOG_MAIN|LOG_PANIC, "Tainted value '%s' from '%s' for interface", expint, istring))
+if (is_tainted(expint))
{
+ 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);
@@ -475,7 +478,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)
diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index 91269890c..440f0de20 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -174,9 +174,6 @@ Arguments:
Returns: OK, FAIL, or DEFER
*/
-void
-open_logs(void);
-
static int
appendfile_transport_setup(transport_instance *tblock, address_item *addrlist,
transport_feedback *dummy, uid_t uid, gid_t gid, uschar **errmsg)
@@ -186,14 +183,6 @@ 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();
-
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);
diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c
index f630c6eb3..13e2eaf19 100644
--- a/src/src/transports/autoreply.c
+++ b/src/src/transports/autoreply.c
@@ -402,15 +402,14 @@ recipient cache. */
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 (is_tainted(oncelog))
{
addr->transport_return = DEFER;
addr->basic_errno = EACCES;
- addr->message = m;
+ addr->message = string_sprintf("Tainted '%s' (once file for %s transport)"
+ " not permitted", oncelog, tblock->name);
goto END_OFF;
}
@@ -514,14 +513,13 @@ if (oncelog && *oncelog && to)
if (then != 0 && (once_repeat_sec <= 0 || now - then < once_repeat_sec))
{
- uschar *m;
int log_fd;
- if ((m = is_tainted2(logfile, 0, "Tainted '%s' (logfile for %s transport)"
- " not permitted", logfile, tblock->name)))
+ if (is_tainted(logfile))
{
addr->transport_return = DEFER;
addr->basic_errno = EACCES;
- addr->message = m;
+ addr->message = string_sprintf("Tainted '%s' (logfile for %s transport)"
+ " not permitted", logfile, tblock->name);
goto END_OFF;
}
@@ -548,13 +546,12 @@ if (oncelog && *oncelog && to)
/* We are going to send a message. Ensure any requested file is available. */
if (file)
{
- uschar *m;
- if ((m = is_tainted2(file, 0, "Tainted '%s' (file for %s transport)"
- " not permitted", file, tblock->name)))
+ if (is_tainted(file))
{
addr->transport_return = DEFER;
addr->basic_errno = EACCES;
- addr->message = m;
+ addr->message = string_sprintf("Tainted '%s' (file for %s transport)"
+ " not permitted", file, tblock->name);
return FALSE;
}
if (!(ff = Ufopen(file, "rb")) && !ob->file_optional)
diff --git a/src/src/transports/pipe.c b/src/src/transports/pipe.c
index e22722fd0..2ec4a72fb 100644
--- a/src/src/transports/pipe.c
+++ b/src/src/transports/pipe.c
@@ -592,16 +592,13 @@ if (!cmd || !*cmd)
tblock->name);
return FALSE;
}
-
-{ uschar *m;
-if ((m = is_tainted2(cmd, 0, "Tainted '%s' (command "
- "for %s transport) not permitted", cmd, tblock->name)))
+if (is_tainted(cmd))
{
+ 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
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 7d5eb35a5..d36e95ce5 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -5090,8 +5090,11 @@ if (!hostlist || (ob->hosts_override && ob->hosts))
else
if (ob->hosts_randomize) s = expanded_hosts = string_copy(s);
- if (is_tainted2(s, LOG_MAIN|LOG_PANIC, "Tainted host list '%s' from '%s' in transport %s", s, ob->hosts, tblock->name))
+ if (is_tainted(s))
{
+ 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;
diff --git a/test/aux-fixed/0990/example.com b/test/aux-fixed/0990/example.com
deleted file mode 100644
index b5860744c..000000000
--- a/test/aux-fixed/0990/example.com
+++ /dev/null
@@ -1 +0,0 @@
-hans
diff --git a/test/confs/0990 b/test/confs/0990
deleted file mode 100644
index 076a39914..000000000
--- a/test/confs/0990
+++ /dev/null
@@ -1,2 +0,0 @@
-# this is the default
-allow_insecure_tainted_data = ALLOW_TAINTED
diff --git a/test/log/0608 b/test/log/0608
index d0130a6a9..5331ae48f 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 Tainted bounce_message_file after expansion: 'TESTSUITE/aux-fixed/0608.CALLER@myhost.test.ex'
+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 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 <CALLER@myhost.test.ex> R=bounces T=savebounce
diff --git a/test/paniclog/0608 b/test/paniclog/0608
index aa9fc2b48..0cf96cfdc 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 bounce_message_file is not untainted 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/scripts/0990-Allow-Tainted-Data/0990 b/test/scripts/0990-Allow-Tainted-Data/0990
deleted file mode 100644
index 87cf4c009..000000000
--- a/test/scripts/0990-Allow-Tainted-Data/0990
+++ /dev/null
@@ -1,7 +0,0 @@
-# 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
deleted file mode 100644
index 5fabbded0..000000000
--- a/test/scripts/0990-Allow-Tainted-Data/REQUIRES
+++ /dev/null
@@ -1 +0,0 @@
-feature _OPT_MAIN_ALLOW_INSECURE_TAINTED_DATA
diff --git a/test/stderr/0608 b/test/stderr/0608
index aa9fc2b48..0cf96cfdc 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 bounce_message_file is not untainted 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/0990 b/test/stderr/0990
deleted file mode 100644
index 3feb126f7..000000000
--- a/test/stderr/0990
+++ /dev/null
@@ -1,3 +0,0 @@
-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/stderr/2620 b/test/stderr/2620
index 992a60904..ab3ca9228 100644
--- a/test/stderr/2620
+++ b/test/stderr/2620
@@ -306,10 +306,10 @@ check set acl_m0 = ok: ${lookup pgsql,servers=localhost::1223 {select name
type=pgsql key="servers=localhost::1223/test/CALLER/; select name from them where id = 'c'" opts=NULL
database lookup required for servers=localhost::1223/test/CALLER/; select name from them where id = 'c'
PostgreSQL query: "servers=localhost::1223/test/CALLER/; select name from them where id = 'c'" opts 'NULL'
- lookup deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ lookup deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
warn: condition test deferred in ACL "check_recipient"
LOG: MAIN
- H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
processing "warn" (TESTSUITE/test-config 38)
check set acl_m0 = ok: hostlist
check hosts = net-pgsql;select * from them where id='$local_part'
@@ -340,11 +340,11 @@ internal_search_find: file="NULL"
type=pgsql key="servers=localhost::1223/test/CALLER/; select * from them where id='c'" opts=NULL
database lookup required for servers=localhost::1223/test/CALLER/; select * from them where id='c'
PostgreSQL query: "servers=localhost::1223/test/CALLER/; select * from them where id='c'" opts 'NULL'
-lookup deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+lookup deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
host in "<& net-pgsql;servers=localhost::1223/test/CALLER/; select * from them where id='c'"? list match deferred for net-pgsql;servers=localhost::1223/test/CALLER/; select * from them where id='c'
warn: condition test deferred in ACL "check_recipient"
LOG: MAIN
- H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
processing "warn" (TESTSUITE/test-config 46)
check set acl_m0 = FAIL: hostlist
check hosts = <& net-pgsql,servers=localhost::1223/test/CALLER/; select * from them where id='$local_part'
@@ -357,11 +357,11 @@ internal_search_find: file="NULL"
type=pgsql key=" select * from them where id='c'" opts="servers=localhost::1223/test/CALLER/"
database lookup required for select * from them where id='c'
PostgreSQL query: " select * from them where id='c'" opts 'servers=localhost::1223/test/CALLER/'
-lookup deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+lookup deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
host in "<& net-pgsql,servers=localhost::1223/test/CALLER/; select * from them where id='c'"? list match deferred for net-pgsql,servers=localhost::1223/test/CALLER/; select * from them where id='c'
warn: condition test deferred in ACL "check_recipient"
LOG: MAIN
- H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
processing "accept" (TESTSUITE/test-config 49)
check domains = +local_domains
d in "@"? no (end of list)
@@ -449,10 +449,10 @@ check set acl_m0 = ok: ${lookup pgsql,servers=localhost::1223 {select name
type=pgsql key="servers=localhost::1223/test/CALLER/; select name from them where id = 'c'" opts=NULL
database lookup required for servers=localhost::1223/test/CALLER/; select name from them where id = 'c'
PostgreSQL query: "servers=localhost::1223/test/CALLER/; select name from them where id = 'c'" opts 'NULL'
- lookup deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ lookup deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
warn: condition test deferred in ACL "check_recipient"
LOG: MAIN
- H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
processing "warn" (TESTSUITE/test-config 38)
check set acl_m0 = ok: hostlist
check hosts = net-pgsql;select * from them where id='$local_part'
@@ -479,11 +479,11 @@ internal_search_find: file="NULL"
type=pgsql key="servers=localhost::1223/test/CALLER/; select * from them where id='c'" opts=NULL
database lookup required for servers=localhost::1223/test/CALLER/; select * from them where id='c'
PostgreSQL query: "servers=localhost::1223/test/CALLER/; select * from them where id='c'" opts 'NULL'
-lookup deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+lookup deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
host in "<& net-pgsql;servers=localhost::1223/test/CALLER/; select * from them where id='c'"? list match deferred for net-pgsql;servers=localhost::1223/test/CALLER/; select * from them where id='c'
warn: condition test deferred in ACL "check_recipient"
LOG: MAIN
- H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
processing "warn" (TESTSUITE/test-config 46)
check set acl_m0 = FAIL: hostlist
check hosts = <& net-pgsql,servers=localhost::1223/test/CALLER/; select * from them where id='$local_part'
@@ -496,11 +496,11 @@ internal_search_find: file="NULL"
type=pgsql key=" select * from them where id='c'" opts="servers=localhost::1223/test/CALLER/"
database lookup required for select * from them where id='c'
PostgreSQL query: " select * from them where id='c'" opts 'servers=localhost::1223/test/CALLER/'
-lookup deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+lookup deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
host in "<& net-pgsql,servers=localhost::1223/test/CALLER/; select * from them where id='c'"? list match deferred for net-pgsql,servers=localhost::1223/test/CALLER/; select * from them where id='c'
warn: condition test deferred in ACL "check_recipient"
LOG: MAIN
- H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: Tainted PostgreSQL server 'localhost:1223/test/CALLER/'
+ H=(test) [10.0.0.0] Warning: ACL "warn" statement skipped: condition test deferred: PostgreSQL server "localhost:1223/test/CALLER/" is tainted
processing "accept" (TESTSUITE/test-config 49)
check domains = +local_domains
d in "@"? no (end of list)
diff --git a/test/stdout/0990 b/test/stdout/0990
deleted file mode 100644
index 5a4290afd..000000000
--- a/test/stdout/0990
+++ /dev/null
@@ -1,4 +0,0 @@
-> Failed: (null)
->
-> yes
->