changeset 1793:464a78666d21

8193833: Better RMI connection support Reviewed-by: smarks
author robm
date Thu, 15 Feb 2018 19:03:51 +0000
parents a0ea2ba34bdd
children 48c243b4ef12
files src/share/classes/sun/rmi/transport/tcp/TCPTransport.java test/sun/rmi/transport/proxy/EagerHttpFallback.java test/sun/rmi/transport/tcp/DisableRMIOverHttp/DisableRMIOverHTTPTest.java test/sun/rmi/transport/tcp/DisableRMIOverHttp/TestIface.java test/sun/rmi/transport/tcp/DisableRMIOverHttp/TestImpl.java test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java
diffstat 6 files changed, 249 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java	Thu Mar 15 17:03:58 2018 +0300
+++ b/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java	Thu Feb 15 19:03:51 2018 +0000
@@ -117,6 +117,11 @@
                 }
             });
 
+    private static final boolean disableIncomingHttp =
+        java.security.AccessController.doPrivileged(
+            new GetPropertyAction("java.rmi.server.disableIncomingHttp", "true"))
+                .equalsIgnoreCase("true");
+
     /** total connections handled */
     private static final AtomicInteger connectionCount = new AtomicInteger(0);
 
@@ -720,6 +725,10 @@
                 int magic = in.readInt();
 
                 if (magic == POST) {
+                    System.err.println("DISABLED: " + disableIncomingHttp);
+                    if (disableIncomingHttp) {
+                        throw new RemoteException("RMI over HTTP is disabled");
+                    }
                     tcpLog.log(Log.BRIEF, "decoding HTTP-wrapped call");
 
                     // It's really a HTTP-wrapped request.  Repackage
--- a/test/sun/rmi/transport/proxy/EagerHttpFallback.java	Thu Mar 15 17:03:58 2018 +0300
+++ b/test/sun/rmi/transport/proxy/EagerHttpFallback.java	Thu Feb 15 19:03:51 2018 +0000
@@ -27,7 +27,7 @@
  *          sun.rmi.transport.proxy.eagerHttpFallback system property is set.
  * @library ../../../../java/rmi/testlibrary
  * @build TestLibrary
- * @run main/othervm EagerHttpFallback
+ * @run main/othervm -Djava.rmi.server.disableIncomingHttp=false EagerHttpFallback
  */
 
 import java.rmi.*;
@@ -45,6 +45,8 @@
                            "true");
         LocateRegistry.createRegistry(FALLBACK_PORT);
 
