How to programmatically grant AllPermissions
to an RMI application without using policy file?
UPDATE:
After some researching, I have written this custom Policy Class and installed it via Policy.setPolicy(new MyPolicy())
.
Now I get the following error:
invalid permission: (java.io.FilePermission
\C:\eclipse\plugins\org.eclipse.osgi_3.7.0.v20110613.jar read
class MyPolicy extends Policy {
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return (new AllPermission()).newPermissionCollection();
}
}
Based on @EJP's advice, I have debugged using -Djava.security.debug=access
and found all the needed permissions in a policy file :
grant { permission java.net.SocketPermission "*:1024-", "connect,
resolve"; };
grant { permission java.util.PropertyPermission "*", "read, write";
};
grant { permission java.io.FilePermission "<>", "read";
};
But because I didn't want to create a policy file, I found a way to replicate this programmatically by extending java.security.Policy
class and setting the policy at the startup of my application using Policy.setPolicy(new MinimalPolicy());
public class MinimalPolicy extends Policy {
private static PermissionCollection perms;
public MinimalPolicy() {
super();
if (perms == null) {
perms = new MyPermissionCollection();
addPermissions();
}
}
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
return perms;
}
private void addPermissions() {
SocketPermission socketPermission = new SocketPermission("*:1024-", "connect, resolve");
PropertyPermission propertyPermission = new PropertyPermission("*", "read, write");
FilePermission filePermission = new FilePermission("<<ALL FILES>>", "read");
perms.add(socketPermission);
perms.add(propertyPermission);
perms.add(filePermission);
}
}
class MyPermissionCollection extends PermissionCollection {
private static final long serialVersionUID = 614300921365729272L;
ArrayList<Permission> perms = new ArrayList<Permission>();
public void add(Permission p) {
perms.add(p);
}
public boolean implies(Permission p) {
for (Iterator<Permission> i = perms.iterator(); i.hasNext();) {
if (((Permission) i.next()).implies(p)) {
return true;
}
}
return false;
}
public Enumeration<Permission> elements() {
return Collections.enumeration(perms);
}
public boolean isReadOnly() {
return false;
}
}
Because your
new AllPermission()).newPermissionCollection()
is treated by Java as immutable (why add permissions to a collection that already allows all permissions?), and because Java will try to add permissions to the collection. That's where the error message comes from - Java tried to add a java.io.FilePermission to your AllPermission.
Instead, do this:
class MyPolicy extends Policy {
@Override
public PermissionCollection getPermissions(CodeSource codesource) {
Permissions p = new Permissions();
p.add(new PropertyPermission("java.class.path", "read"));
p.add(new FilePermission("/home/.../classes/*", "read"));
... etc ...
return p;
}
}
Don't install the SecurityManager. You only need it if you're using the codebase feature, and if you need that you need a proper .policy file,
Short solution
Extend your updated solution to:
public class MyPolicy extends Policy
{
@Override
public PermissionCollection getPermissions(CodeSource codesource)
{
Permissions p = new Permissions();
p.add(new AllPermission());
return p;
}
}
Consider, that Policy.getPermissions() must always return a mutable PermissionCollection
Returns: ...If this operation is supported, the returned set of permissions must be a new mutable instance and it must support heterogeneous Permission types...
This solution works already, since it adds an AllPermission object into every call of the Policy.getPermissions(ProtectionDomain)
, that refers to Policy.getPermissions(CodeSource)
.
Clean solution
But there is a cleaner solution, that doesn't track any unnecessary other Permissions, since AllPermissions allows pretty everything already.
public class MyPolicy extends Policy
{
private static class AllPermissionsSingleton extends PermissionCollection
{
private static final long serialVersionUID = 1L;
private static final Vector<Permission> ALL_PERMISSIONS_VECTOR = new Vector<Permission>(Arrays.asList(new AllPermission()));
@Override
public void add(Permission permission)
{
}
@Override
public boolean implies(Permission permission)
{
return true;
}
@Override
public Enumeration<Permission> elements()
{
return ALL_PERMISSIONS_VECTOR.elements();
}
@Override
public boolean isReadOnly()
{
return false;
}
}
private static final AllPermissionsSingleton ALL_PERMISSIONS_SINGLETON = new AllPermissionsSingleton();
@Override
public PermissionCollection getPermissions(CodeSource codesource)
{
return ALL_PERMISSIONS_SINGLETON;
}
}