1 23 package com.sun.enterprise.security; 24 25 import java.security.AccessController ; 26 import java.security.CodeSource ; 27 import java.security.AllPermission ; 28 import java.security.Permission ; 29 import java.security.PermissionCollection ; 30 import java.security.Permissions ; 31 import java.security.Policy ; 32 import java.security.PrivilegedExceptionAction ; 33 import java.security.PrivilegedActionException ; 34 import java.util.Enumeration ; 35 import java.util.logging.Level ; 36 import java.util.logging.Logger ; 37 import java.util.concurrent.locks.Lock ; 38 import java.util.concurrent.locks.ReadWriteLock ; 39 import java.util.concurrent.locks.ReentrantReadWriteLock ; 40 41 import javax.security.jacc.PolicyContext ; 42 import com.sun.enterprise.security.CachedPermissionImpl.Epoch; 43 44 import com.sun.logging.LogDomains; 45 46 50 51 public class PermissionCache extends Object { 52 53 private static Logger _logger = 54 LogDomains.getLogger(LogDomains.SECURITY_LOGGER); 55 private static Policy policy = Policy.getPolicy(); 56 private static AllPermission allPermission = new AllPermission (); 57 58 private Permissions cache; 59 private CodeSource codesource; 60 private Permission [] protoPerms; 61 private Class [] classes; 62 private String name; 63 private String pcID; 64 private final Integer factoryKey; 65 private volatile int epoch; 66 private volatile boolean loading; 67 private ReadWriteLock rwLock; 68 private Lock rLock; 69 private Lock wLock; 70 71 93 public PermissionCache(Integer key, String pcID, CodeSource codesource, 94 Class clazz, String name){ 95 if (codesource == null) { 96 this.codesource = 97 new CodeSource (null, 98 (java.security.cert.Certificate [])null); 99 } else { 100 this.codesource = codesource; 101 } 102 this.factoryKey = key; 103 this.cache = null; 104 this.pcID = pcID; 105 this.protoPerms = null; 106 if (clazz != null) { 107 this.classes = new Class [] {clazz}; 108 } else { 109 this.classes = null; 110 } 111 this.name = name; 112 this.epoch = 1; 113 this.loading = false; 114 this.rwLock = new ReentrantReadWriteLock (true); 115 this.rLock = rwLock.readLock(); 116 this.wLock = rwLock.writeLock(); 117 } 118 119 139 public PermissionCache(Integer key, String pcID, CodeSource codesource, 140 Permission [] perms, String name){ 141 if (codesource == null) { 142 this.codesource = 143 new CodeSource (null, 144 (java.security.cert.Certificate [])null); 145 } else { 146 this.codesource = codesource; 147 } 148 this.factoryKey = key; 149 this.cache = null; 150 this.pcID = pcID; 151 this.protoPerms = perms; 152 if (perms != null && perms.length>0) { 153 this.classes = new Class [perms.length]; 154 for (int i=0; i<perms.length; i++) { 155 this.classes[i] = perms[i].getClass(); 156 } 157 } else { 158 this.classes = null; 159 } 160 this.name = name; 161 this.epoch = 1; 162 this.loading = false; 163 this.rwLock = new ReentrantReadWriteLock (true); 164 this.rLock = rwLock.readLock(); 165 this.wLock = rwLock.writeLock(); 166 } 167 168 public Integer getFactoryKey() { 169 return this.factoryKey; 170 } 171 172 private boolean loadCache(Permission p) { 173 174 rLock.lock(); 176 if (loading) { 177 rLock.unlock(); 178 return false; 179 } else if (cache != null) { 180 return true; 183 } else { 184 rLock.unlock(); 185 wLock.lock(); 186 if (loading) { 187 wLock.unlock(); 190 return false; 191 } else { 192 cache = null; 195 loading = true; 196 wLock.unlock(); 197 } 198 } 199 200 Permissions nextCache = new Permissions (); 203 204 boolean setPc = false; 205 String oldpcID = null; 206 try { 207 oldpcID = PolicyContext.getContextID(); 208 if (this.pcID != oldpcID && 209 (this.pcID == null || !this.pcID.equals(oldpcID))) { 210 setPc = true; 211 } 212 } catch (Exception ex) { 213 _logger.log(Level.SEVERE,"JACC: Unexpected security exception on access decision" 214 , ex); 215 return false; 216 } 217 218 PermissionCollection pc = null; 219 try { 220 if (setPc) { 221 setPolicyContextID(this.pcID); 222 } 223 224 pc = this.policy.getPermissions(this.codesource); 225 } catch(Exception ex) { 226 _logger.log(Level.SEVERE,"JACC: Unexpected security exception on access decision" 227 , ex); 228 return false; 229 } finally { 230 if (setPc) { 231 try { 232 setPolicyContextID(oldpcID); 233 } catch(Exception ex) { 234 _logger.log(Level.SEVERE,"JACC: Unexpected security exception on access decision", ex); 235 return false; 236 } 237 } 238 } 239 240 244 resolvePermissions(pc,p); 245 246 Enumeration granted = pc.elements(); 247 while (granted.hasMoreElements()) { 248 Permission i = (Permission ) granted.nextElement(); 249 if (i.equals(allPermission)) { 250 nextCache.add(i); 251 } else { 252 boolean classMatch = true; 253 if (this.classes != null) { 254 classMatch = false; 255 Class iClazz = i.getClass(); 256 for (int j=0; j<this.classes.length; j++) { 257 if (this.classes[j].equals(iClazz)) { 258 classMatch = true; 259 break; 260 } 261 } 262 } 263 if (classMatch) { 264 if (this.name != null) { 265 String name = i.getName(); 266 if (name != null && this.name.equals(name)) { 267 nextCache.add(i); 268 } 269 } else { 270 nextCache.add(i); 271 } 272 } 273 } 274 } 275 276 wLock.lock(); 277 cache = nextCache; 278 loading = false; 279 rLock.lock(); 282 wLock.unlock(); 283 return true; 284 } 285 286 public boolean checkPermission(Permission p, Epoch epoch) { 287 boolean rvalue = false; 288 if (loadCache(p)) { 289 try { 290 if (epoch.epoch != this.epoch) { 291 epoch.granted = this.cache.implies(p); 292 epoch.epoch = this.epoch; 293 } 294 } finally { 295 rLock.unlock(); 296 } 297 rvalue = epoch.granted; 298 } 299 return rvalue; 300 } 301 302 public boolean checkPermission(Permission p) { 303 boolean rvalue = false; 304 if (loadCache(p)) { 305 try { 306 rvalue = this.cache.implies(p); 307 } finally { 308 rLock.unlock(); 309 } 310 } 311 return rvalue; 312 } 313 314 public synchronized void reset() { 315 wLock.lock(); 316 try { 317 if (cache != null) { 318 cache = null; 321 epoch = (epoch + 1 == 0) ? 1 : epoch + 1; 322 } 323 } finally { 324 wLock.unlock(); 325 } 326 } 327 328 private void setPolicyContextID(final String newID) 329 throws PrivilegedActionException { 330 AccessController.doPrivileged(new PrivilegedExceptionAction (){ 331 public java.lang.Object run() throws Exception { 332 PolicyContext.setContextID(newID); 333 return null; 334 } 335 }); 336 } 337 338 private void resolvePermissions(PermissionCollection pc, Permission p) { 340 if (this.protoPerms != null && this.protoPerms.length > 0) { 343 for (int i=0; i<this.protoPerms.length; i++) { 344 pc.implies(this.protoPerms[i]); 345 } 346 } else { 347 pc.implies(p); 348 } 349 } 350 } 351 | Popular Tags |