001/*
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: ISPolicy.java,v 1.6 2008/08/19 19:09:17 veiming Exp $
026 *
027 * Portions Copyrighted 2011-2015 ForgeRock AS.
028 */
029
030package com.sun.identity.policy.jaas;
031
032import com.sun.identity.shared.debug.Debug;
033
034import java.security.CodeSource;
035import java.security.PermissionCollection;
036import java.security.ProtectionDomain;
037import java.util.Enumeration;
038
039/**
040 * This is an implementation of abstract class
041 * <code>java.security.Policy</code> for representing the system security
042 * policy for a Java application environment. It provides a custom policy
043 * implementation based on JAAS and JDK 1.5 and above.It makes policy evaluation
044 * against the OpenAM Policy Service instead of the default file
045 * based one.
046 *<p>
047 * It provides implementation of the abstract methods in Policy class.
048 * <p>In general the source location for the policy information utilized by the
049 * Policy object to make policy decisions is up to the Policy implementation.
050 * In the case of ISPolicy the source comes from the OpenAM's policy
051 * store, which is consulted to make the policy evaluation.
052 * <p>A <code>Policy</code> object can be queried for the set of Permissions 
053 * granted to set of classes running as a <code>Principal</code> in the 
054 * following manner: 
055 * <pre>
056 *   policy = Policy.getPolicy();
057 *   PermissionCollection perms = policy.getPermissions(ProtectionDomain);
058 * </pre>
059 * The <code>Policy</code> object consults the local policy and returns the 
060 * appropriate <code>PermissionCollection</code> object
061 * {@link com.sun.identity.policy.jaas.ISPermissionCollection} containing
062 * the Permissions granted to the  Principals and granted to the set of classes
063 *  specified by the provided <code>protectionDomain</code>.
064 *
065 * <p>The currently-installed Policy object can be obtained by
066 * calling the <code>getPolicy</code> method, and it can be
067 * changed by a call to the <code>setPolicy</code> method (by
068 * code with permission to reset the Policy).
069 *
070 * <p>The <code>refresh</code> method causes the policy
071 * object to refresh/reload its current configuration.
072 *
073 * @see java.security.ProtectionDomain
074 * @see java.security.PermissionCollection
075 * @supported.all.api
076 */
077public class ISPolicy extends java.security.Policy {
078
079    private static java.security.Policy defaultPolicy = null;
080
081    static Debug debug = Debug.getInstance("amPolicy");
082
083    /**
084     * Constructs an <code>ISPolicy</code> instance.
085     * Save the existing global policy , so that we can use that
086     * for evaluating permissions we do not support through our custom policy 
087     * implementation like <code>FilePermission</code>,
088     * <code>SecurityPermission</code> etc.
089     */
090    public ISPolicy() {
091        super();
092        defaultPolicy = java.security.Policy.getPolicy();
093        debug.message("ISPolicy:: ISPolicy() called");
094    }
095        
096    /**
097     * Evaluates the global policy and returns a
098     * <code>PermissionCollection</code> object specifying the set of
099     * permissions allowed for Principals associated with the enclosed
100     * set of classes. Here we always return the 
101     * <code>PermissionCollection</code> after
102     * adding the<code>ISPermission</code> object into it, so that policy
103     * determination is also based on OpenAM's policies.
104     *
105     * @param protectionDomain  the protection domain which encapsulates the 
106     *        characteristics of a domain, which encloses the set of classes 
107     *        whose  instances are granted the permissions when being executed 
108     *        on behalf of the given set of Principals.
109     *
110     * @return the Collection of permissions allowed for the protection
111     *        domain according to the policy.
112     *
113     * @exception java.lang.SecurityException if the current thread does not
114     * have permission to call <code>getPermissions</code> on the policy object.
115     */
116    public PermissionCollection getPermissions(ProtectionDomain 
117        protectionDomain)  
118    {
119        debug.message("ISPolicy:: Calling getPermissions");
120        if (debug.messageEnabled()) {
121            debug.message("ISPolicy:: protectionDomain="
122                +protectionDomain.toString());
123        }
124        PermissionCollection pc;
125        pc = defaultPolicy.getPermissions(protectionDomain);
126        
127        // add the ISPermission into the PermissionCollection
128        // returned by the default policy.
129        pc.add(new ISPermission(protectionDomain));
130        if (debug.messageEnabled()) {
131            debug.message("ISPolicy:getPermissions::pc.elements()");
132            for (Enumeration e = pc.elements(); e.hasMoreElements();) {
133                debug.message(e.nextElement().toString()+"\n");
134            }
135        }
136        return pc;
137    }
138
139    /**
140     * Evaluates the global policy and returns a
141     * <code>PermissionCollection</code> object specifying the set of
142     * permissions allowed for Principals associated with the specified code
143     * source. Here we always return the <code>PermissionCollection</code> 
144     * after adding the<code>ISPermission</code> object into it, so that policy
145     * determination is also based on OpenAM's policies.
146     *
147     * @param codesource the <code>CodeSource</code> associated with the caller.
148     * This encapsulates the original location of the code (where the code 
149     * came from) and the public key(s) of its signer.This parameter may 
150     * be null.
151
152     * @return the Collection of permissions allowed for the code
153     *         from <code>codesource</code> according to the policy.
154     *
155     * @exception java.lang.SecurityException if the current thread does not
156     * have permission to call <code>getPermissions</code> on the policy object.
157     */
158    public PermissionCollection getPermissions(CodeSource codesource) { 
159        debug.message("ISPolicy:: Calling getPermissions");
160        if (debug.messageEnabled()) {
161            debug.message("ISPolicy:: codesource's URL="
162                +codesource.getLocation().toString());
163        }
164        PermissionCollection pc;
165        pc = defaultPolicy.getPermissions(codesource);
166        
167        // add the ISPermission into the PermissionCollection
168        // returned by the default policy.
169        pc.add(new ISPermission(codesource));
170        if (debug.messageEnabled()) {
171            debug.message("ISPolicy:getPermissions::pc.elements()");
172            for (Enumeration e = pc.elements(); e.hasMoreElements();) {
173                debug.message(e.nextElement().toString()+"\n");
174            }
175        }
176        return pc;
177    }
178
179    /**
180     * Refreshes/reloads the policy configuration. The behavior of this method
181     * depends on the implementation. In this implementation we will call 
182     * refresh on the <code>defaultPolicy</code> we saved in the
183     * <code>ISPolicy</code> constructor.
184     *
185     * @exception java.lang.SecurityException if the current thread does not
186     *            have permission to refresh this Policy object.
187     */
188    public void refresh() {
189        defaultPolicy.refresh();
190        debug.message("ISPolicy:: Calling refresh");
191    }
192}