Coverage Report - org.mule.management.agents.IBMSslAdapterServerSocketFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
IBMSslAdapterServerSocketFactory
0%
0/100
0%
0/62
4.231
 
 1  
 /*
 2  
  * $Id: IBMSslAdapterServerSocketFactory.java 7963 2007-08-21 08:53:15Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.management.agents;
 12  
 
 13  
 import org.mule.umo.security.provider.AutoDiscoverySecurityProviderFactory;
 14  
 import org.mule.umo.security.provider.SecurityProviderFactory;
 15  
 import org.mule.umo.security.provider.SecurityProviderInfo;
 16  
 import org.mule.util.FileUtils;
 17  
 import org.mule.util.IOUtils;
 18  
 
 19  
 import java.io.File;
 20  
 import java.io.FileInputStream;
 21  
 import java.io.IOException;
 22  
 import java.io.InputStream;
 23  
 import java.net.InetAddress;
 24  
 import java.net.ServerSocket;
 25  
 import java.security.KeyStore;
 26  
 import java.security.Security;
 27  
 import java.security.UnrecoverableKeyException;
 28  
 
 29  
 import javax.net.ssl.KeyManagerFactory;
 30  
 import javax.net.ssl.SSLContext;
 31  
 import javax.net.ssl.SSLServerSocket;
 32  
 import javax.net.ssl.SSLServerSocketFactory;
 33  
 import javax.net.ssl.TrustManagerFactory;
 34  
 
 35  
 import mx4j.log.Log;
 36  
 import mx4j.log.Logger;
 37  
 import mx4j.tools.adaptor.ssl.SSLAdaptorServerSocketFactoryMBean;
 38  
 
 39  
 /**
 40  
  * This MBean creates SSLServerSocket instances.
 41  
  * <p>
 42  
  * It can be configured to use a specific keystore and SSL protocol version to create
 43  
  * SSLServerSockets that will use the keystore information to encrypt data. <br>
 44  
  * <p/> A keystore can be created with this command:
 45  
  * 
 46  
  * <pre>
 47  
  *  keytool -genkey -v -keystore store.key -storepass storepwd -keypass keypwd -dname &quot;CN=Simone Bordet, OU=Project Administrator, O=MX4J, L=Torino, S=TO, C=IT&quot; -validity 365
 48  
  * </pre>
 49  
  * 
 50  
  * or with this minimal command (that will prompt you for further information):
 51  
  * 
 52  
  * <pre>
 53  
  *  keytool -genkey -keystore store.key
 54  
  * </pre>
 55  
  * 
 56  
  * <p/> A keystore may contains more than one entry, but only the first entry will be
 57  
  * used for encryption, no matter which is the alias for that entry. <p/> Following
 58  
  * the first example of generation of the keystore, this MBean must be instantiated
 59  
  * and then setup by invoking the following methods:
 60  
  * <ul>
 61  
  * <li> {@link #setKeyStoreName}("store.key");
 62  
  * <li> {@link #setKeyStorePassword}("storepwd");
 63  
  * <li> {@link #setKeyManagerPassword}("keypwd");
 64  
  * </ul>
 65  
  * before {@link #createServerSocket} is called.
 66  
  */
 67  
 public class IBMSslAdapterServerSocketFactory implements SSLAdaptorServerSocketFactoryMBean
 68  
 {
 69  
 
 70  
     // it will always be IBM, anyway
 71  0
     private SecurityProviderFactory spFactory = new AutoDiscoverySecurityProviderFactory();
 72  0
     private SecurityProviderInfo spInfo = spFactory.getSecurityProviderInfo();
 73  
 
 74  0
     private String m_keyStoreType = "JKS";
 75  0
     private String m_trustStoreType = "JKS";
 76  
     private String m_keyStoreName;
 77  
     private String m_trustStoreName;
 78  
     private String m_keyStorePassword;
 79  
     private String m_trustStorePassword;
 80  0
     private String m_keyManagerAlgorithm = spInfo.getKeyManagerAlgorithm();
 81  
     // the same?
 82  0
     private String m_trustManagerAlgorithm = spInfo.getKeyManagerAlgorithm();
 83  
     private String m_keyManagerPassword;
 84  
     // IMPORTANT Sun-specific version works with TLS protocol,
 85  
     // but fails in Internet Explorer and IBM-specific provider.
 86  
     // SSL works fine though
 87  0
     private String m_sslProtocol = "SSL";
 88  
 
 89  
     public IBMSslAdapterServerSocketFactory()
 90  0
     {
 91  0
         Security.addProvider(spFactory.getProvider());
 92  0
     }
 93  
 
 94  
     public void setKeyStoreType(String keyStoreType)
 95  
     {
 96  0
         if (keyStoreType == null || keyStoreType.trim().length() == 0)
 97  
         {
 98  0
             throw new IllegalArgumentException("Invalid KeyStore type");
 99  
         }
 100  0
         m_keyStoreType = keyStoreType;
 101  0
     }
 102  
 
 103  
     public void setTrustStoreType(String trustStoreType)
 104  
     {
 105  0
         if (trustStoreType == null || trustStoreType.trim().length() == 0)
 106  
         {
 107  0
             throw new IllegalArgumentException("Invalid TrustStore type");
 108  
         }
 109  0
         m_trustStoreType = trustStoreType;
 110  0
     }
 111  
 
 112  
     public void setKeyStoreName(String name)
 113  
     {
 114  0
         if (name == null || name.trim().length() == 0)
 115  
         {
 116  0
             throw new IllegalArgumentException("Invalid KeyStore name");
 117  
         }
 118  0
         m_keyStoreName = name;
 119  0
     }
 120  
 
 121  
     public void setTrustStoreName(String name)
 122  
     {
 123  0
         if (name == null || name.trim().length() == 0)
 124  
         {
 125  0
             throw new IllegalArgumentException("Invalid TrustStore name");
 126  
         }
 127  0
         m_trustStoreName = name;
 128  0
     }
 129  
 
 130  
     public void setKeyStorePassword(String password)
 131  
     {
 132  0
         if (password == null || password.trim().length() == 0)
 133  
         {
 134  0
             throw new IllegalArgumentException("Invalid KeyStore password");
 135  
         }
 136  0
         m_keyStorePassword = password;
 137  0
     }
 138  
 
 139  
     public void setTrustStorePassword(String password)
 140  
     {
 141  0
         if (password == null || password.trim().length() == 0)
 142  
         {
 143  0
             throw new IllegalArgumentException("Invalid TrustStore password");
 144  
         }
 145  0
         m_trustStorePassword = password;
 146  0
     }
 147  
 
 148  
     public void setKeyManagerAlgorithm(String algorithm)
 149  
     {
 150  0
         if (algorithm == null || algorithm.trim().length() == 0)
 151  
         {
 152  0
             throw new IllegalArgumentException("Invalid KeyManager algorithm");
 153  
         }
 154  0
         m_keyManagerAlgorithm = algorithm;
 155  0
     }
 156  
 
 157  
     public void setTrustManagerAlgorithm(String algorithm)
 158  
     {
 159  0
         if (algorithm == null || algorithm.trim().length() == 0)
 160  
         {
 161  0
             throw new IllegalArgumentException("Invalid TrustManager algorithm");
 162  
         }
 163  0
         m_trustManagerAlgorithm = algorithm;
 164  0
     }
 165  
 
 166  
     public void setKeyManagerPassword(String password)
 167  
     {
 168  0
         if (password == null || password.trim().length() == 0)
 169  
         {
 170  0
             throw new IllegalArgumentException("Invalid KeyManager password");
 171  
         }
 172  0
         m_keyManagerPassword = password;
 173  0
     }
 174  
 
 175  
     public void setSSLProtocol(String protocol)
 176  
     {
 177  0
         if (protocol == null || protocol.trim().length() == 0)
 178  
         {
 179  0
             throw new IllegalArgumentException("Invalid SSL protocol");
 180  
         }
 181  0
         m_sslProtocol = protocol;
 182  0
     }
 183  
 
 184  
     /**
 185  
      * Returns a SSLServerSocket on the given port.
 186  
      */
 187  
     public ServerSocket createServerSocket(int port, int backlog, String host) throws IOException
 188  
     {
 189  0
         if (m_keyStoreName == null)
 190  
         {
 191  0
             throw new IOException("KeyStore file name cannot be null");
 192  
         }
 193  0
         if (m_keyStorePassword == null)
 194  
         {
 195  0
             throw new IOException("KeyStore password cannot be null");
 196  
         }
 197  
 
 198  0
         Logger logger = getLogger();
 199  0
         if (logger.isEnabledFor(Logger.TRACE))
 200  
         {
 201  0
             logger.trace("Creating SSLServerSocket");
 202  0
             logger.trace("\tKeyStore " + m_keyStoreName + ", type " + m_keyStoreType);
 203  0
             logger.trace("\tKeyManager algorithm is " + m_keyManagerAlgorithm);
 204  0
             logger.trace("\tTrustStore " + m_trustStoreName + ", type " + m_trustStoreType);
 205  0
             logger.trace("\tTrustManager algorithm is " + m_trustManagerAlgorithm);
 206  0
             logger.trace("\tSSL protocol version is " + m_sslProtocol);
 207  
         }
 208  
 
 209  
         try
 210  
         {
 211  0
             KeyStore keystore = KeyStore.getInstance(m_keyStoreType);
 212  0
             InputStream keyStoreStream = IOUtils.getResourceAsStream(m_keyStoreName, getClass());
 213  
             // Must check for nullity, otherwise a new empty keystore is created by
 214  
             // KeyStore.load
 215  0
             if (keyStoreStream == null)
 216  
             {
 217  
                 // Let's look at the file system, maybe that the name provided is in
 218  
                 // fact a file path
 219  0
                 File fle = FileUtils.newFile(m_keyStoreName);
 220  0
                 if (fle.exists()) keyStoreStream = new FileInputStream(fle);
 221  
             }
 222  0
             if (keyStoreStream == null) throw new IOException("Cannot find KeyStore " + m_keyStoreName);
 223  0
             keystore.load(keyStoreStream, m_keyStorePassword.toCharArray());
 224  
             try
 225  
             {
 226  0
                 keyStoreStream.close();
 227  
             }
 228  0
             catch (IOException x)
 229  
             {
 230  
                 // ignore
 231  0
             }
 232  
 
 233  0
             KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(m_keyManagerAlgorithm);
 234  
             // Use the keystore password as default if not given
 235  0
             keyFactory.init(keystore, m_keyManagerPassword == null
 236  
                             ? m_keyStorePassword.toCharArray() : m_keyManagerPassword.toCharArray());
 237  
 
 238  0
             TrustManagerFactory trustFactory = null;
 239  0
             if (m_trustStoreName != null)
 240  
             {
 241  
                 // User specified a trust store, retrieve it
 242  
 
 243  0
                 if (m_trustStorePassword == null)
 244  
                 {
 245  0
                     throw new IOException("TrustStore password cannot be null");
 246  
                 }
 247  
 
 248  0
                 KeyStore trustStore = KeyStore.getInstance(m_trustStoreType);
 249  0
                 InputStream trustStoreStream = IOUtils.getResourceAsStream(m_trustStoreName, getClass());
 250  
                 // Check for nullity
 251  0
                 if (trustStoreStream == null)
 252  
                 {
 253  0
                     throw new IOException("Cannot find TrustStore " + m_trustStoreName);
 254  
                 }
 255  0
                 trustStore.load(trustStoreStream, m_trustStorePassword.toCharArray());
 256  
 
 257  0
                 trustFactory = TrustManagerFactory.getInstance(m_trustManagerAlgorithm);
 258  0
                 trustFactory.init(trustStore);
 259  
             }
 260  
 
 261  0
             SSLContext context = SSLContext.getInstance(m_sslProtocol);
 262  
             // Below call does not handle TrustManagers, needed when server must
 263  
             // authenticate clients.
 264  0
             context.init(keyFactory.getKeyManagers(), trustFactory == null
 265  
                             ? null : trustFactory.getTrustManagers(), null);
 266  
 
 267  0
             SSLServerSocketFactory ssf = context.getServerSocketFactory();
 268  0
             SSLServerSocket serverSocket = (SSLServerSocket)ssf.createServerSocket(port, backlog,
 269  
                 InetAddress.getByName(host));
 270  
 
 271  0
             return serverSocket;
 272  
         }
 273  0
         catch (IOException x)
 274  
         {
 275  0
             logger.error("", x);
 276  0
             throw x;
 277  
         }
 278  0
         catch (UnrecoverableKeyException x)
 279  
         {
 280  
             // Wrong password for the key
 281  0
             logger.error("Probably a bad key password", x);
 282  0
             throw new IOException("Probably a bad key password: " + x.toString());
 283  
         }
 284  0
         catch (Exception x)
 285  
         {
 286  0
             logger.error("Unexpected exception", x);
 287  0
             throw new IOException(x.toString());
 288  
         }
 289  
     }
 290  
 
 291  
     private Logger getLogger()
 292  
     {
 293  0
         return Log.getLogger(getClass().getName());
 294  
     }
 295  
 }