Storing mail credentials using bcrypt
We wanted to migrate the hashes of our mail user database for some time now. We couldn’t sleep at night anymore since there were still md5 passwords in there. This database is mainly used by exim and dovecot in our setup.
First our plan was to migrate to salted sha512 like it is described in the dovecot wiki. But this migration approach has a huge problem: all passwords are sent to the sql server in plaintext – just to be able to refer to them in a post login script. This is rather insane since there is really no technical reason why the sql server needs the plaintext passwords.
So we went off writing our own authentication script that implements the dovecot checkpassword specification. Now we can migrate our hashes (or everything else we want to do) while checking the password.
And most importantly: inspired by this little post we also decided that it would make sense to use a more sane hash function to store the passwords – namely bcrypt instead of sha.
If you want to check out our solution skip down to the dovecot howto. Please just write us if you need help with this. It is still quite alpha and not so well documented.
Other services
Our MTA (Exim) now uses imap to authenticate smtp users. The solution is originally from here.
For the users to change their passwords we use horde-passwd which does not support bcrypt. We fixed this by extending the sql backend with a custom driver that assumes passwords are in bcrypt. We agree that this is a hack…
Future Plans
The whole approach should be integrated into the tools we use. In the long run it would definitely pay off to directly extend dovecot, exim and horde to support this authentication. If we ever have time we should write patches for them.
Since we now have our custom authentication solution it would be cool to do even more stuff with it.
For example a long standing plan would be to use encfs to encrypt the maildirs. On login we would decrypt the maildir of the user and copy in all mails he got since the last login. When he’s not logged in we couldn’t access his mailbox anymore!
Dovecot Howto
If you’re interested in using our checkpassword script, it is available in our git repo. To get it running you need to:
- set CONFIG_DIR in checkpasswd-bcrypt.incl.rb
- adapt checkpasswd-bcrypt.conf.rb to your needs by providing a db access and the names of your db columns
- adapt the sql queries in checkpasswd-bcrypt.sql.conf.rb to your setup
(There is also a query to store the month of the last login. You can disable this in the config with KeepLastlogin = false) - set the dovecot config to use the checkpasswd-bcrypt.rb script
I plan to do exactly the same, so it’s great to see someone having the same idea.
Unfortunately your checkpassword script isn’t available anymore đ
Thanks for this post!
oh, thanks for the hint. the repo moved. i fixed it now.
looks like the repository moved again? the link to the checkpassword script doesn’t work
Should be fixed for a while now