KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > security > ProtectionDomain


1 /*
2  * @(#)ProtectionDomain.java 1.45 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7  
8 package java.security;
9
10 import java.util.Enumeration JavaDoc;
11 import java.util.List JavaDoc;
12 import java.util.ArrayList JavaDoc;
13 import sun.security.util.Debug;
14 import sun.security.util.SecurityConstants;
15
16 /**
17  *
18  *<p>
19  * This ProtectionDomain class encapsulates the characteristics of a domain,
20  * which encloses a set of classes whose instances are granted a set
21  * of permissions when being executed on behalf of a given set of Principals.
22  * <p>
23  * A static set of permissions can be bound to a ProtectionDomain when it is
24  * constructed; such permissions are granted to the domain regardless of the
25  * Policy in force. However, to support dynamic security policies, a
26  * ProtectionDomain can also be constructed such that it is dynamically
27  * mapped to a set of permissions by the current Policy whenever a permission
28  * is checked.
29  * <p>
30  *
31  * @version 1.45, 12/19/03
32  * @author Li Gong
33  * @author Roland Schemers
34  * @author Gary Ellison
35  */

36
37 public class ProtectionDomain {
38
39     /* CodeSource */
40     private CodeSource JavaDoc codesource ;
41
42     /* ClassLoader the protection domain was consed from */
43     private ClassLoader JavaDoc classloader;
44
45     /* Principals running-as within this protection domain */
46     private Principal JavaDoc[] principals;
47
48     /* the rights this protection domain is granted */
49     private PermissionCollection JavaDoc permissions;
50
51     /* the PermissionCollection is static (pre 1.4 constructor)
52        or dynamic (via a policy refresh) */

53     private boolean staticPermissions;
54
55     private static final Debug debug = Debug.getInstance("domain");
56
57     /**
58      * Creates a new ProtectionDomain with the given CodeSource and
59      * Permissions. If the permissions object is not null, then
60      * <code>setReadOnly())</code> will be called on the passed in
61      * Permissions object. The only permissions granted to this domain
62      * are the ones specified; the current Policy will not be consulted.
63      *
64      * @param codesource the codesource associated with this domain
65      * @param permissions the permissions granted to this domain
66      */

67     public ProtectionDomain(CodeSource JavaDoc codesource,
68                 PermissionCollection JavaDoc permissions) {
69     this.codesource = codesource;
70     if (permissions != null) {
71         this.permissions = permissions;
72         this.permissions.setReadOnly();
73     }
74     this.classloader = null;
75     this.principals = new Principal JavaDoc[0];
76     staticPermissions = true;
77     }
78
79     /**
80      * Creates a new ProtectionDomain qualified by the given CodeSource,
81      * Permissions, ClassLoader and array of Principals. If the
82      * permissions object is not null, then <code>setReadOnly()</code>
83      * will be called on the passed in Permissions object.
84      * The permissions granted to this domain are dynamic; they include
85      * both the static permissions passed to this constructor, and any
86      * permissions granted to this domain by the current Policy at the
87      * time a permission is checked.
88      * <p>
89      * This constructor is typically used by
90      * {@link SecureClassLoader ClassLoaders}
91      * and {@link DomainCombiner DomainCombiners} which delegate to
92      * <code>Policy</code> to actively associate the permissions granted to
93      * this domain. This constructor affords the
94      * Policy provider the opportunity to augment the supplied
95      * PermissionCollection to reflect policy changes.
96      * <p>
97      *
98      * @param codesource the CodeSource associated with this domain
99      * @param permissions the permissions granted to this domain
100      * @param classloader the ClassLoader associated with this domain
101      * @param principals the array of Principals associated with this
102      * domain. The contents of the array are copied to protect against
103      * subsequent modification.
104      * @see Policy#refresh
105      * @see Policy#getPermissions(ProtectionDomain)
106      * @since 1.4
107      */

108     public ProtectionDomain(CodeSource JavaDoc codesource,
109                 PermissionCollection JavaDoc permissions,
110                 ClassLoader JavaDoc classloader,
111                 Principal JavaDoc[] principals) {
112     this.codesource = codesource;
113     if (permissions != null) {
114         this.permissions = permissions;
115         this.permissions.setReadOnly();
116     }
117     this.classloader = classloader;
118     this.principals = (principals != null ?
119                (Principal JavaDoc[])principals.clone():
120                new Principal JavaDoc[0]);
121     staticPermissions = false;
122     }
123
124     /**
125      * Returns the CodeSource of this domain.
126      * @return the CodeSource of this domain which may be null.
127      * @since 1.2
128      */

129     public final CodeSource JavaDoc getCodeSource() {
130     return this.codesource;
131     }
132
133
134     /**
135      * Returns the ClassLoader of this domain.
136      * @return the ClassLoader of this domain which may be null.
137      *
138      * @since 1.4
139      */

140     public final ClassLoader JavaDoc getClassLoader() {
141     return this.classloader;
142     }
143
144
145     /**
146      * Returns an array of principals for this domain.
147      * @return a non-null array of principals for this domain.
148      * Returns a new array each time this method is called.
149      *
150      * @since 1.4
151      */

152     public final Principal JavaDoc[] getPrincipals() {
153     return (Principal JavaDoc[])this.principals.clone();
154     }
155
156     /**
157      * Returns the static permissions granted to this domain.
158      *
159      * @return the static set of permissions for this domain which may be null.
160      * @see Policy#refresh
161      * @see Policy#getPermissions(ProtectionDomain)
162      */

163     public final PermissionCollection JavaDoc getPermissions() {
164     return permissions;
165     }
166
167     /**
168      * Check and see if this ProtectionDomain implies the permissions
169      * expressed in the Permission object.
170      * <p>
171      * The set of permissions evaluated is a function of whether the
172      * ProtectionDomain was constructed with a static set of permissions
173      * or it was bound to a dynamically mapped set of permissions.
174      * <p>
175      * If the ProtectionDomain was constructed to a
176      * {@link #ProtectionDomain(CodeSource, PermissionCollection)
177      * statically bound} PermissionCollection then the permission will
178      * only be checked against the PermissionCollection supplied at
179      * construction.
180      * <p>
181      * However, if the ProtectionDomain was constructed with
182      * the constructor variant which supports
183      * {@link #ProtectionDomain(CodeSource, PermissionCollection,
184      * ClassLoader, java.security.Principal[]) dynamically binding}
185      * permissions, then the permission will be checked against the
186      * combination of the PermissionCollection supplied at construction and
187      * the current Policy binding.
188      * <p>
189      *
190      * @param permission the Permission object to check.
191      *
192      * @return true if "permission" is implicit to this ProtectionDomain.
193      */

194     public boolean implies(Permission JavaDoc permission) {
195     if (!staticPermissions &&
196         Policy.getPolicyNoCheck().implies(this, permission))
197         return true;
198     if (permissions != null)
199         return permissions.implies(permission);
200
201     return false;
202     }
203
204     /**
205      * Convert a ProtectionDomain to a String.
206      */

207     public String JavaDoc toString() {
208     String JavaDoc pals = "<no principals>";
209     if (principals != null && principals.length > 0) {
210         StringBuilder JavaDoc palBuf = new StringBuilder JavaDoc("(principals ");
211         
212         for (int i = 0; i < principals.length; i++) {
213         palBuf.append(principals[i].getClass().getName() +
214                 " \"" + principals[i].getName() +
215                 "\"");
216         if (i < principals.length-1)
217             palBuf.append(",\n");
218         else
219             palBuf.append(")\n");
220         }
221         pals = palBuf.toString();
222     }
223
224     // Check if policy is set; we don't want to load
225
// the policy prematurely here
226
PermissionCollection JavaDoc pc = Policy.isSet() && seeAllp() ?
227                       mergePermissions():
228                                   getPermissions();
229
230     return "ProtectionDomain "+
231         " "+codesource+"\n"+
232         " "+classloader+"\n"+
233         " "+pals+"\n"+
234         " "+pc+"\n";
235     }
236
237     /**
238      * Return true (merge policy permissions) in the following cases:
239      *
240      * . SecurityManager is null
241      *
242      * . SecurityManager is not null,
243      * debug is not null,
244      * SecurityManager impelmentation is in bootclasspath,
245      * Policy implementation is in bootclasspath
246      * (the bootclasspath restrictions avoid recursion)
247      *
248      * . SecurityManager is not null,
249      * debug is null,
250      * caller has Policy.getPolicy permission
251      */

252     private static boolean seeAllp() {
253     SecurityManager JavaDoc sm = System.getSecurityManager();
254
255     if (sm == null) {
256         return true;
257     } else {
258         if (debug != null) {
259         if (sm.getClass().getClassLoader() == null &&
260             Policy.getPolicyNoCheck().getClass().getClassLoader()
261                                 == null) {
262             return true;
263         }
264         } else {
265         try {
266             sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION);
267             return true;
268         } catch (SecurityException JavaDoc se) {
269             // fall thru and return false
270
}
271         }
272     }
273
274     return false;
275     }
276
277     private PermissionCollection JavaDoc mergePermissions() {
278     if (staticPermissions)
279         return permissions;
280     
281         PermissionCollection JavaDoc perms = (PermissionCollection JavaDoc)
282             java.security.AccessController.doPrivileged
283             (new java.security.PrivilegedAction JavaDoc() {
284                     public Object JavaDoc run() {
285                         Policy JavaDoc p = Policy.getPolicyNoCheck();
286                         return p.getPermissions(ProtectionDomain.this);
287                     }
288                 });
289     
290     Permissions JavaDoc mergedPerms = new Permissions JavaDoc();
291     int swag = 32;
292     int vcap = 8;
293     Enumeration JavaDoc e;
294     List JavaDoc pdVector = new ArrayList JavaDoc(vcap);
295     List JavaDoc plVector = new ArrayList JavaDoc(swag);
296             
297     //
298
// Build a vector of domain permissions for subsequent merge
299
if (permissions != null) {
300         synchronized (permissions) {
301         e = permissions.elements();
302         while (e.hasMoreElements()) {
303             Permission JavaDoc p = (Permission JavaDoc)e.nextElement();
304             pdVector.add(p);
305         }
306         }
307     }
308
309     //
310
// Build a vector of Policy permissions for subsequent merge
311
if (perms != null) {
312         synchronized (perms) {
313         e = perms.elements();
314         while (e.hasMoreElements()) {
315             plVector.add(e.nextElement());
316             vcap++;
317         }
318         }
319     }
320
321     if (perms != null && permissions != null) {
322         //
323
// Weed out the duplicates from the policy. Unless a refresh
324
// has occured since the pd was consed this should result in
325
// an empty vector.
326
synchronized (permissions) {
327         e = permissions.elements(); // domain vs policy
328
while (e.hasMoreElements()) {
329             Permission JavaDoc pdp = (Permission JavaDoc)e.nextElement();
330             Class JavaDoc pdpClass = pdp.getClass();
331             String JavaDoc pdpActions = pdp.getActions();
332             String JavaDoc pdpName = pdp.getName();
333             for (int i = 0; i < plVector.size(); i++) {
334             Permission JavaDoc pp = (Permission JavaDoc) plVector.get(i);
335             if (pdpClass.isInstance(pp)) {
336                 // The equals() method on some permissions
337
// have some side effects so this manual
338
// comparison is sufficient.
339
if (pdpName.equals(pp.getName()) &&
340                 pdpActions.equals(pp.getActions())) {
341                 plVector.remove(i);
342                 break;
343                 }
344             }
345             }
346         }
347         }
348     }
349                 
350     if (perms !=null) {
351         // the order of adding to merged perms and permissions
352
// needs to preserve the bugfix 4301064
353

354         for (int i = plVector.size()-1; i >= 0; i--) {
355         mergedPerms.add((Permission JavaDoc)plVector.get(i));
356         }
357     }
358     if (permissions != null) {
359         for (int i = pdVector.size()-1; i >= 0; i--) {
360         mergedPerms.add((Permission JavaDoc)pdVector.get(i));
361         }
362     }
363
364     return mergedPerms;
365     }
366 }
367
Popular Tags