View Javadoc

1   package com.atlassian.sal.core.net;
2   
3   import java.io.IOException;
4   import java.net.InetAddress;
5   import java.net.Socket;
6   import java.net.UnknownHostException;
7   import java.util.Arrays;
8   
9   import javax.net.ssl.SSLSocket;
10  
11  import org.apache.commons.httpclient.ConnectTimeoutException;
12  import org.apache.commons.httpclient.params.HttpConnectionParams;
13  import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
14  
15  /**
16   * A custom SecureProtocolSocketFactory that uses JSSE to create sockets.
17   * <p/>
18   * This factory handles the JSSE system property "https.protocols" used to specify which protocol suites to enable.
19   * http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#Customization
20   */
21  class CustomSSLProtocolSocketFactory extends SSLProtocolSocketFactory
22  {
23      public static final String DEFAULT_PROTOCOLS = "TLSv1,SSLv3";
24      private final String[] protocols;
25  
26      /**
27       * Creates CustomSSLProtocolSocketFactory.
28       * Uses the "https.protocols" system property if defined otherwise uses protocols parameter.
29       *
30       * Available protocols:
31       * http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#AppA
32       *
33       * @param protocols Comma-separated list of protocol versions enabled for use on socket created by this factory.
34       */
35      public CustomSSLProtocolSocketFactory(String protocols)
36      {
37          String protocolsProperty = System.getProperty("https.protocols", protocols);
38          if (protocolsProperty == null)
39          {
40              protocolsProperty = DEFAULT_PROTOCOLS;
41          }
42  
43          this.protocols = protocolsProperty.split(",");
44      }
45  
46      private void setSocketProtocols(Socket socket)
47      {
48          SSLSocket sslSocket = (SSLSocket) socket;
49          sslSocket.setEnabledProtocols(protocols);
50      }
51  
52      @Override
53      public Socket createSocket(final String host, final int port, final InetAddress clientHost, final int clientPort)
54              throws IOException, UnknownHostException
55      {
56          Socket socket = super.createSocket(host, port, clientHost, clientPort);
57          setSocketProtocols(socket);
58          return socket;
59      }
60  
61      @Override
62      public Socket createSocket(final String host, final int port, final InetAddress localAddress, final int localPort, final HttpConnectionParams params)
63              throws IOException, UnknownHostException, ConnectTimeoutException
64      {
65          Socket socket = super.createSocket(host, port, localAddress, localPort, params);
66          setSocketProtocols(socket);
67          return socket;
68      }
69  
70      @Override
71      public Socket createSocket(final String host, final int port) throws IOException, UnknownHostException
72      {
73          Socket socket = super.createSocket(host, port);
74          setSocketProtocols(socket);
75          return socket;
76      }
77  
78      @Override
79      public Socket createSocket(final Socket socket, final String host, final int port, final boolean autoClose)
80              throws IOException, UnknownHostException
81      {
82          Socket newSocket = super.createSocket(socket, host, port, autoClose);
83          setSocketProtocols(newSocket);
84          return newSocket;
85      }
86  
87      public String[] getProtocols()
88      {
89          return protocols;
90      }
91  
92      @Override
93      public boolean equals(Object o)
94      {
95          if (this == o)
96          {
97              return true;
98          }
99          if (o == null || getClass() != o.getClass())
100         {
101             return false;
102         }
103         if (!super.equals(o))
104         {
105             return false;
106         }
107 
108         CustomSSLProtocolSocketFactory that = (CustomSSLProtocolSocketFactory) o;
109         if (!Arrays.equals(protocols, that.protocols))
110         {
111             return false;
112         }
113 
114         return true;
115     }
116 
117     @Override
118     public int hashCode()
119     {
120         int result = super.hashCode();
121         result = 31 * result + (protocols != null ? Arrays.hashCode(protocols) : 0);
122         return result;
123     }
124 }