1 7 8 package java.security; 9 10 import java.util.ArrayList ; 11 import java.util.List ; 12 import sun.security.util.Debug; 13 import sun.security.util.SecurityConstants; 14 15 61 62 public final class AccessControlContext { 63 64 private ProtectionDomain context[]; 65 private boolean isPrivileged; 66 private AccessControlContext privilegedContext; 67 private DomainCombiner combiner = null; 68 69 private static boolean debugInit = false; 70 private static Debug debug = null; 71 72 static Debug getDebug() 73 { 74 if (debugInit) 75 return debug; 76 else { 77 if (Policy.isSet()) { 78 debug = Debug.getInstance("access"); 79 debugInit = true; 80 } 81 return debug; 82 } 83 } 84 85 94 public AccessControlContext(ProtectionDomain context[]) 95 { 96 if (context.length == 0) { 97 this.context = null; 98 } else if (context.length == 1) { 99 if (context[0] != null) { 100 this.context = (ProtectionDomain [])context.clone(); 101 } else { 102 this.context = null; 103 } 104 } else { 105 List v = new ArrayList (context.length); 106 for (int i =0; i< context.length; i++) { 107 if ((context[i] != null) && (!v.contains(context[i]))) 108 v.add(context[i]); 109 } 110 this.context = new ProtectionDomain [v.size()]; 111 this.context = (ProtectionDomain []) v.toArray(this.context); 112 } 113 } 114 115 136 public AccessControlContext(AccessControlContext acc, 137 DomainCombiner combiner) { 138 139 SecurityManager sm = System.getSecurityManager(); 140 if (sm != null) { 141 sm.checkPermission(SecurityConstants.CREATE_ACC_PERMISSION); 142 } 143 144 this.context = acc.context; 145 146 this.combiner = combiner; 153 } 154 155 158 159 AccessControlContext(ProtectionDomain context[], 160 boolean isPrivileged) 161 { 162 this.context = context; 163 this.isPrivileged = isPrivileged; 164 } 165 166 169 boolean isPrivileged() 170 { 171 return isPrivileged; 172 173 } 174 175 189 public DomainCombiner getDomainCombiner() { 190 191 SecurityManager sm = System.getSecurityManager(); 192 if (sm != null) { 193 sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION); 194 } 195 return combiner; 196 } 197 198 214 public void checkPermission(Permission perm) 215 throws AccessControlException 216 { 217 if (perm == null) { 218 throw new NullPointerException ("permission can't be null"); 219 } 220 if (getDebug() != null) { 221 if (Debug.isOn("stack")) 222 Thread.currentThread().dumpStack(); 223 if (Debug.isOn("domain")) { 224 if (context == null) { 225 debug.println("domain (context is null)"); 226 } else { 227 for (int i=0; i< context.length; i++) { 228 debug.println("domain "+i+" "+context[i]); 229 } 230 } 231 } 232 } 233 234 240 241 244 245 if (context == null) 246 return; 247 248 for (int i=0; i< context.length; i++) { 249 if (context[i] != null && !context[i].implies(perm)) { 250 if (debug != null) { 251 debug.println("access denied "+perm); 252 if (Debug.isOn("failure")) { 253 Thread.currentThread().dumpStack(); 254 final ProtectionDomain pd = context[i]; 255 final Debug db = debug; 256 AccessController.doPrivileged (new PrivilegedAction () { 257 public Object run() { 258 db.println("domain that failed "+pd); 259 return null; 260 } 261 }); 262 } 263 } 264 throw new AccessControlException ("access denied "+perm, perm); 265 } 266 } 267 268 if (debug != null) 270 debug.println("access allowed "+perm); 271 272 return; 273 } 274 275 279 AccessControlContext optimize() { 280 AccessControlContext acc; 282 if (isPrivileged) { 283 acc = privilegedContext; 284 } else { 285 acc = AccessController.getInheritedAccessControlContext(); 286 } 287 288 boolean skipStack = (context == null); 291 292 boolean skipAssigned = (acc == null || acc.context == null); 295 296 if (skipAssigned && skipStack) { 299 return (acc != null) ? acc : this; 300 } 301 302 if (acc != null && acc.combiner != null) { 303 return goCombiner(context, acc); 305 } 306 307 if (skipStack) { 310 return acc; 311 } 312 313 int slen = context.length; 314 315 if (skipAssigned && slen <= 2) { 319 return this; 320 } 321 322 if ((slen == 1) && (context[0] == acc.context[0])) { 325 return acc; 326 } 327 328 int n = (skipAssigned) ? 0 : acc.context.length; 329 330 ProtectionDomain pd[] = new ProtectionDomain [slen + n]; 332 333 if (!skipAssigned) { 335 System.arraycopy(acc.context, 0, pd, 0, n); 336 } 337 338 outer: 340 for (int i = 0; i < context.length; i++) { 341 ProtectionDomain sd = context[i]; 342 if (sd != null) { 343 for (int j = 0; j < n; j++) { 344 if (sd == pd[j]) { 345 continue outer; 346 } 347 } 348 pd[n++] = sd; 349 } 350 } 351 352 if (n != pd.length) { 354 if (!skipAssigned && n == acc.context.length) { 356 return acc; 357 } else if (skipAssigned && n == slen) { 358 return this; 359 } 360 ProtectionDomain tmp[] = new ProtectionDomain [n]; 361 System.arraycopy(pd, 0, tmp, 0, n); 362 pd = tmp; 363 } 364 365 367 369 this.context = pd; 370 this.combiner = null; 371 this.isPrivileged = false; 372 373 return this; 374 } 375 376 private AccessControlContext goCombiner(ProtectionDomain [] current, 377 AccessControlContext assigned) { 378 379 382 384 if (getDebug() != null) { 385 debug.println("AccessControlContext invoking the Combiner"); 386 } 387 388 ProtectionDomain [] combinedPds = assigned.combiner.combine( 391 current, assigned.context); 392 393 395 this.context = combinedPds; 397 this.combiner = assigned.combiner; 398 this.isPrivileged = false; 399 400 return this; 401 } 402 403 413 public boolean equals(Object obj) { 414 if (obj == this) 415 return true; 416 417 if (! (obj instanceof AccessControlContext )) 418 return false; 419 420 AccessControlContext that = (AccessControlContext ) obj; 421 422 423 if (context == null) { 424 return (that.context == null); 425 } 426 427 if (that.context == null) 428 return false; 429 430 if (!(this.containsAllPDs(that) && that.containsAllPDs(this))) 431 return false; 432 433 if (this.combiner == null) 434 return (that.combiner == null); 435 436 if (that.combiner == null) 437 return false; 438 439 if (!this.combiner.equals(that.combiner)) 440 return false; 441 442 return true; 443 } 444 445 private boolean containsAllPDs(AccessControlContext that) { 446 boolean match = false; 447 ProtectionDomain thisPd; 454 for (int i = 0; i < context.length; i++) { 455 match = false; 456 if ((thisPd = context[i]) == null) { 457 for (int j = 0; (j < that.context.length) && !match; j++) { 458 match = (that.context[j] == null); 459 } 460 } else { 461 Class thisPdClass = thisPd.getClass(); 462 ProtectionDomain thatPd; 463 for (int j = 0; (j < that.context.length) && !match; j++) { 464 thatPd = that.context[j]; 465 466 match = (thatPd != null && 468 thisPdClass == thatPd.getClass() && thisPd.equals(thatPd)); 469 } 470 } 471 if (!match) return false; 472 } 473 return match; 474 } 475 482 483 public int hashCode() { 484 int hashCode = 0; 485 486 if (context == null) 487 return hashCode; 488 489 for (int i =0; i < context.length; i++) { 490 if (context[i] != null) 491 hashCode ^= context[i].hashCode(); 492 } 493 return hashCode; 494 } 495 } 496 | Popular Tags |