How to check mailserver supports TLS or Not - java

I want to check whether mailserver support TLS encryption or not using javamail.
I can able to check via terminal in Linux OS.
>> dig +short gmail.com mx
20 alt2.gmail-smtp-in.l.google.com.
10 alt1.gmail-smtp-in.l.google.com.
5 gmail-smtp-in.l.google.com.
40 alt4.gmail-smtp-in.l.google.com.
30 alt3.gmail-smtp-in.l.google.com.
>> telnet gmail-smtp-in.l.google.com 25
220 mx.google.com ESMTP c90si10657664pfd.233 - gsmtp
>>ehlo gmail.com
250-mx.google.com at your service,
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250 SMTPUTF8
250 STARTTLS then that email server is configured to support use of TLS.
In the same way, how we can do it using javamail programmatically?
Please help.

Do you really need just "yes, the server supports it" or "no, it does not support it"? Or you have to send an email and want to send it only if you can do it securely?
If it is the former you can just do what telnet does and do not bother using javamail.
If it is the later you can configure javamail to fail if the server does not support TLS.
See An SMTP protocol provider for the JavaMail API for details. Property 'mail.smtp.starttls.required' is what you need.

how would a java "yes, the server supports it" check for tls look like?
The only way i actual see is to make an dns lookup (e.g. via javax.naming.directory.InitialDirContext).
And then connect via telnet (e.g. via apache telnet client)
and parse the

You can query the server with java / jakarta mail using EHLO commands.
The following method queries the server for the support of TLS. No email is send. Other properties could be added. Of course ehlo must be enabled (mail.smtp.ehlo=true)
boolean detectTls(String smtpServerHost, int smtpServerPort, String smtpUserName, String smtpUserAccessToken) {
Transport transport = null;
try {
Properties props = System.getProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.port", smtpServerPort);
Session session = Session.getDefaultInstance(props);
//session.setDebug(true);
transport = session.getTransport();
transport.connect(smtpServerHost, smtpServerPort, smtpUserName, smtpUserAccessToken);
if(transport instanceof SMTPTransport) {
return ((SMTPTransport)transport).supportsExtension("STARTTLS");
}
return false;
}
catch (Exception ex) {
//Proper loggin & exception handling!!!
//return false;
}
finally {
if(transport!=null) {
try {
transport.close();
}
catch (MessagingException e) {
}
}
}
}

Related

JavaMail with proxy not connecting

