diff options
author | Philip Hazel <ph10@hermes.cam.ac.uk> | 2006-03-02 12:25:48 +0000 |
---|---|---|
committer | Philip Hazel <ph10@hermes.cam.ac.uk> | 2006-03-02 12:25:48 +0000 |
commit | c46782effbf7f5ecde21a8d29cb22b42fda0fe8e (patch) | |
tree | 7cd9bc552c81f2c229dc53b6566dcfc052cb3e5e /src | |
parent | 7d89b8caecf6abfddbd6a07597cacf615144cb13 (diff) |
Implemented control=allow_auth_unadvertised.
Diffstat (limited to 'src')
-rw-r--r-- | src/src/acl.c | 114 | ||||
-rw-r--r-- | src/src/globals.c | 3 | ||||
-rw-r--r-- | src/src/globals.h | 3 | ||||
-rw-r--r-- | src/src/smtp_in.c | 21 |
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) |