mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-12 19:35:24 +00:00
8015081: javax.security.auth.Subject.toString() throws NPE
Reviewed-by: xuelei, weijun
This commit is contained in:
parent
5a0450feea
commit
2edd214440
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1998, 2014, 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
|
||||
@ -142,7 +142,9 @@ public final class Subject implements java.io.Serializable {
|
||||
* <p> The newly constructed Sets check whether this {@code Subject}
|
||||
* has been set read-only before permitting subsequent modifications.
|
||||
* The newly created Sets also prevent illegal modifications
|
||||
* by ensuring that callers have sufficient permissions.
|
||||
* by ensuring that callers have sufficient permissions. These Sets
|
||||
* also prohibit null elements, and attempts to add or query a null
|
||||
* element will result in a {@code NullPointerException}.
|
||||
*
|
||||
* <p> To modify the Principals Set, the caller must have
|
||||
* {@code AuthPermission("modifyPrincipals")}.
|
||||
@ -170,7 +172,9 @@ public final class Subject implements java.io.Serializable {
|
||||
* These newly created Sets check whether this {@code Subject}
|
||||
* has been set read-only before permitting subsequent modifications.
|
||||
* The newly created Sets also prevent illegal modifications
|
||||
* by ensuring that callers have sufficient permissions.
|
||||
* by ensuring that callers have sufficient permissions. These Sets
|
||||
* also prohibit null elements, and attempts to add or query a null
|
||||
* element will result in a {@code NullPointerException}.
|
||||
*
|
||||
* <p> To modify the Principals Set, the caller must have
|
||||
* {@code AuthPermission("modifyPrincipals")}.
|
||||
@ -194,17 +198,16 @@ public final class Subject implements java.io.Serializable {
|
||||
*
|
||||
* @exception NullPointerException if the specified
|
||||
* {@code principals}, {@code pubCredentials},
|
||||
* or {@code privCredentials} are {@code null}.
|
||||
* or {@code privCredentials} are {@code null},
|
||||
* or a null value exists within any of these three
|
||||
* Sets.
|
||||
*/
|
||||
public Subject(boolean readOnly, Set<? extends Principal> principals,
|
||||
Set<?> pubCredentials, Set<?> privCredentials)
|
||||
{
|
||||
|
||||
if (principals == null ||
|
||||
pubCredentials == null ||
|
||||
privCredentials == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.input.s."));
|
||||
collectionNullClean(principals);
|
||||
collectionNullClean(pubCredentials);
|
||||
collectionNullClean(privCredentials);
|
||||
|
||||
this.principals = Collections.synchronizedSet(new SecureSet<Principal>
|
||||
(this, PRINCIPAL_SET, principals));
|
||||
@ -287,18 +290,17 @@ public final class Subject implements java.io.Serializable {
|
||||
sm.checkPermission(AuthPermissionHolder.GET_SUBJECT_PERMISSION);
|
||||
}
|
||||
|
||||
if (acc == null) {
|
||||
throw new NullPointerException(ResourcesMgr.getString
|
||||
Objects.requireNonNull(acc, ResourcesMgr.getString
|
||||
("invalid.null.AccessControlContext.provided"));
|
||||
}
|
||||
|
||||
// return the Subject from the DomainCombiner of the provided context
|
||||
return AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<Subject>() {
|
||||
public Subject run() {
|
||||
DomainCombiner dc = acc.getDomainCombiner();
|
||||
if (!(dc instanceof SubjectDomainCombiner))
|
||||
if (!(dc instanceof SubjectDomainCombiner)) {
|
||||
return null;
|
||||
}
|
||||
SubjectDomainCombiner sdc = (SubjectDomainCombiner)dc;
|
||||
return sdc.getSubject();
|
||||
}
|
||||
@ -347,9 +349,9 @@ public final class Subject implements java.io.Serializable {
|
||||
if (sm != null) {
|
||||
sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
|
||||
}
|
||||
if (action == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
|
||||
Objects.requireNonNull(action,
|
||||
ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
|
||||
// set up the new Subject-based AccessControlContext
|
||||
// for doPrivileged
|
||||
@ -410,9 +412,8 @@ public final class Subject implements java.io.Serializable {
|
||||
sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION);
|
||||
}
|
||||
|
||||
if (action == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
Objects.requireNonNull(action,
|
||||
ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
|
||||
// set up the new Subject-based AccessControlContext for doPrivileged
|
||||
final AccessControlContext currentAcc = AccessController.getContext();
|
||||
@ -467,9 +468,8 @@ public final class Subject implements java.io.Serializable {
|
||||
sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
|
||||
}
|
||||
|
||||
if (action == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
Objects.requireNonNull(action,
|
||||
ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
|
||||
// set up the new Subject-based AccessControlContext
|
||||
// for doPrivileged
|
||||
@ -534,9 +534,8 @@ public final class Subject implements java.io.Serializable {
|
||||
sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION);
|
||||
}
|
||||
|
||||
if (action == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
Objects.requireNonNull(action,
|
||||
ResourcesMgr.getString("invalid.null.action.provided"));
|
||||
|
||||
// set up the new Subject-based AccessControlContext for doPrivileged
|
||||
final AccessControlContext callerAcc =
|
||||
@ -557,13 +556,14 @@ public final class Subject implements java.io.Serializable {
|
||||
return java.security.AccessController.doPrivileged
|
||||
(new java.security.PrivilegedAction<AccessControlContext>() {
|
||||
public AccessControlContext run() {
|
||||
if (subject == null)
|
||||
if (subject == null) {
|
||||
return new AccessControlContext(acc, null);
|
||||
else
|
||||
} else {
|
||||
return new AccessControlContext
|
||||
(acc,
|
||||
new SubjectDomainCombiner(subject));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -615,9 +615,8 @@ public final class Subject implements java.io.Serializable {
|
||||
*/
|
||||
public <T extends Principal> Set<T> getPrincipals(Class<T> c) {
|
||||
|
||||
if (c == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.Class.provided"));
|
||||
Objects.requireNonNull(c,
|
||||
ResourcesMgr.getString("invalid.null.Class.provided"));
|
||||
|
||||
// always return an empty Set instead of null
|
||||
// so LoginModules can add to the Set if necessary
|
||||
@ -711,9 +710,8 @@ public final class Subject implements java.io.Serializable {
|
||||
*/
|
||||
public <T> Set<T> getPublicCredentials(Class<T> c) {
|
||||
|
||||
if (c == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.Class.provided"));
|
||||
Objects.requireNonNull(c,
|
||||
ResourcesMgr.getString("invalid.null.Class.provided"));
|
||||
|
||||
// always return an empty Set instead of null
|
||||
// so LoginModules can add to the Set if necessary
|
||||
@ -758,9 +756,8 @@ public final class Subject implements java.io.Serializable {
|
||||
// would do is protect the set operations themselves
|
||||
// (like size()), which don't seem security-sensitive.
|
||||
|
||||
if (c == null)
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.Class.provided"));
|
||||
Objects.requireNonNull(c,
|
||||
ResourcesMgr.getString("invalid.null.Class.provided"));
|
||||
|
||||
// always return an empty Set instead of null
|
||||
// so LoginModules can add to the Set if necessary
|
||||
@ -790,11 +787,13 @@ public final class Subject implements java.io.Serializable {
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
|
||||
if (o == null)
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this == o)
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (o instanceof Subject) {
|
||||
|
||||
@ -969,11 +968,10 @@ public final class Subject implements java.io.Serializable {
|
||||
|
||||
Set<Principal> inputPrincs = (Set<Principal>)gf.get("principals", null);
|
||||
|
||||
Objects.requireNonNull(inputPrincs,
|
||||
ResourcesMgr.getString("invalid.null.input.s."));
|
||||
|
||||
// Rewrap the principals into a SecureSet
|
||||
if (inputPrincs == null) {
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.input.s."));
|
||||
}
|
||||
try {
|
||||
principals = Collections.synchronizedSet(new SecureSet<Principal>
|
||||
(this, PRINCIPAL_SET, inputPrincs));
|
||||
@ -992,14 +990,44 @@ public final class Subject implements java.io.Serializable {
|
||||
(new SecureSet<Object>(this, PRIV_CREDENTIAL_SET));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for null-clean collections (both non-null reference and
|
||||
* no null elements)
|
||||
*
|
||||
* @param coll A {@code Collection} to be tested for null references
|
||||
*
|
||||
* @exception NullPointerException if the specified collection is either
|
||||
* {@code null} or contains a {@code null} element
|
||||
*/
|
||||
private static void collectionNullClean(Collection<?> coll) {
|
||||
boolean hasNullElements = false;
|
||||
|
||||
Objects.requireNonNull(coll,
|
||||
ResourcesMgr.getString("invalid.null.input.s."));
|
||||
|
||||
try {
|
||||
hasNullElements = coll.contains(null);
|
||||
} catch (NullPointerException npe) {
|
||||
// A null-hostile collection may choose to throw
|
||||
// NullPointerException if contains(null) is called on it
|
||||
// rather than returning false.
|
||||
// If this happens we know the collection is null-clean.
|
||||
hasNullElements = false;
|
||||
} finally {
|
||||
if (hasNullElements) {
|
||||
throw new NullPointerException
|
||||
(ResourcesMgr.getString("invalid.null.input.s."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent modifications unless caller has permission.
|
||||
*
|
||||
* @serial include
|
||||
*/
|
||||
private static class SecureSet<E>
|
||||
extends AbstractSet<E>
|
||||
implements java.io.Serializable {
|
||||
implements Set<E>, java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7911754171111800359L;
|
||||
|
||||
@ -1098,6 +1126,9 @@ public final class Subject implements java.io.Serializable {
|
||||
|
||||
public boolean add(E o) {
|
||||
|
||||
Objects.requireNonNull(o,
|
||||
ResourcesMgr.getString("invalid.null.input.s."));
|
||||
|
||||
if (subject.isReadOnly()) {
|
||||
throw new IllegalStateException
|
||||
(ResourcesMgr.getString("Subject.is.read.only"));
|
||||
@ -1133,12 +1164,16 @@ public final class Subject implements java.io.Serializable {
|
||||
// check for duplicates
|
||||
if (!elements.contains(o))
|
||||
return elements.add(o);
|
||||
else
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean remove(Object o) {
|
||||
|
||||
Objects.requireNonNull(o,
|
||||
ResourcesMgr.getString("invalid.null.input.s."));
|
||||
|
||||
final Iterator<E> e = iterator();
|
||||
while (e.hasNext()) {
|
||||
E next;
|
||||
@ -1153,12 +1188,7 @@ public final class Subject implements java.io.Serializable {
|
||||
});
|
||||
}
|
||||
|
||||
if (next == null) {
|
||||
if (o == null) {
|
||||
e.remove();
|
||||
return true;
|
||||
}
|
||||
} else if (next.equals(o)) {
|
||||
if (next.equals(o)) {
|
||||
e.remove();
|
||||
return true;
|
||||
}
|
||||
@ -1167,6 +1197,10 @@ public final class Subject implements java.io.Serializable {
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
|
||||
Objects.requireNonNull(o,
|
||||
ResourcesMgr.getString("invalid.null.input.s."));
|
||||
|
||||
final Iterator<E> e = iterator();
|
||||
while (e.hasNext()) {
|
||||
E next;
|
||||
@ -1194,19 +1228,28 @@ public final class Subject implements java.io.Serializable {
|
||||
});
|
||||
}
|
||||
|
||||
if (next == null) {
|
||||
if (o == null) {
|
||||
return true;
|
||||
}
|
||||
} else if (next.equals(o)) {
|
||||
if (next.equals(o)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
boolean result = false;
|
||||
|
||||
collectionNullClean(c);
|
||||
|
||||
for (E item : c) {
|
||||
result |= this.add(item);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
collectionNullClean(c);
|
||||
|
||||
boolean modified = false;
|
||||
final Iterator<E> e = iterator();
|
||||
while (e.hasNext()) {
|
||||
@ -1224,30 +1267,34 @@ public final class Subject implements java.io.Serializable {
|
||||
|
||||
Iterator<?> ce = c.iterator();
|
||||
while (ce.hasNext()) {
|
||||
Object o = ce.next();
|
||||
if (next == null) {
|
||||
if (o == null) {
|
||||
if (next.equals(ce.next())) {
|
||||
e.remove();
|
||||
modified = true;
|
||||
break;
|
||||
}
|
||||
} else if (next.equals(o)) {
|
||||
e.remove();
|
||||
modified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
collectionNullClean(c);
|
||||
|
||||
for (Object item : c) {
|
||||
if (this.contains(item) == false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
Objects.requireNonNull(c);
|
||||
collectionNullClean(c);
|
||||
|
||||
boolean modified = false;
|
||||
boolean retain = false;
|
||||
final Iterator<E> e = iterator();
|
||||
while (e.hasNext()) {
|
||||
retain = false;
|
||||
E next;
|
||||
if (which != Subject.PRIV_CREDENTIAL_SET) {
|
||||
next = e.next();
|
||||
@ -1260,26 +1307,12 @@ public final class Subject implements java.io.Serializable {
|
||||
});
|
||||
}
|
||||
|
||||
Iterator<?> ce = c.iterator();
|
||||
while (ce.hasNext()) {
|
||||
Object o = ce.next();
|
||||
if (next == null) {
|
||||
if (o == null) {
|
||||
retain = true;
|
||||
break;
|
||||
}
|
||||
} else if (next.equals(o)) {
|
||||
retain = true;
|
||||
break;
|
||||
if (c.contains(next) == false) {
|
||||
e.remove();
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!retain) {
|
||||
e.remove();
|
||||
retain = false;
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@ -1301,6 +1334,73 @@ public final class Subject implements java.io.Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return elements.isEmpty();
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
final Iterator<E> e = iterator();
|
||||
while (e.hasNext()) {
|
||||
// The next() method performs a security manager check
|
||||
// on each element in the SecureSet. If we make it all
|
||||
// the way through we should be able to simply return
|
||||
// element's toArray results. Otherwise we'll let
|
||||
// the SecurityException pass up the call stack.
|
||||
e.next();
|
||||
}
|
||||
|
||||
return elements.toArray();
|
||||
}
|
||||
|
||||
public <T> T[] toArray(T[] a) {
|
||||
final Iterator<E> e = iterator();
|
||||
while (e.hasNext()) {
|
||||
// The next() method performs a security manager check
|
||||
// on each element in the SecureSet. If we make it all
|
||||
// the way through we should be able to simply return
|
||||
// element's toArray results. Otherwise we'll let
|
||||
// the SecurityException pass up the call stack.
|
||||
e.next();
|
||||
}
|
||||
|
||||
return elements.toArray(a);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof Set)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Collection<?> c = (Collection<?>) o;
|
||||
if (c.size() != size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return containsAll(c);
|
||||
} catch (ClassCastException unused) {
|
||||
return false;
|
||||
} catch (NullPointerException unused) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int h = 0;
|
||||
Iterator<E> i = iterator();
|
||||
while (i.hasNext()) {
|
||||
E obj = i.next();
|
||||
if (obj != null) {
|
||||
h += obj.hashCode();
|
||||
}
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes this object out to a stream (i.e., serializes it).
|
||||
*
|
||||
@ -1338,12 +1438,16 @@ public final class Subject implements java.io.Serializable {
|
||||
which = fields.get("which", 0);
|
||||
|
||||
LinkedList<E> tmp = (LinkedList<E>) fields.get("elements", null);
|
||||
|
||||
Subject.collectionNullClean(tmp);
|
||||
|
||||
if (tmp.getClass() != LinkedList.class) {
|
||||
elements = new LinkedList<E>(tmp);
|
||||
} else {
|
||||
elements = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2005, 2014 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
|
||||
@ -28,7 +28,7 @@
|
||||
*/
|
||||
|
||||
import java.security.*;
|
||||
import javax.security.auth.*;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
public class Generic {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2014, 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
|
||||
@ -29,7 +29,7 @@
|
||||
* @run main/othervm/policy=Serial.policy Serial
|
||||
*/
|
||||
|
||||
import javax.security.auth.*;
|
||||
import javax.security.auth.Subject;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
126
jdk/test/javax/security/auth/Subject/Subject.java
Normal file
126
jdk/test/javax/security/auth/Subject/Subject.java
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* An implementation of the Subject class that provides basic functionality
|
||||
* for the construction of Subject objects with null Principal elements.
|
||||
* This is a helper class for serialization tests tied to bug 8015081
|
||||
* (see SubjectNullTests.java).
|
||||
*/
|
||||
package jjjjj.security.auth;
|
||||
|
||||
import sun.misc.HexDumpEncoder;
|
||||
import javax.management.remote.JMXPrincipal;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamField;
|
||||
import java.lang.Exception;
|
||||
import java.lang.RuntimeException;
|
||||
import java.security.Principal;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import java.io.FileOutputStream;
|
||||
|
||||
public class Subject implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8308522755600156056L;
|
||||
|
||||
Set<Principal> principals;
|
||||
private volatile boolean readOnly = false;
|
||||
private static final int PRINCIPAL_SET = 1;
|
||||
|
||||
public Subject(Set<? extends Principal> principals) {
|
||||
this.principals = Collections.synchronizedSet(new SecureSet<Principal>
|
||||
(this, PRINCIPAL_SET, principals));
|
||||
}
|
||||
|
||||
public Set<Principal> getPrincipals() {
|
||||
return principals;
|
||||
}
|
||||
|
||||
private static class SecureSet<E>
|
||||
extends AbstractSet<E>
|
||||
implements java.io.Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7911754171111800359L;
|
||||
private static final ObjectStreamField[] serialPersistentFields = {
|
||||
new ObjectStreamField("this$0", Subject.class),
|
||||
new ObjectStreamField("elements", LinkedList.class),
|
||||
new ObjectStreamField("which", int.class)
|
||||
};
|
||||
|
||||
Subject subject;
|
||||
LinkedList<E> elements;
|
||||
private int which;
|
||||
|
||||
SecureSet(Subject subject, int which, Set<? extends E> set) {
|
||||
this.subject = subject;
|
||||
this.which = which;
|
||||
this.elements = new LinkedList<E>(set);
|
||||
}
|
||||
|
||||
public Iterator<E> iterator() {
|
||||
return elements.iterator();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return elements.size();
|
||||
}
|
||||
|
||||
private void writeObject(java.io.ObjectOutputStream oos)
|
||||
throws java.io.IOException {
|
||||
|
||||
ObjectOutputStream.PutField fields = oos.putFields();
|
||||
fields.put("this$0", subject);
|
||||
fields.put("elements", elements);
|
||||
fields.put("which", which);
|
||||
oos.writeFields();
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] enc(Object obj) {
|
||||
try {
|
||||
HexDumpEncoder hex = new HexDumpEncoder();
|
||||
ByteArrayOutputStream bout;
|
||||
bout = new ByteArrayOutputStream();
|
||||
new ObjectOutputStream(bout).writeObject(obj);
|
||||
byte[] data = bout.toByteArray();
|
||||
for (int i = 0; i < data.length - 5; i++) {
|
||||
if (data[i] == 'j' && data[i + 1] == 'j' && data[i + 2] == 'j'
|
||||
&& data[i + 3] == 'j' && data[i + 4] == 'j') {
|
||||
System.arraycopy("javax".getBytes(), 0, data, i, 5);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
852
jdk/test/javax/security/auth/Subject/SubjectNullTests.java
Normal file
852
jdk/test/javax/security/auth/Subject/SubjectNullTests.java
Normal file
@ -0,0 +1,852 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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
|
||||
* @bug 8015081
|
||||
* @compile Subject.java
|
||||
* @compile SubjectNullTests.java
|
||||
* @build SubjectNullTests
|
||||
* @run main SubjectNullTests
|
||||
* @summary javax.security.auth.Subject.toString() throws NPE
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.management.remote.JMXPrincipal;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import javax.security.auth.kerberos.KerberosPrincipal;
|
||||
|
||||
public class SubjectNullTests {
|
||||
|
||||
// Value templates for the constructor
|
||||
private static Principal[] princVals = {
|
||||
new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US"),
|
||||
new JMXPrincipal("Huckleberry Finn"),
|
||||
new KerberosPrincipal("mtwain/author@LITERATURE.US")
|
||||
};
|
||||
private static String[] pubVals = {"tsawyer", "hfinn", "mtwain"};
|
||||
private static String[] privVals = {"th3R!v3r", "oNth3R4ft", "5Cl3M3nz"};
|
||||
|
||||
// Templates for collection-based modifiers for the Subject
|
||||
private static Principal[] tmplAddPrincs = {
|
||||
new X500Principal("CN=John Doe, O=Bogus Corp."),
|
||||
new KerberosPrincipal("jdoe/admin@BOGUSCORP.COM")
|
||||
};
|
||||
private static String[] tmplAddPubVals = {"jdoe", "djoe"};
|
||||
private static String[] tmplAddPrvVals = {"b4dpa55w0rd", "pass123"};
|
||||
|
||||
/**
|
||||
* Byte arrays used for deserialization:
|
||||
* These byte arrays contain serialized Subjects and SecureSets,
|
||||
* either with or without nulls. These use
|
||||
* jjjjj.security.auth.Subject, which is a modified Subject
|
||||
* implementation that allows the addition of null elements
|
||||
*/
|
||||
private static final byte[] SUBJ_NO_NULL =
|
||||
jjjjj.security.auth.Subject.enc(makeSubjWithNull(false));
|
||||
private static final byte[] SUBJ_WITH_NULL =
|
||||
jjjjj.security.auth.Subject.enc(makeSubjWithNull(true));
|
||||
private static final byte[] PRIN_NO_NULL =
|
||||
jjjjj.security.auth.Subject.enc(makeSecSetWithNull(false));
|
||||
private static final byte[] PRIN_WITH_NULL =
|
||||
jjjjj.security.auth.Subject.enc(makeSecSetWithNull(true));
|
||||
|
||||
/**
|
||||
* Method to allow creation of a subject that can optionally
|
||||
* insert a null reference into the principals Set.
|
||||
*/
|
||||
private static jjjjj.security.auth.Subject makeSubjWithNull(
|
||||
boolean nullPrinc) {
|
||||
Set<Principal> setPrinc = new HashSet<>(Arrays.asList(princVals));
|
||||
if (nullPrinc) {
|
||||
setPrinc.add(null);
|
||||
}
|
||||
|
||||
return (new jjjjj.security.auth.Subject(setPrinc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to allow creation of a SecureSet that can optionally
|
||||
* insert a null reference.
|
||||
*/
|
||||
private static Set<Principal> makeSecSetWithNull(boolean nullPrinc) {
|
||||
Set<Principal> setPrinc = new HashSet<>(Arrays.asList(princVals));
|
||||
if (nullPrinc) {
|
||||
setPrinc.add(null);
|
||||
}
|
||||
|
||||
jjjjj.security.auth.Subject subj =
|
||||
new jjjjj.security.auth.Subject(setPrinc);
|
||||
|
||||
return subj.getPrincipals();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a subject, and optionally place a null in any one
|
||||
* of the three Sets used to initialize a Subject's values
|
||||
*/
|
||||
private static Subject makeSubj(boolean nullPrinc, boolean nullPub,
|
||||
boolean nullPriv) {
|
||||
Set<Principal> setPrinc = new HashSet<>(Arrays.asList(princVals));
|
||||
Set<String> setPubCreds = new HashSet<>(Arrays.asList(pubVals));
|
||||
Set<String> setPrvCreds = new HashSet<>(Arrays.asList(privVals));
|
||||
|
||||
if (nullPrinc) {
|
||||
setPrinc.add(null);
|
||||
}
|
||||
|
||||
if (nullPub) {
|
||||
setPubCreds.add(null);
|
||||
}
|
||||
|
||||
if (nullPriv) {
|
||||
setPrvCreds.add(null);
|
||||
}
|
||||
|
||||
return (new Subject(false, setPrinc, setPubCreds, setPrvCreds));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a simple interface for abstracting collection-on-collection
|
||||
* functions
|
||||
*/
|
||||
public interface Function {
|
||||
boolean execCollection(Set<?> subjSet, Collection<?> actorData);
|
||||
}
|
||||
|
||||
public static final Function methAdd = new Function() {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {
|
||||
return subjSet.addAll((Collection)actorData);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function methContains = new Function() {
|
||||
@Override
|
||||
public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {
|
||||
return subjSet.containsAll(actorData);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function methRemove = new Function() {
|
||||
@Override
|
||||
public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {
|
||||
return subjSet.removeAll(actorData);
|
||||
}
|
||||
};
|
||||
|
||||
public static final Function methRetain = new Function() {
|
||||
@Override
|
||||
public boolean execCollection(Set<?> subjSet, Collection<?> actorData) {
|
||||
return subjSet.retainAll(actorData);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Run a test using a specified Collection method upon a Subject's
|
||||
* SecureSet fields. This method expects NullPointerExceptions
|
||||
* to be thrown, and throws RuntimeException when the operation
|
||||
* succeeds
|
||||
*/
|
||||
private static void nullTestCollection(Function meth, Set<?> subjSet,
|
||||
Collection<?> actorData) {
|
||||
try {
|
||||
meth.execCollection(subjSet, actorData);
|
||||
throw new RuntimeException("Failed to throw NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("Caught expected NullPointerException [PASS]");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run a test using a specified Collection method upon a Subject's
|
||||
* SecureSet fields. This method expects the function and arguments
|
||||
* passed in to complete without exception. It returns false
|
||||
* if either an exception occurs or the result of the operation is
|
||||
* false.
|
||||
*/
|
||||
private static boolean validTestCollection(Function meth, Set<?> subjSet,
|
||||
Collection<?> actorData) {
|
||||
boolean result = false;
|
||||
|
||||
try {
|
||||
result = meth.execCollection(subjSet, actorData);
|
||||
} catch (Exception exc) {
|
||||
System.out.println("Caught exception " + exc);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize an object from a byte array.
|
||||
*
|
||||
* @param type The {@code Class} that the serialized file is supposed
|
||||
* to contain.
|
||||
* @param serBuffer The byte array containing the serialized object data
|
||||
*
|
||||
* @return An object of the type specified in the {@code type} parameter
|
||||
*/
|
||||
private static <T> T deserializeBuffer(Class<T> type, byte[] serBuffer)
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
ByteArrayInputStream bis = new ByteArrayInputStream(serBuffer);
|
||||
ObjectInputStream ois = new ObjectInputStream(bis);
|
||||
|
||||
T newObj = type.cast(ois.readObject());
|
||||
ois.close();
|
||||
bis.close();
|
||||
|
||||
return newObj;
|
||||
}
|
||||
|
||||
private static void testCTOR() {
|
||||
System.out.println("------ constructor ------");
|
||||
|
||||
try {
|
||||
// Case 1: Create a subject with a null principal
|
||||
// Expected result: NullPointerException
|
||||
Subject mtSubj = makeSubj(true, false, false);
|
||||
throw new RuntimeException(
|
||||
"constructor [principal w/ null]: Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("constructor [principal w/ null]: " +
|
||||
"NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 2: Create a subject with a null public credential element
|
||||
// Expected result: NullPointerException
|
||||
Subject mtSubj = makeSubj(false, true, false);
|
||||
throw new RuntimeException(
|
||||
"constructor [pub cred w/ null]: Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("constructor [pub cred w/ null]: " +
|
||||
"NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 3: Create a subject with a null private credential element
|
||||
// Expected result: NullPointerException
|
||||
Subject mtSubj = makeSubj(false, false, true);
|
||||
throw new RuntimeException(
|
||||
"constructor [priv cred w/ null]: Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("constructor [priv cred w/ null]: " +
|
||||
"NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
// Case 4: Create a new subject using the principals, public
|
||||
// and private credentials from another well-formed subject
|
||||
// Expected result: Successful construction
|
||||
Subject srcSubj = makeSubj(false, false, false);
|
||||
Subject mtSubj = new Subject(false, srcSubj.getPrincipals(),
|
||||
srcSubj.getPublicCredentials(),
|
||||
srcSubj.getPrivateCredentials());
|
||||
System.out.println("Construction from another well-formed Subject's " +
|
||||
"principals/creds [PASS]");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static void testDeserialize() throws Exception {
|
||||
System.out.println("------ deserialize -----");
|
||||
|
||||
Subject subj = null;
|
||||
Set<Principal> prin = null;
|
||||
|
||||
// Case 1: positive deserialization test of a Subject
|
||||
// Expected result: well-formed Subject
|
||||
subj = deserializeBuffer(Subject.class, SUBJ_NO_NULL);
|
||||
System.out.println("Positive deserialization test (Subject) passed");
|
||||
|
||||
// Case 2: positive deserialization test of a SecureSet
|
||||
// Expected result: well-formed Set
|
||||
prin = deserializeBuffer(Set.class, PRIN_NO_NULL);
|
||||
System.out.println("Positive deserialization test (SecureSet) passed");
|
||||
|
||||
System.out.println(
|
||||
"* Testing deserialization with null-poisoned objects");
|
||||
// Case 3: deserialization test of a null-poisoned Subject
|
||||
// Expected result: NullPointerException
|
||||
try {
|
||||
subj = deserializeBuffer(Subject.class, SUBJ_WITH_NULL);
|
||||
throw new RuntimeException("Failed to throw NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("Caught expected NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
// Case 4: deserialization test of a null-poisoned SecureSet
|
||||
// Expected result: NullPointerException
|
||||
try {
|
||||
prin = deserializeBuffer(Set.class, PRIN_WITH_NULL);
|
||||
throw new RuntimeException("Failed to throw NullPointerException");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println("Caught expected NullPointerException [PASS]");
|
||||
}
|
||||
}
|
||||
|
||||
private static void testAdd() {
|
||||
System.out.println("------ add() ------");
|
||||
// Create a well formed subject
|
||||
Subject mtSubj = makeSubj(false, false, false);
|
||||
|
||||
try {
|
||||
// Case 1: Attempt to add null values to principal
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPrincipals().add(null);
|
||||
throw new RuntimeException(
|
||||
"PRINCIPAL add(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PRINCIPAL add(null): NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 2: Attempt to add null into the public creds
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPublicCredentials().add(null);
|
||||
throw new RuntimeException(
|
||||
"PUB CRED add(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PUB CRED add(null): NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 3: Attempt to add null into the private creds
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPrivateCredentials().add(null);
|
||||
throw new RuntimeException(
|
||||
"PRIV CRED add(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PRIV CRED add(null): NullPointerException [PASS]");
|
||||
}
|
||||
}
|
||||
|
||||
private static void testRemove() {
|
||||
System.out.println("------ remove() ------");
|
||||
// Create a well formed subject
|
||||
Subject mtSubj = makeSubj(false, false, false);
|
||||
|
||||
try {
|
||||
// Case 1: Attempt to remove null values from principal
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPrincipals().remove(null);
|
||||
throw new RuntimeException(
|
||||
"PRINCIPAL remove(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PRINCIPAL remove(null): NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 2: Attempt to remove null from the public creds
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPublicCredentials().remove(null);
|
||||
throw new RuntimeException(
|
||||
"PUB CRED remove(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PUB CRED remove(null): NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 3: Attempt to remove null from the private creds
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPrivateCredentials().remove(null);
|
||||
throw new RuntimeException(
|
||||
"PRIV CRED remove(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PRIV CRED remove(null): NullPointerException [PASS]");
|
||||
}
|
||||
}
|
||||
|
||||
private static void testContains() {
|
||||
System.out.println("------ contains() ------");
|
||||
// Create a well formed subject
|
||||
Subject mtSubj = makeSubj(false, false, false);
|
||||
|
||||
try {
|
||||
// Case 1: Attempt to check for null values in principals
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPrincipals().contains(null);
|
||||
throw new RuntimeException(
|
||||
"PRINCIPAL contains(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PRINCIPAL contains(null): NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 2: Attempt to check for null in public creds
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPublicCredentials().contains(null);
|
||||
throw new RuntimeException(
|
||||
"PUB CRED contains(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PUB CRED contains(null): NullPointerException [PASS]");
|
||||
}
|
||||
|
||||
try {
|
||||
// Case 3: Attempt to check for null in private creds
|
||||
// Expected result: NullPointerException
|
||||
mtSubj.getPrivateCredentials().contains(null);
|
||||
throw new RuntimeException(
|
||||
"PRIV CRED contains(null): Failed to throw NPE");
|
||||
} catch (NullPointerException npe) {
|
||||
System.out.println(
|
||||
"PRIV CRED contains(null): NullPointerException [PASS]");
|
||||
}
|
||||
}
|
||||
|
||||
private static void testAddAll() {
|
||||
// Create a well formed subject and additional collections
|
||||
Subject mtSubj = makeSubj(false, false, false);
|
||||
Set<Principal> morePrincs = new HashSet<>(Arrays.asList(tmplAddPrincs));
|
||||
Set<Object> morePubVals = new HashSet<>(Arrays.asList(tmplAddPubVals));
|
||||
Set<Object> morePrvVals = new HashSet<>(Arrays.asList(tmplAddPrvVals));
|
||||
|
||||
// Run one success test for each Subject family to verify the
|
||||
// overloaded method works as intended.
|
||||
Set<Principal> setPrin = mtSubj.getPrincipals();
|
||||
Set<Object> setPubCreds = mtSubj.getPublicCredentials();
|
||||
Set<Object> setPrvCreds = mtSubj.getPrivateCredentials();
|
||||
int prinOrigSize = setPrin.size();
|
||||
int pubOrigSize = setPubCreds.size();
|
||||
int prvOrigSize = setPrvCreds.size();
|
||||
|
||||
System.out.println("------ addAll() -----");
|
||||
|
||||
// Add the new members, then check the resulting size of the
|
||||
// Subject attributes to verify they've increased by the proper
|
||||
// amounts.
|
||||
if ((validTestCollection(methAdd, setPrin, morePrincs) != true) ||
|
||||
(setPrin.size() != prinOrigSize + morePrincs.size()))
|
||||
{
|
||||
throw new RuntimeException("Failed addAll() on principals");
|
||||
}
|
||||
if ((validTestCollection(methAdd, setPubCreds,
|
||||
morePubVals) != true) ||
|
||||
(setPubCreds.size() != pubOrigSize + morePubVals.size()))
|
||||
{
|
||||
throw new RuntimeException("Failed addAll() on public creds");
|
||||
}
|
||||
if ((validTestCollection(methAdd, setPrvCreds,
|
||||
morePrvVals) != true) ||
|
||||
(setPrvCreds.size() != prvOrigSize + morePrvVals.size()))
|
||||
{
|
||||
throw new RuntimeException("Failed addAll() on private creds");
|
||||
}
|
||||
System.out.println("Positive addAll() test passed");
|
||||
|
||||
// Now add null elements into each container, then retest
|
||||
morePrincs.add(null);
|
||||
morePubVals.add(null);
|
||||
morePrvVals.add(null);
|
||||
|
||||
System.out.println("* Testing addAll w/ null values on Principals");
|
||||
nullTestCollection(methAdd, mtSubj.getPrincipals(), null);
|
||||
nullTestCollection(methAdd, mtSubj.getPrincipals(), morePrincs);
|
||||
|
||||
System.out.println("* Testing addAll w/ null values on Public Creds");
|
||||
nullTestCollection(methAdd, mtSubj.getPublicCredentials(), null);
|
||||
nullTestCollection(methAdd, mtSubj.getPublicCredentials(),
|
||||
morePubVals);
|
||||
|
||||
System.out.println("* Testing addAll w/ null values on Private Creds");
|
||||
nullTestCollection(methAdd, mtSubj.getPrivateCredentials(), null);
|
||||
nullTestCollection(methAdd, mtSubj.getPrivateCredentials(),
|
||||
morePrvVals);
|
||||
}
|
||||
|
||||
private static void testRemoveAll() {
|
||||
// Create a well formed subject and additional collections
|
||||
Subject mtSubj = makeSubj(false, false, false);
|
||||
Set<Principal> remPrincs = new HashSet<>();
|
||||
Set<Object> remPubVals = new HashSet<>();
|
||||
Set<Object> remPrvVals = new HashSet<>();
|
||||
|
||||
remPrincs.add(new KerberosPrincipal("mtwain/author@LITERATURE.US"));
|
||||
remPubVals.add("mtwain");
|
||||
remPrvVals.add("5Cl3M3nz");
|
||||
|
||||
// Run one success test for each Subject family to verify the
|
||||
// overloaded method works as intended.
|
||||
Set<Principal> setPrin = mtSubj.getPrincipals();
|
||||
Set<Object> setPubCreds = mtSubj.getPublicCredentials();
|
||||
Set<Object> setPrvCreds = mtSubj.getPrivateCredentials();
|
||||
int prinOrigSize = setPrin.size();
|
||||
int pubOrigSize = setPubCreds.size();
|
||||
int prvOrigSize = setPrvCreds.size();
|
||||
|
||||
System.out.println("------ removeAll() -----");
|
||||
|
||||
// Remove the specified members, then check the resulting size of the
|
||||
// Subject attributes to verify they've decreased by the proper
|
||||
// amounts.
|
||||
if ((validTestCollection(methRemove, setPrin, remPrincs) != true) ||
|
||||
(setPrin.size() != prinOrigSize - remPrincs.size()))
|
||||
{
|
||||
throw new RuntimeException("Failed removeAll() on principals");
|
||||
}
|
||||
if ((validTestCollection(methRemove, setPubCreds,
|
||||
remPubVals) != true) ||
|
||||
(setPubCreds.size() != pubOrigSize - remPubVals.size()))
|
||||
{
|
||||
throw new RuntimeException("Failed removeAll() on public creds");
|
||||
}
|
||||
if ((validTestCollection(methRemove, setPrvCreds,
|
||||
remPrvVals) != true) ||
|
||||
(setPrvCreds.size() != prvOrigSize - remPrvVals.size()))
|
||||
{
|
||||
throw new RuntimeException("Failed removeAll() on private creds");
|
||||
}
|
||||
System.out.println("Positive removeAll() test passed");
|
||||
|
||||
// Now add null elements into each container, then retest
|
||||
remPrincs.add(null);
|
||||
remPubVals.add(null);
|
||||
remPrvVals.add(null);
|
||||
|
||||
System.out.println("* Testing removeAll w/ null values on Principals");
|
||||
nullTestCollection(methRemove, mtSubj.getPrincipals(), null);
|
||||
nullTestCollection(methRemove, mtSubj.getPrincipals(), remPrincs);
|
||||
|
||||
System.out.println(
|
||||
"* Testing removeAll w/ null values on Public Creds");
|
||||
nullTestCollection(methRemove, mtSubj.getPublicCredentials(), null);
|
||||
nullTestCollection(methRemove, mtSubj.getPublicCredentials(),
|
||||
remPubVals);
|
||||
|
||||
System.out.println(
|
||||
"* Testing removeAll w/ null values on Private Creds");
|
||||
nullTestCollection(methRemove, mtSubj.getPrivateCredentials(), null);
|
||||
nullTestCollection(methRemove, mtSubj.getPrivateCredentials(),
|
||||
remPrvVals);
|
||||
}
|
||||
|
||||
private static void testContainsAll() {
|
||||
// Create a well formed subject and additional collections
|
||||
Subject mtSubj = makeSubj(false, false, false);
|
||||
Set<Principal> testPrincs = new HashSet<>(Arrays.asList(princVals));
|
||||
Set<Object> testPubVals = new HashSet<>(Arrays.asList(pubVals));
|
||||
Set<Object> testPrvVals = new HashSet<>(Arrays.asList(privVals));
|
||||
|
||||
System.out.println("------ containsAll() -----");
|
||||
|
||||
// Run one success test for each Subject family to verify the
|
||||
// overloaded method works as intended.
|
||||
if ((validTestCollection(methContains, mtSubj.getPrincipals(),
|
||||
testPrincs) == false) &&
|
||||
(validTestCollection(methContains, mtSubj.getPublicCredentials(),
|
||||
testPubVals) == false) &&
|
||||
(validTestCollection(methContains,
|
||||
mtSubj.getPrivateCredentials(), testPrvVals) == false)) {
|
||||
throw new RuntimeException("Valid containsAll() check failed");
|
||||
}
|
||||
System.out.println("Positive containsAll() test passed");
|
||||
|
||||
// Now let's add a null into each collection and watch the fireworks.
|
||||
testPrincs.add(null);
|
||||
testPubVals.add(null);
|
||||
testPrvVals.add(null);
|
||||
|
||||
System.out.println(
|
||||
"* Testing containsAll w/ null values on Principals");
|
||||
nullTestCollection(methContains, mtSubj.getPrincipals(), null);
|
||||
nullTestCollection(methContains, mtSubj.getPrincipals(), testPrincs);
|
||||
|
||||
System.out.println(
|
||||
"* Testing containsAll w/ null values on Public Creds");
|
||||
nullTestCollection(methContains, mtSubj.getPublicCredentials(),
|
||||
null);
|
||||
nullTestCollection(methContains, mtSubj.getPublicCredentials(),
|
||||
testPubVals);
|
||||
|
||||
System.out.println(
|
||||
"* Testing containsAll w/ null values on Private Creds");
|
||||
nullTestCollection(methContains, mtSubj.getPrivateCredentials(),
|
||||
null);
|
||||
nullTestCollection(methContains, mtSubj.getPrivateCredentials(),
|
||||
testPrvVals);
|
||||
}
|
||||
|
||||
private static void testRetainAll() {
|
||||
// Create a well formed subject and additional collections
|
||||
Subject mtSubj = makeSubj(false, false, false);
|
||||
Set<Principal> remPrincs = new HashSet<>(Arrays.asList(tmplAddPrincs));
|
||||
Set<Object> remPubVals = new HashSet<>(Arrays.asList(tmplAddPubVals));
|
||||
Set<Object> remPrvVals = new HashSet<>(Arrays.asList(tmplAddPrvVals));
|
||||
|
||||
// Add in values that exist within the Subject
|
||||
remPrincs.add(princVals[2]);
|
||||
remPubVals.add(pubVals[2]);
|
||||
remPrvVals.add(privVals[2]);
|
||||
|
||||
// Run one success test for each Subject family to verify the
|
||||
// overloaded method works as intended.
|
||||
Set<Principal> setPrin = mtSubj.getPrincipals();
|
||||
Set<Object> setPubCreds = mtSubj.getPublicCredentials();
|
||||
Set<Object> setPrvCreds = mtSubj.getPrivateCredentials();
|
||||
int prinOrigSize = setPrin.size();
|
||||
int pubOrigSize = setPubCreds.size();
|
||||
int prvOrigSize = setPrvCreds.size();
|
||||
|
||||
System.out.println("------ retainAll() -----");
|
||||
|
||||
// Retain the specified members (those that exist in the Subject)
|
||||
// and validate the results.
|
||||
if (validTestCollection(methRetain, setPrin, remPrincs) == false ||
|
||||
setPrin.size() != 1 || setPrin.contains(princVals[2]) == false)
|
||||
{
|
||||
throw new RuntimeException("Failed retainAll() on principals");
|
||||
}
|
||||
|
||||
if (validTestCollection(methRetain, setPubCreds,
|
||||
remPubVals) == false ||
|
||||
setPubCreds.size() != 1 ||
|
||||
setPubCreds.contains(pubVals[2]) == false)
|
||||
{
|
||||
throw new RuntimeException("Failed retainAll() on public creds");
|
||||
}
|
||||
if (validTestCollection(methRetain, setPrvCreds,
|
||||
remPrvVals) == false ||
|
||||
setPrvCreds.size() != 1 ||
|
||||
setPrvCreds.contains(privVals[2]) == false)
|
||||
{
|
||||
throw new RuntimeException("Failed retainAll() on private creds");
|
||||
}
|
||||
System.out.println("Positive retainAll() test passed");
|
||||
|
||||
// Now add null elements into each container, then retest
|
||||
remPrincs.add(null);
|
||||
remPubVals.add(null);
|
||||
remPrvVals.add(null);
|
||||
|
||||
System.out.println("* Testing retainAll w/ null values on Principals");
|
||||
nullTestCollection(methRetain, mtSubj.getPrincipals(), null);
|
||||
nullTestCollection(methRetain, mtSubj.getPrincipals(), remPrincs);
|
||||
|
||||
System.out.println(
|
||||
"* Testing retainAll w/ null values on Public Creds");
|
||||
nullTestCollection(methRetain, mtSubj.getPublicCredentials(), null);
|
||||
nullTestCollection(methRetain, mtSubj.getPublicCredentials(),
|
||||
remPubVals);
|
||||
|
||||
System.out.println(
|
||||
"* Testing retainAll w/ null values on Private Creds");
|
||||
nullTestCollection(methRetain, mtSubj.getPrivateCredentials(), null);
|
||||
nullTestCollection(methRetain, mtSubj.getPrivateCredentials(),
|
||||
remPrvVals);
|
||||
}
|
||||
|
||||
private static void testIsEmpty() {
|
||||
Subject populatedSubj = makeSubj(false, false, false);
|
||||
Subject emptySubj = new Subject();
|
||||
|
||||
System.out.println("------ isEmpty() -----");
|
||||
|
||||
if (populatedSubj.getPrincipals().isEmpty()) {
|
||||
throw new RuntimeException(
|
||||
"Populated Subject Principals incorrectly returned empty");
|
||||
}
|
||||
if (emptySubj.getPrincipals().isEmpty() == false) {
|
||||
throw new RuntimeException(
|
||||
"Empty Subject Principals incorrectly returned non-empty");
|
||||
}
|
||||
System.out.println("isEmpty() test passed");
|
||||
}
|
||||
|
||||
private static void testSecureSetEquals() {
|
||||
System.out.println("------ SecureSet.equals() -----");
|
||||
|
||||
Subject subj = makeSubj(false, false, false);
|
||||
Subject subjComp = makeSubj(false, false, false);
|
||||
|
||||
// Case 1: null comparison [expect false]
|
||||
if (subj.getPublicCredentials().equals(null) != false) {
|
||||
throw new RuntimeException(
|
||||
"equals(null) incorrectly returned true");
|
||||
}
|
||||
|
||||
// Case 2: Self-comparison [expect true]
|
||||
Set<Principal> princs = subj.getPrincipals();
|
||||
princs.equals(subj.getPrincipals());
|
||||
|
||||
// Case 3: Comparison with non-Set type [expect false]
|
||||
List<Principal> listPrinc = new LinkedList<>(Arrays.asList(princVals));
|
||||
if (subj.getPublicCredentials().equals(listPrinc) != false) {
|
||||
throw new RuntimeException(
|
||||
"equals([Non-Set]) incorrectly returned true");
|
||||
}
|
||||
|
||||
// Case 4: SecureSets of differing sizes [expect false]
|
||||
Subject subj1princ = new Subject();
|
||||
Subject subj2princ = new Subject();
|
||||
subj1princ.getPrincipals().add(
|
||||
new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US"));
|
||||
subj1princ.getPrincipals().add(
|
||||
new X500Principal("CN=John Doe, O=Bogus Corp."));
|
||||
subj2princ.getPrincipals().add(
|
||||
new X500Principal("CN=Tom Sawyer, ST=Missouri, C=US"));
|
||||
if (subj1princ.getPrincipals().equals(
|
||||
subj2princ.getPrincipals()) != false) {
|
||||
throw new RuntimeException(
|
||||
"equals([differing sizes]) incorrectly returned true");
|
||||
}
|
||||
|
||||
// Case 5: Content equality test [expect true]
|
||||
Set<Principal> equalSet = new HashSet<>(Arrays.asList(princVals));
|
||||
if (subj.getPrincipals().equals(equalSet) != true) {
|
||||
throw new RuntimeException(
|
||||
"equals([equivalent set]) incorrectly returned false");
|
||||
}
|
||||
|
||||
// Case 5: Content inequality test [expect false]
|
||||
// Note: to not fall into the size inequality check the two
|
||||
// sets need to have the same number of elements.
|
||||
Set<Principal> inequalSet =
|
||||
new HashSet<Principal>(Arrays.asList(tmplAddPrincs));
|
||||
inequalSet.add(new JMXPrincipal("Samuel Clemens"));
|
||||
|
||||
if (subj.getPrincipals().equals(inequalSet) != false) {
|
||||
throw new RuntimeException(
|
||||
"equals([equivalent set]) incorrectly returned false");
|
||||
}
|
||||
System.out.println("SecureSet.equals() tests passed");
|
||||
}
|
||||
|
||||
private static void testSecureSetHashCode() {
|
||||
System.out.println("------ SecureSet.hashCode() -----");
|
||||
|
||||
Subject subj = makeSubj(false, false, false);
|
||||
|
||||
// Make sure two other Set types that we know are equal per
|
||||
// SecureSet.equals() and verify their hashCodes are also the same
|
||||
Set<Principal> equalHashSet = new HashSet<>(Arrays.asList(princVals));
|
||||
|
||||
if (subj.getPrincipals().hashCode() != equalHashSet.hashCode()) {
|
||||
throw new RuntimeException(
|
||||
"SecureSet and HashSet hashCodes() differ");
|
||||
}
|
||||
System.out.println("SecureSet.hashCode() tests passed");
|
||||
}
|
||||
|
||||
private static void testToArray() {
|
||||
System.out.println("------ toArray() -----");
|
||||
|
||||
Subject subj = makeSubj(false, false, false);
|
||||
|
||||
// Case 1: no-parameter toArray with equality comparison
|
||||
// Expected result: true
|
||||
List<Object> alSubj = Arrays.asList(subj.getPrincipals().toArray());
|
||||
List<Principal> alPrincs = Arrays.asList(princVals);
|
||||
|
||||
if (alSubj.size() != alPrincs.size() ||
|
||||
alSubj.containsAll(alPrincs) != true) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected inequality on returned toArray()");
|
||||
}
|
||||
|
||||
// Case 2: generic-type toArray where passed array is of sufficient
|
||||
// size.
|
||||
// Expected result: returned Array is reference-equal to input param
|
||||
// and content equal to data used to construct the originating Subject.
|
||||
Principal[] pBlock = new Principal[3];
|
||||
Principal[] pBlockRef = subj.getPrincipals().toArray(pBlock);
|
||||
alSubj = Arrays.asList((Object[])pBlockRef);
|
||||
|
||||
if (pBlockRef != pBlock) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected reference-inequality on returned toArray(T[])");
|
||||
} else if (alSubj.size() != alPrincs.size() ||
|
||||
alSubj.containsAll(alPrincs) != true) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected content-inequality on returned toArray(T[])");
|
||||
}
|
||||
|
||||
// Case 3: generic-type toArray where passed array is of
|
||||
// insufficient size.
|
||||
// Expected result: returned Array is not reference-equal to
|
||||
// input param but is content equal to data used to construct the
|
||||
// originating Subject.
|
||||
pBlock = new Principal[1];
|
||||
pBlockRef = subj.getPrincipals().toArray(pBlock);
|
||||
alSubj = Arrays.asList((Object[])pBlockRef);
|
||||
|
||||
if (pBlockRef == pBlock) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected reference-equality on returned toArray(T[])");
|
||||
} else if (alSubj.size() != alPrincs.size() ||
|
||||
alSubj.containsAll(alPrincs) != true) {
|
||||
throw new RuntimeException(
|
||||
"Unexpected content-inequality on returned toArray(T[])");
|
||||
}
|
||||
System.out.println("toArray() tests passed");
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
testCTOR();
|
||||
|
||||
testDeserialize();
|
||||
|
||||
testAdd();
|
||||
|
||||
testRemove();
|
||||
|
||||
testContains();
|
||||
|
||||
testAddAll();
|
||||
|
||||
testRemoveAll();
|
||||
|
||||
testContainsAll();
|
||||
|
||||
testRetainAll();
|
||||
|
||||
testIsEmpty();
|
||||
|
||||
testSecureSetEquals();
|
||||
|
||||
testSecureSetHashCode();
|
||||
|
||||
testToArray();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user