+        System.err.println("1-DISABLED: " + System.getProperty("java.rmi.server.disableIncomingHttp"));
+
         /*
          * The call below should trigger a ConnectException in the
          * RMIMasterSocketFactory when it attempts a direct connection to
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/rmi/transport/tcp/DisableRMIOverHttp/DisableRMIOverHTTPTest.java	Thu Feb 15 19:03:51 2018 +0000
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8193833
+ *
+ * @summary Disable RMI over HTTP by default
+ *
+ * @library ../../../../../java/rmi/testlibrary
+ * @build TestIface TestImpl
+ * @run main/othervm/timeout=60 DisableRMIOverHTTPTest
+ * @run main/othervm/timeout=60 -Djava.rmi.server.disableIncomingHttp=false DisableRMIOverHTTPTest
+ */
+
+/*
+ * This test is an adaptation of ../blockAccept/BlockAcceptTest.java
+ *
+ * This test:
+ * 1. Creates an object and exports it.
+ * 2. Makes a regular call, using HTTP tunnelling.
+ * 3. Either throws an exception if RMI over HTTP is disabled or completes
+ *    execution if not.
+ */
+
+import java.rmi.*;
+import java.rmi.server.RMISocketFactory;
+import java.io.*;
+import java.net.*;
+
+import sun.rmi.transport.proxy.RMIMasterSocketFactory;
+import sun.rmi.transport.proxy.RMIHttpToPortSocketFactory;
+
+public class DisableRMIOverHTTPTest
+{
+    public static void main(String[] args)
+        throws Exception
+    {
+        // HTTP direct to the server port
+        System.setProperty("http.proxyHost", "127.0.0.1");
+        boolean incomingHttpDisabled =
+                Boolean.valueOf(
+                    System.getProperty(
+                            "java.rmi.server.disableIncomingHttp", "true")
+                        .equalsIgnoreCase("true"));
+
+        // Set the socket factory.
+        System.err.println("(installing HTTP-out socket factory)");
+        HttpOutFactory fac = new HttpOutFactory();
+        RMISocketFactory.setSocketFactory(fac);
+
+        // Create remote object
+        TestImpl impl = new TestImpl();
+
+        // Export and get which port.
+        System.err.println("(exporting remote object)");
+        TestIface stub = impl.export();
+        try {
+            int port = fac.whichPort();
+
+            // Sanity
+            if (port == 0)
+                throw new Error("TEST FAILED: export didn't reserve a port(?)");
+
+            // The test itself: make a remote call and see if it's blocked or
+            // if it works
+            //Thread.sleep(2000);
+            System.err.println("(making RMI-through-HTTP call)");
+            String result = stub.testCall("dummy load");
+            System.err.println(" => " + result);
+
+            if ("OK".equals(result)) {
+                if (incomingHttpDisabled) {
+                    throw new Error(
+                        "TEST FAILED: should not receive result if incoming http is disabled");
+                }
+            } else {
+                if (!incomingHttpDisabled) {
+                    throw new Error("TEST FAILED: result not OK");
+                }
+            }
+            System.err.println("Test passed.");
+        } catch (UnmarshalException e) {
+            if (!incomingHttpDisabled) {
+                throw e;
+            } else {
+                System.err.println("Test passed.");
+            }
+        } finally {
+            try {
+                impl.unexport();
+            } catch (Throwable unmatter) {
+            }
+        }
+
+        // Should exit here
+    }
+
+    private static class HttpOutFactory
+        extends RMISocketFactory
+    {
+        private int servport = 0;
+
+        public Socket createSocket(String h, int p)
+            throws IOException
+        {
+            return ((new RMIHttpToPortSocketFactory()).createSocket(h, p));
+        }
+
+        /** Create a server socket and remember which port it's on.
+         * Aborts if createServerSocket(0) is called twice, because then
+         * it doesn't know whether to remember the first or second port.
+         */
+        public ServerSocket createServerSocket(int p)
+            throws IOException
+        {
+            ServerSocket ss;
+            ss = (new RMIMasterSocketFactory()).createServerSocket(p);
+            if (p == 0) {
+                if (servport != 0) {
+                    System.err.println("TEST FAILED: " +
+                                       "Duplicate createServerSocket(0)");
+                    throw new Error("Test aborted (createServerSocket)");
+                }
+                servport = ss.getLocalPort();
+            }
+            return (ss);
+        }
+
+        /** Return which port was reserved by createServerSocket(0).
+         * If the return value was 0, createServerSocket(0) wasn't called.
+         */
+        public int whichPort() {
+            return (servport);
+        }
+    } // end class HttpOutFactory
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/rmi/transport/tcp/DisableRMIOverHttp/TestIface.java	Thu Feb 15 19:03:51 2018 +0000
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.rmi.*;
+
+public interface TestIface
+    extends Remote
+{
+    public String testCall(String ign)
+        throws RemoteException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/sun/rmi/transport/tcp/DisableRMIOverHttp/TestImpl.java	Thu Feb 15 19:03:51 2018 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.rmi.*;
+import java.rmi.server.*;
+
+public class TestImpl
+    extends Object
+    implements TestIface
+{
+    public TestImpl() {
+    }
+
+    public TestIface export()
+        throws RemoteException
+    {
+        return (TestIface)UnicastRemoteObject.exportObject(this, 0);
+    }
+
+    public void unexport()
+        throws NoSuchObjectException
+    {
+        UnicastRemoteObject.unexportObject(this, true);
+    }
+
+    public String testCall(String ign) {
+        return ("OK");
+    }
+}
--- a/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java	Thu Mar 15 17:03:58 2018 +0300
+++ b/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java	Thu Feb 15 19:03:51 2018 +0000
@@ -32,7 +32,7 @@
  * @build TestImpl
  * @build TestImpl_Stub
  * @build BlockAcceptTest
- * @run main/othervm/policy=security.policy/timeout=60 BlockAcceptTest
+ * @run main/othervm/policy=security.policy/timeout=60 -Djava.rmi.server.disableIncomingHttp=false BlockAcceptTest
  */
 
 /* This test attempts to stymie the RMI accept loop.  The accept loop in