/* * 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"); } }