0

I'm having a problem with extensions, privileges, permissions, and the SecurityManager in Java. I'm using a SecurityManager because I'm using RMI, but that doesn't really come into this. If I can just get to the point where I'm dealing with RMI issues, I'll be thrilled. My IDE is Eclipse, if that's important. I have two eclipse projects, Auxionr and AuxionrCommon.

The source file Auxionr.java is in the package com.auxionr.ui and the project Auxionr. It contains the main() method I'm trying to run. That main method is this:

public static void main(String[] args)
{
        Util.setupSecurity();
        try {
            DriveUtils.findAuctionDrive();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        ApplicationCore appCore = new ApplicationCore();
        @SuppressWarnings("unused")
        Auxionr auxionr = new Auxionr(appCore);
    }

(Note: The try-catch block with the FileNotFoundException is irrelevant for the purpose of this question. You'll see why in a moment.)

The source file Util.java is in the package com.auxionr and is in the project AuxionrCommon. It contains the method:

public static void setupSecurity()
    {
        if (System.getSecurityManager() == null)
        {
            System.setProperty("java.security.policy", "resources" + File.separator + "auxionr.policy");
            System.setSecurityManager(new SecurityManager());
        }
    }

The source file DriveUtils is in the package com.auxionr and is in the project AuxionrCommon. It contains the method:

public static File findAuctionDrive() throws FileNotFoundException
    {
        System.getSecurityManager().checkRead("F:/"); //throws an exception on runtime
        File[] roots = File.listRoots();
        for (File root : roots)
        {
            if (!root.exists())
                continue;
            File f = new File(root.getAbsolutePath() + File.separator + "auxionr.properties");
            if (!f.exists())
                continue;
            Properties props = new Properties();
            try {
                props.load(new FileInputStream(f));
                if (props.getProperty("stores").equals("auctions") || props.getProperty("stores").equals("both"))
                    return root;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        throw new FileNotFoundException("No flashdrive found formatted for Auxionr Auction storage use.");
    }

The .policy file resources/auxionr.policy is:

/* AUTOMATICALLY GENERATED ON Fri Sep 16 14:28:24 EDT 2016*/
/* DO NOT EDIT */

grant codeBase "file:/E:/Java/Auxionr/" {
  permission java.security.AllPermission;
};

grant codeBase "file:/E:/Java/AuxionrCommo,n/" {
  permission java.security.AllPermission;
};

I have checked and this file is formatted, loaded, etc. properly.

Some of my project settings: The build path for the project 'Auxionr' The classpath for the project 'Auxionr's run configuration

From my reading on the Java documentation and elsewhere on Stack Overflow I've worked out that I need to wrap my the code in the extension (Everything in AuxionrCommon... right?) in

AccessControl.doPrivileged(new PrivilegedAction()<Object>{
public Object run(){
//code
}
});

But I've tried various versions of this and the call to System.getSecurityManager().checkRead("F:/") in findAuctionDrive() always throws:

Exception in thread "main" java.security.AccessControlException: access denied ("java.io.FilePermission" "F:/" "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 com.auxionr.DriveUtils.findAuctionDrive(DriveUtils.java:87)
at com.auxionr.ui.Auxionr.main(Auxionr.java:71)

So the question is: Where do I put the AccessControl.doPrivileged to make the code inside findAuctionDrive() have the proper permissions?

JDeveloper
  • 91
  • 2
  • 11
  • Was the typo in your second `grant` policy statement's URI the cause? Also, since you've essentially granted "everything to everybody" (and assuming no third-party code gets on the call stack) there's no need for privileged blocks. – Uux Oct 10 '16 at 12:57
  • Yeah, that was a typo, it's not in the actual policy file. – JDeveloper Oct 10 '16 at 16:16
  • @Uux so if there's no need for privileged blocks, what's my problem? – JDeveloper Oct 10 '16 at 16:16
  • a few guesses: a) the value of `java.security.policy` must be a URL, and/or b) the grant statements' respective URLs must end with `/-` so as to include subdirs, and/or c) you've hit one of those Windows file: URL quirks. – Uux Oct 11 '16 at 12:53
  • Regarding privileged block use, the typical situation you'll need one in is when some method of yours, *M1*, needs to invoke a "privileged" method, *M2* (i.e., any method calling `SecurityManager`/`AccessController#checkXXX`), in a context where *at least one* of *M1*'s callers (i.e., their respective classes' `ProtectionDomain`s) has not been granted the `Permission` required by *M2*. Obviously, for the privileged operation to succeed, both *M1* and *M2* must themselves have been granted said `Permission`. – Uux Oct 11 '16 at 13:21
  • @Uux a) I've read tutorials elsewhere on the internet that use strings for `java.security.policy b) I tried that, and it didn't help c) I'm currently using a linux machine, so it's not a windows problem – JDeveloper Oct 11 '16 at 19:26
  • I meant that the value of that property is supposed to be (the string representation of) a URL, not a path ([ref](http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html)). I'm pretty sure your policy is just not loaded. – Uux Oct 11 '16 at 23:10
  • `public static void setupSecurity() { try { if (System.getSecurityManager() == null) { URL url = new File("resources" + File.separator + "auxionr.policy").toURI().toURL(); System.setProperty("java.security.policy", url.toString()); System.setSecurityManager(new SecurityManager()); } } catch (MalformedURLException e) { e.printStackTrace(); } }` You mean like that? It still doesn't work. I may have misunderstood, though. – JDeveloper Oct 13 '16 at 01:19
  • Correct... kinda. You're not packaging in a JAR, thus `new File("some relative path").toURI().toURL()` won't, generally speaking, produce a `URL` pointing to your actual policy file (just sys-out the URL to see what I mean). Either use an *absolute* path and get the URL representation thereof, or have your `ClassLoader` do it for you (e.g. `Util.class.getClassLoader().getResource("auxionr.policy")`). – Uux Oct 13 '16 at 09:46
  • It also goes without saying that, in order for the second approach to be effective, the policy file must be on the class path. For a standard Eclipse Java project that means that your "resources" dir must have either been declared of type "source folder" upon creation, or manually added to the class path subsequently, by whatever means. – Uux Oct 13 '16 at 10:29
  • `public static void setupSecurity() { if (System.getSecurityManager() == null) { URL url = Util.class.getClassLoader().getResource("auxionr.policy"); System.setProperty("java.security.policy", url.toString()); System.setSecurityManager(new SecurityManager()); } }`? Still doesn't work. And I checked in the debugger - the url is right. It just still throws the AccessControlException – JDeveloper Oct 13 '16 at 21:09
  • Run the app with `-Djava.security.debug=policy,access` and post/attach the output here. – Uux Oct 14 '16 at 08:08
  • `Exception in thread "main" java.security.AccessControlException: access denied ("java.io.FilePermission" "C:/" "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 com.auxionr.Util.checkSecurity(Util.java:181) at com.auxionr.ui.Auxionr.main(Auxionr.java:64)` – JDeveloper Oct 15 '16 at 18:30
  • I need the debug output *before* the stack trace. When you run your app with the aforementioned property, you'll see a bunch of policy initialization-/evaluation-/enforcement-related messages in your console (or wherever you've redirected `System.err` to), preceding the stack trace. Please provide those. – Uux Oct 15 '16 at 21:34
  • Ohhhh... my bad; I had put it in the program arguements instead of the VM arguements... The messages don't fit here, so I put them in [this google doc](https://docs.google.com/document/d/1EBTi7IijCvtIVMFboyrB0YnSrvn4ZysWqFmTOwPVAh4/edit?usp=sharing) – JDeveloper Oct 15 '16 at 22:34
  • ...which brings us back to the validity of the grant statements' URLs--they need to match the corresponding `ProtectionDomain`s', i.e., the Java .class files' directories', URLs. According to the output, your loaded policy (at `file:/media/joshua/JEL/Java/AuxionrCommon/bin/auxionr.policy`) does indeed grant `AllPermission` but to `file:/E:/Java/Auxionr/` and `file:/E:/Java/AuxionrCommon/`, rather than (presumably) `file:/media/joshua/JEL/Java/Auxionr/-` and `file:/media/joshua/JEL/Java/AuxionrCommon/-`, respectively, as it should. – Uux Oct 16 '16 at 17:34

0 Answers0