UnresolvedPermissionpublic final class UnresolvedPermission extends Permission implements SerializableThe UnresolvedPermission class is used to hold Permissions that
were "unresolved" when the Policy was initialized.
An unresolved permission is one whose actual Permission class
does not yet exist at the time the Policy is initialized (see below).
The policy for a Java runtime (specifying
which permissions are available for code from various principals)
is represented by a Policy object.
Whenever a Policy is initialized or refreshed, Permission objects of
appropriate classes are created for all permissions
allowed by the Policy.
Many permission class types
referenced by the policy configuration are ones that exist
locally (i.e., ones that can be found on CLASSPATH).
Objects for such permissions can be instantiated during
Policy initialization. For example, it is always possible
to instantiate a java.io.FilePermission, since the
FilePermission class is found on the CLASSPATH.
Other permission classes may not yet exist during Policy
initialization. For example, a referenced permission class may
be in a JAR file that will later be loaded.
For each such class, an UnresolvedPermission is instantiated.
Thus, an UnresolvedPermission is essentially a "placeholder"
containing information about the permission.
Later, when code calls AccessController.checkPermission
on a permission of a type that was previously unresolved,
but whose class has since been loaded, previously-unresolved
permissions of that type are "resolved". That is,
for each such UnresolvedPermission, a new object of
the appropriate class type is instantiated, based on the
information in the UnresolvedPermission.
To instantiate the new class, UnresolvedPermission assumes
the class provides a zero, one, and/or two-argument constructor.
The zero-argument constructor would be used to instantiate
a permission without a name and without actions.
A one-arg constructor is assumed to take a String
name as input, and a two-arg constructor is assumed to take a
String name and String actions
as input. UnresolvedPermission may invoke a
constructor with a null name and/or actions.
If an appropriate permission constructor is not available,
the UnresolvedPermission is ignored and the relevant permission
will not be granted to executing code.
The newly created permission object replaces the
UnresolvedPermission, which is removed.
Note that the getName method for an
UnresolvedPermission returns the
type (class name) for the underlying permission
that has not been resolved. |
Fields Summary |
---|
private static final long | serialVersionUID | private static final Debug | debug | private String | typeThe class name of the Permission class that will be
created when this unresolved permission is resolved. | private String | nameThe permission name. | private String | actionsThe actions of the permission. | private transient Certificate[] | certs | private static final Class[] | PARAMS0 | private static final Class[] | PARAMS1 | private static final Class[] | PARAMS2 |
Constructors Summary |
---|
public UnresolvedPermission(String type, String name, String actions, Certificate[] certs)Creates a new UnresolvedPermission containing the permission
information needed later to actually create a Permission of the
specified class, when the permission is resolved.
super(type);
if (type == null)
throw new NullPointerException("type can't be null");
this.type = type;
this.name = name;
this.actions = actions;
if (certs != null) {
// Extract the signer certs from the list of certificates.
for (int i=0; i<certs.length; i++) {
if (!(certs[i] instanceof X509Certificate)) {
// there is no concept of signer certs, so we store the
// entire cert array
this.certs =
(java.security.cert.Certificate[])certs.clone();
break;
}
}
if (this.certs == null) {
// Go through the list of certs and see if all the certs are
// signer certs.
int i = 0;
int count = 0;
while (i < certs.length) {
count++;
while (((i+1) < certs.length) &&
((X509Certificate)certs[i]).getIssuerDN().equals(
((X509Certificate)certs[i+1]).getSubjectDN())) {
i++;
}
i++;
}
if (count == certs.length) {
// All the certs are signer certs, so we store the entire
// array
this.certs =
(java.security.cert.Certificate[])certs.clone();
}
if (this.certs == null) {
// extract the signer certs
ArrayList signerCerts = new ArrayList();
i = 0;
while (i < certs.length) {
signerCerts.add(certs[i]);
while (((i+1) < certs.length) &&
((X509Certificate)certs[i]).getIssuerDN().equals(
((X509Certificate)certs[i+1]).getSubjectDN())) {
i++;
}
i++;
}
this.certs =
new java.security.cert.Certificate[signerCerts.size()];
signerCerts.toArray(this.certs);
}
}
}
|
Methods Summary |
---|
public boolean | equals(java.lang.Object obj)Checks two UnresolvedPermission objects for equality.
Checks that obj is an UnresolvedPermission, and has
the same type (class) name, permission name, actions, and
certificates as this object.
To determine certificate equality, this method only compares
actual signer certificates. Supporting certificate chains
are not taken into consideration by this method.
if (obj == this)
return true;
if (! (obj instanceof UnresolvedPermission))
return false;
UnresolvedPermission that = (UnresolvedPermission) obj;
// check type
if (!this.type.equals(that.type)) {
return false;
}
// check name
if (this.name == null) {
if (that.name != null) {
return false;
}
} else if (!this.name.equals(that.name)) {
return false;
}
// check actions
if (this.actions == null) {
if (that.actions != null) {
return false;
}
} else {
if (!this.actions.equals(that.actions)) {
return false;
}
}
// check certs
if ((this.certs == null && that.certs != null) ||
(this.certs != null && that.certs == null) ||
(this.certs != null && that.certs != null &&
this.certs.length != that.certs.length)) {
return false;
}
int i,j;
boolean match;
for (i = 0; this.certs != null && i < this.certs.length; i++) {
match = false;
for (j = 0; j < that.certs.length; j++) {
if (this.certs[i].equals(that.certs[j])) {
match = true;
break;
}
}
if (!match) return false;
}
for (i = 0; that.certs != null && i < that.certs.length; i++) {
match = false;
for (j = 0; j < this.certs.length; j++) {
if (that.certs[i].equals(this.certs[j])) {
match = true;
break;
}
}
if (!match) return false;
}
return true;
| public java.lang.String | getActions()Returns the canonical string representation of the actions,
which currently is the empty string "", since there are no actions for
an UnresolvedPermission. That is, the actions for the
permission that will be created when this UnresolvedPermission
is resolved may be non-null, but an UnresolvedPermission
itself is never considered to have any actions.
return "";
| public java.lang.String | getUnresolvedActions()Get the actions for the underlying permission that
has not been resolved.
return actions;
| public java.security.cert.Certificate[] | getUnresolvedCerts()Get the signer certificates (without any supporting chain)
for the underlying permission that has not been resolved.
return (certs == null) ? null :
(java.security.cert.Certificate[])certs.clone();
| public java.lang.String | getUnresolvedName()Get the target name of the underlying permission that
has not been resolved.
return name;
| public java.lang.String | getUnresolvedType()Get the type (class name) of the underlying permission that
has not been resolved.
return type;
| public int | hashCode()Returns the hash code value for this object.
int hash = type.hashCode();
if (name != null)
hash ^= name.hashCode();
if (actions != null)
hash ^= actions.hashCode();
return hash;
| public boolean | implies(java.security.Permission p)This method always returns false for unresolved permissions.
That is, an UnresolvedPermission is never considered to
imply another permission.
return false;
| public java.security.PermissionCollection | newPermissionCollection()Returns a new PermissionCollection object for storing
UnresolvedPermission objects.
return new UnresolvedPermissionCollection();
| private void | readObject(java.io.ObjectInputStream ois)Restores this object from a stream (i.e., deserializes it).
CertificateFactory cf;
Hashtable cfs=null;
ois.defaultReadObject();
if (type == null)
throw new NullPointerException("type can't be null");
// process any new-style certs in the stream (if present)
int size = ois.readInt();
if (size > 0) {
// we know of 3 different cert types: X.509, PGP, SDSI, which
// could all be present in the stream at the same time
cfs = new Hashtable(3);
this.certs = new java.security.cert.Certificate[size];
}
for (int i=0; i<size; i++) {
// read the certificate type, and instantiate a certificate
// factory of that type (reuse existing factory if possible)
String certType = ois.readUTF();
if (cfs.containsKey(certType)) {
// reuse certificate factory
cf = (CertificateFactory)cfs.get(certType);
} else {
// create new certificate factory
try {
cf = CertificateFactory.getInstance(certType);
} catch (CertificateException ce) {
throw new ClassNotFoundException
("Certificate factory for "+certType+" not found");
}
// store the certificate factory so we can reuse it later
cfs.put(certType, cf);
}
// parse the certificate
byte[] encoded=null;
try {
encoded = new byte[ois.readInt()];
} catch (OutOfMemoryError oome) {
throw new IOException("Certificate too big");
}
ois.readFully(encoded);
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
try {
this.certs[i] = cf.generateCertificate(bais);
} catch (CertificateException ce) {
throw new IOException(ce.getMessage());
}
bais.close();
}
| java.security.Permission | resolve(java.security.Permission p, java.security.cert.Certificate[] certs)try and resolve this permission using the class loader of the permission
that was passed in.
if (this.certs != null) {
// if p wasn't signed, we don't have a match
if (certs == null) {
return null;
}
// all certs in this.certs must be present in certs
boolean match;
for (int i = 0; i < this.certs.length; i++) {
match = false;
for (int j = 0; j < certs.length; j++) {
if (this.certs[i].equals(certs[j])) {
match = true;
break;
}
}
if (!match) return null;
}
}
try {
Class pc = p.getClass();
if (name == null && actions == null) {
try {
Constructor c = pc.getConstructor(PARAMS0);
return (Permission)c.newInstance(new Object[] {});
} catch (NoSuchMethodException ne) {
try {
Constructor c = pc.getConstructor(PARAMS1);
return (Permission) c.newInstance(
new Object[] { name});
} catch (NoSuchMethodException ne1) {
Constructor c = pc.getConstructor(PARAMS2);
return (Permission) c.newInstance(
new Object[] { name, actions });
}
}
} else {
if (name != null && actions == null) {
try {
Constructor c = pc.getConstructor(PARAMS1);
return (Permission) c.newInstance(
new Object[] { name});
} catch (NoSuchMethodException ne) {
Constructor c = pc.getConstructor(PARAMS2);
return (Permission) c.newInstance(
new Object[] { name, actions });
}
} else {
Constructor c = pc.getConstructor(PARAMS2);
return (Permission) c.newInstance(
new Object[] { name, actions });
}
}
} catch (NoSuchMethodException nsme) {
if (debug != null ) {
debug.println("NoSuchMethodException:\n could not find " +
"proper constructor for " + type);
nsme.printStackTrace();
}
return null;
} catch (Exception e) {
if (debug != null ) {
debug.println("unable to instantiate " + name);
e.printStackTrace();
}
return null;
}
| public java.lang.String | toString()Returns a string describing this UnresolvedPermission. The convention
is to specify the class name, the permission name, and the actions, in
the following format: '(unresolved "ClassName" "name" "actions")'.
return "(unresolved " + type + " " + name + " " + actions + ")";
| private void | writeObject(java.io.ObjectOutputStream oos)Writes this object out to a stream (i.e., serializes it).
oos.defaultWriteObject();
if (certs==null || certs.length==0) {
oos.writeInt(0);
} else {
// write out the total number of certs
oos.writeInt(certs.length);
// write out each cert, including its type
for (int i=0; i < certs.length; i++) {
java.security.cert.Certificate cert = certs[i];
try {
oos.writeUTF(cert.getType());
byte[] encoded = cert.getEncoded();
oos.writeInt(encoded.length);
oos.write(encoded);
} catch (CertificateEncodingException cee) {
throw new IOException(cee.getMessage());
}
}
}
|
|