refactored policy parsing for clarity and to decompose the more complex resolveFoo mechanic
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@443 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
d71050fa73
commit
1d13e96704
|
@ -59,13 +59,15 @@ public class JettyPolicy extends Policy
|
||||||
|
|
||||||
private PropertyEvaluator _evaluator;
|
private PropertyEvaluator _evaluator;
|
||||||
|
|
||||||
private Map<ProtectionDomain, PermissionCollection> pdMapping =
|
private Map<ProtectionDomain, PolicyEntry> pdMapping =
|
||||||
Collections.synchronizedMap( new HashMap<ProtectionDomain, PermissionCollection>() );
|
Collections.synchronizedMap( new HashMap<ProtectionDomain, PolicyEntry>() );
|
||||||
|
|
||||||
|
private PolicyContext _context = new PolicyContext();
|
||||||
|
|
||||||
public JettyPolicy( Set<String> policies, Map<String,String> properties )
|
public JettyPolicy( Set<String> policies, Map<String,String> properties )
|
||||||
{
|
{
|
||||||
_policies = policies;
|
_policies = policies;
|
||||||
_evaluator = new PropertyEvaluator( properties );
|
_context.setEvaluator( new PropertyEvaluator( properties ) );
|
||||||
|
|
||||||
// we have the policies we need and an evaluator to reference, lets refresh and save the user a call.
|
// we have the policies we need and an evaluator to reference, lets refresh and save the user a call.
|
||||||
refresh();
|
refresh();
|
||||||
|
@ -84,7 +86,7 @@ public class JettyPolicy extends Policy
|
||||||
// gather dynamic permissions
|
// gather dynamic permissions
|
||||||
if ( pdMapping.get( pd ) != null )
|
if ( pdMapping.get( pd ) != null )
|
||||||
{
|
{
|
||||||
for ( Enumeration<Permission> e = pdMapping.get( pd ).elements(); e.hasMoreElements(); )
|
for ( Enumeration<Permission> e = pdMapping.get( pd ).getPermissions().elements(); e.hasMoreElements(); )
|
||||||
{
|
{
|
||||||
perms.add( e.nextElement() );
|
perms.add( e.nextElement() );
|
||||||
}
|
}
|
||||||
|
@ -117,7 +119,7 @@ public class JettyPolicy extends Policy
|
||||||
// gather dynamic permissions
|
// gather dynamic permissions
|
||||||
if ( pdMapping.get( pd ) != null )
|
if ( pdMapping.get( pd ) != null )
|
||||||
{
|
{
|
||||||
for ( Enumeration<Permission> e = pdMapping.get( pd ).elements(); e.hasMoreElements(); )
|
for ( Enumeration<Permission> e = pdMapping.get( pd ).getPermissions().elements(); e.hasMoreElements(); )
|
||||||
{
|
{
|
||||||
perms.add( e.nextElement() );
|
perms.add( e.nextElement() );
|
||||||
}
|
}
|
||||||
|
@ -174,7 +176,7 @@ public class JettyPolicy extends Policy
|
||||||
for ( Iterator<String> i = _policies.iterator(); i.hasNext(); )
|
for ( Iterator<String> i = _policies.iterator(); i.hasNext(); )
|
||||||
{
|
{
|
||||||
File policyFile = new File( i.next() );
|
File policyFile = new File( i.next() );
|
||||||
pdMapping.putAll( DefaultPolicyLoader.load( new FileInputStream( policyFile ), _evaluator ) );
|
pdMapping.putAll( DefaultPolicyLoader.load( new FileInputStream( policyFile ), _context ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( Exception e )
|
catch ( Exception e )
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package org.eclipse.jetty.policy;
|
||||||
|
|
||||||
|
import java.security.KeyStore;
|
||||||
|
|
||||||
|
public class PolicyContext
|
||||||
|
{
|
||||||
|
private PropertyEvaluator evaluator;
|
||||||
|
|
||||||
|
private KeyStore keystore;
|
||||||
|
|
||||||
|
public PolicyContext()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public PolicyContext( PropertyEvaluator evaluator )
|
||||||
|
{
|
||||||
|
this.evaluator = evaluator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyEvaluator getEvaluator()
|
||||||
|
{
|
||||||
|
return evaluator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEvaluator( PropertyEvaluator evaluator )
|
||||||
|
{
|
||||||
|
this.evaluator = evaluator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyStore getKeystore()
|
||||||
|
{
|
||||||
|
return keystore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeystore( KeyStore keystores )
|
||||||
|
{
|
||||||
|
this.keystore = keystore;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package org.eclipse.jetty.policy;
|
||||||
|
|
||||||
|
import java.security.CodeSource;
|
||||||
|
import java.security.PermissionCollection;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.security.ProtectionDomain;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class PolicyEntry
|
||||||
|
{
|
||||||
|
public CodeSource codesource;
|
||||||
|
|
||||||
|
public Set<Certificate> certificates;
|
||||||
|
|
||||||
|
public Principal[] principals;
|
||||||
|
|
||||||
|
public PermissionCollection permissions;
|
||||||
|
|
||||||
|
private ProtectionDomain protectionDomain;
|
||||||
|
|
||||||
|
public ProtectionDomain toProtectionDomain()
|
||||||
|
{
|
||||||
|
if ( protectionDomain == null )
|
||||||
|
{
|
||||||
|
if ( codesource == null )
|
||||||
|
{
|
||||||
|
protectionDomain = new ProtectionDomain( null, permissions );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
protectionDomain = new ProtectionDomain( codesource, permissions, Thread.currentThread().getContextClassLoader(), principals );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return protectionDomain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeSource getCodeSource()
|
||||||
|
{
|
||||||
|
return codesource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCodeSource( CodeSource codesource )
|
||||||
|
{
|
||||||
|
this.codesource = codesource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Certificate> getCertificates()
|
||||||
|
{
|
||||||
|
return certificates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCertificates( Set<Certificate> certificates )
|
||||||
|
{
|
||||||
|
this.certificates = certificates;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Principal[] getPrincipals()
|
||||||
|
{
|
||||||
|
return principals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipals( Principal[] principals )
|
||||||
|
{
|
||||||
|
this.principals = principals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PermissionCollection getPermissions()
|
||||||
|
{
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissions( PermissionCollection permissions )
|
||||||
|
{
|
||||||
|
this.permissions = permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.eclipse.jetty.policy.component;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.policy.PolicyContext;
|
||||||
|
import org.eclipse.jetty.policy.PolicyException;
|
||||||
|
|
||||||
|
public abstract class AbstractNode
|
||||||
|
{
|
||||||
|
private boolean isDirty = false;
|
||||||
|
private boolean isExpanded = false;
|
||||||
|
|
||||||
|
public abstract void expand( PolicyContext context ) throws PolicyException;
|
||||||
|
|
||||||
|
public boolean isDirty()
|
||||||
|
{
|
||||||
|
return isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDirty( boolean isDirty )
|
||||||
|
{
|
||||||
|
this.isDirty = isDirty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isExpanded()
|
||||||
|
{
|
||||||
|
return isExpanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExpanded( boolean isExpanded )
|
||||||
|
{
|
||||||
|
this.isExpanded = isExpanded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
package org.eclipse.jetty.policy.component;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.CodeSource;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.PermissionCollection;
|
||||||
|
import java.security.Permissions;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.policy.PolicyContext;
|
||||||
|
import org.eclipse.jetty.policy.PolicyException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class GrantNode extends AbstractNode
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signers part of grant clause. This is a comma-separated list of certificate aliases.
|
||||||
|
*/
|
||||||
|
private String signers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The codebase part of grant clause. This is an URL from which code originates.
|
||||||
|
*/
|
||||||
|
private String codebase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of PrincipalEntries of grant clause.
|
||||||
|
*/
|
||||||
|
private Collection<PrincipalNode> principalNodes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Collection of PermissionEntries of grant clause.
|
||||||
|
*/
|
||||||
|
private Collection<PermissionNode> permissionNodes;
|
||||||
|
|
||||||
|
// cached permissions
|
||||||
|
private PermissionCollection permissions;
|
||||||
|
private Certificate[] signerArray;
|
||||||
|
private CodeSource codesource;
|
||||||
|
private Principal[] principals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds specified element to the <code>principals</code> collection. If collection does not exist yet, creates a
|
||||||
|
* new one.
|
||||||
|
*/
|
||||||
|
public void addPrincipal( PrincipalNode pe )
|
||||||
|
{
|
||||||
|
if ( principalNodes == null )
|
||||||
|
{
|
||||||
|
principalNodes = new HashSet<PrincipalNode>();
|
||||||
|
}
|
||||||
|
principalNodes.add( pe );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expand( PolicyContext context ) throws PolicyException
|
||||||
|
{
|
||||||
|
signerArray = resolveToCertificates( context.getKeystore(), signers ); // TODO alter to support self:: etc
|
||||||
|
codebase = context.getEvaluator().evaluate( codebase );
|
||||||
|
|
||||||
|
if ( principalNodes != null )
|
||||||
|
{
|
||||||
|
Set<Principal> principalSet = new HashSet<Principal>(); // TODO address this not being accurate ( missing prinicipals in codestore)
|
||||||
|
for ( Iterator<PrincipalNode> i = principalNodes.iterator(); i.hasNext(); )
|
||||||
|
{
|
||||||
|
PrincipalNode node = i.next();
|
||||||
|
node.expand( context );
|
||||||
|
principalSet.add( node.toPrincipal( context ) );
|
||||||
|
}
|
||||||
|
principals = principalSet.toArray( new Principal[principalSet.size()] );
|
||||||
|
}
|
||||||
|
|
||||||
|
permissions = new Permissions();
|
||||||
|
for ( Iterator<PermissionNode> i = permissionNodes.iterator(); i.hasNext(); )
|
||||||
|
{
|
||||||
|
PermissionNode node = i.next();
|
||||||
|
node.expand( context );
|
||||||
|
permissions.add( node.toPermission() );
|
||||||
|
}
|
||||||
|
|
||||||
|
setExpanded( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public PermissionCollection getPermissions() throws PolicyException
|
||||||
|
{
|
||||||
|
return permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Principal[] getPrincipals() throws PolicyException
|
||||||
|
{
|
||||||
|
return principals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CodeSource getCodeSource() throws PolicyException
|
||||||
|
{
|
||||||
|
if ( !isExpanded() )
|
||||||
|
{
|
||||||
|
throw new PolicyException("GrantNode needs to be expanded.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ( codesource == null && codebase != null )
|
||||||
|
{
|
||||||
|
URL url = new URL( codebase );
|
||||||
|
codesource = new CodeSource( url, signerArray );
|
||||||
|
}
|
||||||
|
|
||||||
|
return codesource;
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
throw new PolicyException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* resolve signers into an array of certificates using a given keystore
|
||||||
|
*
|
||||||
|
* @param keyStore
|
||||||
|
* @param signers
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private Certificate[] resolveToCertificates( KeyStore keyStore, String signers ) throws PolicyException
|
||||||
|
{
|
||||||
|
if ( keyStore == null )
|
||||||
|
{
|
||||||
|
Certificate[] certs = null;
|
||||||
|
return certs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Certificate> certificateSet = new HashSet<Certificate>();
|
||||||
|
StringTokenizer strTok = new StringTokenizer( signers, ",");
|
||||||
|
|
||||||
|
for ( int i = 0; strTok.hasMoreTokens(); ++i )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Certificate certificate = keyStore.getCertificate( strTok.nextToken().trim() );
|
||||||
|
|
||||||
|
if ( certificate != null )
|
||||||
|
{
|
||||||
|
certificateSet.add( certificate );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( KeyStoreException kse )
|
||||||
|
{
|
||||||
|
throw new PolicyException( kse );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return certificateSet.toArray( new Certificate[certificateSet.size()] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setSigners( String signers )
|
||||||
|
{
|
||||||
|
this.signers = signers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCodebase( String codebase )
|
||||||
|
{
|
||||||
|
this.codebase = codebase;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrincipals( Collection<PrincipalNode> principals )
|
||||||
|
{
|
||||||
|
this.principalNodes = principals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPermissions( Collection<PermissionNode> permissions )
|
||||||
|
{
|
||||||
|
this.permissionNodes = permissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package org.eclipse.jetty.policy.component;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.policy.PolicyContext;
|
||||||
|
import org.eclipse.jetty.policy.PolicyException;
|
||||||
|
|
||||||
|
public class KeystoreNode extends AbstractNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The URL part of keystore clause.
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The typename part of keystore clause.
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
// cached value
|
||||||
|
private KeyStore keystore;
|
||||||
|
|
||||||
|
public KeyStore toKeyStore() throws PolicyException
|
||||||
|
{
|
||||||
|
if ( keystore != null && !isDirty() )
|
||||||
|
{
|
||||||
|
return keystore;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
keystore = KeyStore.getInstance( type );
|
||||||
|
|
||||||
|
URL keyStoreLocation = new URL ( url );
|
||||||
|
InputStream istream = keyStoreLocation.openStream();
|
||||||
|
|
||||||
|
keystore.load( istream, null );
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
throw new PolicyException( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
return keystore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expand( PolicyContext context ) throws PolicyException
|
||||||
|
{
|
||||||
|
url = context.getEvaluator().evaluate( url );
|
||||||
|
|
||||||
|
setExpanded( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl()
|
||||||
|
{
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUrl( String url )
|
||||||
|
{
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType()
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType( String type )
|
||||||
|
{
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,197 @@
|
||||||
|
package org.eclipse.jetty.policy.component;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.Permission;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.policy.PolicyContext;
|
||||||
|
import org.eclipse.jetty.policy.PolicyException;
|
||||||
|
|
||||||
|
public class PermissionNode extends AbstractNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The classname part of permission clause.
|
||||||
|
*/
|
||||||
|
private String klass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name part of permission clause.
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The actions part of permission clause.
|
||||||
|
*/
|
||||||
|
private String actions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signers part of permission clause. This is a comma-separated list of certificate aliases.
|
||||||
|
*/
|
||||||
|
private String signers;
|
||||||
|
|
||||||
|
|
||||||
|
private Certificate[] signerArray;
|
||||||
|
|
||||||
|
public Permission toPermission() throws PolicyException
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class clazz = Class.forName( klass );
|
||||||
|
|
||||||
|
if ( signerArray != null && !validate( signerArray, (Certificate[])clazz.getSigners() ) )
|
||||||
|
{
|
||||||
|
throw new PolicyException( "Unvalidated Permissions: " + klass + "/" + name );
|
||||||
|
}
|
||||||
|
|
||||||
|
Permission permission = null;
|
||||||
|
|
||||||
|
if ( name == null && actions == null )
|
||||||
|
{
|
||||||
|
permission = (Permission) clazz.newInstance();
|
||||||
|
}
|
||||||
|
else if ( name != null && actions == null )
|
||||||
|
{
|
||||||
|
Constructor c = clazz.getConstructor( new Class[] { String.class } );
|
||||||
|
permission = (Permission) c.newInstance( name );
|
||||||
|
}
|
||||||
|
else if ( name != null && actions != null )
|
||||||
|
{
|
||||||
|
Constructor c = clazz.getConstructor( new Class[] { String.class, String.class } );
|
||||||
|
permission = (Permission) c.newInstance( name, actions );
|
||||||
|
}
|
||||||
|
|
||||||
|
return permission;
|
||||||
|
}
|
||||||
|
catch ( Exception e )
|
||||||
|
{
|
||||||
|
throw new PolicyException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expand( PolicyContext context ) throws PolicyException
|
||||||
|
{
|
||||||
|
name = context.getEvaluator().evaluate( name );
|
||||||
|
|
||||||
|
if ( signers != null )
|
||||||
|
{
|
||||||
|
signerArray = resolveCertificates( context.getKeystore(), signers );
|
||||||
|
}
|
||||||
|
|
||||||
|
setExpanded( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* validate that all permission certs are present in the class certs
|
||||||
|
*
|
||||||
|
* @param permCerts
|
||||||
|
* @param classCerts
|
||||||
|
* @return true if the permissions match up
|
||||||
|
*/
|
||||||
|
private static boolean validate( Certificate[] permCerts, Certificate[] classCerts )
|
||||||
|
{
|
||||||
|
if ( classCerts == null )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int i = 0; i < permCerts.length; ++i )
|
||||||
|
{
|
||||||
|
boolean found = false;
|
||||||
|
for ( int j = 0; j < classCerts.length; ++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 )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// we found all the permCerts in classCerts so return true
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Certificate[] resolveCertificates( KeyStore keyStore, String signers ) throws PolicyException
|
||||||
|
{
|
||||||
|
if ( keyStore == null )
|
||||||
|
{
|
||||||
|
Certificate[] certs = null;
|
||||||
|
return certs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Certificate> certificateSet = new HashSet<Certificate>();
|
||||||
|
StringTokenizer strTok = new StringTokenizer( signers, ",");
|
||||||
|
|
||||||
|
for ( int i = 0; strTok.hasMoreTokens(); ++i )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Certificate certificate = keyStore.getCertificate( strTok.nextToken().trim() );
|
||||||
|
|
||||||
|
if ( certificate != null )
|
||||||
|
{
|
||||||
|
certificateSet.add( certificate );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( KeyStoreException kse )
|
||||||
|
{
|
||||||
|
throw new PolicyException( kse );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return certificateSet.toArray( new Certificate[certificateSet.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKlass()
|
||||||
|
{
|
||||||
|
return klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKlass( String klass )
|
||||||
|
{
|
||||||
|
this.klass = klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getActions()
|
||||||
|
{
|
||||||
|
return actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActions( String actions )
|
||||||
|
{
|
||||||
|
this.actions = actions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSigners()
|
||||||
|
{
|
||||||
|
return signers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSigners( String signers )
|
||||||
|
{
|
||||||
|
this.signers = signers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
package org.eclipse.jetty.policy.component;
|
||||||
|
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.policy.PolicyContext;
|
||||||
|
import org.eclipse.jetty.policy.PolicyException;
|
||||||
|
|
||||||
|
public class PrincipalNode extends AbstractNode
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Wildcard value denotes any class and/or any name. Must be asterisk, for proper general expansion and
|
||||||
|
* PrivateCredentialsPermission wildcarding
|
||||||
|
*/
|
||||||
|
public static final String WILDCARD = "*"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The classname part of principal clause.
|
||||||
|
*/
|
||||||
|
private String klass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name part of principal clause.
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cached principal if already computed
|
||||||
|
*/
|
||||||
|
private Principal principal;
|
||||||
|
|
||||||
|
public Principal toPrincipal( PolicyContext context ) throws PolicyException
|
||||||
|
{
|
||||||
|
if ( principal != null && !isDirty() )
|
||||||
|
{
|
||||||
|
return principal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there is no keystore, there is no way to obtain a principal object // TODO validate we need this check
|
||||||
|
if ( context.getKeystore() == null )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Certificate certificate = context.getKeystore().getCertificate( name );
|
||||||
|
|
||||||
|
if ( certificate instanceof X509Certificate )
|
||||||
|
{
|
||||||
|
principal = ( (X509Certificate) certificate ).getSubjectX500Principal();
|
||||||
|
return principal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new PolicyException( "Unknown Certificate, unable to obtain Principal: " + certificate.getType() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch ( KeyStoreException kse )
|
||||||
|
{
|
||||||
|
throw new PolicyException( kse );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void expand( PolicyContext context )
|
||||||
|
throws PolicyException
|
||||||
|
{
|
||||||
|
name = context.getEvaluator().evaluate( name );
|
||||||
|
|
||||||
|
setExpanded(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKlass()
|
||||||
|
{
|
||||||
|
return klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKlass( String klass )
|
||||||
|
{
|
||||||
|
this.klass = klass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -18,30 +18,20 @@ package org.eclipse.jetty.policy.loader;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.security.CodeSource;
|
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.KeyStoreException;
|
|
||||||
import java.security.Permission;
|
|
||||||
import java.security.PermissionCollection;
|
|
||||||
import java.security.Permissions;
|
|
||||||
import java.security.Principal;
|
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.security.cert.Certificate;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
|
import org.eclipse.jetty.policy.PolicyContext;
|
||||||
import org.eclipse.jetty.policy.PolicyException;
|
import org.eclipse.jetty.policy.PolicyException;
|
||||||
import org.eclipse.jetty.policy.PropertyEvaluator;
|
import org.eclipse.jetty.policy.PolicyEntry;
|
||||||
|
import org.eclipse.jetty.policy.component.GrantNode;
|
||||||
|
import org.eclipse.jetty.policy.component.KeystoreNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the policies within the stream and resolve into protection domains and permission collections
|
* Load the policies within the stream and resolve into protection domains and permission collections
|
||||||
|
@ -50,405 +40,55 @@ import org.eclipse.jetty.policy.PropertyEvaluator;
|
||||||
public class DefaultPolicyLoader
|
public class DefaultPolicyLoader
|
||||||
{
|
{
|
||||||
|
|
||||||
public static Map<ProtectionDomain, PermissionCollection> load( InputStream policyStream, PropertyEvaluator evaluator ) throws PolicyException
|
public static Map<ProtectionDomain, PolicyEntry> load( InputStream policyStream, PolicyContext context ) throws PolicyException
|
||||||
{
|
{
|
||||||
Map<ProtectionDomain, PermissionCollection> pdMappings = new HashMap<ProtectionDomain, PermissionCollection>();
|
Map<ProtectionDomain, PolicyEntry> policies = new HashMap<ProtectionDomain, PolicyEntry>();
|
||||||
KeyStore keystore = null;
|
KeyStore keystore = null;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PolicyFileScanner loader = new PolicyFileScanner();
|
PolicyFileScanner loader = new PolicyFileScanner();
|
||||||
|
|
||||||
Collection<GrantEntry> grantEntries = new ArrayList<GrantEntry>();
|
Collection<GrantNode> grantEntries = new ArrayList<GrantNode>();
|
||||||
List<KeystoreEntry> keystoreEntries = new ArrayList<KeystoreEntry>();
|
List<KeystoreNode> keystoreEntries = new ArrayList<KeystoreNode>();
|
||||||
|
|
||||||
loader.scanStream( new InputStreamReader(policyStream), grantEntries, keystoreEntries );
|
loader.scanStream( new InputStreamReader(policyStream), grantEntries, keystoreEntries );
|
||||||
|
|
||||||
for ( Iterator<KeystoreEntry> i = keystoreEntries.iterator(); i.hasNext();)
|
for ( Iterator<KeystoreNode> i = keystoreEntries.iterator(); i.hasNext();)
|
||||||
{
|
{
|
||||||
keystore = resolveKeyStore( i.next(), evaluator );
|
KeystoreNode node = i.next();
|
||||||
|
node.expand( context );
|
||||||
|
|
||||||
|
keystore = node.toKeyStore();
|
||||||
|
|
||||||
if ( keystore != null )
|
if ( keystore != null )
|
||||||
{
|
{
|
||||||
// we only process the first valid keystore
|
// we only process the first valid keystore
|
||||||
|
context.setKeystore( keystore );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( Iterator<GrantEntry> i = grantEntries.iterator(); i.hasNext(); )
|
for ( Iterator<GrantNode> i = grantEntries.iterator(); i.hasNext(); )
|
||||||
{
|
{
|
||||||
GrantEntry grant = i.next();
|
GrantNode grant = i.next();
|
||||||
|
|
||||||
Permissions permissions = processPermissions( grant, keystore, evaluator );
|
grant.expand( context );
|
||||||
|
|
||||||
ProtectionDomain pd;
|
PolicyEntry policy = new PolicyEntry();
|
||||||
|
|
||||||
if ( grant.codebase == null ) // these are hereby known as global permissions (no codebase associated)
|
policy.setCodeSource( grant.getCodeSource() );
|
||||||
{
|
policy.setPrincipals( grant.getPrincipals() );
|
||||||
pd = new ProtectionDomain( null, permissions );
|
policy.setPermissions( grant.getPermissions() );
|
||||||
}
|
|
||||||
else
|
policies.put( policy.toProtectionDomain(), policy );
|
||||||
{
|
|
||||||
Certificate[] certs = resolveToCertificates( keystore, grant.signers );
|
|
||||||
Principal[] principals = resolvePrincipals( keystore, grant.principals );
|
|
||||||
CodeSource codeSource = resolveToCodeSource( grant.codebase, certs, evaluator );
|
|
||||||
pd = new ProtectionDomain( codeSource, permissions, Thread.currentThread().getContextClassLoader(),principals );
|
|
||||||
//System.out.println( pd.toString() );
|
|
||||||
}
|
|
||||||
pdMappings.put( pd, null );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pdMappings;
|
return policies;
|
||||||
}
|
}
|
||||||
catch ( Exception e )
|
catch ( Exception e )
|
||||||
{
|
{
|
||||||
throw new PolicyException( e );
|
throw new PolicyException( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Permissions processPermissions( GrantEntry grant, KeyStore keystore, PropertyEvaluator evaluator ) throws PolicyException
|
|
||||||
{
|
|
||||||
Collection<PermissionEntry> collection = grant.permissions;
|
|
||||||
Permissions permissions = new Permissions();
|
|
||||||
|
|
||||||
for ( Iterator<PermissionEntry> i = collection.iterator(); i.hasNext(); )
|
|
||||||
{
|
|
||||||
PermissionEntry perm = i.next();
|
|
||||||
|
|
||||||
Class clazz;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
clazz = Class.forName( perm.klass );
|
|
||||||
|
|
||||||
// if we have perm.signers then we need to validate against the class certificates
|
|
||||||
if ( perm.signers != null )
|
|
||||||
{
|
|
||||||
if ( validate( resolveToCertificates( keystore, perm.signers ), (Certificate[]) clazz.getSigners() ))
|
|
||||||
{
|
|
||||||
permissions.add( resolveToPermission( clazz, perm, evaluator ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
permissions.add( resolveToPermission( clazz, perm, evaluator ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( Exception e )
|
|
||||||
{
|
|
||||||
throw new PolicyException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return permissions;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Permission resolveToPermission(Class clazz, PermissionEntry perm, PropertyEvaluator evaluator ) throws PolicyException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Permission permission = null;
|
|
||||||
|
|
||||||
if ( perm.name == null && perm.actions == null )
|
|
||||||
{
|
|
||||||
permission = (Permission) clazz.newInstance();
|
|
||||||
}
|
|
||||||
else if ( perm.name != null && perm.actions == null )
|
|
||||||
{
|
|
||||||
Constructor c = clazz.getConstructor( new Class[] { String.class } );
|
|
||||||
permission = (Permission) c.newInstance( evaluator.evaluate( perm.name ) );
|
|
||||||
}
|
|
||||||
else if ( perm.name != null && perm.actions != null )
|
|
||||||
{
|
|
||||||
Constructor c = clazz.getConstructor( new Class[] { String.class, String.class } );
|
|
||||||
permission = (Permission) c.newInstance( evaluator.evaluate( perm.name ), perm.actions );
|
|
||||||
}
|
|
||||||
|
|
||||||
return permission;
|
|
||||||
|
|
||||||
}
|
|
||||||
catch ( Exception e )
|
|
||||||
{
|
|
||||||
throw new PolicyException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* resolve the use of the klass in the principal entry
|
|
||||||
*
|
|
||||||
* @param keystore
|
|
||||||
* @param collection
|
|
||||||
* @return
|
|
||||||
* @throws PolicyException
|
|
||||||
*/
|
|
||||||
private static Principal[] resolvePrincipals( KeyStore keystore, Collection<PrincipalEntry> collection ) throws PolicyException
|
|
||||||
{
|
|
||||||
if ( keystore == null || collection == null )
|
|
||||||
{
|
|
||||||
Principal[] principals = null;
|
|
||||||
return principals;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Principal> principalSet = new HashSet<Principal>();
|
|
||||||
|
|
||||||
|
|
||||||
for ( Iterator<PrincipalEntry> i = collection.iterator(); i.hasNext(); )
|
|
||||||
{
|
|
||||||
PrincipalEntry principal = i.next();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Certificate certificate = keystore.getCertificate( principal.name );
|
|
||||||
|
|
||||||
if ( certificate instanceof X509Certificate )
|
|
||||||
{
|
|
||||||
principalSet.add( ((X509Certificate) certificate).getSubjectX500Principal() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( KeyStoreException kse )
|
|
||||||
{
|
|
||||||
throw new PolicyException( kse );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return principalSet.toArray( new Principal[principalSet.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private static CodeSource resolveToCodeSource( String codeBase, Certificate[] signers, PropertyEvaluator evaluator ) throws PolicyException
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
URL url = new URL( evaluator.evaluate(codeBase) );
|
|
||||||
|
|
||||||
return new CodeSource( url, signers);
|
|
||||||
}
|
|
||||||
catch ( Exception e )
|
|
||||||
{
|
|
||||||
throw new PolicyException( e );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* resolve signers into an array of certificates using a given keystore
|
|
||||||
*
|
|
||||||
* @param keyStore
|
|
||||||
* @param signers
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
private static Certificate[] resolveToCertificates( KeyStore keyStore, String signers ) throws PolicyException
|
|
||||||
{
|
|
||||||
if ( keyStore == null )
|
|
||||||
{
|
|
||||||
Certificate[] certs = null;
|
|
||||||
return certs;
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<Certificate> certificateSet = new HashSet<Certificate>();
|
|
||||||
StringTokenizer strTok = new StringTokenizer( signers, ",");
|
|
||||||
|
|
||||||
for ( int i = 0; strTok.hasMoreTokens(); ++i )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Certificate certificate = keyStore.getCertificate( strTok.nextToken().trim() );
|
|
||||||
|
|
||||||
if ( certificate != null )
|
|
||||||
{
|
|
||||||
certificateSet.add( certificate );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch ( KeyStoreException kse )
|
|
||||||
{
|
|
||||||
throw new PolicyException( kse );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return certificateSet.toArray( new Certificate[certificateSet.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static KeyStore resolveKeyStore( KeystoreEntry entry, PropertyEvaluator evaluator ) throws PolicyException
|
|
||||||
{
|
|
||||||
KeyStore keyStore = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
keyStore = KeyStore.getInstance( entry.type );
|
|
||||||
|
|
||||||
URL keyStoreLocation = new URL ( evaluator.evaluate( entry.url ) );
|
|
||||||
InputStream istream = keyStoreLocation.openStream();
|
|
||||||
|
|
||||||
keyStore.load( istream, null );
|
|
||||||
}
|
|
||||||
catch ( Exception e )
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
//throw new PolicyException( kse );
|
|
||||||
}
|
|
||||||
|
|
||||||
return keyStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* validate that all permission certs are present in the class certs
|
|
||||||
*
|
|
||||||
* @param permCerts
|
|
||||||
* @param classCerts
|
|
||||||
* @return true if the permissions match up
|
|
||||||
*/
|
|
||||||
private static boolean validate( Certificate[] permCerts, Certificate[] classCerts )
|
|
||||||
{
|
|
||||||
if ( classCerts == null )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( int i = 0; i < permCerts.length; ++i )
|
|
||||||
{
|
|
||||||
boolean found = false;
|
|
||||||
for ( int j = 0; j < classCerts.length; ++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 )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// we found all the permCerts in classCerts so return true
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compound token representing <i>keystore</i> clause. See policy format
|
|
||||||
* {@link org.apache.harmony.security.DefaultPolicy description}for details.
|
|
||||||
*
|
|
||||||
* @see org.apache.harmony.security.fortress.DefaultPolicyParser
|
|
||||||
* @see org.apache.harmony.security.DefaultPolicyScanner
|
|
||||||
*/
|
|
||||||
public static class KeystoreEntry
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The URL part of keystore clause.
|
|
||||||
*/
|
|
||||||
public String url;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The typename part of keystore clause.
|
|
||||||
*/
|
|
||||||
public String type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compound token representing <i>grant </i> clause. See policy format
|
|
||||||
* {@link org.apache.harmony.security.DefaultPolicy description}for details.
|
|
||||||
*
|
|
||||||
* @see org.apache.harmony.security.fortress.DefaultPolicyParser
|
|
||||||
* @see org.apache.harmony.security.DefaultPolicyScanner
|
|
||||||
*/
|
|
||||||
public static class GrantEntry
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The signers part of grant clause. This is a comma-separated list of certificate aliases.
|
|
||||||
*/
|
|
||||||
public String signers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The codebase part of grant clause. This is an URL from which code originates.
|
|
||||||
*/
|
|
||||||
public String codebase;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection of PrincipalEntries of grant clause.
|
|
||||||
*/
|
|
||||||
public Collection<PrincipalEntry> principals;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Collection of PermissionEntries of grant clause.
|
|
||||||
*/
|
|
||||||
public Collection<PermissionEntry> permissions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds specified element to the <code>principals</code> collection. If collection does not exist yet, creates a
|
|
||||||
* new one.
|
|
||||||
*/
|
|
||||||
public void addPrincipal( PrincipalEntry pe )
|
|
||||||
{
|
|
||||||
if ( principals == null )
|
|
||||||
{
|
|
||||||
principals = new HashSet<PrincipalEntry>();
|
|
||||||
}
|
|
||||||
principals.add( pe );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compound token representing <i>principal </i> entry of a <i>grant </i> clause. See policy format
|
|
||||||
* {@link org.apache.harmony.security.DefaultPolicy description}for details.
|
|
||||||
*
|
|
||||||
* @see org.apache.harmony.security.fortress.DefaultPolicyParser
|
|
||||||
* @see org.apache.harmony.security.DefaultPolicyScanner
|
|
||||||
*/
|
|
||||||
public static class PrincipalEntry
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wildcard value denotes any class and/or any name. Must be asterisk, for proper general expansion and
|
|
||||||
* PrivateCredentialsPermission wildcarding
|
|
||||||
*/
|
|
||||||
public static final String WILDCARD = "*"; //$NON-NLS-1$
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The classname part of principal clause.
|
|
||||||
*/
|
|
||||||
public String klass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name part of principal clause.
|
|
||||||
*/
|
|
||||||
public String name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compound token representing <i>permission </i> entry of a <i>grant </i> clause. See policy format
|
|
||||||
* {@link org.apache.harmony.security.DefaultPolicy description}for details.
|
|
||||||
*
|
|
||||||
* @see org.apache.harmony.security.fortress.DefaultPolicyParser
|
|
||||||
* @see org.apache.harmony.security.DefaultPolicyScanner
|
|
||||||
*/
|
|
||||||
public static class PermissionEntry
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The classname part of permission clause.
|
|
||||||
*/
|
|
||||||
public String klass;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The name part of permission clause.
|
|
||||||
*/
|
|
||||||
public String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The actions part of permission clause.
|
|
||||||
*/
|
|
||||||
public String actions;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The signers part of permission clause. This is a comma-separated list of certificate aliases.
|
|
||||||
*/
|
|
||||||
public String signers;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,10 +40,10 @@ import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jetty.policy.loader.DefaultPolicyLoader.GrantEntry;
|
import org.eclipse.jetty.policy.component.GrantNode;
|
||||||
import org.eclipse.jetty.policy.loader.DefaultPolicyLoader.KeystoreEntry;
|
import org.eclipse.jetty.policy.component.KeystoreNode;
|
||||||
import org.eclipse.jetty.policy.loader.DefaultPolicyLoader.PermissionEntry;
|
import org.eclipse.jetty.policy.component.PermissionNode;
|
||||||
import org.eclipse.jetty.policy.loader.DefaultPolicyLoader.PrincipalEntry;
|
import org.eclipse.jetty.policy.component.PrincipalNode;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -126,7 +126,7 @@ public class PolicyFileScanner
|
||||||
* @throws IOException if stream reading failed
|
* @throws IOException if stream reading failed
|
||||||
* @throws InvalidFormatException if unexpected or unknown token encountered
|
* @throws InvalidFormatException if unexpected or unknown token encountered
|
||||||
*/
|
*/
|
||||||
public void scanStream( Reader r, Collection<GrantEntry> grantEntries, List<KeystoreEntry> keystoreEntries )
|
public void scanStream( Reader r, Collection<GrantNode> grantEntries, List<KeystoreNode> keystoreEntries )
|
||||||
throws IOException, InvalidFormatException
|
throws IOException, InvalidFormatException
|
||||||
{
|
{
|
||||||
StreamTokenizer st = configure( new StreamTokenizer( r ) );
|
StreamTokenizer st = configure( new StreamTokenizer( r ) );
|
||||||
|
@ -140,10 +140,10 @@ public class PolicyFileScanner
|
||||||
|
|
||||||
case StreamTokenizer.TT_WORD:
|
case StreamTokenizer.TT_WORD:
|
||||||
if ( Util.equalsIgnoreCase( "keystore", st.sval ) ) { //$NON-NLS-1$
|
if ( Util.equalsIgnoreCase( "keystore", st.sval ) ) { //$NON-NLS-1$
|
||||||
keystoreEntries.add( readKeystoreEntry( st ) );
|
keystoreEntries.add( readKeystoreNode( st ) );
|
||||||
}
|
}
|
||||||
else if ( Util.equalsIgnoreCase( "grant", st.sval ) ) { //$NON-NLS-1$
|
else if ( Util.equalsIgnoreCase( "grant", st.sval ) ) { //$NON-NLS-1$
|
||||||
grantEntries.add( readGrantEntry( st ) );
|
grantEntries.add( readGrantNode( st ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -171,20 +171,20 @@ public class PolicyFileScanner
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @return successfully parsed KeystoreEntry
|
* @return successfully parsed KeystoreNode
|
||||||
* @throws IOException if stream reading failed
|
* @throws IOException if stream reading failed
|
||||||
* @throws InvalidFormatException if unexpected or unknown token encountered
|
* @throws InvalidFormatException if unexpected or unknown token encountered
|
||||||
*/
|
*/
|
||||||
protected KeystoreEntry readKeystoreEntry( StreamTokenizer st )
|
protected KeystoreNode readKeystoreNode( StreamTokenizer st )
|
||||||
throws IOException, InvalidFormatException
|
throws IOException, InvalidFormatException
|
||||||
{
|
{
|
||||||
KeystoreEntry ke = new KeystoreEntry();
|
KeystoreNode ke = new KeystoreNode();
|
||||||
if ( st.nextToken() == '"' )
|
if ( st.nextToken() == '"' )
|
||||||
{
|
{
|
||||||
ke.url = st.sval;
|
ke.setUrl( st.sval );
|
||||||
if ( ( st.nextToken() == '"' ) || ( ( st.ttype == ',' ) && ( st.nextToken() == '"' ) ) )
|
if ( ( st.nextToken() == '"' ) || ( ( st.ttype == ',' ) && ( st.nextToken() == '"' ) ) )
|
||||||
{
|
{
|
||||||
ke.type = st.sval;
|
ke.setType( st.sval );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // handle token in the main loop
|
{ // handle token in the main loop
|
||||||
|
@ -203,7 +203,7 @@ public class PolicyFileScanner
|
||||||
* Tries to read <i>grant </i> clause. <br>
|
* Tries to read <i>grant </i> clause. <br>
|
||||||
* First, it reads <i>codebase </i>, <i>signedby </i>, <i>principal </i> entries till the '{' (opening curly brace)
|
* First, it reads <i>codebase </i>, <i>signedby </i>, <i>principal </i> entries till the '{' (opening curly brace)
|
||||||
* symbol. Then it calls readPermissionEntries() method to read the permissions of this clause. <br>
|
* symbol. Then it calls readPermissionEntries() method to read the permissions of this clause. <br>
|
||||||
* Principal entries (if any) are read by invoking readPrincipalEntry() method, obtained PrincipalEntries are
|
* Principal entries (if any) are read by invoking readPrincipalNode() method, obtained PrincipalEntries are
|
||||||
* accumulated. <br>
|
* accumulated. <br>
|
||||||
* The expected syntax is
|
* The expected syntax is
|
||||||
*
|
*
|
||||||
|
@ -214,14 +214,14 @@ public class PolicyFileScanner
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @return successfully parsed GrantEntry
|
* @return successfully parsed GrantNode
|
||||||
* @throws IOException if stream reading failed
|
* @throws IOException if stream reading failed
|
||||||
* @throws InvalidFormatException if unexpected or unknown token encountered
|
* @throws InvalidFormatException if unexpected or unknown token encountered
|
||||||
*/
|
*/
|
||||||
protected GrantEntry readGrantEntry( StreamTokenizer st )
|
protected GrantNode readGrantNode( StreamTokenizer st )
|
||||||
throws IOException, InvalidFormatException
|
throws IOException, InvalidFormatException
|
||||||
{
|
{
|
||||||
GrantEntry ge = new GrantEntry();
|
GrantNode ge = new GrantNode();
|
||||||
parsing: while ( true )
|
parsing: while ( true )
|
||||||
{
|
{
|
||||||
switch ( st.nextToken() )
|
switch ( st.nextToken() )
|
||||||
|
@ -231,7 +231,7 @@ public class PolicyFileScanner
|
||||||
if ( Util.equalsIgnoreCase( "signedby", st.sval ) ) { //$NON-NLS-1$
|
if ( Util.equalsIgnoreCase( "signedby", st.sval ) ) { //$NON-NLS-1$
|
||||||
if ( st.nextToken() == '"' )
|
if ( st.nextToken() == '"' )
|
||||||
{
|
{
|
||||||
ge.signers = st.sval;
|
ge.setSigners( st.sval );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -241,7 +241,7 @@ public class PolicyFileScanner
|
||||||
else if ( Util.equalsIgnoreCase( "codebase", st.sval ) ) { //$NON-NLS-1$
|
else if ( Util.equalsIgnoreCase( "codebase", st.sval ) ) { //$NON-NLS-1$
|
||||||
if ( st.nextToken() == '"' )
|
if ( st.nextToken() == '"' )
|
||||||
{
|
{
|
||||||
ge.codebase = st.sval;
|
ge.setCodebase( st.sval );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -249,7 +249,7 @@ public class PolicyFileScanner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( Util.equalsIgnoreCase( "principal", st.sval ) ) { //$NON-NLS-1$
|
else if ( Util.equalsIgnoreCase( "principal", st.sval ) ) { //$NON-NLS-1$
|
||||||
ge.addPrincipal( readPrincipalEntry( st ) );
|
ge.addPrincipal( readPrincipalNode( st ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -261,7 +261,7 @@ public class PolicyFileScanner
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
ge.permissions = readPermissionEntries( st );
|
ge.setPermissions( readPermissionEntries( st ) );
|
||||||
break parsing;
|
break parsing;
|
||||||
|
|
||||||
default: // handle token in the main loop
|
default: // handle token in the main loop
|
||||||
|
@ -274,7 +274,7 @@ public class PolicyFileScanner
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to read <i>Principal </i> entry fields. The expected syntax is
|
* Tries to read <i>Principal </i> Node fields. The expected syntax is
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
|
@ -284,31 +284,31 @@ public class PolicyFileScanner
|
||||||
*
|
*
|
||||||
* Both class and name may be wildcards, wildcard names should not surrounded by quotes.
|
* Both class and name may be wildcards, wildcard names should not surrounded by quotes.
|
||||||
*
|
*
|
||||||
* @return successfully parsed PrincipalEntry
|
* @return successfully parsed PrincipalNode
|
||||||
* @throws IOException if stream reading failed
|
* @throws IOException if stream reading failed
|
||||||
* @throws InvalidFormatException if unexpected or unknown token encountered
|
* @throws InvalidFormatException if unexpected or unknown token encountered
|
||||||
*/
|
*/
|
||||||
protected PrincipalEntry readPrincipalEntry( StreamTokenizer st )
|
protected PrincipalNode readPrincipalNode( StreamTokenizer st )
|
||||||
throws IOException, InvalidFormatException
|
throws IOException, InvalidFormatException
|
||||||
{
|
{
|
||||||
PrincipalEntry pe = new PrincipalEntry();
|
PrincipalNode pe = new PrincipalNode();
|
||||||
if ( st.nextToken() == StreamTokenizer.TT_WORD )
|
if ( st.nextToken() == StreamTokenizer.TT_WORD )
|
||||||
{
|
{
|
||||||
pe.klass = st.sval;
|
pe.setKlass( st.sval );
|
||||||
st.nextToken();
|
st.nextToken();
|
||||||
}
|
}
|
||||||
else if ( st.ttype == '*' )
|
else if ( st.ttype == '*' )
|
||||||
{
|
{
|
||||||
pe.klass = PrincipalEntry.WILDCARD;
|
pe.setKlass( PrincipalNode.WILDCARD );
|
||||||
st.nextToken();
|
st.nextToken();
|
||||||
}
|
}
|
||||||
if ( st.ttype == '"' )
|
if ( st.ttype == '"' )
|
||||||
{
|
{
|
||||||
pe.name = st.sval;
|
pe.setName( st.sval );
|
||||||
}
|
}
|
||||||
else if ( st.ttype == '*' )
|
else if ( st.ttype == '*' )
|
||||||
{
|
{
|
||||||
pe.name = PrincipalEntry.WILDCARD;
|
pe.setName( PrincipalNode.WILDCARD );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -334,10 +334,10 @@ public class PolicyFileScanner
|
||||||
* @throws IOException if stream reading failed
|
* @throws IOException if stream reading failed
|
||||||
* @throws InvalidFormatException if unexpected or unknown token encountered
|
* @throws InvalidFormatException if unexpected or unknown token encountered
|
||||||
*/
|
*/
|
||||||
protected Collection<PermissionEntry> readPermissionEntries( StreamTokenizer st )
|
protected Collection<PermissionNode> readPermissionEntries( StreamTokenizer st )
|
||||||
throws IOException, InvalidFormatException
|
throws IOException, InvalidFormatException
|
||||||
{
|
{
|
||||||
Collection<PermissionEntry> permissions = new HashSet<PermissionEntry>();
|
Collection<PermissionNode> permissions = new HashSet<PermissionNode>();
|
||||||
parsing: while ( true )
|
parsing: while ( true )
|
||||||
{
|
{
|
||||||
switch ( st.nextToken() )
|
switch ( st.nextToken() )
|
||||||
|
@ -345,13 +345,13 @@ public class PolicyFileScanner
|
||||||
|
|
||||||
case StreamTokenizer.TT_WORD:
|
case StreamTokenizer.TT_WORD:
|
||||||
if ( Util.equalsIgnoreCase( "permission", st.sval ) ) { //$NON-NLS-1$
|
if ( Util.equalsIgnoreCase( "permission", st.sval ) ) { //$NON-NLS-1$
|
||||||
PermissionEntry pe = new PermissionEntry();
|
PermissionNode pe = new PermissionNode();
|
||||||
if ( st.nextToken() == StreamTokenizer.TT_WORD )
|
if ( st.nextToken() == StreamTokenizer.TT_WORD )
|
||||||
{
|
{
|
||||||
pe.klass = st.sval;
|
pe.setKlass( st.sval );
|
||||||
if ( st.nextToken() == '"' )
|
if ( st.nextToken() == '"' )
|
||||||
{
|
{
|
||||||
pe.name = st.sval;
|
pe.setName( st.sval );
|
||||||
st.nextToken();
|
st.nextToken();
|
||||||
}
|
}
|
||||||
if ( st.ttype == ',' )
|
if ( st.ttype == ',' )
|
||||||
|
@ -360,7 +360,7 @@ public class PolicyFileScanner
|
||||||
}
|
}
|
||||||
if ( st.ttype == '"' )
|
if ( st.ttype == '"' )
|
||||||
{
|
{
|
||||||
pe.actions = st.sval;
|
pe.setActions( st.sval );
|
||||||
if ( st.nextToken() == ',' )
|
if ( st.nextToken() == ',' )
|
||||||
{
|
{
|
||||||
st.nextToken();
|
st.nextToken();
|
||||||
|
@ -369,7 +369,7 @@ public class PolicyFileScanner
|
||||||
if ( st.ttype == StreamTokenizer.TT_WORD && Util.equalsIgnoreCase( "signedby", st.sval ) ) { //$NON-NLS-1$
|
if ( st.ttype == StreamTokenizer.TT_WORD && Util.equalsIgnoreCase( "signedby", st.sval ) ) { //$NON-NLS-1$
|
||||||
if ( st.nextToken() == '"' )
|
if ( st.nextToken() == '"' )
|
||||||
{
|
{
|
||||||
pe.signers = st.sval;
|
pe.setSigners( st.sval );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
@ -155,7 +156,13 @@ public class TestJettyPolicy extends TestCase
|
||||||
|
|
||||||
private String getWorkingDirectory()
|
private String getWorkingDirectory()
|
||||||
{
|
{
|
||||||
return System.getProperty( "basedir" ); // TODO work in eclipse
|
String cwd = System.getProperty( "basedir" );
|
||||||
|
|
||||||
|
if ( cwd == null )
|
||||||
|
{
|
||||||
|
cwd = System.getProperty( "user.dir" );
|
||||||
|
}
|
||||||
|
return cwd;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,14 +30,26 @@ public class TestJettyPolicyRuntime extends TestCase
|
||||||
PropertyEvaluator evaluator = new PropertyEvaluator( new HashMap<String,String>());
|
PropertyEvaluator evaluator = new PropertyEvaluator( new HashMap<String,String>());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUp()
|
protected void setUp() throws Exception
|
||||||
throws Exception
|
|
||||||
{
|
{
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
|
||||||
evaluator.put( "jetty.home", getWorkingDirectory() );
|
evaluator.put( "jetty.home", getWorkingDirectory() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception
|
||||||
|
{
|
||||||
|
super.tearDown();
|
||||||
|
|
||||||
|
System.setSecurityManager( null );
|
||||||
|
Policy.setPolicy( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void testSimplePolicyReplacement() throws Exception
|
public void testSimplePolicyReplacement() throws Exception
|
||||||
{
|
{
|
||||||
JettyPolicy ap =
|
JettyPolicy ap =
|
||||||
|
@ -52,9 +64,6 @@ public class TestJettyPolicyRuntime extends TestCase
|
||||||
|
|
||||||
assertTrue ( test.canRead() );
|
assertTrue ( test.canRead() );
|
||||||
|
|
||||||
// Policy nulling must occur after Security Manager null
|
|
||||||
System.setSecurityManager( null );
|
|
||||||
Policy.setPolicy( null );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRepeatedPolicyReplacement() throws Exception
|
public void testRepeatedPolicyReplacement() throws Exception
|
||||||
|
@ -102,8 +111,6 @@ public class TestJettyPolicyRuntime extends TestCase
|
||||||
assertTrue( "Exception was thrown as it should be.", true );
|
assertTrue( "Exception was thrown as it should be.", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
System.setSecurityManager( null );
|
|
||||||
Policy.setPolicy( null );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,8 +145,6 @@ public class TestJettyPolicyRuntime extends TestCase
|
||||||
assertTrue( "Exception was thrown", true );
|
assertTrue( "Exception was thrown", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
System.setSecurityManager( null );
|
|
||||||
Policy.setPolicy( null );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCertificateLoader()
|
public void testCertificateLoader()
|
||||||
|
@ -203,9 +208,6 @@ public class TestJettyPolicyRuntime extends TestCase
|
||||||
assertFalse( "should not have got here", true );
|
assertFalse( "should not have got here", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
System.setSecurityManager( null );
|
|
||||||
Policy.setPolicy( null );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -274,12 +276,17 @@ public class TestJettyPolicyRuntime extends TestCase
|
||||||
|
|
||||||
assertTrue( "checking that we through a security exception", excepted );
|
assertTrue( "checking that we through a security exception", excepted );
|
||||||
|
|
||||||
System.setSecurityManager( null );
|
|
||||||
Policy.setPolicy( null );
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getWorkingDirectory()
|
private String getWorkingDirectory()
|
||||||
{
|
{
|
||||||
return System.getProperty( "basedir" ); // TODO work in eclipse
|
String cwd = System.getProperty( "basedir" );
|
||||||
|
|
||||||
|
if ( cwd == null )
|
||||||
|
{
|
||||||
|
cwd = System.getProperty( "user.dir" );
|
||||||
|
}
|
||||||
|
return cwd;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue