From 481e63ca2bbd7b603e5bb84f6582ab4be5e3300d Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sat, 11 Jan 2020 21:50:58 +0000 Subject: [PATCH] autoreply transport: taint-enfoce options --- doc/doc-txt/ChangeLog | 1 + src/src/transports/autoreply.c | 50 ++++++++++++++++++++++++++-------- test/confs/0243 | 2 +- 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 33381d558..368d37ec1 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -90,6 +90,7 @@ JH/19 Bug 2507: Modules: on handling a dynamic-module (lookups) open failure, JH/20 Taint checking: disallow use of tainted data for - the appendfile transport file and directory options - the pipe transport command + - the autoreply transport file, log and once options - file names used by the redirect router (including filter files) Previously this was permitted. diff --git a/src/src/transports/autoreply.c b/src/src/transports/autoreply.c index 68f8d1f58..666591b60 100644 --- a/src/src/transports/autoreply.c +++ b/src/src/transports/autoreply.c @@ -156,7 +156,7 @@ checkexpand(uschar *s, address_item *addr, uschar *name, int type) { uschar *ss = expand_string(s); -if (ss == NULL) +if (!ss) { addr->transport_return = FAIL; addr->message = string_sprintf("Expansion of \"%s\" failed in %s transport: " @@ -307,7 +307,7 @@ from that block. It has typically been set up by a mail filter processing router. Otherwise, the data must be supplied by this transport, and it has to be expanded here. */ -if (addr->reply != NULL) +if (addr->reply) { DEBUG(D_transport) debug_printf("taking data from address\n"); from = addr->reply->from; @@ -418,18 +418,27 @@ recipient, the effect might not be quite as envisaged. If once_file_size is set, instead of a dbm file, we use a regular file containing a circular buffer recipient cache. */ -if (oncelog && *oncelog != 0 && to) +if (oncelog && *oncelog && to) { time_t then = 0; + if (is_tainted(oncelog)) + { + addr->transport_return = DEFER; + addr->basic_errno = EACCES; + addr->message = string_sprintf("Tainted '%s' (once file for %s transport)" + " not permitted", oncelog, tblock->name); + goto END_OFF; + } + /* Handle fixed-size cache file. */ if (ob->once_file_size > 0) { uschar * nextp; struct stat statbuf; - cache_fd = Uopen(oncelog, O_CREAT|O_RDWR, ob->mode); + cache_fd = Uopen(oncelog, O_CREAT|O_RDWR, ob->mode); if (cache_fd < 0 || fstat(cache_fd, &statbuf) != 0) { addr->transport_return = DEFER; @@ -523,6 +532,15 @@ if (oncelog && *oncelog != 0 && to) if (then != 0 && (once_repeat_sec <= 0 || now - then < once_repeat_sec)) { int log_fd; + if (is_tainted(logfile)) + { + addr->transport_return = DEFER; + addr->basic_errno = EACCES; + addr->message = string_sprintf("Tainted '%s' (logfile for %s transport)" + " not permitted", logfile, tblock->name); + goto END_OFF; + } + DEBUG(D_transport) debug_printf("message previously sent to %s%s\n", to, (once_repeat_sec > 0)? " and repeat time not reached" : ""); log_fd = logfile ? Uopen(logfile, O_WRONLY|O_APPEND|O_CREAT, ob->mode) : -1; @@ -544,14 +562,24 @@ if (oncelog && *oncelog != 0 && to) } /* We are going to send a message. Ensure any requested file is available. */ - -if (file && !(ff = Ufopen(file, "rb")) && !ob->file_optional) +if (file) { - addr->transport_return = DEFER; - addr->basic_errno = errno; - addr->message = string_sprintf("Failed to open file %s when sending " - "message from %s transport: %s", file, tblock->name, strerror(errno)); - return FALSE; + if (is_tainted(file)) + { + addr->transport_return = DEFER; + addr->basic_errno = EACCES; + 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) + { + addr->transport_return = DEFER; + addr->basic_errno = errno; + addr->message = string_sprintf("Failed to open file %s when sending " + "message from %s transport: %s", file, tblock->name, strerror(errno)); + return FALSE; + } } /* Make a subprocess to send the message */ diff --git a/test/confs/0243 b/test/confs/0243 index 5a2f50136..d5e989c5b 100644 --- a/test/confs/0243 +++ b/test/confs/0243 @@ -71,7 +71,7 @@ address_pipe: stuur_auto_antwoord: driver = autoreply - file = DIR/aux-fixed/TESTNUM.antwoord-${local_part} + file = DIR/aux-fixed/TESTNUM.antwoord-${bless:$local_part} file_expand from = "${lookup{$local_part} lsearch \ {DIR/aux-fixed/TESTNUM.beantwoorders} {$value}}" -- 2.30.2