1

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.

Edward
  • 5,942
  • 4
  • 38
  • 55
  • 1
    Run it with `-Djava.security-debug=access,failure` and you will see exactly what is going on. Post the last bit of it here, the bit that encompasses the failure. But you don't really need a `SecurityManager` in an RMI server, unless the client is using the java.rmi.server.codebase feature to supply the server with .class files. – user207421 Oct 29 '12 at 23:08

1 Answers1

2

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'.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I changed the first line of server.policy to `grant codeBase "file:/C:/Users/Edward/College/CS197/authmatch/bin/-"` and the VM runtime parameter to `-Djava.rmi.server.codebase=file:/C:/Users/Edward/Documents/College/CS197/authmatch/bin/`, but this didn't seem to make a difference - I get the exact same "domain that failed" errors in the debug printout. – Edward Oct 30 '12 at 22:39
  • @Edward Do you really need the - in the codebase string? Surely this directory either contains lots of .jar files or is the head of a package structure? What happens when you try it as listed in the 'domain that failed' log? – user207421 Oct 31 '12 at 10:05
  • I got rid of the "-" and that didn't change anything. Then I tried copying and pasting from the log listing "domain that failed" and it worked. It turns out there was a typo in the path I used in the `codeBase` line -- note that it doesn't include the "Documents" folder, while the actual codebase path does. Well, I feel dumb. – Edward Nov 02 '12 at 05:36
  • 1
    @Edward So basically the first sentence in my answer is correct? – user207421 Nov 03 '12 at 21:39