1/* 2 * Copyright (c) 2005, 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 24/* 25 * @test 26 * @bug 6261831 27 * @summary Tests the use of the subject delegation feature on the authenticated 28 * principals within the RMI connector server's creator codebase with 29 * subject delegation. 30 * @author Luis-Miguel Alventosa 31 * @modules java.management.rmi 32 * java.management/com.sun.jmx.remote.security 33 * @run clean SubjectDelegation3Test SimpleStandard SimpleStandardMBean 34 * @run build SubjectDelegation3Test SimpleStandard SimpleStandardMBean 35 * @run main SubjectDelegation3Test policy31 ok 36 * @run main SubjectDelegation3Test policy32 ko 37 * @run main SubjectDelegation3Test policy33 ko 38 * @run main SubjectDelegation3Test policy34 ok 39 * @run main SubjectDelegation3Test policy35 ko 40 */ 41 42import com.sun.jmx.remote.security.JMXPluggableAuthenticator; 43import java.io.File; 44import java.lang.management.ManagementFactory; 45import java.rmi.RemoteException; 46import java.rmi.registry.LocateRegistry; 47import java.rmi.registry.Registry; 48import java.util.Collections; 49import java.util.HashMap; 50import java.util.Properties; 51import javax.management.Attribute; 52import javax.management.MBeanServer; 53import javax.management.MBeanServerConnection; 54import javax.management.Notification; 55import javax.management.NotificationListener; 56import javax.management.ObjectName; 57import javax.management.remote.JMXConnector; 58import javax.management.remote.JMXConnectorFactory; 59import javax.management.remote.JMXConnectorServer; 60import javax.management.remote.JMXConnectorServerFactory; 61import javax.management.remote.JMXPrincipal; 62import javax.management.remote.JMXServiceURL; 63import javax.security.auth.Subject; 64 65public class SubjectDelegation3Test { 66 67 public static void main(String[] args) throws Exception { 68 String policyFile = args[0]; 69 String testResult = args[1]; 70 System.out.println("Policy file = " + policyFile); 71 System.out.println("Expected test result = " + testResult); 72 JMXConnectorServer jmxcs = null; 73 JMXConnector jmxc = null; 74 try { 75 // Create an RMI registry 76 // 77 System.out.println("Start RMI registry..."); 78 Registry reg = null; 79 int port = 5800; 80 while (port++ < 6000) { 81 try { 82 reg = LocateRegistry.createRegistry(port); 83 System.out.println("RMI registry running on port " + port); 84 break; 85 } catch (RemoteException e) { 86 // Failed to create RMI registry... 87 System.out.println("Failed to create RMI registry " + 88 "on port " + port); 89 } 90 } 91 if (reg == null) { 92 System.exit(1); 93 } 94 // Set the default password file 95 // 96 final String passwordFile = System.getProperty("test.src") + 97 File.separator + "jmxremote.password"; 98 System.out.println("Password file = " + passwordFile); 99 // Set policy file 100 // 101 final String policy = System.getProperty("test.src") + 102 File.separator + policyFile; 103 System.out.println("PolicyFile = " + policy); 104 System.setProperty("java.security.policy", policy); 105 // Instantiate the MBean server 106 // 107 System.out.println("Create the MBean server"); 108 MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 109 // Register the SimpleStandardMBean 110 // 111 System.out.println("Create SimpleStandard MBean"); 112 SimpleStandard s = new SimpleStandard("delegate"); 113 mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard")); 114 // Create Properties containing the username/password entries 115 // 116 Properties props = new Properties(); 117 props.setProperty("jmx.remote.x.password.file", passwordFile); 118 // Initialize environment map to be passed to the connector server 119 // 120 System.out.println("Initialize environment map"); 121 HashMap env = new HashMap(); 122 env.put("jmx.remote.authenticator", 123 new JMXPluggableAuthenticator(props)); 124 // Set Security Manager 125 // 126 System.setSecurityManager(new SecurityManager()); 127 // Create an RMI connector server 128 // 129 System.out.println("Create an RMI connector server"); 130 JMXServiceURL url = 131 new JMXServiceURL("rmi", null, 0); 132 jmxcs = 133 JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); 134 jmxcs.start(); 135 // Create an RMI connector client 136 // 137 System.out.println("Create an RMI connector client"); 138 HashMap cli_env = new HashMap(); 139 // These credentials must match those in the default password file 140 // 141 String[] credentials = new String[] { "monitorRole" , "QED" }; 142 cli_env.put("jmx.remote.credentials", credentials); 143 jmxc = JMXConnectorFactory.connect(jmxcs.getAddress(), cli_env); 144 Subject delegationSubject = 145 new Subject(true, 146 Collections.singleton(new JMXPrincipal("delegate")), 147 Collections.EMPTY_SET, 148 Collections.EMPTY_SET); 149 MBeanServerConnection mbsc = 150 jmxc.getMBeanServerConnection(delegationSubject); 151 // Get domains from MBeanServer 152 // 153 System.out.println("Domains:"); 154 String domains[] = mbsc.getDomains(); 155 for (int i = 0; i < domains.length; i++) { 156 System.out.println("\tDomain[" + i + "] = " + domains[i]); 157 } 158 // Get MBean count 159 // 160 System.out.println("MBean count = " + mbsc.getMBeanCount()); 161 // Get State attribute 162 // 163 String oldState = 164 (String) mbsc.getAttribute( 165 new ObjectName("MBeans:type=SimpleStandard"), 166 "State"); 167 System.out.println("Old State = \"" + oldState + "\""); 168 // Set State attribute 169 // 170 System.out.println("Set State to \"changed state\""); 171 mbsc.setAttribute(new ObjectName("MBeans:type=SimpleStandard"), 172 new Attribute("State", "changed state")); 173 // Get State attribute 174 // 175 String newState = 176 (String) mbsc.getAttribute( 177 new ObjectName("MBeans:type=SimpleStandard"), 178 "State"); 179 System.out.println("New State = \"" + newState + "\""); 180 if (!newState.equals("changed state")) { 181 System.out.println("Invalid State = \"" + newState + "\""); 182 System.exit(1); 183 } 184 // Add notification listener on SimpleStandard MBean 185 // 186 System.out.println("Add notification listener..."); 187 mbsc.addNotificationListener( 188 new ObjectName("MBeans:type=SimpleStandard"), 189 new NotificationListener() { 190 public void handleNotification(Notification notification, 191 Object handback) { 192 System.out.println("Received notification: " + 193 notification); 194 } 195 }, 196 null, 197 null); 198 // Unregister SimpleStandard MBean 199 // 200 System.out.println("Unregister SimpleStandard MBean..."); 201 mbsc.unregisterMBean(new ObjectName("MBeans:type=SimpleStandard")); 202 } catch (SecurityException e) { 203 if (testResult.equals("ko")) { 204 System.out.println("Got expected security exception = " + e); 205 } else { 206 System.out.println("Got unexpected security exception = " + e); 207 e.printStackTrace(); 208 throw e; 209 } 210 } catch (Exception e) { 211 System.out.println("Unexpected exception caught = " + e); 212 e.printStackTrace(); 213 throw e; 214 } finally { 215 // Close connector client 216 // 217 if (jmxc != null) 218 jmxc.close(); 219 // Stop connector server 220 // 221 if (jmxcs != null) 222 jmxcs.stop(); 223 // Say goodbye 224 // 225 System.out.println("Bye! Bye!"); 226 } 227 } 228} 229