====== 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