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