1/* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import java.net.InetAddress; 25import java.rmi.AccessException; 26import java.rmi.registry.LocateRegistry; 27import java.rmi.registry.Registry; 28import java.util.Set; 29 30/* @test 31 * @bug 8174770 32 * @summary Verify that Registry rejects non-local access for bind, unbind, rebind. 33 * The test is manual because the (non-local) host running rmiregistry must be supplied as a property. 34 * @run main/othervm/manual -Dregistry.host=rmi-registry-host NonLocalRegistryTest 35 */ 36 37/** 38 * Verify that access checks for Registry.bind(), .rebind(), and .unbind() 39 * are prevented on remote access to the registry. 40 * 41 * This test is a manual test and uses a standard rmiregistry running 42 * on a *different* host. 43 * The test verifies that the access check is performed *before* the object to be 44 * bound or rebound is deserialized. 45 * 46 * Login or ssh to the different host and invoke {@code $JDK_HOME/bin/rmiregistry}. 47 * It will not show any output. 48 * 49 * On the first host modify the @run command above to replace "rmi-registry-host" 50 * with the hostname or IP address of the different host and run the test with jtreg. 51 */ 52public class NonLocalRegistryTest { 53 54 public static void main(String[] args) throws Exception { 55 56 String host = System.getProperty("registry.host"); 57 if (host == null || host.isEmpty()) { 58 throw new RuntimeException("Specify host with system property: -Dregistry.host=<host>"); 59 } 60 61 // Check if running the test on a local system; it only applies to remote 62 String myHostName = InetAddress.getLocalHost().getHostName(); 63 Set<InetAddress> myAddrs = Set.of(InetAddress.getAllByName(myHostName)); 64 Set<InetAddress> hostAddrs = Set.of(InetAddress.getAllByName(host)); 65 if (hostAddrs.stream().anyMatch(i -> myAddrs.contains(i)) 66 || hostAddrs.stream().anyMatch(h -> h.isLoopbackAddress())) { 67 throw new RuntimeException("Error: property 'registry.host' must not be the local host%n"); 68 } 69 70 Registry registry = LocateRegistry.getRegistry(host, Registry.REGISTRY_PORT); 71 72 try { 73 registry.bind("foo", null); 74 throw new RuntimeException("Remote access should not succeed for method: bind"); 75 } catch (Exception e) { 76 assertIsAccessException(e); 77 } 78 79 try { 80 registry.rebind("foo", null); 81 throw new RuntimeException("Remote access should not succeed for method: rebind"); 82 } catch (Exception e) { 83 assertIsAccessException(e); 84 } 85 86 try { 87 registry.unbind("foo"); 88 throw new RuntimeException("Remote access should not succeed for method: unbind"); 89 } catch (Exception e) { 90 assertIsAccessException(e); 91 } 92 } 93 94 /** 95 * Check the exception chain for the expected AccessException and message. 96 * @param ex the exception from the remote invocation. 97 */ 98 private static void assertIsAccessException(Throwable ex) { 99 Throwable t = ex; 100 while (!(t instanceof AccessException) && t.getCause() != null) { 101 t = t.getCause(); 102 } 103 if (t instanceof AccessException) { 104 String msg = t.getMessage(); 105 int asIndex = msg.indexOf("Registry"); 106 int rrIndex = msg.indexOf("Registry.Registry"); // Obsolete error text 107 int disallowIndex = msg.indexOf("disallowed"); 108 int nonLocalHostIndex = msg.indexOf("non-local host"); 109 if (asIndex < 0 || 110 rrIndex != -1 || 111 disallowIndex < 0 || 112 nonLocalHostIndex < 0 ) { 113 throw new RuntimeException("exception message is malformed", t); 114 } 115 System.out.printf("Found expected AccessException: %s%n%n", t); 116 } else { 117 throw new RuntimeException("AccessException did not occur when expected", ex); 118 } 119 } 120} 121