mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-04 12:59:30 +00:00
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:
parent
c8414e5ed1
commit
bcc8a456fc
@ -20,6 +20,7 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.security.AccessControlException;
|
||||
import java.security.CodeSource;
|
||||
import java.security.Permission;
|
||||
import java.security.PermissionCollection;
|
||||
@ -27,151 +28,216 @@ import java.security.Permissions;
|
||||
import java.security.Policy;
|
||||
import java.security.Principal;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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:
|
||||
*
|
||||
* 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) 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 multiple policy files to source permissions from
|
||||
* 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)
|
||||
* 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
|
||||
* multiple policy files to source permissions from
|
||||
*
|
||||
* 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 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
|
||||
* 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
|
||||
* 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
|
||||
{
|
||||
private static boolean __DEBUG = false;
|
||||
|
||||
// Policy files that are actively managed by the aggregate policy mechanism
|
||||
private final Set<String> _policies;
|
||||
|
||||
private final Map<ProtectionDomain, PolicyBlock> pdMapping =
|
||||
Collections.synchronizedMap( new HashMap<ProtectionDomain, PolicyBlock>() );
|
||||
|
||||
private final Map<ProtectionDomain, PolicyBlock> pdMapping = 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 Scanner scanner = new Scanner();
|
||||
private final Scanner scanner = new Scanner();
|
||||
|
||||
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;
|
||||
_context.setProperties( properties );
|
||||
_context.setProperties(properties);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionCollection getPermissions( ProtectionDomain domain )
|
||||
{
|
||||
PermissionCollection perms = new Permissions();
|
||||
|
||||
for ( Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext(); )
|
||||
public PermissionCollection getPermissions(ProtectionDomain domain)
|
||||
{
|
||||
if (!initialized)
|
||||
{
|
||||
ProtectionDomain pd = i.next();
|
||||
|
||||
// System.out.println("----START----");
|
||||
// System.out.println("PDCS: " + pd.getCodeSource());
|
||||
// System.out.println("CS: " + domain.getCodeSource());
|
||||
synchronized (this)
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
if (pd.getCodeSource() == null || pd.getCodeSource().implies(domain.getCodeSource()) && pd.getPrincipals() == null || pd.getCodeSource().implies(domain.getCodeSource()) && validate(pd.getPrincipals(),domain.getPrincipals()))
|
||||
{
|
||||
// gather dynamic permissions
|
||||
if ( pdMapping.get( pd ) != null )
|
||||
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();
|
||||
|
||||
for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();)
|
||||
{
|
||||
ProtectionDomain pd = i.next();
|
||||
|
||||
if (__DEBUG)
|
||||
{
|
||||
for ( Enumeration<Permission> e = pdMapping.get( pd ).getPermissions().elements(); e.hasMoreElements(); )
|
||||
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()))
|
||||
{
|
||||
// gather dynamic permissions
|
||||
if (pdMapping.get(pd) != null)
|
||||
{
|
||||
Permission perm = e.nextElement();
|
||||
// System.out.println("D: " + perm);
|
||||
perms.add(perm);
|
||||
for (Enumeration<Permission> e = pdMapping.get(pd).getPermissions().elements(); e.hasMoreElements();)
|
||||
{
|
||||
Permission perm = e.nextElement();
|
||||
if (__DEBUG)
|
||||
{
|
||||
System.out.println("D: " + perm);
|
||||
}
|
||||
perms.add(perm);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (__DEBUG)
|
||||
{
|
||||
System.out.println("----STOP----");
|
||||
}
|
||||
}
|
||||
// System.out.println("----STOP----");
|
||||
|
||||
_cache.put(domain,perms);
|
||||
return perms;
|
||||
}
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PermissionCollection getPermissions( CodeSource codesource )
|
||||
public PermissionCollection getPermissions(CodeSource codesource)
|
||||
{
|
||||
PermissionCollection perms = new Permissions();
|
||||
|
||||
for ( Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext(); )
|
||||
if (!initialized)
|
||||
{
|
||||
ProtectionDomain pd = i.next();
|
||||
|
||||
if ( pd.getCodeSource() == null || pd.getCodeSource().implies( codesource ) )
|
||||
synchronized (this)
|
||||
{
|
||||
|
||||
// System.out.println("----START----");
|
||||
// System.out.println("PDCS: " + pd.getCodeSource());
|
||||
// System.out.println("CS: " + codesource);
|
||||
|
||||
// gather dynamic permissions
|
||||
if ( pdMapping.get( pd ) != null )
|
||||
{
|
||||
for ( Enumeration<Permission> e = pdMapping.get( pd ).getPermissions().elements(); e.hasMoreElements(); )
|
||||
{
|
||||
Permission perm = e.nextElement();
|
||||
// System.out.println("D: " + perm);
|
||||
perms.add(perm);
|
||||
}
|
||||
}
|
||||
// System.out.println("----STOP----");
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
return perms;
|
||||
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();
|
||||
|
||||
for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();)
|
||||
{
|
||||
ProtectionDomain pd = i.next();
|
||||
|
||||
if (pd.getCodeSource() == null || pd.getCodeSource().implies(codesource))
|
||||
{
|
||||
if (__DEBUG)
|
||||
{
|
||||
System.out.println("----START----");
|
||||
System.out.println("PDCS: " + pd.getCodeSource());
|
||||
System.out.println("CS: " + codesource);
|
||||
}
|
||||
// gather dynamic permissions
|
||||
if (pdMapping.get(pd) != null)
|
||||
{
|
||||
for (Enumeration<Permission> e = pdMapping.get(pd).getPermissions().elements(); e.hasMoreElements();)
|
||||
{
|
||||
Permission perm = e.nextElement();
|
||||
if (__DEBUG)
|
||||
{
|
||||
System.out.println("D: " + perm);
|
||||
}
|
||||
perms.add(perm);
|
||||
}
|
||||
}
|
||||
if (__DEBUG)
|
||||
{
|
||||
System.out.println("----STOP----");
|
||||
}
|
||||
}
|
||||
}
|
||||
_cache.put(codesource,perms);
|
||||
return perms;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean validate( Principal[] permCerts, Principal[] classCerts )
|
||||
private static boolean validate(Principal[] permCerts, Principal[] classCerts)
|
||||
{
|
||||
if ( classCerts == null )
|
||||
if (classCerts == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < permCerts.length; ++i )
|
||||
|
||||
for (int i = 0; i < permCerts.length; ++i)
|
||||
{
|
||||
boolean found = false;
|
||||
for ( int j = 0; j < classCerts.length; ++j )
|
||||
boolean found = false;
|
||||
for (int j = 0; j < classCerts.length; ++j)
|
||||
{
|
||||
if ( permCerts[i].equals( classCerts[j] ) )
|
||||
if (permCerts[i].equals(classCerts[j]))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// if we didn't find the permCert in the classCerts then we don't match up
|
||||
if ( found == false )
|
||||
if (found == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void refresh()
|
||||
{
|
||||
@ -183,70 +249,100 @@ public class JettyPolicy extends Policy
|
||||
initialize();
|
||||
}
|
||||
|
||||
// System.out.println("refreshing policy files");
|
||||
|
||||
if (__DEBUG)
|
||||
{
|
||||
System.out.println("refreshing policy files");
|
||||
}
|
||||
pdMapping.clear();
|
||||
|
||||
for ( Iterator<String> i = _policies.iterator(); i.hasNext(); )
|
||||
for (Iterator<String> i = _policies.iterator(); i.hasNext();)
|
||||
{
|
||||
File policyFile = new File( i.next() );
|
||||
pdMapping.putAll( DefaultPolicyLoader.load( new FileInputStream( policyFile ), _context ) );
|
||||
File policyFile = new File(i.next());
|
||||
pdMapping.putAll(DefaultPolicyLoader.load(new FileInputStream(policyFile),_context));
|
||||
}
|
||||
|
||||
// System.setSecurityManager(null);
|
||||
// Policy.setPolicy(null);
|
||||
|
||||
// Policy.setPolicy(this);
|
||||
// System.setSecurityManager(new SecurityManager());
|
||||
if (__DEBUG)
|
||||
{
|
||||
System.out.println("refreshing policy files");
|
||||
|
||||
// for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();)
|
||||
// {
|
||||
// System.out.println(i.next().toString());
|
||||
// }
|
||||
synchronized (this)
|
||||
{
|
||||
_cache.clear();
|
||||
System.setSecurityManager(null);
|
||||
Policy.setPolicy(null);
|
||||
Policy.setPolicy(this);
|
||||
System.setSecurityManager(new SecurityManager());
|
||||
}
|
||||
|
||||
// System.setSecurityManager(null);
|
||||
// Policy.setPolicy(null);
|
||||
// Policy.setPolicy(this);
|
||||
// System.setSecurityManager(new SecurityManager());
|
||||
|
||||
for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();)
|
||||
{
|
||||
System.out.println(i.next().toString());
|
||||
}
|
||||
|
||||
System.out.println("finished reloading policies");
|
||||
}
|
||||
}
|
||||
catch ( Exception e )
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* TODO make this optional
|
||||
*/
|
||||
private void initialize() throws Exception
|
||||
{
|
||||
/*
|
||||
* List scanDirs = new ArrayList();
|
||||
*
|
||||
* for (Iterator<String> i = _policies.iterator(); i.hasNext();) { File policyFile = new File(i.next()); scanDirs.add(policyFile.getParentFile()); }
|
||||
*
|
||||
* scanner.addListener(new Scanner.DiscreteListener() {
|
||||
*
|
||||
* public void fileRemoved(String filename) throws Exception { // TODO Auto-generated method stub
|
||||
*
|
||||
* }
|
||||
*
|
||||
* 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);
|
||||
*/
|
||||
|
||||
List scanDirs = new ArrayList();
|
||||
|
||||
for (Iterator<String> i = _policies.iterator(); i.hasNext();)
|
||||
{
|
||||
File policyFile = new File(i.next());
|
||||
scanDirs.add(policyFile.getParentFile());
|
||||
}
|
||||
|
||||
scanner.addListener(new Scanner.DiscreteListener()
|
||||
{
|
||||
|
||||
public void fileRemoved(String filename) throws Exception
|
||||
{ // TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public void dump( PrintStream out )
|
||||
public void dump(PrintStream out)
|
||||
{
|
||||
PrintWriter write = new PrintWriter( out );
|
||||
PrintWriter write = new PrintWriter(out);
|
||||
write.println("dumping policy settings");
|
||||
|
||||
for( Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext(); )
|
||||
|
||||
for (Iterator<ProtectionDomain> i = pdMapping.keySet().iterator(); i.hasNext();)
|
||||
{
|
||||
ProtectionDomain domain = i.next();
|
||||
PolicyBlock block = pdMapping.get( domain );
|
||||
write.println(domain.toString());
|
||||
PolicyBlock block = pdMapping.get(domain);
|
||||
write.println(domain.toString());
|
||||
}
|
||||
write.flush();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user