You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@locus.apache.org on 2000/05/26 20:55:36 UTC
cvs commit: jakarta-tomcat/src/shell tomcat.bat tomcat.sh
costin 00/05/26 11:55:34
Modified: src/native/apache2.0 Makefile.linux
src/share/org/apache/jasper Constants.java
EmbededServletOptions.java JspC.java Options.java
src/share/org/apache/jasper/compiler Compiler.java
JikesJavaCompiler.java JspCompiler.java
src/share/org/apache/jasper/runtime JspLoader.java
JspServlet.java
src/share/org/apache/tomcat/context DefaultCMSetter.java
src/share/org/apache/tomcat/core Constants.java Context.java
ContextManager.java Response.java
ServletLoader.java
src/share/org/apache/tomcat/loader AdaptiveClassLoader.java
AdaptiveServletLoader.java
ServletClassLoaderImpl.java
src/share/org/apache/tomcat/startup Tomcat.java
src/shell tomcat.bat tomcat.sh
Added: src/doc/uguide tomcat_security.txt
src/etc server2.xml tomcat.policy
src/share/org/apache/tomcat/loader ClassRepository.java
SetSecurityManager.java
src/share/org/apache/tomcat/startup HostConfig.java
Removed: src/etc server.dtd
Log:
Added the security patch from Glenn Nielsen (glenn@more.net).
I did few changes and made it work with jdk1.1.8 - of course security will not
be available, but you can still use all other features.
A new server2.xml file will be used for all the JDK1.2-specific components. The old server.xml
will keep all stable and JDK1.1.8 components. IF you use JDK1.1 you'll need to
specifiy -f server.xml flag.
You should be able now to run "untrusted" code in tomcat. Please note that this is NOT
a supported feature - security is a long process and needs a LOT of review. There are still
few components that have no facade ( class loader, the I/O streams), that will
be fixed soon, and also core will be made more restrictive to prevent access.
There are many things to do in this are - but most important is to read the code and
understand how it works, and make sure we're safer than a browser running applets.
Submitted by: Glenn Nielsen (glenn@more.net)
Revision Changes Path
1.1 jakarta-tomcat/src/doc/uguide/tomcat_security.txt
Index: tomcat_security.txt
===================================================================
Using the Java SecurityManager with Tomcat
Why use a SecurityManager?
--------------------------
The Java SecurityManager is what allows your browser to run an applet
in its own sandbox to prevent untrusted code from accessing files
on your local system, connecting to a host other than the one the
applet was loaded from, etc.
In the same way the SecurityManager protects you from an untrusted
applet running in your browser, use of a SecurityManager while running
Tomcat can protect your server from trojan servlets, JSP's, JSP beans,
and tag libraries. Or even inadvertant mistakes.
Imagine if someone who is authorized to publish JSP's on your site
invadvertantly included the following in their JSP:
<% System.exit(1); %>
Everytime that JSP was executed by Tomcat, Tomcat would exit.
Using the Java SecurityManager is just one more line of defense
a system administrator can use to keep the server secure and reliable.
System Requirements
-------------------
Use of the SecurityManager requires a JVM that supports JDK 1.2.
Precautions
-----------
Implementation of a SecurityManager in Tomcat has not been fully
tested to ensure the security of Tomcat. No special Permissions
have been created to prevent access to internal Tomcat classes
by JSP's, web applications, servlets, beans, and tag libraries.
Make sure that you are satisfied with your SecurityManager
configuration before allowing untrusted users to publish
web applications, JSP's, servlets, beans, or tag-libraries.
Still, running with a SecurityManager is definitely better than
running without one.
Types of Permissions
--------------------
Permission classes are used to define what Permissions
a class loaded by Tomcat will have. There are a number
of Permission classes as part of the JDK and you can even
create your own Permission class for use in your own
web applications.
This is just a short summary of the System SecurityManager
Permission classes applicable to Tomcat. Please refer to
the JDK documenation for more information on using the below
Permissions.
java.util.PropertyPermission
Controls read/write access to JVM properties such as java.home.
java.lang.RuntimePermission
Controls use of some System/Runtime functions like exit() and exec().
java.io.FilePermission
Controls read/write/execute access to files and directories.
java.net.SocketPermission
Controls use of network sockets.
java.net.NetPermission
Controls use of multicast network connections.
java.lang.reflect.ReflectPermission
Controls use of reflection to do class introspection.
java.security.SecurityPermission
Controls access to Security methods.
java.security.AllPermission
Allows access to all permissions, just as if you were running
Tomcat without a SecurityManager.
Configuring Tomcat for use with a SecurityManager
-------------------------------------------------
conf/tomcat.policy
Used to configure global Permissions for java packages installed
in classpaths searchable by the JVM and for specifying default
Permissions for classes loaded from other sources. This is not
where Permissions are configured for web application Context's.
There should be entries with a codeBase of "file:${java.home}/lib/ext/-"
and "file:${tomcat.home}/lib/-" which grant AllPermissions.
And a default grant entry with no codeBase which has very
restrictive Permissions configured.
Edit the conf/tomcat.policy file and replace ${tomcat.home} with
the path to your Tomcat home directory.
The tomcat.policy file replaces any system java.policy file.
conf/server.xml.security
This is an example server.xml file with a SecurityManager and Permissions
configured. You can use this as a starting point for configuring
your own Permissions.
There are two elements you can use to configure Security and Permissions
in server.xml.
<SecurityManager className="java.security.SecurityManager">
<Permission className="java.lang.RuntimePermission" attribute="stopThread"/>
<Permission className="java.util.PropertyPermission" attribute="java.version" value="read"/>
</SecurityManager>
If Tomcat is started with -security, the above element is used to
contain the default Permissions given to web application Context's.
The JVM java.security.SecurityManager will be used by default as
the SecurityManager unless you define an alternate SecurityManager
using the className attribute.
In addition to the Permissions you define above, the web application
will be given a FilePermission "read" access to its docBase.
To override the default Permissions given to a web application as
configured in the SecurityManager element use the Permission element
within the Context element you want to assign a different Permission
set.
<Context path="/examples" docBase="webapps/examples" debug="0" reloadable="true" >
<Permission className="java.io.FilePermission" attribute="/usr/local/tomcat/webapps/examples/-" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.version" value="read" />
</Context>
You must assign Permissions you want to grant including FilePermission's
when configuring Permissions in a Context.
You might configure Permissions for a Context when you want to grant
a different Permission set from the default configured using the
SecurityManager element.
The Permission element requires that the className for the Permission
class be configured and that the attribute be configured. The value
is optional. These attributes and values match the arguments passed
to the constructor for each type of Permission.
The above SecurityManager and Permission configurations will be
ignored if Tomcat is started without the "-security" option.
Starting Tomcat with a SecurityManager
--------------------------------------
Once you have configured the tomcat.policy and server.xml
files for use with a SecurityManager, Tomcat can be started
with the SecurityManager in place by using the "-security"
opton to bin/startup.bat or bin/startup.sh.
What happens when the SecurityManager detects a Security violation?
-------------------------------------------------------------------
The JVM will throw an AccessControlException or a SecurityException
when the SecurityManager detects a security policy violation.
1.1 jakarta-tomcat/src/etc/server2.xml
Index: server2.xml
===================================================================
<?xml version="1.0" encoding="ISO-8859-1"?>
<Server>
<!-- Debug low-level events in XmlMapper startup -->
<xmlmapper:debug level="0" />
<!-- This is quite flexible; we can either have a log file per
module in Tomcat (example: ContextManager) or we can have
one for Servlets and one for Jasper, or we can just have
one tomcat.log for both Servlet and Jasper.
If you omit "path" there, then stderr should be used.
verbosityLevel values can be:
FATAL
ERROR
WARNING
INFORMATION
DEBUG
-->
<SecurityManager className="java.lang.SecurityManager">
<!-- Set Default Security Policies for webapps and jsp -->
<!-- default permissions granted to all domains -->
<Permission className="java.lang.RuntimePermission" attribute="stopThread"/>
<!-- allows anyone to listen on un-privileged ports -->
<Permission className="java.net.SocketPermission" attribute="localhost:1024-" value="listen"/>
<Permission className="java.util.PropertyPermission" attribute="java.version" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.vendor" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.vendor.url" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.class.version" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="file.separator" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="path.separator" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="line.separator" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.specification.version" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.specification.vendor" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.specification.name" value="read"/>
</SecurityManager>
<Logger name="tc_log"
path="logs/tomcat.log"
customOutput="yes" />
<Logger name="servlet_log"
path="logs/servlet.log"
customOutput="yes" />
<Logger name="JASPER_LOG"
path="logs/jasper.log"
verbosityLevel = "INFORMATION" />
<!-- Add "home" attribute if you want tomcat to be based on a different directory
"home" is used to create work and to read webapps, but not for libs or CLASSPATH.
Note that TOMCAT_HOME is where tomcat is installed, while ContextManager home is the
base directory for contexts, webapps/ and work/
-->
<ContextManager debug="0" workDir="work" >
<!-- ContextInterceptor className="org.apache.tomcat.context.LogEvents" / -->
<ContextInterceptor className="org.apache.tomcat.context.AutoSetup" />
<ContextInterceptor className="org.apache.tomcat.context.DefaultCMSetter" />
<ContextInterceptor className="org.apache.tomcat.context.WorkDirInterceptor" />
<ContextInterceptor className="org.apache.tomcat.context.WebXmlReader" />
<ContextInterceptor className="org.apache.tomcat.context.LoadOnStartupInterceptor" />
<!-- Request processing -->
<!-- Session interceptor will extract the session id from cookies and
deal with URL rewriting. It has to be first to support rewriting ( otherwise
the mapper will have to know about sessions
-->
<RequestInterceptor className="org.apache.tomcat.request.SessionInterceptor" />
<!-- Find the container ( context and prefix/extension map ) for a request.
For "integrated" mode it can be avoided, assuming we get all the info from
the server.
-->
<RequestInterceptor className="org.apache.tomcat.request.SimpleMapper1" debug="0" />
<!-- Check if the request requires an authenticated role -->
<RequestInterceptor className="org.apache.tomcat.request.AccessInterceptor" debug="0" />
<!-- Check permissions using a simple xml file -->
<RequestInterceptor className="org.apache.tomcat.request.SimpleRealm" debug="0" />
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
<Parameter name="handler" value="org.apache.tomcat.service.http.HttpConnectionHandler"/>
<Parameter name="port" value="8080"/>
</Connector>
<Connector className="org.apache.tomcat.service.PoolTcpConnector">
<Parameter name="handler" value="org.apache.tomcat.service.connector.Ajp12ConnectionHandler"/>
<Parameter name="port" value="8007"/>
</Connector>
<!-- example - how to override AutoSetup actions -->
<Context path="/examples" docBase="webapps/examples" debug="0" reloadable="true" >
<!-- Allow read access to the directory class was loaded from
// This isn't really necessary, but it prevents the ClassLoader from
// complaining with an AccessControlException which gets ignored
// by things like getBundle() -->
<Permission className="java.io.FilePermission" attribute="/usr/local/tomcat/webapps/examples/-" value="read"/>
<!-- default permissions granted to all domains -->
<Permission className="java.lang.RuntimePermission" attribute="stopThread"/>
<!-- allows anyone to listen on un-privileged ports -->
<Permission className="java.net.SocketPermission" attribute="localhost:1024-" value="listen"/>
<Permission className="java.util.PropertyPermission" attribute="java.version" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.vendor" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.vendor.url" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.class.version" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="file.separator" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="path.separator" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="line.separator" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.specification.version" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.specification.vendor" value="read"/>
<Permission className="java.util.PropertyPermission" attribute="java.specification.name" value="read"/>
</Context>
<!-- example - how to override AutoSetup actions -->
<Context path="" docBase="webapps/ROOT" debug="0" reloadable="true" >
</Context>
<Context path="/test" docBase="webapps/test" debug="0" reloadable="true" >
</Context>
<Context path="/admin" docBase="webapps/admin" debug="0" reloadable="true" trusted="true" >
</Context>
<!-- Virtual host example - just use numeric IP instead of localhost
and you should see /examples as the root context and root as examples.
Same docBase is used, just different mappings :-) -->
<Host name="127.0.0.1" >
<Context path="" docBase="webapps/examples" />
<Context path="/examples" docBase="webapps/ROOT" />
</Host>
</ContextManager>
</Server>
1.1 jakarta-tomcat/src/etc/tomcat.policy
Index: tomcat.policy
===================================================================
// Standard extensions get all permissions by default
grant codeBase "file:${java.home}/lib/ext/-" {
permission java.security.AllPermission;
};
// Tomcat gets all permissions
grant codeBase "file:${tomcat.home}/lib/-" {
permission java.security.AllPermission;
};
// default permissions granted to all domains
grant {
// Allows any thread to stop itself using the java.lang.Thread.stop()
// method that takes no argument.
// Note that this permission is granted by default only to remain
// backwards compatible.
// It is strongly recommended that you either remove this permission
// from this policy file or further restrict it to code sources
// that you specify, because Thread.stop() is potentially unsafe.
// See "http://java.sun.com/notes" for more information.
permission java.lang.RuntimePermission "stopThread";
// allows anyone to listen on un-privileged ports
permission java.net.SocketPermission "localhost:1024-", "listen";
// "standard" properies that can be read by anyone
permission java.util.PropertyPermission "java.version", "read";
permission java.util.PropertyPermission "java.vendor", "read";
permission java.util.PropertyPermission "java.vendor.url", "read";
permission java.util.PropertyPermission "java.class.version", "read";
permission java.util.PropertyPermission "os.name", "read";
permission java.util.PropertyPermission "os.version", "read";
permission java.util.PropertyPermission "os.arch", "read";
permission java.util.PropertyPermission "file.separator", "read";
permission java.util.PropertyPermission "path.separator", "read";
permission java.util.PropertyPermission "line.separator", "read";
permission java.util.PropertyPermission "java.specification.version", "read";
permission java.util.PropertyPermission "java.specification.vendor", "read";
permission java.util.PropertyPermission "java.specification.name", "read";
permission java.util.PropertyPermission "java.vm.specification.version", "read";
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
permission java.util.PropertyPermission "java.vm.specification.name", "read";
permission java.util.PropertyPermission "java.vm.version", "read";
permission java.util.PropertyPermission "java.vm.vendor", "read";
permission java.util.PropertyPermission "java.vm.name", "read";
};
1.5 +1 -2 jakarta-tomcat/src/native/apache2.0/Makefile.linux
Index: Makefile.linux
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/native/apache2.0/Makefile.linux,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Makefile.linux 2000/05/26 17:32:02 1.4
+++ Makefile.linux 2000/05/26 18:55:07 1.5
@@ -9,10 +9,9 @@
##
+AP20_INCL=-I${APACHE_HOME}/include/apr -I${APACHE_HOME}/include
JAVA_INCL=-I${JAVA_HOME}/include -I${JAVA_HOME}/include/${OS}
JAVA_LIB=-L${JAVA_HOME}/jre/lib/${ARCH} -L${JAVA_HOME}/lib/${ARCH}/native_threads
-
-AP20_INCL=-I${APACHE_HOME}/include/apr -I${APACHE_HOME}/include
AP20SRC_INCL=-I. -I${AP20_SRC}/modules/standard -I${AP20_SRC} -I${AP20_SRC}/include -I${AP20_SRC}/lib/apr/include -I${AP20_SRC}/os/unix
CFLAGS=-DHAVE_CONFIG_H -g -fpic -DSHARED_MODULE -O2 -D_REENTRANT -pthread -DLINUX -Wall
1.12 +6 -0 jakarta-tomcat/src/share/org/apache/jasper/Constants.java
Index: Constants.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/Constants.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Constants.java 2000/04/25 21:10:04 1.11
+++ Constants.java 2000/05/26 18:55:08 1.12
@@ -137,6 +137,12 @@
public static final String TMP_DIR = "javax.servlet.context.tempdir";
/**
+ * ProtectionDomain to use for JspLoader defineClass() for current
+ * Context when using a SecurityManager.
+ */
+ public static final String ATTRIB_JSP_ProtectionDomain = "tomcat.context.jsp.protection_domain";
+
+ /**
* A token which is embedded in file names of the generated
* servlet.
*/
1.4 +17 -3 jakarta-tomcat/src/share/org/apache/jasper/EmbededServletOptions.java
Index: EmbededServletOptions.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/EmbededServletOptions.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- EmbededServletOptions.java 2000/02/23 02:23:44 1.3
+++ EmbededServletOptions.java 2000/05/26 18:55:09 1.4
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/EmbededServletOptions.java,v 1.3 2000/02/23 02:23:44 mandar Exp $
- * $Revision: 1.3 $
- * $Date: 2000/02/23 02:23:44 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/EmbededServletOptions.java,v 1.4 2000/05/26 18:55:09 costin Exp $
+ * $Revision: 1.4 $
+ * $Date: 2000/05/26 18:55:09 $
*
* ====================================================================
*
@@ -107,6 +107,11 @@
* in?
*/
public File scratchDir;
+ /**
+ * When used with a Securitymanager, what ProtectionDomain to use.
+ */
+ private Object protectionDomain;
+
/**
* Need to have this as is for versions 4 and 5 of IE. Can be set from
@@ -174,6 +179,12 @@
}
/**
+ * ProtectionDomain for this JSP Context when using a SecurityManager
+ */
+ public final Object getProtectionDomain() {
+ return protectionDomain;
+ }
+ /**
* What classpath should I use while compiling the servlets
* generated from JSP files?
*/
@@ -262,6 +273,9 @@
}
}
+ // Get the ProtectionDomain for this Context in case
+ // we are using a SecurityManager
+ protectionDomain = context.getAttribute(Constants.ATTRIB_JSP_ProtectionDomain);
if (this.scratchDir == null) {
Constants.message("jsp.error.no.scratch.dir", Logger.FATAL);
return;
1.12 +8 -3 jakarta-tomcat/src/share/org/apache/jasper/JspC.java
Index: JspC.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/JspC.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- JspC.java 2000/05/25 15:57:42 1.11
+++ JspC.java 2000/05/26 18:55:10 1.12
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/JspC.java,v 1.11 2000/05/25 15:57:42 shemnon Exp $
- * $Revision: 1.11 $
- * $Date: 2000/05/25 15:57:42 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/JspC.java,v 1.12 2000/05/26 18:55:10 costin Exp $
+ * $Revision: 1.12 $
+ * $Date: 2000/05/26 18:55:10 $
*
* ====================================================================
*
@@ -161,6 +161,11 @@
public boolean getMappedFile() {
return mappedFile;
}
+
+ // Off-line compiler, no need for security manager
+ public Object getProtectionDomain() {
+ return null;
+ }
public boolean getSendErrorToClient() {
// implied send to System.err
1.11 +7 -3 jakarta-tomcat/src/share/org/apache/jasper/Options.java
Index: Options.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/Options.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Options.java 2000/02/23 02:23:44 1.10
+++ Options.java 2000/05/26 18:55:10 1.11
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/Options.java,v 1.10 2000/02/23 02:23:44 mandar Exp $
- * $Revision: 1.10 $
- * $Date: 2000/02/23 02:23:44 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/Options.java,v 1.11 2000/05/26 18:55:10 costin Exp $
+ * $Revision: 1.11 $
+ * $Date: 2000/05/26 18:55:10 $
*
* ====================================================================
*
@@ -121,4 +121,8 @@
*/
public String getJspCompilerPath();
+ /**
+ * ProtectionDomain for this JSP Context when using a SecurityManager
+ */
+ public Object getProtectionDomain();
}
1.16 +40 -3 jakarta-tomcat/src/share/org/apache/jasper/compiler/Compiler.java
Index: Compiler.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/Compiler.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- Compiler.java 2000/04/25 18:28:20 1.15
+++ Compiler.java 2000/05/26 18:55:12 1.16
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/Compiler.java,v 1.15 2000/04/25 18:28:20 mandar Exp $
- * $Revision: 1.15 $
- * $Date: 2000/04/25 18:28:20 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/Compiler.java,v 1.16 2000/05/26 18:55:12 costin Exp $
+ * $Revision: 1.16 $
+ * $Date: 2000/05/26 18:55:12 $
*
* ====================================================================
*
@@ -67,6 +67,7 @@
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
+import java.security.*;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
@@ -101,6 +102,42 @@
* was recompiled.
*/
public boolean compile()
+ throws FileNotFoundException, JasperException, Exception
+ {
+ if( System.getSecurityManager() == null )
+ return compile_context();
+ else
+ return compile_priviledged();
+ }
+
+ /**
+ * When using a SecurityManager and a JSP page itself triggers
+ * another JSP due to an errorPage or from a jsp:include,
+ * the compile must be performed with the Permissions of
+ * this class using doPriviledged because the parent JSP
+ * may not have sufficient Permissions.
+ */
+ private boolean compile_priviledged()
+ {
+
+ class doInit implements PrivilegedAction {
+ Boolean result;
+ public Object run()
+ {
+ try {
+ result = new Boolean(compile_context());
+ } catch(Exception ex) {
+ return new Boolean(false);
+ }
+ return result;
+ }
+ }
+ doInit di = new doInit();
+ Boolean res = (Boolean)AccessController.doPrivileged(di);
+ return res.booleanValue();
+ }
+
+ private boolean compile_context()
throws FileNotFoundException, JasperException, Exception
{
String pkgName = mangler.getPackageName();
1.4 +37 -4 jakarta-tomcat/src/share/org/apache/jasper/compiler/JikesJavaCompiler.java
Index: JikesJavaCompiler.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/JikesJavaCompiler.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- JikesJavaCompiler.java 2000/01/23 01:37:46 1.3
+++ JikesJavaCompiler.java 2000/05/26 18:55:12 1.4
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/JikesJavaCompiler.java,v 1.3 2000/01/23 01:37:46 bergsten Exp $
- * $Revision: 1.3 $
- * $Date: 2000/01/23 01:37:46 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/JikesJavaCompiler.java,v 1.4 2000/05/26 18:55:12 costin Exp $
+ * $Revision: 1.4 $
+ * $Date: 2000/05/26 18:55:12 $
*
* ====================================================================
*
@@ -67,6 +67,8 @@
import java.io.File;
import java.io.ByteArrayOutputStream;
+import java.security.*;
+
/**
* A Plug-in class for specifying a 'jikes' compile.
*
@@ -120,10 +122,41 @@
}
/**
+ * When using a SecurityManager and a JSP page itself triggers
+ * another JSP due to an errorPage or from a jsp:include,
+ * the compile must be performed with the Permissions of
+ * this class using doPriviledged because the parent JSP
+ * may not have sufficient Permissions.
+ */
+ private boolean compile_priviledged(String source) {
+ class doInit implements PrivilegedAction {
+ String src;
+ Boolean result;
+ public doInit(String source ) {
+ src = source;
+ }
+ public Object run() {
+ result = new Boolean(compile_source(src));
+ return result;
+ }
+ }
+ doInit di = new doInit(source);
+ Boolean res = (Boolean)AccessController.doPrivileged(di);
+ return res.booleanValue();
+ }
+
+ public boolean compile(String source) {
+ if( System.getSecurityManager() == null )
+ return compile_source(source);
+ else
+ return compile_priviledged(source);
+ }
+
+ /**
* Execute the compiler
* @param source - file name of the source to be compiled
*/
- public boolean compile(String source) {
+ private boolean compile_source(String source) {
Process p;
int exitValue = -1;
1.12 +54 -1 jakarta-tomcat/src/share/org/apache/jasper/compiler/JspCompiler.java
Index: JspCompiler.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/compiler/JspCompiler.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- JspCompiler.java 2000/04/05 03:16:15 1.11
+++ JspCompiler.java 2000/05/26 18:55:13 1.12
@@ -58,6 +58,8 @@
import java.io.File;
import java.io.FileNotFoundException;
+import java.security.*;
+
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
@@ -270,6 +272,31 @@
*/
public boolean isOutDated()
{
+ if( System.getSecurityManager() == null )
+ return isOutDated_normal();
+ else
+ return isOutDated_priviledged();
+ }
+
+ /**
+ * When using a SecurityManager and a JSP page itself triggers
+ * another JSP due to an errorPage or from a jsp:include,
+ * the isOutDated check must be performed with the Permissions of
+ * this class using doPriviledged because the parent JSP
+ * may not have sufficient Permissions.
+ */
+ private final boolean isOutDated_priviledged() {
+ class doInit implements PrivilegedAction {
+ public Object run() {
+ return new Boolean(isOutDated_normal());
+ }
+ }
+ doInit di = new doInit();
+ Boolean res = (Boolean)AccessController.doPrivileged(di);
+ return res.booleanValue();
+ }
+
+ private final boolean isOutDated_normal() {
File jspReal = null;
jspReal = new File(ctxt.getRealPath(jsp.getPath()));
@@ -284,8 +311,34 @@
return outDated;
}
- private final void computeClassFileData()
+ /**
+ * When using a SecurityManager and a JSP page itself triggers
+ * another JSP due to an errorPage or from a jsp:include,
+ * the computeClassFileData must be performed with the Permissions of
+ * this class using doPriviledged because the parent JSP
+ * may not have sufficient Permissions.
+ */
+ private final void computeClassFileData() {
+ if( System.getSecurityManager() == null )
+ computeClassFileData_normal();
+ else
+ computeClassFileData_priviledged();
+ }
+
+ private final void computeClassFileData_priviledged()
{
+ class doInit implements PrivilegedAction {
+ public Object run()
+ {
+ computeClassFileData_normal();
+ return null;
+ }
+ }
+ doInit di = new doInit();
+ AccessController.doPrivileged(di);
+ }
+
+ private final void computeClassFileData_normal() {
File jspReal = null;
String initPath = jsp.getPath();
1.7 +59 -11 jakarta-tomcat/src/share/org/apache/jasper/runtime/JspLoader.java
Index: JspLoader.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/runtime/JspLoader.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- JspLoader.java 2000/02/13 06:25:25 1.6
+++ JspLoader.java 2000/05/26 18:55:17 1.7
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/runtime/JspLoader.java,v 1.6 2000/02/13 06:25:25 akv Exp $
- * $Revision: 1.6 $
- * $Date: 2000/02/13 06:25:25 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/runtime/JspLoader.java,v 1.7 2000/05/26 18:55:17 costin Exp $
+ * $Revision: 1.7 $
+ * $Date: 2000/05/26 18:55:17 $
*
* ====================================================================
*
@@ -73,6 +73,8 @@
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
+import java.security.*;
+
import org.apache.jasper.JasperException;
import org.apache.jasper.Constants;
import org.apache.jasper.JspCompilationContext;
@@ -169,15 +171,35 @@
} else {
fileName = className.substring(beg, end) + ".class";
fileName = outputDir + File.separatorChar + fileName;
+ }
+ byte [] classBytes = null;
+ /**
+ * When using a SecurityManager and a JSP page itself triggers
+ * another JSP due to an errorPage or from a jsp:include,
+ * the loadClass must be performed with the Permissions of
+ * this class using doPriviledged because the parent JSP
+ * may not have sufficient Permissions.
+ */
+ if( System.getSecurityManager() != null ) {
+ class doInit implements PrivilegedAction {
+ private String fileName;
+ public doInit(String file) {
+ fileName = file;
+ }
+ public Object run() {
+ return loadClassDataFromFile(fileName);
+ }
+ }
+ doInit di = new doInit(fileName);
+ classBytes = (byte [])AccessController.doPrivileged(di);
+ } else {
+ classBytes = loadClassDataFromFile(fileName);
+ }
+ if( classBytes == null ) {
+ throw new ClassNotFoundException(Constants.getString(
+ "jsp.error.unable.loadclass",
+ new Object[] {className}));
}
- FileInputStream fin = new FileInputStream(fileName);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- byte buf[] = new byte[1024];
- for(int i = 0; (i = fin.read(buf)) != -1; )
- baos.write(buf, 0, i);
- fin.close();
- baos.close();
- byte[] classBytes = baos.toByteArray();
return defClass(className, classBytes);
}
} catch (Exception ex) {
@@ -192,7 +214,33 @@
* make this public at some point of time.
*/
private final Class defClass(String className, byte[] classData) {
+ // If a SecurityManager is being used, set the ProtectionDomain
+ // for this clas when it is defined.
+ Object pd = options.getProtectionDomain();
+ if( pd != null )
+ return defineClass(className, classData, 0, classData.length, (ProtectionDomain)pd);
return defineClass(className, classData, 0, classData.length);
+ }
+
+ /**
+ * Load JSP class data from file, method may be called from
+ * within a doPriviledged if a SecurityManager is installed.
+ */
+ private byte[] loadClassDataFromFile(String fileName) {
+ byte[] classBytes = null;
+ try {
+ FileInputStream fin = new FileInputStream(fileName);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ byte buf[] = new byte[1024];
+ for(int i = 0; (i = fin.read(buf)) != -1; )
+ baos.write(buf, 0, i);
+ fin.close();
+ baos.close();
+ classBytes = baos.toByteArray();
+ } catch(Exception ex) {
+ return null;
+ }
+ return classBytes;
}
private Vector jars = new Vector();
1.22 +4 -3 jakarta-tomcat/src/share/org/apache/jasper/runtime/JspServlet.java
Index: JspServlet.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/jasper/runtime/JspServlet.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- JspServlet.java 2000/04/05 03:36:42 1.21
+++ JspServlet.java 2000/05/26 18:55:18 1.22
@@ -411,11 +411,12 @@
try {
outDated = compiler.compile();
- if ((jspClass == null) || (compiler.isOutDated())) {
+ if ( (jspClass == null) || (compiler.isOutDated()) ) {
synchronized ( this ) {
- if ((jspClass == null) || (compiler.isOutDated() ))
+ if ((jspClass == null) || (compiler.isOutDated() )) {
outDated = compiler.compile();
- }
+ }
+ }
}
} catch (FileNotFoundException ex) {
throw ex;
1.34 +71 -4 jakarta-tomcat/src/share/org/apache/tomcat/context/DefaultCMSetter.java
Index: DefaultCMSetter.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/context/DefaultCMSetter.java,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -r1.33 -r1.34
--- DefaultCMSetter.java 2000/05/12 15:26:38 1.33
+++ DefaultCMSetter.java 2000/05/26 18:55:20 1.34
@@ -67,6 +67,7 @@
import java.io.*;
import java.net.*;
import java.util.*;
+import java.security.*;
import javax.servlet.http.*;
import org.apache.tomcat.logging.*;
@@ -199,18 +200,72 @@
private void initURLs(Context context) {
ServletLoader loader=context.getServletLoader();
- if( loader==null) return;
+ ContextManager cm = context.getContextManager();
+ if( loader==null || cm == null) return;
+ SecurityManager sm = System.getSecurityManager();
+ Permissions p = null;
+
+ String base = context.getDocBase();
+
+ /**
+ * Initialize default FilePermissions for Context if using SecurityManager
+ */
+ if( sm != null ) {
+ p = context.getPermissions();
+ if( p == null ) {
+ // Clone the Permissions to overcome readonly status
+ Permissions perms = cm.getPermissions();
+ p = new Permissions();
+ Enumeration enum=perms.elements();
+ while(enum.hasMoreElements()) {
+ p.add((Permission)enum.nextElement());
+ }
+ // Add default read "-" FilePermission for docBase, classes, lib
+ FilePermission fp;
+ fp = new FilePermission(base + "-", "read");
+ if( fp != null )
+ p.add((Permission)fp);
+ }
+ }
// Add "WEB-INF/classes"
- String base = context.getDocBase();
File dir = new File(base + "/WEB-INF/classes");
// GS, Fix for the jar@lib directory problem.
// Thanks for Kevin Jones for providing the fix.
dir = getAbsolute(dir, context);
if( dir.exists() ) {
- loader.addRepository( dir );
+ ProtectionDomain pd = null;
+ try {
+ if( sm != null ) {
+ // Set the Default Security Permissions
+ URL url = new URL("file:" + dir.getAbsolutePath());
+ CodeSource cs = new CodeSource(url,null);
+ pd = new ProtectionDomain(cs,p);
+ }
+ loader.addRepository( dir, pd );
+ } catch(Exception ex) {
+ System.out.println("Security init for Context " + base + " failed");
+ }
+ }
+
+ // Create ProtectionDomain for JSP's for use by JSP Engine if using SecurityManager
+ if( sm != null ) {
+ File work = (File) context.getAttribute(Constants.ATTRIB_WORKDIR);
+ if( work.exists() ) {
+ ProtectionDomain pd = null;
+ try {
+ // Set the Default Security Permissions
+ URL url = new URL("file:" + work.getAbsolutePath());
+ CodeSource cs = new CodeSource(url,null);
+ pd = new ProtectionDomain(cs,p);
+// loader.addRepository( work, pd );
+ context.setAttribute(Constants.ATTRIB_JSP_ProtectionDomain, pd);
+ } catch(Exception ex) {
+ System.out.println("Security init for Context " + base + " failed");
+ }
+ }
}
File f = new File(base + "/WEB-INF/lib");
@@ -221,7 +276,19 @@
for(int i=0; i < jars.size(); ++i) {
String jarfile = (String) jars.elementAt(i);
File jarF=new File(f, jarfile );
- loader.addRepository( getAbsolute( jarF, context) );
+ ProtectionDomain pd = null;
+ try {
+ // Setup ProtectionDomain for jar files if using SecurityManager
+ if( sm != null ) {
+ // Set the Default Security Permissions
+ URL url = new URL("file:" + jarF.getAbsolutePath());
+ CodeSource cs = new CodeSource(url,null);
+ pd = new ProtectionDomain(cs,p);
+ }
+ loader.addRepository( getAbsolute( jarF, context), pd );
+ } catch(Exception ex) {
+ System.out.println("Security init for Context " + base + " failed");
+ }
}
}
1.21 +4 -0 jakarta-tomcat/src/share/org/apache/tomcat/core/Constants.java
Index: Constants.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Constants.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Constants.java 2000/04/13 15:23:43 1.20
+++ Constants.java 2000/05/26 18:55:21 1.21
@@ -82,6 +82,10 @@
public static final String ATTRIB_WORKDIR1 = "sun.servlet.workdir";
public static final String ATTRIB_WORKDIR = "javax.servlet.context.tempdir";
+ // ProtectionDomain defined for use by JSP's in a Context
+ // when using a SecurityManager
+ public static final String ATTRIB_JSP_ProtectionDomain = "tomcat.context.jsp.protection_domain";
+
public static final String SESSION_COOKIE_NAME = "JSESSIONID";
public static final String SESSION_PARAMETER_NAME = "jsessionid";
1.90 +40 -0 jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java
Index: Context.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Context.java,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -r1.89 -r1.90
--- Context.java 2000/05/24 01:58:14 1.89
+++ Context.java 2000/05/26 18:55:22 1.90
@@ -63,6 +63,8 @@
import org.apache.tomcat.context.*;
import org.apache.tomcat.facade.*;
import org.apache.tomcat.util.*;
+import java.security.*;
+import java.lang.reflect.*;
import org.apache.tomcat.logging.*;
import java.io.*;
import java.net.*;
@@ -118,6 +120,9 @@
private File workDir;
+ // Security Permissions for webapps and jsp for this context
+ Permissions perms = null;
+
// private RequestSecurityProvider rsProvider;
private Vector contextInterceptors = new Vector();
@@ -1004,6 +1009,41 @@
}
return rInterceptors;
}
+
+ /**
+ * Adds a Permission to a Permissions object which will be used as
+ * the Permissions for this Context. These are the Permissions
+ * set using the <Permission> element within the <Context> server.xml element.
+ */
+ public void setPermission(String className, String attr, String value) {
+ try {
+ if( perms == null )
+ perms = new Permissions();
+ Class c=Class.forName(className);
+ Constructor con=c.getConstructor(new Class[]{String.class,String.class});
+ Object [] args=new Object[2];
+ args[0] = attr;
+ args[1] = value;
+ Permission p = (Permission)con.newInstance(args);
+ perms.add(p);
+ } catch( ClassNotFoundException ex ) {
+ System.out.println("SecurityManager Class not found: " + className);
+ System.exit(1);
+ } catch( Exception ex ) {
+ System.out.println("SecurityManager Class could not be loaded: " + className);
+ ex.printStackTrace();
+ System.exit(1);
+ }
+ System.out.println("SecurityManager, " + className + ", \"" + attr + "\", \"" + value + "\" added");
+ }
+
+ /**
+ * Get the SecurityManager Permissions for this Context.
+ */
+ public Object getPermissions() {
+ return perms;
+ }
+
/** @deprecated - use getDocBase and URLUtil if you need it as URL
* NOT USED INSIDE TOMCAT - ONLY IN OLD J2EE CONNECTORS !
1.82 +24 -2 jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java
Index: ContextManager.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ContextManager.java,v
retrieving revision 1.81
retrieving revision 1.82
diff -u -r1.81 -r1.82
--- ContextManager.java 2000/05/26 17:32:05 1.81
+++ ContextManager.java 2000/05/26 18:55:23 1.82
@@ -63,6 +63,7 @@
import org.apache.tomcat.core.*;
import org.apache.tomcat.net.*;
import org.apache.tomcat.context.*;
+import org.apache.tomcat.loader.*;
import org.apache.tomcat.request.*;
import org.apache.tomcat.util.*;
import org.apache.tomcat.logging.*;
@@ -71,6 +72,7 @@
import java.io.*;
import java.net.*;
import java.util.*;
+import java.security.*;
/* XXX The main function of CM is to serve as an entry point into
tomcat and manage a list of resources that are part of the servlet
@@ -128,7 +130,12 @@
// cache - faster access to interceptors, using [] instead of Vector
ContextInterceptor cInterceptors[];
RequestInterceptor rInterceptors[];
-
+
+ /**
+ * The default security permissions to use
+ */
+ private Permissions permissions;
+
/** Adapters for the incoming protocol
*/
Vector connectors=new Vector();
@@ -245,7 +252,22 @@
workDir=getHome() + File.separator + DEFAULT_WORK_DIR;
return workDir;
}
+
+ /**
+ * Get the default Security Permissions for this server
+ */
+ public Object getPermissions() {
+ return permissions;
+ }
+ /**
+ * Add a Permission to the default Permissions
+ */
+ public void addPermissions(SetSecurityManager secman) {
+ permissions = secman.getPermissions();
+ }
+
+
// -------------------- Support functions --------------------
/**
@@ -933,7 +955,7 @@
{
// find if we already have a note with this name ( this is in init(), not critical )
for( int i=0; i< noteId[noteType] ; i++ ) {
- if( noteName[noteType][i].equals( name ) )
+ if( name.equals( noteName[noteType][i] ) )
return i;
}
1.21 +2 -0 jakarta-tomcat/src/share/org/apache/tomcat/core/Response.java
Index: Response.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/Response.java,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- Response.java 2000/05/23 21:39:51 1.20
+++ Response.java 2000/05/26 18:55:23 1.21
@@ -128,6 +128,8 @@
*/
public ServletOutputStream getOutputStream() ;
+ public void doWrite( byte buffer[], int pos, int count) throws IOException;
+
public PrintWriter getWriter() throws IOException ;
/** True if we are in an included servlet
1.8 +5 -1 jakarta-tomcat/src/share/org/apache/tomcat/core/ServletLoader.java
Index: ServletLoader.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/core/ServletLoader.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ServletLoader.java 2000/02/09 21:43:53 1.7
+++ ServletLoader.java 2000/05/26 18:55:24 1.8
@@ -63,6 +63,7 @@
import java.io.*;
import java.net.*;
import java.util.*;
+import java.security.*;
// This is not a class loader, any "normal" class loader can be used.
@@ -105,10 +106,13 @@
/** Add a new directory or jar to the class loader.
+ * Optionally, a SecurityManager ProtectionDomain can
+ * be specified for use by the ClassLoader when defining
+ * a class loaded from this entry in the repository.
* Not all loaders can add resources dynamically -
* that may require a reload.
*/
- public void addRepository( File f );
+ public void addRepository( File f, ProtectionDomain pd );
// XXX notify if it can't add it
1.5 +48 -42 jakarta-tomcat/src/share/org/apache/tomcat/loader/AdaptiveClassLoader.java
Index: AdaptiveClassLoader.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/loader/AdaptiveClassLoader.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- AdaptiveClassLoader.java 2000/03/23 23:34:36 1.4
+++ AdaptiveClassLoader.java 2000/05/26 18:55:27 1.5
@@ -57,10 +57,12 @@
//package org.apache.java.lang;
import java.io.*;
+import java.lang.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
+import java.security.*;
/**
* A class loader that loads classes from directories and/or zip-format
@@ -116,12 +118,17 @@
* @author Martin Pool
* @author Jim Heintz
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
- * @version $Revision: 1.4 $ $Date: 2000/03/23 23:34:36 $
+ * @version $Revision: 1.5 $ $Date: 2000/05/26 18:55:27 $
* @see java.lang.ClassLoader
*/
public class AdaptiveClassLoader extends ClassLoader {
/**
+ * Instance of the SecurityManager installed.
+ */
+ static private SecurityManager sm;
+
+ /**
* Generation counter, incremented for each classloader as they are
* created.
*/
@@ -201,16 +208,16 @@
// Verify that all the repository are valid.
Enumeration e = classRepository.elements();
while(e.hasMoreElements()) {
- Object o = e.nextElement();
+ ClassRepository cp = (ClassRepository) e.nextElement();
File file;
String[] files;
int i;
// Check to see if element is a File instance.
try {
- file = (File) o;
+ file = cp.getFile();
} catch (ClassCastException objectIsNotFile) {
- throw new IllegalArgumentException("Object " + o
+ throw new IllegalArgumentException("Object " + cp
+ "is not a valid \"File\" instance");
}
// org.apache.java.io.XXX
@@ -241,6 +248,11 @@
}
}
+ // Install the SecurityManager if not already installed
+ if( generationCounter == 0 && sm == null ) {
+ sm = System.getSecurityManager();
+ }
+
// Store the class repository for use
this.repository = classRepository;
@@ -294,9 +306,8 @@
// System classes cannot be reloaded
return false;
} else {
- boolean reload =
- (entry.origin.lastModified() != entry.lastModified);
- return reload;
+ return (entry.origin.lastModified() != entry.lastModified);
+
}
}
@@ -392,21 +403,30 @@
return c;
}
- if (!securityAllowsClass(name)) {
- return loadSystemClass(name, resolve);
+ // Make sure we can access this class when using a SecurityManager
+ if (sm != null) {
+ int i = name.lastIndexOf('.');
+ if (i >= 0)
+ sm.checkPackageAccess(name.substring(0,i));
}
// Attempt to load the class from the system
try {
c = loadSystemClass(name, resolve);
if (c != null) {
- if (resolve) resolveClass(c);
return c;
}
} catch (Exception e) {
c = null;
}
+ // Make sure we can define this class when using a SecurityManager
+ if (sm != null) {
+ int i = name.lastIndexOf('.');
+ if (i >= 0)
+ sm.checkPackageDefinition(name.substring(0,i));
+ }
+
// Try to load it from each repository
Enumeration repEnum = repository.elements();
@@ -415,7 +435,8 @@
while (repEnum.hasMoreElements()) {
byte[] classData=null;
- File file = (File) repEnum.nextElement();
+ ClassRepository cp = (ClassRepository) repEnum.nextElement();
+ File file = cp.getFile();
try {
if (file.isDirectory()) {
classData =
@@ -424,6 +445,13 @@
classData =
loadClassFromZipfile(file, name, classCache);
}
+ // Make sure we catch and rethrow SecurityManager exceptions
+ } catch(AccessControlException aex) {
+ aex.printStackTrace();
+ throw aex;
+ } catch(SecurityException sex) {
+ sex.printStackTrace();
+ throw sex;
} catch(IOException ioe) {
// Error while reading in data, consider it as not found
classData = null;
@@ -432,8 +460,13 @@
}
if (classData != null) {
+ // Define the class with a ProtectionDomain if using a SecurityManager
+ if( sm != null ) {
// Define the class
+ c = defineClass(name, classData, 0, classData.length, cp.getProtectionDomain());
+ } else {
c = defineClass(name, classData, 0, classData.length);
+ }
// Cache the result;
classCache.loadedClass = c;
// Origin is set by the specific loader
@@ -477,35 +510,6 @@
}
/**
- * Checks whether a classloader is allowed to define a given class,
- * within the security manager restrictions.
- */
- // XXX: Should we perhaps also not allow classes to be dynamically
- // loaded from org.apache.jserv.*? Would it introduce security
- // problems if people could override classes here?
- // <mbp@humbug.org.au 1998-07-29>
- private boolean securityAllowsClass(String className) {
- try {
- SecurityManager security = System.getSecurityManager();
-
- if (security == null) {
- // if there's no security manager then all classes
- // are allowed to be loaded
- return true;
- }
-
- int lastDot = className.lastIndexOf('.');
- // Check if we are allowed to load the class' package
- security.checkPackageDefinition((lastDot > -1)
- ? className.substring(0, lastDot) : "");
- // Throws if not allowed
- return true;
- } catch (SecurityException e) {
- return false;
- }
- }
-
- /**
* Tries to load the class from a directory.
*
* @param dir The directory that contains classes.
@@ -615,7 +619,8 @@
// Try to find it from every repository
Enumeration repEnum = repository.elements();
while (repEnum.hasMoreElements()) {
- File file = (File) repEnum.nextElement();
+ ClassRepository cp = (ClassRepository) repEnum.nextElement();
+ File file = cp.getFile();
if (file.isDirectory()) {
s = loadResourceFromDirectory(file, name);
}
@@ -715,7 +720,8 @@
// We got here so we have to look for the resource in our list of repository elements
Enumeration repEnum = repository.elements();
while (repEnum.hasMoreElements()) {
- File file = (File) repEnum.nextElement();
+ ClassRepository cp = (ClassRepository) repEnum.nextElement();
+ File file = cp.getFile();
// Construct a file://-URL if the repository is a directory
if (file.isDirectory()) {
String fileName = name.replace('/', File.separatorChar);
1.5 +11 -4 jakarta-tomcat/src/share/org/apache/tomcat/loader/AdaptiveServletLoader.java
Index: AdaptiveServletLoader.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/loader/AdaptiveServletLoader.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- AdaptiveServletLoader.java 2000/04/12 16:19:19 1.4
+++ AdaptiveServletLoader.java 2000/05/26 18:55:28 1.5
@@ -63,6 +63,7 @@
import java.io.*;
import java.net.*;
import java.util.*;
+import java.security.*;
// XXX extends ClassLoader is need only to allow access to protected loadClass
// method in ClassLoader. The alternative is to require a public method with
@@ -148,7 +149,8 @@
String cpath = "";
for(Enumeration e = classP.elements() ; e.hasMoreElements(); ) {
- File f = (File) e.nextElement();
+ ClassRepository cp = (ClassRepository) e.nextElement();
+ File f = cp.getFile();
if (cpath.length()>0) cpath += separator;
cpath += f;
}
@@ -158,13 +160,18 @@
/** Add a new directory or jar to the class loader.
+ * Optionally, a SecurityManager ProtectionDomain can
+ * be specified for use by the ClassLoader when defining
+ * a class loaded from this entry in the repository.
* Not all loaders can add resources dynamically -
* that may require a reload.
*/
- public void addRepository( File f ) {
- // System.out.println("Adding " + f.getName() );
+ public void addRepository( File f, ProtectionDomain pd ) {
+// System.out.println("addRepository " + f.getAbsolutePath() );
try {
- classP.addElement(new File(FileUtil.patch(f.getCanonicalPath())));
+ classP.addElement(
+ new ClassRepository( new File(FileUtil.patch(f.getCanonicalPath())), pd )
+ );
} catch( IOException ex) {
ex.printStackTrace();
}
1.8 +5 -1 jakarta-tomcat/src/share/org/apache/tomcat/loader/ServletClassLoaderImpl.java
Index: ServletClassLoaderImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/loader/ServletClassLoaderImpl.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ServletClassLoaderImpl.java 2000/02/12 19:50:40 1.7
+++ ServletClassLoaderImpl.java 2000/05/26 18:55:28 1.8
@@ -174,5 +174,9 @@
*/
public void addRepository( URL url ) {
return;// no support for URLs in AdaptiveClassLoader
- }
+ }
+
+ public void addRepository(File f , java.security.ProtectionDomain pd) {
+
+ }
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/loader/ClassRepository.java
Index: ClassRepository.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.loader;
import java.io.*;
import java.lang.*;
import java.util.*;
import java.security.*;
public class ClassRepository {
private File file;
private ProtectionDomain protectionDomain;
public ClassRepository( File f, ProtectionDomain pd) {
file = f;
protectionDomain = pd;
}
public File getFile() {
return file;
}
public ProtectionDomain getProtectionDomain() {
return protectionDomain;
}
}
1.1 jakarta-tomcat/src/share/org/apache/tomcat/loader/SetSecurityManager.java
Index: SetSecurityManager.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.loader;
import java.lang.*;
import java.util.*;
import java.lang.reflect.*;
import java.security.*;
/*
* Installs a SecurityManager if one was configured in server.xml
*/
public class SetSecurityManager {
// Default Security Permissions for webapps and jsp
private Permissions perms = new Permissions();
public void setClassName(String className) {
if( System.getSecurityManager() == null ) {
System.out.println("Not started with a SecurityManager, ignoring SecurityManager and Permissions");
return;
}
// Use of a SecurityManager requires java 1.2 or greater
String jv = System.getProperty("java.version");
if( jv.startsWith("1.0") || jv.startsWith("1.1") ) {
// For now just print an error, then exit.
// org.apache.tomcat.util.xml.XmlMapper.SetProperty() is
// catching Exceptions but not rethrowing them.
System.out.println("Use of a SecurityManager requires Java version 1.2 or greater");
System.exit(1);
}
try {
Class c=Class.forName(className);
Object o=c.newInstance();
System.setSecurityManager((SecurityManager)o);
} catch( ClassNotFoundException ex ) {
System.out.println("SecurityManager Class not found: " + className);
System.exit(1);
} catch( Exception ex ) {
System.out.println("SecurityManager Class could not be loaded: " + className);
System.exit(1);
}
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
System.out.println("Could not install SecurityManager: " + className);
System.exit(1);
}
System.out.println("Security Manager set to: " + className);
}
public void setPermission(String className, String attr, String value) {
try {
Class c=Class.forName(className);
Constructor con=c.getConstructor(new Class[]{String.class,String.class});
Object [] args=new Object[2];
args[0] = attr;
args[1] = value;
Permission p = (Permission)con.newInstance(args);
perms.add(p);
} catch( ClassNotFoundException ex ) {
System.out.println("SecurityManager Class not found: " + className);
System.exit(1);
} catch( Exception ex ) {
System.out.println("SecurityManager Class could not be loaded: " + className);
ex.printStackTrace();
System.exit(1);
}
// System.out.println("SecurityManager, " + className + ", \"" + attr + "\", \"" + value + "\" added");
}
public Permissions getPermissions() {
return perms;
}
}
1.24 +19 -25 jakarta-tomcat/src/share/org/apache/tomcat/startup/Tomcat.java
Index: Tomcat.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/startup/Tomcat.java,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -r1.23 -r1.24
--- Tomcat.java 2000/04/26 18:57:36 1.23
+++ Tomcat.java 2000/05/26 18:55:30 1.24
@@ -64,6 +64,11 @@
xh.addRule( "ContextManager/Context", xh.objectCreate("org.apache.tomcat.core.Context"));
xh.addRule( "ContextManager/Context", xh.setParent( "setContextManager") );
xh.addRule( "ContextManager/Context", xh.setProperties() );
+ // Rules for setting Context SecurityManager Permissions
+ xh.addRule( "ContextManager/Context/Permission",xh.methodSetter("setPermission",3));
+ xh.addRule( "ContextManager/Context/Permission",xh.methodParam(0,"className"));
+ xh.addRule( "ContextManager/Context/Permission",xh.methodParam(1,"attribute"));
+ xh.addRule( "ContextManager/Context/Permission",xh.methodParam(2,"value"));
xh.addRule( "ContextManager/Context", xh.addChild( "addContext", null ) );
// Virtual host support.
@@ -132,6 +137,19 @@
}
+ /** Setup a SecurityManager, this can only be called once or a
+ * SecurityException will be generated.
+ */
+ void setSecurityManager( XmlMapper xh ) {
+ xh.addRule("Server/SecurityManager", xh.objectCreate("org.apache.tomcat.loader.SetSecurityManager"));
+ xh.addRule("Server/SecurityManager", xh.setProperties());
+ xh.addRule("Server/SecurityManager/Permission",xh.methodSetter("setPermission",3));
+ xh.addRule("Server/SecurityManager/Permission",xh.methodParam(0,"className"));
+ xh.addRule("Server/SecurityManager/Permission",xh.methodParam(1,"attribute"));
+ xh.addRule("Server/SecurityManager/Permission",xh.methodParam(2,"value"));
+ xh.addRule("Server/SecurityManager",xh.addChild("addPermissions",null));
+ }
+
/**
* Return the configuration file we are processing. If the
* <code>-config filename</code> command line argument is not
@@ -179,6 +197,7 @@
setHelper( xh );
setConnectorHelper( xh );
setLogHelper( xh );
+ setSecurityManager( xh );
File f = getConfigFile(cm);
try {
@@ -296,28 +315,3 @@
}
}
-
-
-class HostConfig {
- ContextManager cm;
- String hostName;
-
- public HostConfig(ContextManager cm) {
- this.cm=cm;
- }
-
- public void setName( String name ) {
- hostName=name;
- }
-
- public void addContext( Context ctx ) {
- try {
- ctx.setContextManager( cm );
- ctx.setHost( hostName );
- cm.addContext( ctx );
- } catch(Exception ex ) {
- ex.printStackTrace();
- }
- }
-}
-
1.1 jakarta-tomcat/src/share/org/apache/tomcat/startup/HostConfig.java
Index: HostConfig.java
===================================================================
package org.apache.tomcat.startup;
import java.beans.*;
import java.io.*;
import java.io.IOException;
import java.lang.reflect.*;
import java.util.Hashtable;
import java.util.*;
import java.net.*;
import org.apache.tomcat.util.*;
import org.apache.tomcat.util.xml.*;
import org.apache.tomcat.core.*;
import org.xml.sax.*;
// Used to stop tomcat
import org.apache.tomcat.service.TcpEndpointConnector;
import org.apache.tomcat.service.connector.Ajp12ConnectionHandler;
/** Used by Tomcat.java, need to be public for Reflection in JDK11
*/
public class HostConfig {
ContextManager cm;
String hostName;
public HostConfig(ContextManager cm) {
this.cm=cm;
}
public void setName( String name ) {
hostName=name;
}
public void addContext( Context ctx ) {
try {
ctx.setContextManager( cm );
ctx.setHost( hostName );
cm.addContext( ctx );
} catch(Exception ex ) {
ex.printStackTrace();
}
}
}
1.22 +13 -0 jakarta-tomcat/src/shell/tomcat.bat
Index: tomcat.bat
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/shell/tomcat.bat,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- tomcat.bat 2000/05/01 15:46:49 1.21
+++ tomcat.bat 2000/05/26 18:55:32 1.22
@@ -48,6 +48,7 @@
echo tomcat (start^|run^|env^|stop)
echo start - start tomcat in a separate window
echo run - start tomcat in the current window
+echo -security - use a SecurityManager when starting
echo env - setup the environment for tomcat
echo stop - stop tomcat
echo ant - run ant with tomcat context
@@ -57,13 +58,25 @@
:startServer
echo Starting tomcat in new window
echo Using classpath: %CLASSPATH%
+if "%2" == "-security" goto startSecure
start java %TOMCAT_OPTS% -Dtomcat.home="%TOMCAT_HOME%" org.apache.tomcat.startup.Tomcat %2 %3 %4 %5 %6 %7 %8 %9
goto cleanup
+:startSecure
+echo Starting with a SecurityManager
+start java %TOMCAT_OPTS% -Djava.security.manager -Djava.security.policy=="%TOMCAT_HOME%/conf/tomcat.policy" -Dtomcat.home="%TOMCAT_HOME%" org.apache.tomcat.startup.Tomcat %3 %4 %5 %6 %7 %8 %9
+to cleanup
+
:runServer
rem Start the Tomcat Server
echo Using classpath: %CLASSPATH%
+if "%2" == "-security" goto runSecure
java %TOMCAT_OPTS% -Dtomcat.home="%TOMCAT_HOME%" org.apache.tomcat.startup.Tomcat %2 %3 %4 %5 %6 %7 %8 %9
+goto cleanup
+
+:runSecure
+echo Starting with a SecurityManager
+java %TOMCAT_OPTS% -Djava.security.manager -Djava.security.policy=="%TOMCAT_HOME%/conf/tomcat.policy" -Dtomcat.home="%TOMCAT_HOME%" org.apache.tomcat.startup.Tomcat %3 %4 %5 %6 %7 %8 %9
goto cleanup
:stopServer
1.17 +12 -1 jakarta-tomcat/src/shell/tomcat.sh
Index: tomcat.sh
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/shell/tomcat.sh,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- tomcat.sh 2000/03/31 20:31:31 1.16
+++ tomcat.sh 2000/05/26 18:55:33 1.17
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# $Id: tomcat.sh,v 1.16 2000/03/31 20:31:31 craigmcc Exp $
+# $Id: tomcat.sh,v 1.17 2000/05/26 18:55:33 costin Exp $
# Shell script to start and stop the server
@@ -118,7 +118,12 @@
if [ "$1" = "start" ] ; then
shift
echo Using classpath: ${CLASSPATH}
+ if [ "$1" = "-security" ] ; then
+ echo Starting with a SecurityManager
+ $JAVACMD $TOMCAT_OPTS -Djava.security.manager -Djava.security.policy==${TOMCAT_HOME}/conf/tomcat.policy -Dtomcat.home=${TOMCAT_HOME} org.apache.tomcat.startup.Tomcat "$@" &
+ else
$JAVACMD $TOMCAT_OPTS -Dtomcat.home=${TOMCAT_HOME} org.apache.tomcat.startup.Tomcat "$@" &
+ fi
# $JAVACMD org.apache.tomcat.shell.Startup "$@" &
elif [ "$1" = "stop" ] ; then
@@ -130,7 +135,12 @@
elif [ "$1" = "run" ] ; then
shift
echo Using classpath: ${CLASSPATH}
+ if [ "$1" = "-security" ] ; then
+ echo Starting with a SecurityManager
+ $JAVACMD $TOMCAT_OPTS -Djava.security.manager -Djava.security.policy==${TOMCAT_HOME}/conf/tomcat.policy -Dtomcat.home=${TOMCAT_HOME} org.apache.tomcat.startup.Tomcat "$@"
+ else
$JAVACMD $TOMCAT_OPTS -Dtomcat.home=${TOMCAT_HOME} org.apache.tomcat.startup.Tomcat "$@"
+ fi
# $JAVACMD org.apache.tomcat.shell.Startup "$@"
# no &
@@ -155,6 +165,7 @@
echo "tomcat (start|env|run|stop|ant)"
echo " start - start tomcat in the background"
echo " run - start tomcat in the foreground"
+ echo " -security - use a SecurityManager when starting"
echo " stop - stop tomcat"
echo " env - set CLASSPATH and TOMCAT_HOME env. variables"
echo " ant - run ant script in tomcat context ( classes, directories, etc)"
Re: cvs commit: jakarta-tomcat/src/shell tomcat.bat tomcat.sh
Posted by Louis Tribble <lo...@metamata.com>.
costin@locus.apache.org wrote:
>
> costin 00/05/26 11:55:34
>
> Modified: src/native/apache2.0 Makefile.linux
> src/share/org/apache/jasper Constants.java
> EmbededServletOptions.java JspC.java Options.java
Might want to fix the spelling of Embeded (to Embedded)?
Louis
--
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
Louis Tribble louis@metamata.com
Metamata, Inc. http://www.metamata.com
Tools for serious Java developers. +1 510 796 0915
<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>