|
|
|
Sponsored Link •
|
|
Advertisement
|
doPrivileged() It is important to understand that a method can never grant itself more privileges than it already has
with a doPrivileged() invocation. By calling
doPrivileged(), a method is merely enabling privileges it already has. It is telling
the AccessController that it is taking responsibility for exercising its own
permissions, and that the AccessController should ignore the permissions of its
callers. Thus, the doPrivileged() call in the previous example,
Example2c enabled answer.txt to be read because
Friend, the class that executed the doPrivileged(), already
had permission to read the file, and so did all the frames above it on the stack.
For an example of a futile attempt to use doPrivileged(), consider the
Example2d application from the security/ex2 directory of
the CD-ROM:
// On CD-ROM in file security/ex2/Example2d.java
import com.artima.security.friend.Friend;
import com.artima.security.stranger.Stranger;
// This fails because even though Stranger does
// a doPrivileged() call, Stranger doesn't have
// permission to read question.txt. (Passing
// false as second arg to Stranger constructor
// causes it to do a doPrivileged().)
class Example2d {
public static void main(String[] args) {
TextFileDisplayer tfd = new TextFileDisplayer("answer.txt");
Stranger stranger = new Stranger(tfd, false);
Friend friend = new Friend(stranger, true);
friend.doYourThing();
}
}
The difference between Example2d and the previous example,
Example2c, is that the Stranger and
Friend objects have swapped positions and roles. The
Stranger object is now farther up the stack, with the Friend
below it on the stack. And this time, it is Stranger that will make the call to
doPrivileged(), not Friend.
When the Example2d program invokes doYourThing()
on the Friend object referenced from the friend variable, the
Friend object invokes doYourThing() on the
Stranger object, which (because direct is
false) invokes doPrivileged(), passing in the anonymous
inner class instance that implements PrivilegedAction. The
doPrivileged() method invokes run() on the passed
PrivilegedAction object, which invokes doYourThing()
on the TextFileDisplayer object.
As in the previous two examples, TextFileDisplayer's
doYourThing() method attempts to open and read a file named
"answer.txt" in the current directory and print its contents to the standard output.
When TextFileDisplayer's doYourThing() method
creates a new FileReader object, the FileReader
constructor creates a new FileInputStream, whose constructor checks to see
whether or not a security manager has been installed. As in all the examples, the concrete
SecurityManager has been installed, so the
FileInputStream's constructor invokes checkRead() on the
concrete SecurityManager. The checkRead() method
instantiates a new FilePermission object representing permission to read file
answer.txt and passes that object to the concrete
SecurityManager's checkPermission() method, which
passes the object on to the checkPermission() method of the
AccessController. The AccessController's
checkPermission() method performs the stack inspection to determine whether
this thread should be allowed to open file answer.txt for reading. The stack
presented to the AccessController by Example2d is shown
in Figure 3-9.

Example2d: frame five doesn't have permission.
The call stack to be inspected in Example2d looks similar to the call stack
inspected in Example2c. The only difference is that Friend and
Stranger have swapped positions. As always, stack inspection starts at the top of the
stack and proceeds on down the stack towards frame one. But alas, once again the inspection process will
not actually reach frame one. When the AccessController reaches frame five, it
discovers a stack frame associated with the STRANGER protection domain, which doesn't have permission
to read answer.txt. As a result of this discovery, the
AccessController throws an
AccessControlException, indicating the requested read of
answer.txt should not be performed.
Had the Stranger class been able to enlist the assistance of an instance of some
class that implemented PrivilegedAction, performed the desired invocation of the
TextFileDisplayer's doYourThing() method, and
belonged to a protection domain that has permission to read >answer.txt,
Stranger's attempt to open answer.txt with the help of
doPrivileged() would have still been futile. Imagine, for example, that the code of
the run() method represented by frame five of Example2d's call
stack had been associated with to the CD-ROM protection domain. In that case, the
AccessController would have determined that frame five had permission to open
answer.txt and continued on to frame four. At frame four, the
AccessController would have discovered the
doPrivileged() invocation. As a result of this discovery, the
AccessController would make one more check: it would make certain the method
that invoked doPrivileged(), which in this case was
Stranger's doYourThing() method represented by stack
frame three, has permission to read file answer.txt. Because frame three is
associated with the STRANGER protection domain that doesn't have permission to read
answer.txt, the AccessController would still throw an
AccessControlException.
To get the Example2d application to work as intended, you must start the
application with yet another appropriate command. When using the java program
from the Java 2 SDK version 1.2, the appropriate command takes the form:
java -Djava.security.manager -Djava.security.policy=policyfile.txt - Dcom.artima.ijvm.cdrom.home=d:\books\InsideJVM\manuscript\cdrom -cp .;jars/friend.jar;jars/stranger.jar Example2d
This command, which is contained in the ex2d.bat file in the
security/ex2 directory of the CD-ROM, is an example of the kind of command
you'll need to use to get the example to work. As before, to execute Example2d on
your own system, you must set the com.artima.ijvm.cdrom.home property to
the security/ex2 directory of your CD-ROM, or to whatever directory you may
have copied the security/ex2 directory from the CD-ROM. When you run this
program, you should see the kind of output that crackers everywhere hate to see:
Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission answer.txt read) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:195) at java.security.AccessController.checkPermission(AccessController.java:403) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkRead(SecurityManager.java:873) at java.io.FileInputStream.(FileInputStream.java:65) at java.io.FileReader. (FileReader.java:35) at TextFileDisplayer.doYourThing(TextFileDisplayer.java, Compiled Code) at com.artima.security.stranger.Stranger$1.run(Stranger.java:27) at java.security.AccessController.doPrivileged(Native Method) at com.artima.security.stranger.Stranger.doYourThing(Stranger.java:24) at com.artima.security.friend.Friend.doYourThing(Friend.java:21) at Example2d.main(Example2d.java:21)
|
Sponsored Links
|