You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Mats Forslöf <ma...@marcwell.se> on 2004/03/23 19:04:58 UTC

[Patch] Tapestry 3.0 RC1 in secure Tomcat 5.0

Hi all,

I've been struggling with Tapestry 3 in a secured Tomcat 5 for some time now
but I have found a way to make this work (both with and without a security
manager). It involves some patches to Tapestry files and a default set of
java permissions. The java security manager uses a policy file with static
code bases to determine what protection domain a class should belong to and
subsequently what permission it is granted. A protection domain consist of a
code source, a class loader, an array of principals and a set of
permissions. Since Tapestry creates and loads classes dynamically the
dynamic classes must be set to belong to a defined protection domain,
currently this does not take place. The effect is that you cannot set
permissions to the dynamic classes in the policy file other than using
global permissions, which counteracts the whole idea of security.

However, this can easily be fixed by adding a protection domain to the
Tapestry class loader that loads the dynamic classes. The files in a need
for a patch is EnhancedClassLoader.java and EnhancedClass.java, see below.
All additions/changes are marked PATCH.

EnhancedClassLoader.java: 
-------------------------
// PATCH: new import
import java.security.ProtectionDomain;

 . . .

    // PATCH: new parameter - protectionDomain
    public Class defineClass(String enhancedClassName, byte[] byteCode,
ProtectionDomain protectionDomain)
    {
        try
        {
            // PATCH: forward protectDomain parameter to super class loader
            return defineClass(enhancedClassName, byteCode, 0,
byteCode.length, protectionDomain);
        }
        catch (Throwable ex)
        {
            throw new ApplicationRuntimeException(
                Tapestry.format(
                    "EnhancedClassLoader.unable-to-define-class",
                    enhancedClassName,
                    ex.getMessage()),
                ex);
        }
    }

EnhancedClass.java:
-------------------
// PATCH: new import
import java.security.ProtectionDomain;

 . . .

    public Class createEnhancedSubclass()
    {
        performEnhancement();

        ClassFabricator cf = getClassFabricator();
        cf.commit();
        
        String enhancedClassName = getClassName();
        byte[] enhancedClassBytes = cf.getByteCode();
        
        // PATCH: use protection domain of parent class
        EnhancedClassLoader loader = _classFactory.getEnhancedClassLoader();
        return loader.defineClass(enhancedClassName,
enhancedClassBytes,_parentClass.getProtectionDomain());
    }

Now, to be able to run a Tapestry application in a secured Tomcat you'll
need a set of default permissions for a bunch of the included libraries.
Using a default Tomcat policy file you can add the following entries (based
on the assumption that the Tapestry libs are located in shared/lib). This is
the minimum set of permissions.

Catalina.policy:
----------------
// OGNL
grant codeBase "file:${catalina.home}/shared/lib/ognl-2.6.3.jar" {

   permission java.io.FilePermission "${catalina.home}\\webapps\\myapp\\-",
"read";

   permission ognl.OgnlInvokePermission "invoke.*";
   permission java.util.PropertyPermission "ognl.*", "read";

   permission java.lang.RuntimePermission "accessDeclaredMembers";

};

// Javassist
grant codeBase "file:${catalina.home}/shared/lib/javassist-2.5.1.jar" {

   permission java.io.FilePermission
"${catalina.home}\\shared\\lib\\tapestry-3.0-rc-1.jar", "read";
   permission java.io.FilePermission "${catalina.home}\\webapps\\myapp\\-",
"read";
   permission java.io.FilePermission "${java.home}\\lib\\-", "read";

   permission java.lang.RuntimePermission "createClassLoader";

};

// Tapestry
grant codeBase "file:${catalina.home}/shared/lib/tapestry-3.0-rc-1.jar" {

   permission java.io.FilePermission "${catalina.home}\\webapps\\myapp\\-",
"read";
   permission java.io.FilePermission "${java.home}\\lib\\-", "read";

   permission ognl.OgnlInvokePermission "invoke.*";
   permission java.util.PropertyPermission "ognl.*", "read";

   permission java.util.PropertyPermission "org.apache.*", "read";
   permission java.util.PropertyPermission "java.class.path", "read";

   permission java.lang.RuntimePermission "createClassLoader";
   permission java.lang.RuntimePermission "getProtectionDomain";
   permission java.lang.RuntimePermission "accessDeclaredMembers";

};

// BSF
grant codeBase "file:${catalina.home}/shared/lib/bsf-2.3.0.jar" {

   permission java.util.PropertyPermission "org.apache.*", "read";

};

// BeanUtils
grant codeBase
"file:${catalina.home}/shared/lib/commons-beanutils-1.6.1.jar" {

   permission java.io.FilePermission "${catalina.home}\\webapps\\myapp\\-",
"read";

};

// Digester
grant codeBase "file:${catalina.home}/shared/lib/commons-digester-1.5.jar" {

   permission java.io.FilePermission
"${catalina.home}\\shared\\lib\\tapestry-3.0-rc-1.jar", "read";
   permission java.io.FilePermission "${catalina.home}\\webapps\\myapp\\-",
"read";

};

// Web application
grant codeBase "file:${catalina.home}/webapps/myapp/-" {

   permission java.io.FilePermission
"${catalina.home}\\shared\\lib\\tapestry-3.0-rc-1.jar", "read";
   permission java.io.FilePermission "${java.home}\\lib\\-", "read";

   permission ognl.OgnlInvokePermission "invoke.*";

   permission java.util.PropertyPermission "org.apache.*", "read";
   permission java.util.PropertyPermission "java.class.path", "read";

   permission java.lang.RuntimePermission "getProtectionDomain";
   permission java.lang.RuntimePermission "accessDeclaredMembers";

   // Plus any other needed application permissions

};

I've tested this using J2SE 1.4.2, Tapestry 3.0 RC1 and Tomcat 5.0.19
together with a simple "Hello World" app. If you are going to run this on
Unix you need to adapt the path separators in the permission paths.

Regards,
Mats Forslöf


---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org