summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/doc-misc/WishList9
-rw-r--r--doc/doc-txt/ChangeLog5
-rw-r--r--doc/doc-txt/NewStuff15
-rw-r--r--src/src/acl.c114
-rw-r--r--src/src/globals.c3
-rw-r--r--src/src/globals.h3
-rw-r--r--src/src/smtp_in.c21
-rw-r--r--test/confs/34006
-rw-r--r--test/scripts/3400-plaintext/340018
-rw-r--r--test/stderr/340035
-rw-r--r--test/stdout/340015
11 files changed, 180 insertions, 64 deletions
diff --git a/doc/doc-misc/WishList b/doc/doc-misc/WishList
index 55aa19d9d..23a597d8a 100644
--- a/doc/doc-misc/WishList
+++ b/doc/doc-misc/WishList
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-misc/WishList,v 1.61 2006/03/02 11:24:25 ph10 Exp $
+$Cambridge: exim/doc/doc-misc/WishList,v 1.62 2006/03/02 12:25:48 ph10 Exp $
EXIM 4 WISH LIST
----------------
@@ -1997,13 +1997,6 @@ code, because of caching. Probably means we have to invent ewildlsearch and
enwildlsearch.
------------------------------------------------------------------------------
-(348) 17-Nov-05 S Option to allow AUTH when not advertised.
-
-It seems that there are clients that send AUTH when it hasn't been advertised,
-some even after HELO, not even EHLO. Sigh. Possibly this should be an ACL
-control, to enable it to be restricted to certain hosts.
-------------------------------------------------------------------------------
-
(350) 28-Feb-06 S Additional errors for retry rules
(i) Unexpected connection close; (ii) mail_4xx.
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 71e3e5e7e..6266ed56b 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.320 2006/03/01 16:07:16 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.321 2006/03/02 12:25:48 ph10 Exp $
Change log file for Exim from version 4.21
-------------------------------------------
@@ -272,6 +272,9 @@ PH/53 This is related to PH/52, but is more general: for any failing address,
"retry timeout exceeded" was returned. Now it returns the full error as
well as "retry timeout exceeded".
+PH/54 Added control=allow_auth_unadvertised, as it seems there are clients that
+ do this, and (what is worse) MTAs that accept it.
+
Exim version 4.60
-----------------
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index e8792c3fc..06c676050 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.93 2006/03/01 11:40:51 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.94 2006/03/02 12:25:48 ph10 Exp $
New Features in Exim
--------------------
@@ -105,6 +105,19 @@ PH/15 The smtp transport has a new option called authenticated_sender_force.
PH/16 The expansion ${time_eval:<string>} converts an Exim time string such as
2d4h1m into a number of seconds.
+PH/17 The ACL modifier control=allow_auth_unadvertised can be used to permit a
+ client host to use the SMTP AUTH command even when it has not been
+ advertised in response to EHLO. Furthermore, because there are apparently
+ some really broken clients that do this, Exim will even accept AUTH after
+ HELO when this control is set. It should only be used if you really need
+ it, and you should limit its use to those broken hosts that do not work
+ without it. For example:
+
+ warn hosts = 192.168.34.25
+ control = allow_auth_unadvertised
+
+ This control is permitted only in the connection and HELO ACLs.
+
Version 4.60
------------
diff --git a/src/src/acl.c b/src/src/acl.c
index 6efc313d1..2a7b5afe8 100644
--- a/src/src/acl.c
+++ b/src/src/acl.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.55 2006/02/13 12:02:59 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.56 2006/03/02 12:25:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -132,19 +132,29 @@ static uschar *conditions[] = {
that follows! */
enum {
-#ifdef EXPERIMENTAL_BRIGHTMAIL
+ CONTROL_AUTH_UNADVERTISED,
+ #ifdef EXPERIMENTAL_BRIGHTMAIL
CONTROL_BMI_RUN,
-#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
+ #endif
+ #ifdef EXPERIMENTAL_DOMAINKEYS
CONTROL_DK_VERIFY,
-#endif
- CONTROL_ERROR, CONTROL_CASEFUL_LOCAL_PART, CONTROL_CASELOWER_LOCAL_PART,
- CONTROL_ENFORCE_SYNC, CONTROL_NO_ENFORCE_SYNC, CONTROL_FREEZE,
- CONTROL_QUEUE_ONLY, CONTROL_SUBMISSION, CONTROL_SUPPRESS_LOCAL_FIXUPS,
-#ifdef WITH_CONTENT_SCAN
+ #endif
+ CONTROL_ERROR,
+ CONTROL_CASEFUL_LOCAL_PART,
+ CONTROL_CASELOWER_LOCAL_PART,
+ CONTROL_ENFORCE_SYNC,
+ CONTROL_NO_ENFORCE_SYNC,
+ CONTROL_FREEZE,
+ CONTROL_QUEUE_ONLY,
+ CONTROL_SUBMISSION,
+ CONTROL_SUPPRESS_LOCAL_FIXUPS,
+ #ifdef WITH_CONTENT_SCAN
CONTROL_NO_MBOX_UNSPOOL,
-#endif
- CONTROL_FAKEDEFER, CONTROL_FAKEREJECT, CONTROL_NO_MULTILINE };
+ #endif
+ CONTROL_FAKEDEFER,
+ CONTROL_FAKEREJECT,
+ CONTROL_NO_MULTILINE
+};
/* ACL control names; keep in step with the table above! This list is used for
turning ids into names. The actual list of recognized names is in the variable
@@ -152,20 +162,27 @@ control_def controls_list[] below. The fact that there are two lists is a mess
and should be tidied up. */
static uschar *controls[] = {
+ US"allow_auth_unadvertised",
#ifdef EXPERIMENTAL_BRIGHTMAIL
US"bmi_run",
#endif
#ifdef EXPERIMENTAL_DOMAINKEYS
US"dk_verify",
#endif
- US"error", US"caseful_local_part",
- US"caselower_local_part", US"enforce_sync", US"no_enforce_sync", US"freeze",
- US"queue_only", US"submission", US"suppress_local_fixups",
+ US"error",
+ US"caseful_local_part",
+ US"caselower_local_part",
+ US"enforce_sync",
+ US"no_enforce_sync",
+ US"freeze",
+ US"queue_only",
+ US"submission",
+ US"suppress_local_fixups",
#ifdef WITH_CONTENT_SCAN
US"no_mbox_unspool",
#endif
-
- US"no_multiline"};
+ US"no_multiline"
+};
/* Flags to indicate for which conditions /modifiers a string expansion is done
at the outer level. In the other cases, expansion already occurs in the
@@ -453,12 +470,16 @@ each control, there's a bitmap of dis-allowed times. For some, it is easier to
specify the negation of a small number of allowed times. */
static unsigned int control_forbids[] = {
-#ifdef EXPERIMENTAL_BRIGHTMAIL
+ (unsigned int)
+ ~((1<<ACL_WHERE_CONNECT)|(1<<ACL_WHERE_HELO)), /* allow_auth_unadvertised */
+
+ #ifdef EXPERIMENTAL_BRIGHTMAIL
0, /* bmi_run */
-#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
+ #endif
+
+ #ifdef EXPERIMENTAL_DOMAINKEYS
(1<<ACL_WHERE_DATA)|(1<<ACL_WHERE_NOTSMTP), /* dk_verify */
-#endif
+ #endif
0, /* error */
@@ -490,12 +511,12 @@ static unsigned int control_forbids[] = {
~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)| /* suppress_local_fixups */
(1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_PREDATA)),
-#ifdef WITH_CONTENT_SCAN
+ #ifdef WITH_CONTENT_SCAN
(unsigned int)
~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)| /* no_mbox_unspool */
(1<<ACL_WHERE_PREDATA)|(1<<ACL_WHERE_DATA)|
(1<<ACL_WHERE_MIME)),
-#endif
+ #endif
(unsigned int)
~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)| /* fakedefer */
@@ -519,26 +540,27 @@ typedef struct control_def {
} control_def;
static control_def controls_list[] = {
+ { US"allow_auth_unadvertised", CONTROL_AUTH_UNADVERTISED, FALSE },
#ifdef EXPERIMENTAL_BRIGHTMAIL
- { US"bmi_run", CONTROL_BMI_RUN, FALSE },
+ { US"bmi_run", CONTROL_BMI_RUN, FALSE },
#endif
#ifdef EXPERIMENTAL_DOMAINKEYS
- { US"dk_verify", CONTROL_DK_VERIFY, FALSE },
-#endif
- { US"caseful_local_part", CONTROL_CASEFUL_LOCAL_PART, FALSE },
- { US"caselower_local_part", CONTROL_CASELOWER_LOCAL_PART, FALSE },
- { US"enforce_sync", CONTROL_ENFORCE_SYNC, FALSE },
- { US"freeze", CONTROL_FREEZE, TRUE },
- { US"no_enforce_sync", CONTROL_NO_ENFORCE_SYNC, FALSE },
- { US"no_multiline_responses", CONTROL_NO_MULTILINE, FALSE },
- { US"queue_only", CONTROL_QUEUE_ONLY, FALSE },
+ { US"dk_verify", CONTROL_DK_VERIFY, FALSE },
+#endif
+ { US"caseful_local_part", CONTROL_CASEFUL_LOCAL_PART, FALSE },
+ { US"caselower_local_part", CONTROL_CASELOWER_LOCAL_PART, FALSE },
+ { US"enforce_sync", CONTROL_ENFORCE_SYNC, FALSE },
+ { US"freeze", CONTROL_FREEZE, TRUE },
+ { US"no_enforce_sync", CONTROL_NO_ENFORCE_SYNC, FALSE },
+ { US"no_multiline_responses", CONTROL_NO_MULTILINE, FALSE },
+ { US"queue_only", CONTROL_QUEUE_ONLY, FALSE },
#ifdef WITH_CONTENT_SCAN
- { US"no_mbox_unspool", CONTROL_NO_MBOX_UNSPOOL, FALSE },
+ { US"no_mbox_unspool", CONTROL_NO_MBOX_UNSPOOL, FALSE },
#endif
- { US"fakedefer", CONTROL_FAKEDEFER, TRUE },
- { US"fakereject", CONTROL_FAKEREJECT, TRUE },
- { US"submission", CONTROL_SUBMISSION, TRUE },
- { US"suppress_local_fixups", CONTROL_SUPPRESS_LOCAL_FIXUPS, FALSE }
+ { US"fakedefer", CONTROL_FAKEDEFER, TRUE },
+ { US"fakereject", CONTROL_FAKEREJECT, TRUE },
+ { US"submission", CONTROL_SUBMISSION, TRUE },
+ { US"suppress_local_fixups", CONTROL_SUPPRESS_LOCAL_FIXUPS, FALSE }
};
/* Support data structures for Client SMTP Authorization. acl_verify_csa()
@@ -2430,16 +2452,22 @@ for (; cb != NULL; cb = cb->next)
switch(control_type)
{
-#ifdef EXPERIMENTAL_BRIGHTMAIL
+ case CONTROL_AUTH_UNADVERTISED:
+ allow_auth_unadvertised = TRUE;
+ break;
+
+ #ifdef EXPERIMENTAL_BRIGHTMAIL
case CONTROL_BMI_RUN:
bmi_run = 1;
break;
-#endif
-#ifdef EXPERIMENTAL_DOMAINKEYS
+ #endif
+
+ #ifdef EXPERIMENTAL_DOMAINKEYS
case CONTROL_DK_VERIFY:
dk_do_verify = 1;
break;
-#endif
+ #endif
+
case CONTROL_ERROR:
return ERROR;
@@ -2459,11 +2487,11 @@ for (; cb != NULL; cb = cb->next)
smtp_enforce_sync = FALSE;
break;
-#ifdef WITH_CONTENT_SCAN
+ #ifdef WITH_CONTENT_SCAN
case CONTROL_NO_MBOX_UNSPOOL:
no_mbox_unspool = TRUE;
break;
-#endif
+ #endif
case CONTROL_NO_MULTILINE:
no_multiline_responses = TRUE;
diff --git a/src/src/globals.c b/src/src/globals.c
index 58b032145..5d898d546 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.51 2006/02/20 16:31:49 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.52 2006/03/02 12:25:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -299,6 +299,7 @@ tree_node *addresslist_anchor = NULL;
int addresslist_count = 0;
gid_t *admin_groups = NULL;
BOOL admin_user = FALSE;
+BOOL allow_auth_unadvertised= FALSE;
BOOL allow_domain_literals = FALSE;
BOOL allow_mx_to_ip = FALSE;
BOOL allow_unqualified_recipient = TRUE; /* For local messages */
diff --git a/src/src/globals.h b/src/src/globals.h
index c884dfaf2..114f859fb 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.35 2006/02/13 12:02:59 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.36 2006/03/02 12:25:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -143,6 +143,7 @@ extern tree_node *addresslist_anchor; /* Tree of defined address lists */
extern int addresslist_count; /* Number defined */
extern gid_t *admin_groups; /* List of admin groups */
extern BOOL admin_user; /* True if caller can do admin */
+extern BOOL allow_auth_unadvertised;/* As it says */
extern BOOL allow_domain_literals; /* As it says */
extern BOOL allow_mx_to_ip; /* Allow MX records to -> ip address */
extern BOOL allow_unqualified_recipient; /* As it says */
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index 4ed335c02..9df0f592a 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.33 2006/02/14 14:55:37 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.34 2006/03/02 12:25:48 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
@@ -2147,10 +2147,14 @@ while (done <= 0)
switch(smtp_read_command(TRUE))
{
/* The AUTH command is not permitted to occur inside a transaction, and may
- occur successfully only once per connection, and then only when we've
- advertised it. Actually, that isn't quite true. When TLS is started, all
- previous information about a connection must be discarded, so a new AUTH is
- permitted at that time.
+ occur successfully only once per connection. Actually, that isn't quite
+ true. When TLS is started, all previous information about a connection must
+ be discarded, so a new AUTH is permitted at that time.
+
+ AUTH may only be used when it has been advertised. However, it seems that
+ there are clients that send AUTH when it hasn't been advertised, some of
+ them even doing this after HELO. And there are MTAs that accept this. Sigh.
+ So there's a get-out that allows this to happen.
AUTH is initially labelled as a "nonmail command" so that one occurrence
doesn't get counted. We change the label here so that multiple failing
@@ -2160,7 +2164,7 @@ while (done <= 0)
authentication_failed = TRUE;
cmd_list[CMD_LIST_AUTH].is_mail_cmd = FALSE;
- if (!auth_advertised)
+ if (!auth_advertised && !allow_auth_unadvertised)
{
done = synprot_error(L_smtp_protocol_error, 503, NULL,
US"AUTH command used when not advertised");
@@ -2215,12 +2219,13 @@ while (done <= 0)
}
/* Search for an authentication mechanism which is configured for use
- as a server and which has been advertised. */
+ as a server and which has been advertised (unless, sigh, allow_auth_
+ unadvertised is set). */
for (au = auths; au != NULL; au = au->next)
{
if (strcmpic(s, au->public_name) == 0 && au->server &&
- au->advertised) break;
+ (au->advertised || allow_auth_unadvertised)) break;
}
if (au == NULL)
diff --git a/test/confs/3400 b/test/confs/3400
index b84ee56c4..e56756543 100644
--- a/test/confs/3400
+++ b/test/confs/3400
@@ -17,6 +17,7 @@ hostlist auth_hosts = 10.0.0.1
hostlist relay_hosts = 10.0.0.4
hostlist auth_relay_hosts = 10.0.0.3 : 10.0.0.4
+acl_smtp_connect = check_connect
acl_smtp_etrn = check_etrn
acl_smtp_expn = check_expn
acl_smtp_rcpt = check_recipient
@@ -32,6 +33,11 @@ trusted_users = CALLER
begin acl
+check_connect:
+ warn hosts = 10.0.0.6
+ control = allow_auth_unadvertised
+ accept
+
check_recipient:
warn hosts = 10.0.0.5
message = authentication-failed: $authentication_failed
diff --git a/test/scripts/3400-plaintext/3400 b/test/scripts/3400-plaintext/3400
index b547a21b9..164ace593 100644
--- a/test/scripts/3400-plaintext/3400
+++ b/test/scripts/3400-plaintext/3400
@@ -150,9 +150,11 @@ auth expandfail
AHVzZXJ4AHNlY3JldA==
quit
****
+# 10.0.0.2 is not allowed to use AUTH when it is not advertised
+#
exim -bs -oMa 10.0.0.2
ehlo test.host
-auth expandfail
+auth explain
AHVzZXJ4AHNlY3JldA==
quit
****
@@ -215,4 +217,18 @@ ehlo testing.testing
auth mylogin dXNlcnggc2VjcmV0
quit
****
+# 10.0.0.6 is allowed to use AUTH when it is not advertised
+#
+exim -bs -oMa 10.0.0.6
+ehlo test.host
+auth explain
+AHVzZXJ4AHNlY3JldA==
+quit
+****
+exim -bs -oMa 10.0.0.6
+helo test.host
+auth explain
+AHVzZXJ4AHNlY3JldA==
+quit
+****
no_msglog_check
diff --git a/test/stderr/3400 b/test/stderr/3400
index fb3b9895b..573d3afee 100644
--- a/test/stderr/3400
+++ b/test/stderr/3400
@@ -6,6 +6,13 @@
>>> host in helo_verify_hosts? no (option unset)
>>> host in helo_try_verify_hosts? no (option unset)
>>> host in helo_accept_junk_hosts? no (option unset)
+>>> using ACL "check_connect"
+>>> processing "warn"
+>>> check hosts = 10.0.0.6
+>>> host in "10.0.0.6"? no (end of list)
+>>> warn: condition test failed
+>>> processing "accept"
+>>> accept: condition test succeeded
>>> host in smtp_accept_max_nonmail_hosts? yes (matched "*")
>>> using ACL "check_vrfy"
>>> processing "deny"
@@ -62,6 +69,13 @@ LOG: H=[10.0.0.2] Warning: accepted ETRN #abcd
>>> host in helo_verify_hosts? no (option unset)
>>> host in helo_try_verify_hosts? no (option unset)
>>> host in helo_accept_junk_hosts? no (option unset)
+>>> using ACL "check_connect"
+>>> processing "warn"
+>>> check hosts = 10.0.0.6
+>>> host in "10.0.0.6"? no (end of list)
+>>> warn: condition test failed
+>>> processing "accept"
+>>> accept: condition test succeeded
>>> test.host in helo_lookup_domains? no (end of list)
>>> host in pipelining_advertise_hosts? yes (matched "*")
>>> host in "10.0.0.1"? yes (matched "10.0.0.1")
@@ -234,6 +248,13 @@ LOG: H=(test.host) [10.0.0.1] Warning: accepted ETRN #abcd
>>> host in helo_verify_hosts? no (option unset)
>>> host in helo_try_verify_hosts? no (option unset)
>>> host in helo_accept_junk_hosts? no (option unset)
+>>> using ACL "check_connect"
+>>> processing "warn"
+>>> check hosts = 10.0.0.6
+>>> host in "10.0.0.6"? no (end of list)
+>>> warn: condition test failed
+>>> processing "accept"
+>>> accept: condition test succeeded
>>> test.host in helo_lookup_domains? no (end of list)
>>> host in pipelining_advertise_hosts? yes (matched "*")
>>> host in "10.0.0.1"? no (end of list)
@@ -318,6 +339,13 @@ LOG: H=(test.host) [10.0.0.3] F=<junk@jink.jonk.test.ex> rejected RCPT <userx@cu
>>> host in helo_verify_hosts? no (option unset)
>>> host in helo_try_verify_hosts? no (option unset)
>>> host in helo_accept_junk_hosts? no (option unset)
+>>> using ACL "check_connect"
+>>> processing "warn"
+>>> check hosts = 10.0.0.6
+>>> host in "10.0.0.6"? no (end of list)
+>>> warn: condition test failed
+>>> processing "accept"
+>>> accept: condition test succeeded
>>> test.host in helo_lookup_domains? no (end of list)
>>> host in pipelining_advertise_hosts? yes (matched "*")
>>> host in "10.0.0.1"? no (end of list)
@@ -348,6 +376,13 @@ host in recipient_unqualified_hosts? no (option unset)
host in helo_verify_hosts? no (option unset)
host in helo_try_verify_hosts? no (option unset)
host in helo_accept_junk_hosts? no (option unset)
+using ACL "check_connect"
+processing "warn"
+check hosts = 10.0.0.6
+host in "10.0.0.6"? no (end of list)
+warn: condition test failed
+processing "accept"
+accept: condition test succeeded
SMTP>> 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
smtp_setup_msg entered
SMTP<< ehlo testing.testing
diff --git a/test/stdout/3400 b/test/stdout/3400
index 7d8e3689a..002166e90 100644
--- a/test/stdout/3400
+++ b/test/stdout/3400
@@ -326,3 +326,18 @@
250 HELP
235 Authentication succeeded
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.host [10.0.0.6]
+250-SIZE 52428800
+250-ETRN
+250-EXPN
+250-PIPELINING
+250 HELP
+334
+235 Authentication succeeded
+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.host [10.0.0.6]
+334
+235 Authentication succeeded
+221 myhost.test.ex closing connection