[kaffe] CVS kaffe (dalibor): Added missing files from last checkin

Kaffe CVS Kaffe Mailing List <kaffe@kaffe.org>
Mon May 31 14:39:03 2004


PatchSet 4802 
Date: 2004/05/31 21:17:15
Author: dalibor
Branch: HEAD
Tag: (none) 
Log:
Added missing files from last checkin

Members: 
	libraries/clib/native/AccessController.c:INITIAL->1.1 
	libraries/javalib/java/security/IntersectingDomainCombiner.java:INITIAL->1.1 
	libraries/javalib/java/security/VMAccessController.java:INITIAL->1.1 

===================================================================
Checking out kaffe/libraries/clib/native/AccessController.c
RCS:  /home/cvs/kaffe/kaffe/libraries/clib/native/AccessController.c,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/clib/native/AccessController.c	Mon May 31 21:22:36 2004
@@ -0,0 +1,88 @@
+/* AccessController.c -- native VMAccessController methods.
+   Copyright (C) 2004  Casey Marshall <csm@gnu.org>
+   Original Copyright (C) 1996, 1997 Transvirtual Technologies, 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA.  */
+
+
+#include "config.h"
+#include "config-std.h"
+#include "config-mem.h"
+#include "gtypes.h"
+#include "access.h"
+#include "constants.h"
+#include "object.h"
+#include "classMethod.h"
+#include "itypes.h"
+#include <native.h>
+#include "defs.h"
+#include <stdlib.h>
+#include "java_security_VMAccessController.h"
+#include "stackTrace.h"
+#include "support.h"
+
+
+/*
+ * Returns the call stack of the current thread as a pair of arrays: the
+ * class in the stack, and the name of the method on the stack.
+ *
+ * This method is based on kaffe_lang_ThreadStack, but returns the
+ * method names along with the classes.
+ */
+HArrayOfArray *
+java_security_VMAccessController_getStack (void)
+{
+  stackTraceInfo *info;
+  errorInfo einfo;
+  int cnt;
+  int i;
+  HArrayOfArray *classes;
+  HArrayOfObject *meths;
+  HArrayOfObject *array;
+
+  info = (stackTraceInfo *) buildStackTrace(0);
+  if (info == NULL)
+    {
+      postOutOfMemory (&einfo);
+      throwError (&einfo);
+    }
+
+  cnt = 0;
+  for (i = 0; info[i].meth != ENDOFSTACK; i++)
+    {
+      if (info[i].meth != NULL && info[i].meth->class != NULL)
+	cnt++;
+    }
+
+  array = (HArrayOfObject *) AllocObjectArray (2, "[Ljava/lang/Object;", 0);
+  classes = (HArrayOfObject *) AllocObjectArray (cnt, "Ljava/lang/Class;", 0);
+  meths = (HArrayOfObject *) AllocObjectArray (cnt, "Ljava/lang/String;", 0);
+
+  cnt = 0;
+  for (i = 0; info[i].meth != ENDOFSTACK; i++)
+    {
+      if (info[i].meth != NULL && info[i].meth->class != NULL)
+	{
+	  unhand_array(classes)->body[cnt] = (Hjava_lang_Object *) info[i].meth->class;
+	  unhand_array(meths)->body[cnt] = (Hjava_lang_Object *) utf8Const2Java (info[i].meth->name);
+	  cnt++;
+	}      
+    }
+
+  unhand_array(array)->body[0] = (Hjava_lang_Object *) classes;
+  unhand_array(array)->body[1] = (Hjava_lang_Object *) meths;
+  return array;
+}
===================================================================
Checking out kaffe/libraries/javalib/java/security/IntersectingDomainCombiner.java
RCS:  /home/cvs/kaffe/kaffe/libraries/javalib/java/security/IntersectingDomainCombiner.java,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/javalib/java/security/IntersectingDomainCombiner.java	Mon May 31 21:22:37 2004
@@ -0,0 +1,82 @@
+/* IntersectingDomainCombiner.java --
+   Copyright (C) 2004  Casey Marshall <csm@gnu.org>
+
+This file is part of GNU Classpath.
+
+GNU Classpath 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.
+
+GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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;
+
+/**
+ * A trivial implementation of {@link DomainCombiner} that produces the
+ * intersection of the supplied {@link ProtectionDomain} objects.
+ */
+final class IntersectingDomainCombiner implements DomainCombiner
+{
+
+  // Contstant.
+  // -------------------------------------------------------------------------
+
+  static final IntersectingDomainCombiner SINGLETON = new IntersectingDomainCombiner();
+
+  // Constructor.
+  // -------------------------------------------------------------------------
+
+  private IntersectingDomainCombiner()
+  {
+  }
+
+  // Methods.
+  // -------------------------------------------------------------------------
+
+  public ProtectionDomain[] combine (ProtectionDomain[] currentDomains,
+                                     ProtectionDomain[] assignedDomains)
+  {
+    HashSet newDomains = new HashSet ();
+    for (int i = 0; i < currentDomains.length; i++)
+      {
+        if (currentDomains[i] == null)
+          continue;
+        for (int j = 0; j < assignedDomains.length; j++)
+          {
+            if (currentDomains[i].equals (assignedDomains[j]))
+              newDomains.add (currentDomains[i]);
+          }
+      }
+    return (ProtectionDomain[])
+      newDomains.toArray(new ProtectionDomain[newDomains.size()]);
+  }
+}
===================================================================
Checking out kaffe/libraries/javalib/java/security/VMAccessController.java
RCS:  /home/cvs/kaffe/kaffe/libraries/javalib/java/security/VMAccessController.java,v
VERS: 1.1
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/javalib/java/security/VMAccessController.java	Mon May 31 21:22:37 2004
@@ -0,0 +1,236 @@
+/* VMAccessController.java -- VM-specific access controller methods.
+   Copyright (C) 2004  Casey Marshall <csm@gnu.org>
+
+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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+final class VMAccessController
+{
+
+  // Fields.
+  // -------------------------------------------------------------------------
+
+  /**
+   * A mapping between pairs (<i>thread</i>, <i>classname</i>) to access
+   * control contexts. The <i>thread</i> and <i>classname</i> are the thread
+   * and <i>classname</i> current as of the last call to doPrivileged with
+   * an AccessControlContext argument.
+   */
+  private static final Map contexts = Collections.synchronizedMap(new HashMap());
+
+  private static final ThreadLocal inGetContext = new ThreadLocal();
+
+  private final static 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 = true;
+  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.
+   * @param clazz The class that implements {@link PrivilegedAction}.
+   */
+  static void pushContext (AccessControlContext acc, Class clazz)
+  {
+    ArrayList pair = new ArrayList (2);
+    pair.add (Thread.currentThread());
+    pair.add (clazz);
+    if (DEBUG) debug ("pushing " + pair);
+    contexts.put (pair, 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)}.
+   *
+   * @param clazz The class that implements {@link PrivilegedAction}.
+   */
+  static void popContext (Class clazz)
+  {
+    ArrayList pair = new ArrayList (2);
+    pair.add (Thread.currentThread());
+    pair.add (clazz);
+    if (DEBUG) debug ("popping " + pair);
+    contexts.remove (pair);
+  }
+
+  /**
+   * 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;
+      }
+
+    Object[][] stack = getStack();
+    Class[] classes = (Class[]) stack[0];
+    String[] methods = (String[]) stack[1];
+
+    inGetContext.set (Boolean.TRUE);
+
+    if (DEBUG) debug (">>> got trace of length " + classes.length);
+
+    HashSet domains = new HashSet();
+    HashSet seenDomains = new HashSet();
+    AccessControlContext context = null;
+
+    // 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; i++)
+      {
+        Class clazz = classes[i];
+        String method = methods[i];
+
+        if (DEBUG) debug (">>> checking " + clazz + "." + method);
+
+        if (DEBUG) debug (">>> loader = " + clazz.getClassLoader());
+
+        if (clazz.equals (AccessController.class)
+            && method.equals ("doPrivileged"))
+          {
+            // If there was a call to doPrivileged with a supplied context,
+            // return that context.
+            List pair = new ArrayList(2);
+            pair.add (Thread.currentThread());
+            pair.add (classes[i-1]);
+            if (contexts.containsKey (pair))
+              context = (AccessControlContext) contexts.get (pair);
+            break;
+          }
+
+        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()]);
+
+    // Intersect the derived protection domain with the context supplied
+    // to doPrivileged.
+    if (context != null)
+      context = new AccessControlContext (result, context,
+                                          IntersectingDomainCombiner.SINGLETON);
+    // 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>XXX note: this interface (VMAccessController) would possibly be
+   * cleaner if we had a method similar to this, but returned an array
+   * of java.lang.reflect.Method objects. Then, instead of having this
+   * much logic in this class, we put everything in AccessController,
+   * and simply have this single getStack method for a VM to implement.
+   */
+  private static native Object[][] getStack();
+}