org.apache.commons.ssl

## Class RMISocketFactoryImpl

- java.lang.Object
- - java.rmi.server.RMISocketFactory
  - - org.apache.commons.ssl.RMISocketFactoryImpl

All Implemented Interfaces:
  java.rmi.server.RMIClientSocketFactory, java.rmi.server.RMIServerSocketFactory

    public class RMISocketFactoryImpl
    extends java.rmi.server.RMISocketFactory

An RMISocketFactory ideal for using RMI over SSL. The server secures both the registry and the remote objects. The client assumes that either both the registry and the remote objects will use SSL, or both will use plain-socket. The client is able to auto detect plain-socket registries and downgrades itself to accomodate those.

Unlike most existing RMI over SSL solutions in use (including Java 5's javax.rmi.ssl.SslRMIClientSocketFactory), this one does proper SSL hostname verification. From the client perspective this is straighforward. From the server perspective we introduce a clever trick: we perform an initial "hostname verification" by trying the current value of "java.rmi.server.hostname" against our server certificate. If the "java.rmi.server.hostname" System Property isn't set, we set it ourselves using the CN value we extract from our server certificate! (Some complications arise should a wildcard certificate show up, but we try our best to deal with those).

An SSL server cannot be started without a private key. We have defined some default behaviour for trying to find a private key to use that we believe is convenient and sensible:

If running from inside Tomcat, we try to re-use Tomcat's private key and certificate chain (assuming Tomcat-SSL on port 8443 is enabled). If this isn't available, we look for the "javax.net.ssl.keyStore" System property. Finally, if that isn't available, we look for "~/.keystore" and assume a password of "changeit".

If after all these attempts we still failed to find a private key, the RMISocketFactoryImpl() constructor will throw an SSLException.

Since:
  22-Apr-2005
Author:
  Credit Union Central of British Columbia, www.cucbc.com, juliusdavies@cucbc.com

### Field Summary

Fields
`private int` `anonymousPort`
`private java.util.Map` `clientMap`
`private javax.net.SocketFactory` `defaultClient`
`private java.lang.String` `localBindAddress`
`private static LogWrapper` `log`
`private javax.net.SocketFactory` `plainClient`
`static java.lang.String` `RMI_HOSTNAME_KEY`
`private java.util.Map` `serverSockets`
`private javax.net.ServerSocketFactory` `sslServer`

### Constructor Summary

Constructors
Constructor and Description
`RMISocketFactoryImpl()`
`RMISocketFactoryImpl(boolean createDefaultServer)`

### Method Summary

Methods
`java.net.ServerSocket` `createServerSocket(int port)`
`java.net.Socket` `createSocket(java.lang.String host, int port)`
`javax.net.SocketFactory` `getClient(java.lang.String host)`
`javax.net.SocketFactory` `getDefaultClient()`
`static java.lang.String` `getMyDefaultIP()`
`static java.util.SortedSet` `getMyInternetFacingIPs()`
`javax.net.ServerSocketFactory` `getServer()`
`private java.util.Set` `hostnamePossibilities(java.lang.String host)`
`void` `removeClient(javax.net.SocketFactory sf)`
`void` `removeClient(java.lang.String host)`
`void` `setAnonymousPort(int port)`
`void` `setClient(java.lang.String host, javax.net.SocketFactory f)`
`void` `setDefaultClient(javax.net.SocketFactory f)`
`void` `setLocalBindAddress(java.lang.String localBindAddress)`
`void` `setServer(javax.net.ServerSocketFactory f)`
`private void` `trustEachOther(SSLClient client, SSLServer server)`
`private void` `trustOurself()`

### Methods inherited from class java.rmi.server.RMISocketFactory

`getDefaultSocketFactory, getFailureHandler, getSocketFactory, setFailureHandler, setSocketFactory`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Field Detail

#### RMI_HOSTNAME_KEY

    public static final java.lang.String RMI_HOSTNAME_KEY

See Also:
  Constant Field Values

#### log

    private static final LogWrapper log

#### defaultClient

    private volatile javax.net.SocketFactory defaultClient

#### sslServer

    private volatile javax.net.ServerSocketFactory sslServer

#### localBindAddress

    private volatile java.lang.String localBindAddress

#### anonymousPort

    private volatile int anonymousPort

#### clientMap

    private java.util.Map clientMap

#### serverSockets

    private java.util.Map serverSockets

#### plainClient

    private final javax.net.SocketFactory plainClient

### Constructor Detail

#### RMISocketFactoryImpl

    public RMISocketFactoryImpl()
                         throws java.security.GeneralSecurityException,
                                java.io.IOException

Throws:
  `java.security.GeneralSecurityException`
  `java.io.IOException`

#### RMISocketFactoryImpl

    public RMISocketFactoryImpl(boolean createDefaultServer)
                         throws java.security.GeneralSecurityException,
                                java.io.IOException

Parameters:
  `createDefaultServer` - If false, then we only set the default client, and the default server is set to null. If true, then a default server is also created.
Throws:
  `java.security.GeneralSecurityException` - bad things
  `java.io.IOException` - bad things

### Method Detail

#### setServer

    public void setServer(javax.net.ServerSocketFactory f)
                   throws java.security.GeneralSecurityException,
                          java.io.IOException

Throws:
  `java.security.GeneralSecurityException`
  `java.io.IOException`

#### setLocalBindAddress

    public void setLocalBindAddress(java.lang.String localBindAddress)

#### setAnonymousPort

    public void setAnonymousPort(int port)

#### setDefaultClient

    public void setDefaultClient(javax.net.SocketFactory f)
                          throws java.security.GeneralSecurityException,
                                 java.io.IOException

Throws:
  `java.security.GeneralSecurityException`
  `java.io.IOException`

#### setClient

    public void setClient(java.lang.String host,
                 javax.net.SocketFactory f)
                   throws java.security.GeneralSecurityException,
                          java.io.IOException

Throws:
  `java.security.GeneralSecurityException`
  `java.io.IOException`

#### removeClient

    public void removeClient(java.lang.String host)

#### removeClient

    public void removeClient(javax.net.SocketFactory sf)

#### hostnamePossibilities

    private java.util.Set hostnamePossibilities(java.lang.String host)

#### trustOurself

    private void trustOurself()
                       throws java.security.GeneralSecurityException,
                              java.io.IOException

Throws:
  `java.security.GeneralSecurityException`
  `java.io.IOException`

#### trustEachOther

    private void trustEachOther(SSLClient client,
                      SSLServer server)
                         throws java.security.GeneralSecurityException,
                                java.io.IOException

Throws:
  `java.security.GeneralSecurityException`
  `java.io.IOException`

#### getServer

    public javax.net.ServerSocketFactory getServer()

#### getDefaultClient

    public javax.net.SocketFactory getDefaultClient()

#### getClient

    public javax.net.SocketFactory getClient(java.lang.String host)

#### createServerSocket

    public java.net.ServerSocket createServerSocket(int port)
                                             throws java.io.IOException

Specified by:
  `createServerSocket` in interface `java.rmi.server.RMIServerSocketFactory`
Specified by:
  `createServerSocket` in class `java.rmi.server.RMISocketFactory`
Throws:
  `java.io.IOException`

#### createSocket

    public java.net.Socket createSocket(java.lang.String host,
                               int port)
                                 throws java.io.IOException

Specified by:
  `createSocket` in interface `java.rmi.server.RMIClientSocketFactory`
Specified by:
  `createSocket` in class `java.rmi.server.RMISocketFactory`
Throws:
  `java.io.IOException`

#### getMyDefaultIP

    public static java.lang.String getMyDefaultIP()

#### getMyInternetFacingIPs

    public static java.util.SortedSet getMyInternetFacingIPs()
                                                      throws java.net.SocketException

Throws:
  `java.net.SocketException`