001/* ProtectionDomain.java -- A security domain 002 Copyright (C) 1998, 2003, 2004 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038package java.security; 039 040import gnu.classpath.SystemProperties; 041 042import gnu.java.lang.CPStringBuilder; 043 044import java.util.Enumeration; 045 046/** 047 * This class represents a group of classes, along with their granted 048 * permissions. The classes are identified by a {@link CodeSource}. Thus, any 049 * class loaded from the specified {@link CodeSource} is treated as part of 050 * this domain. The set of permissions is represented by an instance of 051 * {@link PermissionCollection}. 052 * 053 * <p>Every class in the system will belong to one and only one 054 * <code>ProtectionDomain</code>.</p> 055 * 056 * @author Aaron M. Renn (arenn@urbanophile.com) 057 * @version 0.0 058 */ 059public class ProtectionDomain 060{ 061 /** This is the <code>CodeSource</code> for this protection domain. */ 062 private CodeSource code_source; 063 064 /** This is the set of permissions granted to this domain. */ 065 private PermissionCollection perms; 066 067 /** The {@link ClassLoader} associated with this domain. */ 068 private ClassLoader classloader; 069 070 /** The array of Principals associated with this domain.. */ 071 private Principal[] principals; 072 073 /** Post 1.4 the policy may be refreshed! use false for pre 1.4. */ 074 private boolean staticBinding; 075 076 /** True if this protection domain has all permissions */ 077 private boolean hasAllPermissions; 078 079 /** 080 * Initializes a new instance of <code>ProtectionDomain</code> representing 081 * the specified {@link CodeSource} and set of permissions. No permissions 082 * can be added later to the {@link PermissionCollection} and this contructor 083 * will call the <code>setReadOnly</code> method on the specified set of 084 * permissions. 085 * 086 * @param codesource 087 * The {@link CodeSource} for this domain. 088 * @param permissions 089 * The set of permissions for this domain. 090 * @see PermissionCollection#setReadOnly() 091 */ 092 public ProtectionDomain(CodeSource codesource, PermissionCollection permissions) 093 { 094 this(codesource, permissions, null, null, true); 095 } 096 097 /** 098 * This method initializes a new instance of <code>ProtectionDomain</code> 099 * 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 */ 117 public ProtectionDomain(CodeSource codesource, 118 PermissionCollection permissions, 119 ClassLoader classloader, Principal[] principals) 120 { 121 this(codesource, permissions, classloader, principals, false); 122 } 123 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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}