Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Mail to Exchange Server "no login methods supported"

Tags:

I am trying to implement a Java Mail servlet, first step is connecting to the IMAP server.

I am able to telnet to the server on port 143 (default IMAP port), telnet says: OK The Microsoft Exchange IMAP4 service is ready.

Now I am trying to connect to the server using the Java Mail API like this:

Properties props = new Properties(); session = Session.getDefaultInstance(props, null); store = session.getStore("imap"); store.connect("host","user","password"); 

And I am able to connect to this same server using an existing Outlook Webapp with the same credentials I am trying to pass to it in java.

But running this with session.setDebug(true) produces the following output:

DEBUG: setDebug: JavaMail version 1.4.5 DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc] DEBUG: mail.imap.fetchsize: 16384 DEBUG: mail.imap.statuscachetimeout: 1000 DEBUG: mail.imap.appendbuffersize: -1 DEBUG: mail.imap.minidletime: 10 DEBUG: trying to connect to host "myHost", port 143, isSSL false * OK The Microsoft Exchange IMAP4 service is ready. A0 CAPABILITY * CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+ A0 OK CAPABILITY completed. DEBUG: protocolConnect login, host=myHost, user=myUser, password=<non-null> javax.mail.MessagingException: No login methods supported!; 

EDIT:

I added prop.setProperty("mail.imap.starttls.enable", "true") as suggested.

However, I started getting this debug output:

DEBUG: setDebug: JavaMail version 1.4.5 DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Sun Microsystems, Inc] DEBUG: mail.imap.fetchsize: 16384 DEBUG: mail.imap.statuscachetimeout: 1000 DEBUG: mail.imap.appendbuffersize: -1 DEBUG: mail.imap.minidletime: 10 DEBUG: enable STARTTLS DEBUG: trying to connect to host "myHost", port 143, isSSL false * OK The Microsoft Exchange IMAP4 service is ready. A0 CAPABILITY * CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED STARTTLS UIDPLUS CHILDREN IDLE NAMESPACE LITERAL+ A0 OK CAPABILITY completed. DEBUG: protocolConnect login, host=myHost, user=myUser, password=<non-null> A1 STARTTLS A1 OK Begin TLS negotiation now. DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 

Assuming that this was a certificate problem I followed these instructions and added mail server to my cacerts file. The test program included there ran totally fine and I could connect using an SSL url but I still got the same exception when running the java mail class.

I also tried changing to "imaps" with: session.getStore("imaps") (instead of "imap") and wasn't even able to get the "Microsoft Exchange Server is now ready" message. I think because it is trying to connect on port 993 whenever "imaps" was specified. But using telnet to port 993 does not show any connection to the email server.

So next I tried to force the program to use SSL on port 143 like this:

// Use SSL prop.setProperty("mail.imap.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); prop.setProperty("mail.imap.socketFactory.fallback", "false");  // Use port 143 prop.setProperty("mail.imap.port", "143"); prop.setProperty("mail.imap.socketFactory.port", "143"); 

Only to receive this exception, so I don't think it wants anything to do with SSL:

DEBUG: mail.imap.fetchsize: 16384 DEBUG: mail.imap.statuscachetimeout: 1000 DEBUG: mail.imap.appendbuffersize: -1 DEBUG: mail.imap.minidletime: 10 DEBUG: trying to connect to host "myHost", port 143, isSSL false Not able to process the mail reading. javax.mail.MessagingException: Unrecognized SSL message, plaintext connection?; 

Could that TLS exception above (DEBUG IMAP: STARTTLS Exception: javax.net.ssl.SSLHandshakeException:) come from TLS not being enabled on the Exchange Server?

I don't have ready access to the e-mail server but I could probably get someone to let me in.

SOLUTION:

HulkingUnicorn's comment below his answer pointed out this answer which was the exact handling needed. Apparently MS Exchange Server has this problem. Along with adding the class listed in that answer to my package, I simply implemented my mail connections like this and all was well:

Properties prop = new Properties(); prop.setProperty("mail.imap.starttls.enable", "true"); prop.setProperty("ssl.SocketFactory.provider", "my.package.name.ExchangeSSLSocketFactory"); prop.setProperty("mail.imap.socketFactory.class", "my.package.name.ExchangeSSLSocketFactory"); session = Session.getDefaultInstance(prop, null); session.setDebug(true); store = session.getStore("imap"); store.connect("myHost","myUser","myPassword"); 
like image 485
egerardus Avatar asked May 04 '12 04:05

egerardus


2 Answers

This part, * CAPABILITY IMAP4 IMAP4rev1 LOGINDISABLED suggest you can't log in, in this thread the OP solved it by updating his Javamail to 1.4.4 (although your debug output suggests you've already got that). Try using 1.4.5.

Actually, try adding this line before you create the session; your email server supports it and it's disabled by default: props.put("mail.imap.starttls.enable", "true");

This answer solved the problem.

like image 89
HulkingUnicorn Avatar answered Oct 03 '22 09:10

HulkingUnicorn


You can use the com.sun.mail.util.MailSSLSocketFactory that is part of the javamail 1.4.5 API.

Example:

MailSSLSocketFactory sf = new MailSSLSocketFactory(); sf.setTrustAllHosts(true); props.put("mail.imap.starttls.enable", "true"); props.put("mail.imap.ssl.socketFactory", sf); 

There is no need to use the custom SSLSocketFactory.

like image 37
paf.goncalves Avatar answered Oct 03 '22 10:10

paf.goncalves