/*
 * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

/*
 * @test
 * @author  Ram Marti
 * @bug 4326852
 * @summary Retrive a subset of private credentials can be accessed
 * @run main/othervm/policy=Subset.policy Subset
 */

import java.util.*;
import com.sun.security.auth.SolarisPrincipal;
import javax.security.auth.Subject;

/*
 * Author : Ram Marti
 * This is a test program to verify the fix for Bug 4326852
 * (impossible to extract a subset of private credentials)
 * The policy file used allows read access only to String classes.
 * grant {
 *    permission javax.security.auth.AuthPermission \
 *              "modifyPrivateCredentials";
 *    permission javax.security.auth.PrivateCredentialPermission \
 * "java.lang.String com.sun.security.auth.SolarisPrincipal \"user"", "read";
 * };

 * The test verifies the following:
 *      - String class creds can be retrieved by using
 *        getPrivateCredentials(String.class)
 *      - The above set is not backed internally
 *      - getPrivateCredentials(Boolean or Integer) returns an empty set
 *      - Set is returned by getPrivateCredentials() throws
 *        security exception when trying to access non-String
 *        class credentials
 *      - The above set is internally backed up and any changes in
 *        internal private creds are reflected in the set returned
 *      - When the above set throws security exception the iterator
 *      - is advanced to the next item in the list of creds.
 *      - equals,contains,containsAll,add,remove operations work correctly
 */

