1 /* 2 * Copyright (c) 1999, 2016, 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 /* @test 25 * @bug 4179055 26 * @summary Some java apps need to have access to read "accessClassInPackage.sun.rmi.server" 27 * @author Laird Dornin 28 * 29 * @library ../../../testlibrary 30 * @modules java.base/sun.security.provider 31 * java.rmi/sun.rmi.registry 32 * java.rmi/sun.rmi.server 33 * java.rmi/sun.rmi.transport 34 * java.rmi/sun.rmi.transport.tcp 35 * java.base/sun.nio.ch 36 * @build TestLibrary RMID ActivationLibrary RMIDSelectorProvider 37 * CanCreateStubs StubClassesPermitted_Stub 38 * @run main/othervm/java.security.policy=security.policy/secure=java.lang.SecurityManager/timeout=240 StubClassesPermitted 39 */ 40 41 import java.io.ByteArrayOutputStream; 42 import java.io.PrintStream; 43 import java.rmi.MarshalledObject; 44 import java.rmi.RemoteException; 45 import java.rmi.activation.Activatable; 46 import java.rmi.activation.ActivationDesc; 47 import java.rmi.activation.ActivationGroup; 48 import java.rmi.activation.ActivationGroupDesc; 49 import java.rmi.activation.ActivationGroupDesc.CommandEnvironment; 50 import java.rmi.activation.ActivationGroupID; 51 import java.rmi.activation.ActivationID; 52 import java.rmi.activation.ActivationSystem; 53 import java.rmi.registry.Registry; 54 import java.util.Properties; 55 56 /** 57 * The RMI activation system needs to explicitly allow itself to 58 * create the following sun.* classes on behalf of code that runs with 59 * user privileges and needs to make use of RMI activation: 60 * 61 * sun.rmi.server.Activation$ActivationMonitorImpl_Stub 62 * sun.rmi.server.Activation$ActivationSystemImpl_Stub 63 * sun.rmi.registry.RegistryImpl_Stub 64 * 65 * The test causes the activation system to need to create each of 66 * these classes in turn. The test will fail if the activation system 67 * does not allow these classes to be created. 68 */ 69 public class StubClassesPermitted 70 extends Activatable implements Runnable, CanCreateStubs 71 { 72 public static boolean sameGroup = false; 73 private static int registryPort = -1; 74 private static CanCreateStubs canCreateStubs = null; 75 private static Registry registry = null; 76 77 public static void main(String args[]) { 78 79 sameGroup = true; 80 81 RMID rmid = null; 82 83 System.err.println("\nRegression test for bug/rfe 4179055\n"); 84 85 try { 86 TestLibrary.suggestSecurityManager("java.lang.SecurityManager"); 87 88 registry = TestLibrary.createRegistryOnEphemeralPort(); 89 registryPort = TestLibrary.getRegistryPort(registry); 90 91 // must run with java.lang.SecurityManager or the test 92 // result will be nullified if running with a build where 93 // 4180392 has not been fixed. 94 String smClassName = 95 System.getSecurityManager().getClass().getName(); 96 if (!smClassName.equals("java.lang.SecurityManager")) { 97 TestLibrary.bomb("Test must run with java.lang.SecurityManager"); 98 } 99 100 // start an rmid. 101 RMID.removeLog(); 102 rmid = RMID.createRMIDOnEphemeralPort(); 103 rmid.start(); 104 105 //rmid.addOptions(new String[] {"-C-Djava.rmi.server.logCalls=true"}); 106 107 // Ensure that activation groups run with the correct 108 // security manager. 109 // 110 Properties p = new Properties(); 111 p.put("java.security.policy", 112 TestParams.defaultGroupPolicy); 113 p.put("java.security.manager", 114 "java.lang.SecurityManager"); 115 116 // This action causes the following classes to be created 117 // in this VM (RMI must permit the creation of these classes): 118 // 119 // sun.rmi.server.Activation$ActivationSystemImpl_Stub 120 // sun.rmi.server.Activation$ActivationMonitorImpl_Stub 121 // 122 System.err.println("Create activation group, in a new VM"); 123 CommandEnvironment cmd = new ActivationGroupDesc.CommandEnvironment(null, 124 new String[] { 125 "--add-exports=java.base/sun.security.provider=ALL-UNNAMED", 126 "--add-exports=java.rmi/sun.rmi.registry=ALL-UNNAMED", 127 "--add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED", 128 "--add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED", 129 "--add-exports=java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED" }); 130 131 ActivationGroupDesc groupDesc = 132 new ActivationGroupDesc(p, cmd); 133 ActivationSystem system = ActivationGroup.getSystem(); 134 ActivationGroupID groupID = system.registerGroup(groupDesc); 135 136 System.err.println("register activatable"); 137 // Fix for: 4271615: make sure activation group runs in a new VM 138 ActivationDesc desc = new ActivationDesc 139 (groupID, "StubClassesPermitted", null, null); 140 canCreateStubs = (CanCreateStubs) Activatable.register(desc); 141 142 // ensure registry stub can be passed in a remote call 143 System.err.println("getting the registry"); 144 registry = canCreateStubs.getRegistry(); 145 146 // make sure a client cant load just any sun.* class, just 147 // as a sanity check, try to create a class we are not 148 // allowed to access but which was passed in a remote call 149 try { 150 System.err.println("accessing forbidden class"); 151 Object secureRandom = canCreateStubs.getForbiddenClass(); 152 153 TestLibrary.bomb("test allowed to access forbidden class," + 154 " sun.security.provider.SecureRandom"); 155 } catch (java.security.AccessControlException e) { 156 157 // Make sure we received a *local* AccessControlException 158 ByteArrayOutputStream bout = new ByteArrayOutputStream(); 159 PrintStream ps = new PrintStream(bout); 160 e.printStackTrace(ps); 161 ps.flush(); 162 String trace = new String(bout.toByteArray()); 163 if ((trace.indexOf("exceptionReceivedFromServer") >= 0) || 164 trace.equals("")) 165 { 166 throw e; 167 } 168 System.err.println("received expected local access control exception"); 169 } 170 171 // make sure that an ActivationGroupID can be passed in a 172 // remote call; this is slightly more inclusive than 173 // just passing a reference to the activation system 174 System.err.println("returning group desc"); 175 canCreateStubs.returnGroupID(); 176 177 // Clean up object 178 System.err.println 179 ("Deactivate object via method call"); 180 canCreateStubs.shutdown(); 181 182 System.err.println 183 ("\nsuccess: StubClassesPermitted test passed "); 184 185 } catch (Exception e) { 186 TestLibrary.bomb("\nfailure: unexpected exception ", e); 187 } finally { 188 try { 189 Thread.sleep(4000); 190 } catch (InterruptedException e) { 191 } 192 193 canCreateStubs = null; 194 rmid.cleanup(); 195 System.err.println("rmid shut down"); 196 } 197 } 198 199 static ActivationGroupID GroupID = null; 200 201 /** 202 * implementation of CanCreateStubs 203 */ 204 public StubClassesPermitted 205 (ActivationID id, MarshalledObject mo) throws RemoteException 206 { 207 // register/export anonymously 208 super(id, 0); 209 210 // obtain reference to the test registry 211 registry = java.rmi.registry.LocateRegistry. 212 getRegistry(registryPort); 213 } 214 215 /** 216 * Spawns a thread to deactivate the object. 217 */ 218 public void shutdown() throws Exception { 219 (new Thread(this,"StubClassesPermitted")).start(); 220 } 221 222 /** 223 * Thread to deactivate object. First attempts to make object 224 * inactive (via the inactive method). If that fails (the 225 * object may still have pending/executing calls), then 226 * unexport the object forcibly. 227 */ 228 public void run() { 229 ActivationLibrary.deactivate(this, getID()); 230 } 231 232 /** 233 * Return a reference to the RMI registry, to make sure that 234 * the stub for it can be deserialized in the test client VM. 235 */ 236 public Registry getRegistry() throws RemoteException { 237 if (sameGroup) { 238 System.out.println("in same group"); 239 } else { 240 System.out.println("not in same group"); 241 } 242 return registry; 243 } 244 245 /** 246 * Remote call to create and return a random serializable sun.* 247 * class, the test should get a local security exception when 248 * trying to create the class. Ensure that not all sun.* classes 249 * can be resolved in a remote call. 250 */ 251 public Object getForbiddenClass() throws RemoteException { 252 System.err.println("creating sun class"); 253 return new sun.security.provider.SecureRandom(); 254 } 255 256 /** 257 * Ensures that an activation group id can be passed in a remote 258 * call (class may contain a remote reference to the activation 259 * system implementation). 260 */ 261 public ActivationGroupID returnGroupID() throws RemoteException { 262 return ActivationGroup.currentGroupID(); 263 } 264 }