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