You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2002/03/12 16:10:24 UTC
DO NOT REPLY [Bug 7052] New: -
Security manager not initialised or accessed properly
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=7052>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND
INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=7052
Security manager not initialised or accessed properly
Summary: Security manager not initialised or accessed properly
Product: Tomcat 4
Version: 4.0.3 Final
Platform: PC
OS/Version: Windows NT/2K
Status: NEW
Severity: Blocker
Priority: Other
Component: Jasper
AssignedTo: tomcat-dev@jakarta.apache.org
ReportedBy: keithhb@rolemodellers.com
OS: Win2K
JDK: 1.3.1_02
Stack Trace:
java.lang.NullPointerException
at
org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:180)
at
org.apache.jasper.servlet.JasperLoader.loadClass(JasperLoader.java:132)
at
java.lang.ClassLoader.loadClassInternal(Unknown Source)
at
org.apache.jsp.RMStartRim$jsp._jspService(RMStartRim$jsp.java:114)
at
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:107)
at
javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.jasper.servlet.JspServlet$JspServletWrapper.service(JspServlet.java:202)
at
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:382)
at
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:474)
at
javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
at
org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:190)
at
org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at
org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at
org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at
org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2343)
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at
org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at
org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:170)
at
org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:170)
at
org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at
org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at
org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at
org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at
org.apache.catalina.connector.http.HttpProcessor.process(HttpProcessor.java:1012)
at
org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor.java:1107)
at
java.lang.Thread.run(Unknown Source)
--------------------------------------------------------------------------------
Investigation:
I have had a problem
running JSPs under Tomcat 4.x embedded in JBoss 2.4.4, which I believe stems from the
initialisation of the "java.security.manager" system property.
When running Tomcat
inside JBoss, the security manager property does not seem to be automatically initialised,
perhaps because JBoss uses a different security model. If you try to initialise the system
property value yourself by specifying a security manager class name in the JBoss startup file
command line, you get a weird error, which I have not been able to debug since it crashes the JBoss
VM entirely.
Anyway, this would perhaps not matter to some people, who can get away without
specifying a security manager directly in their own code. However, I need to set one for the RMI
calls in Jini, since I persist data via a JavaSpace. Hence a part of my application
initialisation is to set the system security manager.
Now, the Tomcat class loader object
(an instance of org.apache.jasper.servlet.JasperLoader) is created before any web apps are
loaded, and there seems to be a bug in this class. The class loader object sets its security
manager as a private variable "securityManager" in the constructor from the System property.
This is before I get a chance inside my app to set the property, so the securityManager variable is
null in the Tomcat class loader object.
During a JSP, Tomcat then decides whether to do
security checks by checking whether or not the system property is null. If you have set it to a
value, as I do, Tomcat will try and do security checks. But it doesn't use the system property to
actually do the security check - it uses the private variable, which is still null! Hence,
whenever I try to use Java code in a JSP, Tomcat crashes with a NullPointerException, which is not
caught. See attached stack trace.
To get my JSPs running, I have patched
org.apache.jasper.servlet.JasperLoader to set the private variable "securityManager" if
it is null when about to do a security check, using the system property value. It was necessary to
do this in 3 places inside the class (see listing below). I put my version in a jar and placed it in
the folder %CATALINA_HOME%\common\lib. Since this is earlier on the classpath than the jar
from which the class is normally loaded, my version is used instead of the normal one, and the JSPs
now run OK.
If there is a better way to initialise the security manager in Tomcat4.x when
embedded in JBoss I would be very interested to hear of it, since it is obviously not ideal to be
patching Tomcat in order to get an app to run!
Best wishes
Keith Harrison-
Broninski
keithhb@rolemodellers.com
/*
*
====================================================================
*
* 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/>.
*
*/
package
org.apache.jasper.servlet;
import java.io.ByteArrayOutputStream;
import
java.io.InputStream;
import java.io.IOException;
import java.net.URL;
import
java.net.URLClassLoader;
import java.security.AccessController;
import
java.security.CodeSource;
import java.security.PermissionCollection;
import
java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import
org.apache.jasper.JasperException;
import org.apache.jasper.Constants;
import
org.apache.jasper.JspCompilationContext;
import
org.apache.jasper.JspEngineContext;
import org.apache.jasper.Options;
import
org.apache.jasper.compiler.Compiler;
import
org.apache.jasper.logging.Logger;
import javax.servlet.http.*;
/**
* This is a
class loader that loads JSP files as though they were
* Java classes. It calls the compiler to
compile the JSP file into a
* servlet and then loads the generated class.
*
* @author Anil K.
Vijendran
* @author Harish Prabandham
*/
public class JasperLoader extends
URLClassLoader {
protected class PrivilegedLoadClass
implements PrivilegedAction
{
PrivilegedLoadClass() {
}
public Object run() {
return
Thread.currentThread().getContextClassLoader();
}
}
private
PermissionCollection permissionCollection = null;
private CodeSource codeSource =
null;
private String className = null;
private ClassLoader parent = null;
private
SecurityManager securityManager = null;
private PrivilegedLoadClass privLoadClass =
null;
JasperLoader(URL [] urls, String className, ClassLoader parent,
PermissionCollection permissionCollection,
CodeSource codeSource)
{
super(urls,parent);
this.permissionCollection =
permissionCollection;
this.codeSource = codeSource;
this.className =
className;
this.parent = parent;
this.privLoadClass = new
PrivilegedLoadClass();
this.securityManager = System.getSecurityManager();
}
/**
* Load the class with the specified name. This method searches for
* classes in the same
manner as <code>loadClass(String, boolean)</code>
* with <code>false</code> as the
second argument.
*
* @param name Name of the class to be loaded
*
* @exception
ClassNotFoundException if the class was not found
*/
public Class loadClass(String name)
throws ClassNotFoundException {
return (loadClass(name, false));
}
/**
*
Load the class with the specified name, searching using the following
* algorithm until it
finds and returns the class. If the class cannot
* be found, returns
<code>ClassNotFoundException</code>.
* <ul>
* <li>Call
<code>findLoadedClass(String)</code> to check if the
* class has already been loaded. If it
has, the same
* <code>Class</code> object is returned.</li>
* <li>If the
<code>delegate</code> property is set to <code>true</code>,
* call the
<code>loadClass()</code> method of the parent class
* loader, if any.</li>
* <li>Call
<code>findClass()</code> to find this class in our locally
* defined repositories.</li>
* <li>Call the <code>loadClass()</code> method of our parent
* class loader, if any.</li>
* </ul>
* If the class was found using the above steps, and the
* <code>resolve</code> flag is
<code>true</code>, this method will then
* call <code>resolveClass(Class)</code> on the
resulting Class object.
*
* @param name Name of the class to be loaded
* @param resolve If
<code>true</code> then resolve the class
*
* @exception ClassNotFoundException if the
class was not found
*/
public Class loadClass(String name, boolean resolve)
throws
ClassNotFoundException {
Class clazz = null;
// (0) Check our previously loaded class
cache
clazz = findLoadedClass(name);
if (clazz != null) {
if (resolve)
resolveClass(clazz);
return (clazz);
}
// (.5) Permission to access this class when
using a SecurityManager
int dot = name.lastIndexOf('.');
if
(System.getSecurityManager() != null) {
// Start of patch 1/3 by Keith Harrison-
Broninski
if( securityManager == null ) {
securityManager =
System.getSecurityManager();
}
// End of patch 1/3 by Keith Harrison-Broninski
if
(dot >= 0) {
try {
securityManager.checkPackageAccess(name.substring(0,dot));
}
catch (SecurityException se) {
String error = "Security Violation, attempt to use " +
"Restricted Class: " + name;
System.out.println(error);
throw new
ClassNotFoundException(error);
}
}
}
// Class is in a package, delegate to thread
context class loader
if( !name.startsWith(Constants.JSP_PACKAGE_NAME) )
{
ClassLoader classLoader = null;
if (System.getSecurityManager() != null)
{
// Start of patch 2/3 by Keith Harrison-Broninski
if( securityManager == null )
{
securityManager = System.getSecurityManager();
}
// End of patch 2/3 by Keith
Harrison-Broninski
classLoader = (ClassLoader)
AccessController.doPrivileged(privLoadClass);
} else {
classLoader =
Thread.currentThread().getContextClassLoader();
}
clazz =
classLoader.loadClass(name);
if( resolve )
resolveClass(clazz);
return
clazz;
}
// Only load classes for this JSP page
if(
name.startsWith(Constants.JSP_PACKAGE_NAME + "." + className) ) {
String classFile =
name.substring(Constants.JSP_PACKAGE_NAME.length()+1) +
".class";
byte [] cdata
= loadClassDataFromFile(classFile);
if( cdata == null )
throw new
ClassNotFoundException(name);
if( System.getSecurityManager() != null ) {
//
Start of patch 3/3 by Keith Harrison-Broninski
if( securityManager == null )
{
securityManager = System.getSecurityManager();
}
// End of patch 3/3 by Keith
Harrison-Broninski
ProtectionDomain pd = new
ProtectionDomain(
codeSource,
permissionCollection);
clazz =
defineClass(name,cdata,0,cdata.length,pd);
} else {
clazz =
defineClass(name,cdata,0,cdata.length);
}
if( clazz != null ) {
if( resolve )
resolveClass(clazz);
return clazz;
}
}
throw new
ClassNotFoundException(name);
}
/**
* Get the Permissions for a CodeSource.
*
*
Since this ClassLoader is only used for a JSP page in
* a web application context, we just return
our preset
* PermissionCollection for the web app context.
*
* @param CodeSource where
the code was loaded from
* @return PermissionCollection for CodeSource
*/
protected
final PermissionCollection getPermissions(CodeSource codeSource) {
return
permissionCollection;
}
/**
* Load JSP class data from file.
*/
protected
byte[] loadClassDataFromFile(String fileName) {
byte[] classBytes = null;
try {
InputStream in = getResourceAsStream(fileName);
if (in == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buf[] = new byte[1024];
for(int i = 0; (i = in.read(buf)) != -1; )
baos.write(buf, 0, i);
in.close();
baos.close();
classBytes = baos.toByteArray();
} catch(Exception ex) {
ex.printStackTrace();
return null;
}
return classBytes;
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>