lundi 17 septembre 2018

Creating dynamic security policies for Security Manager

I am currently developing a way of adding 'plugins' or 'apps' to my platform. The general concept is, the developer creates a .jar file, which returns a JPanel when instanced:

appLoader = URLClassLoader.newInstance(new URL[] { someDownloadUrl });
appBuilder = appLoader.loadClass("iezon.app." + someAppName);

I created a AppSecurityManager class to do the processing of the jar file before creating the instance to ensure that their are no socket connections, file reading etc being executed inside the jar file. This is what my default policy looks like:

grant {
    permission java.lang.RuntimePermission "setSecurityManager";
    permission java.lang.RuntimePermission "createSecurityManager";
    permission java.lang.RuntimePermission "usePoliciy";
}

Which works fine when I do this:

System.setProperty("java.security.policy", "file:/C:/Temp/default.policy");
System.setSecurityManager(new SecurityManager());
JPanel panel = (JPanel) appBuilder.newInstance();
System.setSecurityManager(null);
return panel;

However, I want to be able to run a method appBuilder.getMethod("getPermissions").invoke(this, null); which then returns an ArrayList of permissions that jar file needs for the security manager which then the user must agree to before the jar file can create an instance.

I have tried creating a new policy with the app name in the security manager which is called from the policy acceptance panel when the user accepts:

public static void createPolicy(ArrayList<String> policies, App app) {

    try {
        FileWriter fileWriter =
                new FileWriter("C:/Temp/" + app.getName() + ".policy");
        BufferedWriter bufferedWriter =
                new BufferedWriter(fileWriter);

        bufferedWriter.write("grant {");
        bufferedWriter.newLine();

        for(String policy : policies) {
            bufferedWriter.write("    permission java.lang.RuntimePermission \"" + policy + "\";");
            bufferedWriter.newLine();
        }

        bufferedWriter.write("}");
        bufferedWriter.close();

    } catch(IOException ex) {
        ex.printStackTrace();
    }
}

This works fine and all the default policy permissions got wrote into the dynamically made file, however, when I then launch the app:

System.setProperty("java.security.policy", "file:/C:/Temp/" + app.getName() + ".policy");
System.setSecurityManager(new SecurityManager());
JPanel panel = (JPanel) app.getObject().newInstance();
System.setSecurityManager(null);
return panel;

The SecurityManager throws a SecurityException for the setSecurityManager().

Any help would be extremely appreciated where I am going wrong with dynamically building the policy.





Aucun commentaire:

Enregistrer un commentaire