mcconnell 2004/02/25 10:55:40
Modified: merlin/activation/impl/src/test/org/apache/avalon/activation/impl/test
SystemContextBuilder.java
merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl
DefaultClassLoaderModel.java
DefaultSystemContext.java Scanner.java
StandardModelFactory.java
merlin/composition/impl/src/test/org/apache/avalon/composition/model/test
SystemContextBuilder.java
merlin/kernel/impl/src/java/org/apache/avalon/merlin/impl
DefaultFactory.java
Added:
merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl
DefaultSecurityModel.java
Log:
Add a SecurityModel holding the trusted certificates and default permissions and
expose this under the SystemContext. The SecurityModel is not complete yet - also need
to add operations to get supplimentaty permissions on a per-container basis (derived
from targets).
Revision Changes Path
1.3 +10 -2
avalon/merlin/activation/impl/src/test/org/apache/avalon/activation/impl/test/SystemContextBuilder.java
Index: SystemContextBuilder.java
===================================================================
RCS file:
/home/cvs/avalon/merlin/activation/impl/src/test/org/apache/avalon/activation/impl/test/SystemContextBuilder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SystemContextBuilder.java 19 Feb 2004 08:58:04 -0000 1.2
+++ SystemContextBuilder.java 25 Feb 2004 18:55:40 -0000 1.3
@@ -25,8 +25,10 @@
import org.apache.avalon.composition.model.ContainmentModel;
import org.apache.avalon.composition.model.impl.DefaultSystemContext;
+import org.apache.avalon.composition.model.impl.DefaultSecurityModel;
import org.apache.avalon.composition.provider.ModelFactory;
import org.apache.avalon.composition.provider.SystemContext;
+import org.apache.avalon.composition.provider.SecurityModel;
import org.apache.avalon.logging.provider.LoggingManager;
import org.apache.avalon.logging.data.CategoryDirective;
@@ -89,11 +91,17 @@
final File home = new File( base, "home" );
final File temp = new File( base, "temp" );
+ //
+ // FIX ME - build the security model from a configuration
+ //
+
+ SecurityModel security = new DefaultSecurityModel( null, null, secure );
+
Class clazz = DefaultRuntime.class;
return new DefaultSystemContext(
clazz, logging, base, home, temp, repository, "system",
- false, deploymenttimeout, secure );
+ false, deploymenttimeout, security );
}
private static Repository createTestRepository( InitialContext context, File
cache ) throws Exception
1.11 +11 -1
avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java
Index: DefaultClassLoaderModel.java
===================================================================
RCS file:
/home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- DefaultClassLoaderModel.java 23 Feb 2004 13:00:31 -0000 1.10
+++ DefaultClassLoaderModel.java 25 Feb 2004 18:55:40 -0000 1.11
@@ -207,6 +207,15 @@
m_urls = buildQualifiedClassPath();
m_classLoader =
new URLClassLoader( m_urls, context.getClassLoader() );
+
+ //
+ // changes needed here - grants must be under the control of
+ // system administrator which means that grants can only exist in
+ // either the kernel configuration or a targets override
+ // configuration - more specifically, a block's classloader directive
+ // cannot grant permissions
+ //
+
m_protectionDomains = createProtectionDomains(
directive.getGrantDirective() );
//
@@ -230,6 +239,7 @@
Logger serviceLogger = getLocalLogger().getChildLogger( "services" );
m_services = new DefaultServiceRepository(
serviceLogger, context.getServiceRepository(), services );
+
}
catch( Throwable e )
{
1.20 +16 -12
avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultSystemContext.java
Index: DefaultSystemContext.java
===================================================================
RCS file:
/home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultSystemContext.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- DefaultSystemContext.java 19 Feb 2004 08:58:04 -0000 1.19
+++ DefaultSystemContext.java 25 Feb 2004 18:55:40 -0000 1.20
@@ -33,6 +33,7 @@
import org.apache.avalon.composition.provider.ModelFactory;
import org.apache.avalon.composition.provider.SystemContext;
import org.apache.avalon.composition.provider.SystemException;
+import org.apache.avalon.composition.provider.SecurityModel;
import org.apache.avalon.composition.provider.Runtime;
import org.apache.avalon.repository.Artifact;
@@ -91,7 +92,7 @@
private final long m_timeout;
- private boolean m_secure;
+ private final SecurityModel m_security;
//--------------------------------------------------------------
// mutable state
@@ -118,6 +119,7 @@
* @param category the kernel logging category name
* @param trace flag indicating if internal logging is enabled
* @param timeout a system wide default deployment timeout
+ * @param security the security model
*/
public DefaultSystemContext(
InitialContext context,
@@ -130,11 +132,11 @@
String category,
boolean trace,
long timeout,
- boolean secure ) throws SystemException
+ SecurityModel security ) throws SystemException
{
this(
context, artifact, null, logging, base, home, temp,
- repository, category, trace, timeout, secure );
+ repository, category, trace, timeout, security );
}
/**
@@ -151,6 +153,7 @@
* @param category the kernel logging category name
* @param trace flag indicating if internal logging is enabled
* @param timeout a system wide default deployment timeout
+ * @param security the security model
*/
public DefaultSystemContext(
Class clazz,
@@ -162,11 +165,11 @@
String category,
boolean trace,
long timeout,
- boolean secure ) throws SystemException
+ SecurityModel security ) throws SystemException
{
this(
null, null, clazz, logging, base, home, temp, repository, category,
- trace, timeout, secure );
+ trace, timeout, security );
}
/**
@@ -185,6 +188,7 @@
* @param category the kernel logging category name
* @param trace flag indicating if internal logging is enabled
* @param timeout a system wide default deployment timeout
+ * @param security the security model
*/
private DefaultSystemContext(
InitialContext context,
@@ -198,7 +202,7 @@
String category,
boolean trace,
long timeout,
- boolean secure ) throws SystemException
+ SecurityModel security ) throws SystemException
{
if( base == null )
{
@@ -226,7 +230,7 @@
m_repository = repository;
m_logging = logging;
m_timeout = timeout;
- m_secure = secure;
+ m_security = security;
m_logger = m_logging.getLoggerForCategory( category );
m_system = SystemContext.class.getClassLoader();
@@ -386,12 +390,12 @@
}
/**
- * Return the enabled status of the code security policy.
- * @return the code security enabled status
+ * Return the system default grants directive.
+ * @return the grants directive
*/
- public boolean isCodeSecurityEnabled()
+ public SecurityModel getSecurityModel()
{
- return m_secure;
+ return m_security;
}
//------------------------------------------------------------------
1.7 +3 -1
avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/Scanner.java
Index: Scanner.java
===================================================================
RCS file:
/home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/Scanner.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Scanner.java 7 Feb 2004 22:46:42 -0000 1.6
+++ Scanner.java 25 Feb 2004 18:55:40 -0000 1.7
@@ -41,6 +41,7 @@
import org.apache.avalon.meta.info.Service;
import org.apache.avalon.meta.info.ServiceDescriptor;
+import org.apache.avalon.meta.info.PermissionDescriptor;
import org.apache.avalon.meta.info.Type;
import org.apache.avalon.meta.info.builder.TypeBuilder;
import org.apache.avalon.meta.info.builder.ServiceBuilder;
@@ -344,6 +345,7 @@
try
{
verifyType( type, clazz );
+
if( getLogger().isDebugEnabled() )
{
final String message =
1.5 +2 -2
avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/StandardModelFactory.java
Index: StandardModelFactory.java
===================================================================
RCS file:
/home/cvs/avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/StandardModelFactory.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- StandardModelFactory.java 23 Feb 2004 15:03:22 -0000 1.4
+++ StandardModelFactory.java 25 Feb 2004 18:55:40 -0000 1.5
@@ -183,7 +183,7 @@
createRootContainmentContext( profile );
ContainmentModel model = createContainmentModel( context );
- if( m_system.isCodeSecurityEnabled() )
+ if( m_system.getSecurityModel().isCodeSecurityEnabled() )
{
CodeSecurityPolicy policy =
new CodeSecurityPolicy( model );
1.1
avalon/merlin/composition/impl/src/java/org/apache/avalon/composition/model/impl/DefaultSecurityModel.java
Index: DefaultSecurityModel.java
===================================================================
/*
* Copyright 2004 Apache Software Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.avalon.composition.model.impl;
import java.io.IOException;
import java.io.InputStream;
import java.io.ByteArrayInputStream;
import java.security.Permission;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.Permission;
import java.util.ArrayList;
import java.util.Collection;
import java.net.URL;
import org.apache.avalon.composition.provider.SecurityModel;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
/**
* <p>Implementation of the default security model.</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision: 1.1 $ $Date: 2004/02/25 18:55:40 $
*/
public class DefaultSecurityModel implements SecurityModel
{
//-------------------------------------------------------------------
// static
//-------------------------------------------------------------------
private static final Permission[] EMPTY_PERMISSIONS = new Permission[0];
private static final Certificate[] EMPTY_CERTIFICATES = new Certificate[0];
public static SecurityModel createSecurityModel( Configuration config )
throws Exception
{
Configuration certs = config.getChild( "certificates" );
Certificate[] certificates = createCertificates( certs );
Configuration grant = config.getChild( "grant" );
Permission[] permissions = createPermissions( grant );
return new DefaultSecurityModel( certificates, permissions );
}
//-------------------------------------------------------------------
// immutable state
//-------------------------------------------------------------------
private final Certificate[] m_certificates;
private final Permission[] m_permissions;
private final boolean m_enabled;
//-------------------------------------------------------------------
// constructor
//-------------------------------------------------------------------
/**
* Creation of a new security model.
*/
public DefaultSecurityModel()
{
this( null, null, false );
}
/**
* Creation of a new security model.
*
* @param certificates the set of trusted certificates
* @param permissions the default permissions
*/
public DefaultSecurityModel(
Certificate[] certificates, Permission[] permissions )
{
this( certificates, permissions, true );
}
/**
* Creation of a new security model.
*
* @param certificates the set of trusted certificates
* @param permissions the default permissions
* @param flag if TRUE code security is enabled
*/
public DefaultSecurityModel(
Certificate[] certificates, Permission[] permissions, boolean flag )
{
m_enabled = flag;
if( null == permissions )
{
m_permissions = EMPTY_PERMISSIONS;
}
else
{
m_permissions = permissions;
}
if( null == certificates )
{
m_certificates = EMPTY_CERTIFICATES;
}
else
{
m_certificates = certificates;
}
}
//-------------------------------------------------------------------
// SecurityModel
//-------------------------------------------------------------------
/**
* Return the enabled status of the code security policy.
* @return the code security enabled status
*/
public boolean isCodeSecurityEnabled()
{
return m_enabled;
}
/**
* Return the set of default permissions.
*
* @return the permissions
*/
public Permission[] getDefaultPermissions()
{
return m_permissions;
}
/**
* Return the set of trusted certificates.
*
* @return the trusted certificates
*/
public Certificate[] getTrustedCertificates()
{
return m_certificates;
}
//-------------------------------------------------------------------
// internals
//-------------------------------------------------------------------
private static Certificate[] createCertificates( Configuration config )
throws Exception
{
ArrayList list = new ArrayList();
Configuration[] children = config.getChildren();
for( int i=0; i<children.length; i++ )
{
Configuration child = children[i];
String name = child.getName();
if( name.equals( "pkcs7" ) )
{
Certificate[] certs =
DefaultSecurityModel.createPKCS7( child );
for( int j=0; j<certs.length; j++ )
{
list.add( certs[j] );
}
}
else if( name.equals( "x509" ) )
{
Certificate[] certs =
DefaultSecurityModel.createX509( child );
for( int j=0; j<certs.length; j++ )
{
list.add( certs[j] );
}
}
else
{
final String error =
"Unrecognized certificate type [" + name + "].";
throw new ConfigurationException( error );
}
}
return (Certificate[]) list.toArray( new Certificate[0] );
}
/**
* Static utility method to construct a PKCS7 certificate set from a
* supplied configuration.
*
* @param config a configuration describing the PKCS7 certificate
*/
private static Certificate[] createPKCS7( Configuration config ) throws Exception
{
String href = config.getAttribute( "href" );
InputStream in = null;
try
{
URL url = new URL( href );
in = url.openStream();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection certs = cf.generateCertificates(in);
Certificate[] certificates = new Certificate[ certs.size() ];
return (Certificate[]) certs.toArray( certificates );
}
finally
{
if( in != null ) in.close();
}
}
/**
* Static utility method to construct a X509 certificate set for a
* supplied configuration.
*
* @param config a configuration describing the PKCS7 certificate
*/
private static Certificate[] createX509( Configuration config )
throws ConfigurationException, CertificateException, IOException
{
String href = config.getAttribute( "href", "" );
String data = config.getValue();
InputStream in = null;
try
{
if( href == null || "".equals( href ) )
{
in = new ByteArrayInputStream( data.getBytes("UTF-8") );
}
else
{
URL url = new URL( href );
in = url.openStream();
}
CertificateFactory cf = CertificateFactory.getInstance( "X.509" );
Collection certs = cf.generateCertificates( in );
Certificate[] certificates = new Certificate[ certs.size() ];
return (Certificate[]) certs.toArray( certificates );
}
finally
{
if( in != null ) in.close();
}
}
private static Permission[] createPermissions( Configuration config ) throws
Exception
{
Configuration[] children = config.getChildren( "permission" );
Permission[] permissions = new Permission[ children.length ];
for( int i=0; i<children.length; i++ )
{
permissions[i] = createPermission( children[i] );
}
return permissions;
}
private static Permission createPermission( Configuration config ) throws
Exception
{
String classname = config.getAttribute( "class" );
String name = config.getAttribute( "name", null );
String actions = getActions( config );
return createPermission( classname, name, actions );
}
private static String getActions( Configuration config ) throws
ConfigurationException
{
Configuration[] actions = config.getChildren( "action" );
if( actions.length == 0 ) return null;
String result = "";
for( int i=0 ; i < actions.length ; i ++ )
{
if( i > 0 )
{
result = result + "," + actions[i].getValue();
}
else
{
result = result + actions[i].getValue();
}
}
return result;
}
/**
* Utility method to create a Permission instance.
*
* @param classname Permission class
* @param name The name associated with the permission.
* @param action The action associated with the permission. Note that some
* Permissions doesn't support actions.
* @throws InstantiationException if the class could not be instantiated.
* @throws IllegalAccessException, if the class does not have a
* public constructor
* @throws ClassNotFoundException, if the class could not be reached by the
* classloader.
* @throws ClassCastException, if the class is not a subclass of
* java.security.Permission
* @throws InvocationTargetException, if the constructor in the Permission
* class throws an exception.
*/
private static Permission createPermission( String classname, String name,
String action )
throws InstantiationException, IllegalAccessException,
ClassNotFoundException,
ClassCastException, InvocationTargetException
{
if( classname == null )
{
throw new NullPointerException( "classname" );
}
ClassLoader trustedClassloader = DefaultSecurityModel.class.getClassLoader();
Class clazz = trustedClassloader.loadClass( classname );
Constructor[] constructors = clazz.getConstructors();
if( name == null )
{
return (Permission) clazz.newInstance();
}
else if( action == null )
{
Constructor cons = getConstructor( constructors, 1 );
Object[] arg = new Object[] { name };
return (Permission) cons.newInstance( arg );
}
else
{
Constructor cons = getConstructor( constructors, 2 );
Object[] args = new Object[] { name, action };
return (Permission) cons.newInstance( args );
}
}
private static Constructor getConstructor( Constructor[] constructors, int
noOfParameters )
{
for ( int i=0 ; i < constructors.length ; i++ )
{
Class[] params = constructors[i].getParameterTypes();
if( params.length == noOfParameters )
return constructors[i];
}
return null;
}
}
1.3 +11 -2
avalon/merlin/composition/impl/src/test/org/apache/avalon/composition/model/test/SystemContextBuilder.java
Index: SystemContextBuilder.java
===================================================================
RCS file:
/home/cvs/avalon/merlin/composition/impl/src/test/org/apache/avalon/composition/model/test/SystemContextBuilder.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SystemContextBuilder.java 19 Feb 2004 08:58:04 -0000 1.2
+++ SystemContextBuilder.java 25 Feb 2004 18:55:40 -0000 1.3
@@ -23,8 +23,10 @@
import org.apache.avalon.composition.model.ContainmentModel;
import org.apache.avalon.composition.model.impl.DefaultSystemContext;
+import org.apache.avalon.composition.model.impl.DefaultSecurityModel;
import org.apache.avalon.composition.provider.ModelFactory;
import org.apache.avalon.composition.provider.SystemContext;
+import org.apache.avalon.composition.provider.SecurityModel;
import org.apache.avalon.logging.provider.LoggingManager;
import org.apache.avalon.logging.data.CategoryDirective;
@@ -86,10 +88,17 @@
final File home = new File( base, "home" );
final File temp = new File( base, "temp" );
+
+ //
+ // FIX ME - build the security model from a configuration
+ //
+
+ SecurityModel security =
+ new DefaultSecurityModel( null, null, secure );
return new DefaultSystemContext(
context, null, logging, base, home, temp, repository, "system",
- false, timeout, secure );
+ false, timeout, security );
}
private static Repository createTestRepository( InitialContext context, File
cache ) throws Exception
1.32 +31 -3
avalon/merlin/kernel/impl/src/java/org/apache/avalon/merlin/impl/DefaultFactory.java
Index: DefaultFactory.java
===================================================================
RCS file:
/home/cvs/avalon/merlin/kernel/impl/src/java/org/apache/avalon/merlin/impl/DefaultFactory.java,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- DefaultFactory.java 19 Feb 2004 08:58:05 -0000 1.31
+++ DefaultFactory.java 25 Feb 2004 18:55:40 -0000 1.32
@@ -20,18 +20,25 @@
import java.io.File;
import java.io.InputStream;
+import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Locale;
+import java.security.cert.CertificateException;
import org.apache.avalon.logging.data.CategoriesDirective;
import org.apache.avalon.logging.provider.LoggingManager;
import org.apache.avalon.logging.provider.LoggingCriteria;
+import org.apache.avalon.composition.data.CertsDirective;
import org.apache.avalon.composition.data.ContainmentProfile;
+import org.apache.avalon.composition.data.GrantDirective;
+import org.apache.avalon.composition.data.PermissionDirective;
+import org.apache.avalon.composition.data.PKCS7Directive;
import org.apache.avalon.composition.data.TargetDirective;
+import org.apache.avalon.composition.data.X509Directive;
import org.apache.avalon.composition.data.builder.XMLTargetsCreator;
import org.apache.avalon.composition.data.builder.XMLComponentProfileCreator;
import org.apache.avalon.composition.data.builder.XMLContainmentProfileCreator;
@@ -41,12 +48,14 @@
import org.apache.avalon.composition.model.ClassLoaderModel;
import org.apache.avalon.composition.model.DeploymentModel;
import org.apache.avalon.composition.model.ModelRepository;
+import org.apache.avalon.composition.model.impl.DefaultSecurityModel;
import org.apache.avalon.composition.model.impl.DefaultSystemContext;
import org.apache.avalon.composition.model.impl.DefaultContainmentContext;
import org.apache.avalon.composition.model.impl.DefaultContainmentModel;
import org.apache.avalon.composition.model.impl.DefaultClassLoaderModel;
import org.apache.avalon.composition.model.impl.DefaultClassLoaderContext;
import org.apache.avalon.composition.model.impl.DefaultModelRepository;
+import org.apache.avalon.composition.provider.SecurityModel;
import org.apache.avalon.composition.provider.SystemContext;
import org.apache.avalon.composition.provider.ClassLoaderContext;
import org.apache.avalon.composition.util.StringHelper;
@@ -256,8 +265,7 @@
// install any blocks declared within the kernel context
//
- getLogger().info( "block installation" );
- getLogger().debug( "install phase" );
+ getLogger().info( "install phase" );
URL[] urls = criteria.getDeploymentURLs();
for( int i=0; i<urls.length; i++ )
{
@@ -403,6 +411,13 @@
"repository established: " + repository );
//
+ // build the security grants directive
+ //
+
+ Configuration securityConfig = config.getChild( "security" );
+ SecurityModel security = createSecurityModel( criteria, securityConfig );
+
+ //
// create the system context
//
@@ -421,13 +436,26 @@
name,
criteria.isDebugEnabled(),
criteria.getDeploymentTimeout(),
- criteria.isCodeSecurityEnabled() );
+ security );
system.put( "urn:composition:dir", criteria.getWorkingDirectory() );
system.put( "urn:composition:anchor", criteria.getAnchorDirectory() );
system.makeReadOnly();
return system;
+ }
+
+ private SecurityModel createSecurityModel(
+ KernelCriteria criteria, Configuration config ) throws Exception
+ {
+ if( !criteria.isCodeSecurityEnabled() )
+ {
+ return new DefaultSecurityModel();
+ }
+ else
+ {
+ return DefaultSecurityModel.createSecurityModel( config );
+ }
}
private ContainmentModel createApplicationModel(
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]