***  This class provides Binary Compatibility only, not Source Compatibility  ***

com.sas.net.ssl
Class SSLRMISocketFactories

com.sas.net.ssl.SSLRMISocketFactories
All Implemented Interfaces:
RMIExportConfiguration

public final class SSLRMISocketFactories
implements RMIExportConfiguration

Factory which provides an application with the means to obtain RMI client and server socket factories.

The following modes of operation are supported:

Debugging SSL

Interactions with the JSSE API may be debugged using by defining the system property javax.net.debug.

Examples

Source code examples are provided for the following usage scenarios:
  1. Initializing the SSL RMI Socket Factory
  2. Exporting a remote object

Example 1: Initializing the SSL RMI Socket Factory

If your application requires SSL security for some or all of its Java remote objects, then construct an appropriate SSL RMI configuration from a properties object or input stream and use it to initialize the application's SSLRMISocketFactories instance.

This example shows how to construct an SSL RMI configuration and use it to initialize the SSLRMISocketFactories object which provides an application with the capability to obtain RMI port and client/server socket factories which will be used to export a remote object.

  1. Construct an SSLRMIConfiguration passing it either a properties object or an input stream to a properties configuration. The recommended best practice is to define a .config file which specifies the desired configuration properties.
  2. Get the application instance of SSLRMISocketFactories and set the SSL RMI configuration

Notes:

 
 import java.io.*;
 import com.sas.net.ssl.SSLRMIConfiguration;
 import com.sas.net.ssl.SSLRMISocketFactories;
 
 ...
 
 public static void main(String[] args) {
 
    ... 
 
    InputStream inputStream = null;
 
    try {
       // initialize the SSL RMI socket factories object
       // with the desired SSL RMI configuration
 
       final String sslRMIConfigFile = "C:\\xx\\sas_ssl_rmi.config";
       inputStream = new FileInputStream(sslRMIConfigFile);
       final SSLRMIConfiguration sslRMIConfiguration =
          new SSLRMIConfiguration(inputStream);
                        
       // configure the application's SSL RMI socket factory
       // before executing any code which instantiates remote objects
 
       SSLRMISocketFactories.getInstance().setConfiguration(sslRMIConfiguration);
    }
    catch (SSLRMIException e) {
 
       // unable to configure an SSL RMI configuration.
       //
       // check this exception's cause for additional details.
       //
       // if security is required, the application should treat this
       // as a fatal exception since remote objects may not be secured.
       
       ...
 
    }
    catch (IllegalArgumentException e) {
 
       // unable to configure an SSL RMI configuration due
       // to an invalid parameter.
       //
       // check this exception's cause for additional details.
       //
       // if security is required, the application should treat this
       // as a fatal exception since remote objects may not be secured.
 
       ...
 
    }
    finally {
       if (inputStream != null) {
          try {
             inputStream.close();
          }
          catch (IOException e) {
             // log an error message
          }
          finally {
             inputStream = null;
          }
       }
    }
 
    ...
        
    // if neither an SSLRMIException or IllegalArgumentException
    // were thrown, then it is now OK to execute code that
    // exports remote objects using socket factories obtained
    // from SSLRMISocketFactories.getInstance()
    ...
                      
  }
 
 

Example 2: Exporting a remote object that extends java.rmi.server.UnicastRemoteObject

A remote object implementation that extends Sun Microsystem's UnicastRemoteObject must specify the port and the client and server socket factories at construction time since the superclass's constructor exports the remote object to the RMI system. Note that we will not have access to an object until after the superclass's constructor has returned, so one must use the static

 Class Object.getClass()
 
method to obtain the Java Class or pass in the subclass's class as a parameter.

Notes:

  1. If security is desired for some or all Java remote objects, then the application must have already initialized the SSLRMISocketFactories with the desired configuration.
  2. since we need the Class to pass to the superclass's constructor one must use UserContext.class instead of this.getClass() since the object has not yet been instantiated.
  3. or, if your class is not final, ensure that constructors are provided to enable a subclass to specify a Class parameter if one prefers to use the subclass's Class instead of a superclass's Class to determine if SSL security is required.

