0
votes

My application sends emails using Javamail. In order to authenticate with the email server I currently have to store the password somewhere in the application configuration files. I'd like to avoid this, providing at least a bit of security by storing only a hash of the password.

According to the wikipedia article http://en.wikipedia.org/wiki/Digest_access_authentication I should be able to achieve this by using DIGEST-MD5 authentication, which allows the application to authenticate using only an MD5 hash of the username:realm:password instead of needing to know the cleartext password.

I can't find any clear example on how to use DIGEST-MD5 in Javamail. I see some references to a class com.sun.mail.smtp.DigestMD5 but this doesn't exist in the latest javamail package and I can't find any explanation why.

The code below is as far as I could get with it. The email is sent successfully but the debug output seems to indicate it is still using PLAIN authentication through SASL, even though I've specified that DIGEST-MD5 is the only mechanism allowed.

Beyond that, I'm still specifying the plaintext password as an argument to the transport.connect method, whereas I want to be providing the hashed username:realm:password instead.

Can anyone point me to a working example of using DIGEST-MD5 with Javamail? Thanks!

Code below, with try/catch blocks removed...

Properties properties=new Properties();
properties.put("mail.smtp.starttls.enable","true");
properties.put("mail.smtp.timeout",3000); // 3 second timeout establishing connection
properties.put("mail.smtp.auth.mechanisms","DIGEST-MD5");
Session session=Session.getInstance(properties);
session.setDebug(true);
Message message=new MimeMessage(session);
message.setFrom(constructAddress(myGmailAddress,"my name"));
message.addRecipient(Message.RecipientType.TO,constructAddress(recipientEmailAddress,"Recipient Name"));
message.setSubject("test email");
message.setText("...");
SMTPTransport transport=(SMTPTransport)session.getTransport("smtp");
transport.setSASLEnabled(true);
transport.setSASLRealm("gmail.com");
transport.connect("smtp.gmail.com",587,myGmailAddress,password);
transport.sendMessage(message,message.getAllRecipients());
transport.close();

Here's the (truncated) debug output:

DEBUG: setDebug: JavaMail version 1.5.1
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "smtp.gmail.com", port 587, isSSL false
220 mx.google.com ESMTP pb7sm87689296pac.10 - gsmtp
DEBUG SMTP: connected to host "smtp.gmail.com", port: 587

EHLO laptop-mj
250-mx.google.com at your service, [(my ip address)]
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
STARTTLS
220 2.0.0 Ready to start TLS
EHLO laptop-mj
250-mx.google.com at your service, [(my ip address)]
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN
250-ENHANCEDSTATUSCODES
250 CHUNKING
DEBUG SMTP: Found extension "SIZE", arg "35882577"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN PLAIN XOAUTH XOAUTH2 PLAIN-CLIENTTOKEN"
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Authenticate with SASL
DEBUG SMTP: SASL AUTH command trace suppressed
DEBUG SMTP: SASL Mechanisms:
DEBUG SMTP:  LOGIN
DEBUG SMTP:  PLAIN
DEBUG SMTP:  XOAUTH
DEBUG SMTP:  XOAUTH2
DEBUG SMTP:  PLAIN-CLIENTTOKEN
DEBUG SMTP: 
DEBUG SMTP: SASL callback length: 2
DEBUG SMTP: SASL callback 0: javax.security.auth.callback.NameCallback@55f6efd2
DEBUG SMTP: SASL callback 1: javax.security.auth.callback.PasswordCallback@46faf015
DEBUG SMTP: SASL client PLAIN
DEBUG SMTP: use8bit false
MAIL FROM:<(my gmail address)>
250 2.1.0 OK pb7sm87689296pac.10 - gsmtp
... continues on with successful email transmission
1
I store my email passwords in a heavily protected subtree of an LDAP server using the plaintext option, so the application can look them up. That way they aren't part of the application, and I can change them any time administratively.user207421
Thanks for the suggestion but this application will be installed on client sites which might not have an LDAP serverMartin

1 Answers

1
votes

DIGEST-MD5 allows the server to not store the password, but the client still needs the password. The main advantage is that the password is never sent in clear text to the server.

If the server supported DIGEST-MD5 (Gmail doesn't appear to), you use it just like any other authentication, supplying the password to the connect method.