KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas_lib > security > jacc > JPolicy


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 2004-2005 Bull S.A.
4  * Contact: jonas-team@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,v 1.9 2005/05/03 12:55:05 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas_lib.security.jacc;
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.common.TraceCore;
47
48 import org.objectweb.jonas_lib.I18n;
49
50 import org.objectweb.util.monolog.api.BasicLevel;
51 import org.objectweb.util.monolog.api.Logger;
52
53 /**
54  * Defines the "delegating Policy provider" / JACC 2.5
55  * In J2SE 1.4 new methods can be used for dynamic permissions
56  * implies() and getPermissions() methods on Policy class were added.
57  *
58  * A replacement Policy object may accomplish this by delegating
59  * non-javax.security.jacc policy decisions to the corresponding
60  * default system Policy implementation class. A replacement
61  * Policy object that relies in this way on the corresponding
62  * default Policy implementation class must identify itself in
63  * its installation instructions as a "delegating Policy provider"
64  *
65  * JOnAS uses delegating model
66  * @author Florent Benoit
67  */

68 public class JPolicy extends Policy JavaDoc {
69
70     /**
71      * Logger
72      */

73     private static Logger logger = null;
74
75     /**
76      * Unique instance of JPolicy
77      */

78     private static JPolicy unique = null;
79
80     /**
81      * Bootstrap Policy provider use for delegating non-jacc decisions
82      */

83     private static Policy JavaDoc initialPolicy = null;
84
85     /**
86      * I18n
87      */

88     private static I18n i18n = I18n.getInstance(JPolicy.class);
89
90     /**
91      * Reference to the JOnAS PolicyConfigurationFactory
92      * Used for retrieve parameters with interfaces not
93      * in javax.security.jacc.PolicyConfigurationFactory
94      */

95     private static PolicyConfigurationFactory JavaDoc policyConfigurationFactory = null;
96
97
98     /**
99      * Constructor : build a policy which manage JACC permissions
100      * The non-jacc permissions are delegated to the initial Policy class
101      */

102     public JPolicy() {
103         // Retrieve existing policy
104
initialPolicy = Policy.getPolicy();
105
106         // init logger
107
logger = TraceCore.sec;
108     }
109
110     /**
111      * Init the PolicyConfiguration factory object used in Policy configuration
112      * @throws JPolicyException if some methods on PolicyConfigurationFactory fail
113      */

114     private void initPolicyConfigurationFactory() throws JPolicyException {
115         // Check that factory is the JOnAS policy configuration factory
116
try {
117             policyConfigurationFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
118         } catch (ClassNotFoundException JavaDoc cnfe) {
119             throw new JPolicyException("PolicyConfigurationFactory class implementation was not found : '" + cnfe.getMessage() + "'.");
120         } catch (PolicyContextException JavaDoc pce) {
121             throw new JPolicyException("PolicyContextException in PolicyConfigurationFactory : '" + pce.getMessage() + "'.");
122         }
123
124     }
125
126
127     /**
128      * Gets the unique instance of the JACC delegating policy provider
129      * @return unique instance of the JACC delegating policy provider
130      */

131     public static JPolicy getInstance() {
132         if (unique == null) {
133             unique = new JPolicy();
134         }
135         return unique;
136     }
137
138
139
140     // Section 4.8
141
// J2EE 1.4 container can call Policy.implies or Policy.getPermissions
142
// with an argument ProtectionDomain that was constructed with the
143
// principals of the caller.
144
// Then the caller must call implies method on the returned PermissionCollection
145

146
147     /**
148      * Evaluates the global policy for the permissions granted
149      * to the ProtectionDomain and tests whether the permission is granted.
150      * @param domain the ProtectionDomain to test.
151      * @param permission the Permission object to be tested for implication.
152      * @return true if "permission" is a proper subset of a permission
153      * granted to this ProtectionDomain.
154      */

155     public boolean implies(ProtectionDomain JavaDoc domain, Permission JavaDoc permission) {
156         // See 2.5 of JACC. A replacement Policy object may accomplish this
157
// by delegating non-javax.security.jacc policy decisions to the
158
// corresponding default system Policy implementation class.
159

160         if (permission instanceof RuntimePermission JavaDoc || permission instanceof SocketPermission JavaDoc) {
161             return initialPolicy.implies(domain, permission);
162         }
163
164
165         // check with context ID
166
String JavaDoc contextID = PolicyContext.getContextID();
167         // No context, use existing
168
if (contextID == null) {
169             return initialPolicy.implies(domain, permission);
170         }
171
172         if (!(permission instanceof EJBMethodPermission JavaDoc || permission instanceof EJBRoleRefPermission JavaDoc
173               || permission instanceof WebUserDataPermission JavaDoc || permission instanceof WebRoleRefPermission JavaDoc
174               || permission instanceof WebResourcePermission JavaDoc)) {
175             return initialPolicy.implies(domain, permission);
176         }
177
178
179
180
181         if (logger.isLoggable(BasicLevel.DEBUG)) {
182             logger.log(BasicLevel.DEBUG, "!= null, Permission being checked = " + permission);
183         }
184
185         // configuration was committed ?
186
try {
187             if (policyConfigurationFactory == null) {
188                 initPolicyConfigurationFactory();
189             }
190
191             if (!policyConfigurationFactory.inService(contextID)) {
192                 if (logger.isLoggable(BasicLevel.DEBUG)) {
193                     logger.log(BasicLevel.DEBUG, "Not in service, return false");
194                 }
195                 return false;
196             }
197         } catch (JPolicyException jpe) {
198             if (logger.isLoggable(BasicLevel.ERROR)) {
199                 logger.log(BasicLevel.ERROR, i18n.getMessage("JPolicy.implies.canNotCheck", jpe.getMessage()));
200             }
201             return false;
202         } catch (PolicyContextException JavaDoc pce) {
203             if (logger.isLoggable(BasicLevel.ERROR)) {
204                 logger.log(BasicLevel.ERROR, i18n.getMessage("JPolicy.implies.canNotCheck", pce.getMessage()));
205             }
206             return false;
207         }
208
209         JPolicyConfiguration jPolicyConfiguration = null;
210         try {
211             PolicyConfiguration JavaDoc pc = policyConfigurationFactory.getPolicyConfiguration(contextID, false);
212             if (pc instanceof JPolicyConfiguration) {
213                 jPolicyConfiguration = (JPolicyConfiguration) pc;
214             } else {
215                 //Maybe it's a delegating policy configuration and we have a configuration for this object
216
jPolicyConfiguration = JPolicyConfigurationKeeper.getConfiguration(contextID);
217                 if (jPolicyConfiguration == null) {
218                     throw new RuntimeException JavaDoc("This policy provider can only manage JPolicyConfiguration objects");
219                 }
220             }
221         } catch (PolicyContextException JavaDoc pce) {
222             if (logger.isLoggable(BasicLevel.ERROR)) {
223                 logger.log(BasicLevel.ERROR, i18n.getMessage("JPolicy.implies.canNotRetrieve", contextID, pce.getMessage()));
224             }
225             return false;
226         }
227
228         /* JACC 3.2
229            The provider must ensure that excluded policy statements take precedence
230            over overlapping unchecked policy statements, and that both excluded and
231            unchecked policy statements take precedence over overlapping role based policy
232            statements.
233         */

234         PermissionCollection JavaDoc excludedPermissions = jPolicyConfiguration.getExcludedPermissions();
235         PermissionCollection JavaDoc uncheckedPermissions = jPolicyConfiguration.getUncheckedPermissions();
236
237         if (logger.isLoggable(BasicLevel.DEBUG)) {
238             logger.log(BasicLevel.DEBUG, "Check permission");
239             logger.log(BasicLevel.DEBUG, "Excluded permissions = " + excludedPermissions);
240             logger.log(BasicLevel.DEBUG, "unchecked permissions = " + uncheckedPermissions);
241         }
242
243         // excluded ?
244
if (excludedPermissions.implies(permission)) {
245             if (logger.isLoggable(BasicLevel.DEBUG)) {
246                 logger.log(BasicLevel.DEBUG, "Permission '" + permission + "' is excluded, return false");
247             }
248             return false;
249         } else if (uncheckedPermissions.implies(permission)) { // unchecked
250
if (logger.isLoggable(BasicLevel.DEBUG)) {
251                 logger.log(BasicLevel.DEBUG, "Permission '" + permission + "' is unchecked, return true");
252             }
253             return true;
254         } else {
255             // per role if any or false
256
if (domain.getPrincipals().length > 0) {
257                 if (logger.isLoggable(BasicLevel.DEBUG)) {
258                     logger.log(BasicLevel.DEBUG, "There are principals, checking principals...");
259                 }
260                 // check roles
261
return isImpliedPermissionForPrincipals(jPolicyConfiguration, permission, domain.getPrincipals());
262             } else {
263                 if (logger.isLoggable(BasicLevel.DEBUG)) {
264                     logger.log(BasicLevel.DEBUG, "Principals length = 0, there is no principal on this domain");
265                 }
266                 // permission not found
267
if (logger.isLoggable(BasicLevel.DEBUG)) {
268                     logger.log(BasicLevel.DEBUG, "Permission '" + permission + "' not found, return false");
269                 }
270                 return false;
271             }
272         }
273     }
274
275
276     /**
277      * Evaluates the global policy and returns a PermissionCollection
278      * object specifying the set of permissions allowed given the
279      * characteristics of the protection domain.
280      * @param domain the ProtectionDomain associated with the caller.
281      * @return the set of permissions allowed for the domain according
282      * to the policy.The returned set of permissions must be a
283      * new mutable instance and it must support heterogeneous
284      * Permission types.
285      */

286     public PermissionCollection JavaDoc getPermissions(ProtectionDomain JavaDoc domain) {
287
288          // Always use delegating model
289
return initialPolicy.getPermissions(domain);
290
291         //TODO : retrieve all permissions for a given ProtectionDomain
292
//JPolicyConfiguration jPolicyConfiguration = policyConfigurationFactory.getPolicyConfiguration(contextID);
293
//return jPolicyConfiguration.getPermissionsForDomain(domain);
294
// String contextID = PolicyContext.getContextID();
295
// // Delegating model
296
// if (contextID == null) {
297
// return initialPolicy.getPermissions(domain);
298
// } else {
299
// // not implemented as not recommended in section 4.8
300
// throw new UnsupportedOperationException("Method getPermissions with a given protection domain is not supported");
301
// }
302

303     }
304
305
306     /**
307      * Evaluates the global policy and returns a PermissionCollection
308      * object specifying the set of permissions allowed for code from
309      * the specified code source.
310      * @param codeSource the CodeSource associated with the caller.
311      * This encapsulates the original location of the code
312      * (where the code came from) and the public key(s)
313      * of its signer.
314      * @return the set of permissions allowed for code from
315      * codesource according to the policy.The returned
316      * set of permissions must be a new mutable instance
317      * and it must support heterogeneous Permission types.
318      */

319     public PermissionCollection JavaDoc getPermissions(CodeSource JavaDoc codeSource) {
320
321         // Always use delegating model
322
return initialPolicy.getPermissions(codeSource);
323
324         //TODO : retrieve all permissions for a given codesource
325
// String contextID = PolicyContext.getContextID();
326
// if (contextID == null) {
327
// return initialPolicy.getPermissions(codeSource);
328
// } else {
329
// // not implemented
330
// throw new UnsupportedOperationException("Method getPermissions with a given codeSource is not implemented");
331
// }
332
}
333
334
335     /**
336      * Refreshes/reloads the policy configuration.
337      */

338     public void refresh() {
339         initialPolicy.refresh();
340     }
341
342
343
344     /**
345      * Check for each principal permission if the given permission is implied
346      * @param jPolicyConfiguration JOnAS JACC PolicyConfiguration object
347      * @param permission the permission to check
348      * @param principals the array of principals on which we must retrieve permissions
349      * @return true if the given permission is implied by a role's permission
350      */

351     private boolean isImpliedPermissionForPrincipals(JPolicyConfiguration jPolicyConfiguration, Permission JavaDoc permission, Principal JavaDoc[] principals) {
352         //if (logger.isLoggable(BasicLevel.DEBUG)) {
353
// logger.log(BasicLevel.DEBUG, "");
354
//}
355
PermissionCollection JavaDoc permissions = null;
356         int i = 0;
357         boolean implied = false;
358         // for each principal's permissions check if the given permission is implied
359
while (i < principals.length && !implied) {
360             if (logger.isLoggable(BasicLevel.DEBUG)) {
361                 logger.log(BasicLevel.DEBUG, "Checking permission '" + permission + "' with permissions of Principal '" + principals[i].getName() + "'.");
362             }
363             permissions = jPolicyConfiguration.getPermissionsForPrincipal(principals[i]);
364
365             if (permissions.implies(permission)) {
366                 if (logger.isLoggable(BasicLevel.DEBUG)) {
367                     logger.log(BasicLevel.DEBUG, "Permission implied with principal '" + principals[i].getName() + "'.");
368                 }
369                 implied = true;
370             }
371             i++;
372         }
373         if (logger.isLoggable(BasicLevel.DEBUG)) {
374             if (!implied) {
375                 logger.log(BasicLevel.DEBUG, "Permission '" + permission + "' was not found in each permissions of the given roles, return false");
376             }
377         }
378         return implied;
379     }
380
381 }
382
383
Popular Tags