Sunday, September 27, 2015

STMP port 587 blocked by Windows firewall

Recently, I had problems trying to send emails using JavaMail and my Google gmail account. I read in many places that it was most likely my ISP provider, who was blocking my access to the service; however, I didn't believe it because I could send with the same java test program from a different computer within my network, an Apple with OSX, emails. The java test program I used for testing is given below and comes from the tutorialspoint website.

To see in my firewall protocol that the requests were being dropped, I had to first turn my firewall logging on which I did by opening up a command prompt with admin rights and executing the followng:

C:\>netsh advfirewall set allprofiles logging droppedconnections enable
Ok.

Then, I sent a request with the test program and saw in the logfile (%systemroot%\system32\LogFiles\Firewall\pfirewall.log) :

2015-09-27 09:28:37 DROP UDP 192.168.178.58 239.255.255.250 52323 1900 371 - - - - - - - RECEIVE
2015-09-27 09:28:37 DROP UDP 192.168.178.58 239.255.255.250 52323 1900 357 - - - - - - - RECEIVE
2015-09-27 09:34:12 DROP TCP 192.168.178.64 66.102.1.108 58144 587 0 - 0 0 0 - - - SEND

The test program threw the following exception:

>java -classpath .;mail.jar;activation.jar SendEmailUsingGMailSMTP
Exception in thread "main" java.lang.RuntimeException: javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com,
 port: 587;
  nested exception is:
        java.net.SocketException: Permission denied: connect
        at rewards.messaging.client.SendEmailUsingGMailSMTP.main(SendEmailUsingGMailSMTP.java:64)
Caused by: javax.mail.MessagingException: Could not connect to SMTP host: smtp.gmail.com, port: 587;
  nested exception is:
        java.net.SocketException: Permission denied: connect
        at com.sun.mail.smtp.SMTPTransport.openServer(SMTPTransport.java:1972)
..
        at javax.mail.Transport.send(Transport.java:124)
Caused by: java.net.SocketException: Permission denied: connect

I should mention that with wireshark one will not see the requests because the requests don't make it beyond the firewall; however, if one clears the local DNS cache (C:\>ipconfig /flushdns), one can see with wireshark the hostname resolution request. This is nice because one can confirm that the destination address seen in the dropped TCP request is indeed the one associated with the program; the port number is also a good indication that one is looking at the correct request.  


Another useful tool was openssh, which I have installed on my Windows laptop because I'm using Git Bash. With openssl, I could get Google's x509 certificate using the following:

$openssl s_client -connect  smtp.gmail.com:465 -state -tls1

However, what didn't work was this:

$openssl s_client -connect  smtp.gmail.com:587 -state -tls1
Loading 'screen' into random state - done
connect: Bad file descriptor
connect:errno=10013

The dropped request was also logged accordingly in the firewall's protocol similarly to that shown above.

To trouble shoot, I took the following standard snippet of code taken from here:

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class SendEmailUsingGMailSMTP {
   public static void main(String[] args) {
      // Recipient's email ID needs to be mentioned.
      String to = "xyz@gmail.com";//change accordingly

      // Sender's email ID needs to be mentioned
      String from = "abc@gmail.com";//change accordingly
      final String username = "abc";//change accordingly
      final String password = "*****";//change accordingly

      // Assuming you are sending email through relay.jangosmtp.net
      String host = "smtp.gmail.com";

      Properties props = new Properties();
      props.put("mail.smtp.auth", "true");
      props.put("mail.smtp.starttls.enable", "true");
      props.put("mail.smtp.host", host);
      props.put("mail.smtp.port", "587");

      // Get the Session object.
      Session session = Session.getInstance(props,
      new javax.mail.Authenticator() {
         protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication(username, password);
         }
      });

      try {
         // Create a default MimeMessage object.
         Message message = new MimeMessage(session);

         // Set From: header field of the header.
         message.setFrom(new InternetAddress(from));

         // Set To: header field of the header.
         message.setRecipients(Message.RecipientType.TO,
         InternetAddress.parse(to));

         // Set Subject: header field
         message.setSubject("Testing Subject");

         // Now set the actual message
         message.setText("Hello, this is sample for to check send "
            + "email using JavaMailAPI ");

         // Send message
         Transport.send(message);

         System.out.println("Sent message successfully....");

      } catch (MessagingException e) {
            throw new RuntimeException(e);
      }
   }
}



