====== Courier authdaemon ====== ===== Courier authdaemon problem ===== I got an hard-to-solve problem on a Debian Sarge box, using Exim4 and SMTP authentication against Courier authdaemon. This is also reported as **Debian bug [[http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=336979|336979]]**, which is now solved but deep insight is missing there. The symptom was that an existing user can provide a **random password** and gain **authenticated user** rights. An existing user means that also **root** can succeed. Here it is an SMTP session: # telnet localhost 25 Trying 127.0.0.1... Connected to localhost.localdomain. Escape character is '^]'. 220 petra-osm.texnet.org ESMTP Exim 4.50 Wed, 07 Mar 2007 16:12:47 +0100 EHLO test 250-petra-osm.texnet.org Hello test [127.0.0.1] 250-SIZE 52428800 250-PIPELINING 250-AUTH PLAIN LOGIN 250-STARTTLS 250 HELP AUTH LOGIN 334 VXNlcm5hbWU6 cm9vdA== 334 UGFzc3dvcmQ6 bXlzZWNyZXQ= 235 Authentication succeeded Notice that **''%%cm9vdA==%%''** means **root** in base64 encoding, and **''%%bXlzZWNyZXQ=%%''** is a random password. The problem turned out to be the sum of two bugs. The first bug was in the Exim4 authenticators configuration copied from this site: [[http://www.devco.net/archives/2004/06/10/smtp_auth_with_exim_and_courier_authdaemon.php|www.devco.net]]. The snippet of configration is: # WARNING: DO NOT USE THIS UNSAFE AUTHENTICATOR!!! login: driver = plaintext public_name = LOGIN server_prompts = Username:: : Password:: server_condition = ${if eq {${readsocket{/usr/run/courier/authdaemon/socket} \ {AUTH ${strlen:exim\nlogin\n$1\n$2\n}\nexim\nlogin\n$1\n$2\n}}}{FAIL\n} {no}{yes}} server_set_id = $1 The very problem of this configuration is that Exim will **exptect the string ''FAIL''** from the Courier authdaemon socket on authentication failure. Every other result will be interpreted as an authentication success. The second problem is that the **authdaemon has a bug** (at least on Debian Sarge, authdaemon version 0.47-4sarge5): in case of an existing user with a wrong password nor the authentication data nor the **FAIL** string is returned. The problem was solved changing the Exim4 authenticator as suggested by the [[http://www.exim.org/eximwiki/FAQ/Policy_controls/Q0730|Exim FAQ]] (here my [[exim|actual config]]). Also upgrading to **courier-authdaemon 0.58-4** (Debian Etch) fixed the authdaemon bug. ===== Crittografia TLS ===== Per abilitare la crittografia TLS sulla connessione POP3 bisogna installare il pacchetto **courier-pop-ssl**, per verificare se TLS รจ disponibile basta eseguire il comando **''STLS''** dentro una sessione POP3, la risposta deve essere qualcosa del genere: +OK Hello there. STLS +OK Begin SSL/TLS negotiation now. ===== Tracing the Courier authdaemon socket ===== I wrote a little perl script to trace and debug the talk to the authdaemon named socket. The authdaemon expects 5 parameters to be written to the socket: the length in bytes of the entire input, the **SERVICE** name (tipically the name of the program requesting the authentication), the **AUTHTYPE** login (a typical userid/password authentication request) and the **AUTHDATA** consisting of login and password. Each piece of input is separated by a new line. #!/usr/bin/perl use Socket; use strict; my $login = $ARGV[0]; my $pass = $ARGV[1]; my $socket = '/var/run/courier/authdaemon/socket'; my $line; my $auth_string; if ( $#ARGV != 1 ) { print "Usage: courier-authdaemon-test [login] [password]\n"; exit 1; } socket(SOCK, PF_UNIX, SOCK_STREAM, 0) || die "socket: $!"; connect(SOCK, sockaddr_un($socket)) || die "connect: $!"; $line = "postfix\nlogin\n$login\n$pass\n"; $line = length($line) . "\n" . $line; print "=== Send to socket:\n" . $line; send (SOCK, "AUTH $line", 0); while ($line = ) { print "=== Read from socket: " . $line; } And here it is the output of the script, using an existing user with a fake password: # ./authdaemon_test root mysecret === Send to socket: 25 exim login root mysecret The **''FAIL''** string is missing. Here instead the result with a non-existing user: # ./authdaemon_test username mysecret === Send to socket: 29 exim login username mysecret === Read from socket: FAIL When an authentication request succeed, this is the output of authdaemon: # ./authdaemon_test niccolo my_secret === Send to socket: 28 exim login niccolo my_secret === Read from socket: USERNAME=niccolo === Read from socket: GID=111 === Read from socket: HOME=/home/niccolo === Read from socket: ADDRESS=niccolo === Read from socket: NAME=Niccolo Rigacci,,, === Read from socket: PASSWD=$1$0GPemE0H$Ki8KAUWDrxX2SMBA.r84W1 === Read from socket: . ===== A more secure Exim authenticator ===== This is a more secure and robust authenticator (against Courier authdaemon) for Exim4 on a Debian Etch. It serves both the **''AUTH LOGIN''** and the **''AUTH PLAIN''** schemas: ### auth/25_local-courier_authdaemon ################################# # Authenticate against courier authdaemon # This has been copied from # http://www.exim.org/eximwiki/FAQ/Policy_controls/Q0730 # Possible pitfall: access rights on /var/run/courier/authdaemon/socket. # SMTP authenticator "AUTH LOGIN" login_courier_authdaemon: driver = plaintext public_name = LOGIN server_prompts = Username:: : Password:: server_condition = ${extract {address} {${readsocket{/var/run/courier/authdaemon/socket} \ {AUTH ${strlen:exim\nlogin\n$1\n$2\n}\nexim\nlogin\n$1\n$2\n} }} {yes} fail} server_set_id = $1 # Announce this authenticator also if unencrypted connection? .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS server_advertise_condition = ${if eq{$tls_cipher}{} {no} {yes}} .endif # SMTP authenticator "AUTH PLAIN" plain_courier_authdaemon: driver = plaintext public_name = PLAIN server_prompts = : server_condition = ${extract {address} {${readsocket{/var/run/courier/authdaemon/socket} \ {AUTH ${strlen:exim\nlogin\n$2\n$3\n}\nexim\nlogin\n$2\n$3\n} }} {yes} fail} server_set_id = $2 # Announce this authenticator also if unencrypted connection? .ifndef AUTH_SERVER_ALLOW_NOTLS_PASSWORDS server_advertise_condition = ${if eq{$tls_cipher}{} {no} {yes}} .endif ===== Authenticate with an alternative login name ===== How to authenticate users with a login name like **user@doamain.org**, instead of the Unix system name (Debian GNU/Linux 4.0 Etch). Create a password file **''/etc/courier/userdb''** with all the relevant information (**do not break the line!**): info@2domain.org uid=1086|gid=1086|home=/home/info|shell=/bin/false |systempw=$1$GiNkrEZX$UTOWQkZZf0pp2TEOuyEu1/|mail=/home/info/Maildir **WARNING:** after the login name there must be a **tab character**, not spaces. Compile the file with **''makeuserdb''**. Add the **authuserdb** module to the **authmodulelist** into configuration file **''/etc/courier/authdaemonrc''**: authmodulelist="authuserdb authpam" Reload the courier-authdaemon. ===== Problema con dhparams.pem e SSL ===== Facendo un aggiornamento Debian da Wheezy a Jessie la connessione cifrata SSL di IMAP e POP3 smette di funzionare. Pare che il problema sia nella lunghezza del file **''/etc/courier/dhparams.pem''**, che con la nuova versione deve essere di almeno 2048 bit. Nei file di log si trova: couriertls: accept: error:14094417:SSL routines:SSL3_READ_BYTES:sslv3 alert illegal parameter Vedere i due bug report: [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=787579|#787579]] e [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=741620|#741620]]. Per generare un file nuovo: DH_BITS=2048 mkdhparams oppure cd /etc/courier/ openssl dhparam -out dhparams.pem 2048