1/* 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 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 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. 16 */ 17 18package java.security; 19 20import java.util.Enumeration; 21 22import org.apache.harmony.security.fortress.DefaultPolicy; 23import org.apache.harmony.security.fortress.PolicyUtils; 24 25 26/** 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 29 * which code sources. 30 * <p> 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}. 34 * <p> 35 * Only one instance of a {@code Policy} is active at any time. 36 */ 37public abstract class Policy { 38 39 // Key to security properties, defining default policy provider. 40 private static final String POLICY_PROVIDER = "policy.provider"; //$NON-NLS-1$ 41 42 // The SecurityPermission required to set custom Policy. 43 private static final SecurityPermission SET_POLICY = new SecurityPermission( 44 "setPolicy"); //$NON-NLS-1$ 45 46 // The SecurityPermission required to get current Policy. 47 private static final SecurityPermission GET_POLICY = new SecurityPermission( 48 "getPolicy"); //$NON-NLS-1$ 49 50 // The policy currently in effect. 51 private static Policy activePolicy; 52 53 /** 54 * Returns a {@code PermissionCollection} describing what permissions are 55 * allowed for the specified {@code CodeSource} based on the current 56 * security policy. 57 * <p> 58 * Note that this method is not called for classes which are in the system 59 * domain (i.e. system classes). System classes are always given 60 * full permissions (i.e. AllPermission). This can not be changed by 61 * installing a new policy. 62 * 63 * @param cs 64 * the {@code CodeSource} to compute the permissions for. 65 * @return the permissions that are granted to the specified {@code 66 * CodeSource}. 67 */ 68 public abstract PermissionCollection getPermissions(CodeSource cs); 69 70 /** 71 * Reloads the policy configuration for this {@code Policy} instance. 72 */ 73 public abstract void refresh(); 74 75 /** 76 * Returns a {@code PermissionCollection} describing what permissions are 77 * allowed for the specified {@code ProtectionDomain} (more specifically, 78 * its {@code CodeSource}) based on the current security policy. 79 * <p> 80 * Note that this method is not< called for classes which are in the 81 * system domain (i.e. system classes). System classes are always 82 * given full permissions (i.e. AllPermission). This can not be changed by 83 * installing a new policy. 84 * 85 * @param domain 86 * the {@code ProtectionDomain} to compute the permissions for. 87 * @return the permissions that are granted to the specified {@code 88 * CodeSource}. 89 */ 90 public PermissionCollection getPermissions(ProtectionDomain domain) { 91 if (domain != null) { 92 return getPermissions(domain.getCodeSource()); 93 } 94 return new Permissions(); 95 } 96 97 /** 98 * Indicates whether the specified {@code Permission} is implied by the 99 * {@code PermissionCollection} of the specified {@code ProtectionDomain}. 100 * 101 * @param domain 102 * the {@code ProtectionDomain} for which the permission should 103 * be granted. 104 * @param permission 105 * the {@code Permission} for which authorization is to be 106 * verified. 107 * @return {@code true} if the {@code Permission} is implied by the {@code 108 * ProtectionDomain}, {@code false} otherwise. 109 */ 110 public boolean implies(ProtectionDomain domain, Permission permission) { 111 if (domain != null) { 112 PermissionCollection total = getPermissions(domain); 113 PermissionCollection inherent = domain.getPermissions(); 114 if (total == null) { 115 total = inherent; 116 } else if (inherent != null) { 117 for (Enumeration<Permission> en = inherent.elements(); en.hasMoreElements();) { 118 total.add(en.nextElement()); 119 } 120 } 121 if (total != null && total.implies(permission)) { 122 return true; 123 } 124 } 125 return false; 126 } 127 128 /** 129 * Returns the current system security policy. If no policy has been 130 * instantiated then this is done using the security property {@code 131 * "policy.provider"}. 132 * <p> 133 * If a {@code SecurityManager} is installed, code calling this method needs 134 * the {@code SecurityPermission} {@code getPolicy} to be granted, otherwise 135 * a {@code SecurityException} will be thrown. 136 * 137 * @return the current system security policy. 138 * @throws SecurityException 139 * if a {@code SecurityManager} is installed and the caller does 140 * not have permission to invoke this method. 141 */ 142 public static Policy getPolicy() { 143 SecurityManager sm = System.getSecurityManager(); 144 if (sm != null) { 145 sm.checkPermission(GET_POLICY); 146 } 147 return getAccessiblePolicy(); 148 } 149 150 // Reads name of default policy provider from security.properties, 151 // loads the class and instantiates the provider.<br> 152 // In case of any error, including undefined provider name, 153 // returns new instance of org.apache.harmony.security.FilePolicy provider. 154 private static Policy getDefaultProvider() { 155 final String defaultClass = AccessController 156 .doPrivileged(new PolicyUtils.SecurityPropertyAccessor( 157 POLICY_PROVIDER)); 158 if (defaultClass == null) { 159 //TODO log warning 160 //System.err.println("No policy provider specified. Loading the " 161 // + DefaultPolicy.class.getName()); 162 return new DefaultPolicy(); 163 } 164 165 // TODO accurate classloading 166 return AccessController.doPrivileged(new PrivilegedAction<Policy>() { 167 168 public Policy run() { 169 try { 170 return (Policy) Class.forName(defaultClass, true, 171 ClassLoader.getSystemClassLoader()).newInstance(); 172 } 173 catch (Exception e) { 174 //TODO log error 175 //System.err.println("Error loading policy provider <" 176 // + defaultClass + "> : " + e 177 // + "\nSwitching to the default " 178 // + DefaultPolicy.class.getName()); 179 return new DefaultPolicy(); 180 } 181 } 182 }); 183 184 } 185 186 /** 187 * Returns {@code true} if system policy provider is instantiated. 188 */ 189 static boolean isSet() { 190 return activePolicy != null; 191 } 192 193 /** 194 * Shortcut accessor for friendly classes, to skip security checks. 195 * If active policy was set to <code>null</code>, loads default provider, 196 * so this method never returns <code>null</code>. <br> 197 * This method is synchronized with setPolicy() 198 */ 199 static Policy getAccessiblePolicy() { 200 Policy current = activePolicy; 201 if (current == null) { 202 synchronized (Policy.class) { 203 // double check in case value has been reassigned 204 // while we've been awaiting monitor 205 if (activePolicy == null) { 206 activePolicy = getDefaultProvider(); 207 } 208 return activePolicy; 209 } 210 } 211 return current; 212 } 213 214 /** 215 * Sets the system wide policy. 216 * <p> 217 * If a {@code SecurityManager} is installed, code calling this method needs 218 * the {@code SecurityPermission} {@code setPolicy} to be granted, otherwise 219 * a {@code SecurityException} will be thrown. 220 * 221 * @param policy 222 * the {@code Policy} to set. 223 * @throws SecurityException 224 * if a {@code SecurityManager} is installed and the caller does 225 * not have permission to invoke this method. 226 */ 227 public static void setPolicy(Policy policy) { 228 SecurityManager sm = System.getSecurityManager(); 229 if (sm != null) { 230 sm.checkPermission(SET_POLICY); 231 } 232 synchronized (Policy.class) { 233 activePolicy = policy; 234 } 235 } 236} 237