blob: a48e1f98184db20e2dbae612a4d111dbc0869871 [file] [log] [blame]
/*
* Copyright (c) 2000, 2017, 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
* @modules jdk.security.auth
* @summary Retrive a subset of private credentials can be accessed
* @run main/othervm/policy=Subset.policy Subset
*/
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
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");
}
}