Example 2a: Exporting a unicast remote object using the static class attribute

This example obtains the Class name from a static accessor. Use this approach if your class is final or if you do not need to provide control at the subclass level.

Note that if the application requires SSL to secure some or all of its Java remote objects that the application must have already initialized the SSLRMISocketFactories with the desired configuration before executing any code that exports remote objects to the RMI system.

 
 package com.sas.services.user;
 
 import java.rmi.server.UnicastRemoteObject;
 
 import com.sas.net.rmi.Constants;
 import com.sas.net.rmi.SSLRMISocketFactories;
 
 ...
 
 public final class UserContext 
    extends UnicastRemoteObject
    implements UserContextInterface {
 
    ...
 
    UserContext() 
       throws RemoteException {
        
       // if the application requires security for some or all
       // of its remote objects it must initialize its instance
       // of SSLRMISocketFactories prior to executing any code
       // that exports a remote object to the RMI system.
 
       super(
         SSLRMISocketFactories.getInstance().getPortForClass(
            Constants.PORT_ANONYMOUS, 
            UserContext.class),
         SSLRMISocketFactories.getInstance().getRMIClientSocketFactoryForClass(
            UserContext.class),
         SSLRMISocketFactories.getInstance().getRMIServerSocketFactoryForClass(
            UserContext.class));
 
       ...
    }
 
 }
 
 

Example 2b: Exporting a unicast remote object using a subclass Class parameter

This example obtains its socket factories using the subclass's Class. Note that we can't access "this" object until after the superclass's constructor call has returned, so if we want to obtain a socket based upon the subclass's Class it must be provided as a parameter.

Note that if the application requires SSL to secure some or all of its Java remote objects that the application must have already initialized the SSLRMISocketFactories with the desired configuration before executing any code that exports remote objects to the RMI system.

 
 import com.sas.net.rmi.Constants;
 import com.sas.net.ssl.SSLRMISocketFactories;
 
 public abstract class MyBaseRemoteObject
    extends UnicastRemoteObject
    implements MyBaseInterface {
 
    ... 
 
    MyBaseRemoteObject(
       final int rmiPort,
       final Class subclassClass) 
       throws RemoteException {
        
       // if the application requires security for some or all
       // of its remote objects it must initialize its instance
       // of SSLRMISocketFactories prior to executing any code
       // that exports a remote object to the RMI system.
 
       super(
         SSLRMISocketFactories.getInstance().getPortForClass(
            rmiPort,
            subclassClass),
         SSLRMISocketFactories.getInstance().getRMIClientSocketFactoryForClass(
            subclassClass),
         SSLRMISocketFactories.getInstance().getRMIServerSocketFactoryForClass(
            subclassClass));
 
       ...
    }
 
 ...
 
 }
 
 

Example 3: Exporting a Remote Object using an Export Utility

A remote object implementation that does not extend Sun Microsystem's UnicastRemoteObject must specify the client and server socket factories at the time it exports itself to the RMI system.

Example 3a: Exporting a Remote Object using an Export Utility using the static class attribute

An object which implements Remote, but does not extend UnicastRemoteObject, may be configured to conditionally export itself to the RMI system using the UnicastRemoteObjectExporter export utility.

Note that if the application requires SSL to secure some or all of its Java remote objects that the application must have already initialized the SSLRMISocketFactories with the desired configuration before executing any code that exports remote objects to the RMI system.

 
 package com.sas.xxx;
 
 
 import com.sas.net.rmi.Constants;
 import com.sas.net.ssl.SSLRMISocketFactories;
 import com.sas.net.ssl.UnicastRemoteObjectExporter;
 ...
 
 public final class MyService 
    implements MyServiceInterface {
 
   // utility used to export a remote object or null
   // if the service is local
   private RemoteObjectExporterInterface _remoteObjectExporter;
   
   public MyService (
      int rmiPort,
      boolean isRemote) 
      throws 
         RemoteException {
          
      // if the application requires security for some or all
      // of its Java remote objects the application
      // must initialize its instance of SSLRMISocketFactories 
      // prior to executing any code that exports a remote object to the RMI system.
 
      if (isRemote) {
         SSLRMISocketFactories sslRMISocketFactories = SSLRMISocketFactories.getInstance();
         Class theClass = MyService.class;
         _remoteObjectExporter = new UnicastRemoteObjectExporter(
            this,
            sslRMISocketFactories.getPortForClass(
               rmiPort,
               theClass),
            sslRMISocketFactories.getRMIClientSocketFactoryForClass(theClass),
            sslRMISocketFactories.getRMIServerSocketFactoryForClass(theClass));
         
         // export the remote object to the RMI system
         _remoteObjectExporter.export();
      }
 
    }
 
    public destroy () {
       
       if (_remoteObjectExporter != null) {
          try {
          // unexport the remote object from the RMI system
          _remoteObjectExporter.unexport();
          }
          finally {
             _remoteObjectExporter = null;
          }
       }
       
    }
 
 }
 
 

