Link to home
Start Free TrialLog in
Avatar of azami
azamiFlag for Japan

asked on

Re-routing RMI sockets with client socket factory

Okay, here's an overview of what we want to accomplish:
Application Server program running on machine A.
Web (HTTP) server running on machine B.
Client applet running on machine C, on page served by web server at B.

Client on C uses RMI to talk to app server on A, without any change to the security policies on machine C.

I know this sounds impossible, because connecting to a machine other than the web server machine is a security violation.  Here's how we get around it:

We have a special client socket factory that takes the request to connect to machine A, port X, and instead opens a socket to a special port on B where we have another program listening.  It can ask that program, the "link", to connect to A:X.  The "link" can do so, then just hook the socket streams together so that all I/O for the socket gets re-routed.

This works, believe it or not.  The socket transparently communicates through this link program, with no special knowledge at either the client or the server end.  But alternating calls from the client result in security exceptions.  By watching when our factory gets called and when we get exceptions, it looks like what is happening is:

1 - First RMI call - no connection; therefore, factory called.  Factory creates (legal) socket connected to B, and tells the "link" to hook it up to A.
2 - The RMI call completes, everything is fine.
3 - Second RMI call - there's a connection already; the factory is not called, but the RMI code checks security AGAINST THE ORIGINAL INTENDED CONNECTION (to machine A); security check fails and the socket is closed.
4 - Third RMI call - once again, there's no connection, so the factory is called to create one; the RMI call works.

So, it seems the RMI code does not check security itself when it creates a socket - it assumes security is checked when the socket is created.  But if it already has a socket, it does check security, and looks at where it "wanted" a socket rather than where the socket actually goes.

We can work around the problem by re-trying after we get the security violation, or maybe we could force the socket to close after each transaction, but obviously, these are less efficient than leaving the socket open.

Can anyone suggest a way to either get RMI to check against the socket's real connection, or to not check security when the socket already exists?
Avatar of azami
azami
Flag of Japan image

ASKER

Edited text of question.
Avatar of heyhey_
heyhey_

nice problem :)

the only think I can suggest is to
1. decompile sun.rmi.* classes
2. download JDK 1.2 sources from sun
so that you can check the sources and see what's happening.

or you can download some other RMI implementation (I know at least one that is 100% Java and completely free)

I have seen similiar problems with Swing's JPopupMenu - when you create it yourself it has 'Warning' message (you have created it from untrusted class) but when you open some JComboBox (which popups itself JPopupMenu) and than execute the same code - you won't see that warning message.
I lost a lot of time dealing with this problem (it was a lot of bigger, but I reduced it to this one) and the answer was simple - Swing classes are local / trusted, Window object "Warning" label is set inside its constructor and ... JPopupMenus are cached.

it was more like a story - not a comment, but I finally got the URL. :))

http://www.metamata.com/products/
RMILite is a pure Java replacement for RMI that
uses minimal resources and works with all VMs
including browsers and Microsoft VMs.

I really wish you good luck !

best regards
  heyhey
Why not have an RMI server stub on B that re-directs requests to A (rather than a socket server that re-directs the actual traffic)?
Avatar of azami

ASKER

Sprinkmeier -

Because, for maintenance reasons, we don't want application developers to have to do anything extra, like writing those stubs (proxies).  

This goes for install-time, too.  You see, the piece running at B is a generic collection point for a bunch of applications, and we would like that to only be installed once.  Thereafter, any application enabled for the system can just be installed and configured at the application machine (A).  Although we _could_ probably get away with requiring installation at B, we'd really rather not.

I mention the above because at one time I pursued the possibility of somehow using the stubs and skeletons generated by rmic.  One thing we found is that rmi resists serializing a remote object.  Basically, if it has a remote interface, rmi will serialize that instead of the object.  So, we had trouble sending a proxy from the application to machine B.  

We could maybe get it to work if application developers created the proxies themselves, duplicating the remoted interface.  This means one extra class for every class that supports a remote interface.
Avatar of azami

ASKER

Heyhey -

We just got the source code from Sun, and we can see that sure enough it tries to re-use sockets that aren't busy, but checks against its intended connection rather than the real one.  I guess they never really considered the possibility a special socket or factory would connect to a different machine than was requested.

RMILite looks like it may solve our problem, thanks for that tip.  We're trying things out with it (and will need to get funding for it).  If it works out and solves our problem (and nobody answers the question before then), I'll give you the points.

In the meantime, the question is still open as stated - How do I get RMI to check against the real destination, or not do the check at all when getting an existing connection?

ASKER CERTIFIED SOLUTION
Avatar of heyhey_
heyhey_

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of azami

ASKER

Unfortunately, I'm not on that project anymore (changed employers).  But last I heard, they were seriously looking at RMILite.  Whether or not they do, a quick test shows that it definitely accomplishes what we needed.

Thanks!