summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhilip Hazel <ph10@hermes.cam.ac.uk>2006-03-02 12:25:48 +0000
committerPhilip Hazel <ph10@hermes.cam.ac.uk>2006-03-02 12:25:48 +0000
commitc46782effbf7f5ecde21a8d29cb22b42fda0fe8e (patch)
tree7cd9bc552c81f2c229dc53b6566dcfc052cb3e5e /src
parent7d89b8caecf6abfddbd6a07597cacf615144cb13 (diff)
Implemented control=allow_auth_unadvertised.
Diffstat (limited to 'src')
-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
4 files changed, 88 insertions, 53 deletions
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)