ph10 2007/03/21 15:10:40 GMT
Modified files:
exim-doc/doc-txt ChangeLog
exim-src/src smtp_in.c
exim-test/scripts/0000-Basic 0458
exim-test/stdout 0091 0139 0175 0395 0458
Added files:
exim-test/confs 0558
exim-test/log 0558
exim-test/rejectlog 0558
exim-test/scripts/0000-Basic 0558
exim-test/stdout 0558
Log:
Add RCPT error text to unexpected DATA error.
Revision Changes Path
1.497 +8 -0 exim/exim-doc/doc-txt/ChangeLog
1.56 +76 -21 exim/exim-src/src/smtp_in.c
1.1 +26 -0 exim/exim-test/confs/0558 (new)
1.1 +6 -0 exim/exim-test/log/0558 (new)
1.1 +6 -0 exim/exim-test/rejectlog/0558 (new)
1.2 +14 -0 exim/exim-test/scripts/0000-Basic/0458
1.1 +19 -0 exim/exim-test/scripts/0000-Basic/0558 (new)
1.2 +2 -0 exim/exim-test/stdout/0091
1.4 +5 -0 exim/exim-test/stdout/0139
1.2 +4 -0 exim/exim-test/stdout/0175
1.2 +2 -0 exim/exim-test/stdout/0395
1.2 +31 -3 exim/exim-test/stdout/0458
1.1 +30 -0 exim/exim-test/stdout/0558 (new)
Index: ChangeLog
===================================================================
RCS file: /home/cvs/exim/exim-doc/doc-txt/ChangeLog,v
retrieving revision 1.496
retrieving revision 1.497
diff -u -r1.496 -r1.497
--- ChangeLog 14 Mar 2007 12:15:56 -0000 1.496
+++ ChangeLog 21 Mar 2007 15:10:39 -0000 1.497
@@ -1,4 +1,4 @@
-$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.496 2007/03/14 12:15:56 ph10 Exp $
+$Cambridge: exim/exim-doc/doc-txt/ChangeLog,v 1.497 2007/03/21 15:10:39 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -181,6 +181,14 @@
started the daemon, but after a SIGHUP it used the Exim user (because it
calls itself on a restart). I have changed the code so that it now always
uses the Exim user.
+
+PH/41 (Following a suggestion from Tony Finch) If all the RCPT commands in a
+ message are rejected with the same error (e.g. no authentication or bad
+ sender address), and a DATA command is nevertheless sent (as can happen
+ with PIPELINING or a stupid MUA), the error message that was given to the
+ RCPT commands is included in the rejection of the DATA command. This is
+ intended to be helpful for MUAs that show only the final error to their
+ users.
Exim version 4.66
Index: smtp_in.c
===================================================================
RCS file: /home/cvs/exim/exim-src/src/smtp_in.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -r1.55 -r1.56
--- smtp_in.c 20 Feb 2007 15:58:02 -0000 1.55
+++ smtp_in.c 21 Mar 2007 15:10:39 -0000 1.56
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/exim-src/src/smtp_in.c,v 1.55 2007/02/20 15:58:02 ph10 Exp $ */
+/* $Cambridge: exim/exim-src/src/smtp_in.c,v 1.56 2007/03/21 15:10:39 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -120,12 +120,15 @@
static BOOL helo_accept_junk;
static BOOL count_nonmail;
static BOOL pipelining_advertised;
+static BOOL rcpt_smtp_response_same;
+static BOOL rcpt_in_progress;
static int nonmail_command_count;
static int synprot_error_count;
static int unknown_command_count;
static int sync_cmd_limit;
static int smtp_write_error = 0;
+static uschar *rcpt_smtp_response;
static uschar *smtp_data_buffer;
static uschar *smtp_cmd_data;
@@ -368,28 +371,41 @@
}
va_start(ap, format);
+if (!string_vformat(big_buffer, big_buffer_size, format, ap))
+ {
+ log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf()");
+ smtp_closedown(US"Unexpected error");
+ exim_exit(EXIT_FAILURE);
+ }
+va_end(ap);
-/* If in a TLS session we have to format the string, and then write it using a
-TLS function. */
+/* If this is the first output for a (non-batch) RCPT command, see if all RCPTs
+have had the same. Note: this code is also present in smtp_respond(). It would
+be tidier to have it only in one place, but when it was added, it was easier to
+do it that way, so as not to have to mess with the code for the RCPT command,
+which sometimes uses smtp_printf() and sometimes smtp_respond(). */
+
+if (rcpt_in_progress)
+ {
+ if (rcpt_smtp_response == NULL)
+ rcpt_smtp_response = string_copy(big_buffer);
+ else if (rcpt_smtp_response_same &&
+ Ustrcmp(rcpt_smtp_response, big_buffer) != 0)
+ rcpt_smtp_response_same = FALSE;
+ rcpt_in_progress = FALSE;
+ }
+
+/* Now write the string */
#ifdef SUPPORT_TLS
if (tls_active >= 0)
{
- if (!string_vformat(big_buffer, big_buffer_size, format, ap))
- {
- log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf");
- smtp_closedown(US"Unexpected error");
- exim_exit(EXIT_FAILURE);
- }
if (tls_write(big_buffer, Ustrlen(big_buffer)) < 0) smtp_write_error = -1;
}
else
#endif
-/* Otherwise, just use the standard library function. */
-
-if (vfprintf(smtp_out, format, ap) < 0) smtp_write_error = -1;
-va_end(ap);
+if (fprintf(smtp_out, "%s", big_buffer) < 0) smtp_write_error = -1;
}
@@ -961,6 +977,9 @@
message_size = -1;
acl_added_headers = NULL;
queue_only_policy = FALSE;
+rcpt_smtp_response = NULL;
+rcpt_smtp_response_same = TRUE;
+rcpt_in_progress = FALSE;
deliver_freeze = FALSE; /* Can be set by ACL */
freeze_tell = freeze_tell_config; /* Can be set by ACL */
fake_response = OK; /* Can be set by ACL */
@@ -1954,6 +1973,24 @@
esclen = codelen - 4;
}
+/* If this is the first output for a (non-batch) RCPT command, see if all RCPTs
+have had the same. Note: this code is also present in smtp_printf(). It would
+be tidier to have it only in one place, but when it was added, it was easier to
+do it that way, so as not to have to mess with the code for the RCPT command,
+which sometimes uses smtp_printf() and sometimes smtp_respond(). */
+
+if (rcpt_in_progress)
+ {
+ if (rcpt_smtp_response == NULL)
+ rcpt_smtp_response = string_copy(msg);
+ else if (rcpt_smtp_response_same &&
+ Ustrcmp(rcpt_smtp_response, msg) != 0)
+ rcpt_smtp_response_same = FALSE;
+ rcpt_in_progress = FALSE;
+ }
+
+/* Not output the message, splitting it up into multiple lines if necessary. */
+
for (;;)
{
uschar *nl = Ustrchr(msg, '\n');
@@ -2123,6 +2160,9 @@
if (sender_verified_failed != NULL &&
!testflag(sender_verified_failed, af_sverify_told))
{
+ BOOL save_rcpt_in_progress = rcpt_in_progress;
+ rcpt_in_progress = FALSE; /* So as not to treat these as the error */
+
setflag(sender_verified_failed, af_sverify_told);
if (rc != FAIL || (log_extra_selector & LX_sender_verify_fail) != 0)
@@ -2152,6 +2192,8 @@
"Verification failed for <%s>\n%s",
sender_verified_failed->address,
sender_verified_failed->user_message));
+
+ rcpt_in_progress = save_rcpt_in_progress;
}
/* Sort out text for logging */
@@ -3304,17 +3346,15 @@
break;
- /* The RCPT command requires an address as an operand. All we do
- here is to parse it for syntactic correctness. There may be any number
- of RCPT commands, specifying multiple senders. We build them all into
- a data structure that is in argc/argv format. The start/end values
- given by parse_extract_address are not used, as we keep only the
- extracted address. */
+ /* The RCPT command requires an address as an operand. There may be any
+ number of RCPT commands, specifying multiple recipients. We build them all
+ into a data structure. The start/end values given by parse_extract_address
+ are not used, as we keep only the extracted address. */
case RCPT_CMD:
HAD(SCH_RCPT);
rcpt_count++;
- was_rcpt = TRUE;
+ was_rcpt = rcpt_in_progress = TRUE;
/* There must be a sender address; if the sender was rejected and
pipelining was advertised, we assume the client was pipelining, and do not
@@ -3504,14 +3544,29 @@
DATA command.
The example in the pipelining RFC 2920 uses 554, but I use 503 here
- because it is the same whether pipelining is in use or not. */
+ because it is the same whether pipelining is in use or not.
+
+ If all the RCPT commands that precede DATA provoked the same error message
+ (often indicating some kind of system error), it is helpful to include it
+ with the DATA rejection (an idea suggested by Tony Finch). */
case DATA_CMD:
HAD(SCH_DATA);
if (!discarded && recipients_count <= 0)
{
+ if (rcpt_smtp_response_same && rcpt_smtp_response != NULL)
+ {
+ uschar *code = US"503";
+ int len = Ustrlen(rcpt_smtp_response);
+ smtp_respond(code, 3, FALSE, US"All RCPT commands were rejected with "
+ "this error:");
+ /* Responses from smtp_printf() will have \r\n on the end */
+ if (len > 2 && rcpt_smtp_response[len-2] == '\r')
+ rcpt_smtp_response[len-2] = 0;
+ smtp_respond(code, 3, FALSE, rcpt_smtp_response);
+ }
if (pipelining_advertised && last_was_rcpt)
- smtp_printf("503 valid RCPT command must precede DATA\r\n");
+ smtp_printf("503 Valid RCPT command must precede DATA\r\n");
else
done = synprot_error(L_smtp_protocol_error, 503, NULL,
US"valid RCPT command must precede DATA");
Index: 0558
====================================================================
# Exim test configuration 0558
exim_path = EXIM_PATH
host_lookup_order = bydns
primary_hostname = myhost.test.ex
rfc1413_query_timeout = 0s
spool_directory = DIR/spool
log_file_path = DIR/spool/log/%slog
gecos_pattern = ""
gecos_name = CALLER_NAME
# ----- Main settings -----
acl_smtp_rcpt = a1
# ----- ACLs -----
begin acl
a1:
deny message = Special deny message
local_parts = ^special
deny message = Default deny message\non two lines
# End
Index: 0558
====================================================================
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userx@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <usery@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userz@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userx@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <specialusery@???>: Special deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userz@???>: Default deny message
Index: 0558
====================================================================
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userx@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <usery@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userz@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userx@???>: Default deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <specialusery@???>: Special deny message
1999-03-02 09:44:33 U=CALLER F=<> rejected RCPT <userz@???>: Default deny message
Index: 0558
====================================================================
# DATA error after identical RCPT failures
exim -bs
ehlo test.ex
mail from:<>
rcpt to:<userx@???>
rcpt to:<usery@???>
rcpt to:<userz@???>
data
quit
****
exim -bs
ehlo test.ex
mail from:<>
rcpt to:<userx@???>
rcpt to:<specialusery@???>
rcpt to:<userz@???>
data
quit
****
Index: 0458
===================================================================
RCS file: /home/cvs/exim/exim-test/scripts/0000-Basic/0458,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 0458 7 Feb 2006 10:54:33 -0000 1.1
+++ 0458 21 Mar 2007 15:10:40 -0000 1.2
@@ -16,6 +16,8 @@
??? 550
DATA
??? 503
+??? 503
+??? 503
QUIT
??? 221
****
@@ -29,6 +31,8 @@
??? 550
DATA
??? 503
+??? 503
+??? 503
QUIT
??? 221
****
@@ -45,6 +49,8 @@
??? 503
DATA
??? 503
+??? 503
+??? 503
QUIT
??? 221
****
@@ -58,6 +64,8 @@
??? 503
DATA
??? 503
+??? 503
+??? 503
QUIT
??? 221
****
@@ -78,6 +86,8 @@
??? 550
DATA
??? 503
+??? 503
+??? 503
QUIT
??? 221
****
@@ -95,6 +105,8 @@
??? 550
DATA
??? 503
+??? 503
+??? 503
QUIT
??? 221
****
@@ -108,6 +120,8 @@
rcpt to:<userx@???>
??? 503
DATA
+??? 503
+??? 503
??? 503
QUIT
??? 221
Index: 0558
====================================================================
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
250-myhost.test.ex Hello CALLER at test.ex
250-SIZE 52428800
250-PIPELINING
250 HELP
250 OK
550-Default deny message
550 on two lines
550-Default deny message
550 on two lines
550-Default deny message
550 on two lines
503-All RCPT commands were rejected with this error:
503-Default deny message
503-on two lines
503 Valid RCPT command must precede DATA
221 myhost.test.ex closing connection
220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
250-myhost.test.ex Hello CALLER at test.ex
250-SIZE 52428800
250-PIPELINING
250 HELP
250 OK
550-Default deny message
550 on two lines
550 Special deny message
550-Default deny message
550 on two lines
503 Valid RCPT command must precede DATA
221 myhost.test.ex closing connection
Index: 0458
===================================================================
RCS file: /home/cvs/exim/exim-test/stdout/0458,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 0458 7 Feb 2006 10:47:37 -0000 1.1
+++ 0458 21 Mar 2007 15:10:40 -0000 1.2
@@ -18,7 +18,11 @@
<<< 550 Administrative prohibition
>>> DATA
??? 503
-<<< 503 valid RCPT command must precede DATA
+<<< 503-All RCPT commands were rejected with this error:
+??? 503
+<<< 503-Administrative prohibition
+??? 503
+<<< 503 Valid RCPT command must precede DATA
>>> QUIT
??? 221
<<< 221 myhost.test.ex closing connection
@@ -37,6 +41,10 @@
<<< 550 Administrative prohibition
>>> DATA
??? 503
+<<< 503-All RCPT commands were rejected with this error:
+??? 503
+<<< 503-Administrative prohibition
+??? 503
<<< 503 valid RCPT command must precede DATA
>>> QUIT
??? 221
@@ -62,7 +70,11 @@
<<< 503 sender not yet given
>>> DATA
??? 503
-<<< 503 valid RCPT command must precede DATA
+<<< 503-All RCPT commands were rejected with this error:
+??? 503
+<<< 503-503 sender not yet given
+??? 503
+<<< 503 Valid RCPT command must precede DATA
>>> QUIT
??? 221
<<< 221 myhost.test.ex closing connection
@@ -81,6 +93,10 @@
<<< 503 sender not yet given
>>> DATA
??? 503
+<<< 503-All RCPT commands were rejected with this error:
+??? 503
+<<< 503-503 sender not yet given
+??? 503
<<< 503 valid RCPT command must precede DATA
>>> QUIT
??? 221
@@ -112,7 +128,11 @@
<<< 550 Administrative prohibition
>>> DATA
??? 503
-<<< 503 valid RCPT command must precede DATA
+<<< 503-All RCPT commands were rejected with this error:
+??? 503
+<<< 503-Administrative prohibition
+??? 503
+<<< 503 Valid RCPT command must precede DATA
>>> QUIT
??? 221
<<< 221 myhost.test.ex closing connection
@@ -137,6 +157,10 @@
<<< 550 Administrative prohibition
>>> DATA
??? 503
+<<< 503-All RCPT commands were rejected with this error:
+??? 503
+<<< 503-Administrative prohibition
+??? 503
<<< 503 valid RCPT command must precede DATA
>>> QUIT
??? 221
@@ -158,6 +182,10 @@
??? 503
<<< 503 sender not yet given
>>> DATA
+??? 503
+<<< 503-All RCPT commands were rejected with this error:
+??? 503
+<<< 503-503 sender not yet given
??? 503
<<< 503 valid RCPT command must precede DATA
>>> QUIT
Index: 0091
===================================================================
RCS file: /home/cvs/exim/exim-test/stdout/0091,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 0091 7 Feb 2006 10:47:37 -0000 1.1
+++ 0091 21 Mar 2007 15:10:40 -0000 1.2
@@ -19,6 +19,8 @@
550-Verification failed for <junk@???>
550-Unrouteable address
550 Sender verify failed
+503-All RCPT commands were rejected with this error:
+503-Sender verify failed
503 valid RCPT command must precede DATA
500 unrecognized command
221 myhost.test.ex closing connection
Index: 0139
===================================================================
RCS file: /home/cvs/exim/exim-test/stdout/0139,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- 0139 17 Jan 2007 11:17:59 -0000 1.3
+++ 0139 21 Mar 2007 15:10:40 -0000 1.4
@@ -24,6 +24,11 @@
550-This is a very long blacklisting message, continuing for ages and ages and
550-certainly being longer than 128 characters which was a previous limit on
550 the length that Exim was prepared to handle.
+503-All RCPT commands were rejected with this error:
+503-host is listed in rbl3.test.ex with value 127.0.0.3
+503-This is a very long blacklisting message, continuing for ages and ages and
+503-certainly being longer than 128 characters which was a previous limit on
+503-the length that Exim was prepared to handle.
503 valid RCPT command must precede DATA
500 unrecognized command
500 unrecognized command
Index: 0175
===================================================================
RCS file: /home/cvs/exim/exim-test/stdout/0175,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 0175 7 Feb 2006 10:47:37 -0000 1.1
+++ 0175 21 Mar 2007 15:10:40 -0000 1.2
@@ -6,6 +6,8 @@
220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
250 OK
550 Sender verify failed
+503-All RCPT commands were rejected with this error:
+503-Sender verify failed
503 valid RCPT command must precede DATA
500 unrecognized command
221 the.local.host.name closing connection
@@ -17,6 +19,8 @@
220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
250 OK
550 Sender verify failed
+503-All RCPT commands were rejected with this error:
+503-Sender verify failed
503 valid RCPT command must precede DATA
500 unrecognized command
221 the.local.host.name closing connection
Index: 0395
===================================================================
RCS file: /home/cvs/exim/exim-test/stdout/0395,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- 0395 7 Feb 2006 10:47:37 -0000 1.1
+++ 0395 21 Mar 2007 15:10:40 -0000 1.2
@@ -9,6 +9,8 @@
220 the.local.host.name ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
250 OK
501 userx: recipient address must contain a domain
+503-All RCPT commands were rejected with this error:
+503-501 userx: recipient address must contain a domain
503 valid RCPT command must precede DATA
500 unrecognized command
500 unrecognized command