-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.386 2006/08/21 11:31:43 fanf2 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.387 2006/09/05 13:24:10 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
header after the first one which had an odd number of characters
in the field name.
+PH/01 If a server that rejects MAIL FROM:<> was the target of a sender
+ callout verification, Exim cached a "reject" for the entire domain. This
+ is correct for most verifications, but it is not correct for a recipient
+ verification with use_sender or use_postmaster set, because in that case
+ the callout does not use MAIL FROM:<>. Exim now distinguishes the special
+ case of MAIL FROM:<> rejection from other early rejections (e.g.
+ rejection of HELO). When verifying a recipient using a non-null MAIL
+ address, the cache is ignored if it shows MAIL FROM:<> rejection.
+ Whatever the result of the callout, the value of the domain cache is
+ left unchanged (for any other kind of callout, getting as far as trying
+ RCPT means that the domain itself is ok).
+
Exim version 4.63
-----------------
-/* $Cambridge: exim/src/src/dbstuff.h,v 1.4 2006/02/07 11:19:00 ph10 Exp $ */
+/* $Cambridge: exim/src/src/dbstuff.h,v 1.5 2006/09/05 13:24:10 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
2. keyed by domain -
Domain response upto MAIL FROM:<>, postmaster, random local part;
-If a record exists, the result field is either ccache_accept or ccache_reject.
-The other fields, however, (which are only relevant to domain records) may also
-contain ccache_unknown if that particular test has not been done.
+If a record exists, the result field is either ccache_accept or ccache_reject,
+or, for a domain record only, ccache_reject_mfnull when MAIL FROM:<> was
+rejected. The other fields, however, (which are only relevant to domain
+records) may also contain ccache_unknown if that particular test has not been
+done.
Originally, there was only one structure, used for both types. However, it got
expanded for domain records, so it got split. To make it possible for Exim to
-/* $Cambridge: exim/src/src/macros.h,v 1.26 2006/06/28 16:00:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/macros.h,v 1.27 2006/09/05 13:24:10 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
#define ccache_unknown 0 /* test hasn't been done */
#define ccache_accept 1
-#define ccache_reject 2
+#define ccache_reject 2 /* All rejections except */
+#define ccache_reject_mfnull 3 /* MAIL FROM:<> was rejected */
/* Options for lookup functions */
-/* $Cambridge: exim/src/src/verify.c,v 1.37 2006/06/30 15:36:08 ph10 Exp $ */
+/* $Cambridge: exim/src/src/verify.c,v 1.38 2006/09/05 13:24:10 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
BOOL callout_random = (options & vopt_callout_random) != 0;
int yield = OK;
+int old_domain_cache_result = ccache_accept;
BOOL done = FALSE;
uschar *address_key;
uschar *from_address;
if (cache_record != NULL)
{
- /* If an early command (up to and including MAIL FROM:<>) was rejected,
- there is no point carrying on. The callout fails. */
-
- if (cache_record->result == ccache_reject)
+ /* In most cases, if an early command (up to and including MAIL FROM:<>)
+ was rejected, there is no point carrying on. The callout fails. However, if
+ we are doing a recipient verification with use_sender or use_postmaster
+ set, a previous failure of MAIL FROM:<> doesn't count, because this time we
+ will be using a non-empty sender. We have to remember this situation so as
+ not to disturb the cached domain value if this whole verification succeeds
+ (we don't want it turning into "accept"). */
+
+ old_domain_cache_result = cache_record->result;
+
+ if (cache_record->result == ccache_reject ||
+ (*from_address == 0 && cache_record->result == ccache_reject_mfnull))
{
setflag(addr, af_verify_nsfail);
HDEBUG(D_verify)
continue;
}
- /* Wait for initial response, and then run the initial SMTP commands. The
- smtp_write_command() function leaves its command in big_buffer. This is
- used in error responses. Initialize it in case the connection is
- rejected. */
+ /* Wait for initial response, and send HELO. The smtp_write_command()
+ function leaves its command in big_buffer. This is used in error responses.
+ Initialize it in case the connection is rejected. */
Ustrcpy(big_buffer, "initial connection");
done =
smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
'2', callout) &&
-
smtp_write_command(&outblock, FALSE, "%s %s\r\n", helo,
smtp_active_hostname) >= 0 &&
smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
- '2', callout) &&
+ '2', callout);
+ /* Failure to accept HELO is cached; this blocks the whole domain for all
+ senders. I/O errors and defer responses are not cached. */
+
+ if (!done)
+ {
+ *failure_ptr = US"mail"; /* At or before MAIL */
+ if (errno == 0 && responsebuffer[0] == '5')
+ {
+ setflag(addr, af_verify_nsfail);
+ new_domain_record.result = ccache_reject;
+ }
+ }
+
+ /* Send the MAIL command */
+
+ else done =
smtp_write_command(&outblock, FALSE, "MAIL FROM:<%s>\r\n",
from_address) >= 0 &&
smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer),
'2', callout);
- /* If the host gave an initial error, or does not accept HELO or MAIL
- FROM:<>, arrange to cache this information, but don't record anything for an
- I/O error or a defer. Do not cache rejections when a non-empty sender has
- been used, because that blocks the whole domain for all senders. */
+ /* If the host does not accept MAIL FROM:<>, arrange to cache this
+ information, but again, don't record anything for an I/O error or a defer. Do
+ not cache rejections of MAIL when a non-empty sender has been used, because
+ that blocks the whole domain for all senders. */
if (!done)
{
- *failure_ptr = US"mail";
+ *failure_ptr = US"mail"; /* At or before MAIL */
if (errno == 0 && responsebuffer[0] == '5')
{
setflag(addr, af_verify_nsfail);
- if (from_address[0] == 0) new_domain_record.result = ccache_reject;
+ if (from_address[0] == 0)
+ new_domain_record.result = ccache_reject_mfnull;
}
}
/* Otherwise, proceed to check a "random" address (if required), then the
given address, and the postmaster address (if required). Between each check,
issue RSET, because some servers accept only one recipient after MAIL
- FROM:<>. */
+ FROM:<>.
+
+ Before doing this, set the result in the domain cache record to "accept",
+ unless its previous value was ccache_reject_mfnull. In that case, the domain
+ rejects MAIL FROM:<> and we want to continue to remember that. When that is
+ the case, we have got here only in the case of a recipient verification with
+ a non-null sender. */
else
{
- new_domain_record.result = ccache_accept;
+ new_domain_record.result =
+ (old_domain_cache_result == ccache_reject_mfnull)?
+ ccache_reject_mfnull: ccache_accept;
/* Do the random local part check first */
The value of the result field in the new_domain record is ccache_unknown if
there was an error before or with MAIL FROM:, and errno was not zero,
implying some kind of I/O error. We don't want to write the cache in that case.
-Otherwise the value is ccache_accept or ccache_reject. */
+Otherwise the value is ccache_accept, ccache_reject, or ccache_reject_mfnull. */
if (!callout_no_cache && new_domain_record.result != ccache_unknown)
{
-/* $Cambridge: exim/src/src/version.c,v 1.17 2006/06/27 13:39:24 ph10 Exp $ */
+/* $Cambridge: exim/src/src/version.c,v 1.18 2006/09/05 13:24:10 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
#include "exim.h"
-#define THIS_VERSION "4.63"
+#define THIS_VERSION "4.64"
/* The header file cnumber.h contains a single line containing the
--- /dev/null
+# Exim test configuration 0538
+
+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_mail = check_mail
+acl_smtp_rcpt = check_rcpt
+
+
+# ----- ACLs -----
+
+begin acl
+
+check_mail:
+ accept sender_domains = broken.example
+ endpass
+ verify = sender/callout
+ accept
+
+check_rcpt:
+ accept verify = recipient/callout=use_sender
+
+
+# ----- Routers -----
+
+begin routers
+
+r1:
+ driver = manualroute
+ route_list = * "<= 127.0.0.1:PORT_S"
+ self = send
+ verify_only
+
+
+# End
--- /dev/null
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userx@broken.example>: response to "MAIL FROM:<>" from 127.0.0.1 [127.0.0.1] was: 550 I'm misconfigured
+1999-03-02 09:44:33 U=CALLER rejected MAIL <userx@broken.example>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userx@broken.example>
+1999-03-02 09:44:33 U=CALLER rejected MAIL <userx@broken.example>: Sender verify failed
--- /dev/null
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userx@broken.example>: response to "MAIL FROM:<>" from 127.0.0.1 [127.0.0.1] was: 550 I'm misconfigured
+1999-03-02 09:44:33 U=CALLER rejected MAIL <userx@broken.example>: Sender verify failed
+1999-03-02 09:44:33 U=CALLER sender verify fail for <userx@broken.example>
+1999-03-02 09:44:33 U=CALLER rejected MAIL <userx@broken.example>: Sender verify failed
#! /usr/bin/perl -w
-# $Cambridge: exim/test/runtest,v 1.13 2006/07/26 14:39:13 ph10 Exp $
+# $Cambridge: exim/test/runtest,v 1.14 2006/09/05 13:24:10 ph10 Exp $
###############################################################################
# This is the controlling script for the "new" test suite for Exim. It should #
# Start by initializing some global variables
-$testversion = "4.63 (24-Jul-06)";
+$testversion = "4.64 (05-Sep-06)";
$cf = "bin/cf";
$cr = "\r";
--- /dev/null
+# callout for recipient/use_sender after mail from:<> rejection
+need_ipv4
+#
+# Do a sender address verify that rejects MAIL FROM:<>
+server PORT_S
+220 Welcome
+HELO
+250 Hi
+MAIL FROM
+550 I'm misconfigured
+QUIT
+221 Bye
+****
+exim -bs
+mail from:<userx@broken.example>
+quit
+****
+# Now do a recipient verify for the same domain, with use_sender
+server PORT_S
+220 Welcome
+HELO
+250 Hi
+MAIL FROM
+250 OK
+RCPT TO
+250 OK
+QUIT
+221 Bye
+****
+exim -bs
+mail from:<userx@ok.example>
+rcpt to:<usery@broken.example>
+quit
+****
+# A final check that the cache works for sender address
+exim -bs
+mail from:<userx@broken.example>
+quit
+****
SMTP<< 550 REJECT MAIL FROM
SMTP>> QUIT
wrote callout cache domain record:
- result=2 postmaster=0 random=0
+ result=3 postmaster=0 random=0
LOG: MAIN REJECT
H=[V4NET.0.0.1] U=root sender verify fail for <ok@localhost>: response to "MAIL FROM:<>" from 127.0.0.1 [127.0.0.1] was: 550 REJECT MAIL FROM
LOG: MAIN REJECT
--- /dev/null
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+550-Callback setup failed while verifying <userx@broken.example>\r
+550-Called: 127.0.0.1\r
+550-Sent: MAIL FROM:<>\r
+550-Response: 550 I'm misconfigured\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+250 OK\r
+250 Accepted\r
+221 myhost.test.ex closing connection\r
+220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000\r
+550-Callback setup failed while verifying <userx@broken.example>\r
+550-(result of an earlier callout reused).\r
+550-The initial connection, or a HELO or MAIL FROM:<> command was\r
+550-rejected. Refusing MAIL FROM:<> does not help fight spam, disregards\r
+550-RFC requirements, and stops you from receiving standard bounce\r
+550-messages. This host does not accept mail from domains whose servers\r
+550-refuse bounces.\r
+550 Sender verify failed\r
+221 myhost.test.ex closing connection\r
+
+******** SERVER ********
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 Welcome
+HELO myhost.test.ex
+250 Hi
+MAIL FROM:<>
+550 I'm misconfigured
+QUIT
+221 Bye
+End of script
+Listening on port 1224 ...
+Connection request from [127.0.0.1]
+220 Welcome
+HELO myhost.test.ex
+250 Hi
+MAIL FROM:<userx@ok.example>
+250 OK
+RCPT TO:<usery@broken.example>
+250 OK
+QUIT
+221 Bye
+End of script