FileDocCategorySizeDatePackage
Policy.javaAPI DocJava SE 5 API12688Fri Aug 26 14:57:14 BST 2005java.security

Policy

public abstract class Policy extends Object
This is an abstract class for representing the system security policy for a Java application environment (specifying which permissions are available for code from various sources). That is, the security policy is represented by a Policy subclass providing an implementation of the abstract methods in this Policy class.

There is only one Policy object in effect at any given time.

The source location for the policy information utilized by the Policy object is up to the Policy implementation. The policy configuration may be stored, for example, as a flat ASCII file, as a serialized binary file of the Policy class, or as a database.

The currently-installed Policy object can be obtained by calling the getPolicy method, and it can be changed by a call to the setPolicy method (by code with permission to reset the Policy).

The refresh method causes the policy object to refresh/reload its current configuration.

This is implementation-dependent. For example, if the policy object stores its policy in configuration files, calling refresh will cause it to re-read the configuration policy files. The refreshed policy may not have an effect on classes in a particular ProtectionDomain. This is dependent on the Policy provider's implementation of the {@link #implies(ProtectionDomain,Permission) implies} method and the PermissionCollection caching strategy.

The default Policy implementation can be changed by setting the value of the "policy.provider" security property (in the Java security properties file) to the fully qualified name of the desired Policy implementation class. The Java security properties file is located in the file named <JAVA_HOME>/lib/security/java.security, where <JAVA_HOME> refers to the directory where the JDK was installed.

author
Roland Schemers
author
Gary Ellison
version
1.94, 06/28/04
see
java.security.CodeSource
see
java.security.PermissionCollection
see
java.security.SecureClassLoader

Fields Summary
private static Policy
policy
the system-wide policy.
private static final Debug
debug
private WeakHashMap
pdMapping
Constructors Summary
Methods Summary
private voidaddStaticPerms(java.security.PermissionCollection perms, java.security.PermissionCollection statics)
add static permissions to provided permission collection

	if (statics != null) {
	    synchronized (statics) {
		Enumeration e = statics.elements();
		while (e.hasMoreElements()) {
		    perms.add((Permission)e.nextElement());
		}
	    }
	}
    
public abstract java.security.PermissionCollectiongetPermissions(java.security.CodeSource codesource)
Evaluates the global policy and returns a PermissionCollection object specifying the set of permissions allowed for code from the specified code source.

param
codesource the CodeSource associated with the caller. This encapsulates the original location of the code (where the code came from) and the public key(s) of its signer.
return
the set of permissions allowed for code from codesource according to the policy.The returned set of permissions must be a new mutable instance and it must support heterogeneous Permission types.

public java.security.PermissionCollectiongetPermissions(java.security.ProtectionDomain domain)
Evaluates the global policy and returns a PermissionCollection object specifying the set of permissions allowed given the characteristics of the protection domain.

param
domain the ProtectionDomain associated with the caller.
return
the set of permissions allowed for the domain according to the policy.The returned set of permissions must be a new mutable instance and it must support heterogeneous Permission types.
see
java.security.ProtectionDomain
see
java.security.SecureClassLoader
since
1.4

	PermissionCollection pc = null;

	if (domain == null)
	    return new Permissions();

	if (pdMapping == null) {
	    initPolicy(this);
	}

	synchronized (pdMapping) {
	    pc = (PermissionCollection)pdMapping.get(domain);
	}

	if (pc != null) {
	    Permissions perms = new Permissions();
	    synchronized (pc) {
		for (Enumeration e = pc.elements() ; e.hasMoreElements() ;) {
		    perms.add((Permission)e.nextElement());
		}
	    }
	    return perms;
	}

	pc = getPermissions(domain.getCodeSource());
	if (pc == null) {
	    pc = new Permissions();
	}

	addStaticPerms(pc, domain.getPermissions());
	return pc;
    
public static java.security.PolicygetPolicy()
Returns the installed Policy object. This value should not be cached, as it may be changed by a call to setPolicy. This method first calls SecurityManager.checkPermission with a SecurityPermission("getPolicy") permission to ensure it's ok to get the Policy object..

return
the installed Policy.
throws
SecurityException if a security manager exists and its checkPermission method doesn't allow getting the Policy object.
see
SecurityManager#checkPermission(Permission)
see
#setPolicy(java.security.Policy)

        SecurityManager sm = System.getSecurityManager();
        if (sm != null)
	    sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION);
	return getPolicyNoCheck();
    
static synchronized java.security.PolicygetPolicyNoCheck()
Returns the installed Policy object, skipping the security check. Used by SecureClassLoader and getPolicy.

