1. /*
  2. * @(#)Policy.java 1.68 00/02/02
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.security;
  11. import java.io.*;
  12. import java.lang.RuntimePermission;
  13. import java.net.MalformedURLException;
  14. import java.net.URL;
  15. import java.util.Enumeration;
  16. import java.util.Hashtable;
  17. import java.util.Vector;
  18. import java.util.StringTokenizer;
  19. import java.util.PropertyPermission;
  20. import java.lang.reflect.*;
  21. /**
  22. * This is an abstract class for representing the system security
  23. * policy for a Java application environment (specifying
  24. * which permissions are available for code from various sources).
  25. * That is, the security policy is represented by a Policy subclass
  26. * providing an implementation of the abstract methods
  27. * in this Policy class.
  28. *
  29. * <p>There is only one Policy object in effect at any given time.
  30. *
  31. * <p>The Policy object is typically consulted by objects such as the
  32. * {@link java.security.SecureClassLoader#defineClass(String, byte[], int,
  33. * int, CodeSource) SecureClassLoader} when a loader
  34. * needs to determine the permissions to assign to a particular
  35. * protection domain. The SecureClassLoader executes code such as the
  36. * following to ask the currently installed Policy object to populate a
  37. * PermissionCollection object:
  38. *
  39. * <pre>
  40. * policy = Policy.getPolicy();
  41. * PermissionCollection perms = policy.getPermissions(MyCodeSource)
  42. * </pre>
  43. *
  44. * <p>The SecureClassLoader object passes in a CodeSource
  45. * object, which encapsulates the codebase (URL) and public key certificates
  46. * of the classes being loaded.
  47. * The Policy object consults its policy specification and
  48. * returns an appropriate Permissions object enumerating
  49. * the permissions allowed for code from the specified code source.
  50. *
  51. * <p>The source location for the policy information utilized by the
  52. * Policy object is up to the Policy implementation.
  53. * The policy configuration may be stored, for example, as a
  54. * flat ASCII file, as a serialized binary file of
  55. * the Policy class, or as a database.
  56. *
  57. * <p>The currently-installed Policy object can be obtained by
  58. * calling the <code>getPolicy</code> method, and it can be
  59. * changed by a call to the <code>setPolicy</code> method (by
  60. * code with permission to reset the Policy).
  61. *
  62. * <p>The <code>refresh</code> method causes the policy
  63. * object to refresh/reload its current configuration. This is
  64. * implementation-dependent. For example, if the policy object stores
  65. * its policy in configuration files, calling <code>refresh</code> will
  66. * cause it to re-read the configuration policy files. The refreshed
  67. * policy may not have an effect on classes loaded from a given
  68. * CodeSource. This is dependent on the ProtectionDomain caching strategy
  69. * of the ClassLoader. For example, the
  70. * {@link java.security.SecureClassLoader#getPermissions(CodeSource)
  71. * SecureClassLoader} caches protection domains.
  72. *
  73. * <p>The default Policy implementation can be changed by setting the
  74. * value of the "policy.provider" security property (in the Java
  75. * security properties file) to the fully qualified name of
  76. * the desired Policy implementation class.
  77. * The Java security properties file is located in the file named
  78. * <JAVA_HOME>/lib/security/java.security, where <JAVA_HOME>
  79. * refers to the directory where the SDK was installed.
  80. *
  81. * @author Roland Schemers
  82. * @version 1.68, 02/02/00
  83. * @see java.security.CodeSource
  84. * @see java.security.PermissionCollection
  85. * @see java.security.SecureClassLoader
  86. */
  87. public abstract class Policy {
  88. /** the system-wide policy. */
  89. private static Policy policy; // package private for AccessControlContext
  90. /** package private for AccessControlContext */
  91. static boolean isSet()
  92. {
  93. return policy != null;
  94. }
  95. /**
  96. * Returns the installed Policy object. This value should not be cached,
  97. * as it may be changed by a call to <code>setPolicy</code>.
  98. * This method first calls
  99. * <code>SecurityManager.checkPermission</code> with a
  100. * <code>SecurityPermission("getPolicy")</code> permission
  101. * to ensure it's ok to get the Policy object..
  102. *
  103. * @return the installed Policy.
  104. *
  105. * @throws SecurityException
  106. * if a security manager exists and its
  107. * <code>checkPermission</code> method doesn't allow
  108. * getting the Policy object.
  109. *
  110. * @see SecurityManager#checkPermission(SecurityPermission)
  111. * @see #setPolicy(java.security.Policy)
  112. */
  113. public static Policy getPolicy()
  114. {
  115. SecurityManager sm = System.getSecurityManager();
  116. if (sm != null) sm.checkPermission(new SecurityPermission
  117. ("getPolicy"));
  118. return getPolicyNoCheck();
  119. }
  120. /**
  121. * Returns the installed Policy object, skipping the security check.
  122. * Used by SecureClassLoader and getPolicy.
  123. *
  124. * @return the installed Policy.
  125. *
  126. */
  127. static Policy getPolicyNoCheck()
  128. {
  129. if (policy == null) {
  130. synchronized(Policy.class) {
  131. if (policy == null) {
  132. String policy_class = null;
  133. policy_class = (String)AccessController.doPrivileged(
  134. new PrivilegedAction() {
  135. public Object run() {
  136. return Security.getProperty("policy.provider");
  137. }
  138. });
  139. if (policy_class == null) {
  140. policy_class = "sun.security.provider.PolicyFile";
  141. }
  142. try {
  143. policy = (Policy)
  144. Class.forName(policy_class).newInstance();
  145. } catch (Exception e) {
  146. policy = new sun.security.provider.PolicyFile();
  147. }
  148. }
  149. }
  150. }
  151. return policy;
  152. }
  153. /**
  154. * Sets the system-wide Policy object. This method first calls
  155. * <code>SecurityManager.checkPermission</code> with a
  156. * <code>SecurityPermission("setPolicy")</code>
  157. * permission to ensure it's ok to set the Policy.
  158. *
  159. * @param policy the new system Policy object.
  160. *
  161. * @throws SecurityException
  162. * if a security manager exists and its
  163. * <code>checkPermission</code> method doesn't allow
  164. * setting the Policy.
  165. *
  166. * @see SecurityManager#checkPermission(SecurityPermission)
  167. * @see #getPolicy()
  168. *
  169. */
  170. public static void setPolicy(Policy policy)
  171. {
  172. SecurityManager sm = System.getSecurityManager();
  173. if (sm != null) sm.checkPermission(
  174. new SecurityPermission("setPolicy"));
  175. Policy.policy = policy;
  176. }
  177. /**
  178. * Evaluates the global policy and returns a
  179. * PermissionCollection object specifying the set of
  180. * permissions allowed for code from the specified
  181. * code source.
  182. *
  183. * @param codesource the CodeSource associated with the caller.
  184. * This encapsulates the original location of the code (where the code
  185. * came from) and the public key(s) of its signer.
  186. *
  187. * @return the set of permissions allowed for code from <i>codesource</i>
  188. * according to the policy.
  189. *
  190. * @exception java.lang.SecurityException if the current thread does not
  191. * have permission to call <code>getPermissions</code> on the policy object.
  192. */
  193. public abstract PermissionCollection getPermissions(CodeSource codesource);
  194. /**
  195. * Refreshes/reloads the policy configuration. The behavior of this method
  196. * depends on the implementation. For example, calling <code>refresh</code>
  197. * on a file-based policy will cause the file to be re-read.
  198. *
  199. * @exception java.lang.SecurityException if the current thread does not
  200. * have permission to refresh this Policy object.
  201. */
  202. public abstract void refresh();
  203. }