Security Managers and the Java API

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.