/* | 
|
 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. | 
|
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 
|
 * | 
|
 * This code is free software; you can redistribute it and/or modify it | 
|
 * under the terms of the GNU General Public License version 2 only, as | 
|
 * published by the Free Software Foundation.  Oracle designates this | 
|
 * particular file as subject to the "Classpath" exception as provided | 
|
 * by Oracle in the LICENSE file that accompanied this code. | 
|
 * | 
|
 * This code is distributed in the hope that it will be useful, but WITHOUT | 
|
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 
|
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License | 
|
 * version 2 for more details (a copy is included in the LICENSE file that | 
|
 * accompanied this code). | 
|
 * | 
|
 * You should have received a copy of the GNU General Public License version | 
|
 * 2 along with this work; if not, write to the Free Software Foundation, | 
|
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | 
|
 * | 
|
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | 
|
 * or visit www.oracle.com if you need additional information or have any | 
|
 * questions. | 
|
*/  | 
|
package javax.security.auth;  | 
|
import java.security.Security;  | 
|
import java.security.AccessController;  | 
|
import java.security.PrivilegedAction;  | 
|
import java.security.PrivilegedExceptionAction;  | 
|
import java.util.Objects;  | 
|
import sun.security.util.Debug;  | 
|
/** | 
|
 * <p> This is an abstract class for representing the system policy for | 
|
 * Subject-based authorization.  A subclass implementation | 
|
 * of this class provides a means to specify a Subject-based | 
|
 * access control {@code Policy}. | 
|
 * | 
|
 * <p> A {@code Policy} object can be queried for the set of | 
|
 * Permissions granted to code running as a | 
|
 * {@code Principal} in the following manner: | 
|
 * | 
|
 * <pre> | 
|
 *      policy = Policy.getPolicy(); | 
|
 *      PermissionCollection perms = policy.getPermissions(subject, | 
|
 *                                                      codeSource); | 
|
 * </pre> | 
|
 * | 
|
 * The {@code Policy} object consults the local policy and returns | 
|
 * and appropriate {@code Permissions} object with the | 
|
 * Permissions granted to the Principals associated with the | 
|
 * provided <i>subject</i>, and granted to the code specified | 
|
 * by the provided <i>codeSource</i>. | 
|
 * | 
|
 * <p> A {@code Policy} contains the following information. | 
|
 * Note that this example only represents the syntax for the default | 
|
 * {@code Policy} implementation. Subclass implementations of this class | 
|
 * may implement alternative syntaxes and may retrieve the | 
|
 * {@code Policy} from any source such as files, databases, | 
|
 * or servers. | 
|
 * | 
|
 * <p> Each entry in the {@code Policy} is represented as | 
|
 * a <b><i>grant</i></b> entry.  Each <b><i>grant</i></b> entry | 
|
 * specifies a codebase, code signers, and Principals triplet, | 
|
 * as well as the Permissions granted to that triplet. | 
|
 * | 
|
 * <pre> | 
|
 *      grant CodeBase ["URL"], Signedby ["signers"], | 
|
 *            Principal [Principal_Class] "Principal_Name" { | 
|
 *          Permission Permission_Class ["Target_Name"] | 
|
 *                                      [, "Permission_Actions"] | 
|
 *                                      [, signedBy "SignerName"]; | 
|
 *      }; | 
|
 * </pre> | 
|
 * | 
|
 * The CodeBase and Signedby components of the triplet name/value pairs | 
|
 * are optional.  If they are not present, then any any codebase will match, | 
|
 * and any signer (including unsigned code) will match. | 
|
 * For Example, | 
|
 * | 
|
 * <pre> | 
|
 *      grant CodeBase "foo.com", Signedby "foo", | 
|
 *            Principal com.sun.security.auth.SolarisPrincipal "duke" { | 
|
 *          permission java.io.FilePermission "/home/duke", "read, write"; | 
|
 *      }; | 
|
 * </pre> | 
|
 * | 
|
 * This <b><i>grant</i></b> entry specifies that code from "foo.com", | 
|
 * signed by "foo', and running as a {@code SolarisPrincipal} with the | 
|
 * name, duke, has one {@code Permission}.  This {@code Permission} | 
|
 * permits the executing code to read and write files in the directory, | 
|
 * "/home/duke". | 
|
 * | 
|
 * <p> To "run" as a particular {@code Principal}, | 
|
 * code invokes the {@code Subject.doAs(subject, ...)} method. | 
|
 * After invoking that method, the code runs as all the Principals | 
|
 * associated with the specified {@code Subject}. | 
|
 * Note that this {@code Policy} (and the Permissions | 
|
 * granted in this {@code Policy}) only become effective | 
|
 * after the call to {@code Subject.doAs} has occurred. | 
|
 * | 
|
 * <p> Multiple Principals may be listed within one <b><i>grant</i></b> entry. | 
|
 * All the Principals in the grant entry must be associated with | 
|
 * the {@code Subject} provided to {@code Subject.doAs} | 
|
 * for that {@code Subject} to be granted the specified Permissions. | 
|
 * | 
|
 * <pre> | 
|
 *      grant Principal com.sun.security.auth.SolarisPrincipal "duke", | 
|
 *            Principal com.sun.security.auth.SolarisNumericUserPrincipal "0" { | 
|
 *          permission java.io.FilePermission "/home/duke", "read, write"; | 
|
 *          permission java.net.SocketPermission "duke.com", "connect"; | 
|
 *      }; | 
|
 * </pre> | 
|
 * | 
|
 * This entry grants any code running as both "duke" and "0" | 
|
 * permission to read and write files in duke's home directory, | 
|
 * as well as permission to make socket connections to "duke.com". | 
|
 * | 
|
 * <p> Note that non Principal-based grant entries are not permitted | 
|
 * in this {@code Policy}.  Therefore, grant entries such as: | 
|
 * | 
|
 * <pre> | 
|
 *      grant CodeBase "foo.com", Signedby "foo" { | 
|
 *          permission java.io.FilePermission "/tmp/scratch", "read, write"; | 
|
 *      }; | 
|
 * </pre> | 
|
 * | 
|
 * are rejected.  Such permission must be listed in the | 
|
 * {@code java.security.Policy}. | 
|
 * | 
|
 * <p> The default {@code Policy} implementation can be changed by | 
|
 * setting the value of the {@code auth.policy.provider} security property to | 
|
 * the fully qualified name of the desired {@code Policy} implementation class. | 
|
 * | 
|
 * @deprecated  as of JDK version 1.4 -- Replaced by java.security.Policy. | 
|
 *              java.security.Policy has a method: | 
|
 * <pre> | 
|
 *      public PermissionCollection getPermissions | 
|
 *          (java.security.ProtectionDomain pd) | 
|
 * | 
|
 * </pre> | 
|
 * and ProtectionDomain has a constructor: | 
|
 * <pre> | 
|
 *      public ProtectionDomain | 
|
 *          (CodeSource cs, | 
|
 *           PermissionCollection permissions, | 
|
 *           ClassLoader loader, | 
|
 *           Principal[] principals) | 
|
 * </pre> | 
|
 * | 
|
 * These two APIs provide callers the means to query the | 
|
 * Policy for Principal-based Permission entries. | 
|
 * | 
|
 * @see java.security.Security security properties | 
|
*/  | 
|
@Deprecated  | 
|
public abstract class Policy { | 
|
private static Policy policy;  | 
|
private final static String AUTH_POLICY =  | 
|
        "sun.security.provider.AuthPolicyFile"; | 
|
private final java.security.AccessControlContext acc =  | 
|
java.security.AccessController.getContext();  | 
|
    // true if a custom (not AUTH_POLICY) system-wide policy object is set | 
|
private static boolean isCustomPolicy;  | 
|
    /** | 
|
     * Sole constructor.  (For invocation by subclass constructors, typically | 
|
     * implicit.) | 
|
*/  | 
|
    protected Policy() { } | 
|
    /** | 
|
     * Returns the installed Policy object. | 
|
     * This method first calls | 
|
     * {@code SecurityManager.checkPermission} with the | 
|
     * {@code AuthPermission("getPolicy")} permission | 
|
     * to ensure the caller has permission to get the Policy object. | 
|
     * | 
|
     * <p> | 
|
     * | 
|
     * @return the installed Policy.  The return value cannot be | 
|
     *          {@code null}. | 
|
     * | 
|
     * @exception java.lang.SecurityException if the current thread does not | 
|
     *      have permission to get the Policy object. | 
|
     * | 
|
     * @see #setPolicy | 
|
*/  | 
|
public static Policy getPolicy() {  | 
|
java.lang.SecurityManager sm = System.getSecurityManager();  | 
|
if (sm != null) sm.checkPermission(new AuthPermission("getPolicy"));  | 
|
return getPolicyNoCheck();  | 
|
}  | 
|
    /** | 
|
     * Returns the installed Policy object, skipping the security check. | 
|
     * | 
|
     * @return the installed Policy. | 
|
     * | 
|
*/  | 
|
static Policy getPolicyNoCheck() {  | 
|
if (policy == null) {  | 
|
synchronized(Policy.class) {  | 
|
if (policy == null) {  | 
|
String policy_class = null;  | 
|
policy_class = AccessController.doPrivileged  | 
|
(new PrivilegedAction<String>() {  | 
|
public String run() {  | 
|
return java.security.Security.getProperty  | 
|
                                ("auth.policy.provider"); | 
|
}  | 
|
});  | 
|
if (policy_class == null) {  | 
|
policy_class = AUTH_POLICY;  | 
|
}  | 
|
                    try { | 
|
final String finalClass = policy_class;  | 
|
Policy untrustedImpl = AccessController.doPrivileged(  | 
|
new PrivilegedExceptionAction<Policy>() {  | 
|
public Policy run() throws ClassNotFoundException,  | 
|
InstantiationException,  | 
|
IllegalAccessException {  | 
|
Class<? extends Policy> implClass = Class.forName(  | 
|
finalClass, false,  | 
|
Thread.currentThread().getContextClassLoader()  | 
|
).asSubclass(Policy.class);  | 
|
return implClass.newInstance();  | 
|
}  | 
|
});  | 
|
AccessController.doPrivileged(  | 
|
new PrivilegedExceptionAction<Void>() {  | 
|
public Void run() {  | 
|
setPolicy(untrustedImpl);  | 
|
isCustomPolicy = !finalClass.equals(AUTH_POLICY);  | 
|
return null;  | 
|
}  | 
|
}, Objects.requireNonNull(untrustedImpl.acc)  | 
|
);  | 
|
} catch (Exception e) {  | 
|
throw new SecurityException  | 
|
(sun.security.util.ResourcesMgr.getString  | 
|
                                ("unable.to.instantiate.Subject.based.policy")); | 
|
}  | 
|
}  | 
|
}  | 
|
}  | 
|
return policy;  | 
|
}  | 
|
    /** | 
|
     * Sets the system-wide Policy object. This method first calls | 
|
     * {@code SecurityManager.checkPermission} with the | 
|
     * {@code AuthPermission("setPolicy")} | 
|
     * permission to ensure the caller has permission to set the Policy. | 
|
     * | 
|
     * <p> | 
|
     * | 
|
     * @param policy the new system Policy object. | 
|
     * | 
|
     * @exception java.lang.SecurityException if the current thread does not | 
|
     *          have permission to set the Policy. | 
|
     * | 
|
     * @see #getPolicy | 
|
*/  | 
|
public static void setPolicy(Policy policy) {  | 
|
java.lang.SecurityManager sm = System.getSecurityManager();  | 
|
if (sm != null) sm.checkPermission(new AuthPermission("setPolicy"));  | 
|
Policy.policy = policy;  | 
|
        // all non-null policy objects are assumed to be custom | 
|
isCustomPolicy = policy != null ? true : false;  | 
|
}  | 
|
    /** | 
|
     * Returns true if a custom (not AUTH_POLICY) system-wide policy object | 
|
     * has been set or installed. This method is called by | 
|
     * SubjectDomainCombiner to provide backwards compatibility for | 
|
     * developers that provide their own javax.security.auth.Policy | 
|
     * implementations. | 
|
     * | 
|
     * @return true if a custom (not AUTH_POLICY) system-wide policy object | 
|
     * has been set; false otherwise | 
|
*/  | 
|
static boolean isCustomPolicySet(Debug debug) {  | 
|
if (policy != null) {  | 
|
if (debug != null && isCustomPolicy) {  | 
|
debug.println("Providing backwards compatibility for " +  | 
|
                              "javax.security.auth.policy implementation: " + | 
|
policy.toString());  | 
|
}  | 
|
return isCustomPolicy;  | 
|
}  | 
|
        // check if custom policy has been set using auth.policy.provider prop | 
|
String policyClass = java.security.AccessController.doPrivileged  | 
|
(new java.security.PrivilegedAction<String>() {  | 
|
public String run() {  | 
|
return Security.getProperty("auth.policy.provider");  | 
|
}  | 
|
});  | 
|
if (policyClass != null && !policyClass.equals(AUTH_POLICY)) {  | 
|
if (debug != null) {  | 
|
debug.println("Providing backwards compatibility for " +  | 
|
                              "javax.security.auth.policy implementation: " + | 
|
policyClass);  | 
|
}  | 
|
return true;  | 
|
}  | 
|
return false;  | 
|
}  | 
|
    /** | 
|
     * Retrieve the Permissions granted to the Principals associated with | 
|
     * the specified {@code CodeSource}. | 
|
     * | 
|
     * <p> | 
|
     * | 
|
     * @param subject the {@code Subject} | 
|
     *                  whose associated Principals, | 
|
     *                  in conjunction with the provided | 
|
     *                  {@code CodeSource}, determines the Permissions | 
|
     *                  returned by this method.  This parameter | 
|
     *                  may be {@code null}. <p> | 
|
     * | 
|
     * @param cs the code specified by its {@code CodeSource} | 
|
     *                  that determines, in conjunction with the provided | 
|
     *                  {@code Subject}, the Permissions | 
|
     *                  returned by this method.  This parameter may be | 
|
     *                  {@code null}. | 
|
     * | 
|
     * @return the Collection of Permissions granted to all the | 
|
     *                  {@code Subject} and code specified in | 
|
     *                  the provided <i>subject</i> and <i>cs</i> | 
|
     *                  parameters. | 
|
*/  | 
|
public abstract java.security.PermissionCollection getPermissions  | 
|
(Subject subject,  | 
|
java.security.CodeSource cs);  | 
|
    /** | 
|
     * Refresh and reload the Policy. | 
|
     * | 
|
     * <p>This method causes this object to refresh/reload its current | 
|
     * Policy. This is implementation-dependent. | 
|
     * For example, if the Policy object is stored in | 
|
     * a file, calling {@code refresh} will cause the file to be re-read. | 
|
     * | 
|
     * <p> | 
|
     * | 
|
     * @exception SecurityException if the caller does not have permission | 
|
     *                          to refresh the Policy. | 
|
*/  | 
|
public abstract void refresh();  | 
|
}  |