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 */
028/*
029 * Portions Copyrighted [2011] [ForgeRock AS]
030 */
031package com.sun.identity.policy.jaas;
032
033import com.sun.identity.shared.debug.Debug;
034
035import java.security.CodeSource;
036import java.security.PermissionCollection;
037import java.security.ProtectionDomain;
038import java.util.Enumeration;
039
040/**
041 * This is an implementation of abstract class
042 * <code>java.security.Policy</code> for representing the system security
043 * policy for a Java application environment. It provides a custom policy
044 * implementation based on JAAS and JDK 1.5 and above.It makes policy evaluation
045 * against the OpenSSO Policy Service instead of the default file
046 * based one.
047 *<p>
048 * It provides implementation of the abstract methods in Policy class.
049 * <p>In general the source location for the policy information utilized by the
050 * Policy object to make policy decisions is up to the Policy implementation.
051 * In the case of ISPolicy the source comes from the OpenSSO's policy
052 * store, which is consulted to make the policy evaluation.
053 * <p>A <code>Policy</code> object can be queried for the set of Permissions 
054 * granted to set of classes running as a <code>Principal</code> in the 
055 * following manner: 
056 * <pre>
057 *   policy = Policy.getPolicy();
058 *   PermissionCollection perms = policy.getPermissions(ProtectionDomain);
059 * </pre>
060 * The <code>Policy</code> object consults the local policy and returns the 
061 * appropriate <code>PermissionCollection</code> object
062 * {@link com.sun.identity.policy.jaas.ISPermissionCollection} containing
063 * the Permissions granted to the  Principals and granted to the set of classes
064 *  specified by the provided <code>protectionDomain</code>.
065 *
066 * <p>The currently-installed Policy object can be obtained by
067 * calling the <code>getPolicy</code> method, and it can be
068 * changed by a call to the <code>setPolicy</code> method (by
069 * code with permission to reset the Policy).
070 *
071 * <p>The <code>refresh</code> method causes the policy
072 * object to refresh/reload its current configuration.
073 *
074 * @see java.security.ProtectionDomain
075 * @see java.security.PermissionCollection
076 * @supported.all.api
077 */
078public class ISPolicy extends java.security.Policy {
079
080    private static java.security.Policy defaultPolicy = null;
081
082    static Debug debug = Debug.getInstance("amPolicy");
083
084    /**
085     * Constructs an <code>ISPolicy</code> instance.
086     * Save the existing global policy , so that we can use that
087     * for evaluating permissions we do not support through our custom policy 
088     * implementation like <code>FilePermission</code>,
089     * <code>SecurityPermission</code> etc.
090     */
091    public ISPolicy() {
092        super();
093        defaultPolicy = java.security.Policy.getPolicy();
094        debug.message("ISPolicy:: ISPolicy() called");
095    }
096        
097    /**
098     * Evaluates the global policy and returns a
099     * <code>PermissionCollection</code> object specifying the set of
100     * permissions allowed for Principals associated with the enclosed
101     * set of classes. Here we always return the 
102     * <code>PermissionCollection</code> after
103     * adding the<code>ISPermission</code> object into it, so that policy
104     * determination is also based on OpenSSO's policies.
105     *
106     * @param protectionDomain  the protection domain which encapsulates the 
107     *        characteristics of a domain, which encloses the set of classes 
108     *        whose  instances are granted the permissions when being executed 
109     *        on behalf of the given set of Principals.
110     *
111     * @return the Collection of permissions allowed for the protection
112     *        domain according to the policy.
113     *
114     * @exception java.lang.SecurityException if the current thread does not
115     * have permission to call <code>getPermissions</code> on the policy object.
116     */
117    public PermissionCollection getPermissions(ProtectionDomain 
118        protectionDomain)  
119    {
120        debug.message("ISPolicy:: Calling getPermissions");
121        if (debug.messageEnabled()) {
122            debug.message("ISPolicy:: protectionDomain="
123                +protectionDomain.toString());
124        }
125        PermissionCollection pc;
126        pc = defaultPolicy.getPermissions(protectionDomain);
127        
128        // add the ISPermission into the PermissionCollection
129        // returned by the default policy.
130        pc.add(new ISPermission(protectionDomain));
131        if (debug.messageEnabled()) {
132            debug.message("ISPolicy:getPermissions::pc.elements()");
133            for (Enumeration e = pc.elements(); e.hasMoreElements();) {
134                debug.message(e.nextElement().toString()+"\n");
135            }
136        }
137        return pc;
138    }
139
140    /**
141     * Evaluates the global policy and returns a
142     * <code>PermissionCollection</code> object specifying the set of
143     * permissions allowed for Principals associated with the specified code
144     * source. Here we always return the <code>PermissionCollection</code> 
145     * after adding the<code>ISPermission</code> object into it, so that policy
146     * determination is also based on OpenSSO's policies.
147     *
148     * @param codesource the <code>CodeSource</code> associated with the caller.
149     * This encapsulates the original location of the code (where the code 
150     * came from) and the public key(s) of its signer.This parameter may 
151     * be null.
152
153     * @return the Collection of permissions allowed for the code
154     *         from <code>codesource</code> according to the policy.
155     *
156     * @exception java.lang.SecurityException if the current thread does not
157     * have permission to call <code>getPermissions</code> on the policy object.
158     */
159    public PermissionCollection getPermissions(CodeSource codesource) { 
160        debug.message("ISPolicy:: Calling getPermissions");
161        if (debug.messageEnabled()) {
162            debug.message("ISPolicy:: codesource's URL="
163                +codesource.getLocation().toString());
164        }
165        PermissionCollection pc;
166        pc = defaultPolicy.getPermissions(codesource);
167        
168        // add the ISPermission into the PermissionCollection
169        // returned by the default policy.
170        pc.add(new ISPermission(codesource));
171        if (debug.messageEnabled()) {
172            debug.message("ISPolicy:getPermissions::pc.elements()");
173            for (Enumeration e = pc.elements(); e.hasMoreElements();) {
174                debug.message(e.nextElement().toString()+"\n");
175            }
176        }
177        return pc;
178    }
179
180    /**
181     * Refreshes/reloads the policy configuration. The behavior of this method
182     * depends on the implementation. In this implementation we will call 
183     * refresh on the <code>defaultPolicy</code> we saved in the
184     * <code>ISPolicy</code> constructor.
185     *
186     * @exception java.lang.SecurityException if the current thread does not
187     *            have permission to refresh this Policy object.
188     */
189    public void refresh() {
190        defaultPolicy.refresh();
191        debug.message("ISPolicy:: Calling refresh");
192    }
193}