Example 3b: Exporting a SAS Foundation Service using an Export Utility using the static class attribute

All of the foundation services use the UnicastRemoteObjectExporter export utility to themselves to the RMI system.

Note that if the application requires SSL to secure some or all of its Java remote objects that the application must have already initialized the SSLRMISocketFactories with the desired configuration before executing any code that exports remote objects to the RMI system.

 
 package com.sas.services.user;
 
 
 import com.sas.net.rmi.Constants;
 import com.sas.net.ssl.SSLRMISocketFactories;
 import com.sas.net.ssl.UnicastRemoteObjectExporter;
 import com.sas.services.AbstractRemoteService;
 ...
 
 public final class UserService 
    extends AbstractRemoteService
    implements UserServiceInterface {
 
 
   private UserService (
      ServiceConfigurationInterface serviceConfiguration) 
      throws 
         RemoteException,
         ServiceException,
         IllegalArgumentException {
 
      this();
 
      ...
                
      // if the application requires security for some or all
      // of its Java remote objects the application
      // must initialize its instance of SSLRMISocketFactories 
      // prior to executing any code that exports a remote object to the RMI system.
 
      setRemoteableExporter(
         new UnicastRemoteObjectExporter(
            this,
            SSLRMISocketFactories.getInstance().getPortForClass(
               Constants.PORT_ANONYMOUS,
               UserService.class),
            SSLRMISocketFactories.getInstance().getRMIClientSocketFactoryForClass(
               UserService.class,
            SSLRMISocketFactories.getInstance().getRMIServerSocketFactoryForClass(
               UserService.class));
 
      // if this service is configured to be accessed by remote
      // clients, then it will be exported to the RMI system
      // using the RMI socket factories obtained from 
      // the application's instance of SSLRMISocketFactories
 
      configure(serviceConfiguration);
 
       ...
 
    }
 
 ...
 
 }
 
 

Example 3c: Exporting a SAS Foundation Service using an Export Utility using getClass()

If one specifies the remote object exporter in a sub-class, then one may designate the class using this.getClass() if one wants to use the subclass's Class to determine whether security is recommended.

Note that if the application requires SSL to secure some or all of its Java remote objects that the application must have already initialized the SSLRMISocketFactories with the desired configuration before executing any code that exports remote objects to the RMI system.

 
 package com.sas.services.user;
 
 
 import com.sas.net.rmi.Constants;
 import com.sas.net.ssl.SSLRMISocketFactories;
 import com.sas.net.ssl.UnicastRemoteObjectExporter;
 import com.sas.services.AbstractRemoteService;
 ...
 
 public class MyBaseService 
    extends AbstractRemoteService
    implements MyBaseServiceInterface {
 
 
   private MyBaseService (
      ServiceConfigurationInterface serviceConfiguration) 
      throws 
         RemoteException,
         ServiceException,
         IllegalArgumentException {
 
      this();
 
      ...
                
      // if the application requires security for some or all
      // of its Java remote objects the application
      // must initialize its instance of SSLRMISocketFactories 
      // prior to executing any code that exports a remote object to the RMI system.
 
      Class thisClass = getClass();
      setRemoteableExporter(
         new UnicastRemoteObjectExporter(
            this,
            SSLRMISocketFactories.getInstance().getPortForClass(
               Constants.PORT_ANONYMOUS,
               thisClass),
            SSLRMISocketFactories.getInstance().getRMIClientSocketFactoryForClass(
               thisClass,
            SSLRMISocketFactories.getInstance().getRMIServerSocketFactoryForClass(
               thisClass),
            true);
 
      // if this service is configured to be accessed by remote
      // clients, then it will be exported to the RMI system
      // using the RMI socket factories obtained from 
      // the application's instance of SSLRMISocketFactories
 
      configure(serviceConfiguration);
 
       ...
 
    }
 
 ...
 
 }
 
 

Since:
9.1.3

Method Summary
 SSLRMIConfiguration getConfiguration()
          Gets this SSL RMI socket factories configuration.
static SSLRMISocketFactories getInstance()
          Gets the default SSL RMI socket factories instance.
 int getPortForClass(int requestedPort, java.lang.Class javaClass)
          Gets the port which should be used to export the remote object for the specified class.
 java.rmi.server.RMIClientSocketFactory getRMIClientSocketFactory()
          Gets the RMI client socket factory for this factory's SSL RMI configuration without regard to the remote object's class.
 java.rmi.server.RMIClientSocketFactory getRMIClientSocketFactoryForClass(java.lang.Class javaClass)
          Gets the RMI client socket factory for this factory's SSL RMI configuration based upon the remote object's class.
 java.rmi.server.RMIServerSocketFactory getRMIServerSocketFactory()
          Gets the RMI server socket factory for this factory's SSL RMI configuration without regard to the remote object's class.
 java.rmi.server.RMIServerSocketFactory getRMIServerSocketFactoryForClass(java.lang.Class javaClass)
          Gets the RMI server socket factory for this factory's SSL RMI configuration based upon the remote object's class.
static boolean isJSSEAvailable()
          Determines whether the jsse.jar is available in this JRE.
 void setConfiguration(SSLRMIConfiguration sslRMIConfiguration)
          Sets the SSL RMI configuration that controls whether SSL is to be used for remote objects.
 

Method Detail

getInstance

public static SSLRMISocketFactories getInstance()
Gets the default SSL RMI socket factories instance.

This method returns an instance of an SSL RMI socket factories object that is intended for global use throughout a particular application. It will always return the same instance.

This instance's default configuration is to not apply SSL connections to any remote objects. If this is the desired mode of operation, then no additional configuration is required and the instance can be used to return socket factories that do not provide any security.

If the application desires SSL security for its Java remote objects, then the application must configure this instance by calling setConfiguration(SSLRMIConfiguration) specifying the desired SSL RMI configuration. Note that the application must configure this instance prior to executing any code which instantiates remote objects since remote objects will obtain their RMI client/server socket factories from this instance.

Returns:
The application's instance of the SSL RMI socket factories. This will always be non- null.

isJSSEAvailable

public static boolean isJSSEAvailable()
Determines whether the jsse.jar is available in this JRE.

Returns:
true if the jsse.jar is available or false if it is not available. Note that if it is not available then one cannot use an SSL RMI configuration to secure Java remote objects since the JSSE API is not available.

getConfiguration

public SSLRMIConfiguration getConfiguration()
Gets this SSL RMI socket factories configuration.

Configuration updates will only apply to socket factories obtained after the configuration has been updated.

Returns:
The configuration object that controls which, if any, Java remote objects are secured using SSL sockets. The configuration will always be non-null.

setConfiguration

public void setConfiguration(SSLRMIConfiguration sslRMIConfiguration)
                      throws java.lang.IllegalArgumentException
Sets the SSL RMI configuration that controls whether SSL is to be used for remote objects.

The default SSL RMI configuration is to not apply SSL security to any remote objects. If this default mode is acceptable, then the application does not need to invoke this method.

If SSL is desired for Java remote objects, then this method must be called with the desired SSL RMI configuration prior to executing any code which instantiates remote objects.

Parameters:
sslRMIConfiguration - SSL RMI configuration.
Throws:
java.lang.IllegalArgumentException - if a null SSL RMI configuration is specified.

getRMIClientSocketFactory

public java.rmi.server.RMIClientSocketFactory getRMIClientSocketFactory()
Gets the RMI client socket factory for this factory's SSL RMI configuration without regard to the remote object's class.

Use getRMIClientSocketFactoryForClass(Class) to obtain an RMI client socket factory for a specified class when using a configuration that observes security policy recommendations.

Specified by:
getRMIClientSocketFactory in interface RMIExportConfiguration
Returns:
Returns the RMI client socket factory or null if the default client socket factory should be used. This method will always return the same object.
See Also:
RMIExportConfiguration.getRMIClientSocketFactoryForClass(Class)

getRMIClientSocketFactoryForClass

public java.rmi.server.RMIClientSocketFactory getRMIClientSocketFactoryForClass(java.lang.Class javaClass)
                                                                         throws java.lang.IllegalArgumentException
Gets the RMI client socket factory for this factory's SSL RMI configuration based upon the remote object's class.

Use getRMIClientSocketFactory() to obtain an RMI client socket factory without regard to the Java remote object class.

Specified by:
getRMIClientSocketFactoryForClass in interface RMIExportConfiguration
Parameters:
javaClass - The Java class for which an RMI client socket factory is desired.

If the SSL RMI configuration's mode is Some then the selection policy will be consulted to determine whether SSL security is recommended for this class.

If the SSL RMI configuration's mode is All then an SSL RMI client socket factory will be returned if defined.

If the SSL RMI configuration's mode is None then a null RMI client socket factory will be returned indicating that the default non-secure factory should be used.

Returns:
Returns the RMI client socket factory for the specified Java class or null if the default factory should be used.
Throws:
java.lang.IllegalArgumentException - if a null Java class name is specified.
See Also:
RMIExportConfiguration.getRMIClientSocketFactory()

getRMIServerSocketFactory

public java.rmi.server.RMIServerSocketFactory getRMIServerSocketFactory()
Gets the RMI server socket factory for this factory's SSL RMI configuration without regard to the remote object's class.

Use getRMIServerSocketFactoryForClass(Class) to obtain an RMI server socket factory for a specified class when using a configuration that observes security policy recommendations.

Specified by:
getRMIServerSocketFactory in interface RMIExportConfiguration
Returns:
Returns an RMI server socket factory or null if the default factory should be used. This method will always return the same object.
See Also:
RMIExportConfiguration.getRMIServerSocketFactoryForClass(Class)

getRMIServerSocketFactoryForClass

public java.rmi.server.RMIServerSocketFactory getRMIServerSocketFactoryForClass(java.lang.Class javaClass)
                                                                         throws java.lang.IllegalArgumentException
Gets the RMI server socket factory for this factory's SSL RMI configuration based upon the remote object's class.

Use getRMIServerSocketFactory() to obtain an RMI server socket factory without regard to the Java remote object class.

Specified by:
getRMIServerSocketFactoryForClass in interface RMIExportConfiguration
Parameters:
javaClass - The Java class for which an RMI server socket factory is desired.

If the SSL RMI configuration's mode is Some then the selection policy will be consulted to determine whether SSL security is recommended for this class.

If the SSL RMI configuration's mode is All then an SSL RMI server socket factory will be returned if defined.

If the SSL RMI configuration's mode is None then a null RMI server socket factory will be returned indicating that the default non-secure factory should be used.

Returns:
Returns an RMI server socket factory or null if the default factory should be used.
Throws:
java.lang.IllegalArgumentException - if a null Java class name is specified.
See Also:
RMIExportConfiguration.getRMIServerSocketFactory()

getPortForClass

public int getPortForClass(int requestedPort,
                           java.lang.Class javaClass)
Gets the port which should be used to export the remote object for the specified class.

Specified by:
getPortForClass in interface RMIExportConfiguration
Parameters:
requestedPort - The port requested by the caller. An anonymous port may be requested by specifying a value of 0.
javaClass - The Java class for which an export port is desired or null.
Returns:
The requested port or the platform port if an anonymous port was requested and a platform port is defined.

***  This class provides Binary Compatibility only, not Source Compatibility  ***




Copyright © 2009 SAS Institute Inc. All Rights Reserved.