1 /* 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package java.security; 28 29 import java.util.Enumeration; 30 import java.util.WeakHashMap; 31 import java.util.concurrent.atomic.AtomicReference; 32 import sun.security.jca.GetInstance; 33 import sun.security.util.Debug; 34 import sun.security.util.SecurityConstants; 35 36 37 /** 38 * A Policy object is responsible for determining whether code executing 39 * in the Java runtime environment has permission to perform a 40 * security-sensitive operation. 41 * 42 * <p> There is only one Policy object installed in the runtime at any 43 * given time. A Policy object can be installed by calling the 44 * <code>setPolicy</code> method. The installed Policy object can be 45 * obtained by calling the <code>getPolicy</code> method. 46 * 47 * <p> If no Policy object has been installed in the runtime, a call to 48 * <code>getPolicy</code> installs an instance of the default Policy 49 * implementation (a default subclass implementation of this abstract class). 50 * The default Policy implementation can be changed by setting the value 51 * of the {@code policy.provider} security property to the fully qualified 52 * name of the desired Policy subclass implementation. 53 * 54 * <p> Application code can directly subclass Policy to provide a custom 55 * implementation. In addition, an instance of a Policy object can be 56 * constructed by invoking one of the <code>getInstance</code> factory methods 57 * with a standard type. The default policy type is "JavaPolicy". 58 * 59 * <p> Once a Policy instance has been installed (either by default, or by 60 * calling <code>setPolicy</code>), the Java runtime invokes its 61 * <code>implies</code> method when it needs to 62 * determine whether executing code (encapsulated in a ProtectionDomain) 63 * can perform SecurityManager-protected operations. How a Policy object 64 * retrieves its policy data is up to the Policy implementation itself. 65 * The policy data may be stored, for example, in a flat ASCII file, 66 * in a serialized binary file of the Policy class, or in a database. 67 * 68 * <p> The <code>refresh</code> method causes the policy object to 69 * refresh/reload its data. This operation is implementation-dependent. 70 * For example, if the policy object stores its data in configuration files, 71 * calling <code>refresh</code> will cause it to re-read the configuration 72 * policy files. If a refresh operation is not supported, this method does 73 * nothing. Note that refreshed policy may not have an effect on classes 74 * in a particular ProtectionDomain. This is dependent on the Policy 75 * provider's implementation of the <code>implies</code> 76 * method and its PermissionCollection caching strategy. 77 * 78 * @author Roland Schemers 79 * @author Gary Ellison 80 * @see java.security.Provider 81 * @see java.security.ProtectionDomain 82 * @see java.security.Permission 83 * @see java.security.Security security properties 84 */ 85 86 public abstract class Policy { 87 88 /** 89 * A read-only empty PermissionCollection instance. 90 * @since 1.6 91 */ 92 public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION = 93 new UnsupportedEmptyCollection(); 94 95 // Information about the system-wide policy. 96 private static class PolicyInfo { 97 // the system-wide policy 98 final Policy policy; 99 // a flag indicating if the system-wide policy has been initialized 100 final boolean initialized; 101 102 PolicyInfo(Policy policy, boolean initialized) { 103 this.policy = policy; 104 this.initialized = initialized; 105 } 106 } 107 108 // PolicyInfo is stored in an AtomicReference 109 private static AtomicReference<PolicyInfo> policy = 110 new AtomicReference<>(new PolicyInfo(null, false)); 111 112 private static final Debug debug = Debug.getInstance("policy"); 113 114 // Cache mapping ProtectionDomain.Key to PermissionCollection 115 private WeakHashMap<ProtectionDomain.Key, PermissionCollection> pdMapping; 116 117 /** package private for AccessControlContext and ProtectionDomain */ 118 static boolean isSet() 119 { 120 PolicyInfo pi = policy.get(); 121 return pi.policy != null && pi.initialized == true; 122 } 123 124 private static void checkPermission(String type) { 125 SecurityManager sm = System.getSecurityManager(); 126 if (sm != null) { 127 sm.checkPermission(new SecurityPermission("createPolicy." + type)); 128 } 129 } 130 131 /** 132 * Returns the installed Policy object. This value should not be cached, 133 * as it may be changed by a call to <code>setPolicy</code>. 134 * This method first calls 135 * <code>SecurityManager.checkPermission</code> with a 136 * <code>SecurityPermission("getPolicy")</code> permission 137 * to ensure it's ok to get the Policy object. 138 * 139 * @return the installed Policy. 140 * 141 * @throws SecurityException 142 * if a security manager exists and its 143 * <code>checkPermission</code> method doesn't allow 144 * getting the Policy object. 145 * 146 * @see SecurityManager#checkPermission(Permission) 147 * @see #setPolicy(java.security.Policy) 148 */ 149 public static Policy getPolicy() 150 { 151 SecurityManager sm = System.getSecurityManager(); 152 if (sm != null) 153 sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION); 154 return getPolicyNoCheck(); 155 } 156 157 /** 158 * Returns the installed Policy object, skipping the security check. 159 * Used by ProtectionDomain and getPolicy. 160 * 161 * @return the installed Policy. 162 */ 163 static Policy getPolicyNoCheck() 164 { 165 PolicyInfo pi = policy.get(); 166 // Use double-check idiom to avoid locking if system-wide policy is 167 // already initialized 168 if (pi.initialized == false || pi.policy == null) { 169 synchronized (Policy.class) { 170 PolicyInfo pinfo = policy.get(); 171 if (pinfo.policy == null) { 172 String policy_class = AccessController.doPrivileged( 173 new PrivilegedAction<String>() { 174 public String run() { 175 return Security.getProperty("policy.provider"); 176 } 177 }); 178 if (policy_class == null) { 179 policy_class = "sun.security.provider.PolicyFile"; 180 } 181 182 try { 183 pinfo = new PolicyInfo( 184 (Policy) Class.forName(policy_class).newInstance(), 185 true); 186 } catch (Exception e) { 187 /* 188 * The policy_class seems to be an extension 189 * so we have to bootstrap loading it via a policy 190 * provider that is on the bootclasspath. 191 * If it loads then shift gears to using the configured 192 * provider. 193 */ 194 195 // install the bootstrap provider to avoid recursion 196 Policy polFile = new sun.security.provider.PolicyFile(); 197 pinfo = new PolicyInfo(polFile, false); 198 policy.set(pinfo); 199 200 final String pc = policy_class; 201 Policy pol = AccessController.doPrivileged( 202 new PrivilegedAction<Policy>() { 203 public Policy run() { 204 try { 205 ClassLoader cl = 206 ClassLoader.getSystemClassLoader(); 207 // we want the extension loader 208 ClassLoader extcl = null; 209 while (cl != null) { 210 extcl = cl; 211 cl = cl.getParent(); 212 } 213 return (extcl != null ? (Policy)Class.forName( 214 pc, true, extcl).newInstance() : null); 215 } catch (Exception e) { 216 if (debug != null) { 217 debug.println("policy provider " + 218 pc + 219 " not available"); 220 e.printStackTrace(); 221 } 222 return null; 223 } 224 } 225 }); 226 /* 227 * if it loaded install it as the policy provider. Otherwise 228 * continue to use the system default implementation 229 */ 230 if (pol != null) { 231 pinfo = new PolicyInfo(pol, true); 232 } else { 233 if (debug != null) { 234 debug.println("using sun.security.provider.PolicyFile"); 235 } 236 pinfo = new PolicyInfo(polFile, true); 237 } 238 } 239 policy.set(pinfo); 240 } 241 return pinfo.policy; 242 } 243 } 244 return pi.policy; 245 } 246 247 /** 248 * Sets the system-wide Policy object. This method first calls 249 * <code>SecurityManager.checkPermission</code> with a 250 * <code>SecurityPermission("setPolicy")</code> 251 * permission to ensure it's ok to set the Policy. 252 * 253 * @param p the new system Policy object. 254 * 255 * @throws SecurityException 256 * if a security manager exists and its 257 * <code>checkPermission</code> method doesn't allow 258 * setting the Policy. 259 * 260 * @see SecurityManager#checkPermission(Permission) 261 * @see #getPolicy() 262 * 263 */ 264 public static void setPolicy(Policy p) 265 { 266 SecurityManager sm = System.getSecurityManager(); 267 if (sm != null) sm.checkPermission( 268 new SecurityPermission("setPolicy")); 269 if (p != null) { 270 initPolicy(p); 271 } 272 synchronized (Policy.class) { 273 policy.set(new PolicyInfo(p, p != null)); 274 } 275 } 276 277 /** 278 * Initialize superclass state such that a legacy provider can 279 * handle queries for itself. 280 * 281 * @since 1.4 282 */ 283 private static void initPolicy (final Policy p) { 284 /* 285 * A policy provider not on the bootclasspath could trigger 286 * security checks fulfilling a call to either Policy.implies 287 * or Policy.getPermissions. If this does occur the provider 288 * must be able to answer for it's own ProtectionDomain 289 * without triggering additional security checks, otherwise 290 * the policy implementation will end up in an infinite 291 * recursion. 292 * 293 * To mitigate this, the provider can collect it's own 294 * ProtectionDomain and associate a PermissionCollection while 295 * it is being installed. The currently installed policy 296 * provider (if there is one) will handle calls to 297 * Policy.implies or Policy.getPermissions during this 298 * process. 299 * 300 * This Policy superclass caches away the ProtectionDomain and 301 * statically binds permissions so that legacy Policy 302 * implementations will continue to function. 303 */ 304 305 ProtectionDomain policyDomain = 306 AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() { 307 public ProtectionDomain run() { 308 return p.getClass().getProtectionDomain(); 309 } 310 }); 311 312 /* 313 * Collect the permissions granted to this protection domain 314 * so that the provider can be security checked while processing 315 * calls to Policy.implies or Policy.getPermissions. 316 */ 317 PermissionCollection policyPerms = null; 318 synchronized (p) { 319 if (p.pdMapping == null) { 320 p.pdMapping = new WeakHashMap<>(); 321 } 322 } 323 324 if (policyDomain.getCodeSource() != null) { 325 Policy pol = policy.get().policy; 326 if (pol != null) { 327 policyPerms = pol.getPermissions(policyDomain); 328 } 329 330 if (policyPerms == null) { // assume it has all 331 policyPerms = new Permissions(); 332 policyPerms.add(SecurityConstants.ALL_PERMISSION); 333 } 334 335 synchronized (p.pdMapping) { 336 // cache of pd to permissions 337 p.pdMapping.put(policyDomain.key, policyPerms); 338 } 339 } 340 return; 341 } 342 343 344 /** 345 * Returns a Policy object of the specified type. 346 * 347 * <p> This method traverses the list of registered security providers, 348 * starting with the most preferred Provider. 349 * A new Policy object encapsulating the 350 * PolicySpi implementation from the first 351 * Provider that supports the specified type is returned. 352 * 353 * <p> Note that the list of registered providers may be retrieved via 354 * the {@link Security#getProviders() Security.getProviders()} method. 355 * 356 * @param type the specified Policy type. See the Policy section in the 357 * <a href= 358 * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy"> 359 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 360 * for a list of standard Policy types. 361 * 362 * @param params parameters for the Policy, which may be null. 363 * 364 * @return the new Policy object. 365 * 366 * @exception SecurityException if the caller does not have permission 367 * to get a Policy instance for the specified type. 368 * 369 * @exception NullPointerException if the specified type is null. 370 * 371 * @exception IllegalArgumentException if the specified parameters 372 * are not understood by the PolicySpi implementation 373 * from the selected Provider. 374 * 375 * @exception NoSuchAlgorithmException if no Provider supports a PolicySpi 376 * implementation for the specified type. 377 * 378 * @see Provider 379 * @since 1.6 380 */ 381 public static Policy getInstance(String type, Policy.Parameters params) 382 throws NoSuchAlgorithmException { 383 384 checkPermission(type); 385 try { 386 GetInstance.Instance instance = GetInstance.getInstance("Policy", 387 PolicySpi.class, 388 type, 389 params); 390 return new PolicyDelegate((PolicySpi)instance.impl, 391 instance.provider, 392 type, 393 params); 394 } catch (NoSuchAlgorithmException nsae) { 395 return handleException(nsae); 396 } 397 } 398 399 /** 400 * Returns a Policy object of the specified type. 401 * 402 * <p> A new Policy object encapsulating the 403 * PolicySpi implementation from the specified provider 404 * is returned. The specified provider must be registered 405 * in the provider list. 406 * 407 * <p> Note that the list of registered providers may be retrieved via 408 * the {@link Security#getProviders() Security.getProviders()} method. 409 * 410 * @param type the specified Policy type. See the Policy section in the 411 * <a href= 412 * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy"> 413 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 414 * for a list of standard Policy types. 415 * 416 * @param params parameters for the Policy, which may be null. 417 * 418 * @param provider the provider. 419 * 420 * @return the new Policy object. 421 * 422 * @exception SecurityException if the caller does not have permission 423 * to get a Policy instance for the specified type. 424 * 425 * @exception NullPointerException if the specified type is null. 426 * 427 * @exception IllegalArgumentException if the specified provider 428 * is null or empty, 429 * or if the specified parameters are not understood by 430 * the PolicySpi implementation from the specified provider. 431 * 432 * @exception NoSuchProviderException if the specified provider is not 433 * registered in the security provider list. 434 * 435 * @exception NoSuchAlgorithmException if the specified provider does not 436 * support a PolicySpi implementation for the specified type. 437 * 438 * @see Provider 439 * @since 1.6 440 */ 441 public static Policy getInstance(String type, 442 Policy.Parameters params, 443 String provider) 444 throws NoSuchProviderException, NoSuchAlgorithmException { 445 446 if (provider == null || provider.length() == 0) { 447 throw new IllegalArgumentException("missing provider"); 448 } 449 450 checkPermission(type); 451 try { 452 GetInstance.Instance instance = GetInstance.getInstance("Policy", 453 PolicySpi.class, 454 type, 455 params, 456 provider); 457 return new PolicyDelegate((PolicySpi)instance.impl, 458 instance.provider, 459 type, 460 params); 461 } catch (NoSuchAlgorithmException nsae) { 462 return handleException(nsae); 463 } 464 } 465 466 /** 467 * Returns a Policy object of the specified type. 468 * 469 * <p> A new Policy object encapsulating the 470 * PolicySpi implementation from the specified Provider 471 * object is returned. Note that the specified Provider object 472 * does not have to be registered in the provider list. 473 * 474 * @param type the specified Policy type. See the Policy section in the 475 * <a href= 476 * "{@docRoot}/../technotes/guides/security/StandardNames.html#Policy"> 477 * Java Cryptography Architecture Standard Algorithm Name Documentation</a> 478 * for a list of standard Policy types. 479 * 480 * @param params parameters for the Policy, which may be null. 481 * 482 * @param provider the Provider. 483 * 484 * @return the new Policy object. 485 * 486 * @exception SecurityException if the caller does not have permission 487 * to get a Policy instance for the specified type. 488 * 489 * @exception NullPointerException if the specified type is null. 490 * 491 * @exception IllegalArgumentException if the specified Provider is null, 492 * or if the specified parameters are not understood by 493 * the PolicySpi implementation from the specified Provider. 494 * 495 * @exception NoSuchAlgorithmException if the specified Provider does not 496 * support a PolicySpi implementation for the specified type. 497 * 498 * @see Provider 499 * @since 1.6 500 */ 501 public static Policy getInstance(String type, 502 Policy.Parameters params, 503 Provider provider) 504 throws NoSuchAlgorithmException { 505 506 if (provider == null) { 507 throw new IllegalArgumentException("missing provider"); 508 } 509 510 checkPermission(type); 511 try { 512 GetInstance.Instance instance = GetInstance.getInstance("Policy", 513 PolicySpi.class, 514 type, 515 params, 516 provider); 517 return new PolicyDelegate((PolicySpi)instance.impl, 518 instance.provider, 519 type, 520 params); 521 } catch (NoSuchAlgorithmException nsae) { 522 return handleException(nsae); 523 } 524 } 525 526 private static Policy handleException(NoSuchAlgorithmException nsae) 527 throws NoSuchAlgorithmException { 528 Throwable cause = nsae.getCause(); 529 if (cause instanceof IllegalArgumentException) { 530 throw (IllegalArgumentException)cause; 531 } 532 throw nsae; 533 } 534 535 /** 536 * Return the Provider of this Policy. 537 * 538 * <p> This Policy instance will only have a Provider if it 539 * was obtained via a call to <code>Policy.getInstance</code>. 540 * Otherwise this method returns null. 541 * 542 * @return the Provider of this Policy, or null. 543 * 544 * @since 1.6 545 */ 546 public Provider getProvider() { 547 return null; 548 } 549 550 /** 551 * Return the type of this Policy. 552 * 553 * <p> This Policy instance will only have a type if it 554 * was obtained via a call to <code>Policy.getInstance</code>. 555 * Otherwise this method returns null. 556 * 557 * @return the type of this Policy, or null. 558 * 559 * @since 1.6 560 */ 561 public String getType() { 562 return null; 563 } 564 565 /** 566 * Return Policy parameters. 567 * 568 * <p> This Policy instance will only have parameters if it 569 * was obtained via a call to <code>Policy.getInstance</code>. 570 * Otherwise this method returns null. 571 * 572 * @return Policy parameters, or null. 573 * 574 * @since 1.6 575 */ 576 public Policy.Parameters getParameters() { 577 return null; 578 } 579 580 /** 581 * Return a PermissionCollection object containing the set of 582 * permissions granted to the specified CodeSource. 583 * 584 * <p> Applications are discouraged from calling this method 585 * since this operation may not be supported by all policy implementations. 586 * Applications should solely rely on the <code>implies</code> method 587 * to perform policy checks. If an application absolutely must call 588 * a getPermissions method, it should call 589 * <code>getPermissions(ProtectionDomain)</code>. 590 * 591 * <p> The default implementation of this method returns 592 * Policy.UNSUPPORTED_EMPTY_COLLECTION. This method can be 593 * overridden if the policy implementation can return a set of 594 * permissions granted to a CodeSource. 595 * 596 * @param codesource the CodeSource to which the returned 597 * PermissionCollection has been granted. 598 * 599 * @return a set of permissions granted to the specified CodeSource. 600 * If this operation is supported, the returned 601 * set of permissions must be a new mutable instance 602 * and it must support heterogeneous Permission types. 603 * If this operation is not supported, 604 * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. 605 */ 606 public PermissionCollection getPermissions(CodeSource codesource) { 607 return Policy.UNSUPPORTED_EMPTY_COLLECTION; 608 } 609 610 /** 611 * Return a PermissionCollection object containing the set of 612 * permissions granted to the specified ProtectionDomain. 613 * 614 * <p> Applications are discouraged from calling this method 615 * since this operation may not be supported by all policy implementations. 616 * Applications should rely on the <code>implies</code> method 617 * to perform policy checks. 618 * 619 * <p> The default implementation of this method first retrieves 620 * the permissions returned via <code>getPermissions(CodeSource)</code> 621 * (the CodeSource is taken from the specified ProtectionDomain), 622 * as well as the permissions located inside the specified ProtectionDomain. 623 * All of these permissions are then combined and returned in a new 624 * PermissionCollection object. If <code>getPermissions(CodeSource)</code> 625 * returns Policy.UNSUPPORTED_EMPTY_COLLECTION, then this method 626 * returns the permissions contained inside the specified ProtectionDomain 627 * in a new PermissionCollection object. 628 * 629 * <p> This method can be overridden if the policy implementation 630 * supports returning a set of permissions granted to a ProtectionDomain. 631 * 632 * @param domain the ProtectionDomain to which the returned 633 * PermissionCollection has been granted. 634 * 635 * @return a set of permissions granted to the specified ProtectionDomain. 636 * If this operation is supported, the returned 637 * set of permissions must be a new mutable instance 638 * and it must support heterogeneous Permission types. 639 * If this operation is not supported, 640 * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. 641 * 642 * @since 1.4 643 */ 644 public PermissionCollection getPermissions(ProtectionDomain domain) { 645 PermissionCollection pc = null; 646 647 if (domain == null) 648 return new Permissions(); 649 650 if (pdMapping == null) { 651 initPolicy(this); 652 } 653 654 synchronized (pdMapping) { 655 pc = pdMapping.get(domain.key); 656 } 657 658 if (pc != null) { 659 Permissions perms = new Permissions(); 660 synchronized (pc) { 661 for (Enumeration<Permission> e = pc.elements() ; e.hasMoreElements() ;) { 662 perms.add(e.nextElement()); 663 } 664 } 665 return perms; 666 } 667 668 pc = getPermissions(domain.getCodeSource()); 669 if (pc == null || pc == UNSUPPORTED_EMPTY_COLLECTION) { 670 pc = new Permissions(); 671 } 672 673 addStaticPerms(pc, domain.getPermissions()); 674 return pc; 675 } 676 677 /** 678 * add static permissions to provided permission collection 679 */ 680 private void addStaticPerms(PermissionCollection perms, 681 PermissionCollection statics) { 682 if (statics != null) { 683 synchronized (statics) { 684 Enumeration<Permission> e = statics.elements(); 685 while (e.hasMoreElements()) { 686 perms.add(e.nextElement()); 687 } 688 } 689 } 690 } 691 692 /** 693 * Evaluates the global policy for the permissions granted to 694 * the ProtectionDomain and tests whether the permission is 695 * granted. 696 * 697 * @param domain the ProtectionDomain to test 698 * @param permission the Permission object to be tested for implication. 699 * 700 * @return true if "permission" is a proper subset of a permission 701 * granted to this ProtectionDomain. 702 * 703 * @see java.security.ProtectionDomain 704 * @since 1.4 705 */ 706 public boolean implies(ProtectionDomain domain, Permission permission) { 707 PermissionCollection pc; 708 709 if (pdMapping == null) { 710 initPolicy(this); 711 } 712 713 synchronized (pdMapping) { 714 pc = pdMapping.get(domain.key); 715 } 716 717 if (pc != null) { 718 return pc.implies(permission); 719 } 720 721 pc = getPermissions(domain); 722 if (pc == null) { 723 return false; 724 } 725 726 synchronized (pdMapping) { 727 // cache it 728 pdMapping.put(domain.key, pc); 729 } 730 731 return pc.implies(permission); 732 } 733 734 /** 735 * Refreshes/reloads the policy configuration. The behavior of this method 736 * depends on the implementation. For example, calling <code>refresh</code> 737 * on a file-based policy will cause the file to be re-read. 738 * 739 * <p> The default implementation of this method does nothing. 740 * This method should be overridden if a refresh operation is supported 741 * by the policy implementation. 742 */ 743 public void refresh() { } 744 745 /** 746 * This subclass is returned by the getInstance calls. All Policy calls 747 * are delegated to the underlying PolicySpi. 748 */ 749 private static class PolicyDelegate extends Policy { 750 751 private PolicySpi spi; 752 private Provider p; 753 private String type; 754 private Policy.Parameters params; 755 756 private PolicyDelegate(PolicySpi spi, Provider p, 757 String type, Policy.Parameters params) { 758 this.spi = spi; 759 this.p = p; 760 this.type = type; 761 this.params = params; 762 } 763 764 @Override public String getType() { return type; } 765 766 @Override public Policy.Parameters getParameters() { return params; } 767 768 @Override public Provider getProvider() { return p; } 769 770 @Override 771 public PermissionCollection getPermissions(CodeSource codesource) { 772 return spi.engineGetPermissions(codesource); 773 } 774 @Override 775 public PermissionCollection getPermissions(ProtectionDomain domain) { 776 return spi.engineGetPermissions(domain); 777 } 778 @Override 779 public boolean implies(ProtectionDomain domain, Permission perm) { 780 return spi.engineImplies(domain, perm); 781 } 782 @Override 783 public void refresh() { 784 spi.engineRefresh(); 785 } 786 } 787 788 /** 789 * This represents a marker interface for Policy parameters. 790 * 791 * @since 1.6 792 */ 793 public static interface Parameters { } 794 795 /** 796 * This class represents a read-only empty PermissionCollection object that 797 * is returned from the <code>getPermissions(CodeSource)</code> and 798 * <code>getPermissions(ProtectionDomain)</code> 799 * methods in the Policy class when those operations are not 800 * supported by the Policy implementation. 801 */ 802 private static class UnsupportedEmptyCollection 803 extends PermissionCollection { 804 805 private static final long serialVersionUID = -8492269157353014774L; 806 807 private Permissions perms; 808 809 /** 810 * Create a read-only empty PermissionCollection object. 811 */ 812 public UnsupportedEmptyCollection() { 813 this.perms = new Permissions(); 814 perms.setReadOnly(); 815 } 816 817 /** 818 * Adds a permission object to the current collection of permission 819 * objects. 820 * 821 * @param permission the Permission object to add. 822 * 823 * @exception SecurityException - if this PermissionCollection object 824 * has been marked readonly 825 */ 826 @Override public void add(Permission permission) { 827 perms.add(permission); 828 } 829 830 /** 831 * Checks to see if the specified permission is implied by the 832 * collection of Permission objects held in this PermissionCollection. 833 * 834 * @param permission the Permission object to compare. 835 * 836 * @return true if "permission" is implied by the permissions in 837 * the collection, false if not. 838 */ 839 @Override public boolean implies(Permission permission) { 840 return perms.implies(permission); 841 } 842 843 /** 844 * Returns an enumeration of all the Permission objects in the 845 * collection. 846 * 847 * @return an enumeration of all the Permissions. 848 */ 849 @Override public Enumeration<Permission> elements() { 850 return perms.elements(); 851 } 852 } 853 }