151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage javax.security.auth;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.*;
2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.*;
3051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.lang.reflect.*;
3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.text.MessageFormat;
3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessController;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.AccessControlContext;
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.DomainCombiner;
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.Permission;
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PermissionCollection;
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.Principal;
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedAction;
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedExceptionAction;
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.PrivilegedActionException;
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.security.ProtectionDomain;
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.util.ResourcesMgr;
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
4514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * <p> A {@code Subject} represents a grouping of related information
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for a single entity, such as a person.
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Such information includes the Subject's identities as well as
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * its security-related attributes
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * (passwords and cryptographic keys, for example).
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> Subjects may potentially have multiple identities.
5214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * Each identity is represented as a {@code Principal}
5314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * within the {@code Subject}.  Principals simply bind names to a
5414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * {@code Subject}.  For example, a {@code Subject} that happens
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to be a person, Alice, might have two Principals:
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * one which binds "Alice Bar", the name on her driver license,
5714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * to the {@code Subject}, and another which binds,
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * "999-99-9999", the number on her student identification card,
5914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * to the {@code Subject}.  Both Principals refer to the same
6014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * {@code Subject} even though each has a different name.
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * <p> A {@code Subject} may also own security-related attributes,
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * which are referred to as credentials.
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Sensitive credentials that require special protection, such as
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * private cryptographic keys, are stored within a private credential
6614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * {@code Set}.  Credentials intended to be shared, such as
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * public key certificates or Kerberos server tickets are stored
6814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * within a public credential {@code Set}.  Different permissions
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are required to access and modify the different credential Sets.
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
7114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * <p> To retrieve all the Principals associated with a {@code Subject},
7214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * invoke the {@code getPrincipals} method.  To retrieve
7314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * all the public or private credentials belonging to a {@code Subject},
7414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * invoke the {@code getPublicCredentials} method or
7514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * {@code getPrivateCredentials} method, respectively.
7614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * To modify the returned {@code Set} of Principals and credentials,
7714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * use the methods defined in the {@code Set} class.
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * For example:
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <pre>
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *      Subject subject;
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *      Principal principal;
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *      Object credential;
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *      // add a Principal and credential to the Subject
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *      subject.getPrincipals().add(principal);
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *      subject.getPublicCredentials().add(credential);
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * </pre>
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
8914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * <p> This {@code Subject} class implements {@code Serializable}.
9014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * While the Principals associated with the {@code Subject} are serialized,
9114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * the credentials associated with the {@code Subject} are not.
9214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * Note that the {@code java.security.Principal} class
9314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * does not implement {@code Serializable}.  Therefore all concrete
9414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * {@code Principal} implementations associated with Subjects
9514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro * must implement {@code Serializable}.
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.security.Principal
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.security.DomainCombiner
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic final class Subject implements java.io.Serializable {
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final long serialVersionUID = -8308522755600156056L;
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
10514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * A {@code Set} that provides a view of all of this
10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Subject's Principals
10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @serial Each element in this set is a
11114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code java.security.Principal}.
11214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          The set is a {@code Subject.SecureSet}.
11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    Set<Principal> principals;
11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets that provide a view of all of this
11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Subject's Credentials
11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    transient Set<Object> pubCredentials;
12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    transient Set<Object> privCredentials;
12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Whether this Subject is read-only
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @serial
12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private volatile boolean readOnly = false;
12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int PRINCIPAL_SET = 1;
13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int PUB_CREDENTIAL_SET = 2;
13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final int PRIV_CREDENTIAL_SET = 3;
13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static final ProtectionDomain[] NULL_PD_ARRAY
13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        = new ProtectionDomain[0];
13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
13814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Create an instance of a {@code Subject}
13914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * with an empty {@code Set} of Principals and empty
14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets of public and private credentials.
14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
14214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The newly constructed Sets check whether this {@code Subject}
14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * has been set read-only before permitting subsequent modifications.
14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The newly created Sets also prevent illegal modifications
14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by ensuring that callers have sufficient permissions.
14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> To modify the Principals Set, the caller must have
14814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AuthPermission("modifyPrincipals")}.
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * To modify the public credential Set, the caller must have
15014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AuthPermission("modifyPublicCredentials")}.
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * To modify the private credential Set, the caller must have
15214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AuthPermission("modifyPrivateCredentials")}.
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Subject() {
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.principals = Collections.synchronizedSet
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new SecureSet<Principal>(this, PRINCIPAL_SET));
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.pubCredentials = Collections.synchronizedSet
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new SecureSet<Object>(this, PUB_CREDENTIAL_SET));
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.privCredentials = Collections.synchronizedSet
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new SecureSet<Object>(this, PRIV_CREDENTIAL_SET));
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
16514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Create an instance of a {@code Subject} with
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Principals and credentials.
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> The Principals and credentials from the specified Sets
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * are copied into newly constructed Sets.
17014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * These newly created Sets check whether this {@code Subject}
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * has been set read-only before permitting subsequent modifications.
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The newly created Sets also prevent illegal modifications
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * by ensuring that callers have sufficient permissions.
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> To modify the Principals Set, the caller must have
17614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AuthPermission("modifyPrincipals")}.
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * To modify the public credential Set, the caller must have
17814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AuthPermission("modifyPublicCredentials")}.
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * To modify the private credential Set, the caller must have
18014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AuthPermission("modifyPrivateCredentials")}.
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
18314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param readOnly true if the {@code Subject} is to be read-only,
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          and false otherwise. <p>
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
18614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param principals the {@code Set} of Principals
18714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          to be associated with this {@code Subject}. <p>
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
18914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param pubCredentials the {@code Set} of public credentials
19014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          to be associated with this {@code Subject}. <p>
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param privCredentials the {@code Set} of private credentials
19314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          to be associated with this {@code Subject}.
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NullPointerException if the specified
19614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code principals}, {@code pubCredentials},
19714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          or {@code privCredentials} are {@code null}.
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Subject(boolean readOnly, Set<? extends Principal> principals,
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                   Set<?> pubCredentials, Set<?> privCredentials)
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    {
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (principals == null ||
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            pubCredentials == null ||
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            privCredentials == null)
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.input.s."));
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.principals = Collections.synchronizedSet(new SecureSet<Principal>
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                (this, PRINCIPAL_SET, principals));
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.pubCredentials = Collections.synchronizedSet(new SecureSet<Object>
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                (this, PUB_CREDENTIAL_SET, pubCredentials));
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.privCredentials = Collections.synchronizedSet(new SecureSet<Object>
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                (this, PRIV_CREDENTIAL_SET, privCredentials));
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.readOnly = readOnly;
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
21914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Set this {@code Subject} to be read-only.
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> Modifications (additions and removals) to this Subject's
22214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Principal} {@code Set} and
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * credential Sets will be disallowed.
22414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * The {@code destroy} operation on this Subject's credentials will
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * still be permitted.
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
22714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> Subsequent attempts to modify the Subject's {@code Principal}
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and credential Sets will result in an
22914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code IllegalStateException} being thrown.
23014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Also, once a {@code Subject} is read-only,
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * it can not be reset to being writable again.
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
23614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          to set this {@code Subject} to be read-only.
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void setReadOnly() {
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        java.lang.SecurityManager sm = System.getSecurityManager();
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sm != null) {
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sm.checkPermission(AuthPermissionHolder.SET_READ_ONLY_PERMISSION);
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.readOnly = true;
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
24814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Query whether this {@code Subject} is read-only.
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
25214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return true if this {@code Subject} is read-only, false otherwise.
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean isReadOnly() {
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return this.readOnly;
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
25914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Get the {@code Subject} associated with the provided
26014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext}.
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The {@code AccessControlContext} may contain many
26314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Subjects (from nested {@code doAs} calls).
26414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * In this situation, the most recent {@code Subject} associated
26514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * with the {@code AccessControlContext} is returned.
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param  acc the {@code AccessControlContext} from which to retrieve
27014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          the {@code Subject}.
27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return  the {@code Subject} associated with the provided
27314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code AccessControlContext}, or {@code null}
27414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          if no {@code Subject} is associated
27514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          with the provided {@code AccessControlContext}.
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
27814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          to get the {@code Subject}. <p>
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NullPointerException if the provided
28114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code AccessControlContext} is {@code null}.
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static Subject getSubject(final AccessControlContext acc) {
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        java.lang.SecurityManager sm = System.getSecurityManager();
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sm != null) {
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sm.checkPermission(AuthPermissionHolder.GET_SUBJECT_PERMISSION);
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (acc == null) {
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException(ResourcesMgr.getString
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ("invalid.null.AccessControlContext.provided"));
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // return the Subject from the DomainCombiner of the provided context
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return AccessController.doPrivileged
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (new java.security.PrivilegedAction<Subject>() {
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            public Subject run() {
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                DomainCombiner dc = acc.getDomainCombiner();
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (!(dc instanceof SubjectDomainCombiner))
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return null;
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                SubjectDomainCombiner sdc = (SubjectDomainCombiner)dc;
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return sdc.getSubject();
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        });
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
30914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Perform work as a particular {@code Subject}.
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> This method first retrieves the current Thread's
31214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext} via
31314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessController.getContext},
31414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * and then instantiates a new {@code AccessControlContext}
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * using the retrieved context along with a new
31614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code SubjectDomainCombiner} (constructed using
31714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * the provided {@code Subject}).
31814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Finally, this method invokes {@code AccessController.doPrivileged},
31914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * passing it the provided {@code PrivilegedAction},
32014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * as well as the newly constructed {@code AccessControlContext}.
32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
32414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param subject the {@code Subject} that the specified
32514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code action} will run as.  This parameter
32614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  may be {@code null}. <p>
32714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *
32814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param <T> the type of the value returned by the PrivilegedAction's
32914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code run} method.
33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param action the code to be run as the specified
33214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code Subject}. <p>
33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the value returned by the PrivilegedAction's
33514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code run} method.
33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
33714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @exception NullPointerException if the {@code PrivilegedAction}
33814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  is {@code null}. <p>
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  to invoke this method.
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static <T> T doAs(final Subject subject,
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        final java.security.PrivilegedAction<T> action) {
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        java.lang.SecurityManager sm = System.getSecurityManager();
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sm != null) {
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (action == null)
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.action.provided"));
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // set up the new Subject-based AccessControlContext
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // for doPrivileged
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final AccessControlContext currentAcc = AccessController.getContext();
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call doPrivileged and push this new context on the stack
35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return java.security.AccessController.doPrivileged
36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        (action,
36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        createContext(subject, currentAcc));
36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
36514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Perform work as a particular {@code Subject}.
36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> This method first retrieves the current Thread's
36814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext} via
36914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessController.getContext},
37014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * and then instantiates a new {@code AccessControlContext}
37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * using the retrieved context along with a new
37214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code SubjectDomainCombiner} (constructed using
37314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * the provided {@code Subject}).
37414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Finally, this method invokes {@code AccessController.doPrivileged},
37514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * passing it the provided {@code PrivilegedExceptionAction},
37614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * as well as the newly constructed {@code AccessControlContext}.
37751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
37851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
37951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param subject the {@code Subject} that the specified
38114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code action} will run as.  This parameter
38214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  may be {@code null}. <p>
38314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *
38414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param <T> the type of the value returned by the
38514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  PrivilegedExceptionAction's {@code run} method.
38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param action the code to be run as the specified
38814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code Subject}. <p>
38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the value returned by the
39114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  PrivilegedExceptionAction's {@code run} method.
39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception PrivilegedActionException if the
39414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code PrivilegedExceptionAction.run}
39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  method throws a checked exception. <p>
39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NullPointerException if the specified
39814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code PrivilegedExceptionAction} is
39914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code null}. <p>
40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  to invoke this method.
40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static <T> T doAs(final Subject subject,
40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        final java.security.PrivilegedExceptionAction<T> action)
40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throws java.security.PrivilegedActionException {
40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        java.lang.SecurityManager sm = System.getSecurityManager();
40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sm != null) {
41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (action == null)
41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.action.provided"));
41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // set up the new Subject-based AccessControlContext for doPrivileged
41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final AccessControlContext currentAcc = AccessController.getContext();
41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call doPrivileged and push this new context on the stack
42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return java.security.AccessController.doPrivileged
42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        (action,
42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        createContext(subject, currentAcc));
42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
42714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Perform privileged work as a particular {@code Subject}.
42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
42914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> This method behaves exactly as {@code Subject.doAs},
43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * except that instead of retrieving the current Thread's
43114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext}, it uses the provided
43214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext}.  If the provided
43314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext} is {@code null},
43414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * this method instantiates a new {@code AccessControlContext}
43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with an empty collection of ProtectionDomains.
43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
43914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param subject the {@code Subject} that the specified
44014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code action} will run as.  This parameter
44114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  may be {@code null}. <p>
44214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *
44314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param <T> the type of the value returned by the PrivilegedAction's
44414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code run} method.
44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param action the code to be run as the specified
44714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code Subject}. <p>
44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
44914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param acc the {@code AccessControlContext} to be tied to the
45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  specified <i>subject</i> and <i>action</i>. <p>
45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the value returned by the PrivilegedAction's
45314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code run} method.
45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @exception NullPointerException if the {@code PrivilegedAction}
45614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  is {@code null}. <p>
45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  to invoke this method.
46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static <T> T doAsPrivileged(final Subject subject,
46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        final java.security.PrivilegedAction<T> action,
46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        final java.security.AccessControlContext acc) {
46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        java.lang.SecurityManager sm = System.getSecurityManager();
46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sm != null) {
46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (action == null)
47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.action.provided"));
47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // set up the new Subject-based AccessControlContext
47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // for doPrivileged
47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final AccessControlContext callerAcc =
47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (acc == null ?
47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                new AccessControlContext(NULL_PD_ARRAY) :
47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                acc);
48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call doPrivileged and push this new context on the stack
48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return java.security.AccessController.doPrivileged
48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        (action,
48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        createContext(subject, callerAcc));
48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
48814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Perform privileged work as a particular {@code Subject}.
48951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> This method behaves exactly as {@code Subject.doAs},
49151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * except that instead of retrieving the current Thread's
49214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext}, it uses the provided
49314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext}.  If the provided
49414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code AccessControlContext} is {@code null},
49514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * this method instantiates a new {@code AccessControlContext}
49651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * with an empty collection of ProtectionDomains.
49751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
49851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
49951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
50014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param subject the {@code Subject} that the specified
50114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code action} will run as.  This parameter
50214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  may be {@code null}. <p>
50314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *
50414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param <T> the type of the value returned by the
50514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  PrivilegedExceptionAction's {@code run} method.
50651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
50751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param action the code to be run as the specified
50814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code Subject}. <p>
50951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
51014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param acc the {@code AccessControlContext} to be tied to the
51151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  specified <i>subject</i> and <i>action</i>. <p>
51251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
51351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return the value returned by the
51414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  PrivilegedExceptionAction's {@code run} method.
51551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
51651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception PrivilegedActionException if the
51714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code PrivilegedExceptionAction.run}
51851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  method throws a checked exception. <p>
51951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
52051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception NullPointerException if the specified
52114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code PrivilegedExceptionAction} is
52214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  {@code null}. <p>
52351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
52451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
52551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                  to invoke this method.
52651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
52751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public static <T> T doAsPrivileged(final Subject subject,
52851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        final java.security.PrivilegedExceptionAction<T> action,
52951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        final java.security.AccessControlContext acc)
53051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throws java.security.PrivilegedActionException {
53151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        java.lang.SecurityManager sm = System.getSecurityManager();
53351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (sm != null) {
53451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
53551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (action == null)
53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.action.provided"));
54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // set up the new Subject-based AccessControlContext for doPrivileged
54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        final AccessControlContext callerAcc =
54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (acc == null ?
54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                new AccessControlContext(NULL_PD_ARRAY) :
54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                acc);
54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // call doPrivileged and push this new context on the stack
54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return java.security.AccessController.doPrivileged
54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        (action,
55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        createContext(subject, callerAcc));
55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static AccessControlContext createContext(final Subject subject,
55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        final AccessControlContext acc) {
55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return java.security.AccessController.doPrivileged
55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            (new java.security.PrivilegedAction<AccessControlContext>() {
55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            public AccessControlContext run() {
56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (subject == null)
56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return new AccessControlContext(acc, null);
56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                else
56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return new AccessControlContext
56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        (acc,
56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        new SubjectDomainCombiner(subject));
56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        });
56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
57114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Return the {@code Set} of Principals associated with this
57214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Subject}.  Each {@code Principal} represents
57314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * an identity for this {@code Subject}.
57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
57514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The returned {@code Set} is backed by this Subject's
57614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * internal {@code Principal} {@code Set}.  Any modification
57714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * to the returned {@code Set} affects the internal
57814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Principal} {@code Set} as well.
57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
58214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return  The {@code Set} of Principals associated with this
58314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code Subject}.
58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Set<Principal> getPrincipals() {
58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // always return an empty Set instead of null
58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // so LoginModules can add to the Set if necessary
58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return principals;
59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
59314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Return a {@code Set} of Principals associated with this
59414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Subject} that are instances or subclasses of the specified
59514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Class}.
59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
59714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The returned {@code Set} is not backed by this Subject's
59814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * internal {@code Principal} {@code Set}.  A new
59914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Set} is created and returned for each method invocation.
60014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Modifications to the returned {@code Set}
60114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * will not affect the internal {@code Principal} {@code Set}.
60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
60514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param <T> the type of the class modeled by {@code c}
60614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *
60714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param c the returned {@code Set} of Principals will all be
60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          instances of this class.
60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
61014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return a {@code Set} of Principals that are instances of the
61114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          specified {@code Class}.
61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
61314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @exception NullPointerException if the specified {@code Class}
61414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *                  is {@code null}.
61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public <T extends Principal> Set<T> getPrincipals(Class<T> c) {
61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (c == null)
61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.Class.provided"));
62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // always return an empty Set instead of null
62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // so LoginModules can add to the Set if necessary
62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new ClassSet<T>(PRINCIPAL_SET, c);
62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
62814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Return the {@code Set} of public credentials held by this
62914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Subject}.
63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
63114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The returned {@code Set} is backed by this Subject's
63214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * internal public Credential {@code Set}.  Any modification
63314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * to the returned {@code Set} affects the internal public
63414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Credential {@code Set} as well.
63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
63814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return  A {@code Set} of public credentials held by this
63914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code Subject}.
64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Set<Object> getPublicCredentials() {
64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // always return an empty Set instead of null
64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // so LoginModules can add to the Set if necessary
64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return pubCredentials;
64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
64914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Return the {@code Set} of private credentials held by this
65014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Subject}.
65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
65214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The returned {@code Set} is backed by this Subject's
65314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * internal private Credential {@code Set}.  Any modification
65414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * to the returned {@code Set} affects the internal private
65514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Credential {@code Set} as well.
65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> A caller requires permissions to access the Credentials
65814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * in the returned {@code Set}, or to modify the
65914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Set} itself.  A {@code SecurityException}
66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is thrown if the caller does not have the proper permissions.
66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
66214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> While iterating through the {@code Set},
66314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * a {@code SecurityException} is thrown
66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * if the caller does not have permission to access a
66514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * particular Credential.  The {@code Iterator}
66614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * is nevertheless advanced to next element in the {@code Set}.
66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
67014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return  A {@code Set} of private credentials held by this
67114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code Subject}.
67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public Set<Object> getPrivateCredentials() {
67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // XXX
67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // we do not need a security check for
67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // AuthPermission(getPrivateCredentials)
67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // because we already restrict access to private credentials
67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // via the PrivateCredentialPermission.  all the extra AuthPermission
68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // would do is protect the set operations themselves
68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // (like size()), which don't seem security-sensitive.
68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // always return an empty Set instead of null
68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // so LoginModules can add to the Set if necessary
68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return privCredentials;
68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
68914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Return a {@code Set} of public credentials associated with this
69014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Subject} that are instances or subclasses of the specified
69114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Class}.
69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
69314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The returned {@code Set} is not backed by this Subject's
69414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * internal public Credential {@code Set}.  A new
69514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Set} is created and returned for each method invocation.
69614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Modifications to the returned {@code Set}
69714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * will not affect the internal public Credential {@code Set}.
69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
70114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param <T> the type of the class modeled by {@code c}
70214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *
70314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param c the returned {@code Set} of public credentials will all be
70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          instances of this class.
70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
70614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return a {@code Set} of public credentials that are instances
70714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          of the  specified {@code Class}.
70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
70914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @exception NullPointerException if the specified {@code Class}
71014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          is {@code null}.
71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public <T> Set<T> getPublicCredentials(Class<T> c) {
71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (c == null)
71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.Class.provided"));
71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // always return an empty Set instead of null
71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // so LoginModules can add to the Set if necessary
72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new ClassSet<T>(PUB_CREDENTIAL_SET, c);
72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
72414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Return a {@code Set} of private credentials associated with this
72514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Subject} that are instances or subclasses of the specified
72614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Class}.
72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p> The caller must have permission to access all of the
72914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * requested Credentials, or a {@code SecurityException}
73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * will be thrown.
73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
73214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * <p> The returned {@code Set} is not backed by this Subject's
73314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * internal private Credential {@code Set}.  A new
73414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * {@code Set} is created and returned for each method invocation.
73514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Modifications to the returned {@code Set}
73614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * will not affect the internal private Credential {@code Set}.
73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
74014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param <T> the type of the class modeled by {@code c}
74114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *
74214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @param c the returned {@code Set} of private credentials will all be
74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          instances of this class.
74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
74514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return a {@code Set} of private credentials that are instances
74614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          of the  specified {@code Class}.
74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
74814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @exception NullPointerException if the specified {@code Class}
74914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          is {@code null}.
75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public <T> Set<T> getPrivateCredentials(Class<T> c) {
75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // XXX
75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // we do not need a security check for
75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // AuthPermission(getPrivateCredentials)
75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // because we already restrict access to private credentials
75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // via the PrivateCredentialPermission.  all the extra AuthPermission
75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // would do is protect the set operations themselves
75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // (like size()), which don't seem security-sensitive.
76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (c == null)
76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throw new NullPointerException
76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                (ResourcesMgr.getString("invalid.null.Class.provided"));
76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // always return an empty Set instead of null
76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // so LoginModules can add to the Set if necessary
76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return new ClassSet<T>(PRIV_CREDENTIAL_SET, c);
76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
77114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Compares the specified Object with this {@code Subject}
77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * for equality.  Returns true if the given object is also a Subject
77314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * and the two {@code Subject} instances are equivalent.
77414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * More formally, two {@code Subject} instances are
77514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * equal if their {@code Principal} and {@code Credential}
77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Sets are equal.
77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param o Object to be compared for equality with this
78114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code Subject}.
78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return true if the specified Object is equal to this
78414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          {@code Subject}.
78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
78714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          to access the private credentials for this {@code Subject},
78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          or if the caller does not have permission to access the
78914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     *          private credentials for the provided {@code Subject}.
79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean equals(Object o) {
79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (o == null)
79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (this == o)
79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return true;
79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (o instanceof Subject) {
80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final Subject that = (Subject)o;
80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // check the principal and credential sets
80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Set<Principal> thatPrincipals;
80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(that.principals) {
80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // avoid deadlock from dual locks
80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                thatPrincipals = new HashSet<Principal>(that.principals);
80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!principals.equals(thatPrincipals)) {
81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Set<Object> thatPubCredentials;
81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(that.pubCredentials) {
81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // avoid deadlock from dual locks
81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                thatPubCredentials = new HashSet<Object>(that.pubCredentials);
81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!pubCredentials.equals(thatPubCredentials)) {
81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Set<Object> thatPrivCredentials;
82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(that.privCredentials) {
82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // avoid deadlock from dual locks
82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                thatPrivCredentials = new HashSet<Object>(that.privCredentials);
82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!privCredentials.equals(thatPrivCredentials)) {
82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return true;
83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return false;
83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
83614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Return the String representation of this {@code Subject}.
83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
84014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return the String representation of this {@code Subject}.
84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public String toString() {
84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return toString(true);
84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * package private convenience method to print out the Subject
84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * without firing off a security check when trying to access
84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the Private Credentials
85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    String toString(boolean includePrivateCredentials) {
85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String s = ResourcesMgr.getString("Subject.");
85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        String suffix = "";
85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized(principals) {
85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Iterator<Principal> pI = principals.iterator();
85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (pI.hasNext()) {
85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Principal p = pI.next();
86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                suffix = suffix + ResourcesMgr.getString(".Principal.") +
86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        p.toString() + ResourcesMgr.getString("NEWLINE");
86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized(pubCredentials) {
86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Iterator<Object> pI = pubCredentials.iterator();
86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (pI.hasNext()) {
86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Object o = pI.next();
86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                suffix = suffix +
87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ResourcesMgr.getString(".Public.Credential.") +
87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        o.toString() + ResourcesMgr.getString("NEWLINE");
87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (includePrivateCredentials) {
87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            synchronized(privCredentials) {
87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Iterator<Object> pI = privCredentials.iterator();
87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while (pI.hasNext()) {
87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    try {
88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        Object o = pI.next();
88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        suffix += ResourcesMgr.getString
88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        (".Private.Credential.") +
88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        o.toString() +
88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                        ResourcesMgr.getString("NEWLINE");
88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } catch (SecurityException se) {
88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        suffix += ResourcesMgr.getString
88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                (".Private.Credential.inaccessible.");
88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break;
88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return s + suffix;
89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
89714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * Returns a hashcode for this {@code Subject}.
89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
89951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
90051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
90114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * @return a hashcode for this {@code Subject}.
90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception SecurityException if the caller does not have permission
90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          to access this Subject's private credentials.
90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int hashCode() {
90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /**
90951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * The hashcode is derived exclusive or-ing the
91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * hashcodes of this Subject's Principals and credentials.
91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * If a particular credential was destroyed
91314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         * ({@code credential.hashCode()} throws an
91414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         * {@code IllegalStateException}),
91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * the hashcode for that credential is derived via:
91614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         * {@code credential.getClass().toString().hashCode()}.
91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int hashCode = 0;
92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized(principals) {
92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Iterator<Principal> pIterator = principals.iterator();
92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (pIterator.hasNext()) {
92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Principal p = pIterator.next();
92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                hashCode ^= p.hashCode();
92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized(pubCredentials) {
93051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            Iterator<Object> pubCIterator = pubCredentials.iterator();
93151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (pubCIterator.hasNext()) {
93251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                hashCode ^= getCredHashCode(pubCIterator.next());
93351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
93451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
93551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return hashCode;
93651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
93751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
93851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
93951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * get a credential's hashcode
94051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int getCredHashCode(Object o) {
94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        try {
94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return o.hashCode();
94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        } catch (IllegalStateException ise) {
94551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return o.getClass().toString().hashCode();
94651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
94751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
94951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
95051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Writes this object out to a stream (i.e., serializes it).
95151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
95251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void writeObject(java.io.ObjectOutputStream oos)
95351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throws java.io.IOException {
95451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        synchronized(principals) {
95551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            oos.defaultWriteObject();
95651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
95751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
95851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
95951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
96051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads this object from a stream (i.e., deserializes it)
96151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
96214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro    @SuppressWarnings("unchecked")
96351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private void readObject(java.io.ObjectInputStream s)
96451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throws java.io.IOException, ClassNotFoundException {
96551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
96614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        ObjectInputStream.GetField gf = s.readFields();
96714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro
96814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        readOnly = gf.get("readOnly", false);
96914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro
97014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        Set<Principal> inputPrincs = (Set<Principal>)gf.get("principals", null);
97114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro
97214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        // Rewrap the principals into a SecureSet
97314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        if (inputPrincs == null) {
97414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            throw new NullPointerException
97514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro                (ResourcesMgr.getString("invalid.null.input.s."));
97614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        }
97714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        try {
97814dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            principals = Collections.synchronizedSet(new SecureSet<Principal>
97914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro                                (this, PRINCIPAL_SET, inputPrincs));
98014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        } catch (NullPointerException npe) {
98114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            // Sometimes people deserialize the principals set only.
98214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            // Subject is not accessible, so just don't fail.
98314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            principals = Collections.synchronizedSet
98414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro                        (new SecureSet<Principal>(this, PRINCIPAL_SET));
98514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        }
98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
98714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        // The Credential {@code Set} is not serialized, but we do not
98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        // want the default deserialization routine to set it to null.
98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.pubCredentials = Collections.synchronizedSet
99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new SecureSet<Object>(this, PUB_CREDENTIAL_SET));
99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        this.privCredentials = Collections.synchronizedSet
99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new SecureSet<Object>(this, PRIV_CREDENTIAL_SET));
99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Prevent modifications unless caller has permission.
99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @serial include
99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private static class SecureSet<E>
100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        extends AbstractSet<E>
100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        implements java.io.Serializable {
100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private static final long serialVersionUID = 7911754171111800359L;
100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /**
100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * @serialField this$0 Subject The outer Subject instance.
100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * @serialField elements LinkedList The elements in this set.
100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private static final ObjectStreamField[] serialPersistentFields = {
101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new ObjectStreamField("this$0", Subject.class),
101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new ObjectStreamField("elements", LinkedList.class),
101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new ObjectStreamField("which", int.class)
101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        };
101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        Subject subject;
101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        LinkedList<E> elements;
101851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
101951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /**
102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * @serial An integer identifying the type of objects contained
102114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         *      in this set.  If {@code which == 1},
102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      this is a Principal set and all the elements are
102314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         *      of type {@code java.security.Principal}.
102414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         *      If {@code which == 2}, this is a public credential
102514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         *      set and all the elements are of type {@code Object}.
102614dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         *      If {@code which == 3}, this is a private credential
102714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro         *      set and all the elements are of type {@code Object}.
102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private int which;
103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecureSet(Subject subject, int which) {
103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.subject = subject;
103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.which = which;
103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.elements = new LinkedList<E>();
103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        SecureSet(Subject subject, int which, Set<? extends E> set) {
103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.subject = subject;
103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.which = which;
104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.elements = new LinkedList<E>(set);
104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public int size() {
104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return elements.size();
104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public Iterator<E> iterator() {
104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final LinkedList<E> list = elements;
104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return new Iterator<E>() {
105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                ListIterator<E> i = list.listIterator(0);
105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                public boolean hasNext() {return i.hasNext();}
105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                public E next() {
105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (which != Subject.PRIV_CREDENTIAL_SET) {
105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return i.next();
105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    SecurityManager sm = System.getSecurityManager();
106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sm != null) {
106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        try {
106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            sm.checkPermission(new PrivateCredentialPermission
106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                (list.get(i.nextIndex()).getClass().getName(),
106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                subject.getPrincipals()));
106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        } catch (SecurityException se) {
106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            i.next();
106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            throw (se);
106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return i.next();
107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                public void remove() {
107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (subject.isReadOnly()) {
107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        throw new IllegalStateException(ResourcesMgr.getString
107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                ("Subject.is.read.only"));
107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    java.lang.SecurityManager sm = System.getSecurityManager();
108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sm != null) {
108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        switch (which) {
108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        case Subject.PRINCIPAL_SET:
108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            break;
108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        case Subject.PUB_CREDENTIAL_SET:
108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            break;
108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        default:
109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            break;
109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i.remove();
109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            };
109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public boolean add(E o) {
110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (subject.isReadOnly()) {
110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new IllegalStateException
110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (ResourcesMgr.getString("Subject.is.read.only"));
110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            java.lang.SecurityManager sm = System.getSecurityManager();
110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (sm != null) {
110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                switch (which) {
110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case Subject.PRINCIPAL_SET:
111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION);
111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                case Subject.PUB_CREDENTIAL_SET:
111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION);
111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                default:
111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION);
111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    break;
111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            switch (which) {
112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case Subject.PRINCIPAL_SET:
112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (!(o instanceof Principal)) {
112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    throw new SecurityException(ResourcesMgr.getString
112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ("attempting.to.add.an.object.which.is.not.an.instance.of.java.security.Principal.to.a.Subject.s.Principal.Set"));
112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            default:
112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // ok to add Objects of any kind to credential sets
113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // check for duplicates
113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!elements.contains(o))
113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return elements.add(o);
113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            else
113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                return false;
113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public boolean remove(Object o) {
114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final Iterator<E> e = iterator();
114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (e.hasNext()) {
114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                E next;
114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (which != Subject.PRIV_CREDENTIAL_SET) {
114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = e.next();
114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = java.security.AccessController.doPrivileged
114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new java.security.PrivilegedAction<E>() {
115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        public E run() {
115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return e.next();
115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    });
115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (next == null) {
115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (o == null) {
115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        e.remove();
115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return true;
116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if (next.equals(o)) {
116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e.remove();
116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return true;
116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public boolean contains(Object o) {
117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final Iterator<E> e = iterator();
117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (e.hasNext()) {
117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                E next;
117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (which != Subject.PRIV_CREDENTIAL_SET) {
117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = e.next();
117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // For private credentials:
117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // If the caller does not have read permission for
117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // for o.getClass(), we throw a SecurityException.
118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // Otherwise we check the private cred set to see whether
118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    // it contains the Object
118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    SecurityManager sm = System.getSecurityManager();
118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (sm != null) {
118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        sm.checkPermission(new PrivateCredentialPermission
118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                (o.getClass().getName(),
118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                subject.getPrincipals()));
118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = java.security.AccessController.doPrivileged
119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new java.security.PrivilegedAction<E>() {
119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        public E run() {
119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return e.next();
119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    });
119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (next == null) {
119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (o == null) {
119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        return true;
120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else if (next.equals(o)) {
120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    return true;
120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return false;
120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public boolean removeAll(Collection<?> c) {
120914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            Objects.requireNonNull(c);
121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean modified = false;
121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final Iterator<E> e = iterator();
121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (e.hasNext()) {
121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                E next;
121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (which != Subject.PRIV_CREDENTIAL_SET) {
121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = e.next();
121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = java.security.AccessController.doPrivileged
121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new java.security.PrivilegedAction<E>() {
121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        public E run() {
122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return e.next();
122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    });
122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Iterator<?> ce = c.iterator();
122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while (ce.hasNext()) {
122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    Object o = ce.next();
122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (next == null) {
122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (o == null) {
123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            e.remove();
123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            modified = true;
123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            break;
123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else if (next.equals(o)) {
123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        e.remove();
123651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        modified = true;
123751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break;
123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return modified;
124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public boolean retainAll(Collection<?> c) {
124514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            Objects.requireNonNull(c);
124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean modified = false;
124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            boolean retain = false;
124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final Iterator<E> e = iterator();
124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (e.hasNext()) {
125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                retain = false;
125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                E next;
125251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (which != Subject.PRIV_CREDENTIAL_SET) {
125351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = e.next();
125451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
125551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = java.security.AccessController.doPrivileged
125651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new java.security.PrivilegedAction<E>() {
125751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        public E run() {
125851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return e.next();
125951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
126051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    });
126151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
126251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
126351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Iterator<?> ce = c.iterator();
126451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while (ce.hasNext()) {
126551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    Object o = ce.next();
126651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (next == null) {
126751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (o == null) {
126851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            retain = true;
126951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            break;
127051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
127151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else if (next.equals(o)) {
127251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        retain = true;
127351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        break;
127451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
127551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
127651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
127751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (!retain) {
127851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    e.remove();
127951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    retain = false;
128051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    modified = true;
128151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
128251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
128351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return modified;
128451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
128551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
128651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public void clear() {
128751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final Iterator<E> e = iterator();
128851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (e.hasNext()) {
128951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                E next;
129051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (which != Subject.PRIV_CREDENTIAL_SET) {
129151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = e.next();
129251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
129351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = java.security.AccessController.doPrivileged
129451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new java.security.PrivilegedAction<E>() {
129551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        public E run() {
129651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return e.next();
129751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
129851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    });
129951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
130051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                e.remove();
130151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
130251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
130351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
130451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        /**
130551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * Writes this object out to a stream (i.e., serializes it).
130651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
130751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * <p>
130851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *
130951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         * @serialData If this is a private credential set,
131051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      a security check is performed to ensure that
131151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      the caller has permission to access each credential
131251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      in the set.  If the security check passes,
131351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         *      the set is serialized.
131451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski         */
131551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private void writeObject(java.io.ObjectOutputStream oos)
131651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throws java.io.IOException {
131751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
131851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (which == Subject.PRIV_CREDENTIAL_SET) {
131951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                // check permissions before serializing
132051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Iterator<E> i = iterator();
132151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                while (i.hasNext()) {
132251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    i.next();
132351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
132451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
132551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ObjectOutputStream.PutField fields = oos.putFields();
132651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fields.put("this$0", subject);
132751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fields.put("elements", elements);
132851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            fields.put("which", which);
132951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            oos.writeFields();
133051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
133151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
133214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        @SuppressWarnings("unchecked")
133351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private void readObject(ObjectInputStream ois)
133451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            throws IOException, ClassNotFoundException
133551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        {
133651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            ObjectInputStream.GetField fields = ois.readFields();
133751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            subject = (Subject) fields.get("this$0", null);
133851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            which = fields.get("which", 0);
133914dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro
134014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            LinkedList<E> tmp = (LinkedList<E>) fields.get("elements", null);
134114dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            if (tmp.getClass() != LinkedList.class) {
134214dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro                elements = new LinkedList<E>(tmp);
134314dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            } else {
134414dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro                elements = tmp;
134514dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro            }
134651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
134751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
134851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
134951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
135014dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro     * This class implements a {@code Set} which returns only
135151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * members that are an instance of a specified Class.
135251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
135351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private class ClassSet<T> extends AbstractSet<T> {
135451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
135551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private int which;
135651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private Class<T> c;
135751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private Set<T> set;
135851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
135951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ClassSet(int which, Class<T> c) {
136051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.which = which;
136151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            this.c = c;
136251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            set = new HashSet<T>();
136351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
136451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            switch (which) {
136551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case Subject.PRINCIPAL_SET:
136651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized(principals) { populateSet(); }
136751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
136851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case Subject.PUB_CREDENTIAL_SET:
136951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized(pubCredentials) { populateSet(); }
137051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
137151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            default:
137251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                synchronized(privCredentials) { populateSet(); }
137351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
137451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
137551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
137651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
137714dca37c2ca66d2c1649a7ffe157ec1f037646a4Sergio Giro        @SuppressWarnings("unchecked")     /*To suppress warning from line 1374*/
137851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        private void populateSet() {
137951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            final Iterator<?> iterator;
138051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            switch(which) {
138151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case Subject.PRINCIPAL_SET:
138251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                iterator = Subject.this.principals.iterator();
138351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
138451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            case Subject.PUB_CREDENTIAL_SET:
138551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                iterator = Subject.this.pubCredentials.iterator();
138651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
138751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            default:
138851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                iterator = Subject.this.privCredentials.iterator();
138951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                break;
139051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
139151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
139251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // Check whether the caller has permisson to get
139351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // credentials of Class c
139451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
139551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (iterator.hasNext()) {
139651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Object next;
139751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (which == Subject.PRIV_CREDENTIAL_SET) {
139851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = java.security.AccessController.doPrivileged
139951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        (new java.security.PrivilegedAction<Object>() {
140051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        public Object run() {
140151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            return iterator.next();
140251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
140351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    });
140451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                } else {
140551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    next = iterator.next();
140651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
140751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                if (c.isAssignableFrom(next.getClass())) {
140851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    if (which != Subject.PRIV_CREDENTIAL_SET) {
140951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        set.add((T)next);
141051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    } else {
141151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        // Check permission for private creds
141251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        SecurityManager sm = System.getSecurityManager();
141351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        if (sm != null) {
141451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                            sm.checkPermission(new PrivateCredentialPermission
141551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                (next.getClass().getName(),
141651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                                                Subject.this.getPrincipals()));
141751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        }
141851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        set.add((T)next);
141951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                    }
142051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                }
142151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
142251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
142351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
142451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public int size() {
142551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return set.size();
142651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
142751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
142851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public Iterator<T> iterator() {
142951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return set.iterator();
143051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
143151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
143251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        public boolean add(T o) {
143351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
143451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (!o.getClass().isAssignableFrom(c)) {
143551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                MessageFormat form = new MessageFormat(ResourcesMgr.getString
143651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                        ("attempting.to.add.an.object.which.is.not.an.instance.of.class"));
143751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                Object[] source = {c.toString()};
143851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski                throw new SecurityException(form.format(source));
143951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
144051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
144151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return set.add(o);
144251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
144351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
144451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
144551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    static class AuthPermissionHolder {
144651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final AuthPermission DO_AS_PERMISSION =
144751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new AuthPermission("doAs");
144851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
144951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final AuthPermission DO_AS_PRIVILEGED_PERMISSION =
145051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new AuthPermission("doAsPrivileged");
145151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
145251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final AuthPermission SET_READ_ONLY_PERMISSION =
145351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new AuthPermission("setReadOnly");
145451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
145551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final AuthPermission GET_SUBJECT_PERMISSION =
145651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new AuthPermission("getSubject");
145751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
145851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final AuthPermission MODIFY_PRINCIPALS_PERMISSION =
145951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new AuthPermission("modifyPrincipals");
146051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
146151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final AuthPermission MODIFY_PUBLIC_CREDENTIALS_PERMISSION =
146251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new AuthPermission("modifyPublicCredentials");
146351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
146451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        static final AuthPermission MODIFY_PRIVATE_CREDENTIALS_PERMISSION =
146551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            new AuthPermission("modifyPrivateCredentials");
146651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
146751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
1468