KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > security > jacc > provider > JPolicy


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: JPolicy.java 1154 2006-10-16 12:43:47Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.security.jacc.provider;
27
28 import java.net.SocketPermission JavaDoc;
29 import java.security.CodeSource JavaDoc;
30 import java.security.Permission JavaDoc;
31 import java.security.PermissionCollection JavaDoc;
32 import java.security.Policy JavaDoc;
33 import java.security.Principal JavaDoc;
34 import java.security.ProtectionDomain JavaDoc;
35
36 import javax.security.jacc.EJBMethodPermission JavaDoc;
37 import javax.security.jacc.EJBRoleRefPermission JavaDoc;
38 import javax.security.jacc.PolicyConfiguration JavaDoc;
39 import javax.security.jacc.PolicyConfigurationFactory JavaDoc;
40 import javax.security.jacc.PolicyContext JavaDoc;
41 import javax.security.jacc.PolicyContextException JavaDoc;
42 import javax.security.jacc.WebResourcePermission JavaDoc;
43 import javax.security.jacc.WebRoleRefPermission JavaDoc;
44 import javax.security.jacc.WebUserDataPermission JavaDoc;
45
46 import org.objectweb.easybeans.log.JLog;
47 import org.objectweb.easybeans.log.JLogFactory;
48
49 /**
50  * Defines the "delegating Policy provider" / JACC 2.5 In J2SE 1.4 new methods
51  * can be used for dynamic permissions implies() and getPermissions() methods on
52  * Policy class were added. A replacement Policy object may accomplish this by
53  * delegating non-javax.security.jacc policy decisions to the corresponding
54  * default system Policy implementation class. A replacement Policy object that
55  * relies in this way on the corresponding default Policy implementation class
56  * must identify itself in its installation instructions as a "delegating Policy
57  * provider"<br>
58  * EasyBeans uses delegating model
59  * @author Florent Benoit
60  */

