/[classpath]/classpath/vm/reference/java/security/VMAccessController.java
ViewVC logotype

Diff of /classpath/vm/reference/java/security/VMAccessController.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by mark, Sun Jul 4 18:32:32 2004 UTC revision 1.3 by rsdio, Sat Aug 21 22:51:19 2004 UTC
# Line 52  final class VMAccessController Line 52  final class VMAccessController
52    // -------------------------------------------------------------------------    // -------------------------------------------------------------------------
53    
54    /**    /**
55     * A mapping between pairs (<i>thread</i>, <i>classname</i>) to access     * This is a per-thread stack of AccessControlContext objects (which can
56     * control contexts. The <i>thread</i> and <i>classname</i> are the thread     * be null) for each call to AccessController.doPrivileged in each thread's
57     * and <i>classname</i> current as of the last call to doPrivileged with     * call stack. We use this to remember which context object corresponds to
58     * an AccessControlContext argument.     * which call.
59     */     */
60    private static final Map contexts = Collections.synchronizedMap(new HashMap());    private static final ThreadLocal contexts = new ThreadLocal();
61    
62      /**
63       * This is a Boolean that, if set, tells getContext that it has already
64       * been called once, allowing us to handle recursive permission checks
65       * caused by methods getContext calls.
66       */
67    private static final ThreadLocal inGetContext = new ThreadLocal();    private static final ThreadLocal inGetContext = new ThreadLocal();
68    
69      /**
70       * And we return this all-permissive context to ensure that privileged
71       * methods called from getContext succeed.
72       */
73    private final static AccessControlContext DEFAULT_CONTEXT;    private final static AccessControlContext DEFAULT_CONTEXT;
74    static    static
75    {    {
# Line 74  final class VMAccessController Line 83  final class VMAccessController
83    }    }
84    
85    private static final boolean DEBUG = false;    private static final boolean DEBUG = false;
86    private static void debug (String msg)    private static void debug(String msg)
87    {    {
88      System.err.print (">>> VMAccessController: ");      System.err.print(">>> VMAccessController: ");
89      System.err.println (msg);      System.err.println(msg);
90    }    }
91    
92    // Constructors.    // Constructors.
# Line 97  final class VMAccessController Line 106  final class VMAccessController
106     * pushed from one thread will not be available to another.     * pushed from one thread will not be available to another.
107     *     *
108     * @param acc The access control context.     * @param acc The access control context.
    * @param clazz The class that implements {@link PrivilegedAction}.  
