1 /* ProtectionDomain.java -- A security domain
2    Copyright (C) 1998, 2003, 2004  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package java.security;
39 
40 import gnu.classpath.SystemProperties;
41 
42 import gnu.java.lang.CPStringBuilder;
43 
44 import java.util.Enumeration;
45 
46 /**
47  * This class represents a group of classes, along with their granted
48  * permissions. The classes are identified by a {@link CodeSource}. Thus, any
49  * class loaded from the specified {@link CodeSource} is treated as part of
50  * this domain. The set of permissions is represented by an instance of
51  * {@link PermissionCollection}.
52  *
53  * <p>Every class in the system will belong to one and only one
54  * <code>ProtectionDomain</code>.</p>
55  *
56  * @author Aaron M. Renn (arenn@urbanophile.com)
57  * @version 0.0
58  */
59 public class ProtectionDomain
60 {
61   /** This is the <code>CodeSource</code> for this protection domain. */
62   private CodeSource code_source;
63 
64   /** This is the set of permissions granted to this domain. */
65   private PermissionCollection perms;
66 
67   /** The {@link ClassLoader} associated with this domain. */
68   private ClassLoader classloader;
69 
70   /** The array of Principals associated with this domain.. */
71   private Principal[] principals;
72 
73   /** Post 1.4 the policy may be refreshed! use false for pre 1.4. */
74   private boolean staticBinding;
75 
76   /** True if this protection domain has all permissions */
77   private boolean hasAllPermissions;
78 
79   /**
80    * Initializes a new instance of <code>ProtectionDomain</code> representing
81    * the specified {@link CodeSource} and set of permissions. No permissions
82    * can be added later to the {@link PermissionCollection} and this contructor
83    * will call the <code>setReadOnly</code> method on the specified set of
84    * permissions.
85    *
86    * @param codesource
87    *          The {@link CodeSource} for this domain.
88    * @param permissions
89    *          The set of permissions for this domain.
90    * @see PermissionCollection#setReadOnly()
91    */
ProtectionDomain(CodeSource codesource, PermissionCollection permissions)92   public ProtectionDomain(CodeSource codesource, PermissionCollection permissions)
93   {
94     this(codesource, permissions, null, null, true);
95   }
96 
97   /**
98    * This method initializes a new instance of <code>ProtectionDomain</code>
99    * given its {@link CodeSource}, granted permissions, associated
100    * {@link ClassLoader} and {@link Principal}s.
101    *
102    * <p>Similar to the previous constructor, if the designated set of
103    * permissions is not <code>null</code>, the <code>setReadOnly</code> method
104    * is called on that set.</p>
105    *
106    * @param codesource
107    *          The {@link CodeSource} for this domain.
108    * @param permissions
109    *          The permission set for this domain.
110    * @param classloader
111    *          the ClassLoader associated with this domain.
112    * @param principals
113    *          the array of {@link Principal}s associated with this domain.
114    * @since 1.4
115    * @see PermissionCollection#setReadOnly()
116    */
ProtectionDomain(CodeSource codesource, PermissionCollection permissions, ClassLoader classloader, Principal[] principals)117   public ProtectionDomain(CodeSource codesource,
118                           PermissionCollection permissions,
119                           ClassLoader classloader, Principal[] principals)
120   {
121     this(codesource, permissions, classloader, principals, false);
122   }
123 
ProtectionDomain(CodeSource codesource, PermissionCollection permissions, ClassLoader classloader, Principal[] principals, boolean staticBinding)124   private ProtectionDomain(CodeSource codesource,
125                            PermissionCollection permissions,
126                            ClassLoader classloader, Principal[] principals,
127                            boolean staticBinding)
128   {
129     super();
130 
131     code_source = codesource;
132     if (permissions != null)
133       {
134         perms = permissions;
135         perms.setReadOnly();
136         /* Check if this protection domain has all permissions */
137         Enumeration<Permission> e = permissions.elements();
138         while (e.hasMoreElements())
139           {
140             if (e.nextElement() instanceof AllPermission)
141               hasAllPermissions = true;
142           }
143       }
144 
145     this.classloader = classloader;
146     this.principals =
147         (principals != null ? (Principal[]) principals.clone() : new Principal[0]);
148     this.staticBinding = staticBinding;
149   }
150 
151   /**
152    * Returns the {@link CodeSource} of this domain.
153    *
154    * @return the {@link CodeSource} of this domain.
155    * @since 1.2
156    */
getCodeSource()157   public final CodeSource getCodeSource()
158   {
159     return code_source;
160   }
161 
162   /**
163    * Returns the {@link ClassLoader} of this domain.
164    *
165    * @return the {@link ClassLoader} of this domain.
166    * @since 1.4
167    */
getClassLoader()168   public final ClassLoader getClassLoader()
169   {
170     return this.classloader;
171   }
172 
173   /**
174    * Returns a clone of the {@link Principal}s of this domain.
175    *
176    * @return a clone of the {@link Principal}s of this domain.
177    * @since 1.4
178    */
getPrincipals()179   public final Principal[] getPrincipals()
180   {
181     return (Principal[]) principals.clone();
182   }
183 
184   /**
185    * Returns the {@link PermissionCollection} of this domain.
186    *
187    * @return The {@link PermissionCollection} of this domain.
188    */
getPermissions()189   public final PermissionCollection getPermissions()
190   {
191     return perms;
192   }
193 
194   /**
195    * Tests whether or not the specified {@link Permission} is implied by the
196    * set of permissions granted to this domain.
197    *
198    * @param permission
199    *          the {@link Permission} to test.
200    * @return <code>true</code> if the specified {@link Permission} is implied
201    *         for this domain, <code>false</code> otherwise.
202    */
implies(Permission permission)203   public boolean implies(Permission permission)
204   {
205     if (hasAllPermissions)
206       return true;
207     if (staticBinding)
208       return (perms == null ? false : perms.implies(permission));
209     // Else dynamically bound.  Do we have it?
210     // NOTE: this will force loading of Policy.currentPolicy
211     return Policy.getCurrentPolicy().implies(this, permission);
212   }
213 
214   /**
215    * Returns a string representation of this object. It will include the
216    * {@link CodeSource} and set of permissions associated with this domain.
217    *
218    * @return A string representation of this object.
219    */
toString()220   public String toString()
221   {
222     String linesep = SystemProperties.getProperty("line.separator");
223     CPStringBuilder sb = new CPStringBuilder("ProtectionDomain (").append(linesep);
224 
225     if (code_source == null)
226       sb.append("CodeSource:null");
227     else
228       sb.append(code_source);
229 
230     sb.append(linesep);
231     if (classloader == null)
232       sb.append("ClassLoader:null");
233     else
234       sb.append(classloader);
235 
236     sb.append(linesep);
237     sb.append("Principals:");
238     if (principals != null && principals.length > 0)
239       {
240         sb.append("[");
241         Principal pal;
242         for (int i = 0; i < principals.length; i++)
243           {
244             pal = principals[i];
245             sb.append("'").append(pal.getName())
246                 .append("' of type ").append(pal.getClass().getName());
247             if (i < principals.length-1)
248               sb.append(", ");
249           }
250         sb.append("]");
251       }
252     else
253       sb.append("none");
254 
255     sb.append(linesep);
256     if (!staticBinding) // include all but dont force loading Policy.currentPolicy
257       if (Policy.isLoaded())
258         try
259           {
260             sb.append(Policy.getPolicy().getPermissions(this));
261           }
262         catch (SecurityException e)
263           {
264             // We are not allowed access to the policy.
265             sb.append(perms);
266           }
267       else // fallback on this one's permissions
268         sb.append(perms);
269     else
270       sb.append(perms);
271 
272     return sb.append(linesep).append(")").append(linesep).toString();
273   }
274 }
275