determing the socket factory currently used

Hi all,

On the server side, there are 2 different socket factories being used:

SSL server/client socket factory on port 3000

server/client socket factory on port 1099

When a request comes in, can we determine the type of socket factory being used?

Thanks in advance.

[304 byte] By [eddiecjchianga] at [2007-11-27 8:48:40]
# 1
Why would you need to know that? You can get the SSLSocketFactory from an SSLSocket via the SSLContext but why?
ejpa at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 2
> Why would you need to know that? You can get the> SSLSocketFactory from an SSLSocket via the SSLContext> but why?If the connection is using ssl, then more access is given.Could you please explain a bit more about how to getting SSLSocketFactory?
eddiecjchianga at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 3

> If the connection is using ssl, then more access is

> given.

More access to what?

> Could you please explain a bit more about how to

> getting SSLSocketFactory?

I was wrong. You can't get the SSLSocketFactory from the SSLSocket. I still don't understand why you need it. There's nothing in the SSLSocketFactory that isn't also available in the SSLSockets it creates.

ejpa at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 4

> > Why would you need to know that? You can get the

> > SSLSocketFactory from an SSLSocket via the

> SSLContext

> > but why?

>

> If the connection is using ssl, then more access is

> given.

I still don't understand why you don't know. I mean I guess you are referring to it just as Socket in your code...

anyway if all else fails you could do this.

Socket s = // from somewhere

if(s instanceof SSLSocket){

// is secure

}else{

// is not secure

}

cotton.ma at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 5

Pardon me, I should make the point clearer.

I am implementing an RMI registry that accepts two types of requests:

1. secure connection using SslRMI(Server/Client)SocketFactory on port 3000

2. default RMI(Server/Client)SocketFactory on port 1099

The registry shall fulfil requests when clients use SSL connection to make any remote method call (i.e. bind(), rebind() unbind(), list() and lookup()).

But if the connection is non-SSL, the only limited operations are allowed (i.e. list() and lookup()).

Questions is, how can we find out what type of connection is being used when client makes a remote method call.

As cotton.m said:

> [code]

> Socket s = // from somewhere

> if(s instanceof SSLSocket){

>// is secure

> se{

>// is not secure

> /code]

Am I on the right direction on getting the socket used using sun.rmi.transport.tcp.TCPTransport and TCPEndpoint?

Cheers

eddiecjchianga at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 6

Are you aware that the standard RMI Registry already only allows bind/rebind/unbind from processes in the same host as itself?

I smell some overkill here.

Are you also aware that you can't start two instances of the Registry in the same JVM?

And if you're writing your own from scratch, how are you going to deal with the bootstrap issue?

ejpa at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 7

Yea, I do aware that Registry allows bind/rebind/unbind operations from local process.

However, the Registry I am implementing aims to allow authenticated remote process to bind remote objects.

About the mulitple Registry object ID in one JVM, Sun has resolved it:

"The internal object table is now keyed on a combination of ObjID and Transport

so that multiple registries (each on a different port) can be exported."

from: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4267864

Here is how I start up the SSL registry and non SSL registry:

public class RegistryImpl extends RemoteServer implements Registry {

// SSL Registry constructor

public RegistryImpl(int port, RMIClientSocketFactory rcsf, RMIServerSocketFactory rssf) throws RemoteException {

namespace = new Hashtable<String, Remote>();

LiveRef liveref = new LiveRef(ObjID.REGISTRY_ID, port, rcsf, rssf);

UnicastServerRef unicastserverref = new UnicastServerRef2(liveref);

ref = unicastserverref;

unicastserverref.exportObject(this, null, true);

}

// Non-SSL Registry constructor

public RegistryImpl(int port) throws RemoteException {

namespace = new Hashtable<String, Remote>();

LiveRef liveref = new LiveRef(ObjID.REGISTRY_ID, port);

UnicastServerRef unicastserverref = new UnicastServerRef(liveref);

ref = unicastserverref;

unicastserverref.exportObject(this, null, true);

}

}

Registry instances creation:

sslRegistry = new RegistryImpl(sslPort, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory(null, null, true));

registry = new RegistryImpl(port);

Client uses the following code to get Registry instance:

Registry sslRegistry = LocateRegistry.getRegistry(ip, port, new SslRMIClientSocketFactory());

Registry registry = LocateRegistry.getRegistry(ip, port);

Message was edited by:

eddiecjchiang

eddiecjchianga at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 8
So why don't you just create two classes? One can inherit from the other ... much simpler
ejpa at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 9

> So why don't you just create two classes? One can

> inherit from the other ... much simpler

I can even just use a boolean variable to flag whether the current instance is SSL or non-SSL.

But is there a better way to find out the socket used by an incoming RMI request?

Regards

eddiecjchianga at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...
# 10

Not really. Here you go:

import java.rmi.AccessException;

import java.rmi.NotBoundException;

import java.rmi.Remote;

import java.rmi.RemoteException;

import java.rmi.registry.LocateRegistry;

import java.rmi.registry.Registry;

import javax.rmi.ssl.SslRMIClientSocketFactory;

import javax.rmi.ssl.SslRMIServerSocketFactory;

public class ReadOnlyRegistry

extends sun.rmi.registry.RegistryImpl

// NB DO NOT SPECIFY THIS, otherwise the default Registry stub is incompatible with this

// remote object.

// implements Registry

{

private Registrydelegate;

/**

* Creates a new instance of ReadOnlyRegistry.

* @param plaintextPort Plaintext port number: Only list() and lookup() are permitted via this port.

* @param sslPort SSL port number: all operations are permitted via this port. This

* registry is constructed with default SslRMIClientSocketFactory and SslRMIServerSocketFactory.

* All the conditions for using a default SSLContext and these factories are therefore

* required, specifically the system properties:

* <ul>

*<li>javax.net.keyStore

*<li>javax.net.keyStoreType

*<li>javax.net.keyStorePassword

*<li>javax.net.trustStore

*<li>javax.net.trustStoreType

* </ul>to be set correctly.

* @exception RemoteException Exception constructing either Registry.

*/

public ReadOnlyRegistry(int plaintextPort, int sslPort) throws RemoteException

{

super(plaintextPort);

// Construct the SSL delegate.

// Note that as LocateRegistry.createRegistry() reutnrs the remote object, not a stub,

// we will talk to the delegate directly via local method invocation, not via RMI/SSL.

this.delegate = LocateRegistry.createRegistry(sslPort, new SslRMIClientSocketFactory(), new SslRMIServerSocketFactory());

}

public voidbind(String name, Remote object) throws RemoteException

{

throw new AccessException("bind not allowed via plaintext port");

}

public String[] list() throws RemoteException

{

return delegate.list();

}

public Remote lookup(String name) throws RemoteException, NotBoundException

{

return delegate.lookup(name);

}

public void rebind(String str, Remote remote) throws RemoteException

{

throw new AccessException("rebind not allowed via plaintext port");

}

public void unbind(String name) throws RemoteException, NotBoundException

{

throw new AccessException("unbind not allowed via plaintext port");

}

}

Message was edited by:

ejp

ejpa at 2007-7-12 20:56:16 > top of Java-index,Core,Core APIs...