jamvm
view lib/java/security/VMAccessController.java @ 398:6476eceedae8
Comment out Java code that won't compile with OpenJDK's class library.
2008-08-04 Andrew John Hughes <gnu_andrew@member.fsf.org>
* lib/java/lang/VMClassLoader.java,
* lib/java/lang/VMRuntime.java,
* lib/java/lang/VMThread.java,
* lib/java/security/VMAccessController.java:
Remove GNU Classpath specific code through commenting.
2008-08-04 Andrew John Hughes <gnu_andrew@member.fsf.org>
* lib/java/lang/VMClassLoader.java,
* lib/java/lang/VMRuntime.java,
* lib/java/lang/VMThread.java,
* lib/java/security/VMAccessController.java:
Remove GNU Classpath specific code through commenting.
| author | andrew |
|---|---|
| date | Tue Aug 05 04:04:18 2008 +0100 (2008-08-05) |
| parents | 71bcb27dba05 |
| children | 2b94bfbe7ec6 |
line source
1 /* VMAccessController.java -- VM-specific access controller methods.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; see the file COPYING. If not, write to the
16 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17 02111-1307 USA.
19 Linking this library statically or dynamically with other modules is
20 making a combined work based on this library. Thus, the terms and
21 conditions of the GNU General Public License cover the whole
22 combination.
24 As a special exception, the copyright holders of this library give you
25 permission to link this library with independent modules to produce an
26 executable, regardless of the license terms of these independent
27 modules, and to copy and distribute the resulting executable under
28 terms of your choice, provided that you also meet, for each linked
29 independent module, the terms and conditions of the license of that
30 module. An independent module is a module which is not derived from
31 or based on this library. If you modify this library, you may extend
32 this exception to your version of the library, but you are not
33 obligated to do so. If you do not wish to do so, delete this
34 exception statement from your version. */
37 package java.security;
39 import java.util.HashSet;
40 import java.util.LinkedList;
42 /**
43 * This version is for JamVM.
44 */
45 final class VMAccessController
46 {
48 // Fields.
49 // -------------------------------------------------------------------------
51 /**
52 * This is a per-thread stack of AccessControlContext objects (which can
53 * be null) for each call to AccessController.doPrivileged in each thread's
54 * call stack. We use this to remember which context object corresponds to
55 * which call.
56 */
57 private static final ThreadLocal contexts = new ThreadLocal();
59 /**
60 * This is a Boolean that, if set, tells getContext that it has already
61 * been called once, allowing us to handle recursive permission checks
62 * caused by methods getContext calls.
63 */
64 private static final ThreadLocal inGetContext = new ThreadLocal();
66 /**
67 * And we return this all-permissive context to ensure that privileged
68 * methods called from getContext succeed.
69 */
70 private final static AccessControlContext DEFAULT_CONTEXT;
71 static
72 {
73 CodeSource source = new CodeSource(null, null);
74 Permissions permissions = new Permissions();
75 permissions.add(new AllPermission());
76 ProtectionDomain[] domain = new ProtectionDomain[] {
77 new ProtectionDomain(source, permissions)
78 };
79 DEFAULT_CONTEXT = new AccessControlContext(domain);
80 }
82 private static final boolean DEBUG = false;
83 private static void debug(String msg)
84 {
85 System.err.print(">>> VMAccessController: ");
86 System.err.println(msg);
87 }
89 // Constructors.
90 // -------------------------------------------------------------------------
92 private VMAccessController() { }
94 // Class methods.
95 // -------------------------------------------------------------------------
97 /**
98 * Relate a class (which should be an instance of {@link PrivilegedAction}
99 * with an access control context. This method is used by {@link
100 * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
101 * to set up the context that will be returned by {@link #getContext()}.
102 * This method relates the class to the current thread, so contexts
103 * pushed from one thread will not be available to another.
104 *
105 * @param acc The access control context.
106 */
107 static void pushContext (AccessControlContext acc)
108 {
109 if (DEBUG)
110 debug("pushing " + acc);
111 LinkedList stack = (LinkedList) contexts.get();
112 if (stack == null)
113 {
114 stack = new LinkedList();
115 contexts.set(stack);
116 }
117 stack.addFirst(acc);
118 }
120 /**
121 * Removes the relation of a class to an {@link AccessControlContext}.
122 * This method is used by {@link AccessController} when exiting from a
123 * call to {@link
124 * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
125 */
126 static void popContext()
127 {
128 if (DEBUG)
129 debug("popping context");
131 // Stack should never be null, nor should it be empty, if this method
132 // and its counterpart has been called properly.
133 LinkedList stack = (LinkedList) contexts.get();
134 if (stack != null)
135 {
136 stack.removeFirst();
137 if (stack.isEmpty())
138 contexts.set(null);
139 }
140 }
142 /**
143 * Examine the method stack of the currently running thread, and create
144 * an {@link AccessControlContext} filled in with the appropriate {@link
145 * ProtectionDomain} objects given this stack.
146 *
147 * @return The context.
148 */
149 static AccessControlContext getContext()
150 {
151 // If we are already in getContext, but called a method that needs
152 // a permission check, return the all-permissive context so methods
153 // called from here succeed.
154 //
155 // XXX is this necessary? We should verify if there are any calls in
156 // the stack below this method that require permission checks.
157 Boolean inCall = (Boolean) inGetContext.get();
158 if (inCall != null && inCall.booleanValue())
159 {
160 if (DEBUG)
161 debug("already in getContext");
162 return DEFAULT_CONTEXT;
163 }
165 inGetContext.set(Boolean.TRUE);
167 Object[][] stack = getStack();
168 Class[] classes = (Class[]) stack[0];
169 String[] methods = (String[]) stack[1];
171 if (DEBUG)
172 debug(">>> got trace of length " + classes.length);
174 HashSet domains = new HashSet();
175 HashSet seenDomains = new HashSet();
176 AccessControlContext context = null;
177 int privileged = 0;
179 // We walk down the stack, adding each ProtectionDomain for each
180 // class in the call stack. If we reach a call to doPrivileged,
181 // we don't add any more stack frames. We skip the first three stack
182 // frames, since they comprise the calls to getStack, getContext,
183 // and AccessController.getContext.
184 for (int i = 3; i < classes.length && privileged < 2; i++)
185 {
186 Class clazz = classes[i];
187 String method = methods[i];
189 if (DEBUG)
190 {
191 debug(">>> checking " + clazz + "." + method);
192 debug(">>> loader = " + clazz.getClassLoader());
193 }
195 // If the previous frame was a call to doPrivileged, then this is
196 // the last frame we look at.
197 if (privileged == 1)
198 privileged = 2;
200 if (clazz.equals (AccessController.class)
201 && method.equals ("doPrivileged"))
202 {
203 // If there was a call to doPrivileged with a supplied context,
204 // return that context.
205 LinkedList l = (LinkedList) contexts.get();
206 if (l != null)
207 context = (AccessControlContext) l.getFirst();
208 privileged = 1;
209 }
211 ProtectionDomain domain = clazz.getProtectionDomain();
213 if (domain == null)
214 continue;
215 if (seenDomains.contains(domain))
216 continue;
217 seenDomains.add(domain);
219 // Create a static snapshot of this domain, which may change over time
220 // if the current policy changes.
221 domains.add(new ProtectionDomain(domain.getCodeSource(),
222 domain.getPermissions()));
223 }
225 if (DEBUG)
226 debug("created domains: " + domains);
228 ProtectionDomain[] result = (ProtectionDomain[])
229 domains.toArray(new ProtectionDomain[domains.size()]);
231 // Intersect the derived protection domain with the context supplied
232 // to doPrivileged.
233 if (context != null)
234 /*
235 Removed to allow building against OpenJDK
236 Andrew John Hughes - July 2008
237 context = new AccessControlContext(result, context,
238 IntersectingDomainCombiner.SINGLETON);
239 */
240 throw new InternalError("Can't intersect context with derived protection domain");
241 // No context was supplied. Return the derived one.
242 else
243 context = new AccessControlContext(result);
245 inGetContext.set(Boolean.FALSE);
246 return context;
247 }
249 /**
250 * Returns a snapshot of the current call stack as a pair of arrays:
251 * the first an array of classes in the call stack, the second an array
252 * of strings containing the method names in the call stack. The two
253 * arrays match up, meaning that method <i>i</i> is declared in class
254 * <i>i</i>. The arrays are clean; it will only contain Java methods,
255 * and no element of the list should be null.
256 *
257 * @return A pair of arrays describing the current call stack. The first
258 * element is an array of Class objects, and the second is an array
259 * of Strings comprising the method names.
260 */
261 private static native Object[][] getStack();
262 }
