Question

I'm getting a bizarre error trying to run a Java RMI application with a SecurityManager. When the server starts up, I want it to read in text from a file supplied as a command-line argument. I'm using Eclipse, and this file is in the same directory as the root of the Java project (so I can just give the filename in the command-line argument instead of a full path). I know that RMI's SecurityManager forbids file I/O by default, so I've created a policy file for my server that looks like this:

grant codeBase "file:///C:/Users/Edward/College/CS197/authmatch/bin/-" {
    //Giving the server permission to make connections
    permission java.net.SocketPermission "127.0.0.1:1024-", "connect, resolve";
    permission java.net.SocketPermission "127.0.0.1:1024-", "accept, resolve";
    //File I/O permissions
    permission java.io.FilePermission "C:/Users/Edward/College/CS197/authmatch/-", "read,write,delete";
    permission java.util.PropertyPermission "user.dir", "read";
    permission java.lang.RuntimePermission "readFileDescriptor";
    permission java.lang.RuntimePermission "modifyThread";
};

(Note that the name of my Eclipse project is "authmatch", and this is running on Windows). In my Eclipse run configuration, I enable this policy file with the following VM flags:

-Djava.rmi.server.codebase=file:///C:/Users/Edward/Documents/College/CS197/authmatch/bin/
-Djava.security.policy=server.policy

I know that the policy file is being parsed and loaded because if I introduce a syntax error in server.policy Java complains about it ("error parsing file") when my application runs. However, the security manager seems to be somehow ignoring the permissions I grant in my policy, because when I run the application I get this error:

Exception in thread "main" java.security.AccessControlException: access denied ("java.io.FilePermission" "smalltest.txt" "read")
    at java.security.AccessControlContext.checkPermission(Unknown Source)
    at java.security.AccessController.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkPermission(Unknown Source)
    at java.lang.SecurityManager.checkRead(Unknown Source)
    at java.io.RandomAccessFile.<init>(Unknown Source)
    at etremel.authmatch.text.TextFileFormatter.<init>(TextFileFormatter.java:39)
    at etremel.authmatch.source.PatternMatcherSource.main(PatternMatcherSource.java:302)

Since the file I'm asking it to read (smalltest.txt) is in the "authmatch" project directory, and I explicitly gave my application permission to read that directory with the line

permission java.io.FilePermission "C:/Users/Edward/College/CS197/authmatch/-", "read,write,delete";

why is it still insisting that it doesn't have read permission for the file? I suspect this may be a Windows issue because I have the same project running on a Linux computer and a similar policy file allows it to read from its local project directory just fine.

UPDATE

I ran the server with -Djava.security.debug=access,failure and it generated a bunch of debug messages while parsing the policy file. You can see the entire log at this pastebin, but there seem to be two important parts:

access: access allowed ("java.security.SecurityPermission" "getPolicy")
access: access allowed ("java.io.FilePermission" "C:\Users\Edward\Documents\College\CS197\authmatch\bin" "read")
access: domain that failed ProtectionDomain  (file:/C:/Users/Edward/Documents/College/CS197/authmatch/bin/ <no signer certificates>)
 sun.misc.Launcher$AppClassLoader@74ba86ef
 <no principals>
 java.security.Permissions@7a8a44a6 (
 ("java.io.FilePermission" "\C:\Users\Edward\Documents\College\CS197\authmatch\bin\-" "read")
 ("java.net.SocketPermission" "localhost:1024-" "listen,resolve")
 ...

...and much later:

access: access allowed ("java.io.FilePermission" "C:\Users\Edward\Documents\College\CS197\authmatch\bin\etremel\authmatch\text\TextFileFormatter.class" "read")
access: access allowed ("java.util.PropertyPermission" "user.dir" "read")
access: access denied ("java.io.FilePermission" "smalltest.txt" "read")

It looks like there's some kind of "domain protection" failure because my codebase isn't signed, but I thought it was acceptable to specify a security policy without a signature using the grant codeBase setup. More puzzling, it doesn't look like it ever reads the FilePermission for the root authmatch directory, just the authmatch/bin directory. Then it concludes that it should deny access to "smalltest.txt," but it never resolves the full directory path of that file.

Remember, the same project and policy work fine on Linux.

Was it helpful?

Solution

The issue is between the way you spelt the codebase URL and the way it spells it: file:/C:/Users/Edward/Documents/College/CS197/authmatch/bin/. They aren't the same, so your grant block doesn't apply. Have a look at the content of both the 'domain that failed' printouts: your .policy stuff isn't in there.

The stuff about the signer certificates isn't an error, it is just saying there are no signers associated with the 'domain that failed'.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top