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