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