/*
 * Copyright (c) 2000, 2007, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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");
    }

}
