Hello,
I'm looking for a good way to apply a custom hash to passwords. My hope is to add passwords to a (MySQL) database: INSERT INTO users (user='joblo', pass=MYHASH('plain-password')..
For SASL authentication, my thought first was to apply the same hash to the issued password and compare it with the hashed password in the database. I soon discovered the sql driver supplied by Dovecot doesn't provide that ability, unless I'm missing something.
I'm looking for documentation on how to implement a custom authentication script if needed.
Regards, David Koski dkoski@sutinen.com
I have done some testing and found the following queries to work for implementing MySQL SHA2 passwords for authentication:
1 user_query: 2 3 SELECT 4 email AS user, 5 if ( 6 (select crypt & 1 from view_users where email='%u'), 7 (select password from view_users where email='%u' and password=SHA2('%w',512)), 8 (select password from view_users where email='%u' and password='%w') 9 ) as password, 10 '/var/lib/vmail/%d/%n' AS home, 11 'maildir:/var/lib/vmail/%d/%n/Maildir' AS mail, 12 5000 AS uid, 13 5000 AS gid 14 FROM 15 view_users 16 WHERE 17 email = '%u' AND enable = '1' 18 19 20 password_query: 21 22 SELECT 23 email AS user, 24 if ( 25 (select crypt & 1 from view_users where email='%u'), 26 (select password from view_users where email='%u' and password=SHA2('%w',512)), 27 (select password from view_users where email='%u' and password='%w') 28 ) as password 29 FROM 30 view_users 31 WHERE 32 email = '%u' AND enable = '1'
But it seems wasteful in the number of queries required. Looking for ideas to consolidate queries.
Regards, David Koski dkoski@sutinen.com
On 3/18/23 10:07, Aki Tuomi wrote:
Fixing to not top post.
On 3/18/23 10:07, Aki Tuomi wrote:
I have done some testing and found the following queries to work for implementing MySQL SHA2 passwords for authentication:
1 user_query: 2 3 SELECT 4 email AS user, 5 if ( 6 (select crypt & 1 from view_users where email='%u'), 7 (select password from view_users where email='%u' and password=SHA2('%w',512)), 8 (select password from view_users where email='%u' and password='%w') 9 ) as password, 10 '/var/lib/vmail/%d/%n' AS home, 11 'maildir:/var/lib/vmail/%d/%n/Maildir' AS mail, 12 5000 AS uid, 13 5000 AS gid 14 FROM 15 view_users 16 WHERE 17 email = '%u' AND enable = '1' 18 19 20 password_query: 21 22 SELECT 23 email AS user, 24 if ( 25 (select crypt & 1 from view_users where email='%u'), 26 (select password from view_users where email='%u' and password=SHA2('%w',512)), 27 (select password from view_users where email='%u' and password='%w') 28 ) as password 29 FROM 30 view_users 31 WHERE 32 email = '%u' AND enable = '1'
But it seems wasteful in the number of queries required. Looking for ideas to consolidate queries.
Also, do the Dovecot query strings have to be s single query or can there be a query to set a variable, for example, to use in subsequent queries?
Regards, David Koski dkoski@sutinen.com
For the archive: This MySQL configuration seems to work well.
user_query = \
SELECT
email AS user,
'/var/lib/vmail/%d/%n' AS home,
'maildir:/var/lib/vmail/%d/%n/Maildir' AS mail,
5000 AS uid,
5000 AS gid
FROM
view_users
WHERE
email='%u'
AND
enable = '1'
password_query = \
SELECT
email AS user,
NULL AS password,
'Y' as nopassword
FROM
view_users
WHERE
email='%u'
AND
password=IF (crypt & 1, SHA2('%w',512), password)
AND
enable = '1'
Interesting...
I'm not sure why you would need to set : "NULL AS password, 'Y' as nopassword", but then I haven't seen the rest of your auth config. This would seem to allow any password but succeed if it matches the rest of the query.
It seemed a bit awkward to me to embed static variables in the query which are always going to be the same.
In the auth- config, or 10-mail.conf I just set:-
Defaults:
mail_uid = vmail mail_gid = vmail mail_home = /var/lib/vmail/%d/%n
(this is set elsewhere in 10-mail.conf.)
mail_location = maildir:~/Maildir
userdb can still override these if needed, but it means that the query is a lot simpler and if one of the queries doesn't return home/uid/gid etc, it's always going to be set anyway.
What does the "crypt" bit of "IF (crypt & 1, SHA2('%w',512)" do? crypt it before running the select?
Why not just set:
default_pass_scheme = ?
R.
On 2023-04-17 18:57, dkoski@sutinen.com wrote:
Hello R.,
Thank you for the reply.
On 4/17/23 14:49, Robert Lister wrote:
The query does not return the password, only the hash, thus "NULL AS password", as I understand it. It is documented. The 'Y' as no password is found earlier in this thread.
I think you are right. My eye was on migrating global settings to SQL accounts but it probably will not happen. Nevertheless, I suspect it adds little burden having static variables given it requires no database access, no?
Seems to me it is a matter of preference.
"crypt" bit 0 is a flag to encrypt passwords. I have chosen a custom hash. Can I replace it with "default_pass_scheme = ?"?
Regards, David
participants (4)
-
Aki Tuomi
-
David Koski
-
dkoski@sutinen.com
-
Robert Lister