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