lingo.lin lingo.lin - 2 months ago 21
MySQL Question

SASL LOGIN authentication failed: UGFzc3dvcmQ6

CentOS6.6, Postfix, dovecot 2.0.9 and MySQL 5.1.73

dovecot configuration (

/etc/dovecot/dovecot-sql.conf.ext
):

driver = mysql
connect = host=127.0.0.1 dbname=postfix user=root password=lingo

default_pass_scheme = SHA512
password_query = SELECT email as user, password FROM virtual_user WHERE email='%u';


MySQL database:

mysql> SELECT email as user, password FROM virtual_user WHERE email='lingo.lin1@radicasys.com';
+--------------------------+------------------------------------------------------------------------------------------------------------+
| user | password |
+--------------------------+------------------------------------------------------------------------------------------------------------+
| lingo.lin1@example.com | 0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c |
+--------------------------+------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)


The password is generated by
commons-codec
, Java code:

System.out.println(DigestUtils.sha512Hex("lingo".getBytes()));
//print :0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c


Now I wrote some Java-code to authenticate:

public static void sendEmail() throws EmailException, GeneralSecurityException {

SimpleEmail email = new SimpleEmail();
// smtp host
email.setHostName("192.168.15.139");
email.setSmtpPort(25);
email.setDebug(true);
// DigestUtils.sha512Hex("lingo".getBytes())
email.setAuthentication("lingo.lin1@example.com", "lingo");

email.setStartTLSEnabled(true);
MailSSLSocketFactory socketFactory = new MailSSLSocketFactory();
socketFactory.setTrustAllHosts(true);
Properties propsSSL = email.getMailSession().getProperties();
propsSSL.put("mail.smtp.port", "465");
propsSSL.put("mail.smtp.ssl.checkserveridentity", "false");
propsSSL.put("mail.smtp.ssl.socketFactory", socketFactory);
email.addTo("lingo.lin@qamail.rimanggis.com", "John Doe");
email.setFrom("lingo.lin@radicasys.com", "Me");
email.setSubject("Test message");
email.setMsg("This is a simple test of commons-email");
email.send();
System.out.println("success");
}

public static void main(String[] args) throws Exception {
SendEmailTest.sendEmail();
// System.out.println(DigestUtils.sha512Hex("lingo".getBytes()));
}


But it fails with following error:

Sep 12 13:30:51 localhost dovecot: auth: Debug: sql(lingo.lin1@radicasys.com,192.168.15.243): query: SELECT email as user, password FROM virtual_user WHERE email='lingo.lin1@radicasys.com';
Sep 12 13:30:51 localhost dovecot: auth: Error: sql(lingo.lin1@radicasys.com,192.168.15.243): Password in passdb is not in expected scheme SHA512
Sep 12 13:30:53 localhost postfix/smtpd[1872]: warning: unknown[192.168.15.243]: SASL LOGIN authentication failed: UGFzc3dvcmQ6
Sep 12 13:30:53 localhost dovecot: auth: Debug: client out: FAIL#0115#011user=lingo.lin1@radicasys.com
Sep 12 13:30:53 localhost postfix/smtpd[1872]: lost connection after AUTH from unknown[192.168.15.243]
Sep 12 13:30:53 localhost postfix/smtpd[1872]: disconnect from unknown[192.168.15.243]


How can I fix the authentication?

Answer

This is a dovecot configuration issue. Dovecot knows two hash encodings, the "traditional" hex encoding (ie. SHA512.HEX) and Base64-encoding (ie. SHA512.b64). The latter is more space-efficient when stored as strings and default in Dovecot. An example for generating the hash with sha512, sha512.b64 and sha512.hex encodings:

$ doveadm pw -p lingo -s sha512
{SHA512}DaO0sDhcQyqADKFerhqEheX3q617cLThwrnPFfaK/SVs7bICnG987AnhIh5rEBQggeG7jlyAL7l+g8iTwo2GFA==
$ doveadm pw -p lingo -s sha512.b64
{SHA512.b64}DaO0sDhcQyqADKFerhqEheX3q617cLThwrnPFfaK/SVs7bICnG987AnhIh5rEBQggeG7jlyAL7l+g8iTwo2GFA==
$ doveadm pw -p lingo -s sha512.hex
{SHA512.HEX}0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c802fb97e83c893c28d8614

Use default_pass_scheme = SHA512.HEX if you create hex-encoded passwords hashes in Java. The better solution would be to use Dovecot's {SCHEME}hash encoding instead of setting the default_pass_scheme, though: doing so, you can easily change/upgrade the hash method later without invalidating all user's passwords at once. An example for the hash you used in this scheme:

{SHA512.hex}0da3b4b0385c432a800ca15eae1a8485e5f7abad7b70b4e1c2b9cf15f68afd256cedb2029c6f7cec09e1221e6b10142081e1bb8e5c

Finally: plain hashing of passwords is never save, also not when using large SHA512 hashes. Never store unsalted password hashes, you're vulnerable to rainbow table attacks if the database leaks.