|
What this is
Other links
The source code/* * Copyright 1999-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.tomcat.facade; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Enumeration; import java.util.Stack; import java.util.Vector; import org.apache.tomcat.core.BaseInterceptor; import org.apache.tomcat.core.Context; import org.apache.tomcat.core.ContextManager; import org.apache.tomcat.core.TomcatException; import org.apache.tomcat.util.compat.Action; import org.apache.tomcat.util.compat.Jdk11Compat; import org.apache.tomcat.util.io.FileUtil; import org.apache.tomcat.util.res.StringManager; import org.apache.tomcat.util.xml.SaxContext; import org.apache.tomcat.util.xml.XmlAction; import org.apache.tomcat.util.xml.XmlMapper; import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; // XXX XXX Specific to servlet 2.2 /** * Read a servlet2.2 web.xml file and call the apropriate internal API * to set up the configuration. * * @author costin@dnt.ro */ public class WebXmlReader extends BaseInterceptor { public static final String defaultWelcomeList[]={"index.jsp", "index.html", "index.htm"}; public static final int DEFAULT_SESSION_TIMEOUT=30; private static StringManager sm =StringManager.getManager("org.apache.tomcat.resources"); boolean validate=true; static Jdk11Compat jdk11Compat=Jdk11Compat.getJdkCompat(); public WebXmlReader() { } public void setValidate( boolean b ) { validate=b; } private void readDefaultWebXml( Context ctx ) throws TomcatException { ContextManager cm=ctx.getContextManager(); String home = cm.getHome(); File default_xml=new File( home + "/conf/web.xml" ); // try the default ( installation ) if( ! default_xml.exists() ) { String tchome=ctx.getContextManager().getInstallDir(); if( tchome != null ) default_xml=new File( tchome + "/conf/web.xml"); } if( ! default_xml.exists() ) return; processWebXmlFile(ctx , default_xml.getPath()); } public void contextInit(Context ctx) throws TomcatException { if( debug > 0 ) log("contextInit " + ctx.getPath() + " " +ctx.getDocBase() ); ContextManager cm=ctx.getContextManager(); try { // Defaults ctx.setSessionTimeOut( 30 ); // We may read a "default" web.xml from INSTALL/conf/web.xml - // the code is commented out right now because we want to // consolidate the config in server.xml ( or API calls ), // we may put it back for 3.2 if needed. // note that web.xml have to be cleaned up - only diff from // default should be inside // readDefaultWebXml( ctx ); File inf_xml = new File(ctx.getAbsolutePath() + "/WEB-INF/web.xml"); if( inf_xml.exists() ) processWebXmlFile(ctx, inf_xml.getPath() ); // If the user haven't set any welcome file, use the // defaults. // If the user specifies welcome files, it's assumed he // doesn't want extra String newWF[]=ctx.getWelcomeFiles(); if( newWF==null || newWF.length==0 ) { for( int i=0; i< defaultWelcomeList.length; i++ ) ctx.addWelcomeFile( defaultWelcomeList[i]); } } catch (Exception e) { String msg = sm.getString("context.getConfig.e",ctx.getPath() + " " + ctx.getDocBase()); log(msg, e); } } static class WebXmlErrorHandler implements ErrorHandler{ Context ctx; XmlMapper xm; boolean ok=true; WebXmlErrorHandler( XmlMapper xm,Context ctx ) { this.ctx=ctx; this.xm=xm; } public void warning (SAXParseException exception) throws SAXException { ok=false; ctx.log("web.xml: Warning " + exception ); ctx.log(xm.positionToString()); } public void error (SAXParseException exception) throws SAXException { ok=false; ctx.log("web.xml: Error " + exception ); ctx.log(xm.positionToString()); } public void fatalError (SAXParseException exception) throws SAXException { ok=false; ctx.log("web.xml: Fatal error " + exception ); ctx.log(xm.positionToString()); throw new SAXException( "Fatal error " + exception ); } public boolean isOk() { return ok; } } void processWebXmlFile( Context ctx, String file) { try { File f=new File(FileUtil.patch(file)); if( ! f.exists() ) { ctx.log( "File not found " + f + ", using only defaults" ); return; } if( ctx.getDebug() > 0 ) ctx.log("Reading " + file ); XmlMapper xh=new XmlMapper(); WebXmlErrorHandler xeh=null; File v=new File( ctx.getWorkDir(), "webxmlval.txt" ); if( validate ) { if( ! v.exists() || v.lastModified() < f.lastModified() ) { ctx.log("Validating web.xml"); xh.setValidating(true); xeh=new WebXmlErrorHandler( xh, ctx ); xh.setErrorHandler( xeh ); } } // By using dtdURL you brake most parsers ( at least xerces ) xh.registerDTDRes("-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN", "org/apache/tomcat/resources/web.dtd"); xh.addRule("web-app/context-param", xh.methodSetter("addInitParameter", 2) ); xh.addRule("web-app/context-param/param-name", xh.methodParam(0) ); xh.addRule("web-app/context-param/param-value", xh.methodParam(1) ); xh.addRule("web-app/description", xh.methodSetter("setDescription", 0) ); xh.addRule("web-app/icon/small-icon", xh.methodSetter("setIcon", 0) ); xh.addRule("web-app/distributable", xh.methodSetter("setDistributable", 0) ); xh.addRule("web-app/servlet-mapping", xh.methodSetter("addServletMapping", 2) ); xh.addRule("web-app/servlet-mapping/servlet-name", xh.methodParam(1) ); xh.addRule("web-app/servlet-mapping/url-pattern", xh.methodParam(0) ); xh.addRule("web-app/taglib", xh.methodSetter("addTaglib", 2) ); xh.addRule("web-app/taglib/taglib-uri", xh.methodParam(0) ); xh.addRule("web-app/taglib/taglib-location", xh.methodParam(1) ); xh.addRule("web-app/env-entry", xh.methodSetter("addEnvEntry", 4) ); xh.addRule("web-app/env-entry/env-entry-name", xh.methodParam(0) ); xh.addRule("web-app/env-entry/env-entry-type", xh.methodParam(1) ); xh.addRule("web-app/env-entry/env-entry-value", xh.methodParam(2) ); xh.addRule("web-app/env-entry/description", xh.methodParam(3) ); xh.addRule("web-app/login-config", xh.methodSetter("setLoginConfig", 4) ); xh.addRule("web-app/login-config/auth-method", xh.methodParam(0) ); xh.addRule("web-app/login-config/realm-name", xh.methodParam(1) ); xh.addRule("web-app/login-config/form-login-config/form-login-page", xh.methodParam(2) ); xh.addRule("web-app/login-config/form-login-config/form-error-page", xh.methodParam(3) ); xh.addRule("web-app/mime-mapping", xh.methodSetter("addContentType", 2) ); xh.addRule("web-app/mime-mapping/extension", xh.methodParam(0) ); xh.addRule("web-app/mime-mapping/mime-type", xh.methodParam(1) ); xh.addRule("web-app/welcome-file-list/welcome-file", xh.methodSetter("addWelcomeFile", 0) ); xh.addRule("web-app/error-page", xh.methodSetter("addErrorPage",2) ); xh.addRule("web-app/error-page/error-code", xh.methodParam(0) ); xh.addRule("web-app/error-page/exception-type", xh.methodParam(0) ); xh.addRule("web-app/error-page/location", xh.methodParam(1) ); xh.addRule("web-app/session-config", xh.methodSetter("setSessionTimeOut", 1, new String[]{"int"})); xh.addRule("web-app/session-config/session-timeout", xh.methodParam(0)); // Servlet xh.addRule("web-app/servlet", xh.objectCreate("org.apache.tomcat.facade.ServletInfo") ); // servlet-wrapper xh.addRule("web-app/servlet", xh.setParent( "setContext") ); // remove it from stack when done // xh.addRule("web-app/servlet", xh.addChild("addServlet", "org.apache.tomcat.core.Handler") ); final WebXmlReader wxr=this; xh.addRule("web-app/servlet", new XmlAction() { public void end( SaxContext xctx) throws Exception { ServletInfo sw=(ServletInfo) xctx.currentObject(); Context cctx=(Context)xctx.previousObject(); sw.addServlet(cctx, wxr); } } ); // remove it from stack when done xh.addRule("web-app/servlet/servlet-name", xh.methodSetter("setServletName",0) ); xh.addRule("web-app/servlet/servlet-class", xh.methodSetter("setServletClassName",0)); xh.addRule("web-app/servlet/jsp-file", xh.methodSetter("setJspFile",0)); xh.addRule("web-app/servlet/security-role-ref", xh.methodSetter("addSecurityMapping", 3) ); xh.addRule("web-app/servlet/security-role-ref/role-name", xh.methodParam(0) ); xh.addRule("web-app/servlet/security-role-ref/role-link", xh.methodParam(1) ); xh.addRule("web-app/servlet/security-role-ref/description", xh.methodParam(2) ); xh.addRule("web-app/servlet/init-param", xh.methodSetter("addInitParam", 2) ); // addXXX xh.addRule("web-app/servlet/init-param/param-name", xh.methodParam(0) ); xh.addRule("web-app/servlet/init-param/param-value", xh.methodParam(1) ); xh.addRule("web-app/servlet/icon/small-icon", xh.methodSetter("setIcon",0 )); // icon, body xh.addRule("web-app/servlet/description", xh.methodSetter("setDescription", 0) ); // description, body xh.addRule("web-app/servlet/load-on-startup", xh.methodSetter("setLoadOnStartUp", 0 )); addSecurity( xh ); Object ctx1=null; xh.useLocalLoader( false ); // we'll use our own parser for web.xml // Perform the reading with the context privs Object pd=ctx.getAttribute( Context.ATTRIB_PROTECTION_DOMAIN); // System.out.println("Protection domain " + pd); if( pd!=null ) { // Do the action in a sandbox, with context privs PriviledgedAction di = new PriviledgedAction(xh, f, ctx); try { ctx1=jdk11Compat.doPrivileged(di, pd); } catch( TomcatException ex1 ) { throw ex1; } catch( Exception ex ) { throw new TomcatException( ex ); } } else { ctx1=xh.readXml(f, ctx); } if( validate && xeh != null && xeh.isOk() ) { // don't create the validation mark if an error was detected try { FileOutputStream fos=new FileOutputStream( v ); fos.write( 1 ); fos.close(); } catch(IOException ex ) { ctx.log( "Error creating validation mark ", ex ); } } } catch(Exception ex ) { log("ERROR initializing " + file, ex); try { ctx.setState( Context.STATE_DISABLED ); } catch(Exception ex1 ) { ex1.printStackTrace(); } // XXX we should invalidate the context and un-load it !!! } } // Sandbox support static class PriviledgedAction extends Action { XmlMapper xh; File f; Context ctx; public PriviledgedAction(XmlMapper xh, File f, Context ctx ) { this.xh=xh; this.ctx=ctx; this.f=f; } public Object run() throws Exception { return xh.readXml(f, ctx); } } // Add security rules - complex code void addSecurity( XmlMapper xh ) { xh.addRule("web-app/security-constraint", new SCAction() ); xh.addRule("web-app/security-constraint/user-data-constraint/transport-guarantee", new XmlAction() { public void end( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); SecurityConstraint rc=(SecurityConstraint)st.peek(); String body=ctx.getBody().trim(); rc.setTransport( body ); } } ); xh.addRule("web-app/security-constraint/auth-constraint/role-name", new XmlAction() { public void end( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); SecurityConstraint rc=(SecurityConstraint)st.peek(); String body=ctx.getBody().trim(); rc.addRole( body ); } } ); xh.addRule("web-app/security-constraint/web-resource-collection", new XmlAction() { public void start( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); st.push(new ResourceCollection()); } public void end( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); ResourceCollection rc=(ResourceCollection)st.pop(); SecurityConstraint sc=(SecurityConstraint)st.peek(); st.push( rc ); sc.addResourceCollection( rc ); } public void cleanup( SaxContext ctx) { Stack st=ctx.getObjectStack(); Object o=st.pop(); } } ); xh.addRule("web-app/security-constraint/web-resource-collection/url-pattern", new XmlAction() { public void end( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); ResourceCollection rc=(ResourceCollection)st.peek(); String body=ctx.getBody().trim(); rc.addUrlPattern( body ); } } ); xh.addRule("web-app/security-constraint/web-resource-collection/http-method", new XmlAction() { public void end( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); ResourceCollection rc=(ResourceCollection)st.peek(); String body=ctx.getBody().trim(); rc.addHttpMethod( body ); } } ); } } /** Specific action for Security-constraint */ class SCAction extends XmlAction { public void start( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); st.push(new SecurityConstraint()); } public void end( SaxContext ctx) throws Exception { Stack st=ctx.getObjectStack(); String tag=ctx.getTag(ctx.getTagCount()-1); SecurityConstraint sc=(SecurityConstraint)st.pop(); Context context=(Context)st.peek(); st.push( sc ); // restore stack // add all patterns that will need security String roles[]=sc.getRoles(); String transport=sc.getTransport(); Enumeration en=sc.getResourceCollections(); while( en.hasMoreElements()) { ResourceCollection rc=(ResourceCollection)en.nextElement(); String paths[]=rc.getPatterns(); String meths[]=rc.getMethods(); context.addSecurityConstraint( paths, meths , roles, transport); } } public void cleanup( SaxContext ctx) { Stack st=ctx.getObjectStack(); Object o=st.pop(); } } class SecurityConstraint { Vector roles=new Vector(); String transport; Vector resourceC=new Vector(); public SecurityConstraint() { } public void setTransport( String transport ) { this.transport=transport; } public String getTransport() { return this.transport; } public void addRole(String role ) { roles.addElement( role ); } public void addResourceCollection( ResourceCollection rc ) { resourceC.addElement( rc ); } public String []getRoles() { String rolesA[]=new String[roles.size()]; for( int i=0; i< rolesA.length; i++ ) { rolesA[i]=(String)roles.elementAt( i ); } return rolesA; } public Enumeration getResourceCollections() { return resourceC.elements(); } } class ResourceCollection { Vector urlP=new Vector(); Vector methods=new Vector(); public ResourceCollection() { } public void addUrlPattern( String pattern ) { urlP.addElement( pattern ); } public void addHttpMethod( String method ) { methods.addElement( method ); } public String []getMethods() { String methodsA[]=new String[methods.size()]; for( int i=0; i< methodsA.length; i++ ) { methodsA[i]=(String)methods.elementAt( i ); } return methodsA; } public String []getPatterns() { String patternsA[]=new String[urlP.size()]; for( int i=0; i< patternsA.length; i++ ) { patternsA[i]=(String)urlP.elementAt( i ); } return patternsA; } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.