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 }
|