package org.eclipse.jetty.policy.entry;
//========================================================================
//Copyright (c) Webtide LLC
//------------------------------------------------------------------------
//All rights reserved. This program and the accompanying materials
//are made available under the terms of the Eclipse Public License v1.0
//and Apache License v2.0 which accompanies this distribution.
//
//The Eclipse Public License is available at
//http://www.eclipse.org/legal/epl-v10.html
//
//The Apache License v2.0 is available at
//http://www.apache.org/licenses/LICENSE-2.0.txt
//
//You may elect to redistribute this code under either of these licenses.
//========================================================================
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 PermissionEntry extends AbstractEntry
{
/**
* 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 );
}
}
@Override
public void expand( PolicyContext context ) throws PolicyException
{
if ( name != null )
{
name = context.evaluate( name ).trim();
}
if ( actions != null )
{
actions = context.evaluate( actions ).trim();
}
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;
}
}