109     */     */
110    static void pushContext (AccessControlContext acc, Class clazz)    static void pushContext (AccessControlContext acc)
111    {    {
112      ArrayList pair = new ArrayList (2);      if (DEBUG)
113      pair.add (Thread.currentThread());        debug("pushing " + acc);
114      pair.add (clazz);      LinkedList stack = (LinkedList) contexts.get();
115      if (DEBUG) debug ("pushing " + pair);      if (stack == null)
116      contexts.put (pair, acc);        {
117            stack = new LinkedList();
118            contexts.set(stack);
119          }
120        stack.addFirst(acc);
121    }    }
122    
123    /**    /**
# Line 113  final class VMAccessController Line 125  final class VMAccessController
125     * This method is used by {@link AccessController} when exiting from a     * This method is used by {@link AccessController} when exiting from a
126     * call to {@link     * call to {@link
127     * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.     * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
    *  
    * @param clazz The class that implements {@link PrivilegedAction}.  
128     */     */
129    static void popContext (Class clazz)    static void popContext()
130    {    {
131      ArrayList pair = new ArrayList (2);      if (DEBUG)
132      pair.add (Thread.currentThread());        debug("popping context");
133      pair.add (clazz);  
134      if (DEBUG) debug ("popping " + pair);      // Stack should never be null, nor should it be empty, if this method
135      contexts.remove (pair);      // and its counterpart has been called properly.
136        LinkedList stack = (LinkedList) contexts.get();
137        if (stack != null)
138          {
139            stack.removeFirst();
140            if (stack.isEmpty())
141              contexts.set(null);
142          }
143    }    }
144    
145    /**    /**
# Line 143  final class VMAccessController Line 160  final class VMAccessController
160      Boolean inCall = (Boolean) inGetContext.get();      Boolean inCall = (Boolean) inGetContext.get();
161      if (inCall != null && inCall.booleanValue())      if (inCall != null && inCall.booleanValue())
162        {        {
163          if (DEBUG) debug ("already in getContext");          if (DEBUG)
164              debug("already in getContext");
165          return DEFAULT_CONTEXT;          return DEFAULT_CONTEXT;
166        }        }
167    
168        inGetContext.set(Boolean.TRUE);
169    
170      Object[][] stack = getStack();      Object[][] stack = getStack();
171      Class[] classes = (Class[]) stack[0];      Class[] classes = (Class[]) stack[0];
172      String[] methods = (String[]) stack[1];      String[] methods = (String[]) stack[1];
173    
174      inGetContext.set (Boolean.TRUE);      if (DEBUG)
175          debug(">>> got trace of length " + classes.length);
     if (DEBUG) debug (">>> got trace of length " + classes.length);  
176    
177      HashSet domains = new HashSet();      HashSet domains = new HashSet();
178      HashSet seenDomains = new HashSet();      HashSet seenDomains = new HashSet();
179      AccessControlContext context = null;      AccessControlContext context = null;
180        int privileged = 0;
181    
182      // We walk down the stack, adding each ProtectionDomain for each      // We walk down the stack, adding each ProtectionDomain for each
183      // class in the call stack. If we reach a call to doPrivileged,      // class in the call stack. If we reach a call to doPrivileged,
184      // we don't add any more stack frames. We skip the first three stack      // we don't add any more stack frames. We skip the first three stack
185      // frames, since they comprise the calls to getStack, getContext,      // frames, since they comprise the calls to getStack, getContext,
186      // and AccessController.getContext.      // and AccessController.getContext.
187      for (int i = 3; i < classes.length; i++)      for (int i = 3; i < classes.length && privileged < 2; i++)
188        {        {
189          Class clazz = classes[i];          Class clazz = classes[i];
190          String method = methods[i];          String method = methods[i];
191    
192          if (DEBUG)          if (DEBUG)
193            {            {
194              debug (">>> checking " + clazz + "." + method);              debug(">>> checking " + clazz + "." + method);
195              debug (">>> loader = " + clazz.getClassLoader());              debug(">>> loader = " + clazz.getClassLoader());
196            }            }
197    
198            // If the previous frame was a call to doPrivileged, then this is
199            // the last frame we look at.
200            if (privileged == 1)
201              privileged = 2;
202    
203          if (clazz.equals (AccessController.class)          if (clazz.equals (AccessController.class)
204              && method.equals ("doPrivileged"))              && method.equals ("doPrivileged"))
205            {            {
206              // If there was a call to doPrivileged with a supplied context,              // If there was a call to doPrivileged with a supplied context,
207              // return that context.              // return that context.
208              List pair = new ArrayList(2);              LinkedList l = (LinkedList) contexts.get();
209              pair.add (Thread.currentThread());              if (l != null)
210              pair.add (classes[i-1]);                context = (AccessControlContext) l.getFirst();
211              if (contexts.containsKey (pair))              privileged = 1;
               context = (AccessControlContext) contexts.get (pair);  
             break;  
212            }            }
213    
214          ProtectionDomain domain = clazz.getProtectionDomain();          ProtectionDomain domain = clazz.getProtectionDomain();
215    
216          if (domain == null)          if (domain == null)
217            continue;            continue;
218          if (seenDomains.contains (domain))          if (seenDomains.contains(domain))
219            continue;            continue;
220          seenDomains.add (domain);          seenDomains.add(domain);
221    
222          // Create a static snapshot of this domain, which may change over time          // Create a static snapshot of this domain, which may change over time
223          // if the current policy changes.          // if the current policy changes.
224          domains.add (new ProtectionDomain (domain.getCodeSource(),          domains.add(new ProtectionDomain(domain.getCodeSource(),
225                                             domain.getPermissions()));                                           domain.getPermissions()));
226        }        }
227    
228      if (DEBUG) debug ("created domains: " + domains);      if (DEBUG)
229          debug("created domains: " + domains);
230    
231      ProtectionDomain[] result = (ProtectionDomain[])      ProtectionDomain[] result = (ProtectionDomain[])
232        domains.toArray (new ProtectionDomain[domains.size()]);        domains.toArray(new ProtectionDomain[domains.size()]);
233    
234      // Intersect the derived protection domain with the context supplied      // Intersect the derived protection domain with the context supplied
235      // to doPrivileged.      // to doPrivileged.
236      if (context != null)      if (context != null)
237        context = new AccessControlContext (result, context,        context = new AccessControlContext(result, context,
238                                            IntersectingDomainCombiner.SINGLETON);                                           IntersectingDomainCombiner.SINGLETON);
239      // No context was supplied. Return the derived one.      // No context was supplied. Return the derived one.
240      else      else
241        context = new AccessControlContext (result);        context = new AccessControlContext(result);
242    
243      inGetContext.set (Boolean.FALSE);      inGetContext.set(Boolean.FALSE);
244      return context;      return context;
245    }    }
246    

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26