public class Subset {
    public static void main(String[] args) throws Exception {
        int exceptionCounter =0;
        Iterator iter1;
        HashSet creds = new HashSet();
        Subject emptys =
            new Subject(false,  //readOnly
                        Collections.singleton(new SolarisPrincipal("user")),
                        Collections.EMPTY_SET,
                        creds);
        /* Test principals */

        Set princ= emptys.getPrincipals();
        HashSet collp= new HashSet();
        collp.add(new String("abc"));
        collp.add(new String("def"));
        collp.add(new String("Exists"));
        collp.add(new String("Does not Exist"));
        try {
            if (princ.containsAll(collp)) {
                throw new Exception ("Error: Contains the collection");
            } else
                System.out.println ("Does not Contain the collection");
        } catch (SecurityException e) {
            throw new Exception ("Error: Exception in containsAll (string coll)!!");
        }


        Set p1 = emptys.getPrivateCredentials();

        if (p1.size() != 0) {
              throw new Exception("Error:p1 size should have been 6 and was " +
                         p1.size());
        }

        creds.add("abc");
        creds.add(new Integer(3));
        creds.add(Boolean.TRUE);
        Subject sremove =
            new Subject(false,  //readOnly
                        Collections.singleton(new SolarisPrincipal("user")),
                        Collections.EMPTY_SET,
                        creds);
        Set p2 = sremove.getPrivateCredentials();

        if (p2.size() !=3){
              throw new Exception("Error: p2 size should have been 3 and was " +
                         p2.size());
        }
        iter1 = p2.iterator();
        exceptionCounter=0;
        while (iter1.hasNext()) {
            try {
                Object o = iter1.next();
                System.out.println(" private creds of class " +
                        o.getClass() + "value is " + o.toString());
            } catch (SecurityException e) {
                System.out.println("Expected Exception occured");
                exceptionCounter++;
            }
        }
        if (exceptionCounter != 2) {
            throw new Exception("Expected number of exceptions was 2 " +
                        "The actual number was " + exceptionCounter);
        }

        // Verify that remove op was successful

        iter1.remove();
        if (p2.size() !=2) {
           throw new RuntimeException("Error: p2 size should have been 2 and was " +
                               p2.size());
        }
        System.out.println ("Checking the value after removal");
        p2 = sremove.getPrivateCredentials();
        try {
                if (!p2.add(new String("XYZ"))) {

                        throw new RuntimeException("Error in adding string");
                }
                if (!p2.add(new Integer(99))) {

                        throw new RuntimeException("Error in adding Integer");
                }
                HashSet coll1 = new HashSet();
                coll1.add(new String("RST"));
                coll1.add(new Integer(1));
                if (!p2.addAll(coll1)) {

                        throw new RuntimeException("Error in addAll");
                }

        } catch (Exception e){
                e.printStackTrace();
                throw new RuntimeException("Unexpected exception in add");

        }
        iter1 = p2.iterator();

        while (iter1.hasNext()) {
            try {
                Object o = iter1.next();
                System.out.println(" private creds of class " +
                        o.getClass() + "value is " + o.toString());
            } catch (SecurityException e) {
                // System.out.println("Exception!!");
            }
        }
        iter1 = p2.iterator();

        System.out.println ("Checked the value after removal");

        HashSet creds1 = new HashSet();
        creds1.add("abc");
        creds1.add("def");
        creds1.add(Boolean.TRUE);
        creds1.add(new Integer(1));
        creds1.add(new String("Exists"));
        Subject scontain =
            new Subject(false,  //readOnly
                        Collections.singleton(new SolarisPrincipal("user")),
                        Collections.EMPTY_SET,
                        creds1);
        p2 = scontain.getPrivateCredentials();
        try {
            Object ObjAr = p2.toArray();
        } catch (SecurityException e) {
                System.out.println("Should get an Exception in toArray()");
        }

        HashSet creds3 = new HashSet();
        creds3.add (new String("abc"));
        p2 = scontain.getPrivateCredentials();

        try {
            Object ObjCred = (Object)creds3.clone();
            System.out.println ("Size of p2 is " + p2.size() +
                                "Size of ObjCred is " +
                                        ((HashSet)ObjCred).size()
                                );
            if (p2.equals(ObjCred))
                throw new RuntimeException("Error:Equals ObjCred  *** ");
            else
                System.out.println ("Does not Equal Objcred");
        } catch (SecurityException e) {
            throw new RuntimeException("Error:Should not get an Exception in equals of creds3");


        }

        try {
            Object ObjCred = (Object)creds1.clone();
            System.out.println ("Size of p2 is " + p2.size() +
                                "Size of ObjCred is " +
                                        ((HashSet)ObjCred).size()
                                );
            if (p2.equals(ObjCred))
                throw new RuntimeException ("Error: Equals ObjCred");
            else
                throw new RuntimeException ("Error: Does not Equal Objcred");
        } catch (SecurityException e) {
            System.out.println("Should get an Exception in equals of creds1");
        }
        /* We can store only string types of creds
         * Let us create a subject with only string type of creds
         */

        HashSet creds2 = new HashSet();
        creds2.add("abc");
        creds2.add("def");
        creds2.add("ghi");
        Subject sstring =
            new Subject(false,  //readOnly
                        Collections.singleton(new SolarisPrincipal("user")),
                        Collections.EMPTY_SET,
                        creds2);
        p2 = sstring.getPrivateCredentials();
        try {
            String[] selectArray = { "exits", "Does not exist"};
            Object ObjAr = p2.toArray(selectArray);
            System.out.println(" No Exception in ObjAr- String");

        } catch (SecurityException e) {
                throw new RuntimeException(" Error:  Exception in ObjAr- String!!");
        }
        /*
         * New subject scontain1, set p3, creds4
         */


        HashSet creds4 = new HashSet();
        creds4.add("abc");
        creds4.add("def");
        creds4.add("ghi");
        creds4.add(new Integer(1));
        creds4.add("Exists");
        Subject scontain1 =
            new Subject(false,  //readOnly
                        Collections.singleton(new SolarisPrincipal("user")),
                        Collections.EMPTY_SET,
                        creds4);
        Set p3 = scontain1.getPrivateCredentials();
        try {
            Object Obj = new String("Exists");
            if (p3.contains(Obj))
                System.out.println ("Contains String cred");
            else
                throw new RuntimeException ("Error Does not Contain the stringcred exists");
        } catch (SecurityException e) {
            throw new RuntimeException("Error:Exception!!");

        }
        try {
            Object ObjCred = (Object)creds4.clone();
            if (p3.equals(ObjCred))
                throw new RuntimeException ("Error:Equals ObjCred");
            else
                throw new RuntimeException ("Error:Does not Equal Objcred");
        } catch (SecurityException e) {
            System.out.println("Should  get an Exception in equals");
        }

        try {
            Object Obj = new Integer(1);
            if (p3.contains(Obj))
                throw new RuntimeException ("Error:Contains integer cred");
            else
                throw new RuntimeException ("Error:Does not Contain integer cred");
        } catch (SecurityException e) {
            System.out.println("Should get an Exception in contains Integer cred");
        }



        HashSet coll = new HashSet();
        coll.add(new String("abc"));
        coll.add(new String("def"));
        coll.add(new String("Exists"));
        coll.add(new String("Does not Exist"));
        try {
        if (p3.containsAll(coll))
                throw new RuntimeException ("Error: Contains the collection");
        else
                System.out.println ("Does not Contain the collection");
        } catch (SecurityException e) {
                throw new RuntimeException("Error: Exception in containsAll (string coll)!!");

        }
        coll.remove(new String("Exists"));
        coll.remove(new String("Does not Exist"));
        try {
        if (p3.containsAll(coll))
                System.out.println ("Contains the collection");
        else
                throw new RuntimeException ("Error:Does not Contain the collection");
        } catch (SecurityException e) {
                throw new RuntimeException("Error: Exception in containsAll (string coll)!!");
        }

        Object Obj = new String("Exists");
        try {
        if (p3.contains(Obj))
                System.out.println ("Contains String cred exists");
        else
                System.out.println ("Does not Contain String cred exists");
        } catch (SecurityException e) {
                System.out.println("Exception in String cred!!");
        }

        Obj = new String("Does not exist");
        try {
        if (p3.contains(Obj))
                throw new RuntimeException ("Error: Contains the String does not exist");
        else
                System.out.println ("Does not Contain the String cred Does not exist");
        } catch (SecurityException e) {
                throw new RuntimeException("Error: Exception in Contains!!");
        }
        p3.add(new Integer(2));
        coll.add(new Integer(2));
        p3.add("XYZ");

        System.out.println ("Testing Retainall ");
        exceptionCounter =0;
        iter1 = p3.iterator();
        while (iter1.hasNext())
            {
                try {
                    Object o = iter1.next();
                    System.out.println(" private creds of class " +
                                       o.getClass() + "value is " + o.toString());
                } catch (SecurityException e) {
                    System.out.println(" We should get exception");
                    System.out.println("Exception!!");
                    exceptionCounter++;
                }
            }
        System.out.println(" After the retainall Operation");
        try {
            if (p3.retainAll(coll))
                System.out.println ("Retained the collection");
            else
                throw new RuntimeException ("Error: RetainAll did not succeed");
        } catch (SecurityException e) {
                e.printStackTrace();
                throw new RuntimeException("Error: Unexpected Exception in retainAll!");
        }
        iter1 = p3.iterator();
        while (iter1.hasNext())
            {
                try {
                    Object o = iter1.next();
                    System.out.println(" private creds of class " +
                                       o.getClass() + "value is " + o.toString());
                } catch (SecurityException e) {
                    exceptionCounter++;
                }
            }
        System.out.println ("Retainall collection");
        p3.add(new Integer (3));
        iter1 = p3.iterator();
        while (iter1.hasNext()) {
            try {
                Object o = iter1.next();
                System.out.println(" private creds of class " +
                                   o.getClass() + "value is " + o.toString());
            } catch (SecurityException e) {
                System.out.println("Should get Exception ");
            }
        }
        exceptionCounter=0;
        HashSet coll2 = new HashSet();
        coll2.add(new String("abc"));
        coll2.add(new Integer (3));
        System.out.println(" before removeall");
        iter1 = p3.iterator();
        exceptionCounter =0;
        while (iter1.hasNext()) {
            try {
                Object o = iter1.next();
                System.out.println(" private creds of class " +
                                   o.getClass() + "value is " + o.toString());
            } catch (SecurityException e) {
                System.out.println("Expected Exception thrown ");
                exceptionCounter++;
            }
        }
        // We added two integer creds so there must be two exceptions only

        if (exceptionCounter != 2) {
                throw new RuntimeException("Expected 2 Exceptions; received " +
                                   exceptionCounter + "exceptions ");
        }

        try {
        p3.removeAll(coll2);
        System.out.println(" removeall successful! ");
        } catch (SecurityException e) {
                throw new RuntimeException(" Error: removeAll Security Exception!!");
        }

        iter1 = p3.iterator();
        System.out.println(" After removeall");
        exceptionCounter = 0;
        while (iter1.hasNext()) {
            try {
                Object o = iter1.next();
                System.out.println (" private creds of class " +
                                   o.getClass() + "value is " + o.toString());
            } catch (SecurityException e) {
                System.out.println("Expected Exception thrown ");
                exceptionCounter++;
            }
        }
        // We had two integer creds; removed one as  a part of coll2; so
        // only one exception must have been thrown
        if (exceptionCounter != 1) {
                throw new RuntimeException("Expected 1 Exceptions; received " +
                                   exceptionCounter + "exceptions ");
        }
        try {
        p3.clear();
        System.out.println(" Clear() successful! ");
        } catch (SecurityException e) {
                throw new RuntimeException(" Error: Clear Security Exception!!");
        }


         /*   New subject s with creds and privCredSet
          *
          */
        creds.clear();
        creds.add("abc");
        creds.add("def");
        creds.add("ghi");
        creds.add(new Integer(1));
        Subject s =
            new Subject(false,  //readOnly
                        Collections.singleton(new SolarisPrincipal("user")),
                        Collections.EMPTY_SET,
                        creds);
        try {
           Set privCredSet = s.getPrivateCredentials(char.class);
           if (privCredSet.size() != 0) {
              throw new RuntimeException("Error:String Privcred size should have been 0 and was " +
                                 privCredSet.size());
            }

        } catch (Exception e) {
            throw new RuntimeException ("Error " + e.toString());
        }


        try {
           Set privCredSet = s.getPrivateCredentials(String.class);
           if (privCredSet.size() != 3) {
              throw new RuntimeException("Error:String Privcred size should have been 2 and was " +
                         privCredSet.size());
           }
           s.getPrivateCredentials().add("XYZ");
           /*
            * Since the privCredSet is not backed by internal private
            * creds adding to it should not make any difference to
            * privCredSet and theize should still be 3
            */

           if (privCredSet.size() != 3) {
              throw new RuntimeException("Error:String Privcred size should have been 2 and was " +
                         privCredSet.size());
           }
           s.getPrivateCredentials().remove("XYZ");
                /*
                 * Let us try to get the elements
                 * No exception should occur
                 */

           Iterator iter = privCredSet.iterator();
           while (iter.hasNext()) {
             try {
                Object o = iter.next();
                System.out.println(" private creds of class " +
                        o.getClass() + "value is " + o.toString());
             } catch (SecurityException e) {
             }
           }
        } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("Unexcpected Exception");
        }

