0

I have seem to have run into a bit of a problem. I have thoroughly researched this topic, and have not found any solutions.

I have a main java program, the "Server" for example, that imports java .jar "plugin" using this method: How to load Classes at runtime from a folder or JAR?

Now, hypothetically a plugin could run and affect other plugin's config files/system files.

I have looked into SecurityManager, but I can't grab what Object is trying to access said permission.

I noticed that I can use Java policy files to limit classes/codeBases to certain permissions. The end goal is to allow each plugin to their own dir (which we can safely assume is created already), and limit other certain permissions.

I have used the following policy file to see if I could possibly use codeBase for a path inside a jar file,however it does not seem to work.

For a example: In policy.pol:

grant codeBase "jar:file:C:\Users\100048201\git\BotServ\run\plugins\myPlugin.jar!/"{
permission java.io.FilePermission "C:\Users\100048201\git\BotServ\run\-", "read,write";
permission java.io.FilePermission "run\plugins\lol.txt", "read,write";
};

..I can use the following code to set the Policy in runtime.

System.setProperty("java.security.policy", "policy.pol");
java.security.Policy.getPolicy().refresh();
System.setSecurityManager(new SecurityManager());

The following code is in a class called "Main" in myPlugin.jar

File f = new File("run/plugins/lol.txt");
        try {
            f.createNewFile();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

When I use reflection to run the code above, the following exceptions occur:

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at MainClass.finish(MainClass.java:102)
    at MainClass.loadClasses(MainClass.java:87)
    at MainClass.main(MainClass.java:26)
Caused by: java.security.AccessControlException: access denied ("java.io.FilePermission" "run\plugins\lol.txt" "write")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
    at java.security.AccessController.checkPermission(AccessController.java:884)
    at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
    at java.lang.SecurityManager.checkWrite(SecurityManager.java:979)
    at java.io.File.createNewFile(File.java:1008)
    at com.myththewolf.e621bot.Main.onEnable(Main.java:21)
    ... 7 more

Is there something I am doing wrong? Is there a better way of achieving the desired goal? Any information is greatly appreciated!

Myth Da Wolf
  • 23
  • 1
  • 7
  • Are you _sure_ that it's writing to a path inside the directory you've set the permissions for? Add a debug line to print the full path of the file before you create it. – teppic Oct 02 '17 at 23:33
  • I use getClass().getProtectionDomain().getCodeSource() to generate the permission paths stated above, and File.getAbsolutePath() prints to correct path – Myth Da Wolf Oct 02 '17 at 23:37
  • Try `"C:\\Users\\100048201\\git\\BotServ\\run\\-"`. The [doc](http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html#FileSyntax) has a "Note Regarding File Path Specifications on Windows Systems" that says "you need to include two backslashes for each actual single backslash in the path". – teppic Oct 03 '17 at 00:03
  • Will do! Ill write back in a second – Myth Da Wolf Oct 03 '17 at 00:04
  • @teppic I did try that, and that does work if I put it in a plain grant{ }. However, the codeBase still doesn't work. I tried adding double slashes to that as well. – Myth Da Wolf Oct 03 '17 at 00:07
  • The codebase has to use forward slashes. – teppic Oct 03 '17 at 00:09
  • Oh!! I am so dumb. I will attempt this now – Myth Da Wolf Oct 03 '17 at 00:14
  • Nope,still nothing – Myth Da Wolf Oct 03 '17 at 00:17
  • 1
    There's a mismatch between the `CodeSource` of the `ProtectionDomain` being authorized, and the code source (`codeBase` URL in the `Policy` configuration) being assigned the `Permission`s; the latter has to `implies(CodeSource)` the former. Running with `-Djava.security.debug=access,failure` will help you figure out the proper URL (or actually check what `Class.getProtectionDomain().getCodeSource().getLocation()` returns). Alternatively, you can as well bundle a config template with your app, replace any URLs at runtime, and save the result to a temp file for the policy provider to pick up. – Uux Oct 04 '17 at 06:38

0 Answers0