1 /* 2 * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.security.auth; 27 28 import java.security.Security; 29 import java.security.AccessController; 30 import java.security.PrivilegedAction; 31 import java.security.PrivilegedExceptionAction; 32 import java.util.Objects; 33 import sun.security.util.Debug; 34 35 /** 36 * <p> This is an abstract class for representing the system policy for 37 * Subject-based authorization. A subclass implementation 38 * of this class provides a means to specify a Subject-based 39 * access control {@code Policy}. 40 * 41 * <p> A {@code Policy} object can be queried for the set of 42 * Permissions granted to code running as a 43 * {@code Principal} in the following manner: 44 * 45 * <pre> 46 * policy = Policy.getPolicy(); 47 * PermissionCollection perms = policy.getPermissions(subject, 48 * codeSource); 49 * </pre> 50 * 51 * The {@code Policy} object consults the local policy and returns 52 * and appropriate {@code Permissions} object with the 53 * Permissions granted to the Principals associated with the 54 * provided {@code subject}, and granted to the code specified 55 * by the provided {@code codeSource}. 56 * 57 * <p> A {@code Policy} contains the following information. 58 * Note that this example only represents the syntax for the default 59 * {@code Policy} implementation. Subclass implementations of this class 60 * may implement alternative syntaxes and may retrieve the 61 * {@code Policy} from any source such as files, databases, 62 * or servers. 63 * 64 * <p> Each entry in the {@code Policy} is represented as 65 * a <b><i>grant</i></b> entry. Each <b><i>grant</i></b> entry 66 * specifies a codebase, code signers, and Principals triplet, 67 * as well as the Permissions granted to that triplet. 68 * 69 * <pre> 70 * grant CodeBase ["URL"], Signedby ["signers"], 71 * Principal [Principal_Class] "Principal_Name" { 72 * Permission Permission_Class ["Target_Name"] 73 * [, "Permission_Actions"] 74 * [, signedBy "SignerName"]; 75 * }; 76 * </pre> 77 * 78 * The CodeBase and Signedby components of the triplet name/value pairs 79 * are optional. If they are not present, then any codebase will match, 80 * and any signer (including unsigned code) will match. 81 * For Example, 82 * 83 * <pre> 84 * grant CodeBase "foo.com", Signedby "foo", 85 * Principal com.sun.security.auth.UnixPrincipal "duke" { 86 * permission java.io.FilePermission "/home/duke", "read, write"; 87 * }; 88 * </pre> 89 * 90 * This <b><i>grant</i></b> entry specifies that code from "foo.com", 91 * signed by "foo', and running as a {@code UnixPrincipal} with the 92 * name, duke, has one {@code Permission}. This {@code Permission} 93 * permits the executing code to read and write files in the directory, 94 * "/home/duke". 95 * 96 * <p> To "run" as a particular {@code Principal}, 97 * code invokes the {@code Subject.doAs(subject, ...)} method. 98 * After invoking that method, the code runs as all the Principals 99 * associated with the specified {@code Subject}. 100 * Note that this {@code Policy} (and the Permissions 101 * granted in this {@code Policy}) only become effective 102 * after the call to {@code Subject.doAs} has occurred. 103 * 104 * <p> Multiple Principals may be listed within one <b><i>grant</i></b> entry. 105 * All the Principals in the grant entry must be associated with 106 * the {@code Subject} provided to {@code Subject.doAs} 107 * for that {@code Subject} to be granted the specified Permissions. 108 * 109 * <pre> 110 * grant Principal com.sun.security.auth.UnixPrincipal "duke", 111 * Principal com.sun.security.auth.UnixNumericUserPrincipal "0" { 112 * permission java.io.FilePermission "/home/duke", "read, write"; 113 * permission java.net.SocketPermission "duke.com", "connect"; 114 * }; 115 * </pre> 116 * 117 * This entry grants any code running as both "duke" and "0" 118 * permission to read and write files in duke's home directory, 119 * as well as permission to make socket connections to "duke.com". 120 * 121 * <p> Note that non Principal-based grant entries are not permitted 122 * in this {@code Policy}. Therefore, grant entries such as: 123 * 124 * <pre> 125 * grant CodeBase "foo.com", Signedby "foo" { 126 * permission java.io.FilePermission "/tmp/scratch", "read, write"; 127 * }; 128 * </pre> 129 * 130 * are rejected. Such permission must be listed in the 131 * {@code java.security.Policy}. 132 * 133 * <p> The default {@code Policy} implementation can be changed by 134 * setting the value of the {@code auth.policy.provider} security property to 135 * the fully qualified name of the desired {@code Policy} implementation class. 136 * 137 * @deprecated Replaced by java.security.Policy. 138 * java.security.Policy has a method: 139 * <pre> 140 * public PermissionCollection getPermissions 141 * (java.security.ProtectionDomain pd) 142 * 143 * </pre> 144 * and ProtectionDomain has a constructor: 145 * <pre> 146 * public ProtectionDomain 147 * (CodeSource cs, 148 * PermissionCollection permissions, 149 * ClassLoader loader, 150 * Principal[] principals) 151 * </pre> 152 * 153 * These two APIs provide callers the means to query the 154 * Policy for Principal-based Permission entries. 155 * This class is subject to removal in a future version of Java SE. 156 * 157 * @since 1.4 158 * @see java.security.Security security properties 159 */ 160 @Deprecated(since="1.4", forRemoval=true) 161 public abstract class Policy { 162 163 private static Policy policy; 164 private static final String AUTH_POLICY = 165 "sun.security.provider.AuthPolicyFile"; 166 167 private final java.security.AccessControlContext acc = 168 java.security.AccessController.getContext(); 169 170 // true if a custom (not AUTH_POLICY) system-wide policy object is set 171 private static boolean isCustomPolicy; 172 173 /** 174 * Sole constructor. (For invocation by subclass constructors, typically 175 * implicit.) 176 */ 177 protected Policy() { } 178 179 /** 180 * Returns the installed Policy object. 181 * This method first calls 182 * {@code SecurityManager.checkPermission} with the 183 * {@code AuthPermission("getPolicy")} permission 184 * to ensure the caller has permission to get the Policy object. 185 * 186 * @return the installed Policy. The return value cannot be 187 * {@code null}. 188 * 189 * @exception java.lang.SecurityException if the current thread does not 190 * have permission to get the Policy object. 191 * 192 * @see #setPolicy 193 */ 194 public static Policy getPolicy() { 195 java.lang.SecurityManager sm = System.getSecurityManager(); 196 if (sm != null) sm.checkPermission(new AuthPermission("getPolicy")); 197 return getPolicyNoCheck(); 198 } 199 200 /** 201 * Returns the installed Policy object, skipping the security check. 202 * 203 * @return the installed Policy. 204 * 205 */ 206 static Policy getPolicyNoCheck() { 207 if (policy == null) { 208 209 synchronized(Policy.class) { 210 211 if (policy == null) { 212 String policy_class = null; 213 policy_class = AccessController.doPrivileged 214 (new PrivilegedAction<String>() { 215 public String run() { 216 return java.security.Security.getProperty 217 ("auth.policy.provider"); 218 } 219 }); 220 if (policy_class == null) { 221 policy_class = AUTH_POLICY; 222 } 223 224 try { 225 final String finalClass = policy_class; 226 227 Policy untrustedImpl = AccessController.doPrivileged( 228 new PrivilegedExceptionAction<Policy>() { 229 public Policy run() throws ClassNotFoundException, 230 InstantiationException, 231 IllegalAccessException { 232 Class<? extends Policy> implClass = Class.forName( 233 finalClass, false, 234 Thread.currentThread().getContextClassLoader() 235 ).asSubclass(Policy.class); 236 return implClass.newInstance(); 237 } 238 }); 239 AccessController.doPrivileged( 240 new PrivilegedExceptionAction<Void>() { 241 public Void run() { 242 setPolicy(untrustedImpl); 243 isCustomPolicy = !finalClass.equals(AUTH_POLICY); 244 return null; 245 } 246 }, Objects.requireNonNull(untrustedImpl.acc) 247 ); 248 } catch (Exception e) { 249 throw new SecurityException 250 (sun.security.util.ResourcesMgr.getString 251 ("unable.to.instantiate.Subject.based.policy")); 252 } 253 } 254 } 255 } 256 return policy; 257 } 258 259 260 /** 261 * Sets the system-wide Policy object. This method first calls 262 * {@code SecurityManager.checkPermission} with the 263 * {@code AuthPermission("setPolicy")} 264 * permission to ensure the caller has permission to set the Policy. 265 * 266 * @param policy the new system Policy object. 267 * 268 * @exception java.lang.SecurityException if the current thread does not 269 * have permission to set the Policy. 270 * 271 * @see #getPolicy 272 */ 273 public static void setPolicy(Policy policy) { 274 java.lang.SecurityManager sm = System.getSecurityManager(); 275 if (sm != null) sm.checkPermission(new AuthPermission("setPolicy")); 276 Policy.policy = policy; 277 // all non-null policy objects are assumed to be custom 278 isCustomPolicy = policy != null ? true : false; 279 } 280 281 /** 282 * Returns true if a custom (not AUTH_POLICY) system-wide policy object 283 * has been set or installed. This method is called by 284 * SubjectDomainCombiner to provide backwards compatibility for 285 * developers that provide their own javax.security.auth.Policy 286 * implementations. 287 * 288 * @return true if a custom (not AUTH_POLICY) system-wide policy object 289 * has been set; false otherwise 290 */ 291 static boolean isCustomPolicySet(Debug debug) { 292 if (policy != null) { 293 if (debug != null && isCustomPolicy) { 294 debug.println("Providing backwards compatibility for " + 295 "javax.security.auth.policy implementation: " + 296 policy.toString()); 297 } 298 return isCustomPolicy; 299 } 300 // check if custom policy has been set using auth.policy.provider prop 301 String policyClass = java.security.AccessController.doPrivileged 302 (new java.security.PrivilegedAction<String>() { 303 public String run() { 304 return Security.getProperty("auth.policy.provider"); 305 } 306 }); 307 if (policyClass != null && !policyClass.equals(AUTH_POLICY)) { 308 if (debug != null) { 309 debug.println("Providing backwards compatibility for " + 310 "javax.security.auth.policy implementation: " + 311 policyClass); 312 } 313 return true; 314 } 315 return false; 316 } 317 318 /** 319 * Retrieve the Permissions granted to the Principals associated with 320 * the specified {@code CodeSource}. 321 * 322 * @param subject the {@code Subject} 323 * whose associated Principals, 324 * in conjunction with the provided 325 * {@code CodeSource}, determines the Permissions 326 * returned by this method. This parameter 327 * may be {@code null}. 328 * 329 * @param cs the code specified by its {@code CodeSource} 330 * that determines, in conjunction with the provided 331 * {@code Subject}, the Permissions 332 * returned by this method. This parameter may be 333 * {@code null}. 334 * 335 * @return the Collection of Permissions granted to all the 336 * {@code Subject} and code specified in 337 * the provided <i>subject</i> and <i>cs</i> 338 * parameters. 339 */ 340 public abstract java.security.PermissionCollection getPermissions 341 (Subject subject, 342 java.security.CodeSource cs); 343 344 /** 345 * Refresh and reload the Policy. 346 * 347 * <p>This method causes this object to refresh/reload its current 348 * Policy. This is implementation-dependent. 349 * For example, if the Policy object is stored in 350 * a file, calling {@code refresh} will cause the file to be re-read. 351 * 352 * @exception SecurityException if the caller does not have permission 353 * to refresh the Policy. 354 */ 355 public abstract void refresh(); 356 }