The policy for a Java runtime (specifying which permissions
are available for code from various principals) is represented
by a Policy object. More specifically, it is represented by a
Policy
subclass providing an implementation
of the abstract methods in the Policy
class (which is
in the java.security
package).
The source location for the policy information utilized by the Policy object is up to the Policy implementation. There is a default Policy implementation that obtains its information from static policy configuration files. The rest of this document pertains to the default Policy implementation and the syntax that must be used in policy files it reads.
Here is an outline:
In the default Policy implementation, the policy is represented as one or more separate persistent configurations. In this default implementation, each Java runtime may have one system policy file and one user policy file.The system policy file is by default located at
<java.home>/lib/security/java.policywhere <java.home> indicates the JDK installation directory (determined by the value of the "java.home" system property). Note: the name of the system policy file can be changed by resetting the value of the security property named "policy.java" to the new name.
The user policy file is by default located at
<user.home>/.java.policywhere <user.home> indicates the user's home directory (determined by the value of the "user.home" system property). However, if the user is running a program invoked with the -D switch specifying a "java.policy" value, as in:
java -Djava.policy="myPolicyFileName" MyClassthen the name in quotes following "-Djava.policy=" is used as the name of the user policy file. It can include the path; otherwise, the file is assumed to be in the current directory.The default Policy object is initialized the first time its
evaluate
method is called, or whenever itsrefresh
method is called. Initialization involves parsing the policy configuration file(s) (see Policy File Syntax), and then populating the Policy object. It loads in the system policy first, then adds to it the user policy. If neither policy is present, a built-in policy equivalent to the original sandbox policy is used.
The default Policy implementation can be changed to a different class. This is done by editing the security properties file, which is the
java.security
file in thelib/security
directory of the JDK. Thus, if the JDK is installed in a directory calledjdk1.2
, the file would bejdk1.2/lib/security/java.security
.One of the types of properties you can set in
java.security
is of the following form:policy.provider=PolicyClassNamePolicyClassName must specify the fully qualified name of the desired Policy implementation class.
Suppose for example that the Policy implementation class is
COM.acme.Policy
. Then add the following line to thejava.security
file:policy.provider=COM.acme.Policy
The policy configuration file(s) for a JDK installation specify what permissions (which types of system resource accesses) are allowed by code from specified code sources.
In order for an applet (or an application running under a Security Manager) to be allowed to perform secured actions (such as reading or writing a file), the applet must be granted permission for that particular action. In the default Policy implementation, that permission must be granted by a code source entry in a policy configuration file. (See below and the "Java Security Architecture Specification" for more information.)
Code being executed is always considered to come from a particular "code source". The code source includes not only the location (URL) where the applet originated from, but also a reference to the public key corresponding to the private key used to sign the code. Public keys in a code source are referenced by (symbolic) alias names from the user's keystore, located in the file named ".keystore" in the user's home directory. See the keytool (for Solaris) (for Windows) documentation for more information about the keystore.
In a policy configuration file, a code source is represented by two components: a code base (URL), and an alias name (preceded by "signedBy"), where the alias name identifies the keystore entry containing the public key that must be used to verify the signature on the JAR file.
Each policy file consists of one or more "grant entries", each of which consists of a number of "permission entries". Each grant entry grants a specified code source a set of permissions, specifying which actions are allowed. The basic format of a grant entry is the following:
grant signedBy "alias", codeBase "URL" { permission Type "name", "action", signedBy "alias"; .... permission Type "name", "action", signedBy "alias"; };All non-italicized 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
. ThesignedBy
andcodeBase
name/value pairs are optional. If they are not present, then any signer (including unsigned code) will match, and any codeBase will match.A permission entry must begin with the word
permission
. The wordType
in the template above would actually be a specific permission type, such asjava.io.FilePermission
orjava.lang.RuntimePermission
.The "action" is required for many permission types, such as
java.io.FilePermission
(where it specifies what type of file access is permitted). It is not required for categories such asjava.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 the permission to be granted. For example, suppose you have the following grant entry:grant { 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 ifFoo.class
is a system class (i.e., is found on the CLASSPATH), since classes on the CLASSPATH currently cannot be signed and are not subject to policy restrictions.Items that appear in a permission 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 signed by "Duke", grant it read/write access to all // files in /tmp: grant signedBy "Duke" { permission java.io.FilePermission "/tmp/*", "read,write"; };// Grant everyone the following permission: grant { permission java.util.PropertyPermission "java.vendor"; };
The contents of another sample policy configuration file appear below.
grant signedBy "sysadmin", codeBase "file:/home/sysadmin/" { permission java.security.SecurityPermission "Security.insertProvider.*"; permission java.security.SecurityPermission "Security.removeProvider.*"; permission java.security.SecurityPermission "Security.setProperty.*"; };This specifies that only applet code that was loaded from a signed JAR file (whose signature can be verified using the public key referenced by the alias name "sysadmin" in the user's keystore) from beneath the "/home/sysadmin/" directory on the local file system can call methods in the Security class to add or remove providers or to set Security properties.Either component of the code source (or both) may be missing. An example where
codeBase
is missing is:grant signedBy "sysadmin" { permission java.security.SecurityPermission "Security.insertProvider.*"; permission java.security.SecurityPermission "Security.removeProvider.*"; };If this policy is in effect, code that comes in a JAR File signed by "sysadmin" can add/remove providers - regardless of where the JAR File originated from.An example without a signer is:
grant codeBase "file:/home/sysadmin/" { permission java.security.SecurityPermission "Security.insertProvider.*"; permission java.security.SecurityPermission "Security.removeProvider.*"; };In this case, code that comes from anywhere beneath the "/home/sysadmin/" directory on the local filesystem can add/remove providers. The code does not need to be signed.An example where neither codeBase nor signedBy is included is:
grant { permission java.security.SecurityPermission "Security.insertProvider.*"; permission java.security.SecurityPermission "Security.removeProvider.*"; };Here, with both code source components missing, any code (regardless of where it originated from, or whether or not it is signed, or who signed it) can add/remove providers.