|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package javax.security.auth.kerberos; |
|
|
|
import java.util.*; |
|
import java.security.Permission; |
|
import java.security.BasicPermission; |
|
import java.security.PermissionCollection; |
|
import java.io.ObjectStreamField; |
|
import java.io.ObjectOutputStream; |
|
import java.io.ObjectInputStream; |
|
import java.io.IOException; |
|
|
|
/** |
|
* This class is used to restrict the usage of the Kerberos |
|
* delegation model, ie: forwardable and proxiable tickets. |
|
* <p> |
|
* The target name of this {@code Permission} specifies a pair of |
|
* kerberos service principals. The first is the subordinate service principal |
|
* being entrusted to use the TGT. The second service principal designates |
|
* the target service the subordinate service principal is to |
|
* interact with on behalf of the initiating KerberosPrincipal. This |
|
* latter service principal is specified to restrict the use of a |
|
* proxiable ticket. |
|
* <p> |
|
* For example, to specify the "host" service use of a forwardable TGT the |
|
* target permission is specified as follows: |
|
* |
|
* <pre> |
|
* DelegationPermission("\"host/foo.example.com@EXAMPLE.COM\" \"krbtgt/EXAMPLE.COM@EXAMPLE.COM\""); |
|
* </pre> |
|
* <p> |
|
* To give the "backup" service a proxiable nfs service ticket the target permission |
|
* might be specified: |
|
* |
|
* <pre> |
|
* DelegationPermission("\"backup/bar.example.com@EXAMPLE.COM\" \"nfs/home.EXAMPLE.COM@EXAMPLE.COM\""); |
|
* </pre> |
|
* |
|
* @since 1.4 |
|
*/ |
|
|
|
public final class DelegationPermission extends BasicPermission |
|
implements java.io.Serializable { |
|
|
|
private static final long serialVersionUID = 883133252142523922L; |
|
|
|
private transient String subordinate, service; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public DelegationPermission(String principals) { |
|
super(principals); |
|
init(principals); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public DelegationPermission(String principals, String actions) { |
|
super(principals, actions); |
|
init(principals); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private void init(String target) { |
|
|
|
StringTokenizer t = null; |
|
if (!target.startsWith("\"")) { |
|
throw new IllegalArgumentException |
|
("service principal [" + target + |
|
"] syntax invalid: " + |
|
"improperly quoted"); |
|
} else { |
|
t = new StringTokenizer(target, "\"", false); |
|
subordinate = t.nextToken(); |
|
if (t.countTokens() == 2) { |
|
t.nextToken(); |
|
service = t.nextToken(); |
|
} else if (t.countTokens() > 0) { |
|
throw new IllegalArgumentException |
|
("service principal [" + t.nextToken() + |
|
"] syntax invalid: " + |
|
"improperly quoted"); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean implies(Permission p) { |
|
if (!(p instanceof DelegationPermission)) |
|
return false; |
|
|
|
DelegationPermission that = (DelegationPermission) p; |
|
if (this.subordinate.equals(that.subordinate) && |
|
this.service.equals(that.service)) |
|
return true; |
|
|
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean equals(Object obj) { |
|
if (obj == this) |
|
return true; |
|
|
|
if (! (obj instanceof DelegationPermission)) |
|
return false; |
|
|
|
DelegationPermission that = (DelegationPermission) obj; |
|
return implies(that); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public int hashCode() { |
|
return getName().hashCode(); |
|
} |
|
|
|
|
|
/** |
|
* Returns a PermissionCollection object for storing |
|
* DelegationPermission objects. |
|
* <br> |
|
* DelegationPermission objects must be stored in a manner that |
|
* allows them to be inserted into the collection in any order, but |
|
* that also enables the PermissionCollection implies method to |
|
* be implemented in an efficient (and consistent) manner. |
|
* |
|
* @return a new PermissionCollection object suitable for storing |
|
* DelegationPermissions. |
|
*/ |
|
|
|
public PermissionCollection newPermissionCollection() { |
|
return new KrbDelegationPermissionCollection(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
private synchronized void writeObject(java.io.ObjectOutputStream s) |
|
throws IOException |
|
{ |
|
s.defaultWriteObject(); |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private synchronized void readObject(java.io.ObjectInputStream s) |
|
throws IOException, ClassNotFoundException |
|
{ |
|
|
|
s.defaultReadObject(); |
|
init(getName()); |
|
} |
|
|
|
/* |
|
public static void main(String args[]) throws Exception { |
|
DelegationPermission this_ = |
|
new DelegationPermission(args[0]); |
|
DelegationPermission that_ = |
|
new DelegationPermission(args[1]); |
|
System.out.println("-----\n"); |
|
System.out.println("this.implies(that) = " + this_.implies(that_)); |
|
System.out.println("-----\n"); |
|
System.out.println("this = "+this_); |
|
System.out.println("-----\n"); |
|
System.out.println("that = "+that_); |
|
System.out.println("-----\n"); |
|
|
|
KrbDelegationPermissionCollection nps = |
|
new KrbDelegationPermissionCollection(); |
|
nps.add(this_); |
|
nps.add(new DelegationPermission("\"host/foo.example.com@EXAMPLE.COM\" \"CN=Gary Ellison/OU=JSN/O=SUNW/L=Palo Alto/ST=CA/C=US\"")); |
|
try { |
|
nps.add(new DelegationPermission("host/foo.example.com@EXAMPLE.COM \"CN=Gary Ellison/OU=JSN/O=SUNW/L=Palo Alto/ST=CA/C=US\"")); |
|
} catch (Exception e) { |
|
System.err.println(e); |
|
} |
|
|
|
System.out.println("nps.implies(that) = " + nps.implies(that_)); |
|
System.out.println("-----\n"); |
|
|
|
Enumeration e = nps.elements(); |
|
|
|
while (e.hasMoreElements()) { |
|
DelegationPermission x = |
|
(DelegationPermission) e.nextElement(); |
|
System.out.println("nps.e = " + x); |
|
} |
|
} |
|
*/ |
|
} |
|
|
|
|
|
final class KrbDelegationPermissionCollection extends PermissionCollection |
|
implements java.io.Serializable { |
|
|
|
|
|
private transient List<Permission> perms; |
|
|
|
public KrbDelegationPermissionCollection() { |
|
perms = new ArrayList<Permission>(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public boolean implies(Permission permission) { |
|
if (! (permission instanceof DelegationPermission)) |
|
return false; |
|
|
|
synchronized (this) { |
|
for (Permission x : perms) { |
|
if (x.implies(permission)) |
|
return true; |
|
} |
|
} |
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public void add(Permission permission) { |
|
if (! (permission instanceof DelegationPermission)) |
|
throw new IllegalArgumentException("invalid permission: "+ |
|
permission); |
|
if (isReadOnly()) |
|
throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); |
|
|
|
synchronized (this) { |
|
perms.add(0, permission); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public Enumeration<Permission> elements() { |
|
|
|
synchronized (this) { |
|
return Collections.enumeration(perms); |
|
} |
|
} |
|
|
|
private static final long serialVersionUID = -3383936936589966948L; |
|
|
|
// Need to maintain serialization interoperability with earlier releases, |
|
// which had the serializable field: |
|
// private Vector permissions; |
|
|
|
|
|
|
|
*/ |
|
private static final ObjectStreamField[] serialPersistentFields = { |
|
new ObjectStreamField("permissions", Vector.class), |
|
}; |
|
|
|
/** |
|
* @serialData "permissions" field (a Vector containing the DelegationPermissions). |
|
*/ |
|
|
|
|
|
|
|
*/ |
|
private void writeObject(ObjectOutputStream out) throws IOException { |
|
// Don't call out.defaultWriteObject() |
|
|
|
|
|
Vector<Permission> permissions = new Vector<>(perms.size()); |
|
|
|
synchronized (this) { |
|
permissions.addAll(perms); |
|
} |
|
|
|
ObjectOutputStream.PutField pfields = out.putFields(); |
|
pfields.put("permissions", permissions); |
|
out.writeFields(); |
|
} |
|
|
|
|
|
|
|
*/ |
|
@SuppressWarnings("unchecked") |
|
private void readObject(ObjectInputStream in) |
|
throws IOException, ClassNotFoundException |
|
{ |
|
// Don't call defaultReadObject() |
|
|
|
|
|
ObjectInputStream.GetField gfields = in.readFields(); |
|
|
|
|
|
Vector<Permission> permissions = |
|
(Vector<Permission>)gfields.get("permissions", null); |
|
perms = new ArrayList<Permission>(permissions.size()); |
|
perms.addAll(permissions); |
|
} |
|
} |