61 public class JPolicy extends Policy JavaDoc {
62
63     /**
64      * Logger.
65      */

66     private static JLog logger = JLogFactory.getLog(JPolicy.class);
67
68     /**
69      * Unique instance of JPolicy.
70      */

71     private static JPolicy unique = null;
72
73     /**
74      * Bootstrap Policy provider use for delegating non-jacc decisions.
75      */

76     private static Policy JavaDoc initialPolicy = null;
77
78     /**
79      * Reference to the EasyBeans PolicyConfigurationFactory. Used for retrieve
80      * parameters with interfaces not in
81      * javax.security.jacc.PolicyConfigurationFactory
82      */

83     private static PolicyConfigurationFactory JavaDoc policyConfigurationFactory = null;
84
85     /**
86      * Constructor : build a policy which manage JACC permissions. The non-jacc
87      * permissions are delegated to the initial Policy class
88      */

89     public JPolicy() {
90         // Retrieve existing policy
91
initialPolicy = Policy.getPolicy();
92
93     }
94
95     /**
96      * Init the PolicyConfiguration factory object used in Policy configuration.
97      * @throws JPolicyException if some methods on PolicyConfigurationFactory
98      * fail
99      */

100     private void initPolicyConfigurationFactory() throws JPolicyException {
101         // Check that factory is the EasyBeans policy configuration factory
102
try {
103             policyConfigurationFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
104         } catch (ClassNotFoundException JavaDoc cnfe) {
105             throw new JPolicyException("PolicyConfigurationFactory class implementation was not found", cnfe);
106         } catch (PolicyContextException JavaDoc pce) {
107             throw new JPolicyException("PolicyContextException in PolicyConfigurationFactory", pce);
108         }
109
110     }
111
112     /**
113      * Gets the unique instance of the JACC delegating policy provider.
114      * @return unique instance of the JACC delegating policy provider
115      */

116     public static JPolicy getInstance() {
117         if (unique == null) {
118             unique = new JPolicy();
119         }
120         return unique;
121     }
122
123     // Section 4.8
124
// J2EE 1.4 container can call Policy.implies or Policy.getPermissions
125
// with an argument ProtectionDomain that was constructed with the
126
// principals of the caller.
127
// Then the caller must call implies method on the returned
128
// PermissionCollection
129

130     /**
131      * Evaluates the global policy for the permissions granted to the
132      * ProtectionDomain and tests whether the permission is granted.
133      * @param domain the ProtectionDomain to test.
134      * @param permission the Permission object to be tested for implication.
135      * @return true if "permission" is a proper subset of a permission granted
136      * to this ProtectionDomain.
137      */

138     @Override JavaDoc
139     public boolean implies(final ProtectionDomain JavaDoc domain, final Permission JavaDoc permission) {
140         // See 2.5 of JACC. A replacement Policy object may accomplish this
141
// by delegating non-javax.security.jacc policy decisions to the
142
// corresponding default system Policy implementation class.
143

144         if (permission instanceof RuntimePermission JavaDoc || permission instanceof SocketPermission JavaDoc) {
145             return initialPolicy.implies(domain, permission);
146         }
147
148         // check with context ID
149
String JavaDoc contextID = PolicyContext.getContextID();
150         // No context, use existing
151
if (contextID == null) {
152             return initialPolicy.implies(domain, permission);
153         }
154
155         if (!(permission instanceof EJBMethodPermission JavaDoc || permission instanceof EJBRoleRefPermission JavaDoc
156                 || permission instanceof WebUserDataPermission JavaDoc || permission instanceof WebRoleRefPermission JavaDoc
157                 || permission instanceof WebResourcePermission JavaDoc)) {
158             return initialPolicy.implies(domain, permission);
159         }
160
161         logger.debug("Permission being checked = ''{0}''", permission);
162
163         // configuration was committed ?
164
try {
165             if (policyConfigurationFactory == null) {
166                 initPolicyConfigurationFactory();
167             }
168
169             if (!policyConfigurationFactory.inService(contextID)) {
170                 logger.debug("Policy configuration factory not in service, return false");
171                 return false;
172             }
173         } catch (JPolicyException jpe) {
174             logger.error("JPolicy.implies.canNotCheck", jpe);
175             return false;
176         } catch (PolicyContextException JavaDoc pce) {
177             logger.error("JPolicy.implies.canNotCheck", pce);
178             return false;
179         }
180
181         JPolicyConfiguration jPolicyConfiguration = null;
182         try {
183             PolicyConfiguration JavaDoc pc = policyConfigurationFactory.getPolicyConfiguration(contextID, false);
184             if (pc instanceof JPolicyConfiguration) {
185                 jPolicyConfiguration = (JPolicyConfiguration) pc;
186             } else {
187                 // Maybe it's a delegating policy configuration and we have a
188
// configuration for this object
189
jPolicyConfiguration = JPolicyConfigurationKeeper.getConfiguration(contextID);
190                 if (jPolicyConfiguration == null) {
191                     throw new RuntimeException JavaDoc("This policy provider can only manage JPolicyConfiguration objects");
192                 }
193             }
194         } catch (PolicyContextException JavaDoc pce) {
195             logger.error("JPolicy.implies.canNotRetrieve", contextID, pce);
196             return false;
197         }
198
199         /*
200          * JACC 3.2 The provider must ensure that excluded policy statements
201          * take precedence over overlapping unchecked policy statements, and
202          * that both excluded and unchecked policy statements take precedence
203          * over overlapping role based policy statements.
204          */

205         PermissionCollection JavaDoc excludedPermissions = jPolicyConfiguration.getExcludedPermissions();
206         PermissionCollection JavaDoc uncheckedPermissions = jPolicyConfiguration.getUncheckedPermissions();
207
208         // debug info.
209
if (logger.isDebugEnabled()) {
210             logger.debug("Check permission");
211             logger.debug("Excluded permissions = " + excludedPermissions);
212             logger.debug("unchecked permissions = " + uncheckedPermissions);
213         }
214
215         // excluded ?
216
if (excludedPermissions.implies(permission)) {
217             logger.debug("Permission ''{0}'' is excluded, return false", permission);
218             return false;
219         } else if (uncheckedPermissions.implies(permission)) { // unchecked
220
logger.debug("Permission ''{0}'' is unchecked, return true", permission);
221             return true;
222         } else {
223             // per role if any or false
224
if (domain.getPrincipals().length > 0) {
225                 logger.debug("There are principals, checking principals...");
226                 // check roles
227
return isImpliedPermissionForPrincipals(jPolicyConfiguration, permission, domain.getPrincipals());
228             }
229             // permission not found
230
logger.debug("Principals length = 0, there is no principal on this domain");
231             logger.debug("Permission ''{0}'' not found, return false", permission);
232             return false;
233         }
234     }
235
236     /**
237      * Evaluates the global policy and returns a PermissionCollection object
238      * specifying the set of permissions allowed given the characteristics of
239      * the protection domain.
240      * @param domain the ProtectionDomain associated with the caller.
241      * @return the set of permissions allowed for the domain according to the
242      * policy.The returned set of permissions must be a new mutable
243      * instance and it must support heterogeneous Permission types.
244      */

245     @Override JavaDoc
246     public PermissionCollection JavaDoc getPermissions(final ProtectionDomain JavaDoc domain) {
247
248         // Always use delegating model
249
return initialPolicy.getPermissions(domain);
250     }
251
252     /**
253      * Evaluates the global policy and returns a PermissionCollection object
254      * specifying the set of permissions allowed for code from the specified
255      * code source.
256      * @param codeSource the CodeSource associated with the caller. This
257      * encapsulates the original location of the code (where the code
258      * came from) and the public key(s) of its signer.
259      * @return the set of permissions allowed for code from codesource according
260      * to the policy.The returned set of permissions must be a new
261      * mutable instance and it must support heterogeneous Permission
262      * types.
263      */

264     @Override JavaDoc
265     public PermissionCollection JavaDoc getPermissions(final CodeSource JavaDoc codeSource) {
266
267         // Always use delegating model
268
return initialPolicy.getPermissions(codeSource);
269     }
270
271     /**
272      * Refreshes/reloads the policy configuration.
273      */

274     @Override JavaDoc
275     public void refresh() {
276         initialPolicy.refresh();
277     }
278
279     /**
280      * Check for each principal permission if the given permission is implied.
281      * @param jPolicyConfiguration EasyBeans JACC PolicyConfiguration object
282      * @param permission the permission to check
283      * @param principals the array of principals on which we must retrieve
284      * permissions
285      * @return true if the given permission is implied by a role's permission
286      */

287     private boolean isImpliedPermissionForPrincipals(final JPolicyConfiguration jPolicyConfiguration,
288             final Permission JavaDoc permission, final Principal JavaDoc[] principals) {
289         // if (logger.isLoggable(BasicLevel.DEBUG)) {
290
// logger.log(BasicLevel.DEBUG, "");
291
// }
292
PermissionCollection JavaDoc permissions = null;
293         int i = 0;
294         boolean implied = false;
295         // for each principal's permissions check if the given permission is
296
// implied
297
while (i < principals.length && !implied) {
298             if (logger.isDebugEnabled()) {
299                 logger.debug("Checking permission ''{0}'' with permissions of Principal ''{1}''.", permission, principals[i]
300                         .getName());
301             }
302             permissions = jPolicyConfiguration.getPermissionsForPrincipal(principals[i]);
303
304             if (permissions.implies(permission)) {
305                 if (logger.isDebugEnabled()) {
306                     logger.debug("Permission implied with principal ''{0}''.", principals[i].getName());
307                 }
308                 implied = true;
309             }
310             i++;
311         }
312         if (!implied) {
313             logger.debug("Permission ''{0}'' was not found in each permissions of the given roles, return false", permission);
314         }
315         return implied;
316     }
317
318 }
319
Popular Tags