add in debugging for jettyPolicy that outputs to system.out since normal logging is not appropriate for this sort of goop

git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@723 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
Jesse McConnell 2009-08-14 17:55:35 +00:00
parent c8414e5ed1
commit bcc8a456fc

View File

@ -20,6 +20,7 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.security.AccessControlException;
import java.security.CodeSource; import java.security.CodeSource;
import java.security.Permission; import java.security.Permission;
import java.security.PermissionCollection; import java.security.PermissionCollection;
@ -27,52 +28,59 @@ import java.security.Permissions;
import java.security.Policy; import java.security.Policy;
import java.security.Principal; import java.security.Principal;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.eclipse.jetty.policy.loader.DefaultPolicyLoader; import org.eclipse.jetty.policy.loader.DefaultPolicyLoader;
import org.eclipse.jetty.util.Scanner;
/** /**
* Policy implementation that will load a set of policy files and manage the mapping of permissions and protection domains * Policy implementation that will load a set of policy files and manage the mapping of permissions and protection domains
* *
* The reason I created this class and added this mechanism are: * The reason I created this class and added this mechanism are:
* *
* 1) I wanted a way to be able to follow the startup mechanic that jetty uses with jetty-start using OPTIONS=policy,default * 1) I wanted a way to be able to follow the startup mechanic that jetty uses with jetty-start using OPTIONS=policy,default to be able to startup a security manager and policy implementation without have to rely on the existing JVM cli options 2)
* to be able to startup a security manager and policy implementation without have to rely on the existing JVM cli options * establish a starting point to add on further functionality to permissions based security with jetty like jmx enabled permission tweaking or runtime creation and specification of policies for specific webapps 3) I wanted to have support for specifying
* 2) establish a starting point to add on further functionality to permissions based security with jetty like jmx enabled * multiple policy files to source permissions from
* permission tweaking or runtime creation and specification of policies for specific webapps
* 3) I wanted to have support for specifying multiple policy files to source permissions from
* *
* Possible additions are: * Possible additions are: - directories of policy file support - jmx enabled a la #2 above - proxying of system security policy where we can proxy access to the system policy should the jvm have been started with one, I had support for this but ripped it
* - directories of policy file support * out to add in again later - merging of protection domains if process multiple policy files that declare permissions for the same codebase - an xml policy file parser, had originally added this using modello but tore it out since it would have been a
* - jmx enabled a la #2 above * nightmare to get its dependencies through IP validation, could do this with jvm xml parser instead sometime - check performance of the synch'd map I am using for the protection domain mapping
* - proxying of system security policy where we can proxy access to the system policy should the jvm have been started with
* one, I had support for this but ripped it out to add in again later
* - merging of protection domains if process multiple policy files that declare permissions for the same codebase
* - an xml policy file parser, had originally added this using modello but tore it out since it would have been
* a nightmare to get its dependencies through IP validation, could do this with jvm xml parser instead sometime
* - check performance of the synch'd map I am using for the protection domain mapping
*/ */
public class JettyPolicy extends Policy public class JettyPolicy extends Policy
{ {
private static boolean __DEBUG = false;
// Policy files that are actively managed by the aggregate policy mechanism // Policy files that are actively managed by the aggregate policy mechanism
private final Set<String> _policies; private final Set<String> _policies;
private final Map<ProtectionDomain, PolicyBlock> pdMapping = private final Map<ProtectionDomain, PolicyBlock> pdMapping = Collections.synchronizedMap(new HashMap<ProtectionDomain, PolicyBlock>());
Collections.synchronizedMap( new HashMap<ProtectionDomain, PolicyBlock>() );
private final Map<Object, PermissionCollection> _cache = new HashMap<Object, PermissionCollection>(); // Object can be ProtectionDomain or CodeSource
private final PolicyContext _context = new PolicyContext(); private final PolicyContext _context = new PolicyContext();
// private final Scanner scanner = new Scanner(); private final Scanner scanner = new Scanner();
private boolean initialized = false; private boolean initialized = false;
public JettyPolicy(Set<String> policies, Map<String, String> properties) public JettyPolicy(Set<String> policies, Map<String, String> properties)
{ {
try
{
__DEBUG = Boolean.getBoolean("org.eclipse.jetty.policy.DEBUG");
}
catch (AccessControlException ace)
{
__DEBUG = false;
}
_policies = policies; _policies = policies;
_context.setProperties(properties); _context.setProperties(properties);
@ -82,15 +90,38 @@ public class JettyPolicy extends Policy
@Override @Override
public PermissionCollection getPermissions(ProtectionDomain domain) public PermissionCollection getPermissions(ProtectionDomain domain)
{ {
if (!initialized)
{
synchronized (this)
{
refresh();
}
}
if (_cache.containsKey(domain))
{
if (__DEBUG)
{
System.out.println("Pulling from a cache for " + domain.getCodeSource().getLocation() + " with " + _cache.size() + " entries");
}
return _cache.get(domain);
}
else
{
PermissionCollection perms = new Permissions(); PermissionCollection perms = new Permissions();
for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();) for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();)
{ {
ProtectionDomain pd = i.next(); ProtectionDomain pd = i.next();
// System.out.println("----START----"); if (__DEBUG)
// System.out.println("PDCS: " + pd.getCodeSource()); {
// System.out.println("CS: " + domain.getCodeSource()); System.out.println("----START----");
System.out.println("PDCS: " + pd.getCodeSource());
System.out.println("CS: " + domain.getCodeSource());
}
if (pd.getCodeSource() == null || pd.getCodeSource().implies(domain.getCodeSource()) && pd.getPrincipals() == null || pd.getCodeSource().implies(domain.getCodeSource()) && validate(pd.getPrincipals(),domain.getPrincipals())) if (pd.getCodeSource() == null || pd.getCodeSource().implies(domain.getCodeSource()) && pd.getPrincipals() == null || pd.getCodeSource().implies(domain.getCodeSource()) && validate(pd.getPrincipals(),domain.getPrincipals()))
{ {
@ -100,19 +131,45 @@ public class JettyPolicy extends Policy
for (Enumeration<Permission> e = pdMapping.get(pd).getPermissions().elements(); e.hasMoreElements();) for (Enumeration<Permission> e = pdMapping.get(pd).getPermissions().elements(); e.hasMoreElements();)
{ {
Permission perm = e.nextElement(); Permission perm = e.nextElement();
// System.out.println("D: " + perm); if (__DEBUG)
{
System.out.println("D: " + perm);
}
perms.add(perm); perms.add(perm);
} }
} }
} }
// System.out.println("----STOP----"); if (__DEBUG)
{
System.out.println("----STOP----");
}
} }
_cache.put(domain,perms);
return perms; return perms;
} }
}
@Override @Override
public PermissionCollection getPermissions(CodeSource codesource) public PermissionCollection getPermissions(CodeSource codesource)
{
if (!initialized)
{
synchronized (this)
{
refresh();
}
}
if (_cache.containsKey(codesource))
{
if (__DEBUG)
{
System.out.println("Pulling from a cache for " + codesource.getLocation() + " with " + _cache.size() + " entries");
}
return _cache.get(codesource);
}
else
{ {
PermissionCollection perms = new Permissions(); PermissionCollection perms = new Permissions();
@ -122,26 +179,35 @@ public class JettyPolicy extends Policy
if (pd.getCodeSource() == null || pd.getCodeSource().implies(codesource)) if (pd.getCodeSource() == null || pd.getCodeSource().implies(codesource))
{ {
if (__DEBUG)
// System.out.println("----START----"); {
// System.out.println("PDCS: " + pd.getCodeSource()); System.out.println("----START----");
// System.out.println("CS: " + codesource); System.out.println("PDCS: " + pd.getCodeSource());
System.out.println("CS: " + codesource);
}
// gather dynamic permissions // gather dynamic permissions
if (pdMapping.get(pd) != null) if (pdMapping.get(pd) != null)
{ {
for (Enumeration<Permission> e = pdMapping.get(pd).getPermissions().elements(); e.hasMoreElements();) for (Enumeration<Permission> e = pdMapping.get(pd).getPermissions().elements(); e.hasMoreElements();)
{ {
Permission perm = e.nextElement(); Permission perm = e.nextElement();
// System.out.println("D: " + perm); if (__DEBUG)
{
System.out.println("D: " + perm);
}
perms.add(perm); perms.add(perm);
} }
} }
// System.out.println("----STOP----"); if (__DEBUG)
{
System.out.println("----STOP----");
} }
} }
}
_cache.put(codesource,perms);
return perms;
}
return perms;
} }
private static boolean validate(Principal[] permCerts, Principal[] classCerts) private static boolean validate(Principal[] permCerts, Principal[] classCerts)
@ -183,8 +249,10 @@ public class JettyPolicy extends Policy
initialize(); initialize();
} }
// System.out.println("refreshing policy files"); if (__DEBUG)
{
System.out.println("refreshing policy files");
}
pdMapping.clear(); pdMapping.clear();
for (Iterator<String> i = _policies.iterator(); i.hasNext();) for (Iterator<String> i = _policies.iterator(); i.hasNext();)
@ -193,16 +261,31 @@ public class JettyPolicy extends Policy
pdMapping.putAll(DefaultPolicyLoader.load(new FileInputStream(policyFile),_context)); pdMapping.putAll(DefaultPolicyLoader.load(new FileInputStream(policyFile),_context));
} }
if (__DEBUG)
{
System.out.println("refreshing policy files");
synchronized (this)
{
_cache.clear();
System.setSecurityManager(null);
Policy.setPolicy(null);
Policy.setPolicy(this);
System.setSecurityManager(new SecurityManager());
}
// System.setSecurityManager(null); // System.setSecurityManager(null);
// Policy.setPolicy(null); // Policy.setPolicy(null);
// Policy.setPolicy(this); // Policy.setPolicy(this);
// System.setSecurityManager(new SecurityManager()); // System.setSecurityManager(new SecurityManager());
// for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();) for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();)
// { {
// System.out.println(i.next().toString()); System.out.println(i.next().toString());
// } }
System.out.println("finished reloading policies");
}
} }
catch (Exception e) catch (Exception e)
{ {
@ -215,25 +298,38 @@ public class JettyPolicy extends Policy
*/ */
private void initialize() throws Exception private void initialize() throws Exception
{ {
/*
* List scanDirs = new ArrayList(); List scanDirs = new ArrayList();
*
* for (Iterator<String> i = _policies.iterator(); i.hasNext();) { File policyFile = new File(i.next()); scanDirs.add(policyFile.getParentFile()); } for (Iterator<String> i = _policies.iterator(); i.hasNext();)
* {
* scanner.addListener(new Scanner.DiscreteListener() { File policyFile = new File(i.next());
* scanDirs.add(policyFile.getParentFile());
* public void fileRemoved(String filename) throws Exception { // TODO Auto-generated method stub }
*
* } scanner.addListener(new Scanner.DiscreteListener()
* {
* public void fileChanged(String filename) throws Exception { refresh(); }
* public void fileRemoved(String filename) throws Exception
* public void fileAdded(String filename) throws Exception { // TODO Auto-generated method stub { // TODO Auto-generated method stub
*
* } }); }
*
* scanner.setScanDirs(scanDirs); scanner.start(); scanner.setScanInterval(10); public void fileChanged(String filename) throws Exception
*/ {
refresh();
}
public void fileAdded(String filename) throws Exception
{ // TODO Auto-generated method stub
}
});
scanner.setScanDirs(scanDirs);
scanner.start();
scanner.setScanInterval(10);
initialized = true; initialized = true;
} }