        /*
         * Can we add and remove the creds
         */
        s.getPrivateCredentials().add("XYZ");
        s.getPrivateCredentials().remove("XYZ");
        s.getPrivateCredentials().add(new Integer(2));
        s.getPrivateCredentials().remove(new Integer(2));


        // We don't have permission to read Boolean creds
        // SInce the creds have no boolean creds we should get an empty
        // set
        try {
            Set privCredSet1 = s.getPrivateCredentials(Boolean.class);
            if (privCredSet1.size() != 0){
                  throw new RuntimeException("Error:String PrivcredSet1 of Boolean size should have been 0 and was " +
                         privCredSet1.size());
            }
        } catch (SecurityException e) {
                e.printStackTrace();
                throw new RuntimeException("Unexcpected Exception");
        }
        System.out.println ("Checked Boolean Creds ");

        /*
         * We don't have permission to read Integer creds
         * We should get an empty set even though the private creds
         * has an integer cred. No security exception either !
         */

        try {
            Set privCredSet1 = s.getPrivateCredentials(Integer.class);
            if (privCredSet1.size() != 0){
                  throw new RuntimeException("Error:String PrivcredSet1 of Integer size should have been 0 and was " +
                         privCredSet1.size());
            }
        } catch (SecurityException e) {
                System.out.println ("Expected exception");
        }
        System.out.println ("Checked Integer Creds ");

