CS 696 Emerging Technologies: Java Distributed Computing Spring Semester, 1999 RMI SocketFactories |
||
---|---|---|
© 1999, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 09-Mar-99 |
RMI and Security
Java provides security manager to provide controls over what client or server can do a machine
Your application needs to insure proper security manager in installed in application
java.securtiy package is useful in encryption, etc.
Other types of security are your application's problem
RMI addresses encrypting of data over the wire
RMI Wire encryption Process
1. Create a custom socket type that does encryption
2. Create and install a socket factory in you RMI application
We will use xor encryption
Creating a Custom Socket
1. Subclass FilterOutputStream and FilterInputStream to create streams to be used in the socket
2. Subclass java.net.Socket
3. Subclass java.net.ServerSocket
XorInputStream
public class XorInputStream extends FilterInputStream { byte codeMask = 0; public XorInputStream(InputStream in, byte mask) { super(in); codeMask = mask; } public int read() throws IOException { int input = in.read(); if ( input < 0 ) return input; else return (byte) input ^ codeMask; } public int read(byte inputBuffer[], int offset, int length) throws IOException { byte[] codedInput = new byte[length]; int bytesRead = in.read( codedInput ); for (int k = 0; k < bytesRead;k++) inputBuffer[offset + k ] = (byte) (codedInput[k] ^ codeMask); return bytesRead; } }
XorOutputStream
public class XorOutputStream extends FilterOutputStream { byte codeMask = 0; public XorOutputStream(OutputStream out, byte mask) { super(out); codeMask = mask; } public void write(int output) throws IOException { if ( output < 0 ) //not a byte, { out.write(output); } else out.write( ((byte) output) ^ codeMask ); } public void write(byte output[], int offset, int length) throws IOException { byte[] coded = new byte[length]; for (int i = 0 ; i < length ; i++) { coded[i] = (byte) ( output[offset + i] ^ (byte) codeMask ); } out.write( coded); } }
XorSocket
public class XorSocket extends java.net.Socket { /* Streams used by socket */ private InputStream in; private OutputStream out; private byte xorMask = 0; public XorSocket( byte mask) // This is needed!! throws IOException { super(); xorMask = mask; } public XorSocket(String host, int port, byte mask) throws IOException { super(host, port); xorMask = mask; }
XorSocket - Continued public InputStream getInputStream() throws IOException { if (in == null) { BufferedInputStream buffered = new BufferedInputStream( super.getInputStream() ); in = new XorInputStream( buffered , xorMask); } return in; } public OutputStream getOutputStream() throws IOException { if (out == null) { BufferedOutputStream buffered = new BufferedOutputStream( super.getOutputStream() ); out = new XorOutputStream(buffered, xorMask); } return out; } public synchronized void close() throws IOException { OutputStream out = getOutputStream(); out.flush(); super.close(); } }
XorServerSocket
public class XorServerSocket extends ServerSocket { private byte xorMask = 0; public XorServerSocket(int port, byte mask) throws IOException { super(port); xorMask = mask; } public XorServerSocket(int port, int backlog, byte mask) throws IOException { super(port, backlog); xorMask = mask; } public XorServerSocket(int port, int backlog, InetAddress bindAddress, byte mask) throws IOException { super(port, backlog, bindAddress); xorMask = mask; } public Socket accept() throws IOException { Socket socket = new XorSocket( xorMask ); implAccept(socket); return socket; } }
Note ServerSocket uses the Strategy and Prototype patterns
Creating a Custom RMISocketFactory
We need a SocketFactory for both the client and the server side.
Java.rmi.server.RMIClientSocketFactory
Interface with one method
Socket createSocket(String host, int port)
XorClientSocketFactory
package whitney.rmi.examples.sockets; import java.io.IOException; import java.io.Serializable; import java.rmi.server.RMIClientSocketFactory; import java.net.Socket; import sdsu.net.XorSocket; public final class XorClientSocketFactory implements RMIClientSocketFactory, Serializable { private byte xorMask = 0; public XorClientSocketFactory( byte mask ) { xorMask = mask; } public Socket createSocket( String host, int port ) throws IOException { return new XorSocket( host, port, xorMask ); } public boolean equals(Object aSocketFactory ) { if (! (aSocketFactory instanceof XorClientSocketFactory) ) return false; byte otherMask = ((XorClientSocketFactory) aSocketFactory).xorMask; if ( otherMask == xorMask ) return true; else return false; } public int hashCode() { return xorMask; } }
XorServerSocketFactory
package whitney.rmi.examples.sockets; import java.io.IOException; import java.io.Serializable; import java.rmi.server.RMIServerSocketFactory; import java.net.ServerSocket; import sdsu.net.XorServerSocket; public final class XorServerSocketFactory implements RMIServerSocketFactory, Serializable { private byte xorMask = 0; public XorServerSocketFactory( byte mask ) { xorMask = mask; } public ServerSocket createServerSocket( int port ) throws IOException { return new XorServerSocket( port, xorMask ); } public boolean equals(Object aSocketFactory ) { if (! (aSocketFactory instanceof XorServerSocketFactory) ) return false; byte otherMask = ((XorServerSocketFactory) aSocketFactory).xorMask; if ( otherMask == xorMask ) return true; else return false; } public int hashCode() { return xorMask; } }
Using The Socket Factories
Server Side package whitney.rmi.examples.sockets; import java.net.InetAddress; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.RMISecurityManager; import java.rmi.server.UnicastRemoteObject; public class HelloServer extends UnicastRemoteObject implements Hello { public HelloServer(byte mask ) throws RemoteException { super(0, new XorClientSocketFactory( mask), new XorServerSocketFactory( mask) ); } public String sayHello() { return "Hello World from " + getHostName(); } protected static String getHostName() { try { return InetAddress.getLocalHost().getHostName(); } catch (java.net.UnknownHostException who) { return "Unknown"; } } public static void main(String args[]) throws Exception { System.setSecurityManager(new RMISecurityManager()); Naming.rebind("rmi://eli.sdsu.edu/HelloA", new HelloServer( (byte)12) ); Naming.rebind("rmi://eli.sdsu.edu/HelloB", new HelloServer( (byte)42) ); System.out.println("HelloServer bound in registry"); } }
Client Side package whitney.rmi.examples.sockets; import java.rmi.*; import java.net.MalformedURLException; public class HelloClient { public static void main(String args[]) throws Exception { Hello remoteA = (Hello) Naming.lookup( "rmi://eli.sdsu.edu/HelloA"); System.out.println( "From Server A " + remoteA.sayHello() ); Hello remoteB = (Hello) Naming.lookup( "rmi://eli.sdsu.edu/HelloB"); System.out.println( "From Server B " + remoteB.sayHello() ); } }Since a XorClientSocketFactory object is downloaded to the client the XorClientSocketFactory class must be available to the client code at runtime.
Multiple Socket Factory
import java.io.*; import java.net.*; import java.rmi.server.*; public class MultiClientSocketFactory implements RMIClientSocketFactory, Serializable { private static RMISocketFactory defaultFactory = RMISocketFactory.getDefaultSocketFactory(); private String protocol; private byte[] data; public MultiClientSocketFactory(String protocol, byte[] data) { this.protocol = protocol; this.data = data; } public Socket createSocket(String host, int port) throws IOException { if (protocol.equals("compression")) { return new CompressionSocket(host, port); } else if (protocol.equals("xor")) { if (data == null || data.length != 1) throw new IOException("invalid argument for XOR protocol"); return new XorSocket(host, port, data[0]); } return defaultFactory.createSocket(host, port); } }We can have a factory return more than type of socket. This example is from Sun’s Creating a Custom RMI Socket Factory tutorial.
Copyright ©, All rights reserved.
1999 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 09-Mar-99    Next