From 6c512171a8449f14cc284e13aabc0153d9977c43 Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Mon, 18 Jun 2007 13:57:49 +0000 Subject: [PATCH] Add client_condition to authenticators. --- doc/doc-txt/ChangeLog | 9 ++- doc/doc-txt/NewStuff | 14 ++++- src/src/globals.c | 5 +- src/src/structs.h | 3 +- src/src/transports/smtp.c | 29 ++++++++-- test/confs/3455 | 74 ++++++++++++++++++++++++ test/confs/3465 | 74 ++++++++++++++++++++++++ test/log/3455 | 12 ++++ test/log/3465 | 12 ++++ test/scripts/3450-plaintext-GnuTLS/3455 | 12 ++++ test/scripts/3460-plaintext-OpenSSL/3465 | 12 ++++ test/stdout/2022 | 2 +- test/stdout/3407 | 4 ++ 13 files changed, 251 insertions(+), 11 deletions(-) create mode 100644 test/confs/3455 create mode 100644 test/confs/3465 create mode 100644 test/log/3455 create mode 100644 test/log/3465 create mode 100644 test/scripts/3450-plaintext-GnuTLS/3455 create mode 100644 test/scripts/3460-plaintext-OpenSSL/3465 diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 6a8e4d1e1..cd802708e 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.512 2007/06/14 14:18:19 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.513 2007/06/18 13:57:49 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -50,6 +50,13 @@ PH/03 The body_linecount and body_zerocount variables are now exported in the PH/04 Added the $dnslist_matched variable. +PH/05 Unset $tls_cipher and $tls_peerdn before making a connection as a client. + This means they are set thereafter only if the connection becomes + encrypted. + +PH/06 Added the client_condition to authenticators so that some can be skipped + by clients under certain conditions. + Exim version 4.67 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index a63027364..7e0c472ec 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.148 2007/06/14 14:18:19 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.149 2007/06/18 13:57:49 ph10 Exp $ New Features in Exim -------------------- @@ -31,6 +31,18 @@ Version 4.68 If this condition succeeds, the value in $dnslist_matched might be 192.168.6.7 (for example). + 3. Authenticators now have a client_condition option. When Exim is running as + a client, it skips an authenticator whose client_condition expansion yields + "0", "no", or "false". This can be used, for example, to skip plain text + authenticators when the connection is not encrypted by a setting such as: + + client_condition = ${if !eq{$tls_cipher}{}} + + Note that the 4.67 documentation states that $tls_cipher contains the + cipher used for incoming messages. In fact, during SMTP delivery, it + contains the cipher used for the delivery. The same is true for + $tls_peerdn. + Version 4.67 ------------ diff --git a/src/src/globals.c b/src/src/globals.c index 7b14f7b93..7d34c6699 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/globals.c,v 1.73 2007/06/14 14:18:19 ph10 Exp $ */ +/* $Cambridge: exim/src/src/globals.c,v 1.74 2007/06/18 13:57:50 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -32,6 +32,8 @@ static void dummy(int x) { dummy(x-1); } data blocks and hence have the opt_public flag set. */ optionlist optionlist_auths[] = { + { "client_condition", opt_stringptr | opt_public, + (void *)(offsetof(auth_instance, client_condition)) }, { "driver", opt_stringptr | opt_public, (void *)(offsetof(auth_instance, driver_name)) }, { "public_name", opt_stringptr | opt_public, @@ -327,6 +329,7 @@ auth_instance auth_defaults = { NULL, /* private options block pointer */ NULL, /* driver_name */ NULL, /* advertise_condition */ + NULL, /* client_condition */ NULL, /* public_name */ NULL, /* set_id */ NULL, /* server_mail_auth_condition */ diff --git a/src/src/structs.h b/src/src/structs.h index 71d9d3a68..cc0e521b7 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/structs.h,v 1.15 2007/01/08 10:50:18 ph10 Exp $ */ +/* $Cambridge: exim/src/src/structs.h,v 1.16 2007/06/18 13:57:50 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -362,6 +362,7 @@ typedef struct auth_instance { void *options_block; /* Pointer to private options */ uschar *driver_name; /* Must be first */ uschar *advertise_condition; /* Are we going to advertise this?*/ + uschar *client_condition; /* Should the client try this? */ uschar *public_name; /* Advertised name */ uschar *set_id; /* String to set as authenticated id */ uschar *mail_auth_condition; /* Condition for AUTH on MAIL command */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 2fce7bab2..537f32aa5 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/transports/smtp.c,v 1.36 2007/02/08 15:16:19 ph10 Exp $ */ +/* $Cambridge: exim/src/src/transports/smtp.c,v 1.37 2007/06/18 13:57:50 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -789,7 +789,8 @@ return yield; /* If continue_hostname is not null, we get here only when continuing to deliver down an existing channel. The channel was passed as the standard -input. +input. TLS is never active on a passed channel; the previous process always +closes it down before passing the connection on. Otherwise, we have to make a connection to the remote host, and do the initial protocol exchange. @@ -886,6 +887,11 @@ outblock.ptr = outbuffer; outblock.cmd_count = 0; outblock.authenticating = FALSE; +/* Reset the parameters of a TLS session. */ + +tls_cipher = NULL; +tls_peerdn = NULL; + /* If an authenticated_sender override has been specified for this transport instance, expand it. If the expansion is forced to fail, and there was already an authenticated_sender for this message, the original value will be used. @@ -1233,14 +1239,25 @@ if (continue_hostname == NULL DEBUG(D_transport) debug_printf("scanning authentication mechanisms\n"); /* Scan the configured authenticators looking for one which is configured - for use as a client and whose name matches an authentication mechanism - supported by the server. If one is found, attempt to authenticate by - calling its client function. */ + for use as a client, which is not suppressed by client_condition, and + whose name matches an authentication mechanism supported by the server. + If one is found, attempt to authenticate by calling its client function. + */ for (au = auths; !smtp_authenticated && au != NULL; au = au->next) { uschar *p = names; - if (!au->client) continue; + if (!au->client || + (au->client_condition != NULL && + !expand_check_condition(au->client_condition, au->name, + US"client authenticator"))) + { + DEBUG(D_transport) debug_printf("skipping %s authenticator: %s\n", + au->name, + (au->client)? "client_condition is false" : + "not configured as a client"); + continue; + } /* Loop to scan supported server mechanisms */ diff --git a/test/confs/3455 b/test/confs/3455 new file mode 100644 index 000000000..274de6316 --- /dev/null +++ b/test/confs/3455 @@ -0,0 +1,74 @@ +# Exim test configuration 3455 + +HOSTS_AVOID_TLS= + +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 = accept + +domainlist local_domains = test.ex + +log_selector = +smtp_no_mail + +queue_only = true + +tls_advertise_hosts = * +tls_certificate = DIR/aux-fixed/cert1 +tls_privatekey = DIR/aux-fixed/cert1 + + +# ----- Authenticators ----- + +begin authenticators + +plain: + driver = plaintext + public_name = PLAIN + server_condition = "\ + ${if and {{eq{$2}{userx}}{eq{$3}{secret1}}}{yes}{no}}" + server_set_id = $2 + client_condition = ${if !eq {$tls_cipher}{}} + client_send = ^userx^secret1 + +login: + driver = plaintext + public_name = LOGIN + server_prompts = User Name : Password + server_condition = "\ + ${if and {{eq{$auth1}{usery}}{eq{$auth2}{secret2}}}{yes}{no}}" + server_set_id = $auth1 + client_send = : usery : secret2 + + +# ----- Routers ----- + +begin routers + +r1: + driver = accept + transport = t1 + + +# ----- Transports ----- + +begin transports + +t1: + driver = smtp + hosts = 127.0.0.1 + port = PORT_D + hosts_avoid_tls = HOSTS_AVOID_TLS + hosts_require_auth = * + allow_localhost + + +# End diff --git a/test/confs/3465 b/test/confs/3465 new file mode 100644 index 000000000..adadeb059 --- /dev/null +++ b/test/confs/3465 @@ -0,0 +1,74 @@ +# Exim test configuration 3465 + +HOSTS_AVOID_TLS= + +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 = accept + +domainlist local_domains = test.ex + +log_selector = +smtp_no_mail + +queue_only = true + +tls_advertise_hosts = * +tls_certificate = DIR/aux-fixed/cert1 +tls_privatekey = DIR/aux-fixed/cert1 + + +# ----- Authenticators ----- + +begin authenticators + +plain: + driver = plaintext + public_name = PLAIN + server_condition = "\ + ${if and {{eq{$2}{userx}}{eq{$3}{secret1}}}{yes}{no}}" + server_set_id = $2 + client_condition = ${if !eq {$tls_cipher}{}} + client_send = ^userx^secret1 + +login: + driver = plaintext + public_name = LOGIN + server_prompts = User Name : Password + server_condition = "\ + ${if and {{eq{$auth1}{usery}}{eq{$auth2}{secret2}}}{yes}{no}}" + server_set_id = $auth1 + client_send = : usery : secret2 + + +# ----- Routers ----- + +begin routers + +r1: + driver = accept + transport = t1 + + +# ----- Transports ----- + +begin transports + +t1: + driver = smtp + hosts = 127.0.0.1 + port = PORT_D + hosts_avoid_tls = HOSTS_AVOID_TLS + hosts_require_auth = * + allow_localhost + + +# End diff --git a/test/log/3455 b/test/log/3455 new file mode 100644 index 000000000..7e5853647 --- /dev/null +++ b/test/log/3455 @@ -0,0 +1,12 @@ +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtpsa X=TLS-1.0:RSA_AES_256_CBC_SHA1:32 A=plain:userx S=sss id=E10HmaX-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmaX-0005vi-00 => userz@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] X=TLS-1.0:RSA_AES_256_CBC_SHA1:32 +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qf +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtpa A=login:usery S=sss id=E10HmaX-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 => userz@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qf diff --git a/test/log/3465 b/test/log/3465 new file mode 100644 index 000000000..231636829 --- /dev/null +++ b/test/log/3465 @@ -0,0 +1,12 @@ +1999-03-02 09:44:33 exim x.yz daemon started: pid=pppp, no queue runs, listening for SMTP on port 1225 +1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtpsa X=TLSv1:AES256-SHA:256 A=plain:userx S=sss id=E10HmaX-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmaX-0005vi-00 => userz@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] X=TLSv1:AES256-SHA:256 +1999-03-02 09:44:33 10HmaX-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qf +1999-03-02 09:44:33 Start queue run: pid=pppp -qf +1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex H=localhost (myhost.test.ex) [127.0.0.1] P=esmtpa A=login:usery S=sss id=E10HmaX-0005vi-00@myhost.test.ex +1999-03-02 09:44:33 10HmaY-0005vi-00 => userz@test.ex R=r1 T=t1 H=127.0.0.1 [127.0.0.1] +1999-03-02 09:44:33 10HmaY-0005vi-00 Completed +1999-03-02 09:44:33 End queue run: pid=pppp -qf diff --git a/test/scripts/3450-plaintext-GnuTLS/3455 b/test/scripts/3450-plaintext-GnuTLS/3455 new file mode 100644 index 000000000..52a93b50d --- /dev/null +++ b/test/scripts/3450-plaintext-GnuTLS/3455 @@ -0,0 +1,12 @@ +# TLS (client: test for encrypted before authenticating) +exim -DSERVER=server -bd -oX PORT_D +**** +exim userz@test.ex +Message 1. +**** +exim -qf +**** +exim -qf -DHOSTS_AVOID_TLS=* +**** +killdaemon +no_msglog_check diff --git a/test/scripts/3460-plaintext-OpenSSL/3465 b/test/scripts/3460-plaintext-OpenSSL/3465 new file mode 100644 index 000000000..52a93b50d --- /dev/null +++ b/test/scripts/3460-plaintext-OpenSSL/3465 @@ -0,0 +1,12 @@ +# TLS (client: test for encrypted before authenticating) +exim -DSERVER=server -bd -oX PORT_D +**** +exim userz@test.ex +Message 1. +**** +exim -qf +**** +exim -qf -DHOSTS_AVOID_TLS=* +**** +killdaemon +no_msglog_check diff --git a/test/stdout/2022 b/test/stdout/2022 index 4630f0897..b2f4a14f4 100644 --- a/test/stdout/2022 +++ b/test/stdout/2022 @@ -21,7 +21,7 @@ Succeeded in starting TLS ??? 214- <<< 214-Commands supported: ??? 214 -<<< 214 AUTH STARTTLS HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP +<<< 214 AUTH HELO EHLO MAIL RCPT DATA NOOP QUIT RSET HELP >>> quit ??? 221 <<< 221 myhost.test.ex closing connection diff --git a/test/stdout/3407 b/test/stdout/3407 index 274c68c1a..73fe5449e 100644 --- a/test/stdout/3407 +++ b/test/stdout/3407 @@ -1,5 +1,6 @@ a1 authenticator: +client_condition = driver = plaintext public_name = PLAIN server_advertise_condition = @@ -12,6 +13,7 @@ client_send = server_prompts = a2 authenticator: +client_condition = driver = plaintext public_name = PLAIN server_advertise_condition = @@ -24,6 +26,7 @@ client_send = server_prompts = a3 authenticator: +client_condition = driver = plaintext public_name = LOGIN server_advertise_condition = @@ -36,6 +39,7 @@ client_send = server_prompts = a4 authenticator: +client_condition = driver = plaintext public_name = LOGIN server_advertise_condition = -- 2.30.2