The Artima Developer Community
Sponsored Link

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

<<  Page 12 of 17  >>

Advertisement

Stack Inspection Examples

The next few sections give several examples to illustrate the manner in which the AccessController performs stack inspection. In the upcoming examples, code signed by both friend and stranger will be trusted to some extent, but friend code will be trusted more than stranger code. In particular, code signed by both friend and stranger will be given permission to read a file named question.txt, which contains a question. But although code signed by friend will be given permission to read a file named answer.txt, which contains the answer to the question asked in question.txt, code signed by stranger will not. These permissions granted to friend and stranger are those outlined in the policyfile.txt file from the security/ex2 directory of the CD-ROM, which was described earlier in this chapter. Each of the upcoming examples will take their policy from policyfile.txt.

The stack inspection examples all make use of classes that implement the Doer interface:

// On CD-ROM in file
// security/ex2/com/artima/security/doer/Doer.java
package com.artima.security.doer;

public interface Doer {

    void doYourThing();
}

To be a Doer, a class must provide an implementation for one method: doYourThing(). Classes that implement Doer can do whatever they feel like in their doYourThing() method. For example, here's a class that implements Doer named TextFileDisplayer whose "thing" is to display the contents of a text file:

// On CD-ROM in file security/ex2/TextFileDisplayer.java

import com.artima.security.doer.Doer;
import java.io.FileReader;
import java.io.CharArrayWriter;
import java.io.IOException;

public class TextFileDisplayer implements Doer {

    private String fileName;

    public TextFileDisplayer(String fileName) {
        this.fileName = fileName;
    }

    public void doYourThing() {

        try {
            FileReader fr = new FileReader(fileName);

            try {
                CharArrayWriter caw = new CharArrayWriter();

                int c;
                while ((c = fr.read()) != -1) {
                    caw.write(c);
                }

                System.out.println(caw.toString());
            }
            catch (IOException e) {
            }
            finally {
                try {
                    fr.close();
                }
                catch (IOException e) {
                }
            }
        }
        catch (IOException e) {
        }
    }
}

When you create a TextFileDisplayer object, you must pass a file path name to its constructor. The TextFileDisplayer constructor stores the passed path name in the filename instance variable. When you invoke doYourThing() on the TextFileDisplayer object, it will attempt to open and read the contents of the file and print them at the standard output.

Another example of a doYourThing() method comes from classes Friend and Stranger, which appeared earlier in this chapter in the code signing example and are shown again here to refresh your memory:

// On CD-ROM in file
// security/ex2/com/artima/security/friend/Friend.java
package com.artima.security.friend;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Friend implements Doer {

    private Doer next;
    private boolean direct;

    public Friend(Doer next, boolean direct) {
        this.next = next;
        this.direct = direct;
    }

    public void doYourThing() {

        if (direct) {

            next.doYourThing();
        }
        else {
            AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        next.doYourThing();
                        return null;
                    }
                }
            );
        }
    }
}

// On CD-ROM in file
// security/ex2/com/artima/security/stranger/Stranger.java
package com.artima.security.stranger;
import com.artima.security.doer.Doer;
import java.security.AccessController;
import java.security.PrivilegedAction;

public class Stranger implements Doer {

    private Doer next;
    private boolean direct;

    public Stranger(Doer next, boolean direct) {
        this.next = next;
        this.direct = direct;
    }

    public void doYourThing() {

        if (direct) {

            next.doYourThing();
        }
        else {
            AccessController.doPrivileged(
                new PrivilegedAction() {
                    public Object run() {
                        next.doYourThing();
                        return null;
                    }
                }
            );
        }
    }
}

Friend and Stranger have much in common. They have identical instance variables, constructors, and doYourThing() methods. They differ only in their package and simple names. When you create a new Friend or Stranger object, you must pass to the constructor a boolean value and a reference to another object whose class implements the Doer interface. The constructor stores the passed Doer reference in the instance variable, next, and the boolean value in the instance variable, direct. When doYourThing() is invoked on either a Friend or Stranger object, the method invokes doYourThing(), either directly or indirectly, on the Doer reference contained in next. If direct is true, Friend or Stranger's doYourThing() just invokes doYourThing() directly on next. Otherwise, Friend or Stranger's doYourThing() invokes doYourThing() on next indirectly, by way of a doPrivileged() call.

<<  Page 12 of 17  >>


Sponsored Links



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