View Javadoc

1   /*
2   Copyright (C) 2000 - 2007 Grid Systems, S.A.
3   
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License, version 2, as
6   published by the Free Software Foundation.
7   
8   This program is distributed in the hope that it will be useful,
9   but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12  
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  */
17  
18  package com.gridsystems.innergrid.api;
19  
20  import com.gridsystems.innergrid.kernel.KernelException;
21  
22  import java.net.Socket;
23  import java.net.SocketException;
24  import java.security.Provider;
25  import java.security.Security;
26  import java.util.Hashtable;
27  
28  import javax.net.ssl.SSLSocketFactory;
29  
30  import org.apache.axis.AxisProperties;
31  import org.apache.axis.components.net.BooleanHolder;
32  import org.apache.axis.components.net.SocketFactoryFactory;
33  import org.apache.axis.components.net.SunFakeTrustSocketFactory;
34  
35  /**
36   * SSL Socket factory to be used by Innergrid APIs.
37   *
38   * @author Xmas
39   * @version 1.0
40   */
41  public class InnergridJSSESocketFactory extends SunFakeTrustSocketFactory {
42  
43    /**
44     * Puts this class as default SSLSocketFactory
45     */
46    static {
47      SocketFactoryFactory.getFactory("http", new Hashtable());
48      AxisProperties.setProperty("axis.socketSecureFactory",
49        InnergridJSSESocketFactory.class.getName(),
50        true);
51  
52      // Add common security providers
53      addSecurityProvider("sun.security.provider.Sun");
54      addSecurityProvider("com.sun.net.ssl.internal.ssl.Provider");
55      addSecurityProvider("org.bouncycastle.jce.provider.BouncyCastleProvider");
56    }
57  
58    /**
59     * Accept all Certificates.
60     */
61    private static final AcceptAllCertificates ACCEPT_ALL = new AcceptAllCertificates();
62  
63    /**
64     *  Hash of SSL Connection Info for each host_port:
65     *                 KEY ( host_port ) -> VALUE (SSL Connection Info).
66     */
67    private static Hashtable<String, SSLConnectionInfo> connections
68      = new Hashtable<String, SSLConnectionInfo>();
69  
70    /**
71     * Registry a SSLConnection info with host:port.
72     *
73     * @param host Host to connect
74     * @param port Port of host to connect
75     * @param sslinfo Information to establish SSL connection
76     */
77    public static void registrySSLConnectionInfo(String host, int port,
78      SSLConnectionInfo sslinfo) {
79      if ((host == null) || (port < 1) || (sslinfo == null)) {
80        return;
81      }
82      connections.put(host + "_" + port, sslinfo);
83    }
84  
85    /**
86     * Constructor.
87     *
88     * @param attrib Attributes for this factory
89     */
90    public InnergridJSSESocketFactory(Hashtable attrib) {
91      super(attrib);
92    }
93  
94    /**
95     * Read the keystore, init the SSL socket factory.
96     */
97    @Override
98    protected void initFactory() {
99    }
100 
101   /**
102    * Creates a secure socket.
103    *
104    * @param host Host to connect
105    * @param port Port of host to connect
106    * @param otherHeaders More info
107    * @param useFullURL Use full URL
108    *
109    * @return Socket Socket to realize the connection
110    * @throws Exception If error
111    */
112   @Override
113   public synchronized Socket create(String host, int port, StringBuffer otherHeaders,
114     BooleanHolder useFullURL) throws Exception {
115 
116     sslFactory = getSSLSocketFactory(host, port);
117     try {
118       Socket s = super.create(host, port, otherHeaders, useFullURL);
119       s.setSoLinger(false, 0);
120       return s;
121     } catch (SocketException se) {
122       throw se;
123     } catch (Exception e) {
124       // CLT031=Certificate verify failed
125       throw new CKernelException(e, "CLT031");
126     }
127   }
128 
129   /**
130    * Adds a security provider to the security registry by class name.
131    *
132    * @param className  The name of the provider class
133    */
134   private static void addSecurityProvider(String className) {
135     try {
136       Class<?> c = Class.forName(className);
137       Provider provider = (Provider)c.newInstance();
138       Security.addProvider(provider);
139     } catch (Throwable t) { }
140   }
141 
142   /**
143    * Return a SSLSocktedFactory to be used to connect to host:port.
144    *
145    * @param host Host to connect
146    * @param port Port of host to connect
147    * @return A SSLSocketFactory to establish connection
148    * @throws KernelException If error
149    */
150   private SSLSocketFactory getSSLSocketFactory(String host, int port)
151     throws KernelException {
152 
153     String key = host + "_" + port;
154     SSLConnectionInfo sslinfo = (SSLConnectionInfo) connections.get(key);
155 
156     if (sslinfo == null) {
157       sslinfo = ACCEPT_ALL;
158     }
159     return sslinfo.getSSLSocketFactory();
160   }
161 
162 }