        Set privCredSet2 = s.getPrivateCredentials();

        if (privCredSet2.size() != 4){
              throw new RuntimeException("Error:String PrivcredSet1 size should have been 4 and was " +
                         privCredSet2.size());
        }

        /*
         * Since the returned privCredSet2 is internally backed by the
         * private creds, any additions to it should be reflected in
         * privcredSet2
         */
        s.getPrivateCredentials().add("XYZ");
        if (privCredSet2.size() != 5) {
              throw new RuntimeException("Error:String PrivcredSet1 size should have been 5 and was " +
                         privCredSet2.size());
        }
        s.getPrivateCredentials().remove("XYZ");
        if (privCredSet2.size() != 4) {
              throw new RuntimeException("String privCredSet2 size should have been  5 and was " +
                         privCredSet2.size());
        }
        System.out.println("Checked remove(String) operation");
        /* Let us add a couple of Boolean creds */
        s.getPrivateCredentials().add(Boolean.TRUE);
        s.getPrivateCredentials().add(new Integer(2));

        exceptionCounter =0;
        iter1 = privCredSet2.iterator();
        while (iter1.hasNext())
            {
                try {
                    Object o = iter1.next();
                    System.out.println(" private creds of class " +
                                       o.getClass() + "value is " + o.toString());
                } catch (SecurityException e) {
                    System.out.println(" We should get exception");
                    System.out.println("Exception!!");
                    exceptionCounter++;
                }
            }
        if (exceptionCounter != 3) {
            throw new RuntimeException("Expected number of exception was 3 " +
                        "The actual number was " + exceptionCounter);
        }
        privCredSet2.add (new Integer(3));
        try {
        int hashCode = privCredSet2.hashCode();
        } catch (SecurityException e) {
                System.out.println ("hashCode Expected exception");
        }
        System.out.println ("Tests completed");
    }

}
