glenn       01/01/23 14:13:09

  Modified:    catalina/src/share/org/apache/catalina/loader
                        StandardClassLoader.java
  Log:
  Implement SecurityManager
  
  Revision  Changes    Path
  1.8       +179 -281  
jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java
  
  Index: StandardClassLoader.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- StandardClassLoader.java  2001/01/23 05:05:48     1.7
  +++ StandardClassLoader.java  2001/01/23 22:13:06     1.8
  @@ -1,7 +1,7 @@
   /*
  - * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v
 1.7 2001/01/23 05:05:48 remm Exp $
  - * $Revision: 1.7 $
  - * $Date: 2001/01/23 05:05:48 $
  + * $Header: 
/home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/loader/StandardClassLoader.java,v
 1.8 2001/01/23 22:13:06 glenn Exp $
  + * $Revision: 1.8 $
  + * $Date: 2001/01/23 22:13:06 $
    *
    * ====================================================================
    *
  @@ -65,6 +65,7 @@
   package org.apache.catalina.loader;
   
   import java.io.File;
  +import java.io.FilePermission;
   import java.io.InputStream;
   import java.io.IOException;
   import java.net.JarURLConnection;
  @@ -74,6 +75,9 @@
   import java.net.URLConnection;
   import java.net.URLStreamHandlerFactory;
   import java.net.URLStreamHandler;
  +import java.security.CodeSource;
  +import java.security.PermissionCollection;
  +import java.security.Policy;
   import java.util.ArrayList;
   import java.util.Enumeration;
   import java.util.HashMap;
  @@ -105,7 +109,7 @@
    *
    * @author Craig R. McClanahan
    * @author Remy Maucherat
  - * @version $Revision: 1.7 $ $Date: 2001/01/23 05:05:48 $
  + * @version $Revision: 1.8 $ $Date: 2001/01/23 22:13:06 $
    */
   
   public class StandardClassLoader
  @@ -123,6 +127,9 @@
       public StandardClassLoader() {
   
           super(new URL[0]);
  +     this.parent = getParent();
  +     this.system = getSystemClassLoader();
  +     securityManager = System.getSecurityManager();
   
       }
   
  @@ -150,6 +157,9 @@
       public StandardClassLoader(ClassLoader parent) {
   
           super((new URL[0]), parent);
  +     this.parent = parent;
  +     this.system = getSystemClassLoader();
  +     securityManager = System.getSecurityManager();
   
       }
   
  @@ -179,6 +189,9 @@
       public StandardClassLoader(String repositories[]) {
   
           super(convert(repositories));
  +     this.parent = getParent();
  +     this.system = getSystemClassLoader();
  +     securityManager = System.getSecurityManager();
           if (repositories != null) {
               for (int i = 0; i < repositories.length; i++)
                   addRepositoryInternal(repositories[i]);
  @@ -197,6 +210,9 @@
       public StandardClassLoader(String repositories[], ClassLoader parent) {
   
           super(convert(repositories), parent);
  +     this.parent = parent;
  +     this.system = getSystemClassLoader();
  +     securityManager = System.getSecurityManager();
           if (repositories != null) {
               for (int i = 0; i < repositories.length; i++)
                   addRepositoryInternal(repositories[i]);
  @@ -215,6 +231,9 @@
       public StandardClassLoader(URL repositories[], ClassLoader parent) {
   
           super(repositories, parent);
  +     this.parent = parent;
  +     this.system = getSystemClassLoader();
  +     securityManager = System.getSecurityManager();
           if (repositories != null) {
               for (int i = 0; i < repositories.length; i++)
                   addRepositoryInternal(repositories[i].toString());
  @@ -227,14 +246,6 @@
   
   
       /**
  -     * The set of fully qualified class or resource names to which access
  -     * will be allowed (if they exist) by this class loader, even if the
  -     * class or resource name would normally be restricted.
  -     */
  -    protected String allowed[] = new String[0];
  -
  -
  -    /**
        * The set of optional packages (formerly standard extensions) that
        * are available in the repositories associated with this class loader.
        * Each object in this list is of type
  @@ -283,23 +294,32 @@
       protected ArrayList required = new ArrayList();
   
   
  +    /**
  +     * Instance of the SecurityManager installed.
  +     */
  +    private SecurityManager securityManager = null;
  +
  +
       /**
  -     * The set of class name prefixes to which access should be restricted.
  -     * A request for a class or resource that starts with this prefix will
  -     * fail with an appropriate exception or <code>null</code> return value,
  -     * unless that specific class or resource name is on the allowed list.
  +     * The context directory path read FilePermission if this loader
  +     * is for a web application context.
        */
  -    protected String restricted[] = new String[0];
  +    private FilePermission filePermission = null;
   
   
       /**
  -     * The set of class and resource name prefixes that should be allowed,
  -     * but only from the underlying system class loader.
  +     * The parent class loader.
        */
  -    protected String systems[] = { "java." };
  +    private ClassLoader parent = null;
   
   
       /**
  +     * The system class loader.
  +     */
  +    private ClassLoader system = null;
  +
  +
  +    /**
        * URL stream handler for additional protocols.
        */
       protected URLStreamHandlerFactory factory = null;
  @@ -351,31 +371,28 @@
   
       }
   
  -
  -    // ------------------------------------------------------- Reloader Methods
  -
  -
       /**
  -     * Add a new fully qualified class or resource name to which access will be
  -     * allowed, even if the class or resource name would otherwise match one
  -     * of the restricted patterns.
  -     *
  -     * @param name Class or resource name to allow access for
  -     */
  -    public void addAllowed(String name) {
  -
  -     if (debug >= 1)
  -         log("addAllowed(" + name + ")");
  -
  -     synchronized (allowed) {
  -         String results[] = new String[allowed.length + 1];
  -            System.arraycopy(allowed, 0, results, 0, allowed.length);
  -         results[allowed.length] = name;
  -         allowed = results;
  +     * If there is a Java SecurityManager, refresh the security
  +     * policies from file and set the context security permissions.
  +     *
  +     * @param String context directory file url string
  +     */
  +    public void setPermissions(URL url) {
  +     if( securityManager != null ) {
  +         String contextDir = url.getFile();
  +         if( contextDir.endsWith(File.separator) )
  +             contextDir = contextDir + "-";
  +         else
  +             contextDir = contextDir + File.separator + "-";
  +         // Refresh the security policies
  +         Policy policy = Policy.getPolicy();
  +         policy.refresh();
  +            filePermission = new FilePermission(contextDir,"read");
        }
  -
       }
   
  +    // ------------------------------------------------------- Reloader Methods
  +
   
       /**
        * Add a new repository to the set of places this ClassLoader can look for
  @@ -411,65 +428,6 @@
   
   
       /**
  -     * Add a fully qualified class or resource name prefix that, if it matches
  -     * the name of a requested class or resource, will cause access to that
  -     * class or resource to fail (unless the complete name is on the allowed
  -     * list).
  -     *
  -     * @param prefix The restricted prefix
  -     */
  -    public void addRestricted(String prefix) {
  -
  -     if (debug >= 1)
  -         log("addRestricted(" + prefix + ")");
  -
  -     synchronized (restricted) {
  -         String results[] = new String[restricted.length + 1];
  -            System.arraycopy(restricted, 0, results, 0, restricted.length);
  -         results[restricted.length] = prefix;
  -         restricted = results;
  -     }
  -
  -    }
  -
  -
  -    /**
  -     * Add a fully qualified class or resource name prefix that, if it matches
  -     * the name of a requested class or resource, will cause access to that
  -     * class or resource to be attempted in the system class loader only
  -     * (bypassing the repositories defined in this class loader).  By default,
  -     * the <code>java.</code> prefix is defined as a system prefix.
  -     *
  -     * @param prefix The system prefix
  -     */
  -    public void addSystem(String prefix) {
  -
  -     if (debug >= 1)
  -         log("addSystem(" + prefix + ")");
  -
  -     synchronized (systems) {
  -         String results[] = new String[systems.length + 1];
  -            System.arraycopy(systems, 0, results, 0, systems.length);
  -         results[systems.length] = prefix;
  -         systems = results;
  -     }
  -
  -    }
  -
  -
  -    /**
  -     * Return a String array of the allowed class or resource name list
  -     * for this class loader.  If there are none, a zero-length array
  -     * is returned.
  -     */
  -    public String[] findAllowed() {
  -
  -     return (allowed);
  -
  -    }
  -
  -
  -    /**
        * Return a list of "optional packages" (formerly "standard extensions")
        * that have been declared to be available in the repositories associated
        * with this class loader, plus any parent class loader implemented with
  @@ -485,12 +443,12 @@
   
           // Trace our parentage tree and add declared extensions when possible
           ClassLoader loader = this;
  -        while (true) {
  -            loader = loader.getParent();
  -            if (loader == null)
  -                break;
  -            if (!(loader instanceof StandardClassLoader))
  -                continue;
  +        while (true) {                                                       
  +         loader = loader.getParent();
  +         if (loader == null)        
  +             break;        
  +         if (!(loader instanceof StandardClassLoader))
  +             continue;
               Extension extensions[] =
                   ((StandardClassLoader) loader).findAvailable();
               for (int i = 0; i < extensions.length; i++)
  @@ -533,7 +491,7 @@
           // Trace our parentage tree and add declared extensions when possible
           ClassLoader loader = this;
           while (true) {
  -            loader = loader.getParent();
  +         loader = loader.getParent();
               if (loader == null)
                   break;
               if (!(loader instanceof StandardClassLoader))
  @@ -552,30 +510,6 @@
   
   
       /**
  -     * Return a String array of the restricted class or resource name prefixes
  -     * for this class loader.  If there are none, a zero-length array
  -     * is returned.
  -     */
  -    public String[] findRestricted() {
  -
  -     return (restricted);
  -
  -    }
  -
  -
  -    /**
  -     * Return a Striong array of the sytsem class or resource name prefixes
  -     * for this class loader.  If there are none, a zero-length array
  -     * is returned.
  -     */
  -    public String[] findSystem() {
  -
  -     return (systems);
  -
  -    }
  -
  -
  -    /**
        * Have one or more classes or resources been modified so that a reload
        * is appropriate?
        * <p>
  @@ -636,13 +570,6 @@
       public String toString() {
   
           StringBuffer sb = new StringBuffer("StandardClassLoader\r\n");
  -        sb.append("  allowed: ");
  -        for (int i = 0; i < allowed.length; i++) {
  -            if (i > 0)
  -                sb.append(", ");
  -            sb.append(allowed[i]);
  -        }
  -        sb.append("\r\n");
           sb.append("  available:\r\n");
           Iterator available = this.available.iterator();
           while (available.hasNext()) {
  @@ -666,20 +593,7 @@
               sb.append(required.next().toString());
               sb.append("\r\n");
           }
  -        sb.append("  restricted: ");
  -        for (int i = 0; i < restricted.length; i++) {
  -            if (i > 0)
  -                sb.append(", ");
  -            sb.append(restricted[i]);
  -        }
           sb.append("\r\n");
  -        sb.append("  systems: ");
  -        for (int i = 0; i < systems.length; i++) {
  -            if (i > 0)
  -                sb.append(", ");
  -            sb.append(systems[i]);
  -        }
  -        sb.append("\r\n");
           return (sb.toString());
   
       }
  @@ -701,6 +615,20 @@
           if (debug >= 3)
               log("    findClass(" + name + ")");
   
  +        // (1) Permission to define this class when using a SecurityManager
  +        if (securityManager != null) {
  +            int i = name.lastIndexOf('.');
  +            if (i >= 0) {
  +                try {
  +                    securityManager.checkPackageDefinition(name.substring(0,i));
  +                } catch (SecurityException se) {
  +                    String error = "Security Violation, attempt to define " +
  +                        "a Class in a restricted package: " + name;
  +                    throw new ClassNotFoundException(error);
  +                }
  +            }
  +        }
  +
           // Ask our superclass to locate this class, if possible
           // (throws ClassNotFoundException if it is not found)
           Class clazz = null;
  @@ -758,13 +686,6 @@
           if (debug >= 3)
               log("    findResource(" + name + ")");
   
  -        // Check for attempts to load restricted classes
  -        if (restricted(name)) {
  -            if (debug >= 2)
  -                log("  Rejecting restricted resource name");
  -            return (null);
  -        }
  -
           URL url = super.findResource(name);
           if (debug >= 3) {
               if (url != null)
  @@ -822,48 +743,47 @@
           if (debug >= 2)
               log("getResource(" + name + ")");
           URL url = null;
  -        boolean isSystem = system(name);
   
           // (1) Delegate to parent if requested
  -        if (delegate || isSystem) {
  +        if (delegate) {
               if (debug >= 3)
                   log("  Delegating to parent classloader");
  -            ClassLoader parent = getParent();
  -            if (parent == null)
  -                parent = getSystemClassLoader();
  -            url = parent.getResource(name);
  +            ClassLoader loader = parent;
  +            if (loader == null)
  +                loader = system;
  +            url = loader.getResource(name);
               if (url != null) {
                   if (debug >= 2)
                       log("  --> Returning '" + url.toString() + "'");
                   return (url);
               }
  -        }
  -
  +        }    
  +         
           // (2) Search local repositories
  -        if (!isSystem) {
  -            if (debug >= 3)
  -                log("  Searching local repositories");
  -            url = findResource(name);
  -            if (url != null) {
  -                if (debug >= 2)
  -                    log("  --> Returning '" + url.toString() + "'");
  -                return (url);
  -            }
  -        }
  -
  -        // (3) Delegate to parent unconditionally
  -        ClassLoader parent = getParent();
  -        if (parent == null)
  -            parent = getSystemClassLoader();
  -        url = parent.getResource(name);
  +        if (debug >= 3)
  +            log("  Searching local repositories");
  +        url = findResource(name);
           if (url != null) {
               if (debug >= 2)
                   log("  --> Returning '" + url.toString() + "'");
               return (url);
  -        }
  -
  +        }                 
  +            
  +        // (3) Delegate to parent unconditionally if not already attempted
  +     if( !delegate ) {
  +         ClassLoader loader = parent;
  +         if (loader == null)
  +             loader = system;
  +         url = loader.getResource(name);
  +         if (url != null) {
  +             if (debug >= 2)
  +                 log("  --> Returning '" + url.toString() + "'");
  +             return (url); 
  +         }
  +        }                 
  +                        
           // (4) Resource was not found
  -        if (debug >= 2)
  +        if (debug >= 2)   
               log("  --> Resource not found, returning null");
           return (null);
   
  @@ -884,7 +804,6 @@
           if (debug >= 2)
               log("getResourceAsStream(" + name + ")");
           InputStream stream = null;
  -        boolean isSystem = system(name);
   
           // (0) Check for a cached copy of this resource
           stream = findLoadedResource(name);
  @@ -895,13 +814,13 @@
           }
   
           // (1) Delegate to parent if requested
  -        if (delegate || isSystem) {
  +        if (delegate) {
               if (debug >= 3)
                   log("  Delegating to parent classloader");
  -            ClassLoader parent = getParent();
  -            if (parent == null)
  -                parent = getSystemClassLoader();
  -            stream = parent.getResourceAsStream(name);
  +            ClassLoader loader = parent;
  +            if (loader == null)
  +                loader = system;
  +            stream = loader.getResourceAsStream(name);
               if (stream != null) {
                   // FIXME - cache???
                   if (debug >= 2)
  @@ -911,31 +830,29 @@
           }
   
           // (2) Search local repositories
  -        if (!isSystem) {
  -            if (debug >= 3)
  -                log("  Searching local repositories");
  -            URL url = findResource(name);
  -            if (url != null) {
  -                // FIXME - cache???
  -                if (debug >= 2)
  -                    log("  --> Returning stream from local");
  -                try {
  -                    return (url.openStream());
  -                } catch (IOException e) {
  -                    log("url.openStream(" + url.toString() + ")", e);
  -                    return (null);
  -                }
  +        if (debug >= 3)
  +            log("  Searching local repositories");
  +        URL url = findResource(name);
  +        if (url != null) {
  +            // FIXME - cache???
  +            if (debug >= 2)
  +                log("  --> Returning stream from local");
  +            try {
  +               return (url.openStream());
  +            } catch (IOException e) {
  +               log("url.openStream(" + url.toString() + ")", e);
  +               return (null);
               }
           }
   
           // (3) Delegate to parent unconditionally
  -        if (delegate) {
  +        if (!delegate) {
               if (debug >= 3)
                   log("  Delegating to parent classloader");
  -            ClassLoader parent = getParent();
  -            if (parent == null)
  -                parent = getSystemClassLoader();
  -            stream = parent.getResourceAsStream(name);
  +            ClassLoader loader = parent;
  +            if (loader == null)
  +                loader = system;
  +            stream = loader.getResourceAsStream(name);
               if (stream != null) {
                   // FIXME - cache???
                   if (debug >= 2)
  @@ -999,15 +916,7 @@
           if (debug >= 2)
               log("loadClass(" + name + ", " + resolve + ")");
           Class clazz = null;
  -        boolean isSystem = system(name);
   
  -        // Check for attempts to load restricted classes
  -        if (restricted(name)) {
  -            if (debug >= 2)
  -                log("  Rejecting restricted class name");
  -            throw new ClassNotFoundException("Restricted Clas: " + name);
  -        }
  -
           // (0) Check our previously loaded class cache
           clazz = findLoadedClass(name);
           if (clazz != null) {
  @@ -1018,15 +927,31 @@
               return (clazz);
           }
   
  +        // (.5) Permission to access this class when using a SecurityManager
  +        if (securityManager != null) {
  +            int i = name.lastIndexOf('.');
  +            if (i >= 0) {
  +                try {    
  +                    securityManager.checkPackageAccess(name.substring(0,i));
  +                } catch (SecurityException se) {
  +                    String error = "Security Violation, attempt to use " +
  +                        "Restricted Class: " + name;
  +                 System.out.println(error);
  +                    log(error);
  +                    throw new ClassNotFoundException(error);
  +                }
  +            }    
  +        }
  +
           // (1) Delegate to our parent if requested
  -        if (delegate || isSystem) {
  +        if (delegate) {
               if (debug >= 3)
                   log("  Delegating to parent classloader");
  -            ClassLoader parent = getParent();
  -            if (parent == null)
  -                parent = getSystemClassLoader();
  +            ClassLoader loader = parent;
  +            if (loader == null)
  +                loader = system;
               try {
  -                clazz = parent.loadClass(name);
  +                clazz = loader.loadClass(name);
                   if (clazz != null) {
                       if (debug >= 3)
                           log("  Loading class from parent");
  @@ -1040,32 +965,30 @@
           }
   
           // (2) Search local repositories
  -        if (!isSystem) {
  -            if (debug >= 3)
  -                log("  Searching local repositories");
  -            try {
  -                clazz = findClass(name);
  -                if (clazz != null) {
  -                    if (debug >= 3)
  -                        log("  Loading class from local repository");
  -                    if (resolve)
  -                        resolveClass(clazz);
  -                    return (clazz);
  -                }
  -            } catch (ClassNotFoundException e) {
  -                ;
  +        if (debug >= 3)
  +            log("  Searching local repositories");
  +        try {
  +            clazz = findClass(name);
  +            if (clazz != null) {
  +                if (debug >= 3)
  +                    log("  Loading class from local repository");
  +                if (resolve)
  +                    resolveClass(clazz);
  +                return (clazz);
               }
  +        } catch (ClassNotFoundException e) {
  +            ;
           }
   
           // (3) Delegate to parent unconditionally
  -        if (!delegate && !isSystem) {
  +        if (!delegate) {
               if (debug >= 3)
                   log("  Delegating to parent classloader");
  -            ClassLoader parent = getParent();
  -            if (parent == null)
  -                parent = getSystemClassLoader();
  +            ClassLoader loader = parent;
  +            if (loader == null)
  +             loader = system;
               try {
  -                clazz = parent.loadClass(name);
  +                clazz = loader.loadClass(name);
                   if (clazz != null) {
                       if (debug >= 3)
                           log("  Loading class from parent");
  @@ -1084,6 +1007,21 @@
       }
   
   
  +    /**
  +     * Get the Permissions for a CodeSource.  If this instance
  +     * of StandardClassLoader is for a web application context,
  +     * add FilePermission "context root", "read".
  +     *
  +     * @param CodeSource where the code was loaded from
  +     * @return PermissionCollection for CodeSource
  +     */
  +    protected final PermissionCollection getPermissions(CodeSource codeSource) {
  +     PermissionCollection pc = super.getPermissions(codeSource);
  +     if( filePermission != null && pc != null)
  +         pc.add(filePermission);
  +     return pc;
  +    }
  +
       // ------------------------------------------------------ Protected Methods
   
   
  @@ -1254,46 +1192,6 @@
   
        System.out.println("StandardClassLoader: " + message);
        throwable.printStackTrace(System.out);
  -
  -    }
  -
  -
  -    /**
  -     * Is this a class or resource that should not be allowed to load
  -     * in this class loader?
  -     *
  -     * @param name Name of the class or resource to be checked
  -     */
  -    private boolean restricted(String name) {
  -
  -     for (int i = 0; i < allowed.length; i++) {
  -         if (name.equals(allowed[i]))
  -             return (false);
  -     }
  -
  -     for (int i = 0; i < restricted.length; i++) {
  -         if (name.startsWith(restricted[i]))
  -             return (true);
  -     }
  -
  -     return (false);
  -
  -    }
  -
  -
  -    /**
  -     * Is this a class or resource that should be loaded only by the
  -     * system class loader?
  -     *
  -     * @param name Name of the class or resource to be checked
  -     */
  -    private boolean system(String name) {
  -
  -        for (int i = 0; i < systems.length; i++) {
  -            if (name.startsWith(systems[i]))
  -                return (true);
  -        }
  -        return (false);
   
       }
   
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to