The Artima Developer Community
Sponsored Link

Chapter 3 of Inside the Java Virtual Machine
Security
by Bill Venners

<<  Page 9 of 17  >>

Advertisement

Policy

As mentioned previously, one of the greatest advantages of Java's sandbox security model is that the sandbox can be customized. The code signing and authentication technology introduced in Java version 1.1 enables your running application to differentiate code to which you attribute different degrees of trust. By customizing the sandbox, trusted code can be given more access to system resources than untrusted code. This prevents untrusted code from accessing the system, but allows trusted code to access the system and do useful work. The real power of Java's security architecture, however, lies in the ability to grant code with varying degrees of trust different levels of partial access to the system.

Microsoft offers an authentication technology similar to Java's for ActiveX controls, but ActiveX controls don't run inside a sandbox. Thus with ActiveX, a chunk of mobile code is either completely trusted or completely untrusted. If untrusted, the ActiveX control is denied the opportunity to run. If trusted, the ActiveX control is allowed to run and given full access to the system. While this is a big improvement over no authentication at all, if some malicious or buggy code gets authenticated, the dangerous code has full access to the system. One of the strengths of Java's security architecture is that code can be given access only to the resources it needs. If some malicious or buggy code gets authenticated, it has less opportunity to do damage. For example, instead of being able to delete all files on a local hard disk, the malicious or buggy code might only be able to delete the files in a particular directory set aside just for it.

One major goal of the 1.2 security infrastructure is to make it easier and less error prone to establish fine-grained access control policies based on signed code. To be able to assign different system access privileges to different units of code, Java's access control mechanism must be able to ascertain what privileges should be given to each individual piece of code. To facilitate this process, each piece of code (each class file) loaded into a 1.2 or beyond Java virtual machine is associated with a code source. The code source basically says where the code came from and who, if anyone, has vouched for the code by signing it. In the 1.2 security model, permissions (system access privileges) are assigned to code sources. Thus, if a piece of code requests access to a particular system resource, the Java virtual machine will grant the code access to that resource only if such access is a privilege associated with that code's code source.

In the 1.2 security infrastructure, an access control policy for an entire Java application is represented by a single instance of a subclass of the abstract class java.security.Policy. Each application has just one Policy object in effect at any given time. Code that has permission can replace the current Policy object with a new one by invoking Policy.setPolicy() and passing a reference to the new Policy object. Class loaders consult the Policy object to help them to decide what privileges to grant code as they import the code into the virtual machine.

A security policy is a mapping from a set of properties that characterize running code to the permissions granted the code. In the 1.2 security infrastructure, the properties that characterize running code are collectively called the code source. A code source is represented by a java.security.CodeSource object, which contains a java.net.URL to represent the codebase and an array of zero or more certificate objects to represent the signers. Certificate objects are instances of subclasses of the abstract class java.security.cert.Certificate. A Certificate is an abstraction that represents a binding of a principal to a public key, and another principal (the certificate authority mentioned previously) that vouches for that binding. The CodeSource object contains an array of Certificate objects, because the same code can be signed (vouched for) by more than one party. The signatures are usually obtained from a JAR file.

All of the tools and access control infrastructure that accompanies the concrete SecurityManager in version 1.2 work only with certificates. None work with bare public keys. If you don't have a certificate authority handy, you can sign your own public key with your private key and generate a self-signed certificate. The keytool program from the Java 2 SDK version 1.2 always generates a self-signed certificate when it generates keys. In the code signing example given earlier in this chapter, for instance, the keytool created not only public/private key pairs, but also self-signed certificates for the aliases friend and stranger.

A permission is represented by an instance of a subclass of the abstract class java.security.Permission. A permission object has three properties: a type, a name, and an optional action. A permission's type is indicated by the name of the permission class. Some examples of permission types are: java.io.FilePermission, java.net.SocketPermission, and java.awt.AWTPermission. A permission's name is encapsulated inside the Permission object. For example, the name of a FilePermission might be: "/my/finances.dat"; the name of an SocketPermission might be "applets.artima.com:2000"; and the name of an AWTPermission might be "showWindowWithoutBannerWarning". The third property of a Permission object is its action. Not all permissions have an action. An example of an action for a FilePermission is: "read,write", and for a SocketPermission is: "accept,connect". A FilePermission with the name /my/finances.dat and action read,write represents permission to read and write to the file /my/finances.dat. Both name and action are represented by Strings.

The Java API has a large hierarchy of permissions that represent potentially dangerous actions code may wish to take. You can also create your own permission classes to represent custom permissions that you use for your own purposes. For example, you could create permission classes that represent permission to access particular records of your proprietary database. Defining custom permission classes is one way you can extend the 1.2 security mechanism to reflect your own needs. If you create your own Permission classes, you can use them like any of the built-in Permission classes from the Java API.

