Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/management/remote/nonLocalAccess/NonLocalJMXRemoteTest.java
38855 views
/*1* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.net.InetAddress;24import java.rmi.AccessException;25import java.rmi.NotBoundException;26import java.rmi.registry.LocateRegistry;27import java.rmi.registry.Registry;28import java.util.Set;29import java.util.HashSet;3031/* @test32* @bug 817477033* @summary Verify that JMX Registry rejects non-local access for bind, unbind, rebind.34* The test is manual because the (non-local) host and port running JMX must be supplied as properties.35* @run main/othervm/manual -Djmx-registry.host=jmx-registry-host -Djmx-registry.port=jmx-registry-port NonLocalJMXRemoteTest36*/3738/**39* Verify that access checks for the Registry exported by JMX Registry.bind(),40* .rebind(), and .unbind() are prevented on remote access to the registry.41* The test verifies that the access check is performed *before* the object to be42* bound or rebound is deserialized.43* This tests the SingleEntryRegistry implemented by JMX.44* This test is a manual test and uses JMX running on a *different* host.45* JMX can be enabled in any Java runtime; for example:46*47* Note: Use remote host with latest JDK update release for invoking rmiregistry.48*49* Note: Test should be ran twice once using arg1 and once using arg2.50*51* login or ssh to the remote host and invoke rmiregistry with arg1.52* It will not show any output.53* Execute the test, after test completes execution, stop the server.54*55* repeat above step using arg2 and execute the test.56*57*58* arg1: {@code $JDK_HOME/bin/rmiregistry \59* -J-Dcom.sun.management.jmxremote.port=8888 \60* -J-Dcom.sun.management.jmxremote.local.only=false \61* -J-Dcom.sun.management.jmxremote.ssl=false \62* -J-Dcom.sun.management.jmxremote.authenticate=false63* }64*65*66* replace "jmx-registry-host" with the hostname or IP address of the remote host67* for property "-J-Dcom.sun.management.jmxremote.host" below.68*69* arg2: {@code $JDK_HOME/bin/rmiregistry \70* -J-Dcom.sun.management.jmxremote.port=8888 \71* -J-Dcom.sun.management.jmxremote.local.only=false \72* -J-Dcom.sun.management.jmxremote.ssl=false \73* -J-Dcom.sun.management.jmxremote.authenticate=false \74* -J-Dcom.sun.management.jmxremote.host="jmx-registry-host"75* }76*77* On the first host modify the @run command above to replace "jmx-registry-host"78* with the hostname or IP address of the different host and run the test with jtreg.79*/80public class NonLocalJMXRemoteTest {8182public static void main(String[] args) throws Exception {8384String host = System.getProperty("jmx-registry.host");85if (host == null || host.isEmpty()) {86throw new RuntimeException("Specify host with system property: -Djmx-registry.host=<host>");87}88int port = Integer.getInteger("jmx-registry.port", -1);89if (port <= 0) {90throw new RuntimeException("Specify port with system property: -Djmx-registry.port=<port>");91}9293// Check if running the test on a local system; it only applies to remote94String myHostName = InetAddress.getLocalHost().getHostName();95Set<InetAddress> myAddrs = new HashSet<>();96InetAddress[] myAddrsArr = InetAddress.getAllByName(myHostName);97for (InetAddress a : myAddrsArr) {98myAddrs.add(a);99}100Set<InetAddress> hostAddrs = new HashSet<>();101InetAddress[] hostAddrsArr = InetAddress.getAllByName(host);102for (InetAddress a : hostAddrsArr) {103hostAddrs.add(a);104}105if (hostAddrs.stream().anyMatch(i -> myAddrs.contains(i))106|| hostAddrs.stream().anyMatch(h -> h.isLoopbackAddress())) {107throw new RuntimeException("Error: property 'jmx-registry.host' must not be the local host%n");108}109110Registry registry = LocateRegistry.getRegistry(host, port);111try {112// Verify it is a JMX Registry113registry.lookup("jmxrmi");114} catch (NotBoundException nf) {115throw new RuntimeException("Not a JMX registry, jmxrmi is not bound", nf);116}117118try {119registry.bind("foo", null);120throw new RuntimeException("Remote access should not succeed for method: bind");121} catch (Exception e) {122assertIsAccessException(e);123}124125try {126registry.rebind("foo", null);127throw new RuntimeException("Remote access should not succeed for method: rebind");128} catch (Exception e) {129assertIsAccessException(e);130}131132try {133registry.unbind("foo");134throw new RuntimeException("Remote access should not succeed for method: unbind");135} catch (Exception e) {136assertIsAccessException(e);137}138}139140/**141* Check the exception chain for the expected AccessException and message.142* @param ex the exception from the remote invocation.143*/144private static void assertIsAccessException(Throwable ex) {145Throwable t = ex;146while (!(t instanceof AccessException) && t.getCause() != null) {147t = t.getCause();148}149if (t instanceof AccessException) {150String msg = t.getMessage();151int asIndex = msg.indexOf("Registry");152int disallowIndex = msg.indexOf("disallowed");153int nonLocalHostIndex = msg.indexOf("non-local host");154if (asIndex < 0 ||155disallowIndex < 0 ||156nonLocalHostIndex < 0 ) {157System.out.println("Exception message is " + msg);158throw new RuntimeException("exception message is malformed", t);159}160System.out.printf("Found expected AccessException: %s%n%n", t);161} else {162throw new RuntimeException("AccessException did not occur when expected", ex);163}164}165}166167168