[Dovecot] Using pgsql with 'cram-md5 auth' and 'hmac-md5 scheme'
Hello,
I want to use PostgreSQL to store my Dovecot users. I setup a very basic configuration, following word for word this page http://wiki.dovecot.org/DovecotPostgresql and it works ... almost.
In fact, it works if I use PLAIN password scheme in my database. However, I would like to store them encrypted. But, if I replace the password field for my user with {HMAC-MD5}-... (the password generated by dovecotpw), it doesn't work.
Here is the log, using PLAIN password scheme (all debug options activated) :
auth(default): client in: AUTH 1 CRAM-MD5 service=IMAP secured lip=127.0.0.1 rip=127.0.0.1 auth(default): client out: CONT 1 PDU3NTgxMTE5MTcwMTYzNjguMTE1ODAxMTQzN0BkZWI2ND4= auth(default): client in: CONT 1 am9uIDJjN2RmMDVmZWZiNWU4MmE0MzFkMjM2YThhYzc2MDAx auth(default): sql(jon,127.0.0.1): query: SELECT userid as user, password FROM users WHERE userid = 'jon' auth(default): password(jon,127.0.0.1): Credentials: 3fd9989457cb3edf1fb8d31dddaf11f3f0efee3423aeb9ebf9bbe981f86a079b auth(default): client out: OK 1 user=jon auth(default): master in: REQUEST 1 23748 1 auth(default): sql(jon,127.0.0.1): SELECT home, uid, gid FROM users WHERE userid = 'jon' auth(default): master out: USER 1 jon home=/var/mail/jon/ uid=5000 gid=5000 IMAP(jon): Effective uid=5000, gid=5000 IMAP(jon): maildir: data=/var/mail/jon IMAP(jon): maildir:root=/var/mail/jon, index=/var/mail/jon, control=, inbox= imap-login: Login: user=<jon>, method=CRAM-MD5, rip=127.0.0.1, lip=127.0.0.1, secured IMAP(jon): Disconnected: Logged out
And here is the log, using HMAC-MD5 password scheme (all debug options activated too) :
auth(default): client in: AUTH 1 CRAM-MD5 service=IMAP secured lip=127.0.0.1 rip=127.0.0.1 auth(default): client out: CONT 1 PDI0MDc4NTQzMDc5NjU2NTIuMTE1ODAxMTkxNUBkZWI2ND4= auth(default): client in: CONT 1 am9uIDViNmE4NDI5ZjUzZTQ3YTEzZmEzNjhiOThlYjI5OTFi auth(default): sql(jon,127.0.0.1): query: SELECT userid as user, password FROM users WHERE userid = 'jon' auth(default): password(jon,127.0.0.1): Credentials: auth(default): cram-md5(jon,127.0.0.1): password mismatch auth(default): client out: FAIL 1 user=jon imap-login: Disconnected: user=<jon>, method=CRAM-MD5, rip=127.0.0.1, lip=127.0.0.1, secured
The login + password used for those tests are 'jon'/'jonpwd'. In the
second example, I didn't get any Credentials, whereas in the first case
(PLAIN scheme), the Credentials output correspond to the 'dovecotpw'
generated password (as in dovecotpw -s HMAC-MD5 -p jonpwd
).
I don't know if it's normal or not.
So, I'm not sure what to do next :/ I use this kind of 'auth mechanism'/'password scheme' on another computer, with passwd-like files, and it works. So, I don't know why the same data, coming from another location, doesn't work.
Any help would be greatly appreciated ! Thanks,
-- Jonathan
On 255, 09 12, 2006 at 12:13:05AM +0200, Jonathan Ballet wrote:
Hello,
I want to use PostgreSQL to store my Dovecot users. I setup a very basic configuration, following word for word this page http://wiki.dovecot.org/DovecotPostgresql and it works ... almost.
In fact, it works if I use PLAIN password scheme in my database. However, I would like to store them encrypted. But, if I replace the password field for my user with {HMAC-MD5}-... /^
| Is this '-' just a typo ? It is not needed here.
(the password generated by dovecotpw), it doesn't work.
Here is the log, using PLAIN password scheme (all debug options activated) :
auth(default): client in: AUTH 1 CRAM-MD5 service=IMAP secured lip=127.0.0.1 rip=127.0.0.1 auth(default): client out: CONT 1 PDU3NTgxMTE5MTcwMTYzNjguMTE1ODAxMTQzN0BkZWI2ND4= auth(default): client in: CONT 1 am9uIDJjN2RmMDVmZWZiNWU4MmE0MzFkMjM2YThhYzc2MDAx auth(default): sql(jon,127.0.0.1): query: SELECT userid as user, password FROM users WHERE userid = 'jon' auth(default): password(jon,127.0.0.1): Credentials: 3fd9989457cb3edf1fb8d31dddaf11f3f0efee3423aeb9ebf9bbe981f86a079b auth(default): client out: OK 1 user=jon auth(default): master in: REQUEST 1 23748 1 auth(default): sql(jon,127.0.0.1): SELECT home, uid, gid FROM users WHERE userid = 'jon' auth(default): master out: USER 1 jon home=/var/mail/jon/ uid=5000 gid=5000 IMAP(jon): Effective uid=5000, gid=5000 IMAP(jon): maildir: data=/var/mail/jon IMAP(jon): maildir:root=/var/mail/jon, index=/var/mail/jon, control=, inbox= imap-login: Login: user=<jon>, method=CRAM-MD5, rip=127.0.0.1, lip=127.0.0.1, secured IMAP(jon): Disconnected: Logged out
And here is the log, using HMAC-MD5 password scheme (all debug options activated too) :
auth(default): client in: AUTH 1 CRAM-MD5 service=IMAP secured lip=127.0.0.1 rip=127.0.0.1 auth(default): client out: CONT 1 PDI0MDc4NTQzMDc5NjU2NTIuMTE1ODAxMTkxNUBkZWI2ND4= auth(default): client in: CONT 1 am9uIDViNmE4NDI5ZjUzZTQ3YTEzZmEzNjhiOThlYjI5OTFi auth(default): sql(jon,127.0.0.1): query: SELECT userid as user, password FROM users WHERE userid = 'jon' auth(default): password(jon,127.0.0.1): Credentials: auth(default): cram-md5(jon,127.0.0.1): password mismatch auth(default): client out: FAIL 1 user=jon imap-login: Disconnected: user=<jon>, method=CRAM-MD5, rip=127.0.0.1, lip=127.0.0.1, secured
The login + password used for those tests are 'jon'/'jonpwd'. In the second example, I didn't get any Credentials, whereas in the first case (PLAIN scheme), the Credentials output correspond to the 'dovecotpw' generated password (as in
dovecotpw -s HMAC-MD5 -p jonpwd
). I don't know if it's normal or not.So, I'm not sure what to do next :/ I use this kind of 'auth mechanism'/'password scheme' on another computer, with passwd-like files, and it works. So, I don't know why the same data, coming from another location, doesn't work.
Any help would be greatly appreciated ! Thanks,
-- Jonathan
-- Andrey Panin | Linux and UNIX system administrator pazke@donpac.ru | PGP key: wwwkeys.pgp.net
Jonathan Ballet wrote:
In fact, it works if I use PLAIN password scheme in my database. However, I would like to store them encrypted. But, if I replace the password field for my user with {HMAC-MD5}-... (the password generated by dovecotpw), it doesn't work.
It is not possible to use the CRAM-MD5 authentication method, unless the server has the password in plaintext. Here's why[1]:
The server generates a *one-time* challenge string and sends it to the client;
The client responds with the username followed by a digest, which is a HMAC-MD5 hash of the challenge string and the user's password;
The server then performs the same HMAC-MD5 hashing of the challenge string it just sent and the plaintext users password in the database;
If and only if the two HMAC-MD5 hashes are equivalent, does the authentication succeed.
The problem is you have already hashed the password in the database, but the server does not know what the challenge string that was used (and unlike crypt, the challenge is not stored as part of the hash). There is no way to do what you want using CRAM-MD5 (it's one of the serious design flaws of that method).
HTH
John
-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4501 Forbes Boulevard Suite H Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5748
John Peacock wrote: :
Jonathan Ballet wrote:
In fact, it works if I use PLAIN password scheme in my database. However, I would like to store them encrypted. But, if I replace the password field for my user with {HMAC-MD5}-... (the password generated by dovecotpw), it doesn't work.
It is not possible to use the CRAM-MD5 authentication method, unless the server has the password in plaintext. Here's why[1]:
The server generates a *one-time* challenge string and sends it to the client;
The client responds with the username followed by a digest, which is a HMAC-MD5 hash of the challenge string and the user's password;
The server then performs the same HMAC-MD5 hashing of the challenge string it just sent and the plaintext users password in the database;
If and only if the two HMAC-MD5 hashes are equivalent, does the authentication succeed.
The problem is you have already hashed the password in the database, but the server does not know what the challenge string that was used (and unlike crypt, the challenge is not stored as part of the hash). There is no way to do what you want using CRAM-MD5 (it's one of the serious design flaws of that method).
HTH
John
I think I understand this, but :
How can it works with nearly the same configuration, using passwd-like files instead of pgsql database ? Auth mechanism is set to 'cram-md5', and passwords in the passdb file are HMAC-MD5 encrypted passwords (or, if I am wrong somewhere, they are generated by 'dovecotpw -s HMAC-MD5' and start with {HMAC-MD5}) In fact, this is the configuration I want to migrate from :) I'll put the file configuration at the end of the mail [2].
How dovecotpw generates the HMAC-MD5 encrypted password, if the challenge string used to hash the password is supposed not to be the same each time ? I mean, how could the password be used in HMAC-MD5 format, if dovecot doesn't know the secret key used to hash it ?
Dovecot documentation [1] says that HMAC-MD5 password scheme is used with CRAM-MD5 authentication mechanism. As far as I understand you, it means it is used, not to store/retrieve the password from the password database (whatever it is), but only to 'encrypt' the communication between the client and the server. It's not very clear ...
Is there any documentation referencing which password scheme could be used with an authentification mechanism ? I thought it was in [1], but I might be wrong.
So, what are my options, to have encrypted authentication, and encrypted password ?
Thanks for your answer,
-- Jonathan
[1] : http://wiki.dovecot.org/Authentication/PasswordSchemes [2] : Current working configuration :
# grep -v "^[ ]*#" dovecot.conf | grep -v "^$" protocols = imap disable_plaintext_auth = yes log_path = /var/log/mail/dovecot.log log_timestamp = "%Y-%m-%d %H:%M:%S " default_mail_env = maildir:/var/mail/%u mail_extra_groups = vmail first_valid_uid = 5000 last_valid_uid = 5000 protocol imap { }
protocol lda { postmaster_address = postmaster@example.com } auth default { mechanisms = cram-md5 passdb passwd-file { args = /etc/dovecot/userdb.deny deny = yes } passdb passwd-file { args = /etc/dovecot/userdb } userdb passwd-file { args = /etc/dovecot/userdb } user = root } dict { } plugin { }
# cat userdb jon:{HMAC-MD5}xxxxxxxxxxxxxxxxx:5000:5000::/var/mail/jon:/bin/false::/var/mail/jon
Jonathan Ballet wrote:
- How can it works with nearly the same configuration, using passwd-like files instead of pgsql database ?
Actual passwd files use crypt, which includes the seed before the hashed value.
Auth mechanism is set to 'cram-md5', and passwords in the passdb file are HMAC-MD5 encrypted passwords (or, if I am wrong somewhere, they are generated by 'dovecotpw -s HMAC-MD5' and start with {HMAC-MD5})
I don't see how this can work. I checked the source code and it seems to assume that you have the plaintext password. I don't have the time to trace through the code path to be sure; I help write the AUTH support in a SMTP server, so AFAICT you must have both the plaintext password and the generated challenge in order to use CRAM-MD5.
Is there any documentation referencing which password scheme could be used with an authentification mechanism ? I thought it was in [1], but I might be wrong.
So, what are my options, to have encrypted authentication, and encrypted password ?
AIUI, you need to use PLAIN (authentication) over SSL (encrypted) in order to have an encrypted password on the server.
John
-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4501 Forbes Boulevard Suite H Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5748
John Peacock wrote:
I don't see how this can work. I checked the source code and it seems to assume that you have the plaintext password. I don't have the time to trace through the code path to be sure;
Actually, this bugged me, so I did trace it through. It appears that dovecotpw generates the hash by hashing the password with itself. What happens is that the client sends the password as plaintext, and then dovecot sees that the passdb file includes the {HMAC-MD5} in the password field, hashes the plaintext password with itself, and finally compares it with the stored value.
So, it looks like the way to set this up is:
# get your certificates in place protocols = imaps disable_plaintext_auth = no
auth default { mechanisms = plain passdb passwd-file { args = /etc/dovecot/userdb.deny deny = yes } passdb passwd-file { args = /etc/dovecot/userdb } userdb passwd-file { args = /etc/dovecot/userdb } user = root }
and then add your database to the list of passdb's, with the value {HMAC-MD5}xxxxxxxxxxxxxxxxx as the contents of the password field.
HTH
John
-- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4501 Forbes Boulevard Suite H Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5748
Le Tue, 12 Sep 2006 12:02:57 -0400, John Peacock jpeacock@rowman.com a _crit :
So, it looks like the way to set this up is:
# get your certificates in place protocols = imaps disable_plaintext_auth = no auth default { mechanisms = plain
[...]
and then add your database to the list of passdb's, with the value {HMAC-MD5}xxxxxxxxxxxxxxxxx as the contents of the password field.
Yes, I tried this configuration, and it works (which is logical, since it uses plain authentication mechanism).
I will go for it if I don't have any other choice.
However, it doesn't tell me why my previous installation worked :/
Thanks, Jonathan
participants (3)
-
Andrey Panin
-
John Peacock
-
Jonathan Ballet