History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/security/auth/Subject.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/security/auth/Subject.java+1421−0
@@ -0,0 +1,1421 @@
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
23+ * questions.
24+ */
25+
26+package javax.security.auth;
27+
28+import java.util.*;
29+import java.io.*;
30+import java.lang.reflect.*;
31+import java.text.MessageFormat;
32+import java.security.AccessController;
33+import java.security.AccessControlContext;
34+import java.security.DomainCombiner;
35+import java.security.Permission;
36+import java.security.PermissionCollection;
37+import java.security.Principal;
38+import java.security.PrivilegedAction;
39+import java.security.PrivilegedExceptionAction;
40+import java.security.PrivilegedActionException;
41+import java.security.ProtectionDomain;
42+import sun.security.util.ResourcesMgr;
43+
44+/**
45+ * <p> A <code>Subject</code> represents a grouping of related information
46+ * for a single entity, such as a person.
47+ * Such information includes the Subject's identities as well as
48+ * its security-related attributes
49+ * (passwords and cryptographic keys, for example).
50+ *
51+ * <p> Subjects may potentially have multiple identities.
52+ * Each identity is represented as a <code>Principal</code>
53+ * within the <code>Subject</code>. Principals simply bind names to a
54+ * <code>Subject</code>. For example, a <code>Subject</code> that happens
55+ * to be a person, Alice, might have two Principals:
56+ * one which binds "Alice Bar", the name on her driver license,
57+ * to the <code>Subject</code>, and another which binds,
58+ * "999-99-9999", the number on her student identification card,
59+ * to the <code>Subject</code>. Both Principals refer to the same
60+ * <code>Subject</code> even though each has a different name.
61+ *
62+ * <p> A <code>Subject</code> may also own security-related attributes,
63+ * which are referred to as credentials.
64+ * Sensitive credentials that require special protection, such as
65+ * private cryptographic keys, are stored within a private credential
66+ * <code>Set</code>. Credentials intended to be shared, such as
67+ * public key certificates or Kerberos server tickets are stored
68+ * within a public credential <code>Set</code>. Different permissions
69+ * are required to access and modify the different credential Sets.
70+ *
71+ * <p> To retrieve all the Principals associated with a <code>Subject</code>,
72+ * invoke the <code>getPrincipals</code> method. To retrieve
73+ * all the public or private credentials belonging to a <code>Subject</code>,
74+ * invoke the <code>getPublicCredentials</code> method or
75+ * <code>getPrivateCredentials</code> method, respectively.
76+ * To modify the returned <code>Set</code> of Principals and credentials,
77+ * use the methods defined in the <code>Set</code> class.
78+ * For example:
79+ * <pre>
80+ * Subject subject;
81+ * Principal principal;
82+ * Object credential;
83+ *
84+ * // add a Principal and credential to the Subject
85+ * subject.getPrincipals().add(principal);
86+ * subject.getPublicCredentials().add(credential);
87+ * </pre>
88+ *
89+ * <p> This <code>Subject</code> class implements <code>Serializable</code>.
90+ * While the Principals associated with the <code>Subject</code> are serialized,
91+ * the credentials associated with the <code>Subject</code> are not.
92+ * Note that the <code>java.security.Principal</code> class
93+ * does not implement <code>Serializable</code>. Therefore all concrete
94+ * <code>Principal</code> implementations associated with Subjects
95+ * must implement <code>Serializable</code>.
96+ *
97+ * @see java.security.Principal
98+ * @see java.security.DomainCombiner
99+ */
100+public final class Subject implements java.io.Serializable {
101+
102+ private static final long serialVersionUID = -8308522755600156056L;
103+
104+ /**
105+ * A <code>Set</code> that provides a view of all of this
106+ * Subject's Principals
107+ *
108+ * <p>
109+ *
110+ * @serial Each element in this set is a
111+ * <code>java.security.Principal</code>.
112+ * The set is a <code>Subject.SecureSet</code>.
113+ */
114+ Set<Principal> principals;
115+
116+ /**
117+ * Sets that provide a view of all of this
118+ * Subject's Credentials
119+ */
120+ transient Set<Object> pubCredentials;
121+ transient Set<Object> privCredentials;
122+
123+ /**
124+ * Whether this Subject is read-only
125+ *
126+ * @serial
127+ */
128+ private volatile boolean readOnly = false;
129+
130+ private static final int PRINCIPAL_SET = 1;
131+ private static final int PUB_CREDENTIAL_SET = 2;
132+ private static final int PRIV_CREDENTIAL_SET = 3;
133+
134+ private static final ProtectionDomain[] NULL_PD_ARRAY
135+ = new ProtectionDomain[0];
136+
137+ /**
138+ * Create an instance of a <code>Subject</code>
139+ * with an empty <code>Set</code> of Principals and empty
140+ * Sets of public and private credentials.
141+ *
142+ * <p> The newly constructed Sets check whether this <code>Subject</code>
143+ * has been set read-only before permitting subsequent modifications.
144+ * The newly created Sets also prevent illegal modifications
145+ * by ensuring that callers have sufficient permissions.
146+ *
147+ * <p> To modify the Principals Set, the caller must have
148+ * <code>AuthPermission("modifyPrincipals")</code>.
149+ * To modify the public credential Set, the caller must have
150+ * <code>AuthPermission("modifyPublicCredentials")</code>.
151+ * To modify the private credential Set, the caller must have
152+ * <code>AuthPermission("modifyPrivateCredentials")</code>.
153+ */
154+ public Subject() {
155+
156+ this.principals = Collections.synchronizedSet
157+ (new SecureSet<Principal>(this, PRINCIPAL_SET));
158+ this.pubCredentials = Collections.synchronizedSet
159+ (new SecureSet<Object>(this, PUB_CREDENTIAL_SET));
160+ this.privCredentials = Collections.synchronizedSet
161+ (new SecureSet<Object>(this, PRIV_CREDENTIAL_SET));
162+ }
163+
164+ /**
165+ * Create an instance of a <code>Subject</code> with
166+ * Principals and credentials.
167+ *
168+ * <p> The Principals and credentials from the specified Sets
169+ * are copied into newly constructed Sets.
170+ * These newly created Sets check whether this <code>Subject</code>
171+ * has been set read-only before permitting subsequent modifications.
172+ * The newly created Sets also prevent illegal modifications
173+ * by ensuring that callers have sufficient permissions.
174+ *
175+ * <p> To modify the Principals Set, the caller must have
176+ * <code>AuthPermission("modifyPrincipals")</code>.
177+ * To modify the public credential Set, the caller must have
178+ * <code>AuthPermission("modifyPublicCredentials")</code>.
179+ * To modify the private credential Set, the caller must have
180+ * <code>AuthPermission("modifyPrivateCredentials")</code>.
181+ * <p>
182+ *
183+ * @param readOnly true if the <code>Subject</code> is to be read-only,
184+ * and false otherwise. <p>
185+ *
186+ * @param principals the <code>Set</code> of Principals
187+ * to be associated with this <code>Subject</code>. <p>
188+ *
189+ * @param pubCredentials the <code>Set</code> of public credentials
190+ * to be associated with this <code>Subject</code>. <p>
191+ *
192+ * @param privCredentials the <code>Set</code> of private credentials
193+ * to be associated with this <code>Subject</code>.
194+ *
195+ * @exception NullPointerException if the specified
196+ * <code>principals</code>, <code>pubCredentials</code>,
197+ * or <code>privCredentials</code> are <code>null</code>.
198+ */
199+ public Subject(boolean readOnly, Set<? extends Principal> principals,
200+ Set<?> pubCredentials, Set<?> privCredentials)
201+ {
202+
203+ if (principals == null ||
204+ pubCredentials == null ||
205+ privCredentials == null)
206+ throw new NullPointerException
207+ (ResourcesMgr.getString("invalid.null.input.s."));
208+
209+ this.principals = Collections.synchronizedSet(new SecureSet<Principal>
210+ (this, PRINCIPAL_SET, principals));
211+ this.pubCredentials = Collections.synchronizedSet(new SecureSet<Object>
212+ (this, PUB_CREDENTIAL_SET, pubCredentials));
213+ this.privCredentials = Collections.synchronizedSet(new SecureSet<Object>
214+ (this, PRIV_CREDENTIAL_SET, privCredentials));
215+ this.readOnly = readOnly;
216+ }
217+
218+ /**
219+ * Set this <code>Subject</code> to be read-only.
220+ *
221+ * <p> Modifications (additions and removals) to this Subject's
222+ * <code>Principal</code> <code>Set</code> and
223+ * credential Sets will be disallowed.
224+ * The <code>destroy</code> operation on this Subject's credentials will
225+ * still be permitted.
226+ *
227+ * <p> Subsequent attempts to modify the Subject's <code>Principal</code>
228+ * and credential Sets will result in an
229+ * <code>IllegalStateException</code> being thrown.
230+ * Also, once a <code>Subject</code> is read-only,
231+ * it can not be reset to being writable again.
232+ *
233+ * <p>
234+ *
235+ * @exception SecurityException if the caller does not have permission
236+ * to set this <code>Subject</code> to be read-only.
237+ */
238+ public void setReadOnly() {
239+ java.lang.SecurityManager sm = System.getSecurityManager();
240+ if (sm != null) {
241+ sm.checkPermission(AuthPermissionHolder.SET_READ_ONLY_PERMISSION);
242+ }
243+
244+ this.readOnly = true;
245+ }
246+
247+ /**
248+ * Query whether this <code>Subject</code> is read-only.
249+ *
250+ * <p>
251+ *
252+ * @return true if this <code>Subject</code> is read-only, false otherwise.
253+ */
254+ public boolean isReadOnly() {
255+ return this.readOnly;
256+ }
257+
258+ /**
259+ * Get the <code>Subject</code> associated with the provided
260+ * <code>AccessControlContext</code>.
261+ *
262+ * <p> The <code>AccessControlContext</code> may contain many
263+ * Subjects (from nested <code>doAs</code> calls).
264+ * In this situation, the most recent <code>Subject</code> associated
265+ * with the <code>AccessControlContext</code> is returned.
266+ *
267+ * <p>
268+ *
269+ * @param acc the <code>AccessControlContext</code> from which to retrieve
270+ * the <code>Subject</code>.
271+ *
272+ * @return the <code>Subject</code> associated with the provided
273+ * <code>AccessControlContext</code>, or <code>null</code>
274+ * if no <code>Subject</code> is associated
275+ * with the provided <code>AccessControlContext</code>.
276+ *
277+ * @exception SecurityException if the caller does not have permission
278+ * to get the <code>Subject</code>. <p>
279+ *
280+ * @exception NullPointerException if the provided
281+ * <code>AccessControlContext</code> is <code>null</code>.
282+ */
283+ public static Subject getSubject(final AccessControlContext acc) {
284+
285+ java.lang.SecurityManager sm = System.getSecurityManager();
286+ if (sm != null) {
287+ sm.checkPermission(AuthPermissionHolder.GET_SUBJECT_PERMISSION);
288+ }
289+
290+ if (acc == null) {
291+ throw new NullPointerException(ResourcesMgr.getString
292+ ("invalid.null.AccessControlContext.provided"));
293+ }
294+
295+ // return the Subject from the DomainCombiner of the provided context
296+ return AccessController.doPrivileged
297+ (new java.security.PrivilegedAction<Subject>() {
298+ public Subject run() {
299+ DomainCombiner dc = acc.getDomainCombiner();
300+ if (!(dc instanceof SubjectDomainCombiner))
301+ return null;
302+ SubjectDomainCombiner sdc = (SubjectDomainCombiner)dc;
303+ return sdc.getSubject();
304+ }
305+ });
306+ }
307+
308+ /**
309+ * Perform work as a particular <code>Subject</code>.
310+ *
311+ * <p> This method first retrieves the current Thread's
312+ * <code>AccessControlContext</code> via
313+ * <code>AccessController.getContext</code>,
314+ * and then instantiates a new <code>AccessControlContext</code>
315+ * using the retrieved context along with a new
316+ * <code>SubjectDomainCombiner</code> (constructed using
317+ * the provided <code>Subject</code>).
318+ * Finally, this method invokes <code>AccessController.doPrivileged</code>,
319+ * passing it the provided <code>PrivilegedAction</code>,
320+ * as well as the newly constructed <code>AccessControlContext</code>.
321+ *
322+ * <p>
323+ *
324+ * @param subject the <code>Subject</code> that the specified
325+ * <code>action</code> will run as. This parameter
326+ * may be <code>null</code>. <p>
327+ *
328+ * @param action the code to be run as the specified
329+ * <code>Subject</code>. <p>
330+ *
331+ * @return the value returned by the PrivilegedAction's
332+ * <code>run</code> method.
333+ *
334+ * @exception NullPointerException if the <code>PrivilegedAction</code>
335+ * is <code>null</code>. <p>
336+ *
337+ * @exception SecurityException if the caller does not have permission
338+ * to invoke this method.
339+ */
340+ public static <T> T doAs(final Subject subject,
341+ final java.security.PrivilegedAction<T> action) {
342+
343+ java.lang.SecurityManager sm = System.getSecurityManager();
344+ if (sm != null) {
345+ sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
346+ }
347+ if (action == null)
348+ throw new NullPointerException
349+ (ResourcesMgr.getString("invalid.null.action.provided"));
350+
351+ // set up the new Subject-based AccessControlContext
352+ // for doPrivileged
353+ final AccessControlContext currentAcc = AccessController.getContext();
354+
355+ // call doPrivileged and push this new context on the stack
356+ return java.security.AccessController.doPrivileged
357+ (action,
358+ createContext(subject, currentAcc));
359+ }
360+
361+ /**
362+ * Perform work as a particular <code>Subject</code>.
363+ *
364+ * <p> This method first retrieves the current Thread's
365+ * <code>AccessControlContext</code> via
366+ * <code>AccessController.getContext</code>,
367+ * and then instantiates a new <code>AccessControlContext</code>
368+ * using the retrieved context along with a new
369+ * <code>SubjectDomainCombiner</code> (constructed using
370+ * the provided <code>Subject</code>).
371+ * Finally, this method invokes <code>AccessController.doPrivileged</code>,
372+ * passing it the provided <code>PrivilegedExceptionAction</code>,
373+ * as well as the newly constructed <code>AccessControlContext</code>.
374+ *
375+ * <p>
376+ *
377+ * @param subject the <code>Subject</code> that the specified
378+ * <code>action</code> will run as. This parameter
379+ * may be <code>null</code>. <p>
380+ *
381+ * @param action the code to be run as the specified
382+ * <code>Subject</code>. <p>
383+ *
384+ * @return the value returned by the
385+ * PrivilegedExceptionAction's <code>run</code> method.
386+ *
387+ * @exception PrivilegedActionException if the
388+ * <code>PrivilegedExceptionAction.run</code>
389+ * method throws a checked exception. <p>
390+ *
391+ * @exception NullPointerException if the specified
392+ * <code>PrivilegedExceptionAction</code> is
393+ * <code>null</code>. <p>
394+ *
395+ * @exception SecurityException if the caller does not have permission
396+ * to invoke this method.
397+ */
398+ public static <T> T doAs(final Subject subject,
399+ final java.security.PrivilegedExceptionAction<T> action)
400+ throws java.security.PrivilegedActionException {
401+
402+ java.lang.SecurityManager sm = System.getSecurityManager();
403+ if (sm != null) {
404+ sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
405+ }
406+
407+ if (action == null)
408+ throw new NullPointerException
409+ (ResourcesMgr.getString("invalid.null.action.provided"));
410+
411+ // set up the new Subject-based AccessControlContext for doPrivileged
412+ final AccessControlContext currentAcc = AccessController.getContext();
413+
414+ // call doPrivileged and push this new context on the stack
415+ return java.security.AccessController.doPrivileged
416+ (action,
417+ createContext(subject, currentAcc));
418+ }
419+
420+ /**
421+ * Perform privileged work as a particular <code>Subject</code>.
422+ *
423+ * <p> This method behaves exactly as <code>Subject.doAs</code>,
424+ * except that instead of retrieving the current Thread's
425+ * <code>AccessControlContext</code>, it uses the provided
426+ * <code>AccessControlContext</code>. If the provided
427+ * <code>AccessControlContext</code> is <code>null</code>,
428+ * this method instantiates a new <code>AccessControlContext</code>
429+ * with an empty collection of ProtectionDomains.
430+ *
431+ * <p>
432+ *
433+ * @param subject the <code>Subject</code> that the specified
434+ * <code>action</code> will run as. This parameter
435+ * may be <code>null</code>. <p>
436+ *
437+ * @param action the code to be run as the specified
438+ * <code>Subject</code>. <p>
439+ *
440+ * @param acc the <code>AccessControlContext</code> to be tied to the
441+ * specified <i>subject</i> and <i>action</i>. <p>
442+ *
443+ * @return the value returned by the PrivilegedAction's
444+ * <code>run</code> method.
445+ *
446+ * @exception NullPointerException if the <code>PrivilegedAction</code>
447+ * is <code>null</code>. <p>
448+ *
449+ * @exception SecurityException if the caller does not have permission
450+ * to invoke this method.
451+ */
452+ public static <T> T doAsPrivileged(final Subject subject,
453+ final java.security.PrivilegedAction<T> action,
454+ final java.security.AccessControlContext acc) {
455+
456+ java.lang.SecurityManager sm = System.getSecurityManager();
457+ if (sm != null) {
458+ sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
459+ }
460+
461+ if (action == null)
462+ throw new NullPointerException
463+ (ResourcesMgr.getString("invalid.null.action.provided"));
464+
465+ // set up the new Subject-based AccessControlContext
466+ // for doPrivileged
467+ final AccessControlContext callerAcc =
468+ (acc == null ?
469+ new AccessControlContext(NULL_PD_ARRAY) :
470+ acc);
471+
472+ // call doPrivileged and push this new context on the stack
473+ return java.security.AccessController.doPrivileged
474+ (action,
475+ createContext(subject, callerAcc));
476+ }
477+
478+ /**
479+ * Perform privileged work as a particular <code>Subject</code>.
480+ *
481+ * <p> This method behaves exactly as <code>Subject.doAs</code>,
482+ * except that instead of retrieving the current Thread's
483+ * <code>AccessControlContext</code>, it uses the provided
484+ * <code>AccessControlContext</code>. If the provided
485+ * <code>AccessControlContext</code> is <code>null</code>,
486+ * this method instantiates a new <code>AccessControlContext</code>
487+ * with an empty collection of ProtectionDomains.
488+ *
489+ * <p>
490+ *
491+ * @param subject the <code>Subject</code> that the specified
492+ * <code>action</code> will run as. This parameter
493+ * may be <code>null</code>. <p>
494+ *
495+ * @param action the code to be run as the specified
496+ * <code>Subject</code>. <p>
497+ *
498+ * @param acc the <code>AccessControlContext</code> to be tied to the
499+ * specified <i>subject</i> and <i>action</i>. <p>
500+ *
501+ * @return the value returned by the
502+ * PrivilegedExceptionAction's <code>run</code> method.
503+ *
504+ * @exception PrivilegedActionException if the
505+ * <code>PrivilegedExceptionAction.run</code>
506+ * method throws a checked exception. <p>
507+ *
508+ * @exception NullPointerException if the specified
509+ * <code>PrivilegedExceptionAction</code> is
510+ * <code>null</code>. <p>
511+ *
512+ * @exception SecurityException if the caller does not have permission
513+ * to invoke this method.
514+ */
515+ public static <T> T doAsPrivileged(final Subject subject,
516+ final java.security.PrivilegedExceptionAction<T> action,
517+ final java.security.AccessControlContext acc)
518+ throws java.security.PrivilegedActionException {
519+
520+ java.lang.SecurityManager sm = System.getSecurityManager();
521+ if (sm != null) {
522+ sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
523+ }
524+
525+ if (action == null)
526+ throw new NullPointerException
527+ (ResourcesMgr.getString("invalid.null.action.provided"));
528+
529+ // set up the new Subject-based AccessControlContext for doPrivileged
530+ final AccessControlContext callerAcc =
531+ (acc == null ?
532+ new AccessControlContext(NULL_PD_ARRAY) :
533+ acc);
534+
535+ // call doPrivileged and push this new context on the stack
536+ return java.security.AccessController.doPrivileged
537+ (action,
538+ createContext(subject, callerAcc));
539+ }
540+
541+ private static AccessControlContext createContext(final Subject subject,
542+ final AccessControlContext acc) {
543+
544+
545+ return java.security.AccessController.doPrivileged
546+ (new java.security.PrivilegedAction<AccessControlContext>() {
547+ public AccessControlContext run() {
548+ if (subject == null)
549+ return new AccessControlContext(acc, null);
550+ else
551+ return new AccessControlContext
552+ (acc,
553+ new SubjectDomainCombiner(subject));
554+ }
555+ });
556+ }
557+
558+ /**
559+ * Return the <code>Set</code> of Principals associated with this
560+ * <code>Subject</code>. Each <code>Principal</code> represents
561+ * an identity for this <code>Subject</code>.
562+ *
563+ * <p> The returned <code>Set</code> is backed by this Subject's
564+ * internal <code>Principal</code> <code>Set</code>. Any modification
565+ * to the returned <code>Set</code> affects the internal
566+ * <code>Principal</code> <code>Set</code> as well.
567+ *
568+ * <p>
569+ *
570+ * @return The <code>Set</code> of Principals associated with this
571+ * <code>Subject</code>.
572+ */
573+ public Set<Principal> getPrincipals() {
574+
575+ // always return an empty Set instead of null
576+ // so LoginModules can add to the Set if necessary
577+ return principals;
578+ }
579+
580+ /**
581+ * Return a <code>Set</code> of Principals associated with this
582+ * <code>Subject</code> that are instances or subclasses of the specified
583+ * <code>Class</code>.
584+ *
585+ * <p> The returned <code>Set</code> is not backed by this Subject's
586+ * internal <code>Principal</code> <code>Set</code>. A new
587+ * <code>Set</code> is created and returned for each method invocation.
588+ * Modifications to the returned <code>Set</code>
589+ * will not affect the internal <code>Principal</code> <code>Set</code>.
590+ *
591+ * <p>
592+ *
593+ * @param c the returned <code>Set</code> of Principals will all be
594+ * instances of this class.
595+ *
596+ * @return a <code>Set</code> of Principals that are instances of the
597+ * specified <code>Class</code>.
598+ *
599+ * @exception NullPointerException if the specified <code>Class</code>
600+ * is <code>null</code>.
601+ */
602+ public <T extends Principal> Set<T> getPrincipals(Class<T> c) {
603+
604+ if (c == null)
605+ throw new NullPointerException
606+ (ResourcesMgr.getString("invalid.null.Class.provided"));
607+
608+ // always return an empty Set instead of null
609+ // so LoginModules can add to the Set if necessary
610+ return new ClassSet<T>(PRINCIPAL_SET, c);
611+ }
612+
613+ /**
614+ * Return the <code>Set</code> of public credentials held by this
615+ * <code>Subject</code>.
616+ *
617+ * <p> The returned <code>Set</code> is backed by this Subject's
618+ * internal public Credential <code>Set</code>. Any modification
619+ * to the returned <code>Set</code> affects the internal public
620+ * Credential <code>Set</code> as well.
621+ *
622+ * <p>
623+ *
624+ * @return A <code>Set</code> of public credentials held by this
625+ * <code>Subject</code>.
626+ */
627+ public Set<Object> getPublicCredentials() {
628+
629+ // always return an empty Set instead of null
630+ // so LoginModules can add to the Set if necessary
631+ return pubCredentials;
632+ }
633+
634+ /**
635+ * Return the <code>Set</code> of private credentials held by this
636+ * <code>Subject</code>.
637+ *
638+ * <p> The returned <code>Set</code> is backed by this Subject's
639+ * internal private Credential <code>Set</code>. Any modification
640+ * to the returned <code>Set</code> affects the internal private
641+ * Credential <code>Set</code> as well.
642+ *
643+ * <p> A caller requires permissions to access the Credentials
644+ * in the returned <code>Set</code>, or to modify the
645+ * <code>Set</code> itself. A <code>SecurityException</code>
646+ * is thrown if the caller does not have the proper permissions.
647+ *
648+ * <p> While iterating through the <code>Set</code>,
649+ * a <code>SecurityException</code> is thrown
650+ * if the caller does not have permission to access a
651+ * particular Credential. The <code>Iterator</code>
652+ * is nevertheless advanced to next element in the <code>Set</code>.
653+ *
654+ * <p>
655+ *
656+ * @return A <code>Set</code> of private credentials held by this
657+ * <code>Subject</code>.
658+ */
659+ public Set<Object> getPrivateCredentials() {
660+
661+ // XXX
662+ // we do not need a security check for
663+ // AuthPermission(getPrivateCredentials)
664+ // because we already restrict access to private credentials
665+ // via the PrivateCredentialPermission. all the extra AuthPermission
666+ // would do is protect the set operations themselves
667+ // (like size()), which don't seem security-sensitive.
668+
669+ // always return an empty Set instead of null
670+ // so LoginModules can add to the Set if necessary
671+ return privCredentials;
672+ }
673+
674+ /**
675+ * Return a <code>Set</code> of public credentials associated with this
676+ * <code>Subject</code> that are instances or subclasses of the specified
677+ * <code>Class</code>.
678+ *
679+ * <p> The returned <code>Set</code> is not backed by this Subject's
680+ * internal public Credential <code>Set</code>. A new
681+ * <code>Set</code> is created and returned for each method invocation.
682+ * Modifications to the returned <code>Set</code>
683+ * will not affect the internal public Credential <code>Set</code>.
684+ *
685+ * <p>
686+ *
687+ * @param c the returned <code>Set</code> of public credentials will all be
688+ * instances of this class.
689+ *
690+ * @return a <code>Set</code> of public credentials that are instances
691+ * of the specified <code>Class</code>.
692+ *
693+ * @exception NullPointerException if the specified <code>Class</code>
694+ * is <code>null</code>.
695+ */
696+ public <T> Set<T> getPublicCredentials(Class<T> c) {
697+
698+ if (c == null)
699+ throw new NullPointerException
700+ (ResourcesMgr.getString("invalid.null.Class.provided"));
701+
702+ // always return an empty Set instead of null
703+ // so LoginModules can add to the Set if necessary
704+ return new ClassSet<T>(PUB_CREDENTIAL_SET, c);
705+ }
706+
707+ /**
708+ * Return a <code>Set</code> of private credentials associated with this
709+ * <code>Subject</code> that are instances or subclasses of the specified
710+ * <code>Class</code>.
711+ *
712+ * <p> The caller must have permission to access all of the
713+ * requested Credentials, or a <code>SecurityException</code>
714+ * will be thrown.
715+ *
716+ * <p> The returned <code>Set</code> is not backed by this Subject's
717+ * internal private Credential <code>Set</code>. A new
718+ * <code>Set</code> is created and returned for each method invocation.
719+ * Modifications to the returned <code>Set</code>
720+ * will not affect the internal private Credential <code>Set</code>.
721+ *
722+ * <p>
723+ *
724+ * @param c the returned <code>Set</code> of private credentials will all be
725+ * instances of this class.
726+ *
727+ * @return a <code>Set</code> of private credentials that are instances
728+ * of the specified <code>Class</code>.
729+ *
730+ * @exception NullPointerException if the specified <code>Class</code>
731+ * is <code>null</code>.
732+ */
733+ public <T> Set<T> getPrivateCredentials(Class<T> c) {
734+
735+ // XXX
736+ // we do not need a security check for
737+ // AuthPermission(getPrivateCredentials)
738+ // because we already restrict access to private credentials
739+ // via the PrivateCredentialPermission. all the extra AuthPermission
740+ // would do is protect the set operations themselves
741+ // (like size()), which don't seem security-sensitive.
742+
743+ if (c == null)
744+ throw new NullPointerException
745+ (ResourcesMgr.getString("invalid.null.Class.provided"));
746+
747+ // always return an empty Set instead of null
748+ // so LoginModules can add to the Set if necessary
749+ return new ClassSet<T>(PRIV_CREDENTIAL_SET, c);
750+ }
751+
752+ /**
753+ * Compares the specified Object with this <code>Subject</code>
754+ * for equality. Returns true if the given object is also a Subject
755+ * and the two <code>Subject</code> instances are equivalent.
756+ * More formally, two <code>Subject</code> instances are
757+ * equal if their <code>Principal</code> and <code>Credential</code>
758+ * Sets are equal.
759+ *
760+ * <p>
761+ *
762+ * @param o Object to be compared for equality with this
763+ * <code>Subject</code>.
764+ *
765+ * @return true if the specified Object is equal to this
766+ * <code>Subject</code>.
767+ *
768+ * @exception SecurityException if the caller does not have permission
769+ * to access the private credentials for this <code>Subject</code>,
770+ * or if the caller does not have permission to access the
771+ * private credentials for the provided <code>Subject</code>.
772+ */
773+ public boolean equals(Object o) {
774+
775+ if (o == null)
776+ return false;
777+
778+ if (this == o)
779+ return true;
780+
781+ if (o instanceof Subject) {
782+
783+ final Subject that = (Subject)o;
784+
785+ // check the principal and credential sets
786+ Set<Principal> thatPrincipals;
787+ synchronized(that.principals) {
788+ // avoid deadlock from dual locks
789+ thatPrincipals = new HashSet<Principal>(that.principals);
790+ }
791+ if (!principals.equals(thatPrincipals)) {
792+ return false;
793+ }
794+
795+ Set<Object> thatPubCredentials;
796+ synchronized(that.pubCredentials) {
797+ // avoid deadlock from dual locks
798+ thatPubCredentials = new HashSet<Object>(that.pubCredentials);
799+ }
800+ if (!pubCredentials.equals(thatPubCredentials)) {
801+ return false;
802+ }
803+
804+ Set<Object> thatPrivCredentials;
805+ synchronized(that.privCredentials) {
806+ // avoid deadlock from dual locks
807+ thatPrivCredentials = new HashSet<Object>(that.privCredentials);
808+ }
809+ if (!privCredentials.equals(thatPrivCredentials)) {
810+ return false;
811+ }
812+ return true;
813+ }
814+ return false;
815+ }
816+
817+ /**
818+ * Return the String representation of this <code>Subject</code>.
819+ *
820+ * <p>
821+ *
822+ * @return the String representation of this <code>Subject</code>.
823+ */
824+ public String toString() {
825+ return toString(true);
826+ }
827+
828+ /**
829+ * package private convenience method to print out the Subject
830+ * without firing off a security check when trying to access
831+ * the Private Credentials
832+ */
833+ String toString(boolean includePrivateCredentials) {
834+
835+ String s = ResourcesMgr.getString("Subject.");
836+ String suffix = "";
837+
838+ synchronized(principals) {
839+ Iterator<Principal> pI = principals.iterator();
840+ while (pI.hasNext()) {
841+ Principal p = pI.next();
842+ suffix = suffix + ResourcesMgr.getString(".Principal.") +
843+ p.toString() + ResourcesMgr.getString("NEWLINE");
844+ }
845+ }
846+
847+ synchronized(pubCredentials) {
848+ Iterator<Object> pI = pubCredentials.iterator();
849+ while (pI.hasNext()) {
850+ Object o = pI.next();
851+ suffix = suffix +
852+ ResourcesMgr.getString(".Public.Credential.") +
853+ o.toString() + ResourcesMgr.getString("NEWLINE");
854+ }
855+ }
856+
857+ if (includePrivateCredentials) {
858+ synchronized(privCredentials) {
859+ Iterator<Object> pI = privCredentials.iterator();
860+ while (pI.hasNext()) {
861+ try {
862+ Object o = pI.next();
863+ suffix += ResourcesMgr.getString
864+ (".Private.Credential.") +
865+ o.toString() +
866+ ResourcesMgr.getString("NEWLINE");
867+ } catch (SecurityException se) {
868+ suffix += ResourcesMgr.getString
869+ (".Private.Credential.inaccessible.");
870+ break;
871+ }
872+ }
873+ }
874+ }
875+ return s + suffix;
876+ }
877+
878+ /**
879+ * Returns a hashcode for this <code>Subject</code>.
880+ *
881+ * <p>
882+ *
883+ * @return a hashcode for this <code>Subject</code>.
884+ *
885+ * @exception SecurityException if the caller does not have permission
886+ * to access this Subject's private credentials.
887+ */
888+ public int hashCode() {
889+
890+ /**
891+ * The hashcode is derived exclusive or-ing the
892+ * hashcodes of this Subject's Principals and credentials.
893+ *
894+ * If a particular credential was destroyed
895+ * (<code>credential.hashCode()</code> throws an
896+ * <code>IllegalStateException</code>),
897+ * the hashcode for that credential is derived via:
898+ * <code>credential.getClass().toString().hashCode()</code>.
899+ */
900+
901+ int hashCode = 0;
902+
903+ synchronized(principals) {
904+ Iterator<Principal> pIterator = principals.iterator();
905+ while (pIterator.hasNext()) {
906+ Principal p = pIterator.next();
907+ hashCode ^= p.hashCode();
908+ }
909+ }
910+
911+ synchronized(pubCredentials) {
912+ Iterator<Object> pubCIterator = pubCredentials.iterator();
913+ while (pubCIterator.hasNext()) {
914+ hashCode ^= getCredHashCode(pubCIterator.next());
915+ }
916+ }
917+ return hashCode;
918+ }
919+
920+ /**
921+ * get a credential's hashcode
922+ */
923+ private int getCredHashCode(Object o) {
924+ try {
925+ return o.hashCode();
926+ } catch (IllegalStateException ise) {
927+ return o.getClass().toString().hashCode();
928+ }
929+ }
930+
931+ /**
932+ * Writes this object out to a stream (i.e., serializes it).
933+ */
934+ private void writeObject(java.io.ObjectOutputStream oos)
935+ throws java.io.IOException {
936+ synchronized(principals) {
937+ oos.defaultWriteObject();
938+ }
939+ }
940+
941+ /**
942+ * Reads this object from a stream (i.e., deserializes it)
943+ */
944+ private void readObject(java.io.ObjectInputStream s)
945+ throws java.io.IOException, ClassNotFoundException {
946+
947+ s.defaultReadObject();
948+
949+ // The Credential <code>Set</code> is not serialized, but we do not
950+ // want the default deserialization routine to set it to null.
951+ this.pubCredentials = Collections.synchronizedSet
952+ (new SecureSet<Object>(this, PUB_CREDENTIAL_SET));
953+ this.privCredentials = Collections.synchronizedSet
954+ (new SecureSet<Object>(this, PRIV_CREDENTIAL_SET));
955+ }
956+
957+ /**
958+ * Prevent modifications unless caller has permission.
959+ *
960+ * @serial include
961+ */
962+ private static class SecureSet<E>
963+ extends AbstractSet<E>
964+ implements java.io.Serializable {
965+
966+ private static final long serialVersionUID = 7911754171111800359L;
967+
968+ /**
969+ * @serialField this$0 Subject The outer Subject instance.
970+ * @serialField elements LinkedList The elements in this set.
971+ */
972+ private static final ObjectStreamField[] serialPersistentFields = {
973+ new ObjectStreamField("this$0", Subject.class),
974+ new ObjectStreamField("elements", LinkedList.class),
975+ new ObjectStreamField("which", int.class)
976+ };
977+
978+ Subject subject;
979+ LinkedList<E> elements;
980+
981+ /**
982+ * @serial An integer identifying the type of objects contained
983+ * in this set. If <code>which == 1</code>,
984+ * this is a Principal set and all the elements are
985+ * of type <code>java.security.Principal</code>.
986+ * If <code>which == 2</code>, this is a public credential
987+ * set and all the elements are of type <code>Object</code>.
988+ * If <code>which == 3</code>, this is a private credential
989+ * set and all the elements are of type <code>Object</code>.
990+ */
991+ private int which;
992+
993+ SecureSet(Subject subject, int which) {
994+ this.subject = subject;
995+ this.which = which;
996+ this.elements = new LinkedList<E>();
997+ }
998+
999+ SecureSet(Subject subject, int which, Set<? extends E> set) {
1000+ this.subject = subject;
1001+ this.which = which;
1002+ this.elements = new LinkedList<E>(set);
1003+ }
1004+
1005+ public int size() {
1006+ return elements.size();
1007+ }
1008+
1009+ public Iterator<E> iterator() {
1010+ final LinkedList<E> list = elements;
1011+ return new Iterator<E>() {
1012+ ListIterator<E> i = list.listIterator(0);
1013+
1014+ public boolean hasNext() {return i.hasNext();}
1015+
1016+ public E next() {
1017+ if (which != Subject.PRIV_CREDENTIAL_SET) {
1018+ return i.next();
1019+ }
1020+
1021+ SecurityManager sm = System.getSecurityManager();
1022+ if (sm != null) {
1023+ try {
1024+ sm.checkPermission(new PrivateCredentialPermission
1025+ (list.get(i.nextIndex()).getClass().getName(),
1026+ subject.getPrincipals()));
1027+ } catch (SecurityException se) {
1028+ i.next();
1029+ throw (se);
1030+ }
1031+ }
1032+ return i.next();
1033+ }
1034+
1035+ public void remove() {
1036+
1037+ if (subject.isReadOnly()) {
1038+ throw new IllegalStateException(ResourcesMgr.getString
1039+ ("Subject.is.read.only"));
1040+ }
1041+
1042+ java.lang.SecurityManager sm = System.getSecurityManager();
1043+ if (sm != null) {
1044+ switch (which) {
1045+ case Subject.PRINCIPAL_SET:
1046+ sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
1047+ break;
1048+ case Subject.PUB_CREDENTIAL_SET:
1049+ sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
1050+ break;
1051+ default:
1052+ sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
1053+ break;
1054+ }
1055+ }
1056+ i.remove();
1057+ }
1058+ };
1059+ }
1060+
1061+ public boolean add(E o) {
1062+
1063+ if (subject.isReadOnly()) {
1064+ throw new IllegalStateException
1065+ (ResourcesMgr.getString("Subject.is.read.only"));
1066+ }
1067+
1068+ java.lang.SecurityManager sm = System.getSecurityManager();
1069+ if (sm != null) {
1070+ switch (which) {
1071+ case Subject.PRINCIPAL_SET:
1072+ sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
1073+ break;
1074+ case Subject.PUB_CREDENTIAL_SET:
1075+ sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
1076+ break;
1077+ default:
1078+ sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
1079+ break;
1080+ }
1081+ }
1082+
1083+ switch (which) {
1084+ case Subject.PRINCIPAL_SET:
1085+ if (!(o instanceof Principal)) {
1086+ throw new SecurityException(ResourcesMgr.getString
1087+ ("attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set"));
1088+ }
1089+ break;
1090+ default:
1091+ // ok to add Objects of any kind to credential sets
1092+ break;
1093+ }
1094+
1095+ // check for duplicates
1096+ if (!elements.contains(o))
1097+ return elements.add(o);
1098+ else
1099+ return false;
1100+ }
1101+
1102+ public boolean remove(Object o) {
1103+
1104+ final Iterator<E> e = iterator();
1105+ while (e.hasNext()) {
1106+ E next;
1107+ if (which != Subject.PRIV_CREDENTIAL_SET) {
1108+ next = e.next();
1109+ } else {
1110+ next = java.security.AccessController.doPrivileged
1111+ (new java.security.PrivilegedAction<E>() {
1112+ public E run() {
1113+ return e.next();
1114+ }
1115+ });
1116+ }
1117+
1118+ if (next == null) {
1119+ if (o == null) {
1120+ e.remove();
1121+ return true;
1122+ }
1123+ } else if (next.equals(o)) {
1124+ e.remove();
1125+ return true;
1126+ }
1127+ }
1128+ return false;
1129+ }
1130+
1131+ public boolean contains(Object o) {
1132+ final Iterator<E> e = iterator();
1133+ while (e.hasNext()) {
1134+ E next;
1135+ if (which != Subject.PRIV_CREDENTIAL_SET) {
1136+ next = e.next();
1137+ } else {
1138+
1139+ // For private credentials:
1140+ // If the caller does not have read permission for
1141+ // for o.getClass(), we throw a SecurityException.
1142+ // Otherwise we check the private cred set to see whether
1143+ // it contains the Object
1144+
1145+ SecurityManager sm = System.getSecurityManager();
1146+ if (sm != null) {
1147+ sm.checkPermission(new PrivateCredentialPermission
1148+ (o.getClass().getName(),
1149+ subject.getPrincipals()));
1150+ }
1151+ next = java.security.AccessController.doPrivileged
1152+ (new java.security.PrivilegedAction<E>() {
1153+ public E run() {
1154+ return e.next();
1155+ }
1156+ });
1157+ }
1158+
1159+ if (next == null) {
1160+ if (o == null) {
1161+ return true;
1162+ }
1163+ } else if (next.equals(o)) {
1164+ return true;
1165+ }
1166+ }
1167+ return false;
1168+ }
1169+
1170+ public boolean removeAll(Collection<?> c) {
1171+
1172+ boolean modified = false;
1173+ final Iterator<E> e = iterator();
1174+ while (e.hasNext()) {
1175+ E next;
1176+ if (which != Subject.PRIV_CREDENTIAL_SET) {
1177+ next = e.next();
1178+ } else {
1179+ next = java.security.AccessController.doPrivileged
1180+ (new java.security.PrivilegedAction<E>() {
1181+ public E run() {
1182+ return e.next();
1183+ }
1184+ });
1185+ }
1186+
1187+ Iterator<?> ce = c.iterator();
1188+ while (ce.hasNext()) {
1189+ Object o = ce.next();
1190+ if (next == null) {
1191+ if (o == null) {
1192+ e.remove();
1193+ modified = true;
1194+ break;
1195+ }
1196+ } else if (next.equals(o)) {
1197+ e.remove();
1198+ modified = true;
1199+ break;
1200+ }
1201+ }
1202+ }
1203+ return modified;
1204+ }
1205+
1206+ public boolean retainAll(Collection<?> c) {
1207+
1208+ boolean modified = false;
1209+ boolean retain = false;
1210+ final Iterator<E> e = iterator();
1211+ while (e.hasNext()) {
1212+ retain = false;
1213+ E next;
1214+ if (which != Subject.PRIV_CREDENTIAL_SET) {
1215+ next = e.next();
1216+ } else {
1217+ next = java.security.AccessController.doPrivileged
1218+ (new java.security.PrivilegedAction<E>() {
1219+ public E run() {
1220+ return e.next();
1221+ }
1222+ });
1223+ }
1224+
1225+ Iterator<?> ce = c.iterator();
1226+ while (ce.hasNext()) {
1227+ Object o = ce.next();
1228+ if (next == null) {
1229+ if (o == null) {
1230+ retain = true;
1231+ break;
1232+ }
1233+ } else if (next.equals(o)) {
1234+ retain = true;
1235+ break;
1236+ }
1237+ }
1238+
1239+ if (!retain) {
1240+ e.remove();
1241+ retain = false;
1242+ modified = true;
1243+ }
1244+ }
1245+ return modified;
1246+ }
1247+
1248+ public void clear() {
1249+ final Iterator<E> e = iterator();
1250+ while (e.hasNext()) {
1251+ E next;
1252+ if (which != Subject.PRIV_CREDENTIAL_SET) {
1253+ next = e.next();
1254+ } else {
1255+ next = java.security.AccessController.doPrivileged
1256+ (new java.security.PrivilegedAction<E>() {
1257+ public E run() {
1258+ return e.next();
1259+ }
1260+ });
1261+ }
1262+ e.remove();
1263+ }
1264+ }
1265+
1266+ /**
1267+ * Writes this object out to a stream (i.e., serializes it).
1268+ *
1269+ * <p>
1270+ *
1271+ * @serialData If this is a private credential set,
1272+ * a security check is performed to ensure that
1273+ * the caller has permission to access each credential
1274+ * in the set. If the security check passes,
1275+ * the set is serialized.
1276+ */
1277+ private void writeObject(java.io.ObjectOutputStream oos)
1278+ throws java.io.IOException {
1279+
1280+ if (which == Subject.PRIV_CREDENTIAL_SET) {
1281+ // check permissions before serializing
1282+ Iterator<E> i = iterator();
1283+ while (i.hasNext()) {
1284+ i.next();
1285+ }
1286+ }
1287+ ObjectOutputStream.PutField fields = oos.putFields();
1288+ fields.put("this$0", subject);
1289+ fields.put("elements", elements);
1290+ fields.put("which", which);
1291+ oos.writeFields();
1292+ }
1293+
1294+ private void readObject(ObjectInputStream ois)
1295+ throws IOException, ClassNotFoundException
1296+ {
1297+ ObjectInputStream.GetField fields = ois.readFields();
1298+ subject = (Subject) fields.get("this$0", null);
1299+ elements = (LinkedList<E>) fields.get("elements", null);
1300+ which = fields.get("which", 0);
1301+ }
1302+ }
1303+
1304+ /**
1305+ * This class implements a <code>Set</code> which returns only
1306+ * members that are an instance of a specified Class.
1307+ */
1308+ private class ClassSet<T> extends AbstractSet<T> {
1309+
1310+ private int which;
1311+ private Class<T> c;
1312+ private Set<T> set;
1313+
1314+ ClassSet(int which, Class<T> c) {
1315+ this.which = which;
1316+ this.c = c;
1317+ set = new HashSet<T>();
1318+
1319+ switch (which) {
1320+ case Subject.PRINCIPAL_SET:
1321+ synchronized(principals) { populateSet(); }
1322+ break;
1323+ case Subject.PUB_CREDENTIAL_SET:
1324+ synchronized(pubCredentials) { populateSet(); }
1325+ break;
1326+ default:
1327+ synchronized(privCredentials) { populateSet(); }
1328+ break;
1329+ }
1330+ }
1331+
1332+ private void populateSet() {
1333+ final Iterator<?> iterator;
1334+ switch(which) {
1335+ case Subject.PRINCIPAL_SET:
1336+ iterator = Subject.this.principals.iterator();
1337+ break;
1338+ case Subject.PUB_CREDENTIAL_SET:
1339+ iterator = Subject.this.pubCredentials.iterator();
1340+ break;
1341+ default:
1342+ iterator = Subject.this.privCredentials.iterator();
1343+ break;
1344+ }
1345+
1346+ // Check whether the caller has permisson to get
1347+ // credentials of Class c
1348+
1349+ while (iterator.hasNext()) {
1350+ Object next;
1351+ if (which == Subject.PRIV_CREDENTIAL_SET) {
1352+ next = java.security.AccessController.doPrivileged
1353+ (new java.security.PrivilegedAction<Object>() {
1354+ public Object run() {
1355+ return iterator.next();
1356+ }
1357+ });
1358+ } else {
1359+ next = iterator.next();
1360+ }
1361+ if (c.isAssignableFrom(next.getClass())) {
1362+ if (which != Subject.PRIV_CREDENTIAL_SET) {
1363+ set.add((T)next);
1364+ } else {
1365+ // Check permission for private creds
1366+ SecurityManager sm = System.getSecurityManager();
1367+ if (sm != null) {
1368+ sm.checkPermission(new PrivateCredentialPermission
1369+ (next.getClass().getName(),
1370+ Subject.this.getPrincipals()));
1371+ }
1372+ set.add((T)next);
1373+ }
1374+ }
1375+ }
1376+ }
1377+
1378+ public int size() {
1379+ return set.size();
1380+ }
1381+
1382+ public Iterator<T> iterator() {
1383+ return set.iterator();
1384+ }
1385+
1386+ public boolean add(T o) {
1387+
1388+ if (!o.getClass().isAssignableFrom(c)) {
1389+ MessageFormat form = new MessageFormat(ResourcesMgr.getString
1390+ ("attempting.to.add.an.object.which.is.not.an.instance.of.class"));
1391+ Object[] source = {c.toString()};
1392+ throw new SecurityException(form.format(source));
1393+ }
1394+
1395+ return set.add(o);
1396+ }
1397+ }
1398+
1399+ static class AuthPermissionHolder {
1400+ static final AuthPermission DO_AS_PERMISSION =
1401+ new AuthPermission("doAs");
1402+
1403+ static final AuthPermission DO_AS_PRIVILEGED_PERMISSION =
1404+ new AuthPermission("doAsPrivileged");
1405+
1406+ static final AuthPermission SET_READ_ONLY_PERMISSION =
1407+ new AuthPermission("setReadOnly");
1408+
1409+ static final AuthPermission GET_SUBJECT_PERMISSION =
1410+ new AuthPermission("getSubject");
1411+
1412+ static final AuthPermission MODIFY_PRINCIPALS_PERMISSION =
1413+ new AuthPermission("modifyPrincipals");
1414+
1415+ static final AuthPermission MODIFY_PUBLIC_CREDENTIALS_PERMISSION =
1416+ new AuthPermission("modifyPublicCredentials");
1417+
1418+ static final AuthPermission MODIFY_PRIVATE_CREDENTIALS_PERMISSION =
1419+ new AuthPermission("modifyPrivateCredentials");
1420+ }
1421+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t