2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 package java.security;
20 import java.util.Enumeration;
21 import org.apache.harmony.security.fortress.DefaultPolicy;
22 import org.apache.harmony.security.fortress.Engine;
23 import org.apache.harmony.security.fortress.PolicyUtils;
27 * {@code Policy} is the common super type of classes which represent a system
28 * security policy. The {@code Policy} specifies which permissions apply to
31 * The system policy can be changed by setting the {@code 'policy.provider'}
32 * property in the file named {@code JAVA_HOME/lib/security/java.security} to
33 * the fully qualified class name of the desired {@code Policy}.
35 * Only one instance of a {@code Policy} is active at any time.
37 public abstract class Policy {
39 // Key to security properties, defining default policy provider.
40 private static final String POLICY_PROVIDER = "policy.provider";
42 // The SecurityPermission required to set custom Policy.
43 private static final SecurityPermission SET_POLICY = new SecurityPermission(
46 // The SecurityPermission required to get current Policy.
47 static final SecurityPermission GET_POLICY = new SecurityPermission("getPolicy");
49 // The policy currently in effect.
50 private static Policy activePolicy;
52 // Store spi implementation service name
53 private static final String POLICYSERVICE = "Policy";
55 // Used to access common engine functionality
56 private static Engine engine = new Engine(POLICYSERVICE);
60 private Policy.Parameters params;
62 private Provider provider;
64 // Store used spi implementation
65 private PolicySpi spiImpl;
67 private static final String CREATE_POLICY = "createPolicy.";
70 // default constructor
73 private Policy(PolicySpi spi, Provider p, String t, Policy.Parameters para) {
80 private static class PolicyDelegate extends Policy {
82 public PolicyDelegate(PolicySpi spi, Provider p, String t,
83 Policy.Parameters para) {
84 super(spi, p, t, para);
89 * Answers a Policy object with the specified type and the specified
92 * Traverses the list of registered security providers, beginning with the
93 * most preferred Provider. A new Policy object encapsulating the PolicySpi
94 * implementation from the first Provider that supports the specified type
97 * Note that the list of registered providers may be retrieved via the
98 * Security.getProviders() method.
101 * the specified Policy type. See Appendix A in the Java
102 * Cryptography Architecture API Specification & Reference for a
103 * list of standard Policy types.
105 * parameters for the Policy, which may be null.
106 * @return the new Policy object.
107 * @throws NoSuchAlgorithmException -
108 * if no Provider supports a PolicySpi implementation for the
110 * @throws SecurityException -
111 * if the caller does not have permission to get a Policy
112 * instance for the specified type.
113 * @throws NullPointerException -
114 * if the specified type is null.
115 * @throws IllegalArgumentException -
116 * if the specified parameters' type are not allowed by the
117 * PolicySpi implementation from the selected Provider.
119 public static Policy getInstance(String type, Policy.Parameters params)
120 throws NoSuchAlgorithmException {
121 checkSecurityPermission(new SecurityPermission(CREATE_POLICY + type));
124 throw new NullPointerException();
128 synchronized (engine) {
129 engine.getInstance(type, params);
130 return new PolicyDelegate((PolicySpi) engine.spi,
131 engine.provider, type, params);
134 } catch (NoSuchAlgorithmException e) {
135 if (e.getCause() == null) {
138 throw new IllegalArgumentException("Unrecognized policy parameter: " + params);
143 * Answers a Policy object of the specified type.
145 * A new Policy object encapsulating the PolicySpi implementation from the
146 * specified provider is returned. The specified provider must be registered
147 * in the provider list via the Security.getProviders() method, otherwise
148 * NoSuchProviderException will be thrown.
151 * the specified Policy type. So far in Java 6, only 'JavaPolicy'
154 * the Policy.Parameter object, which may be null.
157 * @return the new Policy object.
159 * @throws NoSuchProviderException -
160 * if the specified provider is not registered in the security
162 * @throws NoSuchAlgorithmException -
163 * if the specified provider does not support a PolicySpi
164 * implementation for the specified type.
165 * @throws SecurityException -
166 * if the caller does not have permission to get a Policy
167 * instance for the specified type.
168 * @throws NullPointerException -
169 * if the specified type is null.
170 * @throws IllegalArgumentException -
171 * if the specified Provider is null, or if the specified
172 * parameters' type are not allowed by the PolicySpi
173 * implementation from the specified Provider.
175 public static Policy getInstance(String type, Policy.Parameters params,
176 String provider) throws NoSuchProviderException,
177 NoSuchAlgorithmException {
178 if ((provider == null) || provider.isEmpty()) {
179 throw new IllegalArgumentException("Provider is null or empty string");
181 checkSecurityPermission(new SecurityPermission(CREATE_POLICY + type));
183 Provider impProvider = Security.getProvider(provider);
184 if (impProvider == null) {
185 throw new NoSuchProviderException("Provider " + provider + " is not available");
188 return getInstanceImpl(type, params, impProvider);
192 * Answers a Policy object of the specified type.
194 * A new Policy object encapsulating the PolicySpi implementation from the
195 * specified Provider object is returned. Note that the specified Provider
196 * object does not have to be registered in the provider list.
199 * the specified Policy type. So far in Java 6, only 'JavaPolicy'
202 * the Policy.Parameter object, which may be null.
204 * the Policy service Provider.
205 * @return the new Policy object.
207 * @throws NoSuchAlgorithmException -
208 * if the specified Provider does not support a PolicySpi
209 * implementation for the specified type.
210 * @throws IllegalArgumentException -
211 * if the specified Provider is null, or if the specified
212 * parameters' type are not allowed by the PolicySpi
213 * implementation from the specified Provider.
214 * @throws NullPointerException -
215 * if the specified type is null.
216 * @throws SecurityException -
217 * if the caller does not have permission to get a Policy
218 * instance for the specified type.
220 public static Policy getInstance(String type, Policy.Parameters params,
221 Provider provider) throws NoSuchAlgorithmException {
222 if (provider == null) {
223 throw new IllegalArgumentException("provider == null");
225 checkSecurityPermission(new SecurityPermission(CREATE_POLICY + type));
227 return getInstanceImpl(type, params, provider);
230 private static void checkSecurityPermission(SecurityPermission permission) {
231 SecurityManager sm = System.getSecurityManager();
233 sm.checkPermission(permission);
237 private static Policy getInstanceImpl(String type, Policy.Parameters params, Provider provider) throws NoSuchAlgorithmException {
239 throw new NullPointerException();
243 synchronized (engine) {
244 engine.getInstance(type, provider, params);
245 return new PolicyDelegate((PolicySpi) engine.spi, provider,
248 } catch (NoSuchAlgorithmException e) {
249 if (e.getCause() == null) {
252 throw new IllegalArgumentException("Unrecognized policy parameter: " + params);
257 * Answers Policy parameters.
259 * This method will only answer non-null parameters if it was obtained via a
260 * call to Policy.getInstance. Otherwise this method returns null.
262 * @return Policy parameters, or null.
264 public Policy.Parameters getParameters() {
269 * Answers the Provider of this Policy.
271 * This method will only answer non-null Provider if it was obtained via a
272 * call to Policy.getInstance. Otherwise this method returns null.
274 * @return the Provider of this Policy, or null.
276 public Provider getProvider() {
281 * Answers the type of this Policy.
283 * This method will only answer non-null type if it was obtained via a call
284 * to Policy.getInstance. Otherwise this method returns null.
286 * @return the type of this Policy, or null.
288 public String getType() {
293 * A read-only empty PermissionCollection instance.
295 public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION = new PermissionCollection() {
297 private static final long serialVersionUID = 1L;
300 public void add(Permission permission) {
301 throw new SecurityException(
302 "attempt to add a Permission to a readonly Permissions object");
306 public Enumeration<Permission> elements() {
307 return new Permissions().elements();
311 public boolean implies(Permission permission) {
312 if (permission == null) {
313 throw new NullPointerException();
319 public boolean isReadOnly() {
320 // always returns true since it is a read-only instance.
321 // RI does not override this method.
327 * A marker interface for Policy parameters.
329 public static interface Parameters {
330 // a marker interface
334 * Returns a {@code PermissionCollection} describing what permissions are
335 * allowed for the specified {@code CodeSource} based on the current
338 * Note that this method is not called for classes which are in the system
339 * domain (i.e. system classes). System classes are always given
340 * full permissions (i.e. AllPermission). This can not be changed by
341 * installing a new policy.
344 * the {@code CodeSource} to compute the permissions for.
345 * @return the permissions that are granted to the specified {@code
348 public PermissionCollection getPermissions(CodeSource cs) {
349 return spiImpl == null ? Policy.UNSUPPORTED_EMPTY_COLLECTION : spiImpl
350 .engineGetPermissions(cs);
354 * Reloads the policy configuration for this {@code Policy} instance.
356 public void refresh() {
357 if (spiImpl != null) {
358 spiImpl.engineRefresh();
363 * Returns a {@code PermissionCollection} describing what permissions are
364 * allowed for the specified {@code ProtectionDomain} (more specifically,
365 * its {@code CodeSource}) based on the current security policy.
367 * Note that this method is not< called for classes which are in the
368 * system domain (i.e. system classes). System classes are always
369 * given full permissions (i.e. AllPermission). This can not be changed by
370 * installing a new policy.
373 * the {@code ProtectionDomain} to compute the permissions for.
374 * @return the permissions that are granted to the specified {@code
377 public PermissionCollection getPermissions(ProtectionDomain domain) {
378 Permissions permissions = new Permissions();
379 if (domain != null) {
381 PermissionCollection cds = getPermissions(domain
383 if (cds != Policy.UNSUPPORTED_EMPTY_COLLECTION) {
384 Enumeration<Permission> elements = cds.elements();
385 while (elements.hasMoreElements()) {
386 permissions.add(elements.nextElement());
389 } catch (NullPointerException e) {
390 // ignore the exception, just add nothing to the result set
393 PermissionCollection pds = domain.getPermissions();
395 Enumeration<Permission> pdElements = pds.elements();
396 while (pdElements.hasMoreElements()) {
397 permissions.add(pdElements.nextElement());
405 * Indicates whether the specified {@code Permission} is implied by the
406 * {@code PermissionCollection} of the specified {@code ProtectionDomain}.
409 * the {@code ProtectionDomain} for which the permission should
412 * the {@code Permission} for which authorization is to be
414 * @return {@code true} if the {@code Permission} is implied by the {@code
415 * ProtectionDomain}, {@code false} otherwise.
417 public boolean implies(ProtectionDomain domain, Permission permission) {
418 return spiImpl == null ? defaultImplies(domain, permission) : spiImpl
419 .engineImplies(domain, permission);
422 private boolean defaultImplies(ProtectionDomain domain, Permission permission) {
423 if (domain == null && permission == null) {
424 throw new NullPointerException();
426 boolean implies = false;
427 if (domain != null) {
428 PermissionCollection total = getPermissions(domain);
429 PermissionCollection inherent = domain.getPermissions();
430 if (inherent != null) {
431 Enumeration<Permission> en = inherent.elements();
432 while (en.hasMoreElements()) {
433 total.add(en.nextElement());
437 implies = total.implies(permission);
438 } catch (NullPointerException e) {
439 // return false instead of throwing the NullPointerException
447 * Returns the current system security policy. If no policy has been
448 * instantiated then this is done using the security property {@code
449 * "policy.provider"}.
451 * If a {@code SecurityManager} is installed, code calling this method needs
452 * the {@code SecurityPermission} {@code getPolicy} to be granted, otherwise
453 * a {@code SecurityException} will be thrown.
455 * @return the current system security policy.
456 * @throws SecurityException
457 * if a {@code SecurityManager} is installed and the caller does
458 * not have permission to invoke this method.
460 public static Policy getPolicy() {
461 checkSecurityPermission(GET_POLICY);
462 return getAccessiblePolicy();
465 // Reads name of default policy provider from security.properties,
466 // loads the class and instantiates the provider.<br>
467 // In case of any error, including undefined provider name,
468 // returns new instance of org.apache.harmony.security.FilePolicy provider.
469 private static Policy getDefaultProvider() {
470 final String defaultClass = AccessController
471 .doPrivileged(new PolicyUtils.SecurityPropertyAccessor(
473 if (defaultClass == null) {
475 // System.err.println("No policy provider specified. Loading the "
476 // + DefaultPolicy.class.getName());
477 return new DefaultPolicy();
480 // TODO accurate classloading
481 return AccessController.doPrivileged(new PrivilegedAction<Policy>() {
483 public Policy run() {
485 return (Policy) Class.forName(defaultClass, true,
486 ClassLoader.getSystemClassLoader()).newInstance();
488 catch (Exception e) {
490 //System.err.println("Error loading policy provider <"
491 // + defaultClass + "> : " + e
492 // + "\nSwitching to the default "
493 // + DefaultPolicy.class.getName());
494 return new DefaultPolicy();
502 * Returns {@code true} if system policy provider is instantiated.
504 static boolean isSet() {
505 return activePolicy != null;
509 * Shortcut accessor for friendly classes, to skip security checks.
510 * If active policy was set to <code>null</code>, loads default provider,
511 * so this method never returns <code>null</code>. <br>
512 * This method is synchronized with setPolicy()
514 static synchronized Policy getAccessiblePolicy() {
515 if (activePolicy == null) {
516 activePolicy = getDefaultProvider();
522 * Sets the system wide policy.
524 * If a {@code SecurityManager} is installed, code calling this method needs
525 * the {@code SecurityPermission} {@code setPolicy} to be granted, otherwise
526 * a {@code SecurityException} will be thrown.
529 * the {@code Policy} to set.
530 * @throws SecurityException
531 * if a {@code SecurityManager} is installed and the caller does
532 * not have permission to invoke this method.
534 public static void setPolicy(Policy policy) {
535 checkSecurityPermission(SET_POLICY);
536 synchronized (Policy.class) {
537 activePolicy = policy;