Friday, September 18, 2015

weak ephemeral Diffie-Hellman tomcat6


After upgrading from SUSE 10 to SUSE 11, which encompassed an OpenSSL library upgrade, some HTTPS clients like chrome (Version 45.0.2454.85) or  wget started getting the following error "Server has a weak ephemeral Diffie-Hellman public".  No server changes on the server side, namely tomcat6, had been made.





Attempts to solve the problem by changing the sslEnabledProtocols or sslProtocol attributes of the Connector element in the server.xml shown below were unsuccessful. Also desperate actions such as updating the US_export_policy.jar and local_policy.jar did not help either.

The final solution was to limit the cipher suits by adding the ciphers attribute to the SSL enabled connector. See below

<!-- Define a SSL Coyote HTTP/1.1 Connector on port 443 -->
 <Connector port="443"  SSLEnabled="true"
            protocol="org.apache.coyote.http11.Http11Protocol"
             scheme="https" secure="true"
            clientAuth="want" sslProtocol="TLS"
     ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA"

            keystoreFile="${catalina.base}/conf/%KEYSTORE%"
            keystoreType="JKS" keystorePass="%KEYSTOREPASS%"
            truststoreFile="${catalina.base}/conf/%TRUSTSTORE%"
            truststoreType="JKS" truststorePass="%KEYSTOREPASS%"

   />


Apache Tomcat's ciphers come from the under lying JVM, in particular the JSSE. To see which one are available put the following in a java main routine and run it.

/*******************************************/
StringBuilder sb = new StringBuilder();
try {
SSLParameters ssl  = SSLContext.getDefault().getSupportedSSLParameters();

sb.append("CipherSuites:\n");
for(String cs : ssl.getCipherSuites()){
sb.append(cs);
sb.append('\n');
}

sb.append("\nProtocols:\n");
for(String p : ssl.getProtocols()){
sb.append(p);
sb.append('\n');
}

} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

return sb.toString();

/*******************************************/

The output should look something like this:

CipherSuites:
SSL_RSA_WITH_RC4_128_MD5
SSL_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA
SSL_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
SSL_RSA_WITH_DES_CBC_SHA
SSL_DHE_RSA_WITH_DES_CBC_SHA
SSL_DHE_DSS_WITH_DES_CBC_SHA
SSL_RSA_EXPORT_WITH_RC4_40_MD5
SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_EMPTY_RENEGOTIATION_INFO_SCSV
SSL_RSA_WITH_NULL_MD5
SSL_RSA_WITH_NULL_SHA
SSL_DH_anon_WITH_RC4_128_MD5
TLS_DH_anon_WITH_AES_128_CBC_SHA
TLS_DH_anon_WITH_AES_256_CBC_SHA
SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
SSL_DH_anon_WITH_DES_CBC_SHA
SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_KRB5_WITH_RC4_128_SHA
TLS_KRB5_WITH_RC4_128_MD5
TLS_KRB5_WITH_3DES_EDE_CBC_SHA
TLS_KRB5_WITH_3DES_EDE_CBC_MD5
TLS_KRB5_WITH_DES_CBC_SHA
TLS_KRB5_WITH_DES_CBC_MD5
TLS_KRB5_EXPORT_WITH_RC4_40_SHA
TLS_KRB5_EXPORT_WITH_RC4_40_MD5
TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5


Protocols:
SSLv2Hello
SSLv3
TLSv1