| /* Policy.java --- Policy Manager Class | |
| Copyright (C) 1999, 2003, 2004 Free Software Foundation, Inc. | |
| 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., 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.Collections; | |
| import java.util.Enumeration; | |
| import java.util.LinkedHashMap; | |
| import java.util.Map; | |
| /** | |
| * <code>Policy</code> is an abstract class for managing the system security | |
| * policy for the Java application environment. It specifies which permissions | |
| * are available for code from various sources. The security policy is | |
| * represented through a subclass of <code>Policy</code>. | |
| * | |
| * <p>Only one <code>Policy</code> is in effect at any time. A | |
| * {@link ProtectionDomain} initializes itself with information from this class | |
| * on the set of permssions to grant.</p> | |
| * | |
| * <p>The location for the actual <code>Policy</code> could be anywhere in any | |
| * form because it depends on the Policy implementation. The default system is | |
| * in a flat ASCII file or it could be in a database.</p> | |
| * | |
| * <p>The current installed <code>Policy</code> can be accessed with | |
| * {@link #getPolicy()} and changed with {@link #setPolicy(Policy)} if the code | |
| * has the correct permissions.</p> | |
| * | |
| * <p>The {@link #refresh()} method causes the <code>Policy</code> instance to | |
| * refresh/reload its configuration. The method used to refresh depends on the | |
| * <code>Policy</code> implementation.</p> | |
| * | |
| * <p>When a protection domain initializes its permissions, it uses code like | |
| * the following:</p> | |
| * | |
| * <code> | |
| * policy = Policy.getPolicy(); | |
| * PermissionCollection perms = policy.getPermissions(myCodeSource); | |
| * </code> | |
| * | |
| * <p>The protection domain passes the <code>Policy</code> handler a | |
| * {@link CodeSource} instance which contains the codebase URL and a public key. | |
| * The <code>Policy</code> implementation then returns the proper set of | |
| * permissions for that {@link CodeSource}.</p> | |
| * | |
| * <p>The default <code>Policy</code> implementation can be changed by setting | |
| * the "policy.provider" security provider in the "java.security" file to the | |
| * correct <code>Policy</code> implementation class.</p> | |
| * | |
| * @author Mark Benvenuto | |
| * @see CodeSource | |
| * @see PermissionCollection | |
| * @see SecureClassLoader | |
| * @since 1.2 | |
| */ | |
| public abstract class Policy | |
| { | |
| private static Policy currentPolicy; | |
| /** Map of ProtectionDomains to PermissionCollections for this instance. */ | |
| private Map pd2pc = null; | |
| /** Constructs a new <code>Policy</code> object. */ | |
| public Policy() | |
| { | |
| } | |
| /** | |
| * Returns the currently installed <code>Policy</code> handler. The value | |
| * should not be cached as it can be changed any time by | |
| * {@link #setPolicy(Policy)}. | |
| * | |
| * @return the current <code>Policy</code>. | |
| * @throws SecurityException | |
| * if a {@link SecurityManager} is installed which disallows this | |
| * operation. | |
| */ | |
| public static Policy getPolicy() | |
| { | |
| SecurityManager sm = System.getSecurityManager(); | |
| if (sm != null) | |
| sm.checkPermission(new SecurityPermission("getPolicy")); | |
| return getCurrentPolicy(); | |
| } | |
| /** | |
| * Sets the <code>Policy</code> handler to a new value. | |
| * | |
| * @param policy | |
| * the new <code>Policy</code> to use. | |
| * @throws SecurityException | |
| * if a {@link SecurityManager} is installed which disallows this | |
| * operation. | |
| */ | |
| public static void setPolicy(Policy policy) | |
| { | |
| SecurityManager sm = System.getSecurityManager(); | |
| if (sm != null) | |
| sm.checkPermission(new SecurityPermission("setPolicy")); | |
| setup(policy); | |
| currentPolicy = policy; | |
| } | |
| private static void setup(final Policy policy) | |
| { | |
| if (policy.pd2pc == null) | |
| policy.pd2pc = Collections.synchronizedMap(new LinkedHashMap()); | |
| ProtectionDomain pd = policy.getClass().getProtectionDomain(); | |
| if (pd.getCodeSource() != null) | |
| { | |
| PermissionCollection pc = null; | |
| if (currentPolicy != null) | |
| pc = currentPolicy.getPermissions(pd); | |
| if (pc == null) // assume it has all | |
| { | |
| pc = new Permissions(); | |
| pc.add(new AllPermission()); | |
| } | |
| policy.pd2pc.put(pd, pc); // add the mapping pd -> pc | |
| } | |
| } | |
| /** | |
| * Ensures/forces loading of the configured policy provider, while bypassing | |
| * the {@link SecurityManager} checks for <code>"getPolicy"</code> security | |
| * permission. Needed by {@link ProtectionDomain}. | |
| */ | |
| static Policy getCurrentPolicy() | |
| { | |
| // FIXME: The class name of the Policy provider should really be sourced | |
| // from the "java.security" configuration file. For now, just hard-code | |
| // a stub implementation. | |
| if (currentPolicy == null) | |
| { | |
| String pp = System.getProperty ("policy.provider"); | |
| if (pp != null) | |
| try | |
| { | |
| currentPolicy = (Policy) Class.forName(pp).newInstance(); | |
| } | |
| catch (Exception e) | |
| { | |
| // Ignored. | |
| } | |
| if (currentPolicy == null) | |
| currentPolicy = new gnu.java.security.provider.DefaultPolicy(); | |
| } | |
| return currentPolicy; | |
| } | |
| /** | |
| * Tests if <code>currentPolicy</code> is not <code>null</code>, | |
| * thus allowing clients to not force loading of any policy | |
| * provider; needed by {@link ProtectionDomain}. | |
| */ | |
| static boolean isLoaded() | |
| { | |
| return currentPolicy != null; | |
| } | |
| /** | |
| * Returns the set of Permissions allowed for a given {@link CodeSource}. | |
| * | |
| * @param codesource | |
| * the {@link CodeSource} for which, the caller needs to find the | |
| * set of granted permissions. | |
| * @return a set of permissions for {@link CodeSource} specified by the | |
| * current <code>Policy</code>. | |
| * @throws SecurityException | |
| * if a {@link SecurityManager} is installed which disallows this | |
| * operation. | |
| */ | |
| public abstract PermissionCollection getPermissions(CodeSource codesource); | |
| /** | |
| * Returns the set of Permissions allowed for a given {@link ProtectionDomain}. | |
| * | |
| * @param domain | |
| * the {@link ProtectionDomain} for which, the caller needs to find | |
| * the set of granted permissions. | |
| * @return a set of permissions for {@link ProtectionDomain} specified by the | |
| * current <code>Policy.</code>. | |
| * @since 1.4 | |
| * @see ProtectionDomain | |
| * @see SecureClassLoader | |
| */ | |
| public PermissionCollection getPermissions(ProtectionDomain domain) | |
| { | |
| if (domain == null) | |
| return new Permissions(); | |
| if (pd2pc == null) | |
| setup(this); | |
| PermissionCollection result = (PermissionCollection) pd2pc.get(domain); | |
| if (result != null) | |
| { | |
| Permissions realResult = new Permissions(); | |
| for (Enumeration e = result.elements(); e.hasMoreElements(); ) | |
| realResult.add((Permission) e.nextElement()); | |
| return realResult; | |
| } | |
| result = getPermissions(domain.getCodeSource()); | |
| if (result == null) | |
| result = new Permissions(); | |
| PermissionCollection pc = domain.getPermissions(); | |
| if (pc != null) | |
| for (Enumeration e = pc.elements(); e.hasMoreElements(); ) | |
| result.add((Permission) e.nextElement()); | |
| return result; | |
| } | |
| /** | |
| * Checks if the designated {@link Permission} is granted to a designated | |
| * {@link ProtectionDomain}. | |
| * | |
| * @param domain | |
| * the {@link ProtectionDomain} to test. | |
| * @param permission | |
| * the {@link Permission} to check. | |
| * @return <code>true</code> if <code>permission</code> is implied by a | |
| * permission granted to this {@link ProtectionDomain}. Returns | |
| * <code>false</code> otherwise. | |
| * @since 1.4 | |
| * @see ProtectionDomain | |
| */ | |
| public boolean implies(ProtectionDomain domain, Permission permission) | |
| { | |
| if (pd2pc == null) | |
| setup(this); | |
| PermissionCollection pc = (PermissionCollection) pd2pc.get(domain); | |
| if (pc != null) | |
| return pc.implies(permission); | |
| boolean result = false; | |
| pc = getPermissions(domain); | |
| if (pc != null) | |
| { | |
| result = pc.implies(permission); | |
| pd2pc.put(domain, pc); | |
| } | |
| return result; | |
| } | |
| /** | |
| * Causes this <code>Policy</code> instance to refresh / reload its | |
| * configuration. The method used to refresh depends on the concrete | |
| * implementation. | |
| */ | |
| public abstract void refresh(); | |
| } |