summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2018-03-30 22:54:55 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2018-03-30 23:58:45 +0100
commitd3e58fcb87faf7131a2712fcfaef200ffd191f05 (patch)
tree25ea019f0211336a3c105c01c29e7951ec5bf41f
parent86ba355d5fa60c3e9c444b440e91d233fdda0a27 (diff)
Avoid doing logging in signal-handlers. Bug 1007
-rw-r--r--doc/doc-docbook/spec.xfpt7
-rw-r--r--doc/doc-txt/ChangeLog9
-rw-r--r--src/src/config.h.defaults1
-rw-r--r--src/src/expand.c2
-rw-r--r--src/src/functions.h4
-rw-r--r--src/src/globals.c6
-rw-r--r--src/src/globals.h6
-rw-r--r--src/src/readconf.c2
-rw-r--r--src/src/receive.c201
-rw-r--r--src/src/smtp_in.c82
-rw-r--r--src/src/spool_in.c4
-rw-r--r--src/src/spool_out.c6
-rw-r--r--src/src/tls-gnu.c20
-rw-r--r--src/src/tls-openssl.c11
-rw-r--r--test/confs/00011
-rw-r--r--test/stderr/04652
-rw-r--r--test/stderr/04712
-rw-r--r--test/stderr/04872
-rw-r--r--test/stderr/048916
-rw-r--r--test/stderr/05752
-rw-r--r--test/stderr/26002
-rw-r--r--test/stderr/26102
-rw-r--r--test/stderr/26202
-rw-r--r--test/stderr/50042
-rw-r--r--test/stderr/50058
-rw-r--r--test/stderr/50062
-rw-r--r--test/stdout/05742
27 files changed, 246 insertions, 160 deletions
diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 8e78c7bad..cf2be5654 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -32692,10 +32692,15 @@ code. The incident is logged on the main and reject logs.
.section "Building Exim to use a local scan function" "SECID207"
.cindex "&[local_scan()]& function" "building Exim to use"
To make use of the local scan function feature, you must tell Exim where your
-function is before building Exim, by setting LOCAL_SCAN_SOURCE in your
+function is before building Exim, by setting
+.new
+both HAVE_LOCAL_SCAN and
+.wen
+LOCAL_SCAN_SOURCE in your
&_Local/Makefile_&. A recommended place to put it is in the &_Local_&
directory, so you might set
.code
+HAVE_LOCAL_SCAN=yes
LOCAL_SCAN_SOURCE=Local/local_scan.c
.endd
for example. The function must be called &[local_scan()]&. It is called by
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index ef62b2d07..af186d2e3 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -5,6 +5,15 @@ affect Exim's operation, with an unchanged configuration file. For new
options, and new features, see the NewStuff file next to this ChangeLog.
+Exim 4.next
+----------
+
+JH/01 Remove code calling the customisable local_scan function, unless a new
+ definition "HAVE_LOCAL_SCAN=yes" is present in the Local/Makefile.
+
+JH/02 Bug 1007: Avoid doing logging from signal-handlers, as that can result in
+ non-signal-safe funxtions being used.
+
Since Exim version 4.90
-----------------------
diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults
index ce478d558..0f348fa40 100644
--- a/src/src/config.h.defaults
+++ b/src/src/config.h.defaults
@@ -71,6 +71,7 @@ Do not put spaces between # and the 'define'.
#define FIXED_NEVER_USERS "root"
#define HAVE_CRYPT16
+#define HAVE_LOCAL_SCAN
#define HAVE_SA_LEN
#define HEADERS_CHARSET "ISO-8859-1"
#define HEADER_ADD_BUFFER_SIZE (8192 * 4)
diff --git a/src/src/expand.c b/src/src/expand.c
index 6f67ab138..10fadfd89 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -563,7 +563,9 @@ static var_entry var_table[] = {
{ "local_part_data", vtype_stringptr, &deliver_localpart_data },
{ "local_part_prefix", vtype_stringptr, &deliver_localpart_prefix },
{ "local_part_suffix", vtype_stringptr, &deliver_localpart_suffix },
+#ifdef HAVE_LOCAL_SCAN
{ "local_scan_data", vtype_stringptr, &local_scan_data },
+#endif
{ "local_user_gid", vtype_gid, &local_user_gid },
{ "local_user_uid", vtype_uid, &local_user_uid },
{ "localhost_number", vtype_int, &host_number },
diff --git a/src/src/functions.h b/src/src/functions.h
index 0b261177c..496bd9985 100644
--- a/src/src/functions.h
+++ b/src/src/functions.h
@@ -423,6 +423,10 @@ extern int sieve_interpret(uschar *, int, uschar *, uschar *, uschar *,
extern void sigalrm_handler(int);
extern BOOL smtp_buffered(void);
extern void smtp_closedown(uschar *);
+extern void smtp_command_timeout_exit(void);
+extern void smtp_command_sigterm_exit(void);
+extern void smtp_data_timeout_exit(void);
+extern void smtp_data_sigint_exit(void);
extern uschar *smtp_cmd_hist(void);
extern int smtp_connect(host_item *, int, uschar *, int,
transport_instance *);
diff --git a/src/src/globals.c b/src/src/globals.c
index e8faa9c02..705b1dd0c 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -770,6 +770,10 @@ uschar *gecos_name = NULL;
uschar *gecos_pattern = NULL;
rewrite_rule *global_rewrite_rules = NULL;
+volatile sig_atomic_t had_command_timeout = 0;
+volatile sig_atomic_t had_command_sigterm = 0;
+volatile sig_atomic_t had_data_timeout = 0;
+volatile sig_atomic_t had_data_sigint = 0;
uschar *headers_charset = US HEADERS_CHARSET;
int header_insert_maxlen = 64 * 1024;
header_line *header_last = NULL;
@@ -853,8 +857,10 @@ uschar *local_interfaces = US"<; ::0 ; 0.0.0.0";
uschar *local_interfaces = US"0.0.0.0";
#endif
+#ifdef HAVE_LOCAL_SCAN
uschar *local_scan_data = NULL;
int local_scan_timeout = 5*60;
+#endif
BOOL local_sender_retain = FALSE;
gid_t local_user_gid = (gid_t)(-1);
uid_t local_user_uid = (uid_t)(-1);
diff --git a/src/src/globals.h b/src/src/globals.h
index 63e0e424c..dbc706037 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -492,6 +492,10 @@ extern uschar *gecos_name; /* To be expanded when pattern matches */
extern uschar *gecos_pattern; /* Pattern to match */
extern rewrite_rule *global_rewrite_rules; /* Chain of rewriting rules */
+extern volatile sig_atomic_t had_command_timeout; /* Alarm sighandler called */
+extern volatile sig_atomic_t had_command_sigterm; /* TERM sighandler called */
+extern volatile sig_atomic_t had_data_timeout; /* Alarm sighandler called */
+extern volatile sig_atomic_t had_data_sigint; /* TERM/INT sighandler called */
extern int header_insert_maxlen; /* Max for inserting headers */
extern int header_maxsize; /* Max total length for header */
extern int header_line_maxsize; /* Max for an individual line */
@@ -544,10 +548,12 @@ extern BOOL local_from_check; /* For adding Sender: (global value) */
extern uschar *local_from_prefix; /* Permitted prefixes */
extern uschar *local_from_suffix; /* Permitted suffixes */
extern uschar *local_interfaces; /* For forcing specific interfaces */
+#ifdef HAVE_LOCAL_SCAN
extern uschar *local_scan_data; /* Text returned by local_scan() */
extern optionlist local_scan_options[];/* Option list for local_scan() */
extern int local_scan_options_count; /* Size of the list */
extern int local_scan_timeout; /* Timeout for local_scan() */
+#endif
extern BOOL local_sender_retain; /* Retain Sender: (with no From: check) */
extern gid_t local_user_gid; /* As it says; may be set in routers */
extern uid_t local_user_uid; /* As it says; may be set in routers */
diff --git a/src/src/readconf.c b/src/src/readconf.c
index cbbef6efd..658719dff 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -195,7 +195,9 @@ static optionlist optionlist_config[] = {
{ "local_from_prefix", opt_stringptr, &local_from_prefix },
{ "local_from_suffix", opt_stringptr, &local_from_suffix },
{ "local_interfaces", opt_stringptr, &local_interfaces },
+#ifdef HAVE_LOCAL_SCAN
{ "local_scan_timeout", opt_time, &local_scan_timeout },
+#endif
{ "local_sender_retain", opt_bool, &local_sender_retain },
{ "localhost_number", opt_stringptr, &host_number_string },
{ "log_file_path", opt_stringptr, &log_file_path },
diff --git a/src/src/receive.c b/src/src/receive.c
index 6a534dc87..39a0ed577 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -8,6 +8,7 @@
/* Code for receiving a message and setting up spool files. */
#include "exim.h"
+#include <setjmp.h>
#ifdef EXPERIMENTAL_DCC
extern int dcc_ok;
@@ -27,6 +28,12 @@ static uschar *spool_name = US"";
enum CH_STATE {LF_SEEN, MID_LINE, CR_SEEN};
+#ifdef HAVE_LOCAL_SCAN
+jmp_buf local_scan_env; /* error-handling context for local_scan */
+unsigned had_local_scan_crash;
+unsigned had_local_scan_timeout;
+#endif
+
/*************************************************
* Non-SMTP character reading functions *
@@ -40,7 +47,27 @@ changing the pointer variables.) */
int
stdin_getc(unsigned lim)
{
-return getc(stdin);
+int c = getc(stdin);
+
+if (had_data_timeout)
+ {
+ fprintf(stderr, "exim: timed out while reading - message abandoned\n");
+ log_write(L_lost_incoming_connection,
+ LOG_MAIN, "timed out while reading local message");
+ receive_bomb_out(US"data-timeout", NULL); /* Does not return */
+ }
+if (had_data_sigint)
+ {
+ if (filter_test == FTEST_NONE)
+ {
+ fprintf(stderr, "\nexim: %s received - message abandoned\n",
+ had_data_sigint == SIGTERM ? "SIGTERM" : "SIGINT");
+ log_write(0, LOG_MAIN, "%s received while reading local message",
+ had_data_sigint == SIGTERM ? "SIGTERM" : "SIGINT");
+ }
+ receive_bomb_out(US"signal-exit", NULL); /* Does not return */
+ }
+return c;
}
int
@@ -316,11 +343,13 @@ if (spool_name[0] != '\0')
/* Now close the file if it is open, either as a fd or a stream. */
-if (data_file != NULL)
+if (data_file)
{
(void)fclose(data_file);
data_file = NULL;
-} else if (data_fd >= 0) {
+ }
+else if (data_fd >= 0)
+ {
(void)close(data_fd);
data_fd = -1;
}
@@ -361,37 +390,29 @@ Returns: nothing
static void
data_timeout_handler(int sig)
{
-uschar *msg = NULL;
-
-sig = sig; /* Keep picky compilers happy */
-
-if (smtp_input)
- {
- msg = US"SMTP incoming data timeout";
- log_write(L_lost_incoming_connection,
- LOG_MAIN, "SMTP data timeout (message abandoned) on connection "
- "from %s F=<%s>",
- (sender_fullhost != NULL)? sender_fullhost : US"local process",
- sender_address);
- }
-else
- {
- fprintf(stderr, "exim: timed out while reading - message abandoned\n");
- log_write(L_lost_incoming_connection,
- LOG_MAIN, "timed out while reading local message");
- }
-
-receive_bomb_out(US"data-timeout", msg); /* Does not return */
+had_data_timeout = sig;
}
+#ifdef HAVE_LOCAL_SCAN
/*************************************************
* local_scan() timeout *
*************************************************/
/* Handler function for timeouts that occur while running a local_scan()
-function.
+function. Posix recommends against calling longjmp() from a signal-handler,
+but the GCC manual says you can so we will, and trust that it's better than
+calling probably non-signal-safe funxtions during logging from within the
+handler, even with other compilers.
+
+See also https://cwe.mitre.org/data/definitions/745.html which also lists
+it as unsafe.
+
+This is all because we have no control over what might be written for a
+local-scan function, so cannot sprinkle had-signal checks after each
+call-site. At least with the default "do-nothing" function we won't
+ever get here.
Argument: the signal number
Returns: nothing
@@ -400,11 +421,8 @@ Returns: nothing
static void
local_scan_timeout_handler(int sig)
{
-sig = sig; /* Keep picky compilers happy */
-log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() function timed out - "
- "message temporarily rejected (size %d)", message_size);
-/* Does not return */
-receive_bomb_out(US"local-scan-timeout", US"local verification problem");
+had_local_scan_timeout = sig;
+siglongjmp(local_scan_env, 1);
}
@@ -423,12 +441,12 @@ Returns: nothing
static void
local_scan_crash_handler(int sig)
{
-log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() function crashed with "
- "signal %d - message temporarily rejected (size %d)", sig, message_size);
-/* Does not return */
-receive_bomb_out(US"local-scan-error", US"local verification problem");
+had_local_scan_crash = sig;
+siglongjmp(local_scan_env, 1);
}
+#endif /*HAVE_LOCAL_SCAN*/
+
/*************************************************
* SIGTERM or SIGINT received *
@@ -444,26 +462,7 @@ Returns: nothing
static void
data_sigterm_sigint_handler(int sig)
{
-uschar *msg = NULL;
-
-if (smtp_input)
- {
- msg = US"Service not available - SIGTERM or SIGINT received";
- log_write(0, LOG_MAIN, "%s closed after %s", smtp_get_connection_info(),
- (sig == SIGTERM)? "SIGTERM" : "SIGINT");
- }
-else
- {
- if (filter_test == FTEST_NONE)
- {
- fprintf(stderr, "\nexim: %s received - message abandoned\n",
- (sig == SIGTERM)? "SIGTERM" : "SIGINT");
- log_write(0, LOG_MAIN, "%s received while reading local message",
- (sig == SIGTERM)? "SIGTERM" : "SIGINT");
- }
- }
-
-receive_bomb_out(US"signal-exit", msg); /* Does not return */
+had_data_sigint = sig;
}
@@ -1678,6 +1677,7 @@ int dmarc_up = 0;
uschar *timestamp;
int tslen;
+
/* Release any open files that might have been cached while preparing to
accept the message - e.g. by verifying addresses - because reading a message
might take a fair bit of real time. */
@@ -1751,7 +1751,9 @@ received_time = message_id_tv;
/* If SMTP input, set the special handler for timeouts. The alarm() calls
happen in the smtp_getc() function when it refills its buffer. */
-if (smtp_input) os_non_restarting_signal(SIGALRM, data_timeout_handler);
+had_data_timeout = 0;
+if (smtp_input)
+ os_non_restarting_signal(SIGALRM, data_timeout_handler);
/* If not SMTP input, timeout happens only if configured, and we just set a
single timeout for the whole message. */
@@ -1764,6 +1766,7 @@ else if (receive_timeout > 0)
/* SIGTERM and SIGINT are caught always. */
+had_data_sigint = 0;
signal(SIGTERM, data_sigterm_sigint_handler);
signal(SIGINT, data_sigterm_sigint_handler);
@@ -3633,47 +3636,70 @@ dcc_ok = 0;
#endif
+#ifdef HAVE_LOCAL_SCAN
/* The final check on the message is to run the scan_local() function. The
version supplied with Exim always accepts, but this is a hook for sysadmins to
supply their own checking code. The local_scan() function is run even when all
the recipients have been discarded. */
-/*XXS could we avoid this for the standard case, given that few people will use it? */
lseek(data_fd, (long int)SPOOL_DATA_START_OFFSET, SEEK_SET);
/* Arrange to catch crashes in local_scan(), so that the -D file gets
deleted, and the incident gets logged. */
-os_non_restarting_signal(SIGSEGV, local_scan_crash_handler);
-os_non_restarting_signal(SIGFPE, local_scan_crash_handler);
-os_non_restarting_signal(SIGILL, local_scan_crash_handler);
-os_non_restarting_signal(SIGBUS, local_scan_crash_handler);
-
-DEBUG(D_receive) debug_printf("calling local_scan(); timeout=%d\n",
- local_scan_timeout);
-local_scan_data = NULL;
-
-os_non_restarting_signal(SIGALRM, local_scan_timeout_handler);
-if (local_scan_timeout > 0) alarm(local_scan_timeout);
-rc = local_scan(data_fd, &local_scan_data);
-alarm(0);
-os_non_restarting_signal(SIGALRM, sigalrm_handler);
-
-enable_dollar_recipients = FALSE;
-
-store_pool = POOL_MAIN; /* In case changed */
-DEBUG(D_receive) debug_printf("local_scan() returned %d %s\n", rc,
- local_scan_data);
-
-os_non_restarting_signal(SIGSEGV, SIG_DFL);
-os_non_restarting_signal(SIGFPE, SIG_DFL);
-os_non_restarting_signal(SIGILL, SIG_DFL);
-os_non_restarting_signal(SIGBUS, SIG_DFL);
+if (sigsetjmp(local_scan_env, 1) == 0)
+ {
+ had_local_scan_crash = 0;
+ os_non_restarting_signal(SIGSEGV, local_scan_crash_handler);
+ os_non_restarting_signal(SIGFPE, local_scan_crash_handler);
+ os_non_restarting_signal(SIGILL, local_scan_crash_handler);
+ os_non_restarting_signal(SIGBUS, local_scan_crash_handler);
+
+ DEBUG(D_receive) debug_printf("calling local_scan(); timeout=%d\n",
+ local_scan_timeout);
+ local_scan_data = NULL;
+
+ had_local_scan_timeout = 0;
+ os_non_restarting_signal(SIGALRM, local_scan_timeout_handler);
+ if (local_scan_timeout > 0) alarm(local_scan_timeout);
+ rc = local_scan(data_fd, &local_scan_data);
+ alarm(0);
+ os_non_restarting_signal(SIGALRM, sigalrm_handler);
+
+ enable_dollar_recipients = FALSE;
+
+ store_pool = POOL_MAIN; /* In case changed */
+ DEBUG(D_receive) debug_printf("local_scan() returned %d %s\n", rc,
+ local_scan_data);
+
+ os_non_restarting_signal(SIGSEGV, SIG_DFL);
+ os_non_restarting_signal(SIGFPE, SIG_DFL);
+ os_non_restarting_signal(SIGILL, SIG_DFL);
+ os_non_restarting_signal(SIGBUS, SIG_DFL);
+ }
+else
+ {
+ if (had_local_scan_crash)
+ {
+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() function crashed with "
+ "signal %d - message temporarily rejected (size %d)",
+ had_local_scan_crash, message_size);
+ /* Does not return */
+ receive_bomb_out(US"local-scan-error", US"local verification problem");
+ }
+ if (had_local_scan_timeout)
+ {
+ log_write(0, LOG_MAIN|LOG_REJECT, "local_scan() function timed out - "
+ "message temporarily rejected (size %d)", message_size);
+ /* Does not return */
+ receive_bomb_out(US"local-scan-timeout", US"local verification problem");
+ }
+ }
/* The length check is paranoia against some runaway code, and also because
(for a success return) lines in the spool file are read into big_buffer. */
-if (local_scan_data != NULL)
+if (local_scan_data)
{
int len = Ustrlen(local_scan_data);
if (len > LOCAL_SCAN_MAX_RETURN) len = LOCAL_SCAN_MAX_RETURN;
@@ -3705,7 +3731,7 @@ the spool file gets corrupted. Ensure that all recipients are qualified. */
if (rc == LOCAL_SCAN_ACCEPT)
{
- if (local_scan_data != NULL)
+ if (local_scan_data)
{
uschar *s;
for (s = local_scan_data; *s != 0; s++) if (*s == '\n') *s = ' ';
@@ -3798,6 +3824,7 @@ the message to be abandoned. */
signal(SIGTERM, SIG_IGN);
signal(SIGINT, SIG_IGN);
+#endif /* HAVE_LOCAL_SCAN */
/* Ensure the first time flag is set in the newly-received message. */
@@ -4328,9 +4355,11 @@ starting. */
if (blackholed_by)
{
- const uschar *detail = local_scan_data
- ? string_printing(local_scan_data)
- : string_sprintf("(%s discarded recipients)", blackholed_by);
+ const uschar *detail =
+#ifdef HAVE_LOCAL_SCAN
+ local_scan_data ? string_printing(local_scan_data) :
+#endif
+ string_sprintf("(%s discarded recipients)", blackholed_by);
log_write(0, LOG_MAIN, "=> blackhole %s%s", detail, blackhole_log_msg);
log_write(0, LOG_MAIN, "Completed");
message_id[0] = 0;
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 6cac7d2e2..823fcd27d 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -427,6 +427,53 @@ log_write(L_smtp_incomplete_transaction, LOG_MAIN|LOG_SENDER|LOG_RECIPIENTS,
+void
+smtp_command_timeout_exit(void)
+{
+log_write(L_lost_incoming_connection,
+ LOG_MAIN, "SMTP command timeout on%s connection from %s",
+ tls_in.active >= 0 ? " TLS" : "", host_and_ident(FALSE));
+if (smtp_batched_input)
+ moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */
+smtp_notquit_exit(US"command-timeout", US"421",
+ US"%s: SMTP command timeout - closing connection",
+ smtp_active_hostname);
+exim_exit(EXIT_FAILURE, US"receiving");
+}
+
+void
+smtp_command_sigterm_exit(void)
+{
+log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info());
+if (smtp_batched_input)
+ moan_smtp_batch(NULL, "421 SIGTERM received"); /* Does not return */
+smtp_notquit_exit(US"signal-exit", US"421",
+ US"%s: Service not available - closing connection", smtp_active_hostname);
+exim_exit(EXIT_FAILURE, US"receiving");
+}
+
+void
+smtp_data_timeout_exit(void)
+{
+log_write(L_lost_incoming_connection,
+ LOG_MAIN, "SMTP data timeout (message abandoned) on connection from %s F=<%s>",
+ sender_fullhost ? sender_fullhost : US"local process", sender_address);
+receive_bomb_out(US"data-timeout", US"SMTP incoming data timeout");
+/* Does not return */
+}
+
+void
+smtp_data_sigint_exit(void)
+{
+log_write(0, LOG_MAIN, "%s closed after %s",
+ smtp_get_connection_info(), had_data_sigint == SIGTERM ? "SIGTERM":"SIGINT");
+receive_bomb_out(US"signal-exit",
+ US"Service not available - SIGTERM or SIGINT received");
+/* Does not return */
+}
+
+
+
/* Refill the buffer, and notify DKIM verification code.
Return false for error or EOF.
*/
@@ -443,18 +490,28 @@ if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
rc = read(fileno(smtp_in), smtp_inbuffer, MIN(IN_BUFFER_SIZE, lim));
save_errno = errno;
-alarm(0);
+if (smtp_receive_timeout > 0) alarm(0);
if (rc <= 0)
{
/* Must put the error text in fixed store, because this might be during
header reading, where it releases unused store above the header. */
if (rc < 0)
{
+ if (had_command_timeout) /* set by signal handler */
+ smtp_command_timeout_exit(); /* does not return */
+ if (had_command_sigterm)
+ smtp_command_sigterm_exit();
+ if (had_data_timeout)
+ smtp_data_timeout_exit();
+ if (had_data_sigint)
+ smtp_data_sigint_exit();
+
smtp_had_error = save_errno;
smtp_read_error = string_copy_malloc(
string_sprintf(" (error: %s)", strerror(save_errno)));
}
- else smtp_had_eof = 1;
+ else
+ smtp_had_eof = 1;
return FALSE;
}
#ifndef DISABLE_DKIM
@@ -916,16 +973,7 @@ Returns: nothing
static void
command_timeout_handler(int sig)
{
-sig = sig; /* Keep picky compilers happy */
-log_write(L_lost_incoming_connection,
- LOG_MAIN, "SMTP command timeout on%s connection from %s",
- (tls_in.active >= 0)? " TLS" : "",
- host_and_ident(FALSE));
-if (smtp_batched_input)
- moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */
-smtp_notquit_exit(US"command-timeout", US"421",
- US"%s: SMTP command timeout - closing connection", smtp_active_hostname);
-exim_exit(EXIT_FAILURE, US"receiving");
+had_command_timeout = sig;
}
@@ -943,13 +991,7 @@ Returns: nothing
static void
command_sigterm_handler(int sig)
{
-sig = sig; /* Keep picky compilers happy */
-log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info());
-if (smtp_batched_input)
- moan_smtp_batch(NULL, "421 SIGTERM received"); /* Does not return */
-smtp_notquit_exit(US"signal-exit", US"421",
- US"%s: Service not available - closing connection", smtp_active_hostname);
-exim_exit(EXIT_FAILURE, US"receiving");
+had_command_sigterm = sig;
}
@@ -1509,6 +1551,7 @@ int ptr = 0;
smtp_cmd_list *p;
BOOL hadnull = FALSE;
+had_command_timeout = 0;
os_non_restarting_signal(SIGALRM, command_timeout_handler);
while ((c = (receive_getc)(buffer_lim)) != '\n' && c != EOF)
@@ -3801,6 +3844,7 @@ cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = TRUE;
/* Set the local signal handler for SIGTERM - it tries to end off tidily */
+had_command_sigterm = 0;
os_non_restarting_signal(SIGTERM, command_sigterm_handler);
/* Batched SMTP is handled in a different function. */
diff --git a/src/src/spool_in.c b/src/src/spool_in.c
index e34b54171..0a281f432 100644
--- a/src/src/spool_in.c
+++ b/src/src/spool_in.c
@@ -231,7 +231,9 @@ host_lookup_failed = FALSE;
interface_address = NULL;
interface_port = 0;
local_error_message = FALSE;
+#ifdef HAVE_LOCAL_SCAN
local_scan_data = NULL;
+#endif
max_received_linelength = 0;
message_linecount = 0;
received_protocol = NULL;
@@ -589,8 +591,10 @@ for (;;)
sender_local = TRUE;
else if (Ustrcmp(big_buffer, "-localerror") == 0)
local_error_message = TRUE;
+#ifdef HAVE_LOCAL_SCAN
else if (Ustrncmp(p, "ocal_scan ", 10) == 0)
local_scan_data = string_copy(big_buffer + 12);
+#endif
break;
case 'm':
diff --git a/src/src/spool_out.c b/src/src/spool_out.c
index 8bebf1074..a6ab3754e 100644
--- a/src/src/spool_out.c
+++ b/src/src/spool_out.c
@@ -221,7 +221,9 @@ if (host_lookup_deferred) fprintf(f, "-host_lookup_deferred\n");
if (host_lookup_failed) fprintf(f, "-host_lookup_failed\n");
if (sender_local) fprintf(f, "-local\n");
if (local_error_message) fprintf(f, "-localerror\n");
-if (local_scan_data != NULL) fprintf(f, "-local_scan %s\n", local_scan_data);
+#ifdef HAVE_LOCAL_SCAN
+if (local_scan_data) fprintf(f, "-local_scan %s\n", local_scan_data);
+#endif
#ifdef WITH_CONTENT_SCAN
if (spam_bar) fprintf(f,"-spam_bar %s\n", spam_bar);
if (spam_score) fprintf(f,"-spam_score %s\n", spam_score);
@@ -231,7 +233,7 @@ if (deliver_manual_thaw) fprintf(f, "-manual_thaw\n");
if (sender_set_untrusted) fprintf(f, "-sender_set_untrusted\n");
#ifdef EXPERIMENTAL_BRIGHTMAIL
-if (bmi_verdicts != NULL) fprintf(f, "-bmi_verdicts %s\n", bmi_verdicts);
+if (bmi_verdicts) fprintf(f, "-bmi_verdicts %s\n", bmi_verdicts);
#endif
#ifdef SUPPORT_TLS
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index d73188277..35816cd60 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -2511,12 +2511,20 @@ sigalrm_seen = FALSE;
if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
inbytes = gnutls_record_recv(state->session, state->xfer_buffer,
MIN(ssl_xfer_buffer_size, lim));
-alarm(0);
-
-/* Timeouts do not get this far; see command_timeout_handler().
- A zero-byte return appears to mean that the TLS session has been
- closed down, not that the socket itself has been closed down. Revert to
- non-TLS handling. */
+if (smtp_receive_timeout > 0) alarm(0);
+
+if (had_command_timeout) /* set by signal handler */
+ smtp_command_timeout_exit(); /* does not return */
+if (had_command_sigterm)
+ smtp_command_sigterm_exit();
+if (had_data_timeout)
+ smtp_data_timeout_exit();
+if (had_data_sigint)
+ smtp_data_sigint_exit();
+
+/* Timeouts do not get this far. A zero-byte return appears to mean that the
+TLS session has been closed down, not that the socket itself has been closed
+down. Revert to non-TLS handling. */
if (sigalrm_seen)
{
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index c142bd059..5e3edbb40 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -2469,7 +2469,16 @@ if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout);
inbytes = SSL_read(server_ssl, CS ssl_xfer_buffer,
MIN(ssl_xfer_buffer_size, lim));
error = SSL_get_error(server_ssl, inbytes);
-alarm(0);
+if (smtp_receive_timeout > 0) alarm(0);
+
+if (had_command_timeout) /* set by signal handler */
+ smtp_command_timeout_exit(); /* does not return */
+if (had_command_sigterm)
+ smtp_command_sigterm_exit();
+if (had_data_timeout)
+ smtp_data_timeout_exit();
+if (had_data_sigint)
+ smtp_data_sigint_exit();
/* SSL_ERROR_ZERO_RETURN appears to mean that the SSL session has been
closed down, not that the socket itself has been closed down. Revert to
diff --git a/test/confs/0001 b/test/confs/0001
index 471c8f817..fc2ae3eaf 100644
--- a/test/confs/0001
+++ b/test/confs/0001
@@ -95,7 +95,6 @@ no_local_from_check
local_from_prefix = *-
local_from_suffix = =*
local_interfaces =
-local_scan_timeout = 10s
local_sender_retain
localhost_number = "3 "
log_selector = \
diff --git a/test/stderr/0465 b/test/stderr/0465
index 52dcbf3d5..68bba6ee1 100644
--- a/test/stderr/0465
+++ b/test/stderr/0465
@@ -84,8 +84,6 @@ processing "accept"
check verify = header_syntax
accept: condition test succeeded in ACL "check_data"
end of ACL "check_data": ACCEPT
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/0471 b/test/stderr/0471
index fb5c986dd..3a5aa1c7b 100644
--- a/test/stderr/0471
+++ b/test/stderr/0471
@@ -25375,8 +25375,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmaX-0005vi-00
for r1@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/0487 b/test/stderr/0487
index ad2daa2f8..9064bef64 100644
--- a/test/stderr/0487
+++ b/test/stderr/0487
@@ -59,8 +59,6 @@ P Received: from CALLER (helo=x.y)
(envelope-from <x@y>)
id 10HmaX-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/0489 b/test/stderr/0489
index e1b955b4f..2834338ff 100644
--- a/test/stderr/0489
+++ b/test/stderr/0489
@@ -23,8 +23,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmaX-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmaX-0005vi-00-H
Size of headers = sss
@@ -57,8 +55,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmaY-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmaY-0005vi-00-H
Size of headers = sss
@@ -90,8 +86,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmaZ-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmaZ-0005vi-00-H
Size of headers = sss
@@ -123,8 +117,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmbA-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmbA-0005vi-00-H
Size of headers = sss
@@ -156,8 +148,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmbB-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmbB-0005vi-00-H
Size of headers = sss
@@ -189,8 +179,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmbC-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmbC-0005vi-00-H
Size of headers = sss
@@ -222,8 +210,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmbD-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmbD-0005vi-00-H
Size of headers = sss
@@ -255,8 +241,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmbE-0005vi-00
for X@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
Renaming spool header file: TESTSUITE/spool//input//10HmbE-0005vi-00-H
Size of headers = sss
diff --git a/test/stderr/0575 b/test/stderr/0575
index 73467881a..480cef4b8 100644
--- a/test/stderr/0575
+++ b/test/stderr/0575
@@ -48,8 +48,6 @@ P Received: from [V4NET.0.0.0]
(envelope-from <x@y>)
id 10HmaX-0005vi-00
for x@y; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
LOG: MAIN
<= x@y H=[V4NET.0.0.0] P=smtp S=sss
SMTP>> 250 OK id=10HmaX-0005vi-00
diff --git a/test/stderr/2600 b/test/stderr/2600
index 700e78589..47ee39a4a 100644
--- a/test/stderr/2600
+++ b/test/stderr/2600
@@ -319,8 +319,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmaX-0005vi-00
for userx@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/2610 b/test/stderr/2610
index 0a16c1109..58b508f3c 100644
--- a/test/stderr/2610
+++ b/test/stderr/2610
@@ -312,8 +312,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmaX-0005vi-00
for ph10@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/2620 b/test/stderr/2620
index 32e83b03f..29a4f629c 100644
--- a/test/stderr/2620
+++ b/test/stderr/2620
@@ -330,8 +330,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@myhost.test.ex>)
id 10HmaX-0005vi-00
for CALLER@myhost.test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/5004 b/test/stderr/5004
index 95ccd88cc..21fad61cc 100644
--- a/test/stderr/5004
+++ b/test/stderr/5004
@@ -35,8 +35,6 @@ P Received: from CALLER by mail.test.ex with local (Exim x.yz)
(envelope-from <CALLER@test.ex>)
id 10HmaX-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/5005 b/test/stderr/5005
index 463d71c3c..76d2851dd 100644
--- a/test/stderr/5005
+++ b/test/stderr/5005
@@ -33,8 +33,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@test.ex>)
id 10HmaX-0005vi-00
for nofile@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
@@ -223,8 +221,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@test.ex>)
id 10HmaY-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
@@ -413,8 +409,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@test.ex>)
id 10HmaZ-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
@@ -612,8 +606,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@test.ex>)
id 10HmbA-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stderr/5006 b/test/stderr/5006
index 2a0b9d10f..8e120f627 100644
--- a/test/stderr/5006
+++ b/test/stderr/5006
@@ -33,8 +33,6 @@ P Received: from CALLER by myhost.test.ex with local (Exim x.yz)
(envelope-from <CALLER@test.ex>)
id 10HmaX-0005vi-00
for userx@test.ex; Tue, 2 Mar 1999 09:44:33 +0000
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
Writing spool header file: TESTSUITE/spool//input//hdr.pppp
DSN: Write SPOOL :-dsn_envid NULL
DSN: Write SPOOL :-dsn_ret 0
diff --git a/test/stdout/0574 b/test/stdout/0574
index a9d9cd9d2..36d612eae 100644
--- a/test/stdout/0574
+++ b/test/stdout/0574
@@ -33,8 +33,6 @@ Connecting to 127.0.0.1 port 1225 ... connected
End of script
accept: condition test succeeded in ACL "chk_data"
end of ACL "chk_data": ACCEPT
-calling local_scan(); timeout=300
-local_scan() returned 0 NULL
┌considering: ${tod_full}
├──expanding: ${tod_full}
└─────result: Tue, 2 Mar 1999 09:44:33 +0000