Coverage Report - org.mule.management.agents.IBMSslAdapterServerSocketFactory
 
Classes in this File Line Coverage Branch Coverage Complexity
IBMSslAdapterServerSocketFactory
0%
0/100
0%
0/21
4.231
 
 1  
 /*
 2  
  * $Id: IBMSslAdapterServerSocketFactory.java 7976 2007-08-21 14:26:13Z 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  
  * @version $Revision: 7976 $
 68  
  */
 69  
 public class IBMSslAdapterServerSocketFactory implements SSLAdaptorServerSocketFactoryMBean
 70  
 {
 71  
 
 72  
     // it will always be IBM, anyway
 73  0
     private SecurityProviderFactory spFactory = new AutoDiscoverySecurityProviderFactory();
 74  0
     private SecurityProviderInfo spInfo = spFactory.getSecurityProviderInfo();
 75  
 
 76  0
     private String m_keyStoreType = "JKS";
 77  0
     private String m_trustStoreType = "JKS";
 78  
     private String m_keyStoreName;
 79  
     private String m_trustStoreName;
 80  
     private String m_keyStorePassword;
 81  
     private String m_trustStorePassword;
 82  0
     private String m_keyManagerAlgorithm = spInfo.getKeyManagerAlgorithm();
 83  
     // the same?
 84  0
     private String m_trustManagerAlgorithm = spInfo.getKeyManagerAlgorithm();
 85  
     private String m_keyManagerPassword;
 86  
     // IMPORTANT Sun-specific version works with TLS protocol,
 87  
     // but fails in Internet Explorer and IBM-specific provider.
 88  
     // SSL works fine though
 89  0
     private String m_sslProtocol = "SSL";
 90  
 
 91  
     public IBMSslAdapterServerSocketFactory()
 92  0
     {
 93  0
         Security.addProvider(spFactory.getProvider());
 94  0
     }
 95  
 
 96  
     public void setKeyStoreType(String keyStoreType)
 97  
     {
 98  0
         if (keyStoreType == null || keyStoreType.trim().length() == 0)
 99  
         {
 100  0
             throw new IllegalArgumentException("Invalid KeyStore type");
 101  
         }
 102  0
         m_keyStoreType = keyStoreType;
 103  0
     }
 104  
 
 105  
     public void setTrustStoreType(String trustStoreType)
 106  
     {
 107  0
         if (trustStoreType == null || trustStoreType.trim().length() == 0)
 108  
         {
 109  0
             throw new IllegalArgumentException("Invalid TrustStore type");
 110  
         }
 111  0
         m_trustStoreType = trustStoreType;
 112  0
     }
 113  
 
 114  
     public void setKeyStoreName(String name)
 115  
     {
 116  0
         if (name == null || name.trim().length() == 0)
 117  
         {
 118  0
             throw new IllegalArgumentException("Invalid KeyStore name");
 119  
         }
 120  0
         m_keyStoreName = name;
 121  0
     }
 122  
 
 123  
     public void setTrustStoreName(String name)
 124  
     {
 125  0
         if (name == null || name.trim().length() == 0)
 126  
         {
 127  0
             throw new IllegalArgumentException("Invalid TrustStore name");
 128  
         }
 129  0
         m_trustStoreName = name;
 130  0
     }
 131  
 
 132  
     public void setKeyStorePassword(String password)
 133  
     {
 134  0
         if (password == null || password.trim().length() == 0)
 135  
         {
 136  0
             throw new IllegalArgumentException("Invalid KeyStore password");
 137  
         }
 138  0
         m_keyStorePassword = password;
 139  0
     }
 140  
 
 141  
     public void setTrustStorePassword(String password)
 142  
     {
 143  0
         if (password == null || password.trim().length() == 0)
 144  
         {
 145  0
             throw new IllegalArgumentException("Invalid TrustStore password");
 146  
         }
 147  0
         m_trustStorePassword = password;
 148  0
     }
 149  
 
 150  
     public void setKeyManagerAlgorithm(String algorithm)
 151  
     {
 152  0
         if (algorithm == null || algorithm.trim().length() == 0)
 153  
         {
 154  0
             throw new IllegalArgumentException("Invalid KeyManager algorithm");
 155  
         }
 156  0
         m_keyManagerAlgorithm = algorithm;
 157  0
     }
 158  
 
 159  
     public void setTrustManagerAlgorithm(String algorithm)
 160  
     {
 161  0
         if (algorithm == null || algorithm.trim().length() == 0)
 162  
         {
 163  0
             throw new IllegalArgumentException("Invalid TrustManager algorithm");
 164  
         }
 165  0
         m_trustManagerAlgorithm = algorithm;
 166  0
     }
 167  
 
 168  
     public void setKeyManagerPassword(String password)
 169  
     {
 170  0
         if (password == null || password.trim().length() == 0)
 171  
         {
 172  0
             throw new IllegalArgumentException("Invalid KeyManager password");
 173  
         }
 174  0
         m_keyManagerPassword = password;
 175  0
     }
 176  
 
 177  
     public void setSSLProtocol(String protocol)
 178  
     {
 179  0
         if (protocol == null || protocol.trim().length() == 0)
 180  
         {
 181  0
             throw new IllegalArgumentException("Invalid SSL protocol");
 182  
         }
 183  0
         m_sslProtocol = protocol;
 184  0
     }
 185  
 
 186  
     /**
 187  
      * Returns a SSLServerSocket on the given port.
 188  
      */
 189  
     public ServerSocket createServerSocket(int port, int backlog, String host) throws IOException
 190  
     {
 191  0
         if (m_keyStoreName == null)
 192  
         {
 193  0
             throw new IOException("KeyStore file name cannot be null");
 194  
         }
 195  0
         if (m_keyStorePassword == null)
 196  
         {
 197  0
             throw new IOException("KeyStore password cannot be null");
 198  
         }
 199  
 
 200  0
         Logger logger = getLogger();
 201  0
         if (logger.isEnabledFor(Logger.TRACE))
 202  
         {
 203  0
             logger.trace("Creating SSLServerSocket");
 204  0
             logger.trace("\tKeyStore " + m_keyStoreName + ", type " + m_keyStoreType);
 205  0
             logger.trace("\tKeyManager algorithm is " + m_keyManagerAlgorithm);
 206  0
             logger.trace("\tTrustStore " + m_trustStoreName + ", type " + m_trustStoreType);
 207  0
             logger.trace("\tTrustManager algorithm is " + m_trustManagerAlgorithm);
 208  0
             logger.trace("\tSSL protocol version is " + m_sslProtocol);
 209  
         }
 210  
 
 211  
         try
 212  
         {
 213  0
             KeyStore keystore = KeyStore.getInstance(m_keyStoreType);
 214  0
             InputStream keyStoreStream = IOUtils.getResourceAsStream(m_keyStoreName, getClass());
 215  
             // Must check for nullity, otherwise a new empty keystore is created by
 216  
             // KeyStore.load
 217  0
             if (keyStoreStream == null)
 218  
             {
 219  
                 // Let's look at the file system, maybe that the name provided is in
 220  
                 // fact a file path
 221  0
                 File fle = FileUtils.newFile(m_keyStoreName);
 222  0
                 if (fle.exists()) keyStoreStream = new FileInputStream(fle);
 223  
             }
 224  0
             if (keyStoreStream == null) throw new IOException("Cannot find KeyStore " + m_keyStoreName);
 225  0
             keystore.load(keyStoreStream, m_keyStorePassword.toCharArray());
 226  
             try
 227  
             {
 228  0
                 keyStoreStream.close();
 229  
             }
 230  0
             catch (IOException x)
 231  
             {
 232  
                 // ignore
 233  0
             }
 234  
 
 235  0
             KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(m_keyManagerAlgorithm);
 236  
             // Use the keystore password as default if not given
 237  0
             keyFactory.init(keystore, m_keyManagerPassword == null
 238  
                             ? m_keyStorePassword.toCharArray() : m_keyManagerPassword.toCharArray());
 239  
 
 240  0
             TrustManagerFactory trustFactory = null;
 241  0
             if (m_trustStoreName != null)
 242  
             {
 243  
                 // User specified a trust store, retrieve it
 244  
 
 245  0
                 if (m_trustStorePassword == null)
 246  
                 {
 247  0
                     throw new IOException("TrustStore password cannot be null");
 248  
                 }
 249  
 
 250  0
                 KeyStore trustStore = KeyStore.getInstance(m_trustStoreType);
 251  0
                 InputStream trustStoreStream = IOUtils.getResourceAsStream(m_trustStoreName, getClass());
 252  
                 // Check for nullity
 253  0
                 if (trustStoreStream == null)
 254  
                 {
 255  0
                     throw new IOException("Cannot find TrustStore " + m_trustStoreName);
 256  
                 }
 257  0
                 trustStore.load(trustStoreStream, m_trustStorePassword.toCharArray());
 258  
 
 259  0
                 trustFactory = TrustManagerFactory.getInstance(m_trustManagerAlgorithm);
 260  0
                 trustFactory.init(trustStore);
 261  
             }
 262  
 
 263  0
             SSLContext context = SSLContext.getInstance(m_sslProtocol);
 264  
             // Below call does not handle TrustManagers, needed when server must
 265  
             // authenticate clients.
 266  0
             context.init(keyFactory.getKeyManagers(), trustFactory == null
 267  
                             ? null : trustFactory.getTrustManagers(), null);
 268  
 
 269  0
             SSLServerSocketFactory ssf = context.getServerSocketFactory();
 270  0
             SSLServerSocket serverSocket = (SSLServerSocket)ssf.createServerSocket(port, backlog,
 271  
                 InetAddress.getByName(host));
 272  
 
 273  0
             return serverSocket;
 274  
         }
 275  0
         catch (IOException x)
 276  
         {
 277  0
             logger.error("", x);
 278  0
             throw x;
 279  
         }
 280  0
         catch (UnrecoverableKeyException x)
 281  
         {
 282  
             // Wrong password for the key
 283  0
             logger.error("Probably a bad key password", x);
 284  0
             throw new IOException("Probably a bad key password: " + x.toString());
 285  
         }
 286  0
         catch (Exception x)
 287  
         {
 288  0
             logger.error("Unexpected exception", x);
 289  0
             throw new IOException(x.toString());
 290  
         }
 291  
     }
 292  
 
 293  
     private Logger getLogger()
 294  
     {
 295  0
         return Log.getLogger(getClass().getName());
 296  
     }
 297  
 }