You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/03/31 17:34:51 UTC

svn commit: r390443 [5/5] - in /incubator/harmony/enhanced/classlib/trunk: make/ make/patternsets/ modules/kernel/ modules/luni-kernel/ modules/luni-kernel/META-INF/ modules/luni-kernel/src/ modules/luni-kernel/src/main/ modules/luni-kernel/src/main/ja...

Added: incubator/harmony/enhanced/classlib/trunk/modules/security-kernel/src/main/java/java/security/AccessController.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/security-kernel/src/main/java/java/security/AccessController.java?rev=390443&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/security-kernel/src/main/java/java/security/AccessController.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/security-kernel/src/main/java/java/security/AccessController.java Fri Mar 31 07:34:47 2006
@@ -0,0 +1,271 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.security;
+
+/**
+ * This class must be implemented by the vm vendor, or the reference
+ * implementation can be used if the documented native is implemented.
+ * 
+ * Checks access to system resources. Supports marking of code as priveleged.
+ * Makes context snapshots to allow checking from other contexts.
+ * 
+ */
+
+public final class AccessController {
+	static {
+		// Initialize vm-internal caches
+		initializeInternal();
+	}
+
+	private static native void initializeInternal();
+
+	/**
+	 * Prevents this class from being instantiated.
+	 */
+	private AccessController() {
+	}
+
+	/**
+	 * This native must be implemented to use the reference implementation of
+	 * this class. It is used by checkPermission() and getContext(), which call
+	 * this native with depth = 1.
+	 * 
+	 * Returns an array of ProtectionDomain from the classes on the stack, from
+	 * the specified depth up to the first privileged frame, or the end of the
+	 * stack if there is not a privileged frame. The array may be larger than
+	 * required, but must be null terminated. As bootstrap classes have all
+	 * permissions, bootstrap class frames SHOULD be skipped. Bootstrap class
+	 * frames MUST be skipped if the ProtectionDomain of bootstrap classes is
+	 * null. Duplicate ProtectionDomains SHOULD be removed.
+	 * 
+	 * The first element of the result is the AccessControlContext, which may be
+	 * null, either from the privileged frame, or from the current Thread if
+	 * there is not a privileged frame.
+	 * 
+	 * A privileged frame is any frame running one of the following methods:
+	 * 
+	 * <code><ul>
+	 * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedAction;)Ljava/lang/Object;</li>
+	 * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;)Ljava/lang/Object;</li>
+	 * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;</li>
+	 * <li>java/security/AccessController.doPrivileged(Ljava/security/PrivilegedExceptionAction;Ljava/security/AccessControlContext;)Ljava/lang/Object;</li>
+	 * </ul></code>
+	 * 
+	 * @param depth
+	 *            The stack depth at which to start. Depth 0 is the current
+	 *            frame (the caller of this native).
+	 * 
+	 * @return an Object[] where the first element is AccessControlContext, and
+	 *         the other elements are ProtectionsDomain.
+	 */
+
+	private static native Object[] getProtectionDomains(int depth);
+
+	/**
+	 * Checks whether the running program is allowed to access the resource
+	 * being guarded by the given Permission argument.
+	 * 
+	 * 
+	 * @param perm
+	 *            the permission to check
+	 * @exception AccessControlException
+	 *                if access is not allowed.
+	 */
+	public static void checkPermission(Permission perm)
+			throws AccessControlException {
+		if (perm == null)
+			throw new NullPointerException();
+		Object[] domains = getProtectionDomains(1);
+		AccessControlContext acc = (AccessControlContext) domains[0];
+		ProtectionDomain[] pDomains = null;
+		if (acc != null && acc.domainCombiner != null) {
+			pDomains = acc.domainCombiner.combine(toArrayOfProtectionDomains(
+					domains, null), acc.domainsArray);
+		} else {
+			pDomains = toArrayOfProtectionDomains(domains, acc);
+		}
+		for (int i = 0, length = pDomains.length; i < length; i++) {
+			if (!pDomains[i].implies(perm)) {
+				throw new AccessControlException("Access Denied " + perm, perm);
+			}
+		}
+	}
+
+	/**
+	 * Used to keep the context live during doPrivileged().
+	 * 
+	 * 
+	 * @see #doPrivileged(PrivilegedAction, AccessControlContext)
+	 */
+	private static void keepalive(AccessControlContext context) {
+	}
+
+	/**
+	 * Answers the access controller context of the current thread, including
+	 * the inherited ones. It basically retrieves all the protection domains
+	 * from the calling stack and creates an <code>AccessControlContext</code>
+	 * with them.
+	 * 
+	 * 
+	 * @see AccessControlContext
+	 */
+	public static AccessControlContext getContext() {
+		Object[] domains = getProtectionDomains(1);
+		AccessControlContext acc = (AccessControlContext) domains[0];
+		ProtectionDomain[] pDomains = null;
+		if (acc != null && acc.domainCombiner != null) {
+			pDomains = acc.domainCombiner.combine(toArrayOfProtectionDomains(
+					domains, null), acc.domainsArray);
+			AccessControlContext result = new AccessControlContext(pDomains,
+					false);
+			result.domainCombiner = acc.domainCombiner;
+			return result;
+		}
+		return new AccessControlContext(
+				toArrayOfProtectionDomains(domains, acc), false);
+	}
+
+	private static ProtectionDomain[] toArrayOfProtectionDomains(
+			Object[] domains, AccessControlContext acc) {
+		int len = 0, size = domains.length - 1;
+		int extra = acc == null ? 0 : acc.domainsArray.length;
+		ProtectionDomain[] answer = new ProtectionDomain[size + extra];
+		for (int i = 1; i <= size; i++) {
+			boolean found = false;
+			if ((answer[len] = (ProtectionDomain) domains[i]) == null)
+				break;
+			if (acc != null) {
+				for (int j = 0; j < acc.domainsArray.length; j++) {
+					if (answer[len] == acc.domainsArray[j]) {
+						found = true;
+						break;
+					}
+				}
+			}
+			if (!found)
+				len++;
+		}
+		if (len == 0 && acc != null)
+			return acc.domainsArray;
+		else if (len < size) {
+			ProtectionDomain[] copy = new ProtectionDomain[len + extra];
+			System.arraycopy(answer, 0, copy, 0, len);
+			answer = copy;
+		}
+		if (acc != null)
+			System.arraycopy(acc.domainsArray, 0, answer, len,
+					acc.domainsArray.length);
+		return answer;
+	}
+
+	/**
+	 * Performs the privileged action specified by <code>action</code>.
+	 * <p>
+	 * When permission checks are made, if the permission has been granted by
+	 * all frames below and including the one representing the call to this
+	 * method, then the permission is granted. In otherwords, the check stops
+	 * here.
+	 * 
+	 * Any unchecked exception generated by this method will propagate up the
+	 * chain.
+	 * 
+	 * 
+	 * @see #doPrivileged(PrivilegedAction)
+	 */
+	public static Object doPrivileged(PrivilegedAction action) {
+		return action.run();
+	}
+
+	/**
+	 * Performs the privileged action specified by <code>action</code>.
+	 * <p>
+	 * When permission checks are made, if the permission has been granted by
+	 * all frames below and including the one representing the call to this
+	 * method, then the permission is granted iff it is granted by the
+	 * AccessControlContext <code>context</code>. In otherwords, no more
+	 * checking of the current stack is performed. Instead, the passed in
+	 * context is checked.
+	 * 
+	 * Any unchecked exception generated by this method will propagate up the
+	 * chain.
+	 * 
+	 * 
+	 * @see #doPrivileged(PrivilegedAction)
+	 */
+	public static Object doPrivileged(PrivilegedAction action,
+			AccessControlContext context) {
+		Object result = action.run();
+		keepalive(context);
+		return result;
+	}
+
+	/**
+	 * Performs the privileged action specified by <code>action</code>.
+	 * <p>
+	 * When permission checks are made, if the permission has been granted by
+	 * all frames below and including the one representing the call to this
+	 * method, then the permission is granted. In otherwords, the check stops
+	 * here.
+	 * 
+	 * Any unchecked exception generated by this method will propagate up the
+	 * chain. However, checked exceptions will be caught an re-thrown as
+	 * PrivilegedActionExceptions
+	 * 
+	 * 
+	 * @see #doPrivileged(PrivilegedAction)
+	 */
+	public static Object doPrivileged(PrivilegedExceptionAction action)
+			throws PrivilegedActionException {
+		try {
+			return action.run();
+		} catch (RuntimeException ex) {
+			throw ex;
+		} catch (Exception ex) {
+			throw new PrivilegedActionException(ex);
+		}
+	}
+
+	/**
+	 * Performs the privileged action specified by <code>action</code>.
+	 * <p>
+	 * When permission checks are made, if the permission has been granted by
+	 * all frames below and including the one representing the call to this
+	 * method, then the permission is granted iff it is granted by the
+	 * AccessControlContext <code>context</code>. In otherwords, no more
+	 * checking of the current stack is performed. Instead, the passed in
+	 * context is checked.
+	 * 
+	 * Any unchecked exception generated by this method will propagate up the
+	 * chain. However, checked exceptions will be caught an re-thrown as
+	 * PrivilegedActionExceptions
+	 * 
+	 * 
+	 * @see #doPrivileged(PrivilegedAction)
+	 */
+	public static Object doPrivileged(PrivilegedExceptionAction action,
+			AccessControlContext context) throws PrivilegedActionException {
+		try {
+			Object result = action.run();
+			keepalive(context);
+			return result;
+		} catch (RuntimeException ex) {
+			throw ex;
+		} catch (Exception ex) {
+			throw new PrivilegedActionException(ex);
+		}
+	}
+
+}