summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2020-07-23 16:32:29 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2020-07-24 15:00:57 +0100
commitafaf5a50b05810d75c1f7ae9d1cd83697815a997 (patch)
tree42207793085d579da6e2f61654085bed28851637 /src
parentfd3b39c16b3040cc7f12dbc3afdfc4e9e6e0807b (diff)
OpenSSL: in server, detect TCP RST from client after QUIT under SSL,
and log different message (under new log_selector)
Diffstat (limited to 'src')
-rw-r--r--src/src/acl.c6
-rw-r--r--src/src/globals.c6
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/macros.h2
-rw-r--r--src/src/smtp_in.c18
-rw-r--r--src/src/tls-openssl.c15
6 files changed, 32 insertions, 16 deletions
diff --git a/src/src/acl.c b/src/src/acl.c
index 185a39d5d..934112c31 100644
--- a/src/src/acl.c
+++ b/src/src/acl.c
@@ -1944,7 +1944,8 @@ if (quota)
{
if (!*user_msgptr && *log_msgptr)
*user_msgptr = string_sprintf("Rejected after %s: %s",
- smtp_names[smtp_connection_had[smtp_ch_index-1]], *log_msgptr);
+ smtp_names[smtp_connection_had[SMTP_HBUFF_PREV(smtp_ch_index)]],
+ *log_msgptr);
if (rc == DEFER) f.acl_temp_details = TRUE;
}
}
@@ -4542,7 +4543,8 @@ switch (where)
/* Drop cutthrough conns, and drop heldopen verify conns if
the previous was not DATA */
{
- uschar prev = smtp_connection_had[smtp_ch_index-2];
+ uschar prev =
+ smtp_connection_had[SMTP_HBUFF_PREV(SMTP_HBUFF_PREV(smtp_ch_index))];
BOOL dropverify = !(prev == SCH_DATA || prev == SCH_BDAT);
cancel_cutthrough_connection(dropverify, US"quit or conndrop");
diff --git a/src/src/globals.c b/src/src/globals.c
index 654c39b4f..a5df06d98 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -307,6 +307,7 @@ struct global_flags f =
#endif
.smtp_in_pipelining_advertised = FALSE,
.smtp_in_pipelining_used = FALSE,
+ .smtp_in_quit = FALSE,
.spool_file_wireformat = FALSE,
.submission_mode = FALSE,
.suppress_local_fixups = FALSE,
@@ -1073,6 +1074,7 @@ bit_table log_options[] = { /* must be in alphabetical order,
BIT_TABLE(L, outgoing_port),
BIT_TABLE(L, pid),
BIT_TABLE(L, pipelining),
+ BIT_TABLE(L, protocol_detail),
#if defined(SUPPORT_PROXY) || defined(SUPPORT_SOCKS)
BIT_TABLE(L, proxy),
#endif
@@ -1464,6 +1466,8 @@ uschar *smtp_etrn_command = NULL;
int smtp_max_synprot_errors= 3;
int smtp_max_unknown_commands = 3;
uschar *smtp_notquit_reason = NULL;
+unsigned smtp_peer_options = 0;
+unsigned smtp_peer_options_wrap= 0;
uschar *smtp_ratelimit_hosts = NULL;
uschar *smtp_ratelimit_mail = NULL;
uschar *smtp_ratelimit_rcpt = NULL;
@@ -1479,8 +1483,6 @@ int smtp_rlr_base = 0;
double smtp_rlr_factor = 0.0;
int smtp_rlr_limit = 0;
int smtp_rlr_threshold = INT_MAX;
-unsigned smtp_peer_options = 0;
-unsigned smtp_peer_options_wrap= 0;
#ifdef SUPPORT_I18N
uschar *smtputf8_advertise_hosts = US"*"; /* overridden under test-harness */
#endif
diff --git a/src/src/globals.h b/src/src/globals.h
index 0c85c1150..ea326959d 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -269,6 +269,7 @@ extern struct global_flags {
#endif
BOOL smtp_in_pipelining_advertised :1; /* server advertised PIPELINING */
BOOL smtp_in_pipelining_used :1; /* server noted client using PIPELINING */
+ BOOL smtp_in_quit :1; /* server noted QUIT command */
BOOL spool_file_wireformat :1; /* current -D file has CRLF rather than NL */
BOOL submission_mode :1; /* Can be forced from ACL */
BOOL suppress_local_fixups :1; /* Can be forced from ACL */
diff --git a/src/src/macros.h b/src/src/macros.h
index b5221c7ec..4c5279f0a 100644
--- a/src/src/macros.h
+++ b/src/src/macros.h
@@ -148,6 +148,7 @@ enough to hold all the headers from a normal kind of message. */
/* The size of the circular buffer that remembers recent SMTP commands */
#define SMTP_HBUFF_SIZE 20
+#define SMTP_HBUFF_PREV(n) ((n) ? (n)-1 : SMTP_HBUFF_SIZE-1)
/* The initial size of a big buffer for use in various places. It gets put
into big_buffer_size and in some circumstances increased. It should be at least
@@ -480,6 +481,7 @@ enum logbit {
Li_outgoing_port,
Li_pid,
Li_pipelining,
+ Li_protocol_detail,
Li_proxy,
Li_queue_time,
Li_queue_time_overall,
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index ef3964f5c..3325d54c6 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -1733,6 +1733,7 @@ for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED))
return;
case QUIT_CMD:
+ f.smtp_in_quit = TRUE;
smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
mac_smtp_fflush();
return;
@@ -2349,8 +2350,9 @@ while (done <= 0)
break;
- case EOF_CMD:
case QUIT_CMD:
+ f.smtp_in_quit = TRUE;
+ case EOF_CMD:
done = 2;
break;
@@ -3835,14 +3837,13 @@ static void
smtp_quit_handler(uschar ** user_msgp, uschar ** log_msgp)
{
HAD(SCH_QUIT);
+f.smtp_in_quit = TRUE;
incomplete_transaction_log(US"QUIT");
-if (acl_smtp_quit)
- {
- int rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, user_msgp, log_msgp);
- if (rc == ERROR)
+if ( acl_smtp_quit
+ && acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, user_msgp, log_msgp)
+ == ERROR)
log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s",
*log_msgp);
- }
#ifdef TCP_CORK
(void) setsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_CORK, US &on, sizeof(on));
@@ -5284,10 +5285,10 @@ while (done <= 0)
}
if (f.smtp_in_pipelining_advertised && last_was_rcpt)
smtp_printf("503 Valid RCPT command must precede %s\r\n", FALSE,
- smtp_names[smtp_connection_had[smtp_ch_index-1]]);
+ smtp_names[smtp_connection_had[SMTP_HBUFF_PREV(smtp_ch_index)]]);
else
done = synprot_error(L_smtp_protocol_error, 503, NULL,
- smtp_connection_had[smtp_ch_index-1] == SCH_DATA
+ smtp_connection_had[SMTP_HBUFF_PREV(smtp_ch_index)] == SCH_DATA
? US"valid RCPT command must precede DATA"
: US"valid RCPT command must precede BDAT");
@@ -5551,6 +5552,7 @@ while (done <= 0)
some sense is perhaps "right". */
case QUIT_CMD:
+ f.smtp_in_quit = TRUE;
user_msg = NULL;
if ( acl_smtp_quit
&& ((rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, &user_msg,
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index 50384cbd5..64f60b7e4 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -3673,7 +3673,7 @@ context for the stashed information. */
a store reset there, so use POOL_PERM. */
/* + if CHUNKING, cmds EHLO,MAIL,RCPT(s),BDAT */
-if ((more || corked))
+if (more || corked)
{
if (!len) buff = US &error; /* dummy just so that string_catn is ok */
@@ -3722,9 +3722,16 @@ for (int left = len; left > 0;)
return -1;
case SSL_ERROR_SYSCALL:
- log_write(0, LOG_MAIN, "SSL_write: (from %s) syscall: %s",
- sender_fullhost ? sender_fullhost : US"<unknown>",
- strerror(errno));
+ if (ct_ctx || errno != ECONNRESET || !f.smtp_in_quit)
+ log_write(0, LOG_MAIN, "SSL_write: (from %s) syscall: %s",
+ sender_fullhost ? sender_fullhost : US"<unknown>",
+ strerror(errno));
+ else if (LOGGING(protocol_detail))
+ log_write(0, LOG_MAIN, "[%s] after QUIT, client reset TCP before"
+ " SMTP response and TLS close\n", sender_host_address);
+ else
+ DEBUG(D_tls) debug_printf("[%s] SSL_write: after QUIT,"
+ " client reset TCP before TLS close\n", sender_host_address);
return -1;
default: