From 7befa435e5664f43d90bf5a2703fcf4f2a26139e Mon Sep 17 00:00:00 2001 From: Philip Hazel Date: Mon, 16 Oct 2006 13:43:21 +0000 Subject: [PATCH] Update Dovecot authenticator to (a) lock out tabs (b) add extra parameters "secured" and "valid-client-cert" when relevant. --- doc/doc-txt/ChangeLog | 12 ++++- doc/doc-txt/NewStuff | 8 +++- src/src/auths/dovecot.c | 54 +++++++++++++++++----- src/src/auths/get_no64_data.c | 5 ++- test/confs/9350 | 7 +++ test/log/9350 | 2 + test/rejectlog/9350 | 2 + test/scripts/9350-Dovecot/9350 | 48 ++++++++++++++++++++ test/stdout/9350 | 82 ++++++++++++++++++++++++++++++++++ 9 files changed, 203 insertions(+), 17 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 2355e01fc..124101d78 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.408 2006/10/16 10:58:39 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.409 2006/10/16 13:43:21 ph10 Exp $ Change log file for Exim from version 4.21 ------------------------------------------- @@ -65,7 +65,7 @@ PH/11 Callouts were setting the name used for EHLO/HELO from $smtp_active_ addresses), $smtp_active_hostname is used. PH/12 Installed Andrey Panin's patch to add a dovecot authenticator. Various - tweaks were necessary in order to get it to work: + tweaks were necessary in order to get it to work (see also 21 below): (a) The code assumed that strncpy() returns a negative number on buffer overflow, which isn't the case. Replaced with Exim's string_format() function. @@ -142,6 +142,14 @@ PH/20 It was discovered that the GnuTLS code had support for RSA_EXPORT, a effect of slowing Exim down by computing (never used) parameters for the RSA_EXPORT functionality. +PH/21 On the advice of Timo Sirainen, added a check to the dovecot + authenticator to fail if there's a tab character in the incoming data + (there should never be unless someone is messing about, as it's supposed + to be base64-encoded). Also added, on Timo's advice, the "secured" option + if the connection is using TLS or if the remote IP is the same as the + local IP, and the "valid-client-cert option" if a client certificate has + been verified. + Exim version 4.63 ----------------- diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff index 4ee55fdcf..b66cfb593 100644 --- a/doc/doc-txt/NewStuff +++ b/doc/doc-txt/NewStuff @@ -1,4 +1,4 @@ -$Cambridge: exim/doc/doc-txt/NewStuff,v 1.115 2006/10/03 15:11:22 ph10 Exp $ +$Cambridge: exim/doc/doc-txt/NewStuff,v 1.116 2006/10/16 13:43:21 ph10 Exp $ New Features in Exim -------------------- @@ -72,6 +72,12 @@ Version 4.64 server_name = /var/run/dovecot/auth-client server_setid = $auth1 + If the SMTP connection is encrypted, or if $sender_host_address is equal to + $interface_address (that is, the connection is local), the "secured" option + is passed in the Dovecot authentication command. If, for a TLS connection, a + client certificate has been verified, the "valid-client-cert" option is + passed. + 4. The variable $message_headers_raw provides a concatenation of all the messages's headers without any decoding. This is in contrast to $message_headers, which does RFC2047 decoding on the header contents. diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c index 6168ac9a2..c11b2fe9b 100644 --- a/src/src/auths/dovecot.c +++ b/src/src/auths/dovecot.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/auths/dovecot.c,v 1.1 2006/10/02 13:38:18 ph10 Exp $ */ +/* $Cambridge: exim/src/src/auths/dovecot.c,v 1.2 2006/10/16 13:43:22 ph10 Exp $ */ /* * Copyright (c) 2004 Andrey Panin @@ -94,6 +94,8 @@ static int strcut(char *str, char **ptrs, int nptrs) goto out; \ } while(0) + + /************************************************* * Server entry point * *************************************************/ @@ -105,6 +107,8 @@ int auth_dovecot_server(auth_instance *ablock, uschar *data) struct sockaddr_un sa; char buffer[4096]; char *args[8]; + uschar *auth_command; + uschar *auth_extra_data = US""; int nargs, tmp; int cuid = 0, cont = 1, found = 0, fd, ret = DEFER; FILE *f; @@ -186,31 +190,49 @@ int auth_dovecot_server(auth_instance *ablock, uschar *data) if (!found) goto out; - fprintf(f, "VERSION\t%d\t%d\nCPID\t%d\n" - "AUTH\t%d\t%s\tservice=smtp\trip=%s\tlip=%s\tresp=%s\n", - VERSION_MAJOR, VERSION_MINOR, getpid(), cuid, - ablock->public_name, sender_host_address, interface_address, - data ? (char *) data : ""); + /* Added by PH: data must not contain tab (as it is + b64 it shouldn't, but check for safety). */ + + if (Ustrchr(data, '\t') != NULL) { + ret = FAIL; + goto out; + } + + /* Added by PH: extra fields when TLS is in use or if the TCP/IP + connection is local. */ + + if (tls_cipher != NULL) + auth_extra_data = string_sprintf("secured\t%s%s", + tls_certificate_verified? "valid-client-cert" : "", + tls_certificate_verified? "\t" : ""); + else if (Ustrcmp(sender_host_address, interface_address) == 0) + auth_extra_data = US"secured\t"; + /**************************************************************************** The code below was the original code here. It didn't work. A reading of the file auth-protocol.txt.gz that came with Dovecot 1.0_beta8 indicated that - this was not right. Maybe something changed. I changed it to the above, and - it seems to be better. PH + this was not right. Maybe something changed. I changed it to move the + service indication into the AUTH command, and it seems to be better. PH fprintf(f, "VERSION\t%d\t%d\r\nSERVICE\tSMTP\r\nCPID\t%d\r\n" "AUTH\t%d\t%s\trip=%s\tlip=%s\tresp=%s\r\n", VERSION_MAJOR, VERSION_MINOR, getpid(), cuid, ablock->public_name, sender_host_address, interface_address, data ? (char *) data : ""); + + Subsequently, the command was modified to add "secured" and "valid-client- + cert" when relevant. ****************************************************************************/ - HDEBUG(D_auth) debug_printf("sent: VERSION\t%d\t%d\nsent: CPID\t%d\n" - "sent: AUTH\t%d\t%s\tservice=smtp\trip=%s\tlip=%s\tresp=%s\n", + auth_command = string_sprintf("VERSION\t%d\t%d\nCPID\t%d\n" + "AUTH\t%d\t%s\tservice=smtp\t%srip=%s\tlip=%s\tresp=%s\n", VERSION_MAJOR, VERSION_MINOR, getpid(), cuid, - ablock->public_name, sender_host_address, interface_address, - data ? (char *) data : ""); + ablock->public_name, auth_extra_data, sender_host_address, + interface_address, data ? (char *) data : ""); + fprintf(f, "%s", auth_command); + HDEBUG(D_auth) debug_printf("sent: %s", auth_command); while (1) { if (fgets(buffer, sizeof(buffer), f) == NULL) { @@ -235,6 +257,14 @@ int auth_dovecot_server(auth_instance *ablock, uschar *data) goto out; } + /* Added by PH: data must not contain tab (as it is + b64 it shouldn't, but check for safety). */ + + if (Ustrchr(data, '\t') != NULL) { + ret = FAIL; + goto out; + } + if (fprintf(f, "CONT\t%d\t%s\r\n", cuid, data) < 0) OUT("authentication socket write error"); diff --git a/src/src/auths/get_no64_data.c b/src/src/auths/get_no64_data.c index 9c1461d05..ab2de0ccf 100644 --- a/src/src/auths/get_no64_data.c +++ b/src/src/auths/get_no64_data.c @@ -1,4 +1,4 @@ -/* $Cambridge: exim/src/src/auths/get_no64_data.c,v 1.3 2006/02/07 11:19:01 ph10 Exp $ */ +/* $Cambridge: exim/src/src/auths/get_no64_data.c,v 1.4 2006/10/16 13:43:22 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * @@ -16,7 +16,8 @@ /* This function is used by authentication drivers to output a challenge to the SMTP client and read the response line. This version does not use base -64 encoding for the text on the 334 line. It is used by the SPA authenticator. +64 encoding for the text on the 334 line. It is used by the SPA and dovecot +authenticators. Arguments: aptr set to point to the response (which is in big_buffer) diff --git a/test/confs/9350 b/test/confs/9350 index fd75156f5..4ba8e6d68 100644 --- a/test/confs/9350 +++ b/test/confs/9350 @@ -15,6 +15,13 @@ gecos_name = CALLER_NAME acl_smtp_rcpt = check_recipient +tls_advertise_hosts = * +tls_certificate = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} +tls_privatekey = ${if eq {SERVER}{server}{DIR/aux-fixed/cert1}fail} + +tls_verify_hosts = HOSTIPV4 +tls_verify_certificates = ${if eq {SERVER}{server}{DIR/aux-fixed/cert2}fail} + # ----- ACL ----- diff --git a/test/log/9350 b/test/log/9350 index 8d693548e..1fe64551f 100644 --- a/test/log/9350 +++ b/test/log/9350 @@ -2,3 +2,5 @@ ******** SERVER ******** 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 dovecot authenticator failed for (xxxx) [127.0.0.1]: 535 Incorrect authentication data (set_id=userx) +1999-03-02 09:44:33 dovecot authenticator failed for (xxxx) [127.0.0.1]: 535 Incorrect authentication data (set_id=userx) +1999-03-02 09:44:33 dovecot authenticator failed for (xxxx) [ip4.ip4.ip4.ip4]: 535 Incorrect authentication data (set_id=userx) diff --git a/test/rejectlog/9350 b/test/rejectlog/9350 index 1af78c03d..a3f2a0ab8 100644 --- a/test/rejectlog/9350 +++ b/test/rejectlog/9350 @@ -1,3 +1,5 @@ ******** SERVER ******** 1999-03-02 09:44:33 dovecot authenticator failed for (xxxx) [127.0.0.1]: 535 Incorrect authentication data (set_id=userx) +1999-03-02 09:44:33 dovecot authenticator failed for (xxxx) [127.0.0.1]: 535 Incorrect authentication data (set_id=userx) +1999-03-02 09:44:33 dovecot authenticator failed for (xxxx) [ip4.ip4.ip4.ip4]: 535 Incorrect authentication data (set_id=userx) diff --git a/test/scripts/9350-Dovecot/9350 b/test/scripts/9350-Dovecot/9350 index 55b6c1e42..3325f246c 100644 --- a/test/scripts/9350-Dovecot/9350 +++ b/test/scripts/9350-Dovecot/9350 @@ -1,6 +1,7 @@ # Dovecot authentication (server only) exim -DSERVER=server -bd -oX PORT_D **** +# Try without TLS client -t3 127.0.0.1 PORT_D ??? 220 EHLO xxxx @@ -8,6 +9,53 @@ EHLO xxxx ??? 250- ??? 250- ??? 250- +??? 250- +??? 250 +AUTH PLAIN AHVzZXJ4AHNlY3JldA== +??? 535 +quit +??? 221 +**** +# TLS, but no client certificate +client-gnutls -t3 127.0.0.1 PORT_D +??? 220 +EHLO xxxx +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +STARTTLS +??? 220 +EHLO xxxx +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +AUTH PLAIN AHVzZXJ4AHNlY3JldA== +??? 535 +quit +??? 221 +**** +# TLS with client certificate +client-gnutls -t3 HOSTIPV4 PORT_D DIR/aux-fixed/cert2 DIR/aux-fixed/cert2 +??? 220 +EHLO xxxx +??? 250- +??? 250- +??? 250- +??? 250- +??? 250- +??? 250 +STARTTLS +??? 220 +EHLO xxxx +??? 250- +??? 250- +??? 250- +??? 250- ??? 250 AUTH PLAIN AHVzZXJ4AHNlY3JldA== ??? 535 diff --git a/test/stdout/9350 b/test/stdout/9350 index 87f70de47..3a42a6729 100644 --- a/test/stdout/9350 +++ b/test/stdout/9350 @@ -10,6 +10,88 @@ Connecting to 127.0.0.1 port 1225 ... connected <<< 250-PIPELINING ??? 250- <<< 250-AUTH PLAIN +??? 250- +<<< 250-STARTTLS +??? 250 +<<< 250 HELP +>>> AUTH PLAIN AHVzZXJ4AHNlY3JldA== +??? 535 +<<< 535 Incorrect authentication data +>>> quit +??? 221 +<<< 221 myhost.test.ex closing connection +End of script +Connecting to 127.0.0.1 port 1225 ... connected +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO xxxx +??? 250- +<<< 250-myhost.test.ex Hello xxxx [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-AUTH PLAIN +??? 250- +<<< 250-STARTTLS +??? 250 +<<< 250 HELP +>>> STARTTLS +??? 220 +<<< 220 TLS go ahead +Attempting to start TLS +Succeeded in starting TLS +>>> EHLO xxxx +??? 250- +<<< 250-myhost.test.ex Hello xxxx [127.0.0.1] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-AUTH PLAIN +??? 250 +<<< 250 HELP +>>> AUTH PLAIN AHVzZXJ4AHNlY3JldA== +??? 535 +<<< 535 Incorrect authentication data +>>> quit +??? 221 +<<< 221 myhost.test.ex closing connection +End of script +Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected +Certificate file = TESTSUITE/aux-fixed/cert2 +Key file = TESTSUITE/aux-fixed/cert2 +??? 220 +<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000 +>>> EHLO xxxx +??? 250- +<<< 250-myhost.test.ex Hello xxxx [ip4.ip4.ip4.ip4] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-AUTH PLAIN +??? 250- +<<< 250-STARTTLS +??? 250 +<<< 250 HELP +>>> STARTTLS +??? 220 +<<< 220 TLS go ahead +Attempting to start TLS +Succeeded in starting TLS +>>> EHLO xxxx +??? 250- +<<< 250-myhost.test.ex Hello xxxx [ip4.ip4.ip4.ip4] +??? 250- +<<< 250-SIZE 52428800 +??? 250- +<<< 250-PIPELINING +??? 250- +<<< 250-AUTH PLAIN ??? 250 <<< 250 HELP >>> AUTH PLAIN AHVzZXJ4AHNlY3JldA== -- 2.25.1