/* VMAccessController.java -- VM-specific access controller methods.
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.security;

import java.util.HashSet;
import java.util.LinkedList;

final class VMAccessController
{

  // Fields.
  // -------------------------------------------------------------------------

  /**
   * This is a per-thread stack of AccessControlContext objects (which can
   * be null) for each call to AccessController.doPrivileged in each thread's
   * call stack. We use this to remember which context object corresponds to
   * which call.
   */
  private static final ThreadLocal contexts = new ThreadLocal();

  /**
   * This is a Boolean that, if set, tells getContext that it has already
   * been called once, allowing us to handle recursive permission checks
   * caused by methods getContext calls.
   */
  private static final ThreadLocal inGetContext = new ThreadLocal();

  /**
   * And we return this all-permissive context to ensure that privileged
   * methods called from getContext succeed.
   */
  private static final AccessControlContext DEFAULT_CONTEXT;
  static
  {
    CodeSource source = new CodeSource(null, null);
    Permissions permissions = new Permissions();
    permissions.add(new AllPermission());
    ProtectionDomain[] domain = new ProtectionDomain[] {
      new ProtectionDomain(source, permissions)
    };
    DEFAULT_CONTEXT = new AccessControlContext(domain);
  }

  private static final boolean DEBUG = gnu.classpath.Configuration.DEBUG;
  private static void debug(String msg)
  {
    System.err.print(">>> VMAccessController: ");
    System.err.println(msg);
  }

  // Constructors.
  // -------------------------------------------------------------------------

  private VMAccessController() { }

  // Class methods.
  // -------------------------------------------------------------------------

  /**
   * Relate a class (which should be an instance of {@link PrivilegedAction}
   * with an access control context. This method is used by {@link
   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}
   * to set up the context that will be returned by {@link #getContext()}.
   * This method relates the class to the current thread, so contexts
   * pushed from one thread will not be available to another.
   *
   * @param acc The access control context.
   */
  static void pushContext (AccessControlContext acc)
  {
    if (DEBUG)
      debug("pushing " + acc);
    LinkedList stack = (LinkedList) contexts.get();
    if (stack == null)
      {
         if (DEBUG)
           debug("no stack... creating ");
        stack = new LinkedList();
        contexts.set(stack);
      }
    stack.addFirst(acc);
  }

  /**
   * Removes the relation of a class to an {@link AccessControlContext}.
   * This method is used by {@link AccessController} when exiting from a
   * call to {@link
   * AccessController#doPrivileged(java.security.PrivilegedAction,java.security.AccessControlContext)}.
   */
  static void popContext()
  {
    if (DEBUG)
      debug("popping context");

    // Stack should never be null, nor should it be empty, if this method
    // and its counterpart has been called properly.
    LinkedList stack = (LinkedList) contexts.get();
    if (stack != null)
      {
        stack.removeFirst();
        if (stack.isEmpty())
          contexts.set(null);
      }
    else if (DEBUG)
      {
        debug("no stack during pop?????");
      }
  }

  /**
   * Examine the method stack of the currently running thread, and create
   * an {@link AccessControlContext} filled in with the appropriate {@link
   * ProtectionDomain} objects given this stack.
   *
   * @return The context.
   */
  static AccessControlContext getContext()
  {
    // If we are already in getContext, but called a method that needs
    // a permission check, return the all-permissive context so methods
    // called from here succeed.
    //
    // XXX is this necessary? We should verify if there are any calls in
    // the stack below this method that require permission checks.
    Boolean inCall = (Boolean) inGetContext.get();
    if (inCall != null && inCall.booleanValue())
      {
        if (DEBUG)
          debug("already in getContext");
        return DEFAULT_CONTEXT;
      }

    inGetContext.set(Boolean.TRUE);

    Object[][] stack = getStack();
    Class[] classes = (Class[]) stack[0];
    String[] methods = (String[]) stack[1];

    if (DEBUG)
      debug("got trace of length " + classes.length);

    HashSet domains = new HashSet();
    HashSet seenDomains = new HashSet();
    AccessControlContext context = null;
    int privileged = 0;

    // We walk down the stack, adding each ProtectionDomain for each
    // class in the call stack. If we reach a call to doPrivileged,
    // we don't add any more stack frames. We skip the first three stack
    // frames, since they comprise the calls to getStack, getContext,
    // and AccessController.getContext.
    for (int i = 3; i < classes.length && privileged < 2; i++)
      {
        Class clazz = classes[i];
        String method = methods[i];

        if (DEBUG)
          {
            debug("checking " + clazz + "." + method);
            // subject to getClassLoader RuntimePermission
            debug("loader = " + clazz.getClassLoader());
          }

        // If the previous frame was a call to doPrivileged, then this is
        // the last frame we look at.
        if (privileged == 1)
          privileged = 2;

        if (clazz.equals (AccessController.class)
            && method.equals ("doPrivileged"))
          {
            // If there was a call to doPrivileged with a supplied context,
            // return that context. If using JAAS doAs*, it should be 
	    // a context with a SubjectDomainCombiner
            LinkedList l = (LinkedList) contexts.get();
            if (l != null)
              context = (AccessControlContext) l.getFirst();
            privileged = 1;
          }

        // subject to getProtectionDomain RuntimePermission
	ProtectionDomain domain = clazz.getProtectionDomain();

        if (domain == null)
          continue;
        if (seenDomains.contains(domain))
          continue;
        seenDomains.add(domain);

        // Create a static snapshot of this domain, which may change over time
        // if the current policy changes.
        domains.add(new ProtectionDomain(domain.getCodeSource(),
                                         domain.getPermissions()));
      }

    if (DEBUG)
      debug("created domains: " + domains);

    ProtectionDomain[] result = (ProtectionDomain[])
      domains.toArray(new ProtectionDomain[domains.size()]);

    if (context != null)
      {
        DomainCombiner dc = context.getDomainCombiner ();
        // If the supplied context had no explicit DomainCombiner, use
        // our private version, which computes the intersection of the
        // context's domains with the derived set.
        if (dc == null)
          context = new AccessControlContext
            (IntersectingDomainCombiner.SINGLETON.combine
             (result, context.getProtectionDomains ()));
        // Use the supplied DomainCombiner. This should be secure,
        // because only trusted code may create an
        // AccessControlContext with a custom DomainCombiner.
        else
          context = new AccessControlContext (result, context, dc);
      }
    // No context was supplied. Return the derived one.
    else
      context = new AccessControlContext (result);

    inGetContext.set(Boolean.FALSE);
    return context;
  }

  /**
   * Returns a snapshot of the current call stack as a pair of arrays:
   * the first an array of classes in the call stack, the second an array
   * of strings containing the method names in the call stack. The two
   * arrays match up, meaning that method <i>i</i> is declared in class
   * <i>i</i>. The arrays are clean; it will only contain Java methods,
   * and no element of the list should be null.
   *
   * <p>The default implementation returns an empty stack, which will be
   * interpreted as having no permissions whatsoever.
   *
   * @return A pair of arrays describing the current call stack. The first
   *    element is an array of Class objects, and the second is an array
   *    of Strings comprising the method names.
   */
  private static Object[][] getStack()
  {
    return new Object[][] { new Class[0], new String[0] };
  }
}