i have a class that is called "NotifiationService":
#Service("notificacionService")
public class NotificacionServiceImpl implements NotificacionService{
//servicio llama a repositorio
#Autowired
#Qualifier("notificacionService")
private NotificacionService notificacionService;
#Override
public void send(String to, String subject, String text) {
//proxy
Properties p = System.getProperties();
p.setProperty("proxySet","true");
p.setProperty("socksProxyHost","MYPROXY");
p.setProperty("socksProxyPort","MYPORT");
Properties props = new Properties();
// smtp.gmail.com
props.setProperty("mail.smtp.host", "smtp.gmail.com");
// TLS
props.setProperty("mail.smtp.starttls.enable", "false");
// port
props.setProperty("mail.smtp.port","465");
//
props.setProperty("mail.smtp.user", "reciever#gmail.com");
props.setProperty("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props);
session.setDebug(true);
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress("sender#gmail.com"));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject(subject);
message.setText(text);
//
Transport t = session.getTransport("smtp");
t.connect("sender#gmail.com","senderpassword");
t.sendMessage(message,message.getAllRecipients());
t.close();
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
As you can see i have tried to configure a proxy, since the computer is connected to one that redirects the traffic. So even adding all the specifications about the proxy, it keeps giving me an error saying:
com.sun.mail.util.MailConnectException: Couldn't connect to host, port: smtp.gmail.com, 465; timeout -1;
nested exception is:
java.net.SocketException: Permission denied: connect
I have also tried different ports like: 25,485,587 and none of the respond, so i think its a problem with the proxy.
To be able to find the information about the proxy that is implemented i have typed this command in the console:
reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings" | find /i "proxyserver"
and it responds with:
ProxyServer REG_SZ MYPROXY:MYPORT
If i type: "ping google.com" in cmd, it says its inaccessible
Is there a way to be able to connect from java with javamail to gmail and be able to send an email with the current configuration?
Thanks.
If it's not working after setting the SOCKS properties, most likely your proxy server is just a web proxy server and not a SOCKS proxy server. The JavaMail FAQ has pointers to other software that will allow to tunnel connections through a web proxy server.
Since JavaMail 1.6.2, You can set proxy authentication properties for Session object for sending emails.
Refer to the following documentation link.
https://javaee.github.io/javamail/docs/api/
The following properties are introduced newly and works fine with Proxy Authentication (Basic).
mail.smtp.proxy.host
mail.smtp.proxy.port
mail.smtp.proxy.user
mail.smtp.proxy.password
To clarify at least one point concerning the usage of https.proxySet=true and http.proxySet=true.
JDK-4632974 proxySet=false is ignored for HttpURLConnection.getOutputStream
"The use of property http.proxySet was eliminated in favor of simply testing
for the presence of the http.proxyHost property. This property existed up to
JDK1.0.2 but was removed for JDK1.1 in 1996."
In other words, do not use proxySet as it serves no purpose. It is non-existing Java system property nowadays.

does sending email via SMTP with TLS connection encrypt the username and password?

I've written an appilicaiton with Java which sends Email. For sending Email I've used SMTP with TLS.
Recently I've searched about TLS and I found the flowing description about TLS on this website : Transport Layer Security (TLS), a protocol that encrypts and delivers mail securely, helps prevent eavesdropping and spoofing (message forgery) between mail servers.
The above phrase says that TLS guarantees that the mail will be delivered securely, but it does not say any thing about the password...
suppose that I am using following code in my application, so as you can see you need to have hard code for username and password, without any encryption.
final String username = "...#hotmail.com";
final String password = "your Password";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp-mail.outlook.com");
props.put("mail.smtp.port", "587");
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
by using this strategy does TLS encrypt my password while sending from my server to another server or not? should I be worried about it or not?
Password transmission and communication encryption are two separate matters.
TLS is initiated over what is at first an unencrypted channel by issuing the STARTTLS command; if the server supports it, then the exchange is done and after it is done, the channel is encrypted.
And only then the SMTP negotiation starts; and one part of this negociation is authentication if any. And even if you use the plain authentication mechanism (user and password sent over the wire as is), since the channel is encrypted at that time, eavesdroppers won't see it in clear.
Of course, for more security, you may choose to use another authentication mechanism than the plain one (CRAM-MD5 for instance; others exist).
EDIT OK, the answer above is only partially accurate; more details can be found in this excellent answer on ServerFault by #Bruno

Unknow SMTP host android JavaMail

I have a Mailserver, which is hosted at the same network as my phone, but I keep getting an exception saying Unknow SMTP host. I've read several places that this exception occurs when the hostname isnt correct spelled, of course. But in this case it IS. In C# its done a simple way like this:
var client = new SmtpClient(_strSmtpHost);
client.UseDefaultCredentials = true;
var mailMessage = new MailMessage(_strFrom, emailTo);
mailMessage.Subject = subject;
mailMessage.Attachments.Add(attachment);
client.Send(mailMessage);
And in my application its done this way:
SendMail m = new SendMail("Username", "password");
String[] toArr = {"TO#EXAMPLE.com"};
m.setTo(toArr);
m.setFrom("FROM#EXAMPLE.com");
m.setSubject("This is an email sent using my Mail JavaMail wrapper from an Android device.");
m.setBody("Email body.");
try {
m.addAttachment(fileName);
if(m.send()) {
Log.i("MAIL SENDER: ", "Succesfully");
} else {
Log.i("MAIL SENDER: ", "UnSuccesfully");
}
} catch(Exception e) {
Log.e("MailApp", "Could not send email" + e);
}
In my SendMail class I define a String containing the DNS address of the host
_host = "napserver"; // default smtp server
_port = "25"; // default smtp port
Before I try to do a connect, I want to Authenticate username and password for the mail-address sending the mail:
Session session = Session.getInstance(props, new GMailAuthenticator(_user, _pass));
and then trying to a connect and send message
Transport transport = session.getTransport("smtp");
transport.connect(_host, 25, _user, _pass);
Transport.send(msg);
Just for testing purposes I tried the SMTP address for Gmail, and this worked, and the mail was sent to the specified mail account. Can anybody give me a hint?
EDIT
I should also mention that I tried to connect via Telnet to this mail server, and the ouput from PuTTy, when connected with the host napserver and port 25 :
220 napserver.nap01.dac.no.eu-admin.net Microsoft ESMTP MAIL Service, Version: 6 .0.3790.3959 ready at Tue, 7 Aug 2012 13:38:55 -0700
EDIT 2
As you can see from the PuTTy output:
Microsoft ESMTP MAIL Service
My mailserver uses the ESMTP, but as far as I know this just implements some security layers and so on. Maybe this is where the error is?
EDIT 3
I tried to access the mailserver via remote desktop, I pinging my phones IP-address just to be sure that the server and the phone is located on the same network, and it is..

JavaMail to send email through vps, require NO authentication, but get AuthenticationFailedException - why?

I originally setup my site to use my local ISP to send email through my site. I would like to change this, and start sending email through my VPS. According to the online documentation (from my vps provider) I have "POP before SMTP authentication". So then, I do not require authentication nor do I require a secure connection at this time.
I changed a few things in the code I used for sending email through my local ISP. Here's what I have :
Transport t = null;
try {
String Username = "mrsmith#mydomain.com";
String Password = "somepassword";
InternetAddress from = new InternetAddress("mrsmith#mydomain.com", "Bob Smith");
Properties props = new Properties();
//commented out, since I don't want to use authentication
//props.setProperty("mail.smtp.auth", "true");
props.put("mail.pop3.host", "mydomain.com";
props.put("mail.smtp.host", "mydomain.com");
String protocol = "smtp";
Session ssn = Session.getInstance(props, null);
ssn.setDebug(true);
t = ssn.getTransport(protocol);
Store s = ssn.getStore();
s.connect();
t.connect(SMTP,Username,Password);
//Create the message
Message msg = new MimeMessage(ssn);
msg.setFrom(from);
msg.addRecipient(Message.RecipientType.TO, to);
msg.setSubject(subject);
msg.setContent(body, "text/html");
t.sendMessage(msg, msg.getAllRecipients());
t.close();
s.close();
I contacted my vps provider and after following their instructions, in tweaking the code, I still get "Authentication Failed". This after a successful connection has been made to the host on port 25.
Can someone point out what it is I'm missing here?
Editing to add additional information
After I added the store.connect("mailhost",Username,Password); statement to the code, I got further than ever before!
Here is some info that was printed to the tomcat prompt -
DEBUG : getProvider() returning javax.mail.Provider[STORE,pop3,com.sun.mail.pop3.POP3Store,Sun Microsystems, Inc.]
POP3: connecting to host "mydomain.com", port 110, isSSL false
server ready
OK User name accepted, password please
Password somepassword
OK Mailbox open, 0 messages
DEBUG: geProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smpt.SMTPTransport,Sun Microsystems, Inc.]
DEBUG SMTP: useEhlo true, useAuth false
DEBUG SMTP: trying to connect to host "mydomain.com", port 25, isSSL false
220 mydomain.com ESMTP Sendmail 8.14.3/8.14.3; DEC 2010 29
DEBUG SMTP: connected to host "mydomain.com", port: 25
( a lot of additional debug information was here )
DEBUG SMTP: Attempt to authenticate
AUTH LOGIN
535 5.7.0 authentication failed
javax.mail.AuthenticationFailedException
at javax.mail.Service.connect(Service.java:319)
at javax.mail.Service.connect(Service.java:169)
... continues with more 'at's.
Do you see anything odd in this information? I don't quite understand why the authentication failed while the Pop3 was authenticated with the same username and password.
POP before SMTP authentication basically means you need to be able to prove that you can fetch your mail using POP3 (using proper authentication) before you will be allowed to send mail using SMTP (without authentication).
Using the Java Mail API, you can do the authentication to the POP3 server like this :
Store store = ssn.getStore("pop3");
store.connect("mailhost", Username, Password);
You should execute these calls prior to connecting to the SMTP server, so before connecting to the SMTP server (without username and password) like this
t.connect();
make sure you connect to the store first.
In your snippet, you are still authenticating against the smtp as you are providing a username/password.
Another option is to use Commons Email, that has built-in support for pop before smtp authentication. Check out the following method in http://commons.apache.org/email/apidocs/org/apache/commons/mail/Email.html
email.setPopBeforeSMTP(true,popHost,popUsername,popPassword);
Using commons email, there's no need to do the pop plumbing in your code (connecting prior to sending).
Properties props = new Properties();
props.put("mail.smtp.host", "mailserver.com");
Session s = Session.getInstance(props,null);
InternetAddress from = new InternetAddress("mail#mail.com");
InternetAddress to = new InternetAddress(recepeint#server.com");
For more information please visit:
http://www.itpian.com/Coding/314-SENDING-EMAILS-THROUGH-JAVAMAIL.aspx
Check if provider implementation(pop3.jar) is in your buildpath/classpath.

Unable to send mail from Java application

In my java application I need to send mails to different mail addresses. I am using the next piece of code , but for some reason it doesn't work.
public class main {
public static void main(String[] args) {
Properties props = new Properties();
props.put("mail.smtp.host", "mail.yahoo.com.");
props.put("mail.smtp.auth", "true");
props.put("mail.debug", "true");
Session session = Session.getInstance(props, new MyAuth());
try {
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("giginnho#yahoo.com"));
InternetAddress[] address = {new InternetAddress("rantravee#yahoo.com")};
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("subject ");
msg.setSentDate(new Date());
msg.setText("Message here ");
Transport.send(msg);
} catch (MessagingException e) {}
}
}
class MyAuth extends Authenticator {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("my username","my password");
}
}
I get the folowing text from debuging it:
[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Sun Microsystems, Inc]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host "smtp.mail.yahoo.com.au.", port 25, isSSL false
Could anyone inform me , what I am doing wrong here ?
Yahoo! Mail SMTP server address: smtp.mail.yahoo.com
Yahoo! Mail SMTP user name: Your full Yahoo! Mail email address (including "#yahoo.com")
Yahoo! Mail SMTP password: Your Yahoo! Mail password
Yahoo! Mail SMTP port: 465
Yahoo! Mail SMTP TLS/SSL required: yes
Similar settings work with gmail. For yahoo you might need yahoo plus account
I am not sure, but I faced the same problem when sending mail using a gmail id, you are using yahoo. The problem was gmail uses ssl layer protection, i think same is the case with yahoo so you need to use
mail.smtps.host instead of mail.smtp.host
and same for other properties too.
and isSSL to true.
I can post complete code snippet, once i reach office and use office's machine. For now you can look at http://www.rgagnon.com/javadetails/java-0570.html
It could be an issue with your ISP blocking port 25 traffic (not unusual!)
From http://help.yahoo.com/l/us/yahoo/smallbusiness/bizmail/pop/pop-32.html:
In an attempt to control unsolicited email (spam), some Internet service providers now block port 25, which means you could experience technical problems when sending email. If you are having trouble sending email, you may need to use port 465 (recommended) or 587 when sending email via Yahoo!'s SMTP server.

Categories