FileDocCategorySizeDatePackage
PolicyFile.javaAPI DocJava SE 5 API45043Fri Aug 26 14:56:14 BST 2005com.sun.security.auth

PolicyFile

public class PolicyFile extends javax.security.auth.Policy
This class represents a default implementation for javax.security.auth.Policy.

This object stores the policy for entire Java runtime, and is the amalgamation of multiple static policy configurations that resides in files. The algorithm for locating the policy file(s) and reading their information into this Policy object is:

  1. Loop through the java.security.Security properties, auth.policy.url.1, auth.policy.url.2, ..., auth.policy.url.X". These properties are set in the Java security properties file, which is located in the file named <JAVA_HOME>/lib/security/java.security, where <JAVA_HOME> refers to the directory where the JDK was installed. Each property value specifies a URL pointing to a policy file to be loaded. Read in and load each policy.
  2. The java.lang.System property java.security.auth.policy may also be set to a URL pointing to another policy file (which is the case when a user uses the -D switch at runtime). If this property is defined, and its use is allowed by the security property file (the Security property, policy.allowSystemProperty is set to true), also load that policy.
  3. If the java.security.auth.policy property is defined using "==" (rather than "="), then ignore all other specified policies and only load this policy.
Each policy file consists of one or more grant entries, each of which consists of a number of permission entries.
grant signedBy "alias", codeBase "URL",
principal principalClass "principalName",
principal principalClass "principalName",
... {

permission Type "name "action",
signedBy "alias";
permission Type "name "action",
signedBy "alias";
....
};
All non-bold items above must appear as is (although case doesn't matter and some are optional, as noted below). Italicized items represent variable values.

A grant entry must begin with the word grant. The signedBy and codeBase name/value pairs are optional. If they are not present, then any signer (including unsigned code) will match, and any codeBase will match. Note that the principal name/value pair is not optional. This Policy implementation only permits Principal-based grant entries. Note that the principalClass may be set to the wildcard value, *, which allows it to match any Principal class. In addition, the principalName may also be set to the wildcard value, *, allowing it to match any Principal name. When setting the principalName to the *, do not surround the * with quotes.

A permission entry must begin with the word permission. The word Type in the template above is a specific permission type, such as java.io.FilePermission or java.lang.RuntimePermission.

The "action" is required for many permission types, such as java.io.FilePermission (where it specifies what type of file access that is permitted). It is not required for categories such as java.lang.RuntimePermission where it is not necessary - you either have the permission specified by the "name" value following the type name or you don't.

The signedBy name/value pair for a permission entry is optional. If present, it indicates a signed permission. That is, the permission class itself must be signed by the given alias in order for it to be granted. For example, suppose you have the following grant entry:

grant principal foo.com.Principal "Duke" {
permission Foo "foobar", signedBy "FooSoft";
}

Then this permission of type Foo is granted if the Foo.class permission has been signed by the "FooSoft" alias, or if Foo.class is a system class (i.e., is found on the CLASSPATH).

Items that appear in an entry must appear in the specified order (permission, Type, "name", and "action"). An entry is terminated with a semicolon.

Case is unimportant for the identifiers (permission, signedBy, codeBase, etc.) but is significant for the Type or for any string that is passed in as a value.

An example of two entries in a policy configuration file is

// if the code is comes from "foo.com" and is running as "Duke",
// grant it read/write to all files in /tmp.

grant codeBase "foo.com", principal foo.com.Principal "Duke" {
permission java.io.FilePermission "/tmp/*", "read,write";
};

// grant any code running as "Duke" permission to read
// the "java.vendor" Property.

grant principal foo.com.Principal "Duke" {
permission java.util.PropertyPermission "java.vendor";

This Policy implementation supports special handling for PrivateCredentialPermissions. If a grant entry is configured with a PrivateCredentialPermission, and the "Principal Class/Principal Name" for that PrivateCredentialPermission is "self", then the entry grants the specified Subject permission to access its own private Credential. For example, the following grants the Subject "Duke" access to its own a.b.Credential.

grant principal foo.com.Principal "Duke" {
permission javax.security.auth.PrivateCredentialPermission
"a.b.Credential self",
"read";
};
The following grants the Subject "Duke" access to all of its own private Credentials:
grant principal foo.com.Principal "Duke" {
permission javax.security.auth.PrivateCredentialPermission
"* self",
"read";
};
The following grants all Subjects authenticated as a SolarisPrincipal (regardless of their respective names) permission to access their own private Credentials:
grant principal com.sun.security.auth.SolarisPrincipal * {
permission javax.security.auth.PrivateCredentialPermission
"* self",
"read";
};
The following grants all Subjects permission to access their own private Credentials:
grant principal * * {
permission javax.security.auth.PrivateCredentialPermission
"* self",
"read";
};
deprecated
As of JDK 1.4, replaced by {@link sun.security.provider.PolicyFile}. This class is entirely deprecated.
version
1.22, 01/25/00
see
java.security.CodeSource
see
java.security.Permissions
see
java.security.ProtectionDomain

Fields Summary
static final ResourceBundle
rb
private static final Debug
debug
private static final String
AUTH_POLICY
private static final String
SECURITY_MANAGER
private static final String
AUTH_POLICY_URL
private Vector
policyEntries
private Hashtable
aliasMapping
private boolean
initialized
private boolean
expandProperties
private boolean
ignoreIdentityScope
private static final Class[]
PARAMS
private static IdentityScope
scope
the scope to check
Constructors Summary
public PolicyFile()
Initializes the Policy object and reads the default policy configuration file(s) into the Policy object.


                          
      
	// initialize Policy if either the AUTH_POLICY or
	// SECURITY_MANAGER properties are set
	String prop = System.getProperty(AUTH_POLICY);

	if (prop == null) {
	    prop = System.getProperty(SECURITY_MANAGER);
	}
 	if (prop != null)
 	    init();
    
Methods Summary
private voidaddGrantEntry(PolicyParser.GrantEntry ge, java.security.KeyStore keyStore)
Add one policy entry to the vector.


	if (debug != null) {
	    debug.println("Adding policy entry: ");
	    debug.println("  signedBy " + ge.signedBy);
	    debug.println("  codeBase " + ge.codeBase);
	    if (ge.principals != null && ge.principals.size() > 0) {
		ListIterator li = ge.principals.listIterator();
		while (li.hasNext()) {
		    PolicyParser.PrincipalEntry pppe =
			(PolicyParser.PrincipalEntry)li.next();
		    debug.println("  " + pppe.principalClass +
					" " + pppe.principalName);
		}
	    }
	    debug.println();
	}

	try {
	    CodeSource codesource = getCodeSource(ge, keyStore);
	    // skip if signedBy alias was unknown...
	    if (codesource == null) return;

	    PolicyEntry entry = new PolicyEntry(codesource);
	    Enumeration enum_ = ge.permissionElements();
	    while (enum_.hasMoreElements()) {
		PolicyParser.PermissionEntry pe =
		    (PolicyParser.PermissionEntry) enum_.nextElement();
		try { 
		    // XXX special case PrivateCredentialPermission-SELF
		    Permission perm;
		    if (pe.permission.equals
			("javax.security.auth.PrivateCredentialPermission") &&
			pe.name.endsWith(" self")) {
			perm = getInstance(pe.permission,
					 pe.name + " \"self\"",
					 pe.action);
		    } else {
			perm = getInstance(pe.permission,
					 pe.name,
					 pe.action);
		    }
		    entry.add(perm);
		    if (debug != null) {
			debug.println("  "+perm);
		    }
		} catch (ClassNotFoundException cnfe) {
		    Certificate certs[];
		    if (pe.signedBy != null) 
			certs = getCertificates(keyStore, pe.signedBy);
		    else 
			certs = null;

		    // only add if we had no signer or we had a
		    // a signer and found the keys for it.
		    if (certs != null || pe.signedBy == null) {
			    Permission perm = new UnresolvedPermission(
					     pe.permission,
					     pe.name,
					     pe.action,
					     certs);
			    entry.add(perm);
			    if (debug != null) {
				debug.println("  "+perm);
			    }
		    }
		} catch (java.lang.reflect.InvocationTargetException ite) {
		    System.err.println
			(AUTH_POLICY +
			rb.getString(": error adding Permission ") +
			pe.permission +
			rb.getString(" ") +
			ite.getTargetException());
		} catch (Exception e) {
		    System.err.println
			(AUTH_POLICY +
			rb.getString(": error adding Permission ") +
			pe.permission +
			rb.getString(" ") +
			e);
		}
	    }
	    policyEntries.addElement(entry);
	} catch (Exception e) {
	    System.err.println
		(AUTH_POLICY +
		rb.getString(": error adding Entry ") +
		ge +
		rb.getString(" ") +
		e);
	}

	if (debug != null)
	    debug.println();
    
private booleanaddSelfPermissions(java.security.Permission p, java.security.CodeSource entryCs, java.security.CodeSource accCs, java.security.Permissions perms)
Returns true if 'Self' permissions were added to the provided 'perms', and false otherwise.

param
p check to see if this Permission is a "SELF" PrivateCredentialPermission.

param
entryCs the codesource for the Policy entry.
param
accCs the codesource for from the current AccessControlContext.
param
perms the PermissionCollection where the individual PrivateCredentialPermissions will be added.


	if (!(p instanceof PrivateCredentialPermission))
	    return false;

	if (!(entryCs instanceof SubjectCodeSource))
	    return false;


	PrivateCredentialPermission pcp = (PrivateCredentialPermission)p;
	SubjectCodeSource scs = (SubjectCodeSource)entryCs;

	// see if it is a SELF permission
	String[][] pPrincipals = pcp.getPrincipals();
	if (pPrincipals.length <= 0 ||
	    !pPrincipals[0][0].equalsIgnoreCase("self") ||
	    !pPrincipals[0][1].equalsIgnoreCase("self")) {

	    // regular PrivateCredentialPermission
	    return false;
	} else {

	    // granted a SELF permission - create a
	    // PrivateCredentialPermission for each
	    // of the Policy entry's CodeSource Principals

	    if (scs.getPrincipals() == null) {
		// XXX SubjectCodeSource has no Subject???
		return true;
	    }

	    ListIterator pli = scs.getPrincipals().listIterator();
	    while (pli.hasNext()) {

		PolicyParser.PrincipalEntry principal =
				(PolicyParser.PrincipalEntry)pli.next();

		// XXX
		//	if the Policy entry's Principal does not contain a
		//		WILDCARD for the Principal name, then a
		//		new PrivateCredentialPermission is created
		//		for the Principal listed in the Policy entry.
		//	if the Policy entry's Principal contains a WILDCARD
		//		for the Principal name, then a new
		//		PrivateCredentialPermission is created
		//		for each Principal associated with the Subject
		//		in the current ACC.

		String[][] principalInfo = getPrincipalInfo
						(principal, accCs);

		for (int i = 0; i < principalInfo.length; i++) {

		    // here's the new PrivateCredentialPermission

		    PrivateCredentialPermission newPcp = 
			new PrivateCredentialPermission
				(pcp.getCredentialClass() +
					" " +
					principalInfo[i][0] +
					" " +
					"\"" + principalInfo[i][1] + "\"",
				"read");

		    if (debug != null) {
			debug.println("adding SELF permission: " +
					newPcp.toString());
		    }

		    perms.add(newPcp);
		}
	    }
	}
	return true;
    
private java.security.CodeSourcecanonicalizeCodebase(java.security.CodeSource cs, boolean extractSignerCerts)

	CodeSource canonCs = cs;
	if (cs.getLocation() != null &&
	    cs.getLocation().getProtocol().equalsIgnoreCase("file")) {
	    try {
		String path = cs.getLocation().getFile().replace
							('/",
							File.separatorChar);
		URL csUrl = null;
		if (path.endsWith("*")) {
		    // remove trailing '*' because it causes canonicalization
		    // to fail on win32
		    path = path.substring(0, path.length()-1);
		    boolean appendFileSep = false;
		    if (path.endsWith(File.separator))
			appendFileSep = true;
		    if (path.equals("")) {
			path = System.getProperty("user.dir");
		    }
		    File f = new File(path);
		    path = f.getCanonicalPath();
		    StringBuffer sb = new StringBuffer(path);
		    // reappend '*' to canonicalized filename (note that
		    // canonicalization may have removed trailing file
		    // separator, so we have to check for that, too)
		    if (!path.endsWith(File.separator) &&
			(appendFileSep || f.isDirectory()))
			sb.append(File.separatorChar);
		    sb.append('*");
		    path = sb.toString();
		} else {
		    path = new File(path).getCanonicalPath();
		}
		csUrl = new File(path).toURL();

		if (cs instanceof SubjectCodeSource) {
		    SubjectCodeSource scs = (SubjectCodeSource)cs;
		    if (extractSignerCerts) {
			canonCs = new SubjectCodeSource
						(scs.getSubject(),
						scs.getPrincipals(),
						csUrl,
						getSignerCertificates(scs));
		    } else {
			canonCs = new SubjectCodeSource
						(scs.getSubject(),
						scs.getPrincipals(),
						csUrl,
						scs.getCertificates());
		    }
		} else {
		    if (extractSignerCerts) {
			canonCs = new CodeSource(csUrl,
						getSignerCertificates(cs));
		    } else {
			canonCs = new CodeSource(csUrl,
						cs.getCertificates());
		    }
		}
	    } catch (IOException ioe) {
		// leave codesource as it is, unless we have to extract its
		// signer certificates
		if (extractSignerCerts) {
		    if (!(cs instanceof SubjectCodeSource)) {
			canonCs = new CodeSource(cs.getLocation(),
						getSignerCertificates(cs));
		    } else {
			SubjectCodeSource scs = (SubjectCodeSource)cs;
			canonCs = new SubjectCodeSource(scs.getSubject(),
						scs.getPrincipals(),
						scs.getLocation(),
						getSignerCertificates(scs));
		    }
		}
	    }
	} else {
	    if (extractSignerCerts) {
		if (!(cs instanceof SubjectCodeSource)) {
		    canonCs = new CodeSource(cs.getLocation(),
					getSignerCertificates(cs));
		} else {
		    SubjectCodeSource scs = (SubjectCodeSource)cs;
		    canonCs = new SubjectCodeSource(scs.getSubject(),
					scs.getPrincipals(),
					scs.getLocation(),
					getSignerCertificates(scs));
		}
	    }
	}
	return canonCs;
    
private booleancheckForTrustedIdentity(java.security.cert.Certificate cert)
Checks public key. If it is marked as trusted in the identity database, add it to the policy with the AllPermission.


                               
         
	// XXX	JAAS has no way to access the SUN package.
	//	we'll add this back in when JAAS goes into core.
	return false;
    
private final synchronized java.util.Enumerationelements()
Enumerate all the entries in the global policy object. This method is used by policy admin tools. The tools should use the Enumeration methods on the returned object to fetch the elements sequentially.

	return policyEntries.elements();
    
java.security.cert.Certificate[]getCertificates(java.security.KeyStore keyStore, java.lang.String aliases)
Fetch all certs associated with this alias.


	Vector vcerts = null;

	StringTokenizer st = new StringTokenizer(aliases, ",");
	int n = 0;

	while (st.hasMoreTokens()) {
	    String alias = st.nextToken().trim();
	    n++;
	    Certificate cert = null;
	    //See if this alias's cert has already been cached
	    cert = (Certificate) aliasMapping.get(alias);
	    if (cert == null && keyStore != null) {

		try {
		    cert = keyStore.getCertificate(alias);
		} catch (KeyStoreException kse) {
		    // never happens, because keystore has already been loaded
		    // when we call this
		}
		if (cert != null) {
		    aliasMapping.put(alias, cert);
		    aliasMapping.put(cert, alias);
		} 
	    }

	    if (cert != null) {
		if (vcerts == null)
		    vcerts = new Vector();
		vcerts.addElement(cert);
	    }
	}

	// make sure n == vcerts.size, since we are doing a logical *and*
	if (vcerts != null && n == vcerts.size()) {
	    Certificate[] certs = new Certificate[vcerts.size()];
	    vcerts.copyInto(certs);
	    return certs;
	} else {
	    return null;
	}
    
java.security.CodeSourcegetCodeSource(PolicyParser.GrantEntry ge, java.security.KeyStore keyStore)
Given a PermissionEntry, create a codeSource.

return
null if signedBy alias is not recognized

	Certificate[] certs = null;
	if (ge.signedBy != null) {
	    certs = getCertificates(keyStore, ge.signedBy);
	    if (certs == null) {
		// we don't have a key for this alias,
		// just return
		if (debug != null) {
		    debug.println(" no certs for alias " +
				       ge.signedBy + ", ignoring.");
		}
		return null;
	    }
	}
	
	URL location;

	if (ge.codeBase != null)
	    location = new URL(ge.codeBase);
	else
	    location = null;

	if (ge.principals == null || ge.principals.size() == 0) {
	    return (canonicalizeCodebase
			(new CodeSource(location, certs),
			false));
	} else {
	    return (canonicalizeCodebase
		(new SubjectCodeSource(null, ge.principals, location, certs),
		false));
	}
    
private java.io.InputStreamgetInputStream(java.net.URL url)

	if ("file".equals(url.getProtocol())) {
	    String path = url.getFile().replace('/", File.separatorChar);
	    return new FileInputStream(path);
	} else {
	    return url.openStream();
	}
    
private static final java.security.PermissiongetInstance(java.lang.String type, java.lang.String name, java.lang.String actions)
Returns a new Permission object of the given Type. The Permission is created by getting the Class object using the Class.forName method, and using the reflection API to invoke the (String name, String actions) constructor on the object.

param
type the type of Permission being created.
param
name the name of the Permission being created.
param
actions the actions of the Permission being created.
exception
ClassNotFoundException if the particular Permission class could not be found.
exception
IllegalAccessException if the class or initializer is not accessible.
exception
InstantiationException if getInstance tries to instantiate an abstract class or an interface, or if the instantiation fails for some other reason.
exception
NoSuchMethodException if the (String, String) constructor is not found.
exception
InvocationTargetException if the underlying Permission constructor throws an exception.

	//XXX we might want to keep a hash of created factories...
	Class pc = Class.forName(type);
	Constructor c = pc.getConstructor(PARAMS);
	return (Permission) c.newInstance(new Object[] { name, actions });
    
public java.security.PermissionCollectiongetPermissions(javax.security.auth.Subject subject, java.security.CodeSource codesource)
Examines this Policy and returns the Permissions granted to the specified Subject and CodeSource.

Permissions for a particular grant entry are returned if the CodeSource constructed using the codebase and signedby values specified in the entry implies the CodeSource provided to this method, and if the Subject provided to this method contains all of the Principals specified in the entry.

The Subject provided to this method contains all of the Principals specified in the entry if, for each Principal, "P1", specified in the grant entry one of the following two conditions is met:

  1. the Subject has a Principal, "P2", where P2.getClass().getName() equals the P1's class name, and where P2.getName() equals the P1's name.
  2. P1 implements com.sun.security.auth.PrincipalComparator, and P1.implies the provided Subject.

Note that this Policy implementation has special handling for PrivateCredentialPermissions. When this method encounters a PrivateCredentialPermission which specifies "self" as the Principal class and name, it does not add that Permission to the returned PermissionCollection. Instead, it builds a new PrivateCredentialPermission for each Principal associated with the provided Subject. Each new PrivateCredentialPermission contains the same Credential class as specified in the originally granted permission, as well as the Class and name for the respective Principal.

param
subject the Permissions granted to this Subject and the additionally provided CodeSource are returned.

param
codesource the Permissions granted to this CodeSource and the additionally provided Subject are returned.
return
the Permissions granted to the provided Subject CodeSource.


	// XXX	when JAAS goes into the JDK core,
	//	we can remove this method and simply
	//	rely on the getPermissions variant that takes a codesource,
	//	which no one can use at this point in time.
	//	at that time, we can also make SubjectCodeSource a public
	//	class.

	// XXX
	//
	// 1)	if code instantiates PolicyFile directly, then it will need
	// 	all the permissions required for the PolicyFile initialization
	// 2)	if code calls Policy.getPolicy, then it simply needs
	//	AuthPermission(getPolicy), and the javax.security.auth.Policy
	//	implementation instantiates PolicyFile in a doPrivileged block
	// 3)	if after instantiating a Policy (either via #1 or #2),
	//	code calls getPermissions, PolicyFile wraps the call
	//	in a doPrivileged block.
	return (PermissionCollection)java.security.AccessController.doPrivileged
	    (new java.security.PrivilegedAction() {
	    public Object run() {
		SubjectCodeSource scs = new SubjectCodeSource
		    (subject, 
		    null,
		    codesource == null ? null : codesource.getLocation(),
		    codesource == null ? null : codesource.getCertificates());
 		if (initialized)
 		    return getPermissions(new Permissions(), scs);
 		else
		    return new PolicyPermissions(PolicyFile.this, scs);
	    }
	});
    
java.security.PermissionCollectiongetPermissions(java.security.CodeSource codesource)
Examines the global policy for the specified CodeSource, and creates a PermissionCollection object with the set of permissions for that principal's protection domain.

param
CodeSource the codesource associated with the caller. This encapsulates the original location of the code (where the code came from) and the public key(s) of its signer.
return
the set of permissions according to the policy.


 	if (initialized)
 	    return getPermissions(new Permissions(), codesource);
 	else
 	    return new PolicyPermissions(this, codesource);
    
java.security.PermissionsgetPermissions(java.security.Permissions perms, java.security.CodeSource cs)
Examines the global policy for the specified CodeSource, and creates a PermissionCollection object with the set of permissions for that principal's protection domain.

param
permissions the permissions to populate
param
codesource the codesource associated with the caller. This encapsulates the original location of the code (where the code came from) and the public key(s) of its signer.
return
the set of permissions according to the policy.

	if (!initialized) {
	    init();
	}

	final CodeSource codesource[] = {null};

	codesource[0] = canonicalizeCodebase(cs, true);

	if (debug != null) {
	    debug.println("evaluate("+codesource[0]+")\n");
	}
	    
	// needs to be in a begin/endPrivileged block because
	// codesource.implies calls URL.equals which does an
	// InetAddress lookup

	for (int i = 0; i < policyEntries.size(); i++) {

	   PolicyEntry entry = (PolicyEntry)policyEntries.elementAt(i);

	   if (debug != null) {
		debug.println("PolicyFile CodeSource implies: " +
			entry.codesource.toString() + "\n\n" +
			"\t" + codesource[0].toString() + "\n\n");
	   }

	   if (entry.codesource.implies(codesource[0])) {
	       for (int j = 0; j < entry.permissions.size(); j++) {
		    Permission p = 
		       (Permission) entry.permissions.elementAt(j);
		    if (debug != null) {
		       debug.println("  granting " + p);
		    }
		    if (!addSelfPermissions(p, entry.codesource,
					codesource[0], perms)) {
			// we could check for duplicates
			// before adding new permissions,
			// but the SubjectDomainCombiner
			// already checks for duplicates later
			perms.add(p);
		    }
		}	
	    }
	}

	// now see if any of the keys are trusted ids.

	if (!ignoreIdentityScope) {
	    Certificate certs[] = codesource[0].getCertificates();
	    if (certs != null) {
		for (int k=0; k < certs.length; k++) {
		    if ((aliasMapping.get(certs[k]) == null) &&
			checkForTrustedIdentity(certs[k])) {
			// checkForTrustedIdentity added it
			// to the policy for us. next time
			// around we'll find it. This time
			// around we need to add it.
			perms.add(new java.security.AllPermission());
		    }
		}
	    }
	}
	return perms;
    
private java.lang.String[][]getPrincipalInfo(PolicyParser.PrincipalEntry principal, java.security.CodeSource accCs)
return the principal class/name pair in the 2D array. array[x][y]: x corresponds to the array length. if (y == 0), it's the principal class. if (y == 1), it's the principal name.


	// there are 3 possibilities:
	// 1) the entry's Principal class and name are not wildcarded
	// 2) the entry's Principal name is wildcarded only
	// 3) the entry's Principal class and name are wildcarded
	
	if (!principal.principalClass.equals
		(PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
	    !principal.principalName.equals
		(PolicyParser.PrincipalEntry.WILDCARD_NAME)) {

	    // build a PrivateCredentialPermission for the principal
	    // from the Policy entry
	    String[][] info = new String[1][2];
	    info[0][0] = principal.principalClass;
	    info[0][1] = principal.principalName;
	    return info;

	} else if (!principal.principalClass.equals
		(PolicyParser.PrincipalEntry.WILDCARD_CLASS) &&
	    principal.principalName.equals
		(PolicyParser.PrincipalEntry.WILDCARD_NAME)) {

	    // build a PrivateCredentialPermission for all
	    // the Subject's principals that are instances of principalClass
	    
	    // the accCs is guaranteed to be a SubjectCodeSource
	    // because the earlier CodeSource.implies succeeded
	    SubjectCodeSource scs = (SubjectCodeSource)accCs;

	    Set principalSet = null;
	    try {
		Class pClass = Class.forName(principal.principalClass, false,
				ClassLoader.getSystemClassLoader());
		principalSet = scs.getSubject().getPrincipals(pClass);
	    } catch (Exception e) {
		if (debug != null) {
		    debug.println("problem finding Principal Class " +
				"when expanding SELF permission: " +
				e.toString());
		}
	    }

	    if (principalSet == null) {
		// error
		return new String[0][0];
	    }

	    String[][] info = new String[principalSet.size()][2];
	    java.util.Iterator pIterator = principalSet.iterator();

	    int i = 0;
	    while (pIterator.hasNext()) {
		Principal p = (Principal)pIterator.next();
		info[i][0] = p.getClass().getName();
		info[i][1] = p.getName();
		i++;
	    }
	    return info;

	} else {

	    // build a PrivateCredentialPermission for every
	    // one of the current Subject's principals

	    // the accCs is guaranteed to be a SubjectCodeSource
	    // because the earlier CodeSource.implies succeeded
	    SubjectCodeSource scs = (SubjectCodeSource)accCs;
	    Set principalSet = scs.getSubject().getPrincipals();

	    String[][] info = new String[principalSet.size()][2];
	    java.util.Iterator pIterator = principalSet.iterator();

	    int i = 0;
	    while (pIterator.hasNext()) {
		Principal p = (Principal)pIterator.next();
		info[i][0] = p.getClass().getName();
		info[i][1] = p.getName();
		i++;
	    }
	    return info;
	}
    
java.security.cert.Certificate[]getSignerCertificates(java.security.CodeSource cs)

	Certificate[] certs = null;
	if ((certs = cs.getCertificates()) == null)
	    return null;
	for (int i=0; i<certs.length; i++) {
	    if (!(certs[i] instanceof X509Certificate))
		return cs.getCertificates();
	}

	// Do we have to do anything?
	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)
	    // Done
	    return certs;

	ArrayList userCertList = new ArrayList();
	i = 0;
	while (i < certs.length) {
	    userCertList.add(certs[i]);
	    while (((i+1) < certs.length)
		   && ((X509Certificate)certs[i]).getIssuerDN().equals(
		           ((X509Certificate)certs[i+1]).getSubjectDN())) {
		i++;
	    }
	    i++;
	}
	Certificate[] userCerts = new Certificate[userCertList.size()];
	userCertList.toArray(userCerts);
	return userCerts;
    
private synchronized voidinit()


	if (initialized)
	    return;

	policyEntries = new Vector();
	aliasMapping = new Hashtable(11);
	
	initPolicyFile();
	initialized = true;
    
private voidinit(java.net.URL policy)
Reads a policy configuration into the Policy object using a Reader object.

param
policyFile the policy Reader object.

	PolicyParser pp = new PolicyParser(expandProperties);
	try {
	    InputStreamReader isr
		= new InputStreamReader(getInputStream(policy)); 
	    pp.read(isr);
	    isr.close();
	    KeyStore keyStore = initKeyStore(policy, pp.getKeyStoreUrl(),
					     pp.getKeyStoreType());
	    Enumeration enum_ = pp.grantElements();
	    while (enum_.hasMoreElements()) {
		PolicyParser.GrantEntry ge =
		    (PolicyParser.GrantEntry) enum_.nextElement();
		addGrantEntry(ge, keyStore);
	    }
	} catch (PolicyParser.ParsingException pe) {
	    System.err.println(AUTH_POLICY +
				rb.getString(": error parsing ") + policy);
	    System.err.println(AUTH_POLICY +
				rb.getString(": ") +
				pe.getMessage());
	    if (debug != null) 
		pe.printStackTrace();

	} catch (Exception e) {
	    if (debug != null) {
		debug.println("error parsing "+policy);
		debug.println(e.toString());
		e.printStackTrace();
	    }
	}
    
private java.security.KeyStoreinitKeyStore(java.net.URL policyUrl, java.lang.String keyStoreName, java.lang.String keyStoreType)

	if (keyStoreName != null) {
	    try {
		/*
		 * location of keystore is specified as absolute URL in policy
		 * file, or is relative to URL of policy file
		 */
		URL keyStoreUrl = null;
		try {
		    keyStoreUrl = new URL(keyStoreName);
		    // absolute URL
		} catch (java.net.MalformedURLException e) {
		    // relative URL
		    keyStoreUrl = new URL(policyUrl, keyStoreName);
		}

		if (debug != null) {
		    debug.println("reading keystore"+keyStoreUrl);
		}

		InputStream inStream = 
		    new BufferedInputStream(getInputStream(keyStoreUrl));

		KeyStore ks;
		if (keyStoreType != null)
		    ks = KeyStore.getInstance(keyStoreType);
		else
		    ks = KeyStore.getInstance(KeyStore.getDefaultType());
		ks.load(inStream, null);
		inStream.close();
		return ks;
	    } catch (Exception e) {
		// ignore, treat it like we have no keystore
		if (debug != null) {
		    e.printStackTrace();
		}
		return null;
	    }	    
	}
	return null;
    
private voidinitPolicyFile()


	String prop = Security.getProperty("policy.expandProperties");

	if (prop != null) expandProperties = prop.equalsIgnoreCase("true");

	String iscp = Security.getProperty("policy.ignoreIdentityScope");

	if (iscp != null) ignoreIdentityScope = iscp.equalsIgnoreCase("true");

	String allowSys  = Security.getProperty("policy.allowSystemProperty");

	if ((allowSys!=null) && allowSys.equalsIgnoreCase("true")) {

	    String extra_policy = System.getProperty(AUTH_POLICY);
	    if (extra_policy != null) {
		boolean overrideAll = false;
		if (extra_policy.startsWith("=")) {
		    overrideAll = true;
		    extra_policy = extra_policy.substring(1);
		}
		try {
		    extra_policy = PropertyExpander.expand(extra_policy);
		    URL policyURL;;
		    File policyFile = new File(extra_policy);
		    if (policyFile.exists()) {
			policyURL =
			    new URL("file:" + policyFile.getCanonicalPath());
		    } else {
			policyURL = new URL(extra_policy);
		    }
		    if (debug != null)
			debug.println("reading "+policyURL);
		    init(policyURL);
		} catch (Exception e) {
		    // ignore. 
		    if (debug != null) {
			debug.println("caught exception: "+e);
		    }

		}
		if (overrideAll) {
		    if (debug != null) {
			debug.println("overriding other policies!");
		    }
		    return;
		}
	    }
	}

	int n = 1;
	boolean loaded_one = false;
	String policy_url;

	while ((policy_url = Security.getProperty(AUTH_POLICY_URL+n)) != null) {
	    try {
		policy_url = PropertyExpander.expand(policy_url).replace
						(File.separatorChar, '/");
		if (debug != null)
		    debug.println("reading "+policy_url);
		init(new URL(policy_url));
		loaded_one = true;
	    } catch (Exception e) {
		if (debug != null) {
		    debug.println("error reading policy "+e);
		    e.printStackTrace();
		}
		// ignore that policy
	    }
	    n++;
	}

	if (loaded_one == false) {
	    // do not load a static policy
	}
    
public synchronized voidrefresh()
Refreshes the policy object by re-reading all the policy files.

exception
SecurityException if the caller doesn't have permission to refresh the Policy.


	java.lang.SecurityManager sm = System.getSecurityManager();
	if (sm != null) {
	    sm.checkPermission(new javax.security.auth.AuthPermission
				("refreshPolicy"));
	}

	// XXX
	//
	// 1)	if code instantiates PolicyFile directly, then it will need
	// 	all the permissions required for the PolicyFile initialization
	// 2)	if code calls Policy.getPolicy, then it simply needs
	//	AuthPermission(getPolicy), and the javax.security.auth.Policy
	//	implementation instantiates PolicyFile in a doPrivileged block
	// 3)	if after instantiating a Policy (either via #1 or #2),
	//	code calls refresh, it simply needs
	//	AuthPermission(refreshPolicy).  then PolicyFile wraps
	//	the refresh in a doPrivileged block.
	initialized = false;
	java.security.AccessController.doPrivileged
	    (new java.security.PrivilegedAction() {
	    public Object run() {
		init();
		return null;
	    }
	});