< prev index next >

src/share/classes/javax/security/auth/Subject.java

Print this page
rev 1461 : 6987827: security/util/Resources.java needs improvement
Reviewed-by: valeriep
   1 /*
   2  * Copyright (c) 1998, 2006, 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


 188      *          to be associated with this <code>Subject</code>. <p>
 189      *
 190      * @param pubCredentials the <code>Set</code> of public credentials
 191      *          to be associated with this <code>Subject</code>. <p>
 192      *
 193      * @param privCredentials the <code>Set</code> of private credentials
 194      *          to be associated with this <code>Subject</code>.
 195      *
 196      * @exception NullPointerException if the specified
 197      *          <code>principals</code>, <code>pubCredentials</code>,
 198      *          or <code>privCredentials</code> are <code>null</code>.
 199      */
 200     public Subject(boolean readOnly, Set<? extends Principal> principals,
 201                    Set<?> pubCredentials, Set<?> privCredentials)
 202     {
 203 
 204         if (principals == null ||
 205             pubCredentials == null ||
 206             privCredentials == null)
 207             throw new NullPointerException
 208                 (ResourcesMgr.getString("invalid null input(s)"));
 209 
 210         this.principals = Collections.synchronizedSet(new SecureSet<Principal>
 211                                 (this, PRINCIPAL_SET, principals));
 212         this.pubCredentials = Collections.synchronizedSet(new SecureSet<Object>
 213                                 (this, PUB_CREDENTIAL_SET, pubCredentials));
 214         this.privCredentials = Collections.synchronizedSet(new SecureSet<Object>
 215                                 (this, PRIV_CREDENTIAL_SET, privCredentials));
 216         this.readOnly = readOnly;
 217     }
 218 
 219     /**
 220      * Set this <code>Subject</code> to be read-only.
 221      *
 222      * <p> Modifications (additions and removals) to this Subject's
 223      * <code>Principal</code> <code>Set</code> and
 224      * credential Sets will be disallowed.
 225      * The <code>destroy</code> operation on this Subject's credentials will
 226      * still be permitted.
 227      *
 228      * <p> Subsequent attempts to modify the Subject's <code>Principal</code>


 273      * @return  the <code>Subject</code> associated with the provided
 274      *          <code>AccessControlContext</code>, or <code>null</code>
 275      *          if no <code>Subject</code> is associated
 276      *          with the provided <code>AccessControlContext</code>.
 277      *
 278      * @exception SecurityException if the caller does not have permission
 279      *          to get the <code>Subject</code>. <p>
 280      *
 281      * @exception NullPointerException if the provided
 282      *          <code>AccessControlContext</code> is <code>null</code>.
 283      */
 284     public static Subject getSubject(final AccessControlContext acc) {
 285 
 286         java.lang.SecurityManager sm = System.getSecurityManager();
 287         if (sm != null) {
 288             sm.checkPermission(new AuthPermission("getSubject"));
 289         }
 290 
 291         if (acc == null) {
 292             throw new NullPointerException(ResourcesMgr.getString
 293                 ("invalid null AccessControlContext provided"));
 294         }
 295 
 296         // return the Subject from the DomainCombiner of the provided context
 297         return AccessController.doPrivileged
 298             (new java.security.PrivilegedAction<Subject>() {
 299             public Subject run() {
 300                 DomainCombiner dc = acc.getDomainCombiner();
 301                 if (!(dc instanceof SubjectDomainCombiner))
 302                     return null;
 303                 SubjectDomainCombiner sdc = (SubjectDomainCombiner)dc;
 304                 return sdc.getSubject();
 305             }
 306         });
 307     }
 308 
 309     /**
 310      * Perform work as a particular <code>Subject</code>.
 311      *
 312      * <p> This method first retrieves the current Thread's
 313      * <code>AccessControlContext</code> via


 330      *                  <code>Subject</code>. <p>
 331      *
 332      * @return the value returned by the PrivilegedAction's
 333      *                  <code>run</code> method.
 334      *
 335      * @exception NullPointerException if the <code>PrivilegedAction</code>
 336      *                  is <code>null</code>. <p>
 337      *
 338      * @exception SecurityException if the caller does not have permission
 339      *                  to invoke this method.
 340      */
 341     public static <T> T doAs(final Subject subject,
 342                         final java.security.PrivilegedAction<T> action) {
 343 
 344         java.lang.SecurityManager sm = System.getSecurityManager();
 345         if (sm != null) {
 346             sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
 347         }
 348         if (action == null)
 349             throw new NullPointerException
 350                 (ResourcesMgr.getString("invalid null action provided"));
 351 
 352         // set up the new Subject-based AccessControlContext
 353         // for doPrivileged
 354         final AccessControlContext currentAcc = AccessController.getContext();
 355 
 356         // call doPrivileged and push this new context on the stack
 357         return java.security.AccessController.doPrivileged
 358                                         (action,
 359                                         createContext(subject, currentAcc));
 360     }
 361 
 362     /**
 363      * Perform work as a particular <code>Subject</code>.
 364      *
 365      * <p> This method first retrieves the current Thread's
 366      * <code>AccessControlContext</code> via
 367      * <code>AccessController.getContext</code>,
 368      * and then instantiates a new <code>AccessControlContext</code>
 369      * using the retrieved context along with a new
 370      * <code>SubjectDomainCombiner</code> (constructed using


 390      *                  method throws a checked exception. <p>
 391      *
 392      * @exception NullPointerException if the specified
 393      *                  <code>PrivilegedExceptionAction</code> is
 394      *                  <code>null</code>. <p>
 395      *
 396      * @exception SecurityException if the caller does not have permission
 397      *                  to invoke this method.
 398      */
 399     public static <T> T doAs(final Subject subject,
 400                         final java.security.PrivilegedExceptionAction<T> action)
 401                         throws java.security.PrivilegedActionException {
 402 
 403         java.lang.SecurityManager sm = System.getSecurityManager();
 404         if (sm != null) {
 405             sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
 406         }
 407 
 408         if (action == null)
 409             throw new NullPointerException
 410                 (ResourcesMgr.getString("invalid null action provided"));
 411 
 412         // set up the new Subject-based AccessControlContext for doPrivileged
 413         final AccessControlContext currentAcc = AccessController.getContext();
 414 
 415         // call doPrivileged and push this new context on the stack
 416         return java.security.AccessController.doPrivileged
 417                                         (action,
 418                                         createContext(subject, currentAcc));
 419     }
 420 
 421     /**
 422      * Perform privileged work as a particular <code>Subject</code>.
 423      *
 424      * <p> This method behaves exactly as <code>Subject.doAs</code>,
 425      * except that instead of retrieving the current Thread's
 426      * <code>AccessControlContext</code>, it uses the provided
 427      * <code>AccessControlContext</code>.  If the provided
 428      * <code>AccessControlContext</code> is <code>null</code>,
 429      * this method instantiates a new <code>AccessControlContext</code>
 430      * with an empty collection of ProtectionDomains.


 444      * @return the value returned by the PrivilegedAction's
 445      *                  <code>run</code> method.
 446      *
 447      * @exception NullPointerException if the <code>PrivilegedAction</code>
 448      *                  is <code>null</code>. <p>
 449      *
 450      * @exception SecurityException if the caller does not have permission
 451      *                  to invoke this method.
 452      */
 453     public static <T> T doAsPrivileged(final Subject subject,
 454                         final java.security.PrivilegedAction<T> action,
 455                         final java.security.AccessControlContext acc) {
 456 
 457         java.lang.SecurityManager sm = System.getSecurityManager();
 458         if (sm != null) {
 459             sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
 460         }
 461 
 462         if (action == null)
 463             throw new NullPointerException
 464                 (ResourcesMgr.getString("invalid null action provided"));
 465 
 466         // set up the new Subject-based AccessControlContext
 467         // for doPrivileged
 468         final AccessControlContext callerAcc =
 469                 (acc == null ?
 470                 new AccessControlContext(NULL_PD_ARRAY) :
 471                 acc);
 472 
 473         // call doPrivileged and push this new context on the stack
 474         return java.security.AccessController.doPrivileged
 475                                         (action,
 476                                         createContext(subject, callerAcc));
 477     }
 478 
 479     /**
 480      * Perform privileged work as a particular <code>Subject</code>.
 481      *
 482      * <p> This method behaves exactly as <code>Subject.doAs</code>,
 483      * except that instead of retrieving the current Thread's
 484      * <code>AccessControlContext</code>, it uses the provided


 508      *
 509      * @exception NullPointerException if the specified
 510      *                  <code>PrivilegedExceptionAction</code> is
 511      *                  <code>null</code>. <p>
 512      *
 513      * @exception SecurityException if the caller does not have permission
 514      *                  to invoke this method.
 515      */
 516     public static <T> T doAsPrivileged(final Subject subject,
 517                         final java.security.PrivilegedExceptionAction<T> action,
 518                         final java.security.AccessControlContext acc)
 519                         throws java.security.PrivilegedActionException {
 520 
 521         java.lang.SecurityManager sm = System.getSecurityManager();
 522         if (sm != null) {
 523             sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
 524         }
 525 
 526         if (action == null)
 527             throw new NullPointerException
 528                 (ResourcesMgr.getString("invalid null action provided"));
 529 
 530         // set up the new Subject-based AccessControlContext for doPrivileged
 531         final AccessControlContext callerAcc =
 532                 (acc == null ?
 533                 new AccessControlContext(NULL_PD_ARRAY) :
 534                 acc);
 535 
 536         // call doPrivileged and push this new context on the stack
 537         return java.security.AccessController.doPrivileged
 538                                         (action,
 539                                         createContext(subject, callerAcc));
 540     }
 541 
 542     private static AccessControlContext createContext(final Subject subject,
 543                                         final AccessControlContext acc) {
 544 
 545 
 546         return java.security.AccessController.doPrivileged
 547             (new java.security.PrivilegedAction<AccessControlContext>() {
 548             public AccessControlContext run() {


 587      * internal <code>Principal</code> <code>Set</code>.  A new
 588      * <code>Set</code> is created and returned for each method invocation.
 589      * Modifications to the returned <code>Set</code>
 590      * will not affect the internal <code>Principal</code> <code>Set</code>.
 591      *
 592      * <p>
 593      *
 594      * @param c the returned <code>Set</code> of Principals will all be
 595      *          instances of this class.
 596      *
 597      * @return a <code>Set</code> of Principals that are instances of the
 598      *          specified <code>Class</code>.
 599      *
 600      * @exception NullPointerException if the specified <code>Class</code>
 601      *                  is <code>null</code>.
 602      */
 603     public <T extends Principal> Set<T> getPrincipals(Class<T> c) {
 604 
 605         if (c == null)
 606             throw new NullPointerException
 607                 (ResourcesMgr.getString("invalid null Class provided"));
 608 
 609         // always return an empty Set instead of null
 610         // so LoginModules can add to the Set if necessary
 611         return new ClassSet<T>(PRINCIPAL_SET, c);
 612     }
 613 
 614     /**
 615      * Return the <code>Set</code> of public credentials held by this
 616      * <code>Subject</code>.
 617      *
 618      * <p> The returned <code>Set</code> is backed by this Subject's
 619      * internal public Credential <code>Set</code>.  Any modification
 620      * to the returned <code>Set</code> affects the internal public
 621      * Credential <code>Set</code> as well.
 622      *
 623      * <p>
 624      *
 625      * @return  A <code>Set</code> of public credentials held by this
 626      *          <code>Subject</code>.
 627      */


 681      * internal public Credential <code>Set</code>.  A new
 682      * <code>Set</code> is created and returned for each method invocation.
 683      * Modifications to the returned <code>Set</code>
 684      * will not affect the internal public Credential <code>Set</code>.
 685      *
 686      * <p>
 687      *
 688      * @param c the returned <code>Set</code> of public credentials will all be
 689      *          instances of this class.
 690      *
 691      * @return a <code>Set</code> of public credentials that are instances
 692      *          of the  specified <code>Class</code>.
 693      *
 694      * @exception NullPointerException if the specified <code>Class</code>
 695      *          is <code>null</code>.
 696      */
 697     public <T> Set<T> getPublicCredentials(Class<T> c) {
 698 
 699         if (c == null)
 700             throw new NullPointerException
 701                 (ResourcesMgr.getString("invalid null Class provided"));
 702 
 703         // always return an empty Set instead of null
 704         // so LoginModules can add to the Set if necessary
 705         return new ClassSet<T>(PUB_CREDENTIAL_SET, c);
 706     }
 707 
 708     /**
 709      * Return a <code>Set</code> of private credentials associated with this
 710      * <code>Subject</code> that are instances or subclasses of the specified
 711      * <code>Class</code>.
 712      *
 713      * <p> The caller must have permission to access all of the
 714      * requested Credentials, or a <code>SecurityException</code>
 715      * will be thrown.
 716      *
 717      * <p> The returned <code>Set</code> is not backed by this Subject's
 718      * internal private Credential <code>Set</code>.  A new
 719      * <code>Set</code> is created and returned for each method invocation.
 720      * Modifications to the returned <code>Set</code>
 721      * will not affect the internal private Credential <code>Set</code>.


 726      *          instances of this class.
 727      *
 728      * @return a <code>Set</code> of private credentials that are instances
 729      *          of the  specified <code>Class</code>.
 730      *
 731      * @exception NullPointerException if the specified <code>Class</code>
 732      *          is <code>null</code>.
 733      */
 734     public <T> Set<T> getPrivateCredentials(Class<T> c) {
 735 
 736         // XXX
 737         // we do not need a security check for
 738         // AuthPermission(getPrivateCredentials)
 739         // because we already restrict access to private credentials
 740         // via the PrivateCredentialPermission.  all the extra AuthPermission
 741         // would do is protect the set operations themselves
 742         // (like size()), which don't seem security-sensitive.
 743 
 744         if (c == null)
 745             throw new NullPointerException
 746                 (ResourcesMgr.getString("invalid null Class provided"));
 747 
 748         // always return an empty Set instead of null
 749         // so LoginModules can add to the Set if necessary
 750         return new ClassSet<T>(PRIV_CREDENTIAL_SET, c);
 751     }
 752 
 753     /**
 754      * Compares the specified Object with this <code>Subject</code>
 755      * for equality.  Returns true if the given object is also a Subject
 756      * and the two <code>Subject</code> instances are equivalent.
 757      * More formally, two <code>Subject</code> instances are
 758      * equal if their <code>Principal</code> and <code>Credential</code>
 759      * Sets are equal.
 760      *
 761      * <p>
 762      *
 763      * @param o Object to be compared for equality with this
 764      *          <code>Subject</code>.
 765      *
 766      * @return true if the specified Object is equal to this


 816     }
 817 
 818     /**
 819      * Return the String representation of this <code>Subject</code>.
 820      *
 821      * <p>
 822      *
 823      * @return the String representation of this <code>Subject</code>.
 824      */
 825     public String toString() {
 826         return toString(true);
 827     }
 828 
 829     /**
 830      * package private convenience method to print out the Subject
 831      * without firing off a security check when trying to access
 832      * the Private Credentials
 833      */
 834     String toString(boolean includePrivateCredentials) {
 835 
 836         String s = ResourcesMgr.getString("Subject:\n");
 837         String suffix = "";
 838 
 839         synchronized(principals) {
 840             Iterator<Principal> pI = principals.iterator();
 841             while (pI.hasNext()) {
 842                 Principal p = pI.next();
 843                 suffix = suffix + ResourcesMgr.getString("\tPrincipal: ") +
 844                         p.toString() + ResourcesMgr.getString("\n");
 845             }
 846         }
 847 
 848         synchronized(pubCredentials) {
 849             Iterator<Object> pI = pubCredentials.iterator();
 850             while (pI.hasNext()) {
 851                 Object o = pI.next();
 852                 suffix = suffix +
 853                         ResourcesMgr.getString("\tPublic Credential: ") +
 854                         o.toString() + ResourcesMgr.getString("\n");
 855             }
 856         }
 857 
 858         if (includePrivateCredentials) {
 859             synchronized(privCredentials) {
 860                 Iterator<Object> pI = privCredentials.iterator();
 861                 while (pI.hasNext()) {
 862                     try {
 863                         Object o = pI.next();
 864                         suffix += ResourcesMgr.getString
 865                                         ("\tPrivate Credential: ") +
 866                                         o.toString() +
 867                                         ResourcesMgr.getString("\n");
 868                     } catch (SecurityException se) {
 869                         suffix += ResourcesMgr.getString
 870                                 ("\tPrivate Credential inaccessible\n");
 871                         break;
 872                     }
 873                 }
 874             }
 875         }
 876         return s + suffix;
 877     }
 878 
 879     /**
 880      * Returns a hashcode for this <code>Subject</code>.
 881      *
 882      * <p>
 883      *
 884      * @return a hashcode for this <code>Subject</code>.
 885      *
 886      * @exception SecurityException if the caller does not have permission
 887      *          to access this Subject's private credentials.
 888      */
 889     public int hashCode() {
 890 


1024                     }
1025 
1026                     SecurityManager sm = System.getSecurityManager();
1027                     if (sm != null) {
1028                         try {
1029                             sm.checkPermission(new PrivateCredentialPermission
1030                                 (list.get(i.nextIndex()).getClass().getName(),
1031                                 subject.getPrincipals()));
1032                         } catch (SecurityException se) {
1033                             i.next();
1034                             throw (se);
1035                         }
1036                     }
1037                     return i.next();
1038                 }
1039 
1040                 public void remove() {
1041 
1042                     if (subject.isReadOnly()) {
1043                         throw new IllegalStateException(ResourcesMgr.getString
1044                                 ("Subject is read-only"));
1045                     }
1046 
1047                     java.lang.SecurityManager sm = System.getSecurityManager();
1048                     if (sm != null) {
1049                         switch (which) {
1050                         case Subject.PRINCIPAL_SET:
1051                             sm.checkPermission(new AuthPermission
1052                                         ("modifyPrincipals"));
1053                             break;
1054                         case Subject.PUB_CREDENTIAL_SET:
1055                             sm.checkPermission(new AuthPermission
1056                                         ("modifyPublicCredentials"));
1057                             break;
1058                         default:
1059                             sm.checkPermission(new AuthPermission
1060                                         ("modifyPrivateCredentials"));
1061                             break;
1062                         }
1063                     }
1064                     i.remove();
1065                 }
1066             };
1067         }
1068 
1069         public boolean add(E o) {
1070 
1071             if (subject.isReadOnly()) {
1072                 throw new IllegalStateException
1073                         (ResourcesMgr.getString("Subject is read-only"));
1074             }
1075 
1076             java.lang.SecurityManager sm = System.getSecurityManager();
1077             if (sm != null) {
1078                 switch (which) {
1079                 case Subject.PRINCIPAL_SET:
1080                     sm.checkPermission
1081                         (new AuthPermission("modifyPrincipals"));
1082                     break;
1083                 case Subject.PUB_CREDENTIAL_SET:
1084                     sm.checkPermission
1085                         (new AuthPermission("modifyPublicCredentials"));
1086                     break;
1087                 default:
1088                     sm.checkPermission
1089                         (new AuthPermission("modifyPrivateCredentials"));
1090                     break;
1091                 }
1092             }
1093 
1094             switch (which) {
1095             case Subject.PRINCIPAL_SET:
1096                 if (!(o instanceof Principal)) {
1097                     throw new SecurityException(ResourcesMgr.getString
1098                         ("attempting to add an object which is not an " +
1099                         "instance of java.security.Principal to a " +
1100                         "Subject's Principal Set"));
1101                 }
1102                 break;
1103             default:
1104                 // ok to add Objects of any kind to credential sets
1105                 break;
1106             }
1107 
1108             // check for duplicates
1109             if (!elements.contains(o))
1110                 return elements.add(o);
1111             else
1112                 return false;
1113         }
1114 
1115         public boolean remove(Object o) {
1116 
1117             final Iterator<E> e = iterator();
1118             while (e.hasNext()) {
1119                 E next;
1120                 if (which != Subject.PRIV_CREDENTIAL_SET) {


1389                                                 Subject.this.getPrincipals()));
1390                         }
1391                         set.add((T)next);
1392                     }
1393                 }
1394             }
1395         }
1396 
1397         public int size() {
1398             return set.size();
1399         }
1400 
1401         public Iterator<T> iterator() {
1402             return set.iterator();
1403         }
1404 
1405         public boolean add(T o) {
1406 
1407             if (!o.getClass().isAssignableFrom(c)) {
1408                 MessageFormat form = new MessageFormat(ResourcesMgr.getString
1409                         ("attempting to add an object which is not an " +
1410                         "instance of class"));
1411                 Object[] source = {c.toString()};
1412                 throw new SecurityException(form.format(source));
1413             }
1414 
1415             return set.add(o);
1416         }
1417     }
1418 }
   1 /*
   2  * Copyright (c) 1998, 2010, 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


 188      *          to be associated with this <code>Subject</code>. <p>
 189      *
 190      * @param pubCredentials the <code>Set</code> of public credentials
 191      *          to be associated with this <code>Subject</code>. <p>
 192      *
 193      * @param privCredentials the <code>Set</code> of private credentials
 194      *          to be associated with this <code>Subject</code>.
 195      *
 196      * @exception NullPointerException if the specified
 197      *          <code>principals</code>, <code>pubCredentials</code>,
 198      *          or <code>privCredentials</code> are <code>null</code>.
 199      */
 200     public Subject(boolean readOnly, Set<? extends Principal> principals,
 201                    Set<?> pubCredentials, Set<?> privCredentials)
 202     {
 203 
 204         if (principals == null ||
 205             pubCredentials == null ||
 206             privCredentials == null)
 207             throw new NullPointerException
 208                 (ResourcesMgr.getString("invalid.null.input.s."));
 209 
 210         this.principals = Collections.synchronizedSet(new SecureSet<Principal>
 211                                 (this, PRINCIPAL_SET, principals));
 212         this.pubCredentials = Collections.synchronizedSet(new SecureSet<Object>
 213                                 (this, PUB_CREDENTIAL_SET, pubCredentials));
 214         this.privCredentials = Collections.synchronizedSet(new SecureSet<Object>
 215                                 (this, PRIV_CREDENTIAL_SET, privCredentials));
 216         this.readOnly = readOnly;
 217     }
 218 
 219     /**
 220      * Set this <code>Subject</code> to be read-only.
 221      *
 222      * <p> Modifications (additions and removals) to this Subject's
 223      * <code>Principal</code> <code>Set</code> and
 224      * credential Sets will be disallowed.
 225      * The <code>destroy</code> operation on this Subject's credentials will
 226      * still be permitted.
 227      *
 228      * <p> Subsequent attempts to modify the Subject's <code>Principal</code>


 273      * @return  the <code>Subject</code> associated with the provided
 274      *          <code>AccessControlContext</code>, or <code>null</code>
 275      *          if no <code>Subject</code> is associated
 276      *          with the provided <code>AccessControlContext</code>.
 277      *
 278      * @exception SecurityException if the caller does not have permission
 279      *          to get the <code>Subject</code>. <p>
 280      *
 281      * @exception NullPointerException if the provided
 282      *          <code>AccessControlContext</code> is <code>null</code>.
 283      */
 284     public static Subject getSubject(final AccessControlContext acc) {
 285 
 286         java.lang.SecurityManager sm = System.getSecurityManager();
 287         if (sm != null) {
 288             sm.checkPermission(new AuthPermission("getSubject"));
 289         }
 290 
 291         if (acc == null) {
 292             throw new NullPointerException(ResourcesMgr.getString
 293                 ("invalid.null.AccessControlContext.provided"));
 294         }
 295 
 296         // return the Subject from the DomainCombiner of the provided context
 297         return AccessController.doPrivileged
 298             (new java.security.PrivilegedAction<Subject>() {
 299             public Subject run() {
 300                 DomainCombiner dc = acc.getDomainCombiner();
 301                 if (!(dc instanceof SubjectDomainCombiner))
 302                     return null;
 303                 SubjectDomainCombiner sdc = (SubjectDomainCombiner)dc;
 304                 return sdc.getSubject();
 305             }
 306         });
 307     }
 308 
 309     /**
 310      * Perform work as a particular <code>Subject</code>.
 311      *
 312      * <p> This method first retrieves the current Thread's
 313      * <code>AccessControlContext</code> via


 330      *                  <code>Subject</code>. <p>
 331      *
 332      * @return the value returned by the PrivilegedAction's
 333      *                  <code>run</code> method.
 334      *
 335      * @exception NullPointerException if the <code>PrivilegedAction</code>
 336      *                  is <code>null</code>. <p>
 337      *
 338      * @exception SecurityException if the caller does not have permission
 339      *                  to invoke this method.
 340      */
 341     public static <T> T doAs(final Subject subject,
 342                         final java.security.PrivilegedAction<T> action) {
 343 
 344         java.lang.SecurityManager sm = System.getSecurityManager();
 345         if (sm != null) {
 346             sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
 347         }
 348         if (action == null)
 349             throw new NullPointerException
 350                 (ResourcesMgr.getString("invalid.null.action.provided"));
 351 
 352         // set up the new Subject-based AccessControlContext
 353         // for doPrivileged
 354         final AccessControlContext currentAcc = AccessController.getContext();
 355 
 356         // call doPrivileged and push this new context on the stack
 357         return java.security.AccessController.doPrivileged
 358                                         (action,
 359                                         createContext(subject, currentAcc));
 360     }
 361 
 362     /**
 363      * Perform work as a particular <code>Subject</code>.
 364      *
 365      * <p> This method first retrieves the current Thread's
 366      * <code>AccessControlContext</code> via
 367      * <code>AccessController.getContext</code>,
 368      * and then instantiates a new <code>AccessControlContext</code>
 369      * using the retrieved context along with a new
 370      * <code>SubjectDomainCombiner</code> (constructed using


 390      *                  method throws a checked exception. <p>
 391      *
 392      * @exception NullPointerException if the specified
 393      *                  <code>PrivilegedExceptionAction</code> is
 394      *                  <code>null</code>. <p>
 395      *
 396      * @exception SecurityException if the caller does not have permission
 397      *                  to invoke this method.
 398      */
 399     public static <T> T doAs(final Subject subject,
 400                         final java.security.PrivilegedExceptionAction<T> action)
 401                         throws java.security.PrivilegedActionException {
 402 
 403         java.lang.SecurityManager sm = System.getSecurityManager();
 404         if (sm != null) {
 405             sm.checkPermission(SecurityConstants.DO_AS_PERMISSION);
 406         }
 407 
 408         if (action == null)
 409             throw new NullPointerException
 410                 (ResourcesMgr.getString("invalid.null.action.provided"));
 411 
 412         // set up the new Subject-based AccessControlContext for doPrivileged
 413         final AccessControlContext currentAcc = AccessController.getContext();
 414 
 415         // call doPrivileged and push this new context on the stack
 416         return java.security.AccessController.doPrivileged
 417                                         (action,
 418                                         createContext(subject, currentAcc));
 419     }
 420 
 421     /**
 422      * Perform privileged work as a particular <code>Subject</code>.
 423      *
 424      * <p> This method behaves exactly as <code>Subject.doAs</code>,
 425      * except that instead of retrieving the current Thread's
 426      * <code>AccessControlContext</code>, it uses the provided
 427      * <code>AccessControlContext</code>.  If the provided
 428      * <code>AccessControlContext</code> is <code>null</code>,
 429      * this method instantiates a new <code>AccessControlContext</code>
 430      * with an empty collection of ProtectionDomains.


 444      * @return the value returned by the PrivilegedAction's
 445      *                  <code>run</code> method.
 446      *
 447      * @exception NullPointerException if the <code>PrivilegedAction</code>
 448      *                  is <code>null</code>. <p>
 449      *
 450      * @exception SecurityException if the caller does not have permission
 451      *                  to invoke this method.
 452      */
 453     public static <T> T doAsPrivileged(final Subject subject,
 454                         final java.security.PrivilegedAction<T> action,
 455                         final java.security.AccessControlContext acc) {
 456 
 457         java.lang.SecurityManager sm = System.getSecurityManager();
 458         if (sm != null) {
 459             sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
 460         }
 461 
 462         if (action == null)
 463             throw new NullPointerException
 464                 (ResourcesMgr.getString("invalid.null.action.provided"));
 465 
 466         // set up the new Subject-based AccessControlContext
 467         // for doPrivileged
 468         final AccessControlContext callerAcc =
 469                 (acc == null ?
 470                 new AccessControlContext(NULL_PD_ARRAY) :
 471                 acc);
 472 
 473         // call doPrivileged and push this new context on the stack
 474         return java.security.AccessController.doPrivileged
 475                                         (action,
 476                                         createContext(subject, callerAcc));
 477     }
 478 
 479     /**
 480      * Perform privileged work as a particular <code>Subject</code>.
 481      *
 482      * <p> This method behaves exactly as <code>Subject.doAs</code>,
 483      * except that instead of retrieving the current Thread's
 484      * <code>AccessControlContext</code>, it uses the provided


 508      *
 509      * @exception NullPointerException if the specified
 510      *                  <code>PrivilegedExceptionAction</code> is
 511      *                  <code>null</code>. <p>
 512      *
 513      * @exception SecurityException if the caller does not have permission
 514      *                  to invoke this method.
 515      */
 516     public static <T> T doAsPrivileged(final Subject subject,
 517                         final java.security.PrivilegedExceptionAction<T> action,
 518                         final java.security.AccessControlContext acc)
 519                         throws java.security.PrivilegedActionException {
 520 
 521         java.lang.SecurityManager sm = System.getSecurityManager();
 522         if (sm != null) {
 523             sm.checkPermission(SecurityConstants.DO_AS_PRIVILEGED_PERMISSION);
 524         }
 525 
 526         if (action == null)
 527             throw new NullPointerException
 528                 (ResourcesMgr.getString("invalid.null.action.provided"));
 529 
 530         // set up the new Subject-based AccessControlContext for doPrivileged
 531         final AccessControlContext callerAcc =
 532                 (acc == null ?
 533                 new AccessControlContext(NULL_PD_ARRAY) :
 534                 acc);
 535 
 536         // call doPrivileged and push this new context on the stack
 537         return java.security.AccessController.doPrivileged
 538                                         (action,
 539                                         createContext(subject, callerAcc));
 540     }
 541 
 542     private static AccessControlContext createContext(final Subject subject,
 543                                         final AccessControlContext acc) {
 544 
 545 
 546         return java.security.AccessController.doPrivileged
 547             (new java.security.PrivilegedAction<AccessControlContext>() {
 548             public AccessControlContext run() {


 587      * internal <code>Principal</code> <code>Set</code>.  A new
 588      * <code>Set</code> is created and returned for each method invocation.
 589      * Modifications to the returned <code>Set</code>
 590      * will not affect the internal <code>Principal</code> <code>Set</code>.
 591      *
 592      * <p>
 593      *
 594      * @param c the returned <code>Set</code> of Principals will all be
 595      *          instances of this class.
 596      *
 597      * @return a <code>Set</code> of Principals that are instances of the
 598      *          specified <code>Class</code>.
 599      *
 600      * @exception NullPointerException if the specified <code>Class</code>
 601      *                  is <code>null</code>.
 602      */
 603     public <T extends Principal> Set<T> getPrincipals(Class<T> c) {
 604 
 605         if (c == null)
 606             throw new NullPointerException
 607                 (ResourcesMgr.getString("invalid.null.Class.provided"));
 608 
 609         // always return an empty Set instead of null
 610         // so LoginModules can add to the Set if necessary
 611         return new ClassSet<T>(PRINCIPAL_SET, c);
 612     }
 613 
 614     /**
 615      * Return the <code>Set</code> of public credentials held by this
 616      * <code>Subject</code>.
 617      *
 618      * <p> The returned <code>Set</code> is backed by this Subject's
 619      * internal public Credential <code>Set</code>.  Any modification
 620      * to the returned <code>Set</code> affects the internal public
 621      * Credential <code>Set</code> as well.
 622      *
 623      * <p>
 624      *
 625      * @return  A <code>Set</code> of public credentials held by this
 626      *          <code>Subject</code>.
 627      */


 681      * internal public Credential <code>Set</code>.  A new
 682      * <code>Set</code> is created and returned for each method invocation.
 683      * Modifications to the returned <code>Set</code>
 684      * will not affect the internal public Credential <code>Set</code>.
 685      *
 686      * <p>
 687      *
 688      * @param c the returned <code>Set</code> of public credentials will all be
 689      *          instances of this class.
 690      *
 691      * @return a <code>Set</code> of public credentials that are instances
 692      *          of the  specified <code>Class</code>.
 693      *
 694      * @exception NullPointerException if the specified <code>Class</code>
 695      *          is <code>null</code>.
 696      */
 697     public <T> Set<T> getPublicCredentials(Class<T> c) {
 698 
 699         if (c == null)
 700             throw new NullPointerException
 701                 (ResourcesMgr.getString("invalid.null.Class.provided"));
 702 
 703         // always return an empty Set instead of null
 704         // so LoginModules can add to the Set if necessary
 705         return new ClassSet<T>(PUB_CREDENTIAL_SET, c);
 706     }
 707 
 708     /**
 709      * Return a <code>Set</code> of private credentials associated with this
 710      * <code>Subject</code> that are instances or subclasses of the specified
 711      * <code>Class</code>.
 712      *
 713      * <p> The caller must have permission to access all of the
 714      * requested Credentials, or a <code>SecurityException</code>
 715      * will be thrown.
 716      *
 717      * <p> The returned <code>Set</code> is not backed by this Subject's
 718      * internal private Credential <code>Set</code>.  A new
 719      * <code>Set</code> is created and returned for each method invocation.
 720      * Modifications to the returned <code>Set</code>
 721      * will not affect the internal private Credential <code>Set</code>.


 726      *          instances of this class.
 727      *
 728      * @return a <code>Set</code> of private credentials that are instances
 729      *          of the  specified <code>Class</code>.
 730      *
 731      * @exception NullPointerException if the specified <code>Class</code>
 732      *          is <code>null</code>.
 733      */
 734     public <T> Set<T> getPrivateCredentials(Class<T> c) {
 735 
 736         // XXX
 737         // we do not need a security check for
 738         // AuthPermission(getPrivateCredentials)
 739         // because we already restrict access to private credentials
 740         // via the PrivateCredentialPermission.  all the extra AuthPermission
 741         // would do is protect the set operations themselves
 742         // (like size()), which don't seem security-sensitive.
 743 
 744         if (c == null)
 745             throw new NullPointerException
 746                 (ResourcesMgr.getString("invalid.null.Class.provided"));
 747 
 748         // always return an empty Set instead of null
 749         // so LoginModules can add to the Set if necessary
 750         return new ClassSet<T>(PRIV_CREDENTIAL_SET, c);
 751     }
 752 
 753     /**
 754      * Compares the specified Object with this <code>Subject</code>
 755      * for equality.  Returns true if the given object is also a Subject
 756      * and the two <code>Subject</code> instances are equivalent.
 757      * More formally, two <code>Subject</code> instances are
 758      * equal if their <code>Principal</code> and <code>Credential</code>
 759      * Sets are equal.
 760      *
 761      * <p>
 762      *
 763      * @param o Object to be compared for equality with this
 764      *          <code>Subject</code>.
 765      *
 766      * @return true if the specified Object is equal to this


 816     }
 817 
 818     /**
 819      * Return the String representation of this <code>Subject</code>.
 820      *
 821      * <p>
 822      *
 823      * @return the String representation of this <code>Subject</code>.
 824      */
 825     public String toString() {
 826         return toString(true);
 827     }
 828 
 829     /**
 830      * package private convenience method to print out the Subject
 831      * without firing off a security check when trying to access
 832      * the Private Credentials
 833      */
 834     String toString(boolean includePrivateCredentials) {
 835 
 836         String s = ResourcesMgr.getString("Subject.");
 837         String suffix = "";
 838 
 839         synchronized(principals) {
 840             Iterator<Principal> pI = principals.iterator();
 841             while (pI.hasNext()) {
 842                 Principal p = pI.next();
 843                 suffix = suffix + ResourcesMgr.getString(".Principal.") +
 844                         p.toString() + ResourcesMgr.getString("NEWLINE");
 845             }
 846         }
 847 
 848         synchronized(pubCredentials) {
 849             Iterator<Object> pI = pubCredentials.iterator();
 850             while (pI.hasNext()) {
 851                 Object o = pI.next();
 852                 suffix = suffix +
 853                         ResourcesMgr.getString(".Public.Credential.") +
 854                         o.toString() + ResourcesMgr.getString("NEWLINE");
 855             }
 856         }
 857 
 858         if (includePrivateCredentials) {
 859             synchronized(privCredentials) {
 860                 Iterator<Object> pI = privCredentials.iterator();
 861                 while (pI.hasNext()) {
 862                     try {
 863                         Object o = pI.next();
 864                         suffix += ResourcesMgr.getString
 865                                         (".Private.Credential.") +
 866                                         o.toString() +
 867                                         ResourcesMgr.getString("NEWLINE");
 868                     } catch (SecurityException se) {
 869                         suffix += ResourcesMgr.getString
 870                                 (".Private.Credential.inaccessible.");
 871                         break;
 872                     }
 873                 }
 874             }
 875         }
 876         return s + suffix;
 877     }
 878 
 879     /**
 880      * Returns a hashcode for this <code>Subject</code>.
 881      *
 882      * <p>
 883      *
 884      * @return a hashcode for this <code>Subject</code>.
 885      *
 886      * @exception SecurityException if the caller does not have permission
 887      *          to access this Subject's private credentials.
 888      */
 889     public int hashCode() {
 890 


1024                     }
1025 
1026                     SecurityManager sm = System.getSecurityManager();
1027                     if (sm != null) {
1028                         try {
1029                             sm.checkPermission(new PrivateCredentialPermission
1030                                 (list.get(i.nextIndex()).getClass().getName(),
1031                                 subject.getPrincipals()));
1032                         } catch (SecurityException se) {
1033                             i.next();
1034                             throw (se);
1035                         }
1036                     }
1037                     return i.next();
1038                 }
1039 
1040                 public void remove() {
1041 
1042                     if (subject.isReadOnly()) {
1043                         throw new IllegalStateException(ResourcesMgr.getString
1044                                 ("Subject.is.read.only"));
1045                     }
1046 
1047                     java.lang.SecurityManager sm = System.getSecurityManager();
1048                     if (sm != null) {
1049                         switch (which) {
1050                         case Subject.PRINCIPAL_SET:
1051                             sm.checkPermission(new AuthPermission
1052                                         ("modifyPrincipals"));
1053                             break;
1054                         case Subject.PUB_CREDENTIAL_SET:
1055                             sm.checkPermission(new AuthPermission
1056                                         ("modifyPublicCredentials"));
1057                             break;
1058                         default:
1059                             sm.checkPermission(new AuthPermission
1060                                         ("modifyPrivateCredentials"));
1061                             break;
1062                         }
1063                     }
1064                     i.remove();
1065                 }
1066             };
1067         }
1068 
1069         public boolean add(E o) {
1070 
1071             if (subject.isReadOnly()) {
1072                 throw new IllegalStateException
1073                         (ResourcesMgr.getString("Subject.is.read.only"));
1074             }
1075 
1076             java.lang.SecurityManager sm = System.getSecurityManager();
1077             if (sm != null) {
1078                 switch (which) {
1079                 case Subject.PRINCIPAL_SET:
1080                     sm.checkPermission
1081                         (new AuthPermission("modifyPrincipals"));
1082                     break;
1083                 case Subject.PUB_CREDENTIAL_SET:
1084                     sm.checkPermission
1085                         (new AuthPermission("modifyPublicCredentials"));
1086                     break;
1087                 default:
1088                     sm.checkPermission
1089                         (new AuthPermission("modifyPrivateCredentials"));
1090                     break;
1091                 }
1092             }
1093 
1094             switch (which) {
1095             case Subject.PRINCIPAL_SET:
1096                 if (!(o instanceof Principal)) {
1097                     throw new SecurityException(ResourcesMgr.getString
1098                         ("attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set"));


1099                 }
1100                 break;
1101             default:
1102                 // ok to add Objects of any kind to credential sets
1103                 break;
1104             }
1105 
1106             // check for duplicates
1107             if (!elements.contains(o))
1108                 return elements.add(o);
1109             else
1110                 return false;
1111         }
1112 
1113         public boolean remove(Object o) {
1114 
1115             final Iterator<E> e = iterator();
1116             while (e.hasNext()) {
1117                 E next;
1118                 if (which != Subject.PRIV_CREDENTIAL_SET) {


1387                                                 Subject.this.getPrincipals()));
1388                         }
1389                         set.add((T)next);
1390                     }
1391                 }
1392             }
1393         }
1394 
1395         public int size() {
1396             return set.size();
1397         }
1398 
1399         public Iterator<T> iterator() {
1400             return set.iterator();
1401         }
1402 
1403         public boolean add(T o) {
1404 
1405             if (!o.getClass().isAssignableFrom(c)) {
1406                 MessageFormat form = new MessageFormat(ResourcesMgr.getString
1407                         ("attempting.to.add.an.object.which.is.not.an.instance.of.class"));

1408                 Object[] source = {c.toString()};
1409                 throw new SecurityException(form.format(source));
1410             }
1411 
1412             return set.add(o);
1413         }
1414     }
1415 }
< prev index next >