In the Policy object, each CodeSource is associated with one or more Permission objects. The Permission objects with which a CodeSource is associated are encapsulated in an instance of a subclass of java.security.PermissionCollection. Class loaders can invoke Policy.getPolicy() to get a reference to the policy object currently in effect. They can then invoke getPermissions() on the Policy object, passing in a CodeSource to get a PermissionCollection of Permission objects for the passed CodeSource. A class loader can then use the PermissionCollection retrieved from the Policy object to help it decide what permissions the code it is about to import will be granted.

Policy File

java.security.Policy is an abstract class. One of the implementation details of concrete Policy subclasses is how an instance of the subclass learns what the policy should be. Subclasses can take various approaches, such as deserializing a previously serialized policy object, extracting the policy from a database, or reading the policy from a file. The concrete policy subclass supplied by Sun with the version 1.2 Java Platform takes the latter approach: it enables you to express your security policy in a context free grammar in an ASCII policy file.

A policy file is consists of a series grant clauses, each of which grants a code source a set of permissions. As mentioned previously, a code source consists of a codebase, which is a URL from which code was loaded, and a set of signers. In the policy file, signers are designated with the alias with which the signer's public key is stored in a keystore file. The keystore can be explicitly specified in the policy file in a keystore statement.

As an example of a policy file, consider the policyfile.txt file from the security/ex2 directory of the CD-ROM:

keystore "ijvmkeys";

grant signedBy "friend" {
    permission java.io.FilePermission "question.txt", "read";
    permission java.io.FilePermission "answer.txt", "read";
};

grant signedBy "stranger" {
    permission java.io.FilePermission "question.txt", "read";
};

grant codeBase "file:${com.artima.ijvm.cdrom.home}/security/ex2/*" {
	permission java.io.FilePermission "question.txt", "read";
	permission java.io.FilePermission "answer.txt", "read";
};

The first statement in the policyfile.txt file is a keystore statement:

keystore "ijvmkeys";

This keystore statement indicates that the key aliases mentioned in the rest of the policy file refer to certificates stored in a file named "ijvmkeys". Because this filename includes no path, the file must be located in the current directory -- the directory in which the Java application using this policy file is started.

The second statement in the policy file is a grant statement:

grant signedBy "friend" {
    permission java.io.FilePermission "question.txt", "read";
    permission java.io.FilePermission "answer.txt", "read";
};

This statement grants two permissions to any code signed by the entity with the alias "friend". The granted permissions are: permission to read a file named question.txt and permission to read a file named answer.txt. Because these filenames appear with no path, both files must be in the current directory, the directory in which the application is started. Because no codebase is mentioned in the grant clause, code signed by friend can come from any codebase. All code signed by friend, regardless of codebase, will be awarded permission to read question.txt and answer.txt.

The third statement in policyfile.txt is another grant statement, similar in form to the first:

grant signedBy "stranger" {
    permission java.io.FilePermission "question.txt", "read";
};

This statement grants one permission to any code signed by the entity with the alias "stranger": permission to read a file named question.txt. This file must be sitting in the current directory, the directory in which the application is started. Because no codebase is mentioned in the grant clause, code signed by stranger can come from any codebase and will still be awarded permission to read question.txt. Note that although stranger is allowed to read the question contained in question.txt, stranger is not allowed to peek at the answer contained in answer.txt. This contrasts with the privileges awarded to friend, who is allowed to read both the question and the answer.

The fourth and final statement in this policy file is yet another grant statement:

grant codeBase "file:${com.artima.ijvm.cdrom.home}/security/ex2/*" {
	permission java.io.FilePermission "question.txt", "read";
	permission java.io.FilePermission "answer.txt", "read";
};

This final grant statement grants two permissions to any code that was loaded from a particular directory, permission to read a file named question.txt and permission to read a file named answer.txt. Both files must be in the current directory, the directory in which the application is started. Note that this grant statement does not mention any signers. The code can be signed by anyone or no one. So long as it is loaded from the indicated directory, the code will be granted the listed permissions.

The codebase URL in this grant statement takes the form of a file: URL that includes a property, ${com.artima.ijvm.cdrom.home}. If you run the AccessControl example programs described later in this chapter, you'll have to set the com.artima.ijvm.cdrom.home property to the path of the CD-ROM that comes with this book, or to whatever directory you have moved the security subdirectory from the CD-ROM. The Policy object that is instantiated based on the contents of policyfile.txt will take the com.artima.ijvm.cdrom.home property into account when it constructs the URL for the CodeSource for this grant clause.

<<  Page 9 of 17  >>


Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use