Search code examples
javarmi

LocateRegistry.createRegistry


I need an RMI registry that makes the service accessible from outside my machine, while still being able to refuse a connection based on the IP of the client. The following code makes the registry only accessible from my machine, but never gets into the "RMIClientSocketFactory" code:

LocateRegistry.createRegistry(uri.getPort(), new RMIClientSocketFactory() {
            @Override
            public Socket createSocket(String host, int port) throws IOException {
                System.out.println("RMIServerSocketFactory().createSocket()");
                InetAddress addr = InetAddress.getByName(host);
                if (addr.equals(InetAddress.getLocalHost())) {
                    return new Socket(addr, port);
                } else {
                    throw new IOException("remote socket bind forbidden.");
                }
            }
        }, new RMIServerSocketFactory() {
            @Override
            public ServerSocket createServerSocket(int port) throws IOException {
                System.out.println("RMIServerSocketFactory().createServerSocket()");
                return new ServerSocket(port, 0, InetAddress.getByName("127.0.0.1"));
            }
        });

So it runs "RMIServerSocketFactory" and binds on the loopback, but never verifies the client IP. Any help is welcome, thank you very much!


Solution

  • The client socket factory is not what you need.

    What you need is the ServerSocket to reject connections from unwanted IPs. The easiest way to achieve this is to create a subclass of ServerSocket which overrides the accept() method to immediately close connections from unwanted IPs and throw an exception.

    However there are better, low level ways to control network access, I don't think your application doubling as a firewall (which is essentially what you need) is a particularly good idea.