- As suggested by Mladen, add a more robust mechanism for restricted servlets.
authorremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 3 May 2006 08:07:02 +0000 (08:07 +0000)
committerremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 3 May 2006 08:07:02 +0000 (08:07 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@399196 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/core/RestrictedServlets.properties [new file with mode: 0644]
java/org/apache/catalina/core/StandardWrapper.java

diff --git a/java/org/apache/catalina/core/RestrictedServlets.properties b/java/org/apache/catalina/core/RestrictedServlets.properties
new file mode 100644 (file)
index 0000000..2f8245e
--- /dev/null
@@ -0,0 +1,3 @@
+org.apache.catalina.ssi.SSIServlet=restricted
+org.apache.catalina.servlets.CGIServlet=restricted
+org.apache.catalina.servlets.InvokerServlet=restricted
index c107ef8..c9e9a78 100644 (file)
 package org.apache.catalina.core;\r
 \r
 import java.lang.reflect.Method;\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
 import java.io.PrintStream;\r
 import java.util.ArrayList;\r
 import java.util.Enumeration;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
+import java.util.Properties;\r
 import java.util.Stack;\r
 import java.security.AccessController;\r
 import java.security.PrivilegedActionException;\r
@@ -73,10 +76,10 @@ public class StandardWrapper
     extends ContainerBase\r
     implements ServletConfig, Wrapper, NotificationEmitter {\r
 \r
-    private static org.apache.commons.logging.Log log=\r
+    protected static org.apache.commons.logging.Log log=\r
         org.apache.commons.logging.LogFactory.getLog( StandardWrapper.class );\r
 \r
-    private static final String[] DEFAULT_SERVLET_METHODS = new String[] {\r
+    protected static final String[] DEFAULT_SERVLET_METHODS = new String[] {\r
                                                     "GET", "HEAD", "POST" };\r
 \r
     // ----------------------------------------------------------- Constructors\r
@@ -92,6 +95,22 @@ public class StandardWrapper
         pipeline.setBasic(swValve);\r
         broadcaster = new NotificationBroadcasterSupport();\r
 \r
+        if (restrictedServlets == null) {\r
+            restrictedServlets = new Properties();\r
+            try {\r
+                InputStream is = \r
+                    this.getClass().getClassLoader().getResourceAsStream\r
+                        ("org/apache/catalina/core/RestrictedServlets.properties");\r
+                if (is != null) {\r
+                    restrictedServlets.load(is);\r
+                } else {\r
+                    log.error(sm.getString("standardWrapper.restrictedServletsResources"));\r
+                }\r
+            } catch (IOException e) {\r
+                log.error(sm.getString("standardWrapper.restrictedServletsResources"), e);\r
+            }\r
+        }\r
+        \r
     }\r
 \r
 \r
@@ -104,70 +123,70 @@ public class StandardWrapper
      * If this value equals Long.MAX_VALUE, the unavailability of this\r
      * servlet is considered permanent.\r
      */\r
-    private long available = 0L;\r
+    protected long available = 0L;\r
     \r
     /**\r
      * The broadcaster that sends j2ee notifications. \r
      */\r
-    private NotificationBroadcasterSupport broadcaster = null;\r
+    protected NotificationBroadcasterSupport broadcaster = null;\r
     \r
     /**\r
      * The count of allocations that are currently active (even if they\r
      * are for the same instance, as will be true on a non-STM servlet).\r
      */\r
-    private int countAllocated = 0;\r
+    protected int countAllocated = 0;\r
 \r
 \r
     /**\r
      * The facade associated with this wrapper.\r
      */\r
-    private StandardWrapperFacade facade =\r
+    protected StandardWrapperFacade facade =\r
         new StandardWrapperFacade(this);\r
 \r
 \r
     /**\r
      * The descriptive information string for this implementation.\r
      */\r
-    private static final String info =\r
+    protected static final String info =\r
         "org.apache.catalina.core.StandardWrapper/1.0";\r
 \r
 \r
     /**\r
      * The (single) initialized instance of this servlet.\r
      */\r
-    private Servlet instance = null;\r
+    protected Servlet instance = null;\r
 \r
 \r
     /**\r
      * The support object for our instance listeners.\r
      */\r
-    private InstanceSupport instanceSupport = new InstanceSupport(this);\r
+    protected InstanceSupport instanceSupport = new InstanceSupport(this);\r
 \r
 \r
     /**\r
      * The context-relative URI of the JSP file for this servlet.\r
      */\r
-    private String jspFile = null;\r
+    protected String jspFile = null;\r
 \r
 \r
     /**\r
      * The load-on-startup order value (negative value means load on\r
      * first call) for this servlet.\r
      */\r
-    private int loadOnStartup = -1;\r
+    protected int loadOnStartup = -1;\r
 \r
 \r
     /**\r
      * Mappings associated with the wrapper.\r
      */\r
-    private ArrayList mappings = new ArrayList();\r
+    protected ArrayList mappings = new ArrayList();\r
 \r
 \r
     /**\r
      * The initialization parameters for this servlet, keyed by\r
      * parameter name.\r
      */\r
-    private HashMap parameters = new HashMap();\r
+    protected HashMap parameters = new HashMap();\r
 \r
 \r
     /**\r
@@ -175,97 +194,104 @@ public class StandardWrapper
      * used in the servlet.  The corresponding value is the role name of\r
      * the web application itself.\r
      */\r
-    private HashMap references = new HashMap();\r
+    protected HashMap references = new HashMap();\r
 \r
 \r
     /**\r
      * The run-as identity for this servlet.\r
      */\r
-    private String runAs = null;\r
+    protected String runAs = null;\r
 \r
     /**\r
      * The notification sequence number.\r
      */\r
-    private long sequenceNumber = 0;\r
+    protected long sequenceNumber = 0;\r
 \r
     /**\r
      * The fully qualified servlet class name for this servlet.\r
      */\r
-    private String servletClass = null;\r
+    protected String servletClass = null;\r
 \r
 \r
     /**\r
      * Does this servlet implement the SingleThreadModel interface?\r
      */\r
-    private boolean singleThreadModel = false;\r
+    protected boolean singleThreadModel = false;\r
 \r
 \r
     /**\r
      * Are we unloading our servlet instance at the moment?\r
      */\r
-    private boolean unloading = false;\r
+    protected boolean unloading = false;\r
 \r
 \r
     /**\r
      * Maximum number of STM instances.\r
      */\r
-    private int maxInstances = 20;\r
+    protected int maxInstances = 20;\r
 \r
 \r
     /**\r
      * Number of instances currently loaded for a STM servlet.\r
      */\r
-    private int nInstances = 0;\r
+    protected int nInstances = 0;\r
 \r
 \r
     /**\r
      * Stack containing the STM instances.\r
      */\r
-    private Stack instancePool = null;\r
+    protected Stack instancePool = null;\r
 \r
     \r
     /**\r
      * Wait time for servlet unload in ms.\r
      */\r
-    private long unloadDelay = 2000;\r
+    protected long unloadDelay = 2000;\r
     \r
 \r
     /**\r
      * True if this StandardWrapper is for the JspServlet\r
      */\r
-    private boolean isJspServlet;\r
+    protected boolean isJspServlet;\r
 \r
 \r
     /**\r
      * The ObjectName of the JSP monitoring mbean\r
      */\r
-    private ObjectName jspMonitorON;\r
+    protected ObjectName jspMonitorON;\r
 \r
 \r
     /**\r
      * Should we swallow System.out\r
      */\r
-    private boolean swallowOutput = false;\r
+    protected boolean swallowOutput = false;\r
 \r
     // To support jmx attributes\r
-    private StandardWrapperValve swValve;\r
-    private long loadTime=0;\r
-    private int classLoadTime=0;\r
+    protected StandardWrapperValve swValve;\r
+    protected long loadTime=0;\r
+    protected int classLoadTime=0;\r
     \r
     /**\r
      * Static class array used when the SecurityManager is turned on and \r
      * <code>Servlet.init</code> is invoked.\r
      */\r
-    private static Class[] classType = new Class[]{ServletConfig.class};\r
+    protected static Class[] classType = new Class[]{ServletConfig.class};\r
     \r
     \r
     /**\r
      * Static class array used when the SecurityManager is turned on and \r
      * <code>Servlet.service</code>  is invoked.\r
      */                                                 \r
-    private static Class[] classTypeUsedInService = new Class[]{\r
+    protected static Class[] classTypeUsedInService = new Class[]{\r
                                                          ServletRequest.class,\r
                                                          ServletResponse.class};\r
+    \r
+    /**\r
+     * Restricted servlets (which can only be loaded by a privileged webapp).\r
+     */\r
+    protected static Properties restrictedServlets = null;\r
+    \r
+    \r
     // ------------------------------------------------------------- Properties\r
 \r
 \r
@@ -1535,7 +1561,7 @@ public class StandardWrapper
     // -------------------------------------------------------- Package Methods\r
 \r
 \r
-    // -------------------------------------------------------- Private Methods\r
+    // -------------------------------------------------------- protected Methods\r
 \r
 \r
     /**\r
@@ -1558,7 +1584,7 @@ public class StandardWrapper
      *\r
      * @param classname Name of the class to be checked\r
      */\r
-    private boolean isContainerProvidedServlet(String classname) {\r
+    protected boolean isContainerProvidedServlet(String classname) {\r
 \r
         if (classname.startsWith("org.apache.catalina.")) {\r
             return (true);\r
@@ -1577,24 +1603,31 @@ public class StandardWrapper
     /**\r
      * Return <code>true</code> if loading this servlet is allowed.\r
      */\r
-    private boolean isServletAllowed(Object servlet) {\r
+    protected boolean isServletAllowed(Object servlet) {\r
 \r
+        // Privileged webapps may load all servlets without restriction\r
+        if (((Context) getParent()).getPrivileged()) {\r
+            return true;\r
+        }\r
+        \r
         if (servlet instanceof ContainerServlet) {\r
-            if (((Context) getParent()).getPrivileged()\r
-                || (servlet.getClass().getName().equals\r
-                    ("org.apache.catalina.servlets.InvokerServlet"))) {\r
-                return (true);\r
-            } else {\r
+            return (false);\r
+        }\r
+\r
+        Class clazz = servlet.getClass();\r
+        while (clazz != null && !clazz.getName().equals("javax.servlet.http.HttpServlet")) {\r
+            if ("restricted".equals(restrictedServlets.getProperty(clazz.getName()))) {\r
                 return (false);\r
             }\r
+            clazz = clazz.getSuperclass();\r
         }\r
-\r
+        \r
         return (true);\r
 \r
     }\r
 \r
 \r
-    private Method[] getAllDeclaredMethods(Class c) {\r
+    protected Method[] getAllDeclaredMethods(Class c) {\r
 \r
         if (c.equals(javax.servlet.http.HttpServlet.class)) {\r
             return null;\r
@@ -1776,7 +1809,7 @@ public class StandardWrapper
        \r
     }\r
     \r
-    private MBeanNotificationInfo[] notificationInfo;\r
+    protected MBeanNotificationInfo[] notificationInfo;\r
     \r
     /* Get JMX Broadcaster Info\r
      * @TODO use StringManager for international support!\r