Now the Java program has an appropriate output stream to save its data. On the other hand, this technique can be used by the author of an applet to probe your browsers
security manager without your knowledge −− and because the applet is catching the security exceptions, youll never see them. This is one reason why its important to understand the
ramifications of adjusting your browsers security policy.
One exception to this guideline occurs when you extend the virtual operating system of the Java API, and it is important to ensure that your extensions are well−integrated into Javas security scheme. Certain parts of the
Java API −− the Toolkit
class, the Provider
class, the Socket
class, and others −− are written in such a way that they allow you to provide your own implementation of those classes. If youre providing your own
implementation of any one of these classes, you have to make sure that it calls the security manager at appropriate times.
Its important to note that there is by design no attempt in the Java API to maintain any sort of state. Whenever the Java API needs to perform an operation, it checks with the security manager to see if the
operation is to be allowed −− even if that same operation has been permitted by the security manager before. This is because the context of the operation is often significant −− the security manager might allow a
FileOutputStream object to be opened in some cases e.g., by certain classes while it might deny it in
other cases. The Java API cannot keep track of this contextual information, so it asks the security manager for permission to perform every operation.
4.2 Operating on the Security Manager
There are two methods in the System
class that are used to work with the security manager itself: public static SecurityManager getSecurityManager
Return a reference to the currently installed security manager object or null
if no security manager is in place. Once obtained, this object can be used to test against various security policies.
public static void setSecurityManagerSecurityManager sm Set the systems security manager to the given object. Code that wants to install a security manager
must have the runtime permissions createSecurityManager
in order to instantiate the security manager object and
setSecurityManager in order to install it.
These methods operate with the understanding that there is a single security manager in the virtual machine; the only operations that are possible on the security manager are setting it that is, creating an instance of the
security manager class and telling the virtual machine that the newly created object should be the security manager and getting it that is, asking the virtual machine to return the object that is the security manager so
that a method might be invoked upon it.
Weve already seen how you might use the getSecurityManager
method to retrieve the security manager and invoke an operation on it. Setting the security manager is a predictably simple operation:
public static void mainString args[] { System.setSecurityManagernew SecurityManagerImpl ;
... do the work of the application ... }
}
The SecurityManager
class provides a complete implementation that uses the access controller to implement the permission−based sandbox we discussed in Chapter 2. When you specify the
−Djava.security.manager option to a Java application, the virtual machine executes the
setSecurityManager method on your behalf, before it calls the
main method of your
application. However, its possible to extend the
SecurityManager class to provide a different implementation of the
sandbox. The Java Plug−in and appletviewer
use such a modified implementation and install it before they load any applets. And while the changes that the Java Plug−in and
appletviewer make are very
minor, other environments can have completely different implementations.
4.3 Methods of the Security Manager
Now that we have an understanding of how the security manager works, well look into what protection the security manager actually provides. Well discuss the public methods of the security manager that perform
security checks and when those methods are called, along with the rationale behind each of the methods. Since these methods are all public, they can be called anywhere, including in your own code, although as
weve mentioned, thats a rare thing. The real point of this section is so that you can know which methods of the core Java API are affected by the security manager and to give you some background on why these
choices were made.
When we discuss the methods below, we speak of them in terms of trusted and untrusted classes. A trusted class is a class of the core Java API or a class that has been granted explicit permission to perform the
operation in question.
Youll note that the methods of the security manager correspond fairly well to the set of default permissions that we listed in Chapter 2. In fact, the basic implementation of each method of the security manager is to test
to ensure that each active protection domain has permission to perform the desired operation.
4.3.1 Methods Relating to File Access
The most well−known methods of the security manager class handle access to files on the local network. This includes any files that are on the local disk as well as files that might be physically located on another
machine but appear through the use of NFS, NetWare, Samba, or a similar network−based filesystem to be part of the local filesystem.
These are the methods the security manager uses to track file access: public void checkReadFileDescriptor fd
public void checkReadString file public void checkReadString file, Object context
Check whether the program is allowed to read the given file. The first of these methods succeeds if the current protection domain has been granted the runtime permission with the name
readFileDescriptor . The other methods succeed if the current protection domain has a file
permission with a name that matches the given file and an action of read. public void checkWriteFileDescriptor fd
public void checkWriteString file Check whether the program is allowed to write the given file. The first of these methods succeeds if
the current protection domain has been granted the runtime permission with the name 58
writeFileDescriptor . The second succeeds if the current protection domain has a file
permission with a name that matches the given file and an action of write. public void checkDeleteString file
Check whether the program is allowed to delete the given file. This succeeds if the current protection domain has a file permission with a name that matches the given file and an action of delete.
Interestingly, although as developers we tend to think of other file operations −− such as creating a file or seeing when the file was last modified −− as being distinct operations, as far as security is concerned, the Java
API considers all operations to be either reading, writing, or deleting.
Table 4−1 lists the Java API interaction with the checkRead
, checkWrite
, and checkDelete
methods, listing when and why each check is invoked. In all the tables in this chapter, the syntax may imply that the calling methods are all static, but it of course is not the case: the entry
File.canRead means the
canRead method invoked on an instance of the
File class.
This table lists only those classes that directly call the security manager method in question. There may be many routes through the Java API that lead to one of these checks; for example, when a
FileReader object
is constructed, it will construct a FileInputStream
object, which will result in a call to checkRead
.
Table 4−1. Check Methods
Method Called By
Rationale
checkRead File.canRead
Test if the current thread can read the file.
FileInputStream RandomAccessFile
Constructing a file object requires that you read the file.
File.isDirectory File.isFile
Determining whether a file object is an actual file or a directory requires that you read the file.
File.lastModified
Determining the modification date requires that you read the files attributes.
File.length
Determining the length requires that you read the files attributes.
File.list
Determining the files in a directory requires that you read the directory.
checkWrite File.canWrite
Test if the current thread can write the file.
FileOutputStream RandomAccessFile
To construct a file object, you must be able to write the file.
File.mkdir
To create a directory, you must be able to write to the filesystem.
File.renameTo
To rename a file, you must be able to write to the directory containing the file.
File.createTempFile
To create a temporary file, you must be able to write the file.
checkDelete File.delete
Test if the current thread can delete a file.
File.deleteOnExit
Test if the current thread can delete the file when the virtual machine exits.