001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /**
019: * @author Alexey V. Varlamov
020: * @version $Revision$
021: */package java.security;
022:
023: import java.util.Enumeration;
024:
025: import org.apache.harmony.security.fortress.DefaultPolicy;
026: import org.apache.harmony.security.fortress.PolicyUtils;
027:
028: /**
029: * Abstract superclass of classes which represent the system security policy.
030: *
031: */
032: public abstract class Policy {
033:
034: // Key to security properties, defining default policy provider.
035: private static final String POLICY_PROVIDER = "policy.provider"; //$NON-NLS-1$
036:
037: // The SecurityPermission required to set custom Policy.
038: private static final SecurityPermission SET_POLICY = new SecurityPermission(
039: "setPolicy"); //$NON-NLS-1$
040:
041: // The SecurityPermission required to get current Policy.
042: private static final SecurityPermission GET_POLICY = new SecurityPermission(
043: "getPolicy"); //$NON-NLS-1$
044:
045: // The policy currently in effect.
046: private static Policy activePolicy;
047:
048: /**
049: * Answers a PermissionCollection describing what permissions are available
050: * to the given CodeSource based on the current security policy.
051: * <p>
052: * Note that this method is <em>not</em> called for classes which are in
053: * the system domain (i.e. system classes). System classes are
054: * <em>always</em> given full permissions (i.e. AllPermission). This can
055: * not be changed by installing a new Policy.
056: *
057: *
058: * @param cs
059: * CodeSource the code source to compute the permissions for.
060: * @return PermissionCollection the permissions the code source should have.
061: */
062: public abstract PermissionCollection getPermissions(CodeSource cs);
063:
064: /**
065: * Reloads the policy configuration, depending on how the type of source
066: * location for the policy information.
067: *
068: *
069: */
070: public abstract void refresh();
071:
072: /**
073: * Answers a PermissionCollection describing what permissions are available
074: * to the given ProtectionDomain (more specifically, its CodeSource) based
075: * on the current security policy.
076: *
077: * @param domain
078: * ProtectionDomain the protection domain to compute the
079: * permissions for.
080: * @return PermissionCollection the permissions the code source should have.
081: */
082: public PermissionCollection getPermissions(ProtectionDomain domain) {
083: if (domain != null) {
084: return getPermissions(domain.getCodeSource());
085: }
086: return new Permissions();
087: }
088:
089: /**
090: * Answers whether the Permission is implied by the PermissionCollection of
091: * the Protection Domain
092: *
093: * @param domain
094: * ProtectionDomain for which Permission to be checked
095: * @param permission
096: * Permission for which authorization is to be verified
097: * @return boolean Permission implied by ProtectionDomain
098: */
099: public boolean implies(ProtectionDomain domain,
100: Permission permission) {
101: if (domain != null) {
102: PermissionCollection total = getPermissions(domain);
103: PermissionCollection inherent = domain.getPermissions();
104: if (total == null) {
105: total = inherent;
106: } else if (inherent != null) {
107: for (Enumeration en = inherent.elements(); en
108: .hasMoreElements();) {
109: total.add((Permission) en.nextElement());
110: }
111: }
112: if (total != null && total.implies(permission)) {
113: return true;
114: }
115: }
116: return false;
117: }
118:
119: /**
120: * Answers the current system security policy. If no policy has been
121: * instantiated then this is done using the security property <EM>policy.provider</EM>
122: *
123: *
124: * @return Policy the current system security policy.
125: */
126: public static Policy getPolicy() {
127: SecurityManager sm = System.getSecurityManager();
128: if (sm != null) {
129: sm.checkPermission(GET_POLICY);
130: }
131: return getAccessiblePolicy();
132: }
133:
134: // Reads name of default policy provider from security.properties,
135: // loads the class and instantiates the provider.<br>
136: // In case of any error, including undefined provider name,
137: // returns new instance of org.apache.harmony.security.FilePolicy provider.
138: private static Policy getDefaultProvider() {
139: final String defaultClass = (String) AccessController
140: .doPrivileged(new PolicyUtils.SecurityPropertyAccessor(
141: POLICY_PROVIDER));
142: if (defaultClass == null) {
143: //TODO log warning
144: //System.err.println("No policy provider specified. Loading the "
145: // + DefaultPolicy.class.getName());
146: return new DefaultPolicy();
147: }
148:
149: // TODO accurate classloading
150: return AccessController
151: .doPrivileged(new PrivilegedAction<Policy>() {
152:
153: public Policy run() {
154: try {
155: return (Policy) Class.forName(defaultClass,
156: true,
157: ClassLoader.getSystemClassLoader())
158: .newInstance();
159: } catch (Exception e) {
160: //TODO log error
161: //System.err.println("Error loading policy provider <"
162: // + defaultClass + "> : " + e
163: // + "\nSwitching to the default "
164: // + DefaultPolicy.class.getName());
165: return new DefaultPolicy();
166: }
167: }
168: });
169:
170: }
171:
172: /**
173: * Returns true if system policy provider is instantiated.
174: */
175: static boolean isSet() {
176: return activePolicy != null;
177: }
178:
179: /**
180: * Shortcut accessor for friendly classes, to skip security checks.
181: * If active policy was set to <code>null</code>, loads default provider,
182: * so this method never returns <code>null</code>. <br>
183: * This method is synchronized with setPolicy()
184: */
185: static Policy getAccessiblePolicy() {
186: Policy current = activePolicy;
187: if (current == null) {
188: synchronized (Policy.class) {
189: // double check in case value has been reassigned
190: // while we've been awaiting monitor
191: if (activePolicy == null) {
192: activePolicy = getDefaultProvider();
193: }
194: return activePolicy;
195: }
196: }
197: return current;
198: }
199:
200: /**
201: * Sets the system-wide policy object if it is permitted by the security
202: * manager.
203: *
204: * @param policy
205: * Policy the policy object that needs to be set.
206: */
207: public static void setPolicy(Policy policy) {
208: SecurityManager sm = System.getSecurityManager();
209: if (sm != null) {
210: sm.checkPermission(SET_POLICY);
211: }
212: synchronized (Policy.class) {
213: activePolicy = policy;
214: }
215: }
216: }
|