001 /* ProtectionDomain.java -- A security domain
002 Copyright (C) 1998, 2003, 2004 Free Software Foundation, Inc.
003
004 This file is part of GNU Classpath.
005
006 GNU Classpath is free software; you can redistribute it and/or modify
007 it under the terms of the GNU General Public License as published by
008 the Free Software Foundation; either version 2, or (at your option)
009 any later version.
010
011 GNU Classpath is distributed in the hope that it will be useful, but
012 WITHOUT ANY WARRANTY; without even the implied warranty of
013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 General Public License for more details.
015
016 You should have received a copy of the GNU General Public License
017 along with GNU Classpath; see the file COPYING. If not, write to the
018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019 02110-1301 USA.
020
021 Linking this library statically or dynamically with other modules is
022 making a combined work based on this library. Thus, the terms and
023 conditions of the GNU General Public License cover the whole
024 combination.
025
026 As a special exception, the copyright holders of this library give you
027 permission to link this library with independent modules to produce an
028 executable, regardless of the license terms of these independent
029 modules, and to copy and distribute the resulting executable under
030 terms of your choice, provided that you also meet, for each linked
031 independent module, the terms and conditions of the license of that
032 module. An independent module is a module which is not derived from
033 or based on this library. If you modify this library, you may extend
034 this exception to your version of the library, but you are not
035 obligated to do so. If you do not wish to do so, delete this
036 exception statement from your version. */
037
038 package java.security;
039
040 import gnu.classpath.SystemProperties;
041
042 import gnu.java.lang.CPStringBuilder;
043
044 /**
045 * This class represents a group of classes, along with their granted
046 * permissions. The classes are identified by a {@link CodeSource}. Thus, any
047 * class loaded from the specified {@link CodeSource} is treated as part of
048 * this domain. The set of permissions is represented by an instance of
049 * {@link PermissionCollection}.
050 *
051 * <p>Every class in the system will belong to one and only one
052 * <code>ProtectionDomain</code>.</p>
053 *
054 * @author Aaron M. Renn (arenn@urbanophile.com)
055 * @version 0.0
056 */
057 public class ProtectionDomain
058 {
059 /** This is the <code>CodeSource</code> for this protection domain. */
060 private CodeSource code_source;
061
062 /** This is the set of permissions granted to this domain. */
063 private PermissionCollection perms;
064
065 /** The {@link ClassLoader} associated with this domain. */
066 private ClassLoader classloader;
067
068 /** The array of Principals associated with this domain.. */
069 private Principal[] principals;
070
071 /** Post 1.4 the policy may be refreshed! use false for pre 1.4. */
072 private boolean staticBinding;
073
074 /**
075 * Initializes a new instance of <code>ProtectionDomain</code> representing
076 * the specified {@link CodeSource} and set of permissions. No permissions
077 * can be added later to the {@link PermissionCollection} and this contructor
078 * will call the <code>setReadOnly</code> method on the specified set of
079 * permissions.
080 *
081 * @param codesource
082 * The {@link CodeSource} for this domain.
083 * @param permissions
084 * The set of permissions for this domain.
085 * @see PermissionCollection#setReadOnly()
086 */
087 public ProtectionDomain(CodeSource codesource, PermissionCollection permissions)
088 {
089 this(codesource, permissions, null, null, true);
090 }
091
092 /**
093 * This method initializes a new instance of <code>ProtectionDomain</code>
094 * given its {@link CodeSource}, granted permissions, associated
095 * {@link ClassLoader} and {@link Principal}s.
096 *
097 * <p>Similar to the previous constructor, if the designated set of
098 * permissions is not <code>null</code>, the <code>setReadOnly</code> method
099 * is called on that set.</p>
100 *
101 * @param codesource
102 * The {@link CodeSource} for this domain.
103 * @param permissions
104 * The permission set for this domain.
105 * @param classloader
106 * the ClassLoader associated with this domain.
107 * @param principals
108 * the array of {@link Principal}s associated with this domain.
109 * @since 1.4
110 * @see PermissionCollection#setReadOnly()
111 */
112 public ProtectionDomain(CodeSource codesource,
113 PermissionCollection permissions,
114 ClassLoader classloader, Principal[] principals)
115 {
116 this(codesource, permissions, classloader, principals, false);
117 }
118
119 private ProtectionDomain(CodeSource codesource,
120 PermissionCollection permissions,
121 ClassLoader classloader, Principal[] principals,
122 boolean staticBinding)
123 {
124 super();
125
126 code_source = codesource;
127 if (permissions != null)
128 {
129 perms = permissions;
130 perms.setReadOnly();
131 }
132
133 this.classloader = classloader;
134 this.principals =
135 (principals != null ? (Principal[]) principals.clone() : new Principal[0]);
136 this.staticBinding = staticBinding;
137 }
138
139 /**
140 * Returns the {@link CodeSource} of this domain.
141 *
142 * @return the {@link CodeSource} of this domain.
143 * @since 1.2
144 */
145 public final CodeSource getCodeSource()
146 {
147 return code_source;
148 }
149
150 /**
151 * Returns the {@link ClassLoader} of this domain.
152 *
153 * @return the {@link ClassLoader} of this domain.
154 * @since 1.4
155 */
156 public final ClassLoader getClassLoader()
157 {
158 return this.classloader;
159 }
160
161 /**
162 * Returns a clone of the {@link Principal}s of this domain.
163 *
164 * @return a clone of the {@link Principal}s of this domain.
165 * @since 1.4
166 */
167 public final Principal[] getPrincipals()
168 {
169 return (Principal[]) principals.clone();
170 }
171
172 /**
173 * Returns the {@link PermissionCollection} of this domain.
174 *
175 * @return The {@link PermissionCollection} of this domain.
176 */
177 public final PermissionCollection getPermissions()
178 {
179 return perms;
180 }
181
182 /**
183 * Tests whether or not the specified {@link Permission} is implied by the
184 * set of permissions granted to this domain.
185 *
186 * @param permission
187 * the {@link Permission} to test.
188 * @return <code>true</code> if the specified {@link Permission} is implied
189 * for this domain, <code>false</code> otherwise.
190 */
191 public boolean implies(Permission permission)
192 {
193 if (staticBinding)
194 return (perms == null ? false : perms.implies(permission));
195 // Else dynamically bound. Do we have it?
196 // NOTE: this will force loading of Policy.currentPolicy
197 return Policy.getCurrentPolicy().implies(this, permission);
198 }
199
200 /**
201 * Returns a string representation of this object. It will include the
202 * {@link CodeSource} and set of permissions associated with this domain.
203 *
204 * @return A string representation of this object.
205 */
206 public String toString()
207 {
208 String linesep = SystemProperties.getProperty("line.separator");
209 CPStringBuilder sb = new CPStringBuilder("ProtectionDomain (").append(linesep);
210
211 if (code_source == null)
212 sb.append("CodeSource:null");
213 else
214 sb.append(code_source);
215
216 sb.append(linesep);
217 if (classloader == null)
218 sb.append("ClassLoader:null");
219 else
220 sb.append(classloader);
221
222 sb.append(linesep);
223 sb.append("Principals:");
224 if (principals != null && principals.length > 0)
225 {
226 sb.append("[");
227 Principal pal;
228 for (int i = 0; i < principals.length; i++)
229 {
230 pal = principals[i];
231 sb.append("'").append(pal.getName())
232 .append("' of type ").append(pal.getClass().getName());
233 if (i < principals.length-1)
234 sb.append(", ");
235 }
236 sb.append("]");
237 }
238 else
239 sb.append("none");
240
241 sb.append(linesep);
242 if (!staticBinding) // include all but dont force loading Policy.currentPolicy
243 if (Policy.isLoaded())
244 sb.append(Policy.getCurrentPolicy().getPermissions(this));
245 else // fallback on this one's permissions
246 sb.append(perms);
247 else
248 sb.append(perms);
249
250 return sb.append(linesep).append(")").append(linesep).toString();
251 }
252 }