[exim] CRAM-MD5 with Courier authdaemon (with one wishlist …

Top Page
Delete this message
Reply to this message
Author: Jakob Hirsch
Date:  
To: 'Exim-users'
Subject: [exim] CRAM-MD5 with Courier authdaemon (with one wishlist suggestion and a security question)
Hi,

if somebody is interested, I put together an authenticator to use
CRAM-MD5 with Courier's authdaemon:

AUTHDAEMON_SOCKET = /var/run/authdaemon.courier-imap/socket

acl_smtp_auth = acl_check_auth

acl_check_auth:
accept set acl_c0 = <$pid.$tod_epoch@$primary_hostname>


# CRAM-MD5, RFC2195
cram_md5:
   driver = plaintext
   public_name = CRAM-MD5
   server_prompts = $acl_c0
   server_set_id = ${sg {${extract {1}{ }{$1}}} {[^a-zA-Z0-9.-_]} {?}}
   server_condition = ${if eq \
     {${extract {ADDRESS} \
       {${readsocket{AUTHDAEMON_SOCKET} \
         {AUTH 
${strlen:exim\ncram-md5\n${str2b64:$acl_c0}\n${str2b64:$1}\n}\nexim\ncram-md5\n${str2b
64:$acl_c0}\n${str2b64:$1}\n} \
       }} \
     {$value} fail}} \
     {${extract {1}{ }{$1}}} \
     {yes}}



This should probably go into the Wiki, but I wanted to get some input first.


Notes:

- Exim's builtin cram expects to get the plaintext password, so I had to
abuse the plaintext driver.

- We need the challenge from server_prompts in server_condition, but it
has to be unique at least per connection (and $pid itself is too weak),
so I use an ACL variable. That's not really neat, but I could not find a
better solution.
I read in the archive the suggestion to use a macro, but that did not
work (probably because the macro is expanded every time).
Phil, maybe you could put on the wishlist to have server_prompts in a
variable (though server_prompts is a list and I would need a string).

- You need at least Exim 4.43 because of str2b64

- authdaemon sometime just returns an empty string instead of FAIL
(maybe because of invalid input), so I try to extract ADDRESS and force
the expansion to fail if that key is not present (in contrast to the
login and plain authenticators in the FAQ, which just compare to "FAIL\n").

- I replace invalid characters in the user name trough sg. The login
name is logged as it is, so if there is any non-ASCII character in the
login name, it ends up in the log and and I don't want binary data
there. Phil, shouldn't that be prevented in the logging code? Don't know
if it could be used in an attack...

- You can also add cram-sha1 by replacing every "md5" with "sha1". (Does
anybody know a MUA that's supports it?)
Even though everybody now thinks SHA-1 is insecure...

- To use CRAM-*, you need to add md5/sha1 hashed passwords in your
userdb. Add them with
# userdbpw -hmac-md5 | userdb $user set hmac-md5pw
(and sha1 respectively) and run makeuserdb afterwards. Your old stored
passwords will not work.

- Tested on Exim 4.50 (and the 4.47 snapshot)