return
the installed Policy.

	if (policy == null) {
	    String policy_class = null;
	    policy_class = (String)AccessController.doPrivileged(
                new PrivilegedAction() {
		    public Object run() {
			return Security.getProperty("policy.provider");
		    }
		});
	    if (policy_class == null) {
		policy_class = "sun.security.provider.PolicyFile";
	    }

	    try {
		policy = (Policy)
		    Class.forName(policy_class).newInstance();
	    } catch (Exception e) {
		/*
		 * The policy_class seems to be an extension
		 * so we have to bootstrap loading it via a policy
		 * provider that is on the bootclasspath
		 * If it loads then shift gears to using the configured
		 * provider. 
		 */

		// install the bootstrap provider to avoid recursion
		policy = new sun.security.provider.PolicyFile();
			
		final String pc = policy_class;
		Policy p = (Policy)
		    AccessController.doPrivileged(new PrivilegedAction() {
			public Object run() {
			    try {
				ClassLoader cl =
					ClassLoader.getSystemClassLoader();
				// we want the extension loader 
				ClassLoader extcl = null;
				while (cl != null) {
				    extcl = cl;
				    cl = cl.getParent();
				} 
				return (extcl != null? Class.forName
					(pc, true, extcl).newInstance():
					null);
			    } catch (Exception e) {
				return null;
			    }
			}
		    });
		/*
		 * if it loaded install it as the policy provider. Otherwise
		 * continue to use the system default implementation
		 */
		if (p != null) 
		    policy = p;
			
		if (p == null && debug != null) {
		    debug.println("policy provider " + 
				  policy_class + " not available;using " +
				  "sun.security.provider.PolicyFile");
		    e.printStackTrace();
		}
	    }
	}
	return policy;
    
public booleanimplies(java.security.ProtectionDomain domain, java.security.Permission permission)
Evaluates the global policy for the permissions granted to the ProtectionDomain and tests whether the permission is granted.

param
domain the ProtectionDomain to test
param
permission the Permission object to be tested for implication.
return
true if "permission" is a proper subset of a permission granted to this ProtectionDomain.
see
java.security.ProtectionDomain
since
1.4

	PermissionCollection pc;

	if (pdMapping == null) {
	    initPolicy(this);
	}

	synchronized (pdMapping) {
	    pc = (PermissionCollection)pdMapping.get(domain);
	}

	if (pc != null) {
	    return pc.implies(permission);
	} 
	
	pc = getPermissions(domain);
	if (pc == null) {
	    return false;
	}

	synchronized (pdMapping) {
	    // cache it 
	    pdMapping.put(domain, pc);
	}
	
	return pc.implies(permission);
    
private static voidinitPolicy(java.security.Policy p)
Initialize superclass state such that a legacy provider can handle queries for itself.

since
1.4

	/*
	 * A policy provider not on the bootclasspath could trigger
	 * security checks fulfilling a call to either Policy.implies
	 * or Policy.getPermissions. If this does occur the provider
	 * must be able to answer for it's own ProtectionDomain
	 * without triggering additional security checks, otherwise
	 * the policy implementation will end up in an infinite
	 * recursion.
	 * 
	 * To mitigate this, the provider can collect it's own
	 * ProtectionDomain and associate a PermissionCollection while
	 * it is being installed. The currently installed policy
	 * provider (if there is one) will handle calls to
	 * Policy.implies or Policy.getPermissions during this
	 * process.
	 * 
	 * This Policy superclass caches away the ProtectionDomain and
	 * statically binds permissions so that legacy Policy 
	 * implementations will continue to function.
	 */

	ProtectionDomain policyDomain = (ProtectionDomain)
		AccessController.doPrivileged(new PrivilegedAction() {
		    public Object run() {
			return p.getClass().getProtectionDomain();
		    }
		});

	/*
	 * Collect the permissions granted to this protection domain
	 * so that the provider can be security checked while processing
	 * calls to Policy.implies or Policy.getPermissions.
	 */
	PermissionCollection policyPerms = null;
	synchronized (p) {
	   if (p.pdMapping == null) {
	       p.pdMapping = new WeakHashMap();
	   }
	}

	if (policyDomain.getCodeSource() != null) {
	    if (Policy.isSet()) {
		policyPerms = policy.getPermissions(policyDomain);
	    }

	    if (policyPerms == null) { // assume it has all
		policyPerms = new Permissions();
		policyPerms.add(SecurityConstants.ALL_PERMISSION);
	    }

	    synchronized (p.pdMapping) {
		// cache of pd to permissions
		p.pdMapping.put(policyDomain, policyPerms);
	    }
	}
	return;
    
static booleanisSet()
package private for AccessControlContext


         
      
    
	return policy != null;
    
public abstract voidrefresh()
Refreshes/reloads the policy configuration. The behavior of this method depends on the implementation. For example, calling refresh on a file-based policy will cause the file to be re-read.

public static voidsetPolicy(java.security.Policy p)
Sets the system-wide Policy object. This method first calls SecurityManager.checkPermission with a SecurityPermission("setPolicy") permission to ensure it's ok to set the Policy.

param
p the new system Policy object.
throws
SecurityException if a security manager exists and its checkPermission method doesn't allow setting the Policy.
see
SecurityManager#checkPermission(Permission)
see
#getPolicy()

	SecurityManager sm = System.getSecurityManager();
	if (sm != null) sm.checkPermission(
				 new SecurityPermission("setPolicy"));
	if (p != null) {
	    initPolicy(p);
	}
	synchronized (Policy.class) {
	    Policy.policy = p;
	}