diff --git a/.gitignore b/.gitignore index f6a7b45..fbdde0d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/apache-tomcat-7.0.42-src.tar.gz +SOURCES/apache-tomcat-7.0.54-src.tar.gz diff --git a/.tomcat.metadata b/.tomcat.metadata index 0f4bcad..5f4aba0 100644 --- a/.tomcat.metadata +++ b/.tomcat.metadata @@ -1 +1 @@ -3f1061428dc6274e5b6159ed06462702e0550bd1 SOURCES/apache-tomcat-7.0.42-src.tar.gz +70253e53572005adca147414a3d0eea4dbcc1ae0 SOURCES/apache-tomcat-7.0.54-src.tar.gz diff --git a/SOURCES/tomcat-7.0.42-CVE-2013-4286.patch b/SOURCES/tomcat-7.0.42-CVE-2013-4286.patch deleted file mode 100644 index d5b48a0..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2013-4286.patch +++ /dev/null @@ -1,206 +0,0 @@ ---- java/org/apache/coyote/ajp/AbstractAjpProcessor.java.orig 2014-03-14 17:13:46.228345000 -0400 -+++ java/org/apache/coyote/ajp/AbstractAjpProcessor.java 2014-03-18 13:54:13.570758000 -0400 -@@ -25,6 +25,8 @@ - import java.security.cert.X509Certificate; - import java.util.concurrent.atomic.AtomicBoolean; - -+import javax.servlet.http.HttpServletResponse; -+ - import org.apache.coyote.AbstractProcessor; - import org.apache.coyote.ActionCode; - import org.apache.coyote.AsyncContextCallback; -@@ -651,7 +653,7 @@ - - // Set this every time in case limit has been changed via JMX - headers.setLimit(endpoint.getMaxHeaderCount()); -- -+ boolean contentLengthSet = false; - int hCount = requestHeaderMessage.getInt(); - for(int i = 0 ; i < hCount ; i++) { - String hName = null; -@@ -686,10 +688,15 @@ - - if (hId == Constants.SC_REQ_CONTENT_LENGTH || - (hId == -1 && tmpMB.equalsIgnoreCase("Content-Length"))) { -- // just read the content-length header, so set it - long cl = vMB.getLong(); -- if(cl < Integer.MAX_VALUE) -- request.setContentLength( (int)cl ); -+ if (contentLengthSet) { -+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST); -+ error = true; -+ } else { -+ contentLengthSet = true; -+ // Set the content-length header for the request -+ request.setContentLength((int)cl); -+ } - } else if (hId == Constants.SC_REQ_CONTENT_TYPE || - (hId == -1 && tmpMB.equalsIgnoreCase("Content-Type"))) { - // just read the content-type header, so set it ---- java/org/apache/coyote/http11/AbstractHttp11Processor.java.orig 2014-03-14 17:13:46.514347000 -0400 -+++ java/org/apache/coyote/http11/AbstractHttp11Processor.java 2014-04-16 12:21:12.524505000 -0400 -@@ -1277,10 +1277,30 @@ - - // Parse content-length header - long contentLength = request.getContentLengthLong(); -- if (contentLength >= 0 && !contentDelimitation) { -- getInputBuffer().addActiveFilter -- (inputFilters[Constants.IDENTITY_FILTER]); -- contentDelimitation = true; -+ if (contentLength >= 0) { -+ if (getLog().isDebugEnabled()) { -+ getLog().debug("ContentLength="+contentLength); -+ getLog().debug(request.toString()); -+ } -+ if (contentDelimitation) { -+ // contentDelimitation being true at this point indicates that -+ // chunked encoding is being used but chunked encoding should -+ // not be used with a content length. RFC 2616, section 4.4, -+ // bullet 3 states Content-Length must be ignored in this case - -+ // so remove it. -+ headers.removeHeader("content-length"); -+ request.setContentLength(-1); -+ if (getLog().isDebugEnabled()) { -+ getLog().debug("ContentLength=-1"); -+ } -+ } else { -+ getInputBuffer().addActiveFilter -+ (inputFilters[Constants.IDENTITY_FILTER]); -+ contentDelimitation = true; -+ if (getLog().isDebugEnabled()) { -+ getLog().debug("ContentDelimitation=true"); -+ } -+ } - } - - MessageBytes valueMB = headers.getValue("host"); ---- test/org/apache/coyote/ajp/TestAbstractAjpProcessor.java.orig 2014-03-14 17:13:52.878367000 -0400 -+++ test/org/apache/coyote/ajp/TestAbstractAjpProcessor.java 2014-03-14 17:21:43.278956000 -0400 -@@ -90,6 +90,61 @@ - ajpClient.disconnect(); - } - -+ @Test -+ public void testPost() throws Exception { -+ doTestPost(false, HttpServletResponse.SC_OK); -+ } -+ -+ public void testPostMultipleContentLength() throws Exception { -+ // Multiple content lengths -+ doTestPost(true, HttpServletResponse.SC_BAD_REQUEST); -+ } -+ -+ -+ public void doTestPost(boolean multipleCL, int expectedStatus) -+ throws Exception { -+ Tomcat tomcat = getTomcatInstance(); -+ // Use the normal Tomcat ROOT context -+ File root = new File("test/webapp-3.0"); -+ tomcat.addWebapp("", root.getAbsolutePath()); -+ tomcat.start(); -+ SimpleAjpClient ajpClient = new SimpleAjpClient(); -+ ajpClient.setPort(getPort()); -+ ajpClient.connect(); -+ -+ validateCpong(ajpClient.cping()); -+ -+ TesterAjpMessage forwardMessage = -+ ajpClient.createForwardMessage("/echo-params.jsp", 4); -+ forwardMessage.addHeader(0xA008, "9"); -+ if (multipleCL) { -+ forwardMessage.addHeader(0xA008, "99"); -+ } -+ forwardMessage.addHeader(0xA007, "application/x-www-form-urlencoded"); -+ forwardMessage.end(); -+ TesterAjpMessage bodyMessage = -+ ajpClient.createBodyMessage("test=data".getBytes()); -+ -+ TesterAjpMessage responseHeaders = -+ ajpClient.sendMessage(forwardMessage, bodyMessage); -+ -+ validateResponseHeaders(responseHeaders, expectedStatus); -+ if (expectedStatus == HttpServletResponse.SC_OK) { -+ // Expect 3 messages: headers, body, end for a valid request -+ TesterAjpMessage responseBody = ajpClient.readMessage(); -+ validateResponseBody(responseBody, "test - data"); -+ validateResponseEnd(ajpClient.readMessage(), true); -+ // Double check the connection is still open -+ validateCpong(ajpClient.cping()); -+ } else { -+ // Expect 2 messages: headers, end for an invalid request -+ validateResponseEnd(ajpClient.readMessage(), false); -+ } -+ -+ ajpClient.disconnect(); -+ } -+ -+ - /** - * Process response header packet and checks the status. Any other data is - * ignored. ---- test/org/apache/coyote/http11/TestAbstractHttp11Processor.java.orig 2014-03-14 17:13:52.946367000 -0400 -+++ test/org/apache/coyote/http11/TestAbstractHttp11Processor.java 2014-03-14 17:13:52.925368000 -0400 -@@ -87,7 +87,7 @@ - "Transfer-encoding: buffered" + SimpleHttpClient.CRLF + - "Content-Length: 9" + SimpleHttpClient.CRLF + - "Content-Type: application/x-www-form-urlencoded" + -- SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF + - SimpleHttpClient.CRLF + - "test=data"; - -@@ -99,6 +99,54 @@ - assertTrue(client.isResponse501()); - } - -+ @Test -+ public void testWithTEChunked() throws Exception { -+ doTestWithTEChunked(false); -+ } -+ -+ @Test -+ public void testWithTEChunkedWithCL() throws Exception { -+ // Should be ignored -+ doTestWithTEChunked(true); -+ } -+ -+ private void doTestWithTEChunked(boolean withCL) -+ throws Exception { -+ -+ Tomcat tomcat = getTomcatInstance(); -+ -+ // Use the normal Tomcat ROOT context -+ File root = new File("test/webapp-3.0"); -+ tomcat.addWebapp("", root.getAbsolutePath()); -+ -+ tomcat.start(); -+ -+ String request = -+ "POST /echo-params.jsp HTTP/1.1" + SimpleHttpClient.CRLF + -+ "Host: any" + SimpleHttpClient.CRLF + -+ (withCL ? "Content-length: 1" + SimpleHttpClient.CRLF : "") + -+ "Transfer-encoding: chunked" + SimpleHttpClient.CRLF + -+ "Content-Type: application/x-www-form-urlencoded" + -+ SimpleHttpClient.CRLF + -+ "Connection: close" + SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF + -+ "9" + SimpleHttpClient.CRLF + -+ "test=data" + SimpleHttpClient.CRLF + -+ "0" + SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF; -+ -+ Client client = new Client(tomcat.getConnector().getLocalPort()); -+ client.setRequest(new String[] {request}); -+ -+ client.connect(); -+ client.processRequest(); -+ assertTrue(client.isResponse200()); -+ assertTrue(client.getResponseBody().contains("test - data")); -+ } -+ -+ -+ -+ - - @Test - public void testWithTEIdentity() throws Exception { diff --git a/SOURCES/tomcat-7.0.42-CVE-2013-4322.patch b/SOURCES/tomcat-7.0.42-CVE-2013-4322.patch deleted file mode 100644 index bb3803c..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2013-4322.patch +++ /dev/null @@ -1,377 +0,0 @@ ---- java/org/apache/coyote/http11/AbstractHttp11Processor.java.orig 2014-03-17 16:00:40.592415000 -0400 -+++ java/org/apache/coyote/http11/AbstractHttp11Processor.java 2014-03-18 13:39:06.789696000 -0400 -@@ -684,13 +684,14 @@ - /** - * Initialize standard input and output filters. - */ -- protected void initializeFilters(int maxTrailerSize) { -+ protected void initializeFilters(int maxTrailerSize, int maxExtensionSize) { - // Create and add the identity filters. - getInputBuffer().addFilter(new IdentityInputFilter()); - getOutputBuffer().addFilter(new IdentityOutputFilter()); - - // Create and add the chunked filters. -- getInputBuffer().addFilter(new ChunkedInputFilter(maxTrailerSize)); -+ getInputBuffer().addFilter( -+ new ChunkedInputFilter(maxTrailerSize, maxExtensionSize)); - getOutputBuffer().addFilter(new ChunkedOutputFilter()); - - // Create and add the void filters. ---- java/org/apache/coyote/http11/AbstractHttp11Protocol.java.orig 2014-03-17 16:00:57.458467000 -0400 -+++ java/org/apache/coyote/http11/AbstractHttp11Protocol.java 2014-03-17 16:40:11.035409000 -0400 -@@ -151,7 +151,15 @@ - this.maxTrailerSize = maxTrailerSize; - } - -- -+ /** -+ * Maximum size of extension information in chunked encoding -+ */ -+ private int maxExtensionSize = 8192; -+ public int getMaxExtensionSize() { return maxExtensionSize; } -+ public void setMaxExtensionSize(int maxExtensionSize) { -+ this.maxExtensionSize = maxExtensionSize; -+ } -+ - /** - * This field indicates if the protocol is treated as if it is secure. This - * normally means https is being used but can be used to fake https e.g ---- java/org/apache/coyote/http11/Http11AprProcessor.java.orig 2014-03-17 16:01:22.889559000 -0400 -+++ java/org/apache/coyote/http11/Http11AprProcessor.java 2014-03-17 16:43:14.716027000 -0400 -@@ -58,7 +58,7 @@ - - - public Http11AprProcessor(int headerBufferSize, AprEndpoint endpoint, -- int maxTrailerSize) { -+ int maxTrailerSize, int maxExtensionSize) { - - super(endpoint); - -@@ -68,7 +68,7 @@ - outputBuffer = new InternalAprOutputBuffer(response, headerBufferSize); - response.setOutputBuffer(outputBuffer); - -- initializeFilters(maxTrailerSize); -+ initializeFilters(maxTrailerSize, maxExtensionSize); - } - - ---- java/org/apache/coyote/http11/Http11AprProtocol.java.orig 2014-03-17 16:10:16.268358000 -0400 -+++ java/org/apache/coyote/http11/Http11AprProtocol.java 2014-03-17 16:50:17.428466000 -0400 -@@ -294,7 +294,7 @@ - protected Http11AprProcessor createProcessor() { - Http11AprProcessor processor = new Http11AprProcessor( - proto.getMaxHttpHeaderSize(), (AprEndpoint)proto.endpoint, -- proto.getMaxTrailerSize()); -+ proto.getMaxTrailerSize(), proto.getMaxExtensionSize()); - processor.setAdapter(proto.adapter); - processor.setMaxKeepAliveRequests(proto.getMaxKeepAliveRequests()); - processor.setKeepAliveTimeout(proto.getKeepAliveTimeout()); ---- java/org/apache/coyote/http11/Http11NioProcessor.java.orig 2014-03-17 16:02:20.016748000 -0400 -+++ java/org/apache/coyote/http11/Http11NioProcessor.java 2014-03-17 16:51:55.623782000 -0400 -@@ -63,7 +63,7 @@ - - - public Http11NioProcessor(int maxHttpHeaderSize, NioEndpoint endpoint, -- int maxTrailerSize) { -+ int maxTrailerSize, int maxExtensionSize) { - - super(endpoint); - -@@ -73,7 +73,7 @@ - outputBuffer = new InternalNioOutputBuffer(response, maxHttpHeaderSize); - response.setOutputBuffer(outputBuffer); - -- initializeFilters(maxTrailerSize); -+ initializeFilters(maxTrailerSize, maxExtensionSize); - } - - ---- java/org/apache/coyote/http11/Http11NioProtocol.java.orig 2014-03-17 16:07:26.027787000 -0400 -+++ java/org/apache/coyote/http11/Http11NioProtocol.java 2014-03-17 16:53:09.198025000 -0400 -@@ -260,7 +260,7 @@ - public Http11NioProcessor createProcessor() { - Http11NioProcessor processor = new Http11NioProcessor( - proto.getMaxHttpHeaderSize(), (NioEndpoint)proto.endpoint, -- proto.getMaxTrailerSize()); -+ proto.getMaxTrailerSize(), proto.getMaxExtensionSize()); - processor.setAdapter(proto.adapter); - processor.setMaxKeepAliveRequests(proto.getMaxKeepAliveRequests()); - processor.setKeepAliveTimeout(proto.getKeepAliveTimeout()); ---- java/org/apache/coyote/http11/Http11Processor.java.orig 2014-03-17 16:07:45.099837000 -0400 -+++ java/org/apache/coyote/http11/Http11Processor.java 2014-03-18 12:42:34.018260000 -0400 -@@ -50,7 +50,7 @@ - - - public Http11Processor(int headerBufferSize, JIoEndpoint endpoint, -- int maxTrailerSize) { -+ int maxTrailerSize, int maxExtensionSize) { - - super(endpoint); - -@@ -60,7 +60,7 @@ - outputBuffer = new InternalOutputBuffer(response, headerBufferSize); - response.setOutputBuffer(outputBuffer); - -- initializeFilters(maxTrailerSize); -+ initializeFilters(maxTrailerSize, maxExtensionSize); - } - - ---- java/org/apache/coyote/http11/Http11Protocol.java.orig 2014-03-17 16:08:00.058113000 -0400 -+++ java/org/apache/coyote/http11/Http11Protocol.java 2014-03-17 16:56:04.194609000 -0400 -@@ -164,7 +164,7 @@ - protected Http11Processor createProcessor() { - Http11Processor processor = new Http11Processor( - proto.getMaxHttpHeaderSize(), (JIoEndpoint)proto.endpoint, -- proto.getMaxTrailerSize()); -+ proto.getMaxTrailerSize(), proto.getMaxExtensionSize()); - processor.setAdapter(proto.adapter); - processor.setMaxKeepAliveRequests(proto.getMaxKeepAliveRequests()); - processor.setKeepAliveTimeout(proto.getKeepAliveTimeout()); ---- java/org/apache/coyote/http11/filters/ChunkedInputFilter.java.orig 2014-03-17 16:08:12.213985000 -0400 -+++ java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2014-04-15 19:51:43.729201000 -0400 -@@ -39,6 +39,8 @@ - */ - public class ChunkedInputFilter implements InputFilter { - -+ private static final org.apache.juli.logging.Log log -+ = org.apache.juli.logging.LogFactory.getLog(ChunkedInputFilter.class); - - // -------------------------------------------------------------- Constants - -@@ -118,9 +120,29 @@ - */ - private Request request; - -+ -+ /** -+ * Limit for extension size. -+ */ -+ private final long maxExtensionSize; -+ -+ -+ /** -+ * Limit for trailer size. -+ */ -+ private int maxTrailerSize; -+ -+ -+ /** -+ * Size of extensions processed for this request. -+ */ -+ private long extensionSize; -+ - // ----------------------------------------------------------- Constructors -- public ChunkedInputFilter(int maxTrailerSize) { -+ public ChunkedInputFilter(int maxTrailerSize, int maxExtensionSize) { - this.trailingHeaders.setLimit(maxTrailerSize); -+ this.maxTrailerSize = maxTrailerSize; -+ this.maxExtensionSize = maxExtensionSize; - } - - // ---------------------------------------------------- InputBuffer Methods -@@ -250,6 +272,8 @@ - endChunk = false; - needCRLFParse = false; - trailingHeaders.recycle(); -+ trailingHeaders.setLimit(maxTrailerSize); -+ extensionSize = 0; - } - - -@@ -299,7 +323,7 @@ - int result = 0; - boolean eol = false; - boolean readDigit = false; -- boolean trailer = false; -+ boolean extension = false; - - while (!eol) { - -@@ -309,11 +333,17 @@ - } - - if (buf[pos] == Constants.CR || buf[pos] == Constants.LF) { -+ log.info("EOL is true"); - parseCRLF(false); - eol = true; -- } else if (buf[pos] == Constants.SEMI_COLON) { -- trailer = true; -- } else if (!trailer) { -+ } else if (buf[pos] == Constants.SEMI_COLON && !extension) { -+ // First semi-colon marks the start of the extension. Further -+ // semi-colons may appear to separate multiple chunk-extensions. -+ // These need to be processed as part of parsing the extensions. -+ extension = true; -+ extensionSize++; -+ log.info("SEMI_COLON"); -+ } else if (!extension) { - //don't read data after the trailer - int charValue = HexUtils.getDec(buf[pos]); - if (charValue != -1) { -@@ -323,15 +353,22 @@ - } else { - //we shouldn't allow invalid, non hex characters - //in the chunked header -+ log.info("Returning false"); - return false; - } -- } -- -+ } else { -+ // Extension 'parsing' -+ // Note that the chunk-extension is neither parsed nor -+ // validated. Currently it is simply ignored. -+ extensionSize++; -+ if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) { -+ throw new IOException("maxExtensionSize exceeded"); -+ } -+ } - // Parsing the CRLF increments pos - if (!eol) { - pos++; - } -- - } - - if (!readDigit) -@@ -489,12 +526,17 @@ - chr = buf[pos]; - if ((chr == Constants.SP) || (chr == Constants.HT)) { - pos++; -+ // If we swallow whitespace, make sure it counts towards the -+ // limit placed on trailing header size -+ int newlimit = trailingHeaders.getLimit() -1; -+ if (trailingHeaders.getEnd() > newlimit) { -+ throw new IOException("Exceeded maxTrailerSize"); -+ } -+ trailingHeaders.setLimit(newlimit); - } else { - space = false; - } -- - } -- - // Reading bytes until the end of the line - while (!eol) { - ---- test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java.orig 2014-03-17 16:08:33.031999000 -0400 -+++ test/org/apache/coyote/http11/filters/TestChunkedInputFilter.java 2014-03-17 17:40:23.853592000 -0400 -@@ -41,6 +41,7 @@ - public class TestChunkedInputFilter extends TomcatBaseTest { - - private static final String LF = "\n"; -+ private static final int EXT_SIZE_LIMIT = 10; - - @Test - public void testChunkHeaderCRLF() throws Exception { -@@ -202,6 +203,79 @@ - assertTrue(client.isResponse500()); - } - -+ -+ @Test -+ public void testExtensionSizeLimitOneBelow() throws Exception { -+ doTestExtensionSizeLimit(EXT_SIZE_LIMIT - 1, true); -+ } -+ -+ -+ @Test -+ public void testExtensionSizeLimitExact() throws Exception { -+ doTestExtensionSizeLimit(EXT_SIZE_LIMIT, true); -+ } -+ -+ -+ @Test -+ public void testExtensionSizeLimitOneOver() throws Exception { -+ doTestExtensionSizeLimit(EXT_SIZE_LIMIT + 1, false); -+ } -+ -+ private void doTestExtensionSizeLimit(int len, boolean ok) -+ throws Exception { -+ // Setup Tomcat instance -+ Tomcat tomcat = getTomcatInstance(); -+ -+ tomcat.getConnector().setProperty( -+ "maxExtensionSize", Integer.toString(EXT_SIZE_LIMIT)); -+ -+ // Must have a real docBase - just use temp -+ Context ctx = -+ tomcat.addContext("", System.getProperty("java.io.tmpdir")); -+ -+ Tomcat.addServlet(ctx, "servlet", new EchoHeaderServlet()); -+ ctx.addServletMapping("/", "servlet"); -+ -+ tomcat.start(); -+ -+ String extName = ";foo="; -+ StringBuilder extValue = new StringBuilder(len); -+ for (int i = 0; i < (len - extName.length()); i++) { -+ extValue.append("x"); -+ } -+ -+ String[] request = new String[]{ -+ "POST /echo-params.jsp HTTP/1.1" + SimpleHttpClient.CRLF + -+ "Host: any" + SimpleHttpClient.CRLF + -+ "Transfer-encoding: chunked" + SimpleHttpClient.CRLF + -+ "Content-Type: application/x-www-form-urlencoded" + -+ SimpleHttpClient.CRLF + -+ "Connection: close" + SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF + -+ "3" + extName + extValue.toString() + SimpleHttpClient.CRLF + -+ "a=0" + SimpleHttpClient.CRLF + -+ "4" + SimpleHttpClient.CRLF + -+ "&b=1" + SimpleHttpClient.CRLF + -+ "0" + SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF }; -+ -+ TrailerClient client = -+ new TrailerClient(tomcat.getConnector().getLocalPort()); -+ client.setRequest(request); -+ -+ client.connect(); -+ client.processRequest(); -+ -+ if (ok) { -+ assertTrue(client.isResponse200()); -+ } else { -+ assertTrue(client.isResponse500()); -+ } -+ } -+ -+ -+ -+ - @Test - public void testNoTrailingHeaders() throws Exception { - // Setup Tomcat instance ---- webapps/docs/changelog.xml.orig 2014-03-17 16:08:46.095050000 -0400 -+++ webapps/docs/changelog.xml 2014-03-17 17:44:14.163385000 -0400 -@@ -394,6 +394,11 @@ -
- - -+ -+ Add support for limiting the size of chunk extensions when using chunked -+ encoding. (markt) -+ CVE-2013-4322 patch applied by Red Hat. -+ - - Update Tomcat's internal copy of Commons FileUpload to FileUpload 1.3. - (markt) ---- webapps/docs/config/http.xml.orig 2014-03-17 16:08:59.013101000 -0400 -+++ webapps/docs/config/http.xml 2014-03-17 18:10:13.965639000 -0400 -@@ -399,6 +399,12 @@ - and connections are not counted.

- - -+ -+

Limits the total length of chunk extensions in chunked HTTP requests. -+ If the value is -1, no limit will be imposed. If not -+ specified, the default value of 8192 will be used.

-+
-+ - -

The maximum size of the request and response HTTP header, specified - in bytes. If not specified, this attribute is set to 8192 (8 KB).

diff --git a/SOURCES/tomcat-7.0.42-CVE-2013-4590.patch b/SOURCES/tomcat-7.0.42-CVE-2013-4590.patch deleted file mode 100644 index 2382995..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2013-4590.patch +++ /dev/null @@ -1,3141 +0,0 @@ ---- java/org/apache/catalina/Context.java.orig 2014-07-21 17:24:05.516400000 -0400 -+++ java/org/apache/catalina/Context.java 2014-07-21 17:46:59.386109000 -0400 -@@ -40,6 +40,7 @@ - import org.apache.catalina.deploy.NamingResources; - import org.apache.catalina.deploy.SecurityConstraint; - import org.apache.catalina.util.CharsetMapper; -+import org.apache.tomcat.InstanceManager; - import org.apache.tomcat.JarScanner; - import org.apache.tomcat.util.http.mapper.Mapper; - -@@ -61,7 +62,7 @@ - *

- * - * @author Craig R. McClanahan -- * @version $Id: Context.java 1492415 2013-06-12 20:41:33Z markt $ -+ * @version $Id: Context.java 1552258 2013-12-19 09:25:18Z markt $ - */ - - public interface Context extends Container { -@@ -616,70 +617,99 @@ - - - /** -- * Get the server.xml attribute's xmlNamespaceAware. -- * @return true if namespace awareness is enabled. -+ * Will the parsing of web.xml and web-fragment.xml files for this Context -+ * be performed by a namespace aware parser? - * -+ * @return true if namespace awareness is enabled. - */ - public boolean getXmlNamespaceAware(); - -+ -+ /** -+ * Controls whether the parsing of web.xml and web-fragment.xml files for -+ * this Context will be performed by a namespace aware parser. -+ * -+ * @param xmlNamespaceAware true to enable namespace awareness -+ */ -+ public void setXmlNamespaceAware(boolean xmlNamespaceAware); - -+ - /** -- * Get the server.xml attribute's xmlValidation. -- * @return true if validation is enabled. -+ * Will the parsing of web.xml and web-fragment.xml files for this Context -+ * be performed by a validating parser? - * -+ * @return true if validation is enabled. - */ - public boolean getXmlValidation(); - - - /** -- * Set the validation feature of the XML parser used when -- * parsing xml instances. -- * @param xmlValidation true to enable xml instance validation -+ * Controls whether the parsing of web.xml and web-fragment.xml files -+ * for this Context will be performed by a validating parser. -+ * -+ * @param xmlValidation true to enable xml validation - */ - public void setXmlValidation(boolean xmlValidation); - - -- /** -- * Set the namespace aware feature of the XML parser used when -- * parsing xml instances. -- * @param xmlNamespaceAware true to enable namespace awareness -+ /** -+ * *.tld files are always parsed using a namespace aware parser. -+ * -+ * @return Always true -+ * -+ * @deprecated This option will be removed in 8.0.x. - */ -- public void setXmlNamespaceAware(boolean xmlNamespaceAware); -+ @Deprecated -+ public boolean getTldNamespaceAware(); -+ -+ - /** -- * Get the server.xml attribute's xmlValidation. -- * @return true if validation is enabled. -+ * *.tld files are always parsed using a namespace aware parser. -+ * -+ * @param tldNamespaceAware ignored -+ * -+ * @deprecated This option will be removed in 8.0.x. - */ -+ @Deprecated -+ public void setTldNamespaceAware(boolean tldNamespaceAware); - - - /** -- * Set the validation feature of the XML parser used when -- * parsing tlds files. -- * @param tldValidation true to enable xml instance validation -+ * Will the parsing of web.xml, web-fragment.xml, *.tld, *.jspx, *.tagx and -+ * tagplugin.xml files for this Context block the use of external entities? -+ * -+ * @return true if access to external entities is blocked - */ -- public void setTldValidation(boolean tldValidation); -+ public boolean getXmlBlockExternal(); - - - /** -- * Get the server.xml attribute's webXmlValidation. -- * @return true if validation is enabled. -+ * Controls whether the parsing of web.xml, web-fragment.xml, *.tld, *.jspx, -+ * *.tagx and tagplugin.xml files for this Context will block the use of -+ * external entities. - * -+ * @param xmlBlockExternal true to block external entities - */ -- public boolean getTldValidation(); -+ public void setXmlBlockExternal(boolean xmlBlockExternal); - - - /** -- * Get the server.xml <host> attribute's xmlNamespaceAware. -- * @return true if namespace awareness is enabled. -+ * Will the parsing of *.tld files for this Context be performed by a -+ * validating parser? -+ * -+ * @return true if validation is enabled. - */ -- public boolean getTldNamespaceAware(); -+ public boolean getTldValidation(); - - - /** -- * Set the namespace aware feature of the XML parser used when -- * parsing xml instances. -- * @param tldNamespaceAware true to enable namespace awareness -+ * Controls whether the parsing of *.tld files for this Context will be -+ * performed by a validating parser. -+ * -+ * @param tldValidation true to enable xml validation - */ -- public void setTldNamespaceAware(boolean tldNamespaceAware); -+ public void setTldValidation(boolean tldValidation); -+ - - /** - * Get the Jar Scanner to be used to scan for JAR resources for this -@@ -712,6 +742,16 @@ - */ - public boolean getLogEffectiveWebXml(); - -+ /** -+ * Get the instance manager associated with this context. -+ */ -+ public InstanceManager getInstanceManager(); -+ -+ /** -+ * Set the instance manager associated with this context. -+ */ -+ public void setInstanceManager(InstanceManager instanceManager); -+ - // --------------------------------------------------------- Public Methods - - ---- java/org/apache/catalina/Globals.java.orig 2014-07-21 17:24:05.521402000 -0400 -+++ java/org/apache/catalina/Globals.java 2014-07-21 17:46:59.394034000 -0400 -@@ -14,18 +14,14 @@ - * See the License for the specific language governing permissions and - * limitations under the License. - */ -- -- - package org.apache.catalina; - -- - /** - * Global constants that are applicable to multiple packages within Catalina. - * - * @author Craig R. McClanahan -- * @version $Id: Globals.java 1301255 2012-03-15 22:47:40Z markt $ -+ * @version $Id: Globals.java 1549529 2013-12-09 10:05:56Z markt $ - */ -- - public final class Globals { - - /** -@@ -310,4 +306,25 @@ - * the tomcat instance installation path - */ - public static final String CATALINA_BASE_PROP = "catalina.base"; -+ -+ -+ /** -+ * Name of the ServletContext init-param that determines if the JSP engine -+ * should validate *.tld files when parsing them. -+ *

-+ * This must be kept in sync with org.apache.jasper.Constants -+ */ -+ public static final String JASPER_XML_VALIDATION_TLD_INIT_PARAM = -+ "org.apache.jasper.XML_VALIDATE_TLD"; -+ -+ -+ /** -+ * Name of the ServletContext init-param that determines if the JSP engine -+ * will block external entities from being used in *.tld, *.jspx, *.tagx and -+ * tagplugin.xml files. -+ *

-+ * This must be kept in sync with org.apache.jasper.Constants -+ */ -+ public static final String JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM = -+ "org.apache.jasper.XML_BLOCK_EXTERNAL"; - } ---- java/org/apache/catalina/ant/ValidatorTask.java.orig 2014-07-21 17:24:05.537406000 -0400 -+++ java/org/apache/catalina/ant/ValidatorTask.java 2014-07-21 17:46:59.401034000 -0400 -@@ -14,18 +14,16 @@ - * See the License for the specific language governing permissions and - * limitations under the License. - */ -- -- - package org.apache.catalina.ant; - -- - import java.io.BufferedInputStream; - import java.io.File; - import java.io.FileInputStream; - import java.io.InputStream; - -+import org.apache.catalina.Globals; - import org.apache.catalina.startup.Constants; --import org.apache.catalina.startup.DigesterFactory; -+import org.apache.tomcat.util.descriptor.DigesterFactory; - import org.apache.tomcat.util.digester.Digester; - import org.apache.tools.ant.BuildException; - import org.xml.sax.InputSource; -@@ -36,7 +34,7 @@ - * schema validation. - * - * @author Remy Maucherat -- * @version $Id: ValidatorTask.java 1001899 2010-09-27 20:24:18Z markt $ -+ * @version $Id: ValidatorTask.java 1549529 2013-12-09 10:05:56Z markt $ - * @since 5.0 - */ - -@@ -90,7 +88,10 @@ - Thread.currentThread().setContextClassLoader - (ValidatorTask.class.getClassLoader()); - -- Digester digester = DigesterFactory.newDigester(true, true, null); -+ // Called through trusted manager interface. If running under a -+ // SecurityManager assume that untrusted applications may be deployed. -+ Digester digester = DigesterFactory.newDigester( -+ true, true, null, Globals.IS_SECURITY_ENABLED); - try { - file = file.getCanonicalFile(); - InputStream stream = ---- java/org/apache/catalina/core/ApplicationContext.java.orig 2014-07-21 17:24:05.543399000 -0400 -+++ java/org/apache/catalina/core/ApplicationContext.java 2014-07-22 16:07:21.579832000 -0400 -@@ -5,9 +5,9 @@ - * The ASF licenses this file to You 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. -@@ -84,7 +84,7 @@ - * - * @author Craig R. McClanahan - * @author Remy Maucherat -- * @version $Id: ApplicationContext.java 1493015 2013-06-14 10:00:57Z markt $ -+ * @version $Id: ApplicationContext.java 1549529 2013-12-09 10:05:56Z markt $ - */ - - public class ApplicationContext -@@ -97,7 +97,7 @@ - - static { - STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE; -- -+ - String requireSlash = System.getProperty( - "org.apache.catalina.core.ApplicationContext.GET_RESOURCE_REQUIRE_SLASH"); - if (requireSlash == null) { -@@ -302,7 +302,7 @@ - } - } - -- -+ - /** - * Return the main path associated with this context. - */ -@@ -310,7 +310,7 @@ - public String getContextPath() { - return context.getPath(); - } -- -+ - - /** - * Return the value of the specified initialization parameter, or -@@ -320,6 +320,20 @@ - */ - @Override - public String getInitParameter(final String name) { -+ // Special handling for XML settings as the context setting must -+ // always override anything that might have been set by an application. -+ if (Globals.JASPER_XML_VALIDATION_TLD_INIT_PARAM.equals(name) && -+ context.getTldValidation()) { -+ return "true"; -+ } -+ if (Globals.JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM.equals(name)) { -+ if (context.getXmlBlockExternal()) { -+ return "true"; -+ } else if (Globals.IS_SECURITY_ENABLED) { -+ // System admin has explicitly changed the default -+ return "false"; -+ } -+ } - return parameters.get(name); - } - -@@ -330,7 +344,17 @@ - */ - @Override - public Enumeration getInitParameterNames() { -- return Collections.enumeration(parameters.keySet()); -+ Set names = new HashSet(); -+ names.addAll(parameters.keySet()); -+ // Special handling for XML settings as these attributes will always be -+ // available if they have been set on the context -+ if (context.getTldValidation()) { -+ names.add(Globals.JASPER_XML_VALIDATION_TLD_INIT_PARAM); -+ } -+ if (context.getXmlBlockExternal() || Globals.IS_SECURITY_ENABLED) { -+ names.add(Globals.JASPER_XML_BLOCK_EXTERNAL_INIT_PARAM); -+ } -+ return Collections.enumeration(names); - } - - -@@ -395,7 +419,7 @@ - Wrapper wrapper = (Wrapper) context.findChild(name); - if (wrapper == null) - return (null); -- -+ - return new ApplicationDispatcher(wrapper, null, null, null, null, name); - - } -@@ -444,7 +468,7 @@ - if (normalizedPath == null) - return (null); - -- pos = normalizedPath.length(); -+ pos = normalizedPath.length(); - - // Use the thread local URI and mapping data - DispatchData dd = dispatchData.get(); -@@ -495,10 +519,10 @@ - String pathInfo = mappingData.pathInfo.toString(); - - mappingData.recycle(); -- -+ - // Construct a RequestDispatcher to process this request - return new ApplicationDispatcher -- (wrapper, uriCC.toString(), wrapperPath, pathInfo, -+ (wrapper, uriCC.toString(), wrapperPath, pathInfo, - queryString, null); - - } -@@ -523,7 +547,7 @@ - !path.startsWith("/") && GET_RESOURCE_REQUIRE_SLASH) - throw new MalformedURLException(sm.getString( - "applicationContext.requestDispatcher.iae", path)); -- -+ - String normPath = RequestUtil.normalize(path); - if (normPath == null) - return (null); -@@ -724,7 +748,7 @@ - @Override - @Deprecated - public void log(Exception exception, String message) { -- -+ - context.getLogger().error(message, exception); - - } -@@ -738,7 +762,7 @@ - */ - @Override - public void log(String message, Throwable throwable) { -- -+ - context.getLogger().error(message, throwable); - - } -@@ -893,11 +917,11 @@ - @Override - public FilterRegistration.Dynamic addFilter(String filterName, - String filterClass) throws IllegalStateException { -- -+ - return addFilter(filterName, filterClass, null); - } - -- -+ - /** - * Add filter to context. - * @param filterName Name of filter to add -@@ -915,11 +939,11 @@ - @Override - public FilterRegistration.Dynamic addFilter(String filterName, - Filter filter) throws IllegalStateException { -- -+ - return addFilter(filterName, null, filter); - } - -- -+ - /** - * Add filter to context. - * @param filterName Name of filter to add -@@ -937,13 +961,13 @@ - @Override - public FilterRegistration.Dynamic addFilter(String filterName, - Class filterClass) throws IllegalStateException { -- -+ - return addFilter(filterName, filterClass.getName(), null); - } - - private FilterRegistration.Dynamic addFilter(String filterName, - String filterClass, Filter filter) throws IllegalStateException { -- -+ - if (filterName == null || filterName.equals("")) { - throw new IllegalArgumentException(sm.getString( - "applicationContext.invalidFilterName", filterName)); -@@ -957,7 +981,7 @@ - } - - FilterDef filterDef = context.findFilterDef(filterName); -- -+ - // Assume a 'complete' FilterRegistration is one that has a class and - // a name - if (filterDef == null) { -@@ -977,14 +1001,15 @@ - filterDef.setFilterClass(filter.getClass().getName()); - filterDef.setFilter(filter); - } -- -+ - return new ApplicationFilterRegistration(filterDef, context); -- } -- -+ } -+ - @Override - public T createFilter(Class c) - throws ServletException { - try { -+ @SuppressWarnings("unchecked") - T filter = (T) context.getInstanceManager().newInstance(c.getName()); - return filter; - } catch (IllegalAccessException e) { -@@ -1011,7 +1036,7 @@ - return new ApplicationFilterRegistration(filterDef, context); - } - -- -+ - /** - * Add servlet to context. - * @param servletName Name of servlet to add -@@ -1029,7 +1054,7 @@ - @Override - public ServletRegistration.Dynamic addServlet(String servletName, - String servletClass) throws IllegalStateException { -- -+ - return addServlet(servletName, servletClass, null); - } - -@@ -1055,7 +1080,7 @@ - return addServlet(servletName, null, servlet); - } - -- -+ - /** - * Add servlet to context. - * @param servletName Name of servlet to add -@@ -1080,7 +1105,7 @@ - - private ServletRegistration.Dynamic addServlet(String servletName, - String servletClass, Servlet servlet) throws IllegalStateException { -- -+ - if (servletName == null || servletName.equals("")) { - throw new IllegalArgumentException(sm.getString( - "applicationContext.invalidServletName", servletName)); -@@ -1092,9 +1117,9 @@ - sm.getString("applicationContext.addServlet.ise", - getContextPath())); - } -- -+ - Wrapper wrapper = (Wrapper) context.findChild(servletName); -- -+ - // Assume a 'complete' ServletRegistration is one that has a class and - // a name - if (wrapper == null) { -@@ -1127,6 +1152,7 @@ - public T createServlet(Class c) - throws ServletException { - try { -+ @SuppressWarnings("unchecked") - T servlet = (T) context.getInstanceManager().newInstance(c.getName()); - context.dynamicServletCreated(servlet); - return servlet; -@@ -1151,10 +1177,10 @@ - if (wrapper == null) { - return null; - } -- -+ - return new ApplicationServletRegistration(wrapper, context); - } -- -+ - - /** - * By default {@link SessionTrackingMode#URL} is always supported, {@link -@@ -1171,15 +1197,15 @@ - - private void populateSessionTrackingModes() { - // URL re-writing is always enabled by default -- defaultSessionTrackingModes = EnumSet.of(SessionTrackingMode.URL); -+ defaultSessionTrackingModes = EnumSet.of(SessionTrackingMode.URL); - supportedSessionTrackingModes = EnumSet.of(SessionTrackingMode.URL); -- -+ - if (context.getCookies()) { - defaultSessionTrackingModes.add(SessionTrackingMode.COOKIE); - supportedSessionTrackingModes.add(SessionTrackingMode.COOKIE); - } - -- // SSL not enabled by default as it can only used on its own -+ // SSL not enabled by default as it can only used on its own - // Context > Host > Engine > Service - Service s = ((Engine) context.getParent().getParent()).getService(); - Connector[] connectors = s.findConnectors(); -@@ -1189,7 +1215,7 @@ - supportedSessionTrackingModes.add(SessionTrackingMode.SSL); - break; - } -- } -+ } - } - - /** -@@ -1226,7 +1252,7 @@ - sm.getString("applicationContext.setSessionTracking.ise", - getContextPath())); - } -- -+ - // Check that only supported tracking modes have been requested - for (SessionTrackingMode sessionTrackingMode : sessionTrackingModes) { - if (!supportedSessionTrackingModes.contains(sessionTrackingMode)) { -@@ -1244,7 +1270,7 @@ - getContextPath())); - } - } -- -+ - this.sessionTrackingModes = sessionTrackingModes; - } - -@@ -1253,8 +1279,8 @@ - public boolean setInitParameter(String name, String value) { - return parameters.putIfAbsent(name, value) == null; - } -- -- -+ -+ - @Override - public void addListener(Class listenerClass) { - EventListener listener; -@@ -1271,7 +1297,7 @@ - - @Override - public void addListener(String className) { -- -+ - try { - Object obj = context.getInstanceManager().newInstance(className); - -@@ -1305,7 +1331,7 @@ - "applicationContext.addListener.iae.cnfe", className), - e); - } -- -+ - } - - -@@ -1325,7 +1351,7 @@ - context.addApplicationEventListener(t); - match = true; - } -- -+ - if (t instanceof HttpSessionListener - || (t instanceof ServletContextListener && - newServletContextListenerAllowed)) { -@@ -1334,9 +1360,9 @@ - context.addApplicationLifecycleListener(t); - match = true; - } -- -+ - if (match) return; -- -+ - if (t instanceof ServletContextListener) { - throw new IllegalArgumentException(sm.getString( - "applicationContext.addListener.iae.sclNotAllowed", -@@ -1353,8 +1379,9 @@ - public T createListener(Class c) - throws ServletException { - try { -+ @SuppressWarnings("unchecked") - T listener = -- (T) context.getInstanceManager().newInstance(c.getName()); -+ (T) context.getInstanceManager().newInstance(c); - if (listener instanceof ServletContextListener || - listener instanceof ServletContextAttributeListener || - listener instanceof ServletRequestListener || -@@ -1375,27 +1402,26 @@ - throw new ServletException(e); - } catch (InstantiationException e) { - throw new ServletException(e); -- } catch (ClassNotFoundException e) { -- throw new ServletException(e); -- } } -+ } -+ } - - - @Override - public void declareRoles(String... roleNames) { -- -+ - if (!context.getState().equals(LifecycleState.STARTING_PREP)) { - //TODO Spec breaking enhancement to ignore this restriction - throw new IllegalStateException( - sm.getString("applicationContext.addRole.ise", - getContextPath())); - } -- -+ - if (roleNames == null) { - throw new IllegalArgumentException( - sm.getString("applicationContext.roles.iae", - getContextPath())); - } -- -+ - for (String role : roleNames) { - if (role == null || "".equals(role)) { - throw new IllegalArgumentException( -@@ -1424,7 +1450,7 @@ - new RuntimePermission("getClassLoader")); - } - } -- -+ - return result; - } - -@@ -1445,7 +1471,7 @@ - public Map getFilterRegistrations() { - Map result = - new HashMap(); -- -+ - FilterDef[] filterDefs = context.findFilterDefs(); - for (FilterDef filterDef : filterDefs) { - result.put(filterDef.getFilterName(), -@@ -1473,7 +1499,7 @@ - public Map getServletRegistrations() { - Map result = - new HashMap(); -- -+ - Container[] wrappers = context.findChildren(); - for (Container wrapper : wrappers) { - result.put(((Wrapper) wrapper).getName(), -@@ -1484,12 +1510,12 @@ - return result; - } - -- -+ - // -------------------------------------------------------- Package Methods - protected StandardContext getContext() { - return this.context; - } -- -+ - @Deprecated - protected Map getReadonlyAttributes() { - return this.readOnlyAttributes; -@@ -1513,10 +1539,10 @@ - String key = keys.next(); - removeAttribute(key); - } -- -+ - } -- -- -+ -+ - /** - * Return the facade associated with this ApplicationContext. - */ -@@ -1541,7 +1567,7 @@ - protected void setNewServletContextListenerAllowed(boolean allowed) { - this.newServletContextListenerAllowed = allowed; - } -- -+ - /** - * List resource paths (recursively), and store all of them in the given - * Set. -@@ -1572,13 +1598,13 @@ - */ - private static String getJNDIUri(String hostName, String path) { - String result; -- -+ - if (path.startsWith("/")) { - result = "/" + hostName + path; - } else { - result = "/" + hostName + "/" + path; - } -- -+ - return result; - } - ---- java/org/apache/catalina/core/StandardContext.java.orig 2014-07-21 17:24:05.568403000 -0400 -+++ java/org/apache/catalina/core/StandardContext.java 2014-07-22 16:08:44.199113000 -0400 -@@ -126,6 +126,7 @@ - import org.apache.tomcat.InstanceManager; - import org.apache.tomcat.JarScanner; - import org.apache.tomcat.util.ExceptionUtils; -+import org.apache.tomcat.util.descriptor.XmlIdentifiers; - import org.apache.tomcat.util.modeler.Registry; - import org.apache.tomcat.util.scan.StandardJarScanner; - -@@ -136,7 +137,7 @@ - * - * @author Craig R. McClanahan - * @author Remy Maucherat -- * @version $Id: StandardContext.java 1493073 2013-06-14 13:51:13Z markt $ -+ * @version $Id: StandardContext.java 1549529 2013-12-09 10:05:56Z markt $ - */ - - public class StandardContext extends ContainerBase -@@ -524,6 +525,12 @@ - - - /** -+ * Context level override for default {@link StandardHost#isCopyXML()}. -+ */ -+ private boolean copyXML = false; -+ -+ -+ /** - * The default context override flag for this web application. - */ - private boolean override = false; -@@ -691,6 +698,13 @@ - protected int cacheMaxSize = 10240; // 10 MB - - -+ -+ /** -+ * Attribute used to turn on/off the use of external entities. -+ */ -+ private boolean xmlBlockExternal = Globals.IS_SECURITY_ENABLED; -+ -+ - /** - * Cache object max size in KB. - */ -@@ -726,7 +740,8 @@ - - - /** -- * Attribute value used to turn on/off XML validation -+ * Attribute value used to turn on/off XML validation for web.xml and -+ * web-fragment.xml files. - */ - private boolean webXmlValidation = Globals.STRICT_SERVLET_COMPLIANCE; - -@@ -748,12 +763,6 @@ - - - /** -- * Attribute value used to turn on/off TLD XML namespace validation -- */ -- private boolean tldNamespaceAware = Globals.STRICT_SERVLET_COMPLIANCE; -- -- -- /** - * Should we save the configuration. - */ - private boolean saveConfig = true; -@@ -1055,11 +1064,13 @@ - } - - -+ @Override - public InstanceManager getInstanceManager() { - return instanceManager; - } - - -+ @Override - public void setInstanceManager(InstanceManager instanceManager) { - this.instanceManager = instanceManager; - } -@@ -2463,6 +2474,17 @@ - - } - -+ -+ public boolean getCopyXML() { -+ return copyXML; -+ } -+ -+ -+ public void setCopyXML(boolean copyXML) { -+ this.copyXML = copyXML; -+ } -+ -+ - /** - * Return the Java class name of the Wrapper implementation used - * for servlets registered in this Context. -@@ -4861,7 +4883,7 @@ - ExceptionUtils.handleThrowable(t); - getLogger().error - (sm.getString("standardContext.applicationListener", -- listeners[i]), t); -+ listeners[i].getClassName()), t); - ok = false; - } - } -@@ -5233,8 +5255,7 @@ - } - if (ok) { - if (!resourcesStart()) { -- log.error( "Error in resourceStart()"); -- ok = false; -+ throw new LifecycleException("Error in resourceStart()"); - } - } - -@@ -5822,17 +5843,10 @@ - */ - @Override - public boolean isServlet22() { -- -- if (this.publicId == null) -- return (false); -- if (this.publicId.equals -- (org.apache.catalina.startup.Constants.WebDtdPublicId_22)) -- return (true); -- else -- return (false); -- -+ return XmlIdentifiers.WEB_22_PUBLIC.equals(publicId); - } - -+ - @Override - public Set addServletSecurity( - ApplicationServletRegistration registration, -@@ -5928,7 +5942,7 @@ - if (getResources() == null) - return oldContextClassLoader; - -- if (getLoader().getClassLoader() != null) { -+ if (getLoader() != null && getLoader().getClassLoader() != null) { - Thread.currentThread().setContextClassLoader - (getLoader().getClassLoader()); - } -@@ -6580,72 +6594,67 @@ - - } - -- /** -- * Set the validation feature of the XML parser used when -- * parsing xml instances. -- * @param webXmlValidation true to enable xml instance validation -- */ -+ -+ @Override -+ public boolean getXmlNamespaceAware(){ -+ return webXmlNamespaceAware; -+ } -+ -+ -+ @Override -+ public void setXmlNamespaceAware(boolean webXmlNamespaceAware){ -+ this.webXmlNamespaceAware = webXmlNamespaceAware; -+ } -+ -+ - @Override - public void setXmlValidation(boolean webXmlValidation){ -- - this.webXmlValidation = webXmlValidation; -- - } - -- /** -- * Get the server.xml attribute's xmlValidation. -- * @return true if validation is enabled. -- * -- */ -+ - @Override - public boolean getXmlValidation(){ - return webXmlValidation; - } - - -- /** -- * Get the server.xml attribute's xmlNamespaceAware. -- * @return true if namespace awarenes is enabled. -- */ - @Override -- public boolean getXmlNamespaceAware(){ -- return webXmlNamespaceAware; -+ public boolean getTldNamespaceAware(){ -+ return true; - } - - -- /** -- * Set the namespace aware feature of the XML parser used when -- * parsing xml instances. -- * @param webXmlNamespaceAware true to enable namespace awareness -- */ - @Override -- public void setXmlNamespaceAware(boolean webXmlNamespaceAware){ -- this.webXmlNamespaceAware= webXmlNamespaceAware; -+ public void setTldNamespaceAware(boolean tldNamespaceAware){ -+ // NO-OP; - } - - -- /** -- * Set the validation feature of the XML parser used when -- * parsing tlds files. -- * @param tldValidation true to enable xml instance validation -- */ -+ @Override -+ public void setXmlBlockExternal(boolean xmlBlockExternal) { -+ this.xmlBlockExternal = xmlBlockExternal; -+ } -+ -+ -+ @Override -+ public boolean getXmlBlockExternal() { -+ return xmlBlockExternal; -+ } -+ -+ - @Override - public void setTldValidation(boolean tldValidation){ -- - this.tldValidation = tldValidation; -- - } - -- /** -- * Get the server.xml attribute's webXmlValidation. -- * @return true if validation is enabled. -- * -- */ -+ - @Override - public boolean getTldValidation(){ - return tldValidation; - } - -+ - /** - * Sets the process TLDs attribute. - * -@@ -6655,6 +6664,7 @@ - processTlds = newProcessTlds; - } - -+ - /** - * Returns the processTlds attribute value. - */ -@@ -6662,26 +6672,6 @@ - return processTlds; - } - -- /** -- * Get the server.xml <host> attribute's xmlNamespaceAware. -- * @return true if namespace awarenes is enabled. -- */ -- @Override -- public boolean getTldNamespaceAware(){ -- return tldNamespaceAware; -- } -- -- -- /** -- * Set the namespace aware feature of the XML parser used when -- * parsing xml instances. -- * @param tldNamespaceAware true to enable namespace awareness -- */ -- @Override -- public void setTldNamespaceAware(boolean tldNamespaceAware){ -- this.tldNamespaceAware= tldNamespaceAware; -- } -- - - /** - * Support for "stateManageable" JSR77 ---- java/org/apache/catalina/startup/ContextConfig.java.orig 2014-07-21 17:24:05.574403000 -0400 -+++ java/org/apache/catalina/startup/ContextConfig.java 2014-07-21 17:46:59.422037000 -0400 -@@ -95,6 +95,8 @@ - import org.apache.tomcat.util.bcel.classfile.ElementValue; - import org.apache.tomcat.util.bcel.classfile.ElementValuePair; - import org.apache.tomcat.util.bcel.classfile.JavaClass; -+import org.apache.tomcat.util.descriptor.DigesterFactory; -+import org.apache.tomcat.util.descriptor.XmlErrorHandler; - import org.apache.tomcat.util.digester.Digester; - import org.apache.tomcat.util.digester.RuleSet; - import org.apache.tomcat.util.res.StringManager; -@@ -109,7 +111,7 @@ - * - * @author Craig R. McClanahan - * @author Jean-Francois Arcand -- * @version $Id: ContextConfig.java 1488152 2013-05-31 11:07:18Z kkolinko $ -+ * @version $Id: ContextConfig.java 1549529 2013-12-09 10:05:56Z markt $ - */ - public class ContextConfig implements LifecycleListener { - -@@ -514,14 +516,16 @@ - public void createWebXmlDigester(boolean namespaceAware, - boolean validation) { - -+ boolean blockExternal = context.getXmlBlockExternal(); -+ - webRuleSet = new WebRuleSet(false); - webDigester = DigesterFactory.newDigester(validation, -- namespaceAware, webRuleSet); -+ namespaceAware, webRuleSet, blockExternal); - webDigester.getParser(); - - webFragmentRuleSet = new WebRuleSet(true); - webFragmentDigester = DigesterFactory.newDigester(validation, -- namespaceAware, webFragmentRuleSet); -+ namespaceAware, webFragmentRuleSet, blockExternal); - webFragmentDigester.getParser(); - } - -@@ -710,11 +714,11 @@ - String pathName = cn.getBaseName(); - - boolean unpackWARs = true; -- if (host instanceof StandardHost && -- context instanceof StandardContext) { -- unpackWARs = ((StandardHost) host).isUnpackWARs() && -- ((StandardContext) context).getUnpackWAR() && -- (docBase.startsWith(canonicalAppBase.getPath())); -+ if (host instanceof StandardHost) { -+ unpackWARs = ((StandardHost) host).isUnpackWARs(); -+ if (unpackWARs && context instanceof StandardContext) { -+ unpackWARs = ((StandardContext) context).getUnpackWAR(); -+ } - } - - if (docBase.toLowerCase(Locale.ENGLISH).endsWith(".war") && !file.isDirectory() && unpackWARs) { -@@ -838,14 +842,6 @@ - - createWebXmlDigester(context.getXmlNamespaceAware(), - context.getXmlValidation()); -- -- try { -- fixDocBase(); -- } catch (IOException e) { -- log.error(sm.getString( -- "contextConfig.fixDocBase", context.getName()), e); -- } -- - } - - -@@ -854,8 +850,14 @@ - */ - protected synchronized void beforeStart() { - -- antiLocking(); -+ try { -+ fixDocBase(); -+ } catch (IOException e) { -+ log.error(sm.getString( -+ "contextConfig.fixDocBase", context.getName()), e); -+ } - -+ antiLocking(); - } - - -@@ -1131,7 +1133,7 @@ - for (int j = 0; j < roles.length; j++) { - if (!"*".equals(roles[j]) && - !context.findSecurityRole(roles[j])) { -- log.info(sm.getString("contextConfig.role.auth", roles[j])); -+ log.warn(sm.getString("contextConfig.role.auth", roles[j])); - context.addSecurityRole(roles[j]); - } - } -@@ -1143,14 +1145,14 @@ - Wrapper wrapper = (Wrapper) wrappers[i]; - String runAs = wrapper.getRunAs(); - if ((runAs != null) && !context.findSecurityRole(runAs)) { -- log.info(sm.getString("contextConfig.role.runas", runAs)); -+ log.warn(sm.getString("contextConfig.role.runas", runAs)); - context.addSecurityRole(runAs); - } - String names[] = wrapper.findSecurityReferences(); - for (int j = 0; j < names.length; j++) { - String link = wrapper.findSecurityReference(names[j]); - if ((link != null) && !context.findSecurityRole(link)) { -- log.info(sm.getString("contextConfig.role.link", link)); -+ log.warn(sm.getString("contextConfig.role.link", link)); - context.addSecurityRole(link); - } - } -@@ -1258,7 +1260,7 @@ - // Step 1. Identify all the JARs packaged with the application - // If the JARs have a web-fragment.xml it will be parsed at this - // point. -- Map fragments = processJarsForWebFragments(); -+ Map fragments = processJarsForWebFragments(webXml); - - // Step 2. Order the fragments. - Set orderedFragments = null; -@@ -1546,7 +1548,7 @@ - URL url = fragment.getURL(); - Jar jar = null; - InputStream is = null; -- ServletContainerInitializer sci = null; -+ List detectedScis = null; - try { - if ("jar".equals(url.getProtocol())) { - jar = JarFactory.newInstance(url); -@@ -1559,7 +1561,7 @@ - } - } - if (is != null) { -- sci = getServletContainerInitializer(is); -+ detectedScis = getServletContainerInitializers(is); - } - } catch (IOException ioe) { - log.error(sm.getString( -@@ -1580,42 +1582,44 @@ - } - } - -- if (sci == null) { -+ if (detectedScis == null) { - continue; - } - -- initializerClassMap.put(sci, new HashSet>()); -+ for (ServletContainerInitializer sci : detectedScis) { -+ initializerClassMap.put(sci, new HashSet>()); - -- HandlesTypes ht = null; -- try { -- ht = sci.getClass().getAnnotation(HandlesTypes.class); -- } catch (Exception e) { -- if (log.isDebugEnabled()) { -- log.info(sm.getString("contextConfig.sci.debug", url), e); -- } else { -- log.info(sm.getString("contextConfig.sci.info", url)); -+ HandlesTypes ht = null; -+ try { -+ ht = sci.getClass().getAnnotation(HandlesTypes.class); -+ } catch (Exception e) { -+ if (log.isDebugEnabled()) { -+ log.info(sm.getString("contextConfig.sci.debug", url), -+ e); -+ } else { -+ log.info(sm.getString("contextConfig.sci.info", url)); -+ } - } -- } -- if (ht != null) { -- Class[] types = ht.value(); -- if (types != null) { -- for (Class type : types) { -- if (type.isAnnotation()) { -- handlesTypesAnnotations = true; -- } else { -- handlesTypesNonAnnotations = true; -- } -- Set scis = -- typeInitializerMap.get(type); -- if (scis == null) { -- scis = new HashSet(); -- typeInitializerMap.put(type, scis); -+ if (ht != null) { -+ Class[] types = ht.value(); -+ if (types != null) { -+ for (Class type : types) { -+ if (type.isAnnotation()) { -+ handlesTypesAnnotations = true; -+ } else { -+ handlesTypesNonAnnotations = true; -+ } -+ Set scis = typeInitializerMap -+ .get(type); -+ if (scis == null) { -+ scis = new HashSet(); -+ typeInitializerMap.put(type, scis); -+ } -+ scis.add(sci); - } -- scis.add(sci); - } - } - } -- - } - } - -@@ -1627,19 +1631,28 @@ - * @return The class name - * @throws IOException - */ -- protected ServletContainerInitializer getServletContainerInitializer( -+ protected List getServletContainerInitializers( - InputStream is) throws IOException { - -- String className = null; -+ List initializers = new ArrayList(); - - if (is != null) { - String line = null; - try { -- BufferedReader br = -- new BufferedReader(new InputStreamReader(is, "UTF-8")); -- line = br.readLine(); -- if (line != null && line.trim().length() > 0) { -- className = line.trim(); -+ BufferedReader br = new BufferedReader(new InputStreamReader( -+ is, "UTF-8")); -+ while ((line = br.readLine()) != null) { -+ line = line.trim(); -+ if (line.length() > 0) { -+ int i = line.indexOf('#'); -+ if (i > -1) { -+ if (i == 0) { -+ continue; -+ } -+ line = line.substring(0, i).trim(); -+ } -+ initializers.add(getServletContainerInitializer(line)); -+ } - } - } catch (UnsupportedEncodingException e) { - // Should never happen with UTF-8 -@@ -1647,11 +1660,16 @@ - } - } - -+ return initializers; -+ } -+ -+ protected ServletContainerInitializer getServletContainerInitializer( -+ String className) throws IOException { - ServletContainerInitializer sci = null; - try { -- Class clazz = Class.forName(className,true, -- context.getLoader().getClassLoader()); -- sci = (ServletContainerInitializer) clazz.newInstance(); -+ Class clazz = Class.forName(className, true, context.getLoader() -+ .getClassLoader()); -+ sci = (ServletContainerInitializer) clazz.newInstance(); - } catch (ClassNotFoundException e) { - log.error(sm.getString("contextConfig.invalidSci", className), e); - throw new IOException(e); -@@ -1923,10 +1941,21 @@ - * - * @return A map of JAR name to processed web fragment (if any) - */ -- protected Map processJarsForWebFragments() { -+ protected Map processJarsForWebFragments(WebXml application) { - - JarScanner jarScanner = context.getJarScanner(); -- FragmentJarScannerCallback callback = new FragmentJarScannerCallback(); -+ -+ boolean parseRequired = true; -+ Set absoluteOrder = application.getAbsoluteOrdering(); -+ if (absoluteOrder != null && absoluteOrder.isEmpty() && -+ !context.getXmlValidation()) { -+ // Skip parsing when there is an empty absolute ordering and -+ // validation is not enabled -+ parseRequired = false; -+ } -+ -+ FragmentJarScannerCallback callback = -+ new FragmentJarScannerCallback(parseRequired); - - jarScanner.scan(context.getServletContext(), - context.getLoader().getClassLoader(), callback, -@@ -2282,6 +2311,12 @@ - } catch (IOException e) { - log.debug(sm.getString("contextConfig.invalidSciHandlesTypes", - className), e); -+ } finally { -+ try { -+ is.close(); -+ } catch (IOException e) { -+ // ignore -+ } - } - } - } -@@ -2650,7 +2685,12 @@ - private static final String FRAGMENT_LOCATION = - "META-INF/web-fragment.xml"; - private Map fragments = new HashMap(); -+ private final boolean parseRequired; - -+ public FragmentJarScannerCallback(boolean parseRequired) { -+ this.parseRequired = parseRequired; -+ } -+ - @Override - public void scan(JarURLConnection jarConn) throws IOException { - -@@ -2662,15 +2702,18 @@ - - try { - jar = JarFactory.newInstance(url); -- is = jar.getInputStream(FRAGMENT_LOCATION); -+ if (parseRequired || context.getXmlValidation()) { -+ is = jar.getInputStream(FRAGMENT_LOCATION); -+ } - - if (is == null) { -- // If there is no web.xml, normal JAR no impact on -- // distributable -+ // If there is no web-fragment.xml to process there is no -+ // impact on distributable - fragment.setDistributable(true); - } else { - InputSource source = new InputSource( -- resourceURL.toString() + "!/" + FRAGMENT_LOCATION); -+ "jar:" + resourceURL.toString() + "!/" + -+ FRAGMENT_LOCATION); - source.setByteStream(is); - parseWebXml(source, fragment, true); - } ---- java/org/apache/catalina/startup/FailedContext.java.orig 2014-07-21 17:24:05.579400000 -0400 -+++ java/org/apache/catalina/startup/FailedContext.java 2014-07-21 17:46:59.429034000 -0400 -@@ -59,6 +59,7 @@ - import org.apache.catalina.util.CharsetMapper; - import org.apache.catalina.util.LifecycleMBeanBase; - import org.apache.juli.logging.Log; -+import org.apache.tomcat.InstanceManager; - import org.apache.tomcat.JarScanner; - import org.apache.tomcat.util.http.mapper.Mapper; - import org.apache.tomcat.util.res.StringManager; -@@ -427,10 +428,15 @@ - @Override - public void setTldValidation(boolean tldValidation) { /* NO-OP */ } - @Override -+ public boolean getXmlBlockExternal() { return true; } -+ @Override -+ public void setXmlBlockExternal(boolean xmlBlockExternal) { /* NO-OP */ } -+ -+ @Override - public boolean getTldValidation() { return false; } - - @Override -- public boolean getTldNamespaceAware() { return false; } -+ public boolean getTldNamespaceAware() { return true; } - @Override - public void setTldNamespaceAware(boolean tldNamespaceAware) { /* NO-OP */ } - -@@ -685,4 +691,10 @@ - - @Override - public Map findPreDestroyMethods() { return null; } -+ -+ @Override -+ public InstanceManager getInstanceManager() { return null; } -+ -+ @Override -+ public void setInstanceManager(InstanceManager instanceManager) { /* NO-OP */ } - } -\ No newline at end of file ---- java/org/apache/catalina/startup/TldConfig.java.orig 2014-07-21 17:24:05.583404000 -0400 -+++ java/org/apache/catalina/startup/TldConfig.java 2014-07-24 12:20:22.130289000 -0400 -@@ -40,6 +40,8 @@ - import org.apache.tomcat.JarScanner; - import org.apache.tomcat.JarScannerCallback; - import org.apache.tomcat.util.ExceptionUtils; -+import org.apache.tomcat.util.descriptor.DigesterFactory; -+import org.apache.tomcat.util.descriptor.XmlErrorHandler; - import org.apache.tomcat.util.digester.Digester; - import org.apache.tomcat.util.res.StringManager; - import org.apache.tomcat.util.scan.Jar; -@@ -83,38 +85,23 @@ - * Create (if necessary) and return a Digester configured to process the - * tld. - */ -- private static Digester createTldDigester(boolean namespaceAware, -- boolean validation) { -- -- Digester digester = null; -- if (!namespaceAware && !validation) { -- if (tldDigesters[0] == null) { -- tldDigesters[0] = DigesterFactory.newDigester(validation, -- namespaceAware, new TldRuleSet()); -- tldDigesters[0].getParser(); -- } -- digester = tldDigesters[0]; -- } else if (!namespaceAware && validation) { -- if (tldDigesters[1] == null) { -- tldDigesters[1] = DigesterFactory.newDigester(validation, -- namespaceAware, new TldRuleSet()); -- tldDigesters[1].getParser(); -- } -- digester = tldDigesters[1]; -- } else if (namespaceAware && !validation) { -- if (tldDigesters[2] == null) { -- tldDigesters[2] = DigesterFactory.newDigester(validation, -- namespaceAware, new TldRuleSet()); -- tldDigesters[2].getParser(); -- } -- digester = tldDigesters[2]; -- } else { -- if (tldDigesters[3] == null) { -- tldDigesters[3] = DigesterFactory.newDigester(validation, -- namespaceAware, new TldRuleSet()); -- tldDigesters[3].getParser(); -- } -- digester = tldDigesters[3]; -+ private static synchronized Digester createTldDigester(boolean validation, -+ boolean blockExternal) { -+ -+ Digester digester; -+ int cacheIndex = 0; -+ if (validation) { -+ cacheIndex += 1; -+ } -+ if (blockExternal) { -+ cacheIndex += 2; -+ } -+ digester = tldDigesters[cacheIndex]; -+ if (digester == null) { -+ digester = DigesterFactory.newDigester(validation, -+ true, new TldRuleSet(), blockExternal); -+ digester.getParser(); -+ tldDigesters[cacheIndex] = digester; - } - return digester; - } -@@ -155,7 +142,10 @@ - } - StringTokenizer tokenizer = new StringTokenizer(jarNames, ","); - while (tokenizer.hasMoreElements()) { -- noTldJars.add(tokenizer.nextToken()); -+ String token = tokenizer.nextToken().trim(); -+ if (token.length() > 0) { -+ noTldJars.add(token); -+ } - } - } - } -@@ -354,10 +344,15 @@ - try { - stream = context.getServletContext().getResourceAsStream( - resourcePath); -- XmlErrorHandler handler = tldScanStream(stream); -- handler.logFindings(log, resourcePath); -- taglibUris.add(descriptor.getTaglibURI()); -- webxmlTaglibUris.add(descriptor.getTaglibURI()); -+ if (stream != null) { -+ XmlErrorHandler handler = tldScanStream(stream); -+ handler.logFindings(log, resourcePath); -+ taglibUris.add(descriptor.getTaglibURI()); -+ webxmlTaglibUris.add(descriptor.getTaglibURI()); -+ } else { -+ log.warn(sm.getString("tldConfig.webxmlFailPathDoesNotExist", resourcePath, -+ descriptor.getTaglibURI())); -+ } - } catch (IOException ioe) { - log.warn(sm.getString("tldConfig.webxmlFail", resourcePath, - descriptor.getTaglibURI()), ioe); -@@ -580,8 +575,8 @@ - - private void init() { - if (tldDigester == null){ -- tldDigester = createTldDigester(context.getTldNamespaceAware(), -- context.getTldValidation()); -+ tldDigester = createTldDigester(context.getTldValidation(), -+ context.getXmlBlockExternal()); - } - } - ---- java/org/apache/jasper/Constants.java.orig 2014-07-21 17:24:05.588400000 -0400 -+++ java/org/apache/jasper/Constants.java 2014-07-21 17:46:59.443034000 -0400 -@@ -14,14 +14,12 @@ - * See the License for the specific language governing permissions and - * limitations under the License. - */ -- - package org.apache.jasper; - - import java.util.Arrays; - import java.util.Collections; - import java.util.List; - -- - /** - * Some constants and other global data that are used by the compiler and the runtime. - * -@@ -233,4 +231,23 @@ - */ - public static final String TLD_JAR_SKIP_PROP= - "org.apache.catalina.startup.TldConfig.jarsToSkip"; -+ -+ -+ /** -+ * Name of the ServletContext init-param that determines if the XML parsers -+ * used for *.tld files will be validating or not. -+ *

-+ * This must be kept in sync with org.apache.catalina.Globals -+ */ -+ public static final String XML_VALIDATION_TLD_INIT_PARAM = -+ "org.apache.jasper.XML_VALIDATE_TLD"; -+ -+ /** -+ * Name of the ServletContext init-param that determines if the XML parsers -+ * will block the resolution of external entities. -+ *

-+ * This must be kept in sync with org.apache.catalina.Globals -+ */ -+ public static final String XML_BLOCK_EXTERNAL_INIT_PARAM = -+ "org.apache.jasper.XML_BLOCK_EXTERNAL"; - } ---- java/org/apache/jasper/JspC.java.orig 2014-07-21 17:24:05.593406000 -0400 -+++ java/org/apache/jasper/JspC.java 2014-07-21 17:46:59.450034000 -0400 -@@ -126,6 +126,8 @@ - protected static final String SWITCH_ENCODING = "-javaEncoding"; - protected static final String SWITCH_SMAP = "-smap"; - protected static final String SWITCH_DUMP_SMAP = "-dumpsmap"; -+ protected static final String SWITCH_VALIDATE_TLD = "-validateTld"; -+ protected static final String SWITCH_BLOCK_EXTERNAL = "-blockExternal"; - protected static final String SHOW_SUCCESS ="-s"; - protected static final String LIST_ERRORS = "-l"; - protected static final int INC_WEBXML = 10; -@@ -156,6 +158,8 @@ - protected URLClassLoader loader = null; - protected boolean trimSpaces = false; - protected boolean genStringAsCharArray = false; -+ protected boolean validateTld; -+ protected boolean blockExternal; - protected boolean xpoweredBy; - protected boolean mappedFile = false; - protected boolean poolingEnabled = true; -@@ -363,6 +367,10 @@ - smapSuppressed = false; - } else if (tok.equals(SWITCH_DUMP_SMAP)) { - smapDumped = true; -+ } else if (tok.equals(SWITCH_VALIDATE_TLD)) { -+ setValidateTld(true); -+ } else if (tok.equals(SWITCH_BLOCK_EXTERNAL)) { -+ setBlockExternal(true); - } else { - if (tok.startsWith("-")) { - throw new JasperException("Unrecognized option: " + tok + -@@ -842,8 +850,20 @@ - } - } - -- public void setValidateXml( boolean b ) { -- org.apache.jasper.xmlparser.ParserUtils.validating=b; -+ public void setValidateTld( boolean b ) { -+ this.validateTld = b; -+ } -+ -+ public boolean isValidateTld() { -+ return validateTld; -+ } -+ -+ public void setBlockExternal( boolean b ) { -+ this.blockExternal = b; -+ } -+ -+ public boolean isBlockExternal() { -+ return blockExternal; - } - - public void setListErrors( boolean b ) { -@@ -1257,8 +1277,6 @@ - - /** - * Executes the compilation. -- * -- * @throws JasperException If an error occurs - */ - @Override - public void execute() { -@@ -1426,6 +1444,13 @@ - } catch (MalformedURLException me) { - System.out.println("**" + me); - } -+ if (isValidateTld()) { -+ context.setInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM, "true"); -+ } -+ if (isBlockExternal()) { -+ context.setInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM, "true"); -+ } -+ - rctxt = new JspRuntimeContext(context, this); - jspConfig = new JspConfig(context); - tagPluginManager = new TagPluginManager(context); ---- java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java.orig 2014-07-21 17:24:05.597404000 -0400 -+++ java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java 2014-07-21 17:46:59.457040000 -0400 -@@ -14,7 +14,6 @@ - * See the License for the specific language governing permissions and - * limitations under the License. - */ -- - package org.apache.jasper.compiler; - - import java.io.InputStream; -@@ -24,11 +23,13 @@ - import java.util.Set; - import java.util.Vector; - -+import javax.servlet.ServletContext; - import javax.servlet.jsp.tagext.FunctionInfo; - import javax.servlet.jsp.tagext.TagFileInfo; - import javax.servlet.jsp.tagext.TagInfo; - import javax.servlet.jsp.tagext.TagLibraryInfo; - -+import org.apache.jasper.Constants; - import org.apache.jasper.JasperException; - import org.apache.jasper.JspCompilationContext; - import org.apache.jasper.util.ExceptionUtils; -@@ -124,7 +125,21 @@ - pi.addDependant(path, ctxt.getLastModified(path)); - } - -- ParserUtils pu = new ParserUtils(); -+ ServletContext servletContext = ctxt.getServletContext(); -+ boolean validate = Boolean.parseBoolean( -+ servletContext.getInitParameter( -+ Constants.XML_VALIDATION_TLD_INIT_PARAM)); -+ String blockExternalString = -+ servletContext.getInitParameter( -+ Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); -+ boolean blockExternal; -+ if (blockExternalString == null) { -+ blockExternal = Constants.IS_SECURITY_ENABLED; -+ } else { -+ blockExternal = Boolean.parseBoolean(blockExternalString); -+ } -+ -+ ParserUtils pu = new ParserUtils(validate, blockExternal); - TreeNode tld = pu.parseXMLDocument(uri, in); - - if (tld.findAttribute("version") != null) { ---- java/org/apache/jasper/compiler/JspConfig.java.orig 2014-07-21 17:24:05.605401000 -0400 -+++ java/org/apache/jasper/compiler/JspConfig.java 2014-07-21 17:46:59.469055000 -0400 -@@ -22,6 +22,7 @@ - - import javax.servlet.ServletContext; - -+import org.apache.jasper.Constants; - import org.apache.jasper.JasperException; - import org.apache.jasper.xmlparser.ParserUtils; - import org.apache.jasper.xmlparser.TreeNode; -@@ -77,9 +78,20 @@ - try { - webXml = new WebXml(ctxt); - -+ boolean validate = Boolean.parseBoolean( -+ ctxt.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM)); -+ String blockExternalString = -+ ctxt.getInitParameter(Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); -+ boolean blockExternal; -+ if (blockExternalString == null) { -+ blockExternal = Constants.IS_SECURITY_ENABLED; -+ } else { -+ blockExternal = Boolean.parseBoolean(blockExternalString); -+ } -+ - TreeNode webApp = null; - if (webXml.getInputSource() != null) { -- ParserUtils pu = new ParserUtils(); -+ ParserUtils pu = new ParserUtils(validate, blockExternal); - webApp = pu.parseXMLDocument(webXml.getSystemId(), - webXml.getInputSource()); - } ---- java/org/apache/jasper/compiler/JspDocumentParser.java.orig 2014-07-21 17:24:05.610399000 -0400 -+++ java/org/apache/jasper/compiler/JspDocumentParser.java 2014-07-21 17:46:59.476041000 -0400 -@@ -5,9 +5,9 @@ - * The ASF licenses this file to You 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. -@@ -30,17 +30,20 @@ - import javax.xml.parsers.SAXParser; - import javax.xml.parsers.SAXParserFactory; - -+import org.apache.jasper.Constants; - import org.apache.jasper.JasperException; - import org.apache.jasper.JspCompilationContext; -+import org.apache.tomcat.util.descriptor.DigesterFactory; -+import org.apache.tomcat.util.descriptor.LocalResolver; - import org.xml.sax.Attributes; - import org.xml.sax.InputSource; - import org.xml.sax.Locator; - import org.xml.sax.SAXException; - import org.xml.sax.SAXParseException; - import org.xml.sax.XMLReader; --import org.xml.sax.ext.LexicalHandler; -+import org.xml.sax.ext.DefaultHandler2; -+import org.xml.sax.ext.EntityResolver2; - import org.xml.sax.helpers.AttributesImpl; --import org.xml.sax.helpers.DefaultHandler; - - /** - * Class implementing a parser for a JSP document, that is, a JSP page in XML -@@ -51,8 +54,8 @@ - */ - - class JspDocumentParser -- extends DefaultHandler -- implements LexicalHandler, TagConstants { -+ extends DefaultHandler2 -+ implements TagConstants { - - private static final String LEXICAL_HANDLER_PROPERTY = - "http://xml.org/sax/properties/lexical-handler"; -@@ -71,7 +74,7 @@ - * Outermost (in the nesting hierarchy) node whose body is declared to be - * scriptless. If a node's body is declared to be scriptless, all its - * nested nodes must be scriptless, too. -- */ -+ */ - private Node scriptlessBodyNode; - - private Locator locator; -@@ -92,6 +95,7 @@ - private boolean inDTD; - - private boolean isValidating; -+ private final EntityResolver2 entityResolver; - - private ErrorDispatcher err; - private boolean isTagFile; -@@ -120,6 +124,20 @@ - this.isTagFile = isTagFile; - this.directivesOnly = directivesOnly; - this.isTop = true; -+ -+ String blockExternalString = ctxt.getServletContext().getInitParameter( -+ Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); -+ boolean blockExternal; -+ if (blockExternalString == null) { -+ blockExternal = Constants.IS_SECURITY_ENABLED; -+ } else { -+ blockExternal = Boolean.parseBoolean(blockExternalString); -+ } -+ -+ this.entityResolver = new LocalResolver( -+ DigesterFactory.SERVLET_API_PUBLIC_IDS, -+ DigesterFactory.SERVLET_API_SYSTEM_IDS, -+ blockExternal); - } - - /* -@@ -162,6 +180,8 @@ - jspDocParser.isTop = false; - } - -+ jspDocParser.isValidating = false; -+ - // Parse the input - SAXParser saxParser = getSAXParser(false, jspDocParser); - InputStream inStream = null; -@@ -238,11 +258,34 @@ - } - } - -+ -+ @Override -+ public InputSource getExternalSubset(String name, String baseURI) -+ throws SAXException, IOException { -+ return entityResolver.getExternalSubset(name, baseURI); -+ } -+ -+ -+ -+ @Override -+ public InputSource resolveEntity(String publicId, String systemId) -+ throws SAXException, IOException { -+ return entityResolver.resolveEntity(publicId, systemId); -+ } -+ -+ -+ @Override -+ public InputSource resolveEntity(String name, String publicId, String baseURI, String systemId) -+ throws SAXException, IOException { -+ return entityResolver.resolveEntity(name, publicId, baseURI, systemId); -+ } -+ -+ - /* - * Receives notification of the start of an element. - * - * This method assigns the given tag attributes to one of 3 buckets: -- * -+ * - * - "xmlns" attributes that represent (standard or custom) tag libraries. - * - "xmlns" attributes that do not represent tag libraries. - * - all remaining attributes. -@@ -272,11 +315,8 @@ - return; - } - -- String currentPrefix = getPrefix(current.getQName()); -- - // jsp:text must not have any subelements -- if (JSP_URI.equals(uri) && TEXT_ACTION.equals(current.getLocalName()) -- && "jsp".equals(currentPrefix)) { -+ if (current instanceof Node.JspText) { - throw new SAXParseException( - Localizer.getMessage("jsp.error.text.has_subelement"), - locator); -@@ -288,7 +328,7 @@ - if (attrs != null) { - /* - * Notice that due to a bug in the underlying SAX parser, the -- * attributes must be enumerated in descending order. -+ * attributes must be enumerated in descending order. - */ - boolean isTaglib = false; - for (int i = attrs.getLength() - 1; i >= 0; i--) { -@@ -437,7 +477,7 @@ - * invoke this method with chunks of it. This is a problem when we try - * to determine if the text contains only whitespaces, or when we are - * looking for an EL expression string. Therefore it is necessary to -- * buffer and concatenate the chunks and process the concatenated text -+ * buffer and concatenate the chunks and process the concatenated text - * later (at beginTag and endTag) - * - * @param buf The characters -@@ -670,7 +710,7 @@ - if (!(child instanceof Node.NamedAttribute)) { - throw new SAXParseException(Localizer.getMessage( - "jasper.error.emptybodycontent.nonempty", -- current.qName), locator); -+ current.qName), locator); - } - } - } -@@ -785,7 +825,7 @@ - } - - /* -- * Receives notification of the start of a Namespace mapping. -+ * Receives notification of the start of a Namespace mapping. - */ - @Override - public void startPrefixMapping(String prefix, String uri) -@@ -795,7 +835,7 @@ - if (directivesOnly && !(JSP_URI.equals(uri))) { - return; - } -- -+ - try { - taglibInfo = getTaglibInfo(prefix, uri); - } catch (JasperException je) { -@@ -816,7 +856,7 @@ - } - - /* -- * Receives notification of the end of a Namespace mapping. -+ * Receives notification of the end of a Namespace mapping. - */ - @Override - public void endPrefixMapping(String prefix) throws SAXException { -@@ -1425,17 +1465,25 @@ - throws Exception { - - SAXParserFactory factory = SAXParserFactory.newInstance(); -- factory.setNamespaceAware(true); - -+ factory.setNamespaceAware(true); - // Preserve xmlns attributes - factory.setFeature( - "http://xml.org/sax/features/namespace-prefixes", - true); -+ - factory.setValidating(validating); -- //factory.setFeature( -- // "http://xml.org/sax/features/validation", -- // validating); -- -+ if (validating) { -+ // Enable DTD validation -+ factory.setFeature( -+ "http://xml.org/sax/features/validation", -+ true); -+ // Enable schema validation -+ factory.setFeature( -+ "http://apache.org/xml/features/validation/schema", -+ true); -+ } -+ - // Configure the parser - SAXParser saxParser = factory.newSAXParser(); - XMLReader xmlReader = saxParser.getXMLReader(); ---- java/org/apache/jasper/compiler/TagLibraryInfoImpl.java.orig 2014-07-21 17:24:05.614400000 -0400 -+++ java/org/apache/jasper/compiler/TagLibraryInfoImpl.java 2014-07-21 17:46:59.483050000 -0400 -@@ -31,6 +31,7 @@ - import java.util.Map; - import java.util.Vector; - -+import javax.servlet.ServletContext; - import javax.servlet.jsp.tagext.FunctionInfo; - import javax.servlet.jsp.tagext.PageData; - import javax.servlet.jsp.tagext.TagAttributeInfo; -@@ -43,6 +44,7 @@ - import javax.servlet.jsp.tagext.ValidationMessage; - import javax.servlet.jsp.tagext.VariableInfo; - -+import org.apache.jasper.Constants; - import org.apache.jasper.JasperException; - import org.apache.jasper.JspCompilationContext; - import org.apache.jasper.util.ExceptionUtils; -@@ -212,8 +214,20 @@ - Vector tagFileVector = new Vector(); - Hashtable functionTable = new Hashtable(); - -+ ServletContext servletContext = ctxt.getServletContext(); -+ boolean validate = Boolean.parseBoolean(servletContext.getInitParameter( -+ Constants.XML_VALIDATION_TLD_INIT_PARAM)); -+ String blockExternalString = servletContext.getInitParameter( -+ Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); -+ boolean blockExternal; -+ if (blockExternalString == null) { -+ blockExternal = Constants.IS_SECURITY_ENABLED; -+ } else { -+ blockExternal = Boolean.parseBoolean(blockExternalString); -+ } -+ - // Create an iterator over the child elements of our element -- ParserUtils pu = new ParserUtils(); -+ ParserUtils pu = new ParserUtils(validate, blockExternal); - TreeNode tld = pu.parseXMLDocument(uri, in); - - // Check to see if the root element contains a 'version' ---- java/org/apache/jasper/compiler/TagPluginManager.java.orig 2014-07-21 17:24:05.619399000 -0400 -+++ java/org/apache/jasper/compiler/TagPluginManager.java 2014-07-21 17:46:59.492036000 -0400 -@@ -5,9 +5,9 @@ - * The ASF licenses this file to You 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. -@@ -25,6 +25,7 @@ - - import javax.servlet.ServletContext; - -+import org.apache.jasper.Constants; - import org.apache.jasper.JasperException; - import org.apache.jasper.compiler.tagplugin.TagPlugin; - import org.apache.jasper.compiler.tagplugin.TagPluginContext; -@@ -45,7 +46,6 @@ - private boolean initialized = false; - private HashMap tagPlugins = null; - private ServletContext ctxt; -- private PageInfo pageInfo; - - public TagPluginManager(ServletContext ctxt) { - this.ctxt = ctxt; -@@ -59,19 +59,9 @@ - return; - } - -- this.pageInfo = pageInfo; -- -- page.visit(new Node.Visitor() { -- @Override -- public void visit(Node.CustomTag n) -- throws JasperException { -- invokePlugin(n); -- visitBody(n); -- } -- }); -- -+ page.visit(new NodeVisitor(this, pageInfo)); - } -- -+ - private void init(ErrorDispatcher err) throws JasperException { - if (initialized) - return; -@@ -130,8 +120,18 @@ - private void loadTagPlugins(ErrorDispatcher err, InputStream is) - throws JasperException { - -- TreeNode root = -- (new ParserUtils()).parseXMLDocument(TAG_PLUGINS_XML, is); -+ String blockExternalString = ctxt.getInitParameter( -+ Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); -+ boolean blockExternal; -+ if (blockExternalString == null) { -+ blockExternal = Constants.IS_SECURITY_ENABLED; -+ } else { -+ blockExternal = Boolean.parseBoolean(blockExternalString); -+ } -+ -+ ParserUtils pu = new ParserUtils(false, blockExternal); -+ -+ TreeNode root = pu.parseXMLDocument(TAG_PLUGINS_XML, is); - if (root == null) { - return; - } -@@ -175,12 +175,12 @@ - } - - /** -- * Invoke tag plugin for the given custom tag, if a plugin exists for -+ * Invoke tag plugin for the given custom tag, if a plugin exists for - * the custom tag's tag handler. - * - * The given custom tag node will be manipulated by the plugin. - */ -- private void invokePlugin(Node.CustomTag n) { -+ private void invokePlugin(Node.CustomTag n, PageInfo pageInfo) { - TagPlugin tagPlugin = tagPlugins.get(n.getTagHandlerClass().getName()); - if (tagPlugin == null) { - return; -@@ -191,8 +191,24 @@ - tagPlugin.doTag(tagPluginContext); - } - -- static class TagPluginContextImpl implements TagPluginContext { -- private Node.CustomTag node; -+ private static class NodeVisitor extends Node.Visitor { -+ private final TagPluginManager manager; -+ private final PageInfo pageInfo; -+ -+ public NodeVisitor(TagPluginManager manager, PageInfo pageInfo) { -+ this.manager = manager; -+ this.pageInfo = pageInfo; -+ } -+ -+ @Override -+ public void visit(Node.CustomTag n) throws JasperException { -+ manager.invokePlugin(n, pageInfo); -+ visitBody(n); -+ } -+ } -+ -+ private static class TagPluginContextImpl implements TagPluginContext { -+ private final Node.CustomTag node; - private Node.Nodes curNodes; - private PageInfo pageInfo; - private HashMap pluginAttributes; -@@ -291,7 +307,7 @@ - - @Override - public void generateBody() { -- // Since we'll generate the body anyway, this is really a nop, -+ // Since we'll generate the body anyway, this is really a nop, - // except for the fact that it lets us put the Java sources the - // plugins produce in the correct order (w.r.t the body). - curNodes = node.getAtETag(); ---- java/org/apache/jasper/compiler/TldLocationsCache.java.orig 2014-07-21 17:24:05.623404000 -0400 -+++ java/org/apache/jasper/compiler/TldLocationsCache.java 2014-07-21 17:46:59.500034000 -0400 -@@ -286,9 +286,23 @@ - return; - } - -+ boolean validate = Boolean.parseBoolean( -+ ctxt.getInitParameter( -+ Constants.XML_VALIDATION_TLD_INIT_PARAM)); -+ String blockExternalString = ctxt.getInitParameter( -+ Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); -+ boolean blockExternal; -+ if (blockExternalString == null) { -+ blockExternal = Constants.IS_SECURITY_ENABLED; -+ } else { -+ blockExternal = Boolean.parseBoolean(blockExternalString); -+ } -+ - // Parse the web application deployment descriptor -+ ParserUtils pu = new ParserUtils(validate, blockExternal); -+ - TreeNode webtld = null; -- webtld = new ParserUtils().parseXMLDocument(webXml.getSystemId(), -+ webtld = pu.parseXMLDocument(webXml.getSystemId(), - webXml.getInputSource()); - - // Allow taglib to be an element of the root or jsp-config (JSP2.0) -@@ -491,8 +505,20 @@ - // Parse the tag library descriptor at the specified resource path - String uri = null; - -- TreeNode tld = -- new ParserUtils().parseXMLDocument(resourcePath, stream); -+ boolean validate = Boolean.parseBoolean( -+ ctxt.getInitParameter( -+ Constants.XML_VALIDATION_TLD_INIT_PARAM)); -+ String blockExternalString = ctxt.getInitParameter( -+ Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); -+ boolean blockExternal; -+ if (blockExternalString == null) { -+ blockExternal = Constants.IS_SECURITY_ENABLED; -+ } else { -+ blockExternal = Boolean.parseBoolean(blockExternalString); -+ } -+ -+ ParserUtils pu = new ParserUtils(validate, blockExternal); -+ TreeNode tld = pu.parseXMLDocument(resourcePath, stream); - TreeNode uriNode = tld.findChild("uri"); - if (uriNode != null) { - String body = uriNode.getBody(); ---- java/org/apache/jasper/xmlparser/ParserUtils.java.orig 2014-07-21 17:24:05.628407000 -0400 -+++ java/org/apache/jasper/xmlparser/ParserUtils.java 2014-07-21 17:46:59.508034000 -0400 -@@ -14,7 +14,6 @@ - * See the License for the specific language governing permissions and - * limitations under the License. - */ -- - package org.apache.jasper.xmlparser; - - import java.io.IOException; -@@ -27,8 +26,9 @@ - import org.apache.jasper.Constants; - import org.apache.jasper.JasperException; - import org.apache.jasper.compiler.Localizer; --import org.apache.juli.logging.Log; --import org.apache.juli.logging.LogFactory; -+import org.apache.tomcat.util.descriptor.DigesterFactory; -+import org.apache.tomcat.util.descriptor.LocalResolver; -+import org.apache.tomcat.util.descriptor.XmlErrorHandler; - import org.w3c.dom.Comment; - import org.w3c.dom.Document; - import org.w3c.dom.NamedNodeMap; -@@ -48,24 +48,38 @@ - * use a separate class loader for the parser to be used. - * - * @author Craig R. McClanahan -- * @version $Id: ParserUtils.java 1301227 2012-03-15 21:59:06Z markt $ -+ * @version $Id: ParserUtils.java 1549529 2013-12-09 10:05:56Z markt $ - */ -- - public class ParserUtils { - - /** - * An error handler for use when parsing XML documents. - */ -- static ErrorHandler errorHandler = new MyErrorHandler(); -+ static ErrorHandler errorHandler = new XmlErrorHandler(); - - /** - * An entity resolver for use when parsing XML documents. - */ -- static EntityResolver entityResolver = new MyEntityResolver(); -- -- // Turn off for JSP 2.0 until switch over to using xschema. -- public static boolean validating = false; -- -+ static EntityResolver entityResolver; -+ -+ private final EntityResolver entityResolverInstance; -+ -+ private final boolean validating; -+ -+ public ParserUtils(boolean validating) { -+ this(validating, Constants.IS_SECURITY_ENABLED); -+ } -+ -+ public ParserUtils(boolean validating, boolean blockExternal) { -+ this.validating = validating; -+ if (entityResolver == null) { -+ this.entityResolverInstance = new LocalResolver( -+ DigesterFactory.SERVLET_API_PUBLIC_IDS, -+ DigesterFactory.SERVLET_API_SYSTEM_IDS, blockExternal); -+ } else { -+ this.entityResolverInstance = entityResolver; -+ } -+ } - - // --------------------------------------------------------- Public Methods - -@@ -91,7 +105,7 @@ - factory.setNamespaceAware(true); - factory.setValidating(validating); - DocumentBuilder builder = factory.newDocumentBuilder(); -- builder.setEntityResolver(entityResolver); -+ builder.setEntityResolver(entityResolverInstance); - builder.setErrorHandler(errorHandler); - document = builder.parse(is); - } catch (ParserConfigurationException ex) { -@@ -196,56 +210,3 @@ - return (treeNode); - } - } -- -- --// ------------------------------------------------------------ Private Classes -- --class MyEntityResolver implements EntityResolver { -- -- @Override -- public InputSource resolveEntity(String publicId, String systemId) -- throws SAXException { -- for (int i = 0; i < Constants.CACHED_DTD_PUBLIC_IDS.size(); i++) { -- String cachedDtdPublicId = Constants.CACHED_DTD_PUBLIC_IDS.get(i); -- if (cachedDtdPublicId.equals(publicId)) { -- String resourcePath = -- Constants.CACHED_DTD_RESOURCE_PATHS.get(i); -- InputStream input = this.getClass().getResourceAsStream( -- resourcePath); -- if (input == null) { -- throw new SAXException(Localizer.getMessage( -- "jsp.error.internal.filenotfound", resourcePath)); -- } -- InputSource isrc = new InputSource(input); -- return isrc; -- } -- } -- Log log = LogFactory.getLog(MyEntityResolver.class); -- if (log.isDebugEnabled()) -- log.debug("Resolve entity failed" + publicId + " " + systemId); -- log.error(Localizer.getMessage("jsp.error.parse.xml.invalidPublicId", -- publicId)); -- return null; -- } --} -- --class MyErrorHandler implements ErrorHandler { -- -- @Override -- public void warning(SAXParseException ex) throws SAXException { -- Log log = LogFactory.getLog(MyErrorHandler.class); -- if (log.isDebugEnabled()) -- log.debug("ParserUtils: warning ", ex); -- // We ignore warnings -- } -- -- @Override -- public void error(SAXParseException ex) throws SAXException { -- throw ex; -- } -- -- @Override -- public void fatalError(SAXParseException ex) throws SAXException { -- throw ex; -- } --} ---- webapps/docs/changelog.xml.orig 2014-07-22 17:42:18.576034000 -0400 -+++ webapps/docs/changelog.xml 2014-07-22 18:48:34.775453000 -0400 -@@ -58,6 +58,12 @@ -

- - -+ -+ Add an option to the Context to control the blocking of XML external -+ entities when parsing XML configuration files and enable this blocking -+ by default when a security manager is used. The block is implemented via -+ a custom resolver to enable the logging of any blocked entities. (markt) -+ - - CVE-2014-0099, Fix overflow when parsing long values from - byte array. (markt) Patch applied by Red Hat Jun 16 2014 ---- webapps/docs/config/context.xml.orig 2014-07-21 17:24:05.643402000 -0400 -+++ webapps/docs/config/context.xml 2014-07-21 17:46:59.530037000 -0400 -@@ -448,6 +448,14 @@ - useful for portlet specification implementations) set this attribute to - / in the global CATALINA_BASE/conf/context.xml - file.

-+

Note: Once one web application using -+ sessionCookiePath="/" obtains a session, all -+ subsequent sessions for any other web application in the same host also -+ configured with sessionCookiePath="/" will always -+ use the same session ID. This holds even if the session is invalidated -+ and a new one created. This makes session fixation protection more -+ difficult and requires custom, Tomcat specific code to change the -+ session ID shared by the multiple applications.

- - - -@@ -493,18 +501,6 @@ - of the flag is false.

-
- -- --

If the value of this flag is true, the TLD files -- XML validation will be namespace-aware. If you turn this flag on, -- you should probably also turn tldValidation on. If the -- org.apache.catalina.STRICT_SERVLET_COMPLIANCE -- system property is set to -- true, the default value of this attribute will be -- true, else the default value will be false. -- Setting this attribute to true will incur a performance -- penalty.

--
-- - -

If the value of this flag is true, the TLD files - will be XML validated on context startup. If the -@@ -528,11 +524,26 @@ - Context. If not specified, a standard default value will be used.

-
- -+ -+

If the value of this flag is true, the parsing of -+ web.xml, web-fragment.xml, *.tld, -+ *.jspx, *.tagx and tagPlugins.xml -+ files for this web application will not permit external entities to be -+ loaded. If a SecurityManager is configured then the default -+ value of this attribute will be true, else the default -+ value will be false.

-+
-+ - --

If the value of this flag is true, the validation of -- XML files will be namespace-aware. If you turn this flag on, -- you should probably also turn xmlValidation on. If -- the org.apache.catalina.STRICT_SERVLET_COMPLIANCE -+

If the value of this flag is true, the parsing of -+ web.xml and web-fragment.xml files for this -+ web application will be namespace-aware. Note that *.tld, -+ *.jspx and *.tagx files are always parsed -+ using a namespace-aware parser and that the tagPlugins.xml -+ file (if any) is never parsed using a namespace-aware parser. Note also -+ that if you turn this flag on, you should probably also turn -+ xmlValidation on. If the -+ org.apache.catalina.STRICT_SERVLET_COMPLIANCE - system property is set to - true, the default value of this attribute will be - true, else the default value will be false. -@@ -541,8 +552,9 @@ - - - --

If the value of this flag is true, the XML files -- will be validated on context startup. If the -+

If the value of this flag is true, the parsing of -+ web.xml and web-fragment.xml files for this -+ web application will use a validating parser. If the - org.apache.catalina.STRICT_SERVLET_COMPLIANCE - system property is set to - true, the default value of this attribute will be -@@ -706,7 +718,10 @@ - is likely to result in instability. As such, enabling this should be - viewed as an option of last resort in a development environment and is - not recommended in a production environment. If not specified, the -- default value of false will be used.

-+ default value of false will be used. If this feature is -+ enabled, web applications may take up to two seconds longer to stop as -+ executor threads are given up to two seconds to stop gracefully before -+ Thread.stop() is called on any remaining threads.

-
- - -@@ -717,6 +732,22 @@ - not specified, the default value of false will be used.

-
- -+ -+

Set to true if you want a context XML descriptor -+ embedded inside the application (located at -+ /META-INF/context.xml) to be copied to the owning -+ Host's xmlBase when the application -+ is deployed. On subsequent starts, the copied context XML descriptor -+ will be used in preference to any context XML descriptor embedded inside -+ the application even if the descriptor embedded inside the application -+ is more recent. The flag's value defaults to false. Note if -+ the deployXML attribute of the owning -+ Host is false or if the -+ copyXML attribute of the owning -+ Host is true, this attribute will -+ have no effect.

-+
-+ - -

If true, any attempt by an application to modify the - provided JNDI context with a call to bind(), unbind(), ---- webapps/docs/security-howto.xml.orig 2014-07-21 17:24:05.649404000 -0400 -+++ webapps/docs/security-howto.xml 2014-07-21 17:46:59.538035000 -0400 -@@ -72,10 +72,74 @@ -

- -
--

Tomcat ships with a number of web applications by default. -- Vulnerabilities have been discovered in these applications in the past. -- Applications that are not required should be removed so the system will not -- be at risk if another vulnerability is discovered.

-+ -+ -+

Tomcat ships with a number of web applications that are enabled by -+ default. Vulnerabilities have been discovered in these applications in the -+ past. Applications that are not required should be removed so the system -+ will not be at risk if another vulnerability is discovered.

-+
-+ -+ -+

The ROOT web application presents a very low security risk but it does -+ include the version of Tomcat that is being used. The ROOT web application -+ should normally be removed from a publicly accessible Tomcat instance, not -+ for security reasons, but so that a more appropriate default page is shown -+ to users.

-+
-+ -+ -+

The documentation web application presents a very low security risk but -+ it does identify the version of Tomcat that is being used. It should -+ normally be removed from a publicly accessible Tomcat instance.

-+
-+ -+ -+

The examples web application should always be removed from any security -+ sensitive installation. While the examples web application does not -+ contain any known vulnerabilities, it is known to contain features -+ (particularly the cookie examples that display the contents of all -+ received and allow new cookies to be set) that may be used by an attacker -+ in conjunction with a vulnerability in another application deployed on the -+ Tomcat instance to obtain additional information that would otherwise be -+ unavailable.

-+
-+ -+ -+

The Manager application allows the remote deployment of web -+ applications and is frequently targeted by attackers due to the widespread -+ use of weak passwords and publicly accessible Tomcat instances with the -+ Manager application enabled. The Manager application is not accessible by -+ default as no users are configured with the necessary access. If the -+ Manager application is enabled then guidance in the section -+ Securing Management Applications section should be -+ followed.

-+
-+ -+ -+

The Host Manager application allows the creation and management of -+ virtual hosts - including the enabling of the Manager application for a -+ virtual host. The Host Manager application is not accessible by default -+ as no users are configured with the necessary access. If the Host Manager -+ application is enabled then guidance in the section Securing -+ Management Applications section should be followed.

-+
-+ -+ -+

When deploying a web application that provides management functions for -+ the Tomcat instance, the following guidelines should be followed:

-+
    -+
      Ensure that any users permitted to access the management application -+ have strong passwords.
    -+
      Do not remove the use of the LockOutRealm -+ which prevents brute force attacks against user passwords.
    -+
      Uncomment the RemoteAddrValve -+ in /META-INF/context.xml which limits access to -+ localhost. If remote access is required, limit it to specific IP -+ addresses using this valve.
    -+
-+
-
- -
-@@ -109,6 +173,16 @@ - manager should be introduced at the start of the development cycle as it can - be time-consuming to track down and fix issues caused by enabling a security - manager for a mature application.

-+ -+

Enabling the security manager changes the defaults for the following -+ settings:

-+
    -+
  • The default value for the deployXML attribute of the -+ Host element is changed to false.
  • -+
  • The default value for the xmlBlockExternal attribute -+ of the Context element is changed to true. -+
  • -+
-
- -
-@@ -229,9 +303,11 @@ -

- -

In a hosted environment where web applications may not be trusted, set -- the deployXML attribute to false to ignore any -- context.xml packaged with the web application that may try to assign -- increased privileges to the web application.

-+ the deployXML attribute to false to ignore -+ any context.xml packaged with the web application that may try to assign -+ increased privileges to the web application. Note that if the security -+ manager is enabled that the deployXML attribute will -+ default to false.

- - - ---- java/org/apache/catalina/core/DefaultInstanceManager.java.orig 2014-07-22 16:56:51.460868000 -0400 -+++ java/org/apache/catalina/core/DefaultInstanceManager.java 2014-07-22 16:59:03.496296000 -0400 -@@ -55,7 +55,7 @@ - import org.apache.tomcat.util.res.StringManager; - - /** -- * @version $Id: DefaultInstanceManager.java 1437338 2013-01-23 11:02:35Z markt $ -+ * @version $Id: DefaultInstanceManager.java 1514663 2013-08-16 11:51:28Z markt $ - */ - public class DefaultInstanceManager implements InstanceManager { - -@@ -133,6 +133,11 @@ - } - - @Override -+ public Object newInstance(Class clazz) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException { -+ return newInstance(clazz.newInstance(), clazz); -+ } -+ -+ @Override - public Object newInstance(String className) throws IllegalAccessException, InvocationTargetException, NamingException, InstantiationException, ClassNotFoundException { - Class clazz = loadClassMaybePrivileged(className, classLoader); - return newInstance(clazz.newInstance(), clazz); ---- java/org/apache/tomcat/InstanceManager.java.orig 2014-07-22 16:57:21.347937000 -0400 -+++ java/org/apache/tomcat/InstanceManager.java 2014-07-22 17:00:47.400650000 -0400 -@@ -21,10 +21,14 @@ - import javax.naming.NamingException; - - /** -- * @version $Id: InstanceManager.java 1200164 2011-11-10 05:46:02Z kkolinko $ -+ * @version $Id: InstanceManager.java 1514663 2013-08-16 11:51:28Z markt $ - */ - public interface InstanceManager { - -+ public Object newInstance(Class clazz) -+ throws IllegalAccessException, InvocationTargetException, NamingException, -+ InstantiationException; -+ - public Object newInstance(String className) - throws IllegalAccessException, InvocationTargetException, NamingException, - InstantiationException, ClassNotFoundException; ---- java/org/apache/jasper/EmbeddedServletOptions.java.orig 2014-07-22 17:08:09.862127000 -0400 -+++ java/org/apache/jasper/EmbeddedServletOptions.java 2014-07-22 17:08:43.749244000 -0400 -@@ -30,7 +30,6 @@ - import org.apache.jasper.compiler.Localizer; - import org.apache.jasper.compiler.TagPluginManager; - import org.apache.jasper.compiler.TldLocationsCache; --import org.apache.jasper.xmlparser.ParserUtils; - import org.apache.juli.logging.Log; - import org.apache.juli.logging.LogFactory; - -@@ -456,11 +455,7 @@ - String v=config.getInitParameter( k ); - setProperty( k, v); - } -- -- // quick hack -- String validating=config.getInitParameter( "validating"); -- if( "false".equals( validating )) ParserUtils.validating=false; -- -+ - String keepgen = config.getInitParameter("keepgenerated"); - if (keepgen != null) { - if (keepgen.equalsIgnoreCase("true")) { ---- java/org/apache/tomcat/util/descriptor/DigesterFactory.java.orig 2014-07-21 17:24:05.654400000 -0400 -+++ java/org/apache/tomcat/util/descriptor/DigesterFactory.java 2014-07-21 17:46:59.547034000 -0400 -@@ -0,0 +1,135 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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.util.descriptor; -+ -+import java.net.URL; -+import java.util.Collections; -+import java.util.HashMap; -+import java.util.Map; -+ -+import javax.servlet.ServletContext; -+ -+import org.apache.tomcat.util.digester.Digester; -+import org.apache.tomcat.util.digester.RuleSet; -+import org.xml.sax.ext.EntityResolver2; -+ -+/** -+ * Wrapper class around the Digester that hide Digester's initialization -+ * details. -+ */ -+public class DigesterFactory { -+ -+ /** -+ * Mapping of well-known public IDs used by the Servlet API to the matching -+ * local resource. -+ */ -+ public static final Map SERVLET_API_PUBLIC_IDS; -+ -+ /** -+ * Mapping of well-known system IDs used by the Servlet API to the matching -+ * local resource. -+ */ -+ public static final Map SERVLET_API_SYSTEM_IDS; -+ -+ static { -+ Map publicIds = new HashMap(); -+ Map systemIds = new HashMap(); -+ -+ // W3C -+ publicIds.put(XmlIdentifiers.XSD_10_PUBLIC, idFor("XMLSchema.dtd")); -+ publicIds.put(XmlIdentifiers.DATATYPES_PUBLIC, idFor("datatypes.dtd")); -+ systemIds.put(XmlIdentifiers.XML_2001_XSD, idFor("xml.xsd")); -+ -+ // from J2EE 1.2 -+ publicIds.put(XmlIdentifiers.WEB_22_PUBLIC, idFor("web-app_2_2.dtd")); -+ publicIds.put(XmlIdentifiers.TLD_11_PUBLIC, idFor("web-jsptaglibrary_1_1.dtd")); -+ -+ // from J2EE 1.3 -+ publicIds.put(XmlIdentifiers.WEB_23_PUBLIC, idFor("web-app_2_3.dtd")); -+ publicIds.put(XmlIdentifiers.TLD_12_PUBLIC, idFor("web-jsptaglibrary_1_2.dtd")); -+ -+ // from J2EE 1.4 -+ systemIds.put("http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd", -+ idFor("j2ee_web_services_1_1.xsd")); -+ systemIds.put("http://www.ibm.com/webservices/xsd/j2ee_web_services_client_1_1.xsd", -+ idFor("j2ee_web_services_client_1_1.xsd")); -+ systemIds.put(XmlIdentifiers.WEB_24_XSD, idFor("web-app_2_4.xsd")); -+ systemIds.put(XmlIdentifiers.TLD_20_XSD, idFor("web-jsptaglibrary_2_0.xsd")); -+ addSelf(systemIds, "j2ee_1_4.xsd"); -+ addSelf(systemIds, "jsp_2_0.xsd"); -+ -+ // from JavaEE 5 -+ systemIds.put(XmlIdentifiers.WEB_25_XSD, idFor("web-app_2_5.xsd")); -+ systemIds.put(XmlIdentifiers.TLD_21_XSD, idFor("web-jsptaglibrary_2_1.xsd")); -+ addSelf(systemIds, "javaee_5.xsd"); -+ addSelf(systemIds, "jsp_2_1.xsd"); -+ addSelf(systemIds, "javaee_web_services_1_2.xsd"); -+ addSelf(systemIds, "javaee_web_services_client_1_2.xsd"); -+ -+ // from JavaEE 6 -+ systemIds.put(XmlIdentifiers.WEB_30_XSD, idFor("web-app_3_0.xsd")); -+ systemIds.put(XmlIdentifiers.WEB_FRAGMENT_30_XSD, idFor("web-fragment_3_0.xsd")); -+ addSelf(systemIds, "web-common_3_0.xsd"); -+ addSelf(systemIds, "javaee_6.xsd"); -+ addSelf(systemIds, "jsp_2_2.xsd"); -+ addSelf(systemIds, "javaee_web_services_1_3.xsd"); -+ addSelf(systemIds, "javaee_web_services_client_1_3.xsd"); -+ -+ SERVLET_API_PUBLIC_IDS = Collections.unmodifiableMap(publicIds); -+ SERVLET_API_SYSTEM_IDS = Collections.unmodifiableMap(systemIds); -+ } -+ -+ private static void addSelf(Map ids, String id) { -+ String systemId = idFor(id); -+ ids.put(systemId, systemId); -+ ids.put(id, systemId); -+ } -+ -+ private static String idFor(String url) { -+ URL id = ServletContext.class.getResource("resources/" + url); -+ if (id == null) { -+ id = ServletContext.class.getResource("jsp/resources/" + url); -+ } -+ return id.toExternalForm(); -+ } -+ -+ -+ /** -+ * Create a Digester parser. -+ * @param xmlValidation turn on/off xml validation -+ * @param xmlNamespaceAware turn on/off namespace validation -+ * @param rule an instance of RuleSet used for parsing the xml. -+ * @param blockExternal turn on/off the blocking of external resources -+ */ -+ public static Digester newDigester(boolean xmlValidation, -+ boolean xmlNamespaceAware, -+ RuleSet rule, -+ boolean blockExternal) { -+ Digester digester = new Digester(); -+ digester.setNamespaceAware(xmlNamespaceAware); -+ digester.setValidating(xmlValidation); -+ digester.setUseContextClassLoader(true); -+ EntityResolver2 resolver = new LocalResolver(SERVLET_API_PUBLIC_IDS, -+ SERVLET_API_SYSTEM_IDS, blockExternal); -+ digester.setEntityResolver(resolver); -+ if (rule != null) { -+ digester.addRuleSet(rule); -+ } -+ -+ return digester; -+ } -+} ---- java/org/apache/tomcat/util/descriptor/LocalResolver.java.orig 2014-07-21 17:24:05.658412000 -0400 -+++ java/org/apache/tomcat/util/descriptor/LocalResolver.java 2014-07-21 17:46:59.555034000 -0400 -@@ -0,0 +1,146 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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.util.descriptor; -+ -+import java.io.FileNotFoundException; -+import java.io.IOException; -+import java.net.MalformedURLException; -+import java.net.URI; -+import java.net.URISyntaxException; -+import java.net.URL; -+import java.util.Map; -+ -+import org.apache.tomcat.util.res.StringManager; -+import org.xml.sax.InputSource; -+import org.xml.sax.SAXException; -+import org.xml.sax.ext.EntityResolver2; -+ -+/** -+ * A resolver for locally cached XML resources. -+ */ -+public class LocalResolver implements EntityResolver2 { -+ -+ private static final StringManager sm = -+ StringManager.getManager(Constants.PACKAGE_NAME); -+ -+ private final Map publicIds; -+ private final Map systemIds; -+ private final boolean blockExternal; -+ -+ /** -+ * Constructor providing mappings of public and system identifiers to local -+ * resources. Each map contains a mapping from a well-known identifier to a -+ * URL for a local resource path. -+ * -+ * @param publicIds mapping of well-known public identifiers to local -+ * resources -+ * @param systemIds mapping of well-known system identifiers to local -+ * resources -+ * @param blockExternal are external resources blocked that are not -+ * well-known -+ */ -+ public LocalResolver(Map publicIds, -+ Map systemIds, boolean blockExternal) { -+ this.publicIds = publicIds; -+ this.systemIds = systemIds; -+ this.blockExternal = blockExternal; -+ } -+ -+ -+ @Override -+ public InputSource resolveEntity(String publicId, String systemId) -+ throws SAXException, IOException { -+ return resolveEntity(null, publicId, null, systemId); -+ } -+ -+ -+ @Override -+ public InputSource resolveEntity(String name, String publicId, -+ String base, String systemId) throws SAXException, IOException { -+ -+ // First try resolving using the publicId -+ String resolved = publicIds.get(publicId); -+ if (resolved != null) { -+ InputSource is = new InputSource(resolved); -+ is.setPublicId(publicId); -+ return is; -+ } -+ -+ // If there is no systemId, can't try anything else -+ if (systemId == null) { -+ throw new FileNotFoundException(sm.getString("localResolver.unresolvedEntity", -+ name, publicId, systemId, base)); -+ } -+ -+ // Try resolving with the supplied systemId -+ resolved = systemIds.get(systemId); -+ if (resolved != null) { -+ InputSource is = new InputSource(resolved); -+ is.setPublicId(publicId); -+ return is; -+ } -+ -+ // Resolve the supplied systemId against the base -+ URI systemUri; -+ try { -+ if (base == null) { -+ systemUri = new URI(systemId); -+ } else { -+ // Can't use URI.resolve() because "jar:..." URLs are not valid -+ // hierarchical URIs so resolve() does not work. new URL() -+ // delegates to the jar: stream handler and it manages to figure -+ // it out. -+ URI baseUri = new URI(base); -+ systemUri = new URL(baseUri.toURL(), systemId).toURI(); -+ } -+ systemUri = systemUri.normalize(); -+ } catch (URISyntaxException e) { -+ // May be caused by a | being used instead of a : in an absolute -+ // file URI on Windows. -+ if (blockExternal) { -+ // Absolute paths aren't allowed so block it -+ throw new MalformedURLException(e.getMessage()); -+ } else { -+ // See if the URLHandler can resolve it -+ return new InputSource(systemId); -+ } -+ } -+ if (systemUri.isAbsolute()) { -+ // Try the resolved systemId -+ resolved = systemIds.get(systemUri.toString()); -+ if (resolved != null) { -+ InputSource is = new InputSource(resolved); -+ is.setPublicId(publicId); -+ return is; -+ } -+ if (!blockExternal) { -+ InputSource is = new InputSource(systemUri.toString()); -+ is.setPublicId(publicId); -+ return is; -+ } -+ } -+ throw new FileNotFoundException(sm.getString("localResolver.unresolvedEntity", -+ name, publicId, systemId, base)); -+ } -+ -+ -+ @Override -+ public InputSource getExternalSubset(String name, String baseURI) -+ throws SAXException, IOException { -+ return null; -+ } -+} ---- java/org/apache/tomcat/util/descriptor/LocalStrings.properties.orig 2014-07-21 17:24:05.663406000 -0400 -+++ java/org/apache/tomcat/util/descriptor/LocalStrings.properties 2014-07-21 17:46:59.562036000 -0400 -@@ -0,0 +1,19 @@ -+# Licensed to the Apache Software Foundation (ASF) under one or more -+# contributor license agreements. See the NOTICE file distributed with -+# this work for additional information regarding copyright ownership. -+# The ASF licenses this file to You 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. -+ -+localResolver.unresolvedEntity=Could not resolve XML resource [{0}] with public ID [{1}], system ID [{2}] and base URI [{3}] to a known, local entity. -+ -+xmlErrorHandler.error=Non-fatal error [{0}] reported processing [{1}]. -+xmlErrorHandler.warning=Warning [{0}] reported processing [{1}]. ---- java/org/apache/tomcat/util/descriptor/Constants.java.orig 2014-07-21 17:24:05.668398000 -0400 -+++ java/org/apache/tomcat/util/descriptor/Constants.java 2014-07-21 17:46:59.569034000 -0400 -@@ -0,0 +1,24 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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.util.descriptor; -+ -+public class Constants { -+ -+ public static final String PACKAGE_NAME = -+ Constants.class.getPackage().getName(); -+ -+} ---- java/org/apache/tomcat/util/descriptor/LocalStrings_es.properties.orig 2014-07-21 17:24:05.672404000 -0400 -+++ java/org/apache/tomcat/util/descriptor/LocalStrings_es.properties 2014-07-21 17:46:59.574035000 -0400 -@@ -0,0 +1,17 @@ -+# Licensed to the Apache Software Foundation (ASF) under one or more -+# contributor license agreements. See the NOTICE file distributed with -+# this work for additional information regarding copyright ownership. -+# The ASF licenses this file to You 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. -+ -+xmlErrorHandler.error = Error no fatal [{0}] reportado por el proceso [{1}]. -+xmlErrorHandler.warning = Aviso [{0}] reportado por el proceso [{1}]. ---- java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java.orig 2014-07-21 17:24:05.677400000 -0400 -+++ java/org/apache/tomcat/util/descriptor/XmlIdentifiers.java 2014-07-21 17:46:59.580036000 -0400 -@@ -0,0 +1,77 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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.util.descriptor; -+ -+/** -+ * Defines constants for well-known Public and System identifiers documented by -+ * the Servlet and JSP specifications. -+ */ -+public final class XmlIdentifiers { -+ -+ // from W3C -+ public static final String XML_2001_XSD = "http://www.w3.org/2001/xml.xsd"; -+ public static final String DATATYPES_PUBLIC = "datatypes"; -+ public static final String XSD_10_PUBLIC = -+ "-//W3C//DTD XMLSCHEMA 200102//EN"; -+ -+ // from J2EE 1.2 -+ public static final String WEB_22_PUBLIC = -+ "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"; -+ public static final String WEB_22_SYSTEM = -+ "http://java.sun.com/dtd/web-app_2_2.dtd"; -+ public static final String TLD_11_PUBLIC = -+ "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"; -+ public static final String TLD_11_SYSTEM = -+ "http://java.sun.com/dtd/web-jsptaglibrary_1_1.dtd"; -+ -+ // from J2EE 1.3 -+ public static final String WEB_23_PUBLIC = -+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"; -+ public static final String WEB_23_SYSTEM = -+ "http://java.sun.com/dtd/web-app_2_3.dtd"; -+ public static final String TLD_12_PUBLIC = -+ "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"; -+ public static final String TLD_12_SYSTEM = -+ "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"; -+ -+ // from J2EE 1.4 -+ public static final String WEB_24_XSD = -+ "http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"; -+ public static final String TLD_20_XSD = -+ "http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"; -+ public static final String WEBSERVICES_11_XSD = -+ "http://www.ibm.com/webservices/xsd/j2ee_web_services_1_1.xsd"; -+ -+ // from JavaEE 5 -+ public static final String WEB_25_XSD = -+ "http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"; -+ public static final String TLD_21_XSD = -+ "http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"; -+ public static final String WEBSERVICES_12_XSD = -+ "http://java.sun.com/xml/ns/javaee/javaee_web_services_1_2.xsd"; -+ -+ // from JavaEE 6 -+ public static final String WEB_30_XSD = -+ "http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"; -+ public static final String WEB_FRAGMENT_30_XSD = -+ "http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd"; -+ public static final String WEBSERVICES_13_XSD = -+ "http://java.sun.com/xml/ns/javaee/javaee_web_services_1_3.xsd"; -+ -+ private XmlIdentifiers() { -+ } -+} -\ No newline at end of file ---- java/org/apache/tomcat/util/descriptor/XmlErrorHandler.java.orig 2014-07-21 17:24:05.683398000 -0400 -+++ java/org/apache/tomcat/util/descriptor/XmlErrorHandler.java 2014-07-21 17:46:59.586038000 -0400 -@@ -0,0 +1,75 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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.util.descriptor; -+ -+import java.util.HashSet; -+import java.util.Set; -+ -+import org.apache.juli.logging.Log; -+import org.apache.tomcat.util.res.StringManager; -+import org.xml.sax.ErrorHandler; -+import org.xml.sax.SAXException; -+import org.xml.sax.SAXParseException; -+ -+public class XmlErrorHandler implements ErrorHandler { -+ -+ private static final StringManager sm = -+ StringManager.getManager(Constants.PACKAGE_NAME); -+ -+ private final Set errors = new HashSet(); -+ -+ private final Set warnings = new HashSet(); -+ -+ @Override -+ public void error(SAXParseException exception) throws SAXException { -+ // Collect non-fatal errors -+ errors.add(exception); -+ } -+ -+ @Override -+ public void fatalError(SAXParseException exception) throws SAXException { -+ // Re-throw fatal errors -+ throw exception; -+ } -+ -+ @Override -+ public void warning(SAXParseException exception) throws SAXException { -+ // Collect warnings -+ warnings.add(exception); -+ } -+ -+ public Set getErrors() { -+ // Internal use only - don't worry about immutability -+ return errors; -+ } -+ -+ public Set getWarnings() { -+ // Internal use only - don't worry about immutability -+ return warnings; -+ } -+ -+ public void logFindings(Log log, String source) { -+ for (SAXParseException e : getWarnings()) { -+ log.warn(sm.getString( -+ "xmlErrorHandler.warning", e.getMessage(), source)); -+ } -+ for (SAXParseException e : getErrors()) { -+ log.warn(sm.getString( -+ "xmlErrorHandler.error", e.getMessage(), source)); -+ } -+ } -+} diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0050.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0050.patch deleted file mode 100644 index 522cbd5..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2014-0050.patch +++ /dev/null @@ -1,110 +0,0 @@ ---- java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java.orig 2014-03-17 18:30:01.467636000 -0400 -+++ java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java 2014-03-17 18:37:43.992207000 -0400 -@@ -805,7 +805,7 @@ - || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) { - throw new InvalidContentTypeException(String.format( - "the request doesn't contain a %s or %s stream, content type header is %s", -- MULTIPART_FORM_DATA, MULTIPART_FORM_DATA, contentType)); -+ MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType)); - } - - InputStream input = ctx.getInputStream(); -@@ -816,8 +816,7 @@ - if (requestSize != -1 && requestSize > sizeMax) { - throw new SizeLimitExceededException(String.format( - "the request was rejected because its size (%s) exceeds the configured maximum (%s)", -- Long.valueOf(requestSize), -- Long.valueOf(sizeMax)), -+ Long.valueOf(requestSize), Long.valueOf(sizeMax)), - requestSize, sizeMax); - } - input = new LimitedInputStream(input, sizeMax) { -@@ -844,7 +843,14 @@ - } - - notifier = new MultipartStream.ProgressNotifier(listener, requestSize); -- multi = new MultipartStream(input, boundary, notifier); -+ try { -+ multi = new MultipartStream(input, boundary, notifier); -+ } catch (IllegalArgumentException iae) { -+ throw new InvalidContentTypeException(String.format( -+ "The boundary specified in the %s header is too long", -+ CONTENT_TYPE), iae); -+ } -+ - multi.setHeaderEncoding(charEncoding); - - skipPreamble = true; -@@ -1022,7 +1028,7 @@ - * detail message. - */ - public InvalidContentTypeException() { -- // Nothing to do. -+ super(); - } - - /** -@@ -1035,6 +1041,10 @@ - super(message); - } - -+ public InvalidContentTypeException(String msg, Throwable cause) { -+ super(msg, cause); -+ } -+ - } - - /** ---- java/org/apache/tomcat/util/http/fileupload/MultipartStream.java.orig 2014-03-17 18:30:01.512626000 -0400 -+++ java/org/apache/tomcat/util/http/fileupload/MultipartStream.java 2014-04-16 13:23:35.983099000 -0400 -@@ -278,10 +278,9 @@ - * @param pNotifier The notifier, which is used for calling the - * progress listener, if any. - * -- * @see #MultipartStream(InputStream, byte[], -- * MultipartStream.ProgressNotifier) -+ * @throws IllegalArgumentException If the buffer size is too small - */ -- MultipartStream(InputStream input, -+ public MultipartStream(InputStream input, - byte[] boundary, - int bufSize, - ProgressNotifier pNotifier) { -@@ -292,8 +291,12 @@ - - // We prepend CR/LF to the boundary to chop trailing CR/LF from - // body-data tokens. -- this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; - this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; -+ if (bufSize < this.boundaryLength + 1) { -+ throw new IllegalArgumentException( -+ "The buffer size specified for the MultipartStream is too small"); -+ } -+ this.boundary = new byte[this.boundaryLength]; - this.keepRegion = this.boundary.length; - System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, - BOUNDARY_PREFIX.length); -@@ -313,8 +316,7 @@ - * @param pNotifier An object for calling the progress listener, if any. - * - * -- * @see #MultipartStream(InputStream, byte[], int, -- * MultipartStream.ProgressNotifier) -+ * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier) - */ - MultipartStream(InputStream input, - byte[] boundary, ---- webapps/docs/changelog.xml.orig 2014-03-17 18:30:01.569656000 -0400 -+++ webapps/docs/changelog.xml 2014-03-17 18:44:11.967500000 -0400 -@@ -59,6 +59,11 @@ - - - -+ Fix CVE-2014-0050, a denial of service with a malicious, malformed -+ Content-Type header and multipart request processing. Fixed by merging -+ latest code (r1565163) from Commons FileUpload. (markt) -+ -+ - Enforce the restriction described in section 4.4 of the Servlet 3.0 - specification that requires the new pluggability methods only to be - available to ServletContextListeners defined in one of the diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0075.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0075.patch deleted file mode 100644 index 0b682d5..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2014-0075.patch +++ /dev/null @@ -1,284 +0,0 @@ ---- java/org/apache/coyote/http11/filters/ChunkedInputFilter.java.orig 2014-06-16 18:41:33.642851000 -0400 -+++ java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2014-06-16 19:36:36.796994000 -0400 -@@ -29,6 +29,7 @@ - import org.apache.tomcat.util.buf.HexUtils; - import org.apache.tomcat.util.buf.MessageBytes; - import org.apache.tomcat.util.http.MimeHeaders; -+import org.apache.tomcat.util.res.StringManager; - - /** - * Chunked input filter. Parses chunked data according to -@@ -39,6 +40,9 @@ - */ - public class ChunkedInputFilter implements InputFilter { - -+ private static final StringManager sm = StringManager.getManager( -+ ChunkedInputFilter.class.getPackage().getName()); -+ - private static final org.apache.juli.logging.Log log - = org.apache.juli.logging.LogFactory.getLog(ChunkedInputFilter.class); - -@@ -138,6 +142,11 @@ - */ - private long extensionSize; - -+ /** -+ * Flat that indicates an error has occured -+ */ -+ private boolean error; -+ - // ----------------------------------------------------------- Constructors - public ChunkedInputFilter(int maxTrailerSize, int maxExtensionSize) { - this.trailingHeaders.setLimit(maxTrailerSize); -@@ -161,6 +170,8 @@ - public int doRead(ByteChunk chunk, Request req) - throws IOException { - -+ checkError(); -+ - if (endChunk) - return -1; - -@@ -171,7 +182,8 @@ - - if (remaining <= 0) { - if (!parseChunkHeader()) { -- throw new IOException("Invalid chunk header"); -+ throwIOException(sm.getString( -+ "chunkedInputFilter.invalidHeader")); - } - if (endChunk) { - parseEndChunk(); -@@ -183,9 +195,9 @@ - - if (pos >= lastValid) { - if (readBytes() < 0) { -- throw new IOException( -- "Unexpected end of stream whilst reading request body"); -+ throwIOException(sm.getString("chunkedInputFilter.eos")); - } -+ - } - - if (remaining > (lastValid - pos)) { -@@ -232,6 +244,8 @@ - public long end() - throws IOException { - -+ checkError(); -+ - // Consume extra bytes : parse the stream until the end chunk is found - while (doRead(readChunk, null) >= 0) { - // NOOP: Just consume the input -@@ -274,6 +288,7 @@ - trailingHeaders.recycle(); - trailingHeaders.setLimit(maxTrailerSize); - extensionSize = 0; -+ error = false; - } - - -@@ -286,6 +301,22 @@ - return ENCODING; - } - -+ private void throwIOException(String msg) throws IOException { -+ error = true; -+ throw new IOException(msg); -+ } -+ -+ private void throwEOFException(String msg) throws IOException { -+ error = true; -+ throw new IOException(msg); -+ } -+ -+ private void checkError() throws IOException { -+ if (error) { -+ throw new IOException( -+ sm.getString("chunkedInputFilter.error")); -+ } -+ } - - // ------------------------------------------------------ Protected Methods - -@@ -322,7 +353,7 @@ - - int result = 0; - boolean eol = false; -- boolean readDigit = false; -+ int readDigit = 0; - boolean extension = false; - - while (!eol) { -@@ -346,10 +377,9 @@ - } else if (!extension) { - //don't read data after the trailer - int charValue = HexUtils.getDec(buf[pos]); -- if (charValue != -1) { -- readDigit = true; -- result *= 16; -- result += charValue; -+ if (charValue != -1 && readDigit < 8) { -+ readDigit++; -+ result = (result << 4) | charValue; - } else { - //we shouldn't allow invalid, non hex characters - //in the chunked header -@@ -362,7 +392,8 @@ - // validated. Currently it is simply ignored. - extensionSize++; - if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) { -- throw new IOException("maxExtensionSize exceeded"); -+ throwIOException(sm.getString( -+ "chunkedInputFilter.maxExtension")); - } - } - // Parsing the CRLF increments pos -@@ -371,7 +402,7 @@ - } - } - -- if (!readDigit) -+ if (readDigit == 0 || result < 0) - return false; - - if (result == 0) -@@ -411,20 +442,27 @@ - while (!eol) { - - if (pos >= lastValid) { -- if (readBytes() <= 0) -- throw new IOException("Invalid CRLF"); -+ if (readBytes() <= 0) { -+ throwIOException(sm.getString( -+ "chunkedInputFilter.invaldCrlfNoData")); -+ } - } - - if (buf[pos] == Constants.CR) { -- if (crfound) throw new IOException("Invalid CRLF, two CR characters encountered."); -+ if (crfound) { -+ throwIOException(sm.getString( -+ "chunkedInputFilter.invaldCrlfCRCR")); -+ } - crfound = true; - } else if (buf[pos] == Constants.LF) { - if (!tolerant && !crfound) { -- throw new IOException("Invalid CRLF, no CR character encountered."); -+ throwIOException(sm.getString( -+ "chunkedInputFilter.invalidCrlfNoCR")); - } - eol = true; - } else { -- throw new IOException("Invalid CRLF"); -+ throwIOException( -+ sm.getString("chunkedInputFilter.invalidCrlf")); - } - - pos++; -@@ -453,8 +491,10 @@ - - // Read new bytes if needed - if (pos >= lastValid) { -- if (readBytes() <0) -- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); -+ if (readBytes() <0) { -+ throwEOFException( -+ sm.getString("chunkedInputFilter.eosTrailer")); -+ } - } - - chr = buf[pos]; -@@ -478,8 +518,10 @@ - - // Read new bytes if needed - if (pos >= lastValid) { -- if (readBytes() <0) -- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); -+ if (readBytes() <0) { -+ throwEOFException(sm.getString( -+ "chunkedInputFilter.eosTrailer")); -+ } - } - - chr = buf[pos]; -@@ -530,7 +572,8 @@ - // limit placed on trailing header size - int newlimit = trailingHeaders.getLimit() -1; - if (trailingHeaders.getEnd() > newlimit) { -- throw new IOException("Exceeded maxTrailerSize"); -+ throw new IOException( -+ sm.getString("chunkedInputFilter.maxTrailer")); - } - trailingHeaders.setLimit(newlimit); - } else { -@@ -542,8 +585,11 @@ - - // Read new bytes if needed - if (pos >= lastValid) { -- if (readBytes() <0) -- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); -+ if (readBytes() <0) { -+ throwEOFException( -+ sm.getString("chunkedInputFilter.eosTrailer")); -+ } -+ - } - - chr = buf[pos]; -@@ -567,8 +613,10 @@ - - // Read new bytes if needed - if (pos >= lastValid) { -- if (readBytes() <0) -- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request"); -+ if (readBytes() <0) { -+ throwEOFException(sm.getString( -+ "chunkedInputFilter.eosTrailer")); -+ } - } - - chr = buf[pos]; ---- java/org/apache/coyote/http11/filters/LocalStrings.properties.orig 2014-06-16 18:41:33.647850000 -0400 -+++ java/org/apache/coyote/http11/filters/LocalStrings.properties 2014-06-16 19:22:22.740111000 -0400 -@@ -0,0 +1,25 @@ -+# Licensed to the Apache Software Foundation (ASF) under one or more -+# contributor license agreements. See the NOTICE file distributed with -+# this work for additional information regarding copyright ownership. -+# The ASF licenses this file to You 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. -+ -+chunkedInputFilter.error=No data available due to previous error -+chunkedInputFilter.eos=Unexpected end of stream while reading request body -+chunkedInputFilter.eosTrailer=Unexpected end of stream while reading trailer headers -+chunkedInputFilter.invalidCrlf=Invalid end of line sequence (character other than CR or LF found) -+chunkedInputFilter.invalidCrlfCRCR=Invalid end of line sequence (CRCR) -+chunkedInputFilter.invalidCrlfNoCR=Invalid end of line sequence (No CR before LF) -+chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read) -+chunkedInputFilter.invalidHeader=Invalid chunk header -+chunkedInputFilter.maxExtension=maxExtensionSize exceeded -+chunkedInputFilter.maxTrailer=maxTrailerSize exceeded ---- webapps/docs/changelog.xml.orig 2014-06-16 18:41:33.658857000 -0400 -+++ webapps/docs/changelog.xml 2014-06-16 19:37:59.354278000 -0400 -@@ -336,6 +336,12 @@ - - - -+ Resolves: CVE-2014-0075. Improve processing of chunk size from -+ chunked headers. Avoid overflow and use a bit of shift instead -+ of multiplication as it is marginally faster. (mark/kkolinko) -+ Patch applied by Red Hat Jun 16 2014 -+ -+ - 54947: Fix the HTTP NIO connector that incorrectly rejected a - request if the CRLF terminating the request line was split across - multiple packets. Patch by Konstantin Preißer. (markt) diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0096.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0096.patch deleted file mode 100644 index 4137056..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2014-0096.patch +++ /dev/null @@ -1,380 +0,0 @@ ---- conf/web.xml.orig 2014-06-16 14:44:40.800412000 -0400 -+++ conf/web.xml 2014-06-16 15:16:19.075817000 -0400 -@@ -88,10 +88,10 @@ - - - -- -- -- -- -+ -+ -+ -+ - - - default ---- java/org/apache/catalina/servlets/DefaultServlet.java.orig 2014-06-16 14:44:40.820409000 -0400 -+++ java/org/apache/catalina/servlets/DefaultServlet.java 2014-06-16 17:31:56.392767000 -0400 -@@ -36,6 +36,7 @@ - import java.io.StringWriter; - import java.util.ArrayList; - import java.util.Iterator; -+import java.util.Locale; - import java.util.StringTokenizer; - - import javax.naming.InitialContext; -@@ -53,10 +54,14 @@ - import javax.servlet.http.HttpServlet; - import javax.servlet.http.HttpServletRequest; - import javax.servlet.http.HttpServletResponse; -+import javax.xml.parsers.DocumentBuilder; -+import javax.xml.parsers.DocumentBuilderFactory; -+import javax.xml.parsers.ParserConfigurationException; - import javax.xml.transform.Source; - import javax.xml.transform.Transformer; - import javax.xml.transform.TransformerException; - import javax.xml.transform.TransformerFactory; -+import javax.xml.transform.dom.DOMSource; - import javax.xml.transform.stream.StreamResult; - import javax.xml.transform.stream.StreamSource; - -@@ -72,7 +77,10 @@ - import org.apache.naming.resources.ResourceAttributes; - import org.apache.tomcat.util.res.StringManager; - -- -+import org.w3c.dom.Document; -+import org.xml.sax.InputSource; -+import org.xml.sax.SAXException; -+import org.xml.sax.ext.EntityResolver2; - /** - *

The default resource-serving servlet for most web applications, - * used to serve static resources such as HTML pages and images. -@@ -122,6 +130,10 @@ - - private static final long serialVersionUID = 1L; - -+ private static final DocumentBuilderFactory factory; -+ -+ private static final SecureEntityResolver secureEntityResolver = -+ new SecureEntityResolver(); - // ----------------------------------------------------- Instance Variables - - -@@ -227,6 +239,9 @@ - urlEncoder.addSafeCharacter('.'); - urlEncoder.addSafeCharacter('*'); - urlEncoder.addSafeCharacter('/'); -+ factory = DocumentBuilderFactory.newInstance(); -+ factory.setNamespaceAware(true); -+ factory.setValidating(false); - } - - -@@ -1243,13 +1258,11 @@ - protected InputStream render(String contextPath, CacheEntry cacheEntry) - throws IOException, ServletException { - -- InputStream xsltInputStream = -- findXsltInputStream(cacheEntry.context); -- -- if (xsltInputStream==null) { -+ Source xsltSource = findXsltInputStream(cacheEntry.context); -+ if (xsltSource ==null) { - return renderHtml(contextPath, cacheEntry); - } -- return renderXml(contextPath, cacheEntry, xsltInputStream); -+ return renderXml(contextPath, cacheEntry, xsltSource); - - } - -@@ -1262,7 +1275,7 @@ - */ - protected InputStream renderXml(String contextPath, - CacheEntry cacheEntry, -- InputStream xsltInputStream) -+ Source xsltSource) - throws IOException, ServletException { - - StringBuilder sb = new StringBuilder(); -@@ -1356,8 +1369,7 @@ - try { - TransformerFactory tFactory = TransformerFactory.newInstance(); - Source xmlSource = new StreamSource(new StringReader(sb.toString())); -- Source xslSource = new StreamSource(xsltInputStream); -- Transformer transformer = tFactory.newTransformer(xslSource); -+ Transformer transformer = tFactory.newTransformer(xsltSource); - - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - OutputStreamWriter osWriter = new OutputStreamWriter(stream, "UTF8"); -@@ -1578,7 +1590,7 @@ - /** - * Return the xsl template inputstream (if possible) - */ -- protected InputStream findXsltInputStream(DirContext directory) -+ protected Source findXsltInputStream(DirContext directory) - throws IOException { - - if (localXsltFile != null) { -@@ -1586,8 +1598,13 @@ - Object obj = directory.lookup(localXsltFile); - if ((obj != null) && (obj instanceof Resource)) { - InputStream is = ((Resource) obj).streamContent(); -- if (is != null) -- return is; -+ if (is != null) { -+ if (Globals.IS_SECURITY_ENABLED) { -+ return secureXslt(is); -+ } else { -+ return new StreamSource(is); -+ } -+ } - } - } catch (NamingException e) { - if (debug > 10) -@@ -1598,8 +1615,13 @@ - if (contextXsltFile != null) { - InputStream is = - getServletContext().getResourceAsStream(contextXsltFile); -- if (is != null) -- return is; -+ if (is != null) { -+ if (Globals.IS_SECURITY_ENABLED) { -+ return secureXslt(is); -+ } else { -+ return new StreamSource(is); -+ } -+ } - - if (debug > 10) - log("contextXsltFile '" + contextXsltFile + "' not found"); -@@ -1608,25 +1630,111 @@ - /* Open and read in file in one fell swoop to reduce chance - * chance of leaving handle open. - */ -- if (globalXsltFile!=null) { -- FileInputStream fis = null; -+ if (globalXsltFile != null) { -+ File f = validateGlobalXsltFile(); -+ if (f != null ){ -+ FileInputStream fis = null; -+ try { -+ fis = new FileInputStream(f); -+ byte b[] = new byte[(int)f.length()]; /* danger! */ -+ fis.read(b); -+ return new StreamSource(new ByteArrayInputStream(b)); -+ } finally { -+ if (fis != null) { -+ try { -+ fis.close(); -+ } catch(IOException ioe) { -+ // ignore -+ } -+ } -+ } -+ } -+ } - -- try { -- File f = new File(globalXsltFile); -- if (f.exists()){ -- fis =new FileInputStream(f); -- byte b[] = new byte[(int)f.length()]; /* danger! */ -- fis.read(b); -- return new ByteArrayInputStream(b); -- } -- } finally { -- if (fis!=null) -- fis.close(); -+ return null; -+ -+ } -+ -+ private File validateGlobalXsltFile() { -+ -+ File result = null; -+ String base = System.getProperty(Globals.CATALINA_BASE_PROP); -+ -+ if (base != null) { -+ File baseConf = new File(base, "conf"); -+ result = validateGlobalXsltFile(baseConf); -+ } -+ -+ if (result == null) { -+ String home = System.getProperty(Globals.CATALINA_HOME_PROP); -+ if (home != null && !home.equals(base)) { -+ File homeConf = new File(home, "conf"); -+ result = validateGlobalXsltFile(homeConf); - } - } - -- return null; -+ return result; -+ } -+ - -+ private File validateGlobalXsltFile(File base) { -+ File candidate = new File(globalXsltFile); -+ if (!candidate.isAbsolute()) { -+ candidate = new File(base, globalXsltFile); -+ } -+ -+ if (!candidate.isFile()) { -+ return null; -+ } -+ -+ // First check that the resulting path is under the provided base -+ try { -+ if (!candidate.getCanonicalPath().startsWith(base.getCanonicalPath())) { -+ return null; -+ } -+ } catch (IOException ioe) { -+ return null; -+ } -+ -+ // Next check that an .xsl or .xslt file has been specified -+ String nameLower = candidate.getName().toLowerCase(Locale.ENGLISH); -+ if (!nameLower.endsWith(".xslt") && !nameLower.endsWith(".xsl")) { -+ return null; -+ } -+ -+ return candidate; -+ } -+ -+ private Source secureXslt(InputStream is) { -+ // Need to filter out any external entities -+ Source result = null; -+ try { -+ DocumentBuilder builder = factory.newDocumentBuilder(); -+ builder.setEntityResolver(secureEntityResolver); -+ Document document = builder.parse(is); -+ result = new DOMSource(document); -+ } catch (ParserConfigurationException e) { -+ if (debug > 0) { -+ log(e.getMessage(), e); -+ } -+ } catch (SAXException e) { -+ if (debug > 0) { -+ log(e.getMessage(), e); -+ } -+ } catch (IOException e) { -+ if (debug > 0) { -+ log(e.getMessage(), e); -+ } -+ } finally { -+ if (is != null) { -+ try { -+ is.close(); -+ } catch (IOException e) { -+ // Ignore -+ } -+ } -+ } -+ return result; - } - - -@@ -2150,4 +2258,34 @@ - return (start >= 0) && (end >= 0) && (start <= end) && (length > 0); - } - } -+ -+ /** -+ * This is secure in the sense that any attempt to use an external entity -+ * will trigger an exception. -+ */ -+ private static class SecureEntityResolver implements EntityResolver2 { -+ -+ @Override -+ public InputSource resolveEntity(String publicId, String systemId) -+ throws SAXException, IOException { -+ throw new SAXException(sm.getString("defaultServlet.blockExternalEntity", -+ publicId, systemId)); -+ } -+ -+ @Override -+ public InputSource getExternalSubset(String name, String baseURI) -+ throws SAXException, IOException { -+ throw new SAXException(sm.getString("defaultServlet.blockExternalSubset", -+ name, baseURI)); -+ } -+ -+ @Override -+ public InputSource resolveEntity(String name, String publicId, -+ String baseURI, String systemId) throws SAXException, -+ IOException { -+ throw new SAXException(sm.getString("defaultServlet.blockExternalEntity2", -+ name, publicId, baseURI, systemId)); -+ } -+ } - } -+ ---- java/org/apache/catalina/servlets/LocalStrings.properties.orig 2014-06-16 14:44:40.830411000 -0400 -+++ java/org/apache/catalina/servlets/LocalStrings.properties 2014-06-16 16:15:08.577726000 -0400 -@@ -13,6 +13,10 @@ - # See the License for the specific language governing permissions and - # limitations under the License. - -+ -+defaultServlet.blockExternalEntity=Blocked access to external entity with publicId [{0}] and systemId [{0}] -+defaultServlet.blockExternalEntity2=Blocked access to external entity with name [{0}], publicId [{1}], baseURI [{2}] and systemId [{3}] -+defaultServlet.blockExternalSubset=Blocked access to external subset with name [{0}] and baseURI [{1}] - defaultServlet.missingResource=The requested resource ({0}) is not available - defaultservlet.directorylistingfor=Directory Listing for: - defaultservlet.upto=Up to: ---- webapps/docs/default-servlet.xml.orig 2014-06-16 14:44:40.836413000 -0400 -+++ webapps/docs/default-servlet.xml 2014-06-16 16:17:41.419241000 -0400 -@@ -110,22 +110,24 @@ - globalXsltFile - - If you wish to customize your directory listing, you -- can use an XSL transformation. This value is an absolute -- file name which be used for all directory listings. -- This can be overridden per context and/or per directory. See -- contextXsltFile and localXsltFile -- below. The format of the xml is shown below. -+ can use an XSL transformation. This value is a relative file name (to -+ either $CATALINA_BASE/conf/ or $CATALINA_HOME/conf/) which will be used -+ for all directory listings. This can be overridden per context and/or -+ per directory. See contextXsltFile and -+ localXsltFile below. The format of the xml is shown -+ below. - - - - contextXsltFile - - You may also customize your directory listing by context by -- configuring contextXsltFile. This should be a context -- relative path (e.g.: /path/to/context.xslt). This -- overrides globalXsltFile. If this value is present but a -- file does not exist, then globalXsltFile will be used. If - globalXsltFile does not exist, then the default -+ configuring contextXsltFile. This must be a context -+ relative path (e.g.: /path/to/context.xslt) to a file with -+ a .xsl or .xslt extension. This overrides -+ globalXsltFile. If this value is present but a file does -+ not exist, then globalXsltFile will be used. If - directory listing will be shown. - - -@@ -133,11 +135,12 @@ - localXsltFile - - You may also customize your directory listing by directory by -- configuring localXsltFile. This should be a relative -- file name in the directory where the listing will take place. -- This overrides globalXsltFile and -- contextXsltFile. If this value is present but a file -- does not exist, then contextXsltFile will be used. If -+ configuring localXsltFile. This must be a file in the -+ directory where the listing will take place to with a -+ .xsl or .xslt extension. This overrides -+ globalXsltFile and contextXsltFile. If this -+ value is present but a file does not exist, then -+ contextXsltFile will be used. If - contextXsltFile does not exist, then - globalXsltFile will be used. If - globalXsltFile does not exist, then the default diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0099.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0099.patch deleted file mode 100644 index ac72ae3..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2014-0099.patch +++ /dev/null @@ -1,49 +0,0 @@ ---- java/org/apache/tomcat/util/buf/Ascii.java.orig 2014-06-16 13:31:00.031497000 -0400 -+++ java/org/apache/tomcat/util/buf/Ascii.java 2014-06-16 13:40:15.667390000 -0400 -@@ -40,6 +40,7 @@ - private static final boolean[] isWhite = new boolean[256]; - private static final boolean[] isDigit = new boolean[256]; - -+ private static final long OVERFLOW_LIMIT = Long.MAX_VALUE / 10; - /* - * Initialize character translation and type tables. - */ -@@ -206,20 +207,16 @@ - } - - long n = c - '0'; -- long m; - - while (--len > 0) { -- if (!isDigit(c = b[off++])) { -+ if (isDigit(c = b[off++]) && -+ (n < OVERFLOW_LIMIT || -+ ( n == OVERFLOW_LIMIT && (c - '0') < 8))) { -+ n = n * 10 + c - '0'; -+ } else { - throw new NumberFormatException(); - } -- m = n * 10 + c - '0'; - -- if (m < n) { -- // Overflow -- throw new NumberFormatException(); -- } else { -- n = m; -- } - } - - return n; ---- webapps/docs/changelog.xml.orig 2014-06-16 13:31:00.067494000 -0400 -+++ webapps/docs/changelog.xml 2014-06-16 13:42:21.284821000 -0400 -@@ -59,6 +59,10 @@ - - - -+ CVE-2014-0099, Fix overflow when parsing long values from -+ byte array. (markt) Patch applied by Red Hat Jun 16 2014 -+ -+ - Fix CVE-2014-0050, a denial of service with a malicious, malformed - Content-Type header and multipart request processing. Fixed by merging - latest code (r1565163) from Commons FileUpload. (markt) diff --git a/SOURCES/tomcat-7.0.42-CVE-2014-0119.patch b/SOURCES/tomcat-7.0.42-CVE-2014-0119.patch deleted file mode 100644 index 84e93a2..0000000 --- a/SOURCES/tomcat-7.0.42-CVE-2014-0119.patch +++ /dev/null @@ -1,678 +0,0 @@ ---- java/org/apache/catalina/security/SecurityClassLoad.java.orig 2014-07-24 18:29:38.830023000 -0400 -+++ java/org/apache/catalina/security/SecurityClassLoad.java 2014-07-24 18:31:18.655356000 -0400 -@@ -25,9 +25,7 @@ - * - * @author Glenn L. Nielsen - * @author Jean-Francois Arcand -- * @version $Id: SecurityClassLoad.java 1410548 2012-11-16 19:38:51Z markt $ - */ -- - public final class SecurityClassLoad { - - public static void securityClassLoad(ClassLoader loader) -@@ -41,6 +39,7 @@ - loadCoyotePackage(loader); - loadLoaderPackage(loader); - loadRealmPackage(loader); -+ loadServletsPackage(loader); - loadSessionPackage(loader); - loadUtilPackage(loader); - loadValvesPackage(loader); -@@ -76,12 +75,6 @@ - "AsyncContextImpl$1"); - loader.loadClass - (basePackage + -- "AsyncContextImpl$PrivilegedGetTccl"); -- loader.loadClass -- (basePackage + -- "AsyncContextImpl$PrivilegedSetTccl"); -- loader.loadClass -- (basePackage + - "AsyncListenerWrapper"); - loader.loadClass - (basePackage + -@@ -124,14 +117,24 @@ - } - - -+ private static final void loadServletsPackage(ClassLoader loader) -+ throws Exception { -+ final String basePackage = "org.apache.catalina.servlets."; -+ // Avoid a possible memory leak in the DefaultServlet when running with -+ // a security manager. The DefaultServlet needs to load an XML parser -+ // when running under a security manager. We want this to be loaded by -+ // the container rather than a web application to prevent a memory leak -+ // via web application class loader. -+ loader.loadClass(basePackage + "DefaultServlet"); -+ } -+ -+ - private static final void loadSessionPackage(ClassLoader loader) - throws Exception { - final String basePackage = "org.apache.catalina.session."; - loader.loadClass - (basePackage + "StandardSession"); - loader.loadClass -- (basePackage + "StandardSession$PrivilegedSetTccl"); -- loader.loadClass - (basePackage + "StandardSession$1"); - loader.loadClass - (basePackage + "StandardManager$PrivilegedDoUnload"); -@@ -280,10 +283,9 @@ - loader.loadClass(basePackage + - "util.net.NioBlockingSelector$BlockPoller$3"); - loader.loadClass(basePackage + "util.net.SSLSupport$CipherData"); -- loader.loadClass -- (basePackage + "util.net.JIoEndpoint$PrivilegedSetTccl"); -- loader.loadClass -- (basePackage + "util.net.AprEndpoint$PrivilegedSetTccl"); -+ // security -+ loader.loadClass(basePackage + "util.security.PrivilegedGetTccl"); -+ loader.loadClass(basePackage + "util.security.PrivilegedSetTccl"); - } - } - ---- java/org/apache/catalina/servlets/DefaultServlet.java.orig 2014-07-24 18:29:38.875020000 -0400 -+++ java/org/apache/catalina/servlets/DefaultServlet.java 2014-07-24 18:31:18.695352000 -0400 -@@ -14,8 +14,6 @@ - * See the License for the specific language governing permissions and - * limitations under the License. - */ -- -- - package org.apache.catalina.servlets; - - -@@ -34,6 +32,7 @@ - import java.io.Reader; - import java.io.StringReader; - import java.io.StringWriter; -+import java.security.AccessController; - import java.util.ArrayList; - import java.util.Iterator; - import java.util.Locale; -@@ -76,11 +75,14 @@ - import org.apache.naming.resources.Resource; - import org.apache.naming.resources.ResourceAttributes; - import org.apache.tomcat.util.res.StringManager; -- -+import org.apache.tomcat.util.security.PrivilegedGetTccl; -+import org.apache.tomcat.util.security.PrivilegedSetTccl; - import org.w3c.dom.Document; - import org.xml.sax.InputSource; - import org.xml.sax.SAXException; - import org.xml.sax.ext.EntityResolver2; -+ -+ - /** - *

The default resource-serving servlet for most web applications, - * used to serve static resources such as HTML pages and images. -@@ -122,9 +124,7 @@ - *

- * @author Craig R. McClanahan - * @author Remy Maucherat -- * @version $Id: DefaultServlet.java 1301255 2012-03-15 22:47:40Z markt $ - */ -- - public class DefaultServlet - extends HttpServlet { - -@@ -132,10 +132,10 @@ - - private static final DocumentBuilderFactory factory; - -- private static final SecureEntityResolver secureEntityResolver = -- new SecureEntityResolver(); -- // ----------------------------------------------------- Instance Variables -+ private static final SecureEntityResolver secureEntityResolver; -+ - -+ // ----------------------------------------------------- Instance Variables - - /** - * The debugging detail level for this servlet. -@@ -225,6 +225,11 @@ - */ - protected static final ArrayList FULL = new ArrayList(); - -+ /** -+ * Flag to determine if server information is presented. -+ */ -+ protected boolean showServerInfo = true; -+ - - // ----------------------------------------------------- Static Initializer - -@@ -239,9 +244,16 @@ - urlEncoder.addSafeCharacter('.'); - urlEncoder.addSafeCharacter('*'); - urlEncoder.addSafeCharacter('/'); -- factory = DocumentBuilderFactory.newInstance(); -- factory.setNamespaceAware(true); -- factory.setValidating(false); -+ -+ if (Globals.IS_SECURITY_ENABLED) { -+ factory = DocumentBuilderFactory.newInstance(); -+ factory.setNamespaceAware(true); -+ factory.setValidating(false); -+ secureEntityResolver = new SecureEntityResolver(); -+ } else { -+ factory = null; -+ secureEntityResolver = null; -+ } - } - - -@@ -270,6 +282,7 @@ - protected static final int BUFFER_SIZE = 4096; - - -+ - // --------------------------------------------------------- Public Methods - - -@@ -345,6 +358,9 @@ - throw new UnavailableException("No resources"); - } - -+ if (getServletConfig().getInitParameter("showServerInfo") != null) { -+ showServerInfo = Boolean.parseBoolean(getServletConfig().getInitParameter("showServerInfo")); -+ } - } - - -@@ -1251,7 +1267,6 @@ - } - - -- - /** - * Decide which way to render. HTML or XML. - */ -@@ -1259,13 +1274,15 @@ - throws IOException, ServletException { - - Source xsltSource = findXsltInputStream(cacheEntry.context); -- if (xsltSource ==null) { -+ -+ if (xsltSource == null) { - return renderHtml(contextPath, cacheEntry); - } - return renderXml(contextPath, cacheEntry, xsltSource); - - } - -+ - /** - * Return an InputStream to an HTML representation of the contents - * of this directory. -@@ -1362,11 +1379,27 @@ - sb.append("]]>"); - } - -- - sb.append(""); - -- -+ // Prevent possible memory leak. Ensure Transformer and -+ // TransformerFactory are not loaded from the web application. -+ ClassLoader original; -+ if (Globals.IS_SECURITY_ENABLED) { -+ PrivilegedGetTccl pa = new PrivilegedGetTccl(); -+ original = AccessController.doPrivileged(pa); -+ } else { -+ original = Thread.currentThread().getContextClassLoader(); -+ } - try { -+ if (Globals.IS_SECURITY_ENABLED) { -+ PrivilegedSetTccl pa = -+ new PrivilegedSetTccl(DefaultServlet.class.getClassLoader()); -+ AccessController.doPrivileged(pa); -+ } else { -+ Thread.currentThread().setContextClassLoader( -+ DefaultServlet.class.getClassLoader()); -+ } -+ - TransformerFactory tFactory = TransformerFactory.newInstance(); - Source xmlSource = new StreamSource(new StringReader(sb.toString())); - Transformer transformer = tFactory.newTransformer(xsltSource); -@@ -1379,6 +1412,13 @@ - return (new ByteArrayInputStream(stream.toByteArray())); - } catch (TransformerException e) { - throw new ServletException("XSL transformer error", e); -+ } finally { -+ if (Globals.IS_SECURITY_ENABLED) { -+ PrivilegedSetTccl pa = new PrivilegedSetTccl(original); -+ AccessController.doPrivileged(pa); -+ } else { -+ Thread.currentThread().setContextClassLoader(original); -+ } - } - } - -@@ -1530,7 +1570,9 @@ - sb.append("
"); - } - -- sb.append("

").append(ServerInfo.getServerInfo()).append("

"); -+ if (showServerInfo) { -+ sb.append("

").append(ServerInfo.getServerInfo()).append("

"); -+ } - sb.append("\r\n"); - sb.append("\r\n"); - -@@ -1588,7 +1630,7 @@ - - - /** -- * Return the xsl template inputstream (if possible) -+ * Return a Source for the xsl template (if possible) - */ - protected Source findXsltInputStream(DirContext directory) - throws IOException { -@@ -1630,31 +1672,32 @@ - /* Open and read in file in one fell swoop to reduce chance - * chance of leaving handle open. - */ -- if (globalXsltFile != null) { -- File f = validateGlobalXsltFile(); -- if (f != null ){ -- FileInputStream fis = null; -- try { -- fis = new FileInputStream(f); -- byte b[] = new byte[(int)f.length()]; /* danger! */ -- fis.read(b); -- return new StreamSource(new ByteArrayInputStream(b)); -- } finally { -- if (fis != null) { -- try { -- fis.close(); -- } catch(IOException ioe) { -- // ignore -- } -- } -- } -- } -+ if (globalXsltFile != null) { -+ File f = validateGlobalXsltFile(); -+ if (f != null){ -+ FileInputStream fis = null; -+ try { -+ fis = new FileInputStream(f); -+ byte b[] = new byte[(int)f.length()]; /* danger! */ -+ fis.read(b); -+ return new StreamSource(new ByteArrayInputStream(b)); -+ } finally { -+ if (fis != null) { -+ try { -+ fis.close(); -+ } catch (IOException ioe) { -+ // Ignore -+ } -+ } -+ } -+ } - } - - return null; - - } - -+ - private File validateGlobalXsltFile() { - - File result = null; -@@ -1705,6 +1748,7 @@ - return candidate; - } - -+ - private Source secureXslt(InputStream is) { - // Need to filter out any external entities - Source result = null; -@@ -1740,7 +1784,6 @@ - - // -------------------------------------------------------- protected Methods - -- - /** - * Check if sendfile can be used. - */ -@@ -2240,9 +2283,6 @@ - } - - -- // ------------------------------------------------------ Range Inner Class -- -- - protected static class Range { - - public long start; -@@ -2259,6 +2299,7 @@ - } - } - -+ - /** - * This is secure in the sense that any attempt to use an external entity - * will trigger an exception. -@@ -2288,4 +2329,3 @@ - } - } - } -- ---- webapps/docs/changelog.xml.orig 2014-07-24 18:29:38.917021000 -0400 -+++ webapps/docs/changelog.xml 2014-07-24 18:36:52.526481000 -0400 -@@ -158,6 +158,15 @@ - 55176: Correctly handle regular expressions within SSI - expressions that contain an equals character. (markt) -
-+ -+ Ensure that a TLD parser obtained from the cache has the correct value -+ of blockExternal. (markt) -+ -+ -+ Extend XML factory, parser etc. memory leak protection to cover some -+ additional locations where, theoretically, a memory leak could occur. -+ (markt) -+ -
-
- -@@ -352,6 +361,10 @@ - request if the CRLF terminating the request line was split across - multiple packets. Patch by Konstantin Preißer. (markt) -
-+ -+ Only create XML parsing objects if required and fix associated potential -+ memory leak in the default Servlet. (markt) -+ -
-
- ---- java/org/apache/jasper/xmlparser/ParserUtils.java.orig 2014-07-24 18:29:38.952016000 -0400 -+++ java/org/apache/jasper/xmlparser/ParserUtils.java 2014-07-24 18:31:18.746354000 -0400 -@@ -18,6 +18,7 @@ - - import java.io.IOException; - import java.io.InputStream; -+import java.security.AccessController; - - import javax.xml.parsers.DocumentBuilder; - import javax.xml.parsers.DocumentBuilderFactory; -@@ -29,6 +30,8 @@ - import org.apache.tomcat.util.descriptor.DigesterFactory; - import org.apache.tomcat.util.descriptor.LocalResolver; - import org.apache.tomcat.util.descriptor.XmlErrorHandler; -+import org.apache.tomcat.util.security.PrivilegedGetTccl; -+import org.apache.tomcat.util.security.PrivilegedSetTccl; - import org.w3c.dom.Comment; - import org.w3c.dom.Document; - import org.w3c.dom.NamedNodeMap; -@@ -36,7 +39,6 @@ - import org.w3c.dom.NodeList; - import org.w3c.dom.Text; - import org.xml.sax.EntityResolver; --import org.xml.sax.ErrorHandler; - import org.xml.sax.InputSource; - import org.xml.sax.SAXException; - import org.xml.sax.SAXParseException; -@@ -48,16 +50,10 @@ - * use a separate class loader for the parser to be used. - * - * @author Craig R. McClanahan -- * @version $Id: ParserUtils.java 1549529 2013-12-09 10:05:56Z markt $ - */ - public class ParserUtils { - - /** -- * An error handler for use when parsing XML documents. -- */ -- static ErrorHandler errorHandler = new XmlErrorHandler(); -- -- /** - * An entity resolver for use when parsing XML documents. - */ - static EntityResolver entityResolver; -@@ -99,15 +95,46 @@ - Document document = null; - - // Perform an XML parse of this document, via JAXP -+ ClassLoader original; -+ if (Constants.IS_SECURITY_ENABLED) { -+ PrivilegedGetTccl pa = new PrivilegedGetTccl(); -+ original = AccessController.doPrivileged(pa); -+ } else { -+ original = Thread.currentThread().getContextClassLoader(); -+ } - try { -+ if (Constants.IS_SECURITY_ENABLED) { -+ PrivilegedSetTccl pa = -+ new PrivilegedSetTccl(ParserUtils.class.getClassLoader()); -+ AccessController.doPrivileged(pa); -+ } else { -+ Thread.currentThread().setContextClassLoader( -+ ParserUtils.class.getClassLoader()); -+ } -+ - DocumentBuilderFactory factory = - DocumentBuilderFactory.newInstance(); - factory.setNamespaceAware(true); - factory.setValidating(validating); -+ if (validating) { -+ // Enable DTD validation -+ factory.setFeature( -+ "http://xml.org/sax/features/validation", -+ true); -+ // Enable schema validation -+ factory.setFeature( -+ "http://apache.org/xml/features/validation/schema", -+ true); -+ } - DocumentBuilder builder = factory.newDocumentBuilder(); - builder.setEntityResolver(entityResolverInstance); -- builder.setErrorHandler(errorHandler); -+ XmlErrorHandler handler = new XmlErrorHandler(); -+ builder.setErrorHandler(handler); - document = builder.parse(is); -+ if (!handler.getErrors().isEmpty()) { -+ // throw the first to indicate there was a error during processing -+ throw handler.getErrors().iterator().next(); -+ } - } catch (ParserConfigurationException ex) { - throw new JasperException - (Localizer.getMessage("jsp.error.parse.xml", location), ex); -@@ -124,6 +151,13 @@ - } catch (IOException io) { - throw new JasperException - (Localizer.getMessage("jsp.error.parse.xml", location), io); -+ } finally { -+ if (Constants.IS_SECURITY_ENABLED) { -+ PrivilegedSetTccl pa = new PrivilegedSetTccl(original); -+ AccessController.doPrivileged(pa); -+ } else { -+ Thread.currentThread().setContextClassLoader(original); -+ } - } - - // Convert the resulting document to a graph of TreeNodes ---- java/org/apache/jasper/compiler/JspDocumentParser.java.orig 2014-07-24 18:29:38.974016000 -0400 -+++ java/org/apache/jasper/compiler/JspDocumentParser.java 2014-07-24 18:31:18.774352000 -0400 -@@ -20,6 +20,7 @@ - import java.io.FileNotFoundException; - import java.io.IOException; - import java.io.InputStream; -+import java.security.AccessController; - import java.util.Iterator; - import java.util.List; - import java.util.jar.JarFile; -@@ -35,6 +36,8 @@ - import org.apache.jasper.JspCompilationContext; - import org.apache.tomcat.util.descriptor.DigesterFactory; - import org.apache.tomcat.util.descriptor.LocalResolver; -+import org.apache.tomcat.util.security.PrivilegedGetTccl; -+import org.apache.tomcat.util.security.PrivilegedSetTccl; - import org.xml.sax.Attributes; - import org.xml.sax.InputSource; - import org.xml.sax.Locator; -@@ -129,7 +132,7 @@ - Constants.XML_BLOCK_EXTERNAL_INIT_PARAM); - boolean blockExternal; - if (blockExternalString == null) { -- blockExternal = Constants.IS_SECURITY_ENABLED; -+ blockExternal = true; - } else { - blockExternal = Boolean.parseBoolean(blockExternalString); - } -@@ -1464,33 +1467,58 @@ - JspDocumentParser jspDocParser) - throws Exception { - -- SAXParserFactory factory = SAXParserFactory.newInstance(); -- -- factory.setNamespaceAware(true); -- // Preserve xmlns attributes -- factory.setFeature( -- "http://xml.org/sax/features/namespace-prefixes", -- true); -- -- factory.setValidating(validating); -- if (validating) { -- // Enable DTD validation -- factory.setFeature( -- "http://xml.org/sax/features/validation", -- true); -- // Enable schema validation -- factory.setFeature( -- "http://apache.org/xml/features/validation/schema", -- true); -+ ClassLoader original; -+ if (Constants.IS_SECURITY_ENABLED) { -+ PrivilegedGetTccl pa = new PrivilegedGetTccl(); -+ original = AccessController.doPrivileged(pa); -+ } else { -+ original = Thread.currentThread().getContextClassLoader(); - } -+ try { -+ if (Constants.IS_SECURITY_ENABLED) { -+ PrivilegedSetTccl pa = -+ new PrivilegedSetTccl(JspDocumentParser.class.getClassLoader()); -+ AccessController.doPrivileged(pa); -+ } else { -+ Thread.currentThread().setContextClassLoader( -+ JspDocumentParser.class.getClassLoader()); -+ } -+ -+ SAXParserFactory factory = SAXParserFactory.newInstance(); - -- // Configure the parser -- SAXParser saxParser = factory.newSAXParser(); -- XMLReader xmlReader = saxParser.getXMLReader(); -- xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser); -- xmlReader.setErrorHandler(jspDocParser); -+ factory.setNamespaceAware(true); -+ // Preserve xmlns attributes -+ factory.setFeature( -+ "http://xml.org/sax/features/namespace-prefixes", -+ true); - -- return saxParser; -+ factory.setValidating(validating); -+ if (validating) { -+ // Enable DTD validation -+ factory.setFeature( -+ "http://xml.org/sax/features/validation", -+ true); -+ // Enable schema validation -+ factory.setFeature( -+ "http://apache.org/xml/features/validation/schema", -+ true); -+ } -+ -+ // Configure the parser -+ SAXParser saxParser = factory.newSAXParser(); -+ XMLReader xmlReader = saxParser.getXMLReader(); -+ xmlReader.setProperty(LEXICAL_HANDLER_PROPERTY, jspDocParser); -+ xmlReader.setErrorHandler(jspDocParser); -+ -+ return saxParser; -+ } finally { -+ if (Constants.IS_SECURITY_ENABLED) { -+ PrivilegedSetTccl pa = new PrivilegedSetTccl(original); -+ AccessController.doPrivileged(pa); -+ } else { -+ Thread.currentThread().setContextClassLoader(original); -+ } -+ } - } - - /* ---- java/org/apache/tomcat/util/security/PrivilegedGetTccl.java.orig 2014-07-24 18:59:42.923103000 -0400 -+++ java/org/apache/tomcat/util/security/PrivilegedGetTccl.java 2014-07-24 18:56:17.729411000 -0400 -@@ -0,0 +1,28 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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.util.security; -+ -+import java.security.PrivilegedAction; -+ -+public class PrivilegedGetTccl implements PrivilegedAction { -+ @Override -+ public ClassLoader run() { -+ return Thread.currentThread().getContextClassLoader(); -+ } -+} -+ -+ ---- java/org/apache/tomcat/util/security/PrivilegedSetTccl.java.orig 2014-07-24 18:59:42.928107000 -0400 -+++ java/org/apache/tomcat/util/security/PrivilegedSetTccl.java 2014-07-24 18:56:17.736421000 -0400 -@@ -0,0 +1,34 @@ -+/* -+ * Licensed to the Apache Software Foundation (ASF) under one or more -+ * contributor license agreements. See the NOTICE file distributed with -+ * this work for additional information regarding copyright ownership. -+ * The ASF licenses this file to You 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.util.security; -+ -+import java.security.PrivilegedAction; -+ -+public class PrivilegedSetTccl implements PrivilegedAction { -+ -+ private ClassLoader cl; -+ -+ public PrivilegedSetTccl(ClassLoader cl) { -+ this.cl = cl; -+ } -+ -+ @Override -+ public Void run() { -+ Thread.currentThread().setContextClassLoader(cl); -+ return null; -+ } -+} -\ No newline at end of file diff --git a/SOURCES/tomcat-7.0.54-rebase.patch b/SOURCES/tomcat-7.0.54-rebase.patch new file mode 100644 index 0000000..e7c9590 --- /dev/null +++ b/SOURCES/tomcat-7.0.54-rebase.patch @@ -0,0 +1,28 @@ +--- java/org/apache/jasper/compiler/JDTCompiler.java.orig 2014-09-17 12:18:00.909020000 -0400 ++++ java/org/apache/jasper/compiler/JDTCompiler.java 2014-09-17 12:21:41.007769000 -0400 +@@ -333,9 +333,11 @@ + } else if(opt.equals("1.7")) { + settings.put(CompilerOptions.OPTION_Source, + CompilerOptions.VERSION_1_7); ++ /** + } else if(opt.equals("1.8")) { + settings.put(CompilerOptions.OPTION_Source, + CompilerOptions.VERSION_1_8); ++ **/ + } else { + log.warn("Unknown source VM " + opt + " ignored."); + settings.put(CompilerOptions.OPTION_Source, +@@ -377,11 +379,13 @@ + CompilerOptions.VERSION_1_7); + settings.put(CompilerOptions.OPTION_Compliance, + CompilerOptions.VERSION_1_7); ++ /** + } else if(opt.equals("1.8")) { + settings.put(CompilerOptions.OPTION_TargetPlatform, + CompilerOptions.VERSION_1_8); + settings.put(CompilerOptions.OPTION_Compliance, + CompilerOptions.VERSION_1_8); ++ **/ + } else { + log.warn("Unknown target VM " + opt + " ignored."); + settings.put(CompilerOptions.OPTION_TargetPlatform, diff --git a/SOURCES/tomcat-7.0.conf b/SOURCES/tomcat-7.0.conf index a500479..03119b7 100644 --- a/SOURCES/tomcat-7.0.conf +++ b/SOURCES/tomcat-7.0.conf @@ -1,30 +1,37 @@ # System-wide configuration file for tomcat services -# This will be sourced by tomcat and any secondary service -# Values will be overridden by service-specific configuration -# files in /etc/sysconfig +# This will be loaded by systemd as an environment file, +# so please keep the syntax. # -# Use this one to change default values for all services -# Change the service specific ones to affect only one service -# (see, for instance, /etc/sysconfig/tomcat) +# There are 2 "classes" of startup behavior in this package. +# The old one, the default service named tomcat.service. +# The new named instances are called tomcat@instance.service. # +# Use this file to change default values for all services. +# Change the service specific ones to affect only one service. +# For tomcat.service it's /etc/sysconfig/tomcat, for +# tomcat@instance it's /etc/sysconfig/tomcat@instance. + +# This variable is used to figure out if config is loaded or not. +TOMCAT_CFG_LOADED="1" + +# In new-style instances, if CATALINA_BASE isn't specified, it will +# be constructed by joining TOMCATS_BASE and NAME. +TOMCATS_BASE="/var/lib/tomcats/" # Where your java installation lives JAVA_HOME="/usr/lib/jvm/jre" # Where your tomcat installation lives -CATALINA_BASE="@@@TCHOME@@@" CATALINA_HOME="@@@TCHOME@@@" -JASPER_HOME="@@@TCHOME@@@" -CATALINA_TMPDIR="@@@TCTEMP@@@" + +# System-wide tmp +CATALINA_TMPDIR="/var/cache/tomcat/temp" # You can pass some parameters to java here if you wish to #JAVA_OPTS="-Xminf0.1 -Xmaxf0.3" # Use JAVA_OPTS to set java.library.path for libtcnative.so -#JAVA_OPTS="-Djava.library.path=@@@LIBDIR@@@" - -# What user should run tomcat -TOMCAT_USER="tomcat" +#JAVA_OPTS="-Djava.library.path=/usr/lib" # You can change your tomcat locale here #LANG="en_US" @@ -33,18 +40,9 @@ TOMCAT_USER="tomcat" SECURITY_MANAGER="false" # Time to wait in seconds, before killing process -SHUTDOWN_WAIT="30" - -# Whether to annoy the user with "attempting to shut down" messages or not -SHUTDOWN_VERBOSE="false" - -# Set the TOMCAT_PID location -CATALINA_PID="/var/run/tomcat.pid" - -# Connector port is 8080 for this tomcat instance -#CONNECTOR_PORT="8080" +# TODO(stingray): does nothing, fix. +# SHUTDOWN_WAIT="30" # If you wish to further customize your tomcat environment, # put your own definitions here # (i.e. LD_LIBRARY_PATH for some jdbc drivers) - diff --git a/SOURCES/tomcat-7.0.service b/SOURCES/tomcat-7.0.service index e2ab30c..103d464 100644 --- a/SOURCES/tomcat-7.0.service +++ b/SOURCES/tomcat-7.0.service @@ -1,19 +1,19 @@ -# Systemd unit file for tomcat +# Systemd unit file for default tomcat # # To create clones of this service: -# 1) By default SERVICE_NAME=tomcat. When cloned, the value must be defined -# before tomcat-sysd is called. -# 2) Create /etc/sysconfig/${SERVICE_NAME} from /etc/sysconfig/tomcat -# to override tomcat defaults +# DO NOTHING, use tomcat@.service instead. [Unit] Description=Apache Tomcat Web Application Container After=syslog.target network.target [Service] -Type=forking -ExecStart=/usr/sbin/tomcat-sysd start -ExecStop=/usr/sbin/tomcat-sysd stop +Type=simple +EnvironmentFile=/etc/tomcat/tomcat.conf +Environment="NAME=" +EnvironmentFile=-/etc/sysconfig/tomcat +ExecStart=/usr/libexec/tomcat/server start +ExecStop=/usr/libexec/tomcat/server stop SuccessExitStatus=143 User=tomcat Group=tomcat diff --git a/SOURCES/tomcat-functions b/SOURCES/tomcat-functions new file mode 100644 index 0000000..6f03951 --- /dev/null +++ b/SOURCES/tomcat-functions @@ -0,0 +1,42 @@ +#!/bin/bash + +if [ -r /usr/share/java-utils/java-functions ]; then + . /usr/share/java-utils/java-functions +else + echo "Can't read Java functions library, aborting" + exit 1 +fi + +_save_function() { + local ORIG_FUNC=$(declare -f $1) + local NEWNAME_FUNC="$2${ORIG_FUNC#$1}" + eval "$NEWNAME_FUNC" +} + +run_jsvc(){ + if [ -x /usr/bin/jsvc ]; then + TOMCAT_USER="tomcat" + JSVC="/usr/bin/jsvc" + + JSVC_OPTS="-nodetach -pidfile /var/run/jsvc-tomcat${NAME}.pid -user ${TOMCAT_USER} -outfile ${CATALINA_BASE}/logs/catalina.out -errfile ${CATALINA_BASE}/logs/catalina.out" + if [ "$1" = "stop" ]; then + JSVC_OPTS="${JSVC_OPTS} -stop" + fi + + exec "${JSVC}" ${JSVC_OPTS} ${FLAGS} -classpath "${CLASSPATH}" ${OPTIONS} "${MAIN_CLASS}" "${@}" + else + echo "Can't find /usr/bin/jsvc executable" + fi + +} + +_save_function run run_java + +run() { + if [ "${USE_JSVC}" = "true" ] ; then + run_jsvc $@ + else + run_java $@ + fi +} + diff --git a/SOURCES/tomcat-named.service b/SOURCES/tomcat-named.service new file mode 100644 index 0000000..9bbcb17 --- /dev/null +++ b/SOURCES/tomcat-named.service @@ -0,0 +1,26 @@ +# Systemd unit file for tomcat instances. +# +# To create clones of this service: +# 0. systemctl enable tomcat@name.service +# 1. create catalina.base directory structure in +# /var/lib/tomcats/name +# 2. profit. + +[Unit] +Description=Apache Tomcat Web Application Container +After=syslog.target network.target + +[Service] +Type=simple +EnvironmentFile=/etc/tomcat/tomcat.conf +Environment="NAME=%I" +EnvironmentFile=-/etc/sysconfig/tomcat@%I +ExecStart=/usr/libexec/tomcat/server start +ExecStop=/usr/libexec/tomcat/server stop +SuccessExitStatus=143 +User=tomcat +Group=tomcat + +[Install] +WantedBy=multi-user.target + diff --git a/SOURCES/tomcat-preamble b/SOURCES/tomcat-preamble new file mode 100644 index 0000000..0079a8c --- /dev/null +++ b/SOURCES/tomcat-preamble @@ -0,0 +1,44 @@ +#!/bin/bash + +. /usr/libexec/tomcat/functions + +# Get the tomcat config (use this for environment specific settings) + +if [ -z "${TOMCAT_CFG_LOADED}" ]; then + if [ -z "${TOMCAT_CFG}" ]; then + TOMCAT_CFG="/etc/tomcat/tomcat.conf" + fi + . $TOMCAT_CFG +fi + +if [ -z "$CATALINA_BASE" ]; then + if [ -n "$NAME" ]; then + if [ -z "$TOMCATS_BASE" ]; then + TOMCATS_BASE="/var/lib/tomcats/" + fi + CATALINA_BASE="${TOMCATS_BASE}${NAME}" + else + CATALINA_BASE="${CATALINA_HOME}" + fi +fi +VERBOSE=1 +set_javacmd +cd ${CATALINA_HOME} +# CLASSPATH munging +if [ ! -z "$CLASSPATH" ] ; then + CLASSPATH="$CLASSPATH": +fi + +if [ -n "$JSSE_HOME" ]; then + CLASSPATH="${CLASSPATH}$(build-classpath jcert jnet jsse 2>/dev/null):" +fi +CLASSPATH="${CLASSPATH}${CATALINA_HOME}/bin/bootstrap.jar" +CLASSPATH="${CLASSPATH}:${CATALINA_HOME}/bin/tomcat-juli.jar" +CLASSPATH="${CLASSPATH}:$(build-classpath commons-daemon 2>/dev/null)" + +if [ -z "$LOGGING_PROPERTIES" ] ; then + LOGGING_PROPERTIES="${CATALINA_BASE}/conf/logging.properties" + if [ ! -f "${LOGGING_PROPERTIES}" ] ; then + LOGGING_PROPERTIES="${CATALINA_HOME}/conf/logging.properties" + fi +fi diff --git a/SOURCES/tomcat-server b/SOURCES/tomcat-server new file mode 100644 index 0000000..bd55999 --- /dev/null +++ b/SOURCES/tomcat-server @@ -0,0 +1,24 @@ +#!/bin/bash + +. /usr/libexec/tomcat/preamble + +MAIN_CLASS=org.apache.catalina.startup.Bootstrap + +FLAGS="$JAVA_OPTS $CATALINA_OPTS" +OPTIONS="-Dcatalina.base=$CATALINA_BASE \ +-Dcatalina.home=$CATALINA_HOME \ +-Djava.endorsed.dirs=$JAVA_ENDORSED_DIRS \ +-Djava.io.tmpdir=$CATALINA_TMPDIR \ +-Djava.util.logging.config.file=${LOGGING_PROPERTIES} \ +-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager" + +if [ "$1" = "start" ] ; then + if [ "${SECURITY_MANAGER}" = "true" ] ; then + OPTIONS="${OPTIONS} \ + -Djava.security.manager \ + -Djava.security.policy==${CATALINA_BASE}/conf/catalina.policy" + fi + run start +elif [ "$1" = "stop" ] ; then + run stop +fi diff --git a/SPECS/tomcat.spec b/SPECS/tomcat.spec index 60dd0bc..0d242a1 100644 --- a/SPECS/tomcat.spec +++ b/SPECS/tomcat.spec @@ -31,7 +31,7 @@ %global jspspec 2.2 %global major_version 7 %global minor_version 0 -%global micro_version 42 +%global micro_version 54 %global packdname apache-tomcat-%{version}-src %global servletspec 3.0 %global elspec 2.2 @@ -54,7 +54,7 @@ Name: tomcat Epoch: 0 Version: %{major_version}.%{minor_version}.%{micro_version} -Release: 8%{?dist} +Release: 1%{?dist} Summary: Apache Servlet/JSP Engine, RI for Servlet %{servletspec}/JSP %{jspspec} API Group: System Environment/Daemons @@ -81,18 +81,24 @@ Source17: %{name}-%{major_version}.%{minor_version}-tomcat-sysd Source18: %{name}-%{major_version}.%{minor_version}-tomcat-jsvc-sysd Source19: %{name}-%{major_version}.%{minor_version}-jsvc.wrapper Source20: %{name}-%{major_version}.%{minor_version}-jsvc.service +Source21: tomcat-functions +Source22: tomcat-preamble +Source23: tomcat-server +Source24: tomcat-named.service Patch0: %{name}-%{major_version}.%{minor_version}-bootstrap-MANIFEST.MF.patch Patch1: %{name}-%{major_version}.%{minor_version}-tomcat-users-webapp.patch -Patch2: %{name}-%{version}-CVE-2013-4286.patch -Patch3: %{name}-%{version}-CVE-2013-4322.patch -Patch4: %{name}-%{version}-CVE-2014-0050.patch -Patch5: %{name}-%{version}-CVE-2014-0099.patch -Patch6: %{name}-%{version}-CVE-2014-0096.patch -Patch7: %{name}-%{version}-CVE-2014-0075.patch -Patch8: %{name}-%{version}-CVE-2013-4590.patch -Patch9: %{name}-%{version}-CVE-2014-0119.patch +Patch2: tomcat-7.0.54-rebase.patch +#Patch2: %{name}-%{version}-CVE-2013-4286.patch +#Patch3: %{name}-%{version}-CVE-2013-4322.patch +#Patch4: %{name}-%{version}-CVE-2014-0050.patch +#Patch5: %{name}-%{version}-CVE-2014-0099.patch +#Patch6: %{name}-%{version}-CVE-2014-0096.patch +#Patch7: %{name}-%{version}-CVE-2014-0075.patch + +# Postponed +#Patch5: %{name}-%{version}-CVE-2013-4590.patch BuildArch: noarch @@ -161,16 +167,6 @@ Requires: jpackage-utils %description javadoc Javadoc generated documentation for Apache Tomcat. -#%package systemv -#Group: System Environment/Daemons -#Summary: Systemv scripts for Apache Tomcat -#Requires: %{name} = %{epoch}:%{version}-%{release} -#Requires(post): chkconfig -#Requires(postun): chkconfig - -#%description systemv -#SystemV scripts to start and stop tomcat service - %package jsvc Group: System Environment/Daemons Summary: Apache jsvc wrapper for Apache Tomcat as separate service @@ -194,7 +190,6 @@ Requires(postun): chkconfig %description jsp-%{jspspec}-api Apache Tomcat JSP API implementation classes. - %package lib Group: Development/Libraries Summary: Libraries needed to run the Tomcat Web container @@ -224,14 +219,14 @@ Apache Tomcat Servlet API implementation classes. %package el-%{elspec}-api Group: Development/Libraries -Summary: Expression Language v1.0 API +Summary: Expression Language v%{elspec} API Provides: el_1_0_api = %{epoch}:%{version}-%{release} Provides: el_api = %{elspec} Requires(post): chkconfig Requires(postun): chkconfig %description el-%{elspec}-api -Expression Language 1.0. +Expression Language %{elspec}. %package webapps Group: Applications/Internet @@ -251,14 +246,11 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch0 -p0 %patch1 -p0 %patch2 -p0 -%patch3 -p0 -%patch4 -p0 -%patch5 -p0 -%patch6 -p0 -%patch7 -p0 -%patch8 -p0 -%patch9 -p0 - +#%patch3 -p0 +#%patch4 -p0 +#%patch5 -p0 +#%patch6 -p0 +#%patch7 -p0 %{__ln_s} $(build-classpath jakarta-taglibs-core) webapps/examples/WEB-INF/lib/jstl.jar %{__ln_s} $(build-classpath jakarta-taglibs-standard) webapps/examples/WEB-INF/lib/standard.jar @@ -292,6 +284,7 @@ export OPT_JAR_LIST="xalan-j2-serializer" -Dno.build.dbcp=true \ -Dversion="%{version}" \ -Dversion.build="%{micro_version}" \ + -Djava.7.home=%{java_home} \ deploy dist-prepare dist-source javadoc # remove some jars that we'll replace with symlinks later @@ -350,12 +343,14 @@ zip -u output/build/bin/tomcat-juli.jar META-INF/MANIFEST.MF %{__install} -d -m 0775 ${RPM_BUILD_ROOT}%{logdir} /bin/touch ${RPM_BUILD_ROOT}%{logdir}/catalina.out %{__install} -d -m 0775 ${RPM_BUILD_ROOT}%{_localstatedir}/run +%{__install} -d -m 0775 ${RPM_BUILD_ROOT}%{_localstatedir}/lib/tomcats /bin/touch ${RPM_BUILD_ROOT}%{_localstatedir}/run/%{name}.pid /bin/echo "%{name}-%{major_version}.%{minor_version}.%{micro_version} RPM installed" >> ${RPM_BUILD_ROOT}%{logdir}/catalina.out %{__install} -d -m 0775 ${RPM_BUILD_ROOT}%{homedir} %{__install} -d -m 0775 ${RPM_BUILD_ROOT}%{tempdir} %{__install} -d -m 0775 ${RPM_BUILD_ROOT}%{workdir} %{__install} -d -m 0755 ${RPM_BUILD_ROOT}%{_unitdir} +%{__install} -d -m 0755 ${RPM_BUILD_ROOT}%{_libexecdir}/%{name} # move things into place # First copy supporting libs to tomcat lib @@ -377,20 +372,12 @@ popd -e "s|\@\@\@TCTEMP\@\@\@|%{tempdir}|g" \ -e "s|\@\@\@LIBDIR\@\@\@|%{_libdir}|g" %{SOURCE3} \ > ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/%{name} -#%{__install} -m 0644 %{SOURCE2} \ -# ${RPM_BUILD_ROOT}%{_initrddir}/%{name} %{__install} -m 0644 %{SOURCE4} \ ${RPM_BUILD_ROOT}%{_sbindir}/%{name} %{__install} -m 0644 %{SOURCE11} \ ${RPM_BUILD_ROOT}%{_unitdir}/%{name}.service -%{__install} -m 0644 %{SOURCE17} \ - ${RPM_BUILD_ROOT}%{_sbindir}/%{name}-sysd -%{__install} -m 0644 %{SOURCE19} \ - ${RPM_BUILD_ROOT}%{_sbindir}/%{name}-jsvc %{__install} -m 0644 %{SOURCE20} \ ${RPM_BUILD_ROOT}%{_unitdir}/%{name}-jsvc.service -%{__install} -m 0644 %{SOURCE18} \ - ${RPM_BUILD_ROOT}%{_sbindir}/%{name}-jsvc-sysd # %{__ln_s} %{name} ${RPM_BUILD_ROOT}%{_sbindir}/d%{name} %{__sed} -e "s|\@\@\@TCLOG\@\@\@|%{logdir}|g" %{SOURCE5} \ > ${RPM_BUILD_ROOT}%{_sysconfdir}/logrotate.d/%{name} @@ -402,6 +389,16 @@ popd -e "s|\@\@\@TCTEMP\@\@\@|%{tempdir}|g" \ -e "s|\@\@\@LIBDIR\@\@\@|%{_libdir}|g" %{SOURCE7} \ > ${RPM_BUILD_ROOT}%{_bindir}/%{name}-tool-wrapper + +%{__install} -m 0644 %{SOURCE21} \ + ${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/functions +%{__install} -m 0755 %{SOURCE22} \ + ${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/preamble +%{__install} -m 0755 %{SOURCE23} \ + ${RPM_BUILD_ROOT}%{_libexecdir}/%{name}/server +%{__install} -m 0644 %{SOURCE24} \ + ${RPM_BUILD_ROOT}%{_unitdir}/%{name}@.service + # create jsp and servlet API symlinks pushd ${RPM_BUILD_ROOT}%{_javadir} %{__mv} %{name}/jsp-api.jar %{name}-jsp-%{jspspec}-api.jar @@ -522,16 +519,12 @@ EOF # add the tomcat user and group %{_sbindir}/groupadd -g %{tcuid} -r tomcat 2>/dev/null || : %{_sbindir}/useradd -c "Apache Tomcat" -u %{tcuid} -g tomcat \ - -s /sbin/nologin -r -d %{homedir} tomcat 2>/dev/null || : + -s /bin/nologin -r -d %{homedir} tomcat 2>/dev/null || : %post # install but don't activate %systemd_post %{name}.service -#%post systemv -# install but don't activate -#/sbin/chkconfig --add %{name} - %post jsp-%{jspspec}-api %{_sbindir}/update-alternatives --install %{_javadir}/jsp.jar jsp \ %{_javadir}/%{name}-jsp-%{jspspec}-api.jar 20200 @@ -544,12 +537,6 @@ EOF %{_sbindir}/update-alternatives --install %{_javadir}/elspec.jar elspec \ %{_javadir}/%{name}-el-%{elspec}-api.jar 20300 -#%preun systemv -#if [ "$1" = "0" ]; then -# %{_initrddir}/%{name} stop >/dev/null 2>&1 -# /sbin/chkconfig --del %{name} -#fi - %preun # clean tempdir and workdir on removal or upgrade %{__rm} -rf %{workdir}/* %{tempdir}/* @@ -589,7 +576,12 @@ fi %attr(0755,root,root) %{_bindir}/%{name}-tool-wrapper %attr(0755,root,root) %{_sbindir}/%{name} %attr(0644,root,root) %{_unitdir}/%{name}.service -%attr(0755,root,root) %{_sbindir}/%{name}-sysd +%attr(0644,root,root) %{_unitdir}/%{name}@.service +%attr(0755,root,root) %dir %{_libexecdir}/%{name} +%attr(0755,root,root) %dir %{_localstatedir}/lib/tomcats +%attr(0644,root,root) %{_libexecdir}/%{name}/functions +%attr(0755,root,root) %{_libexecdir}/%{name}/preamble +%attr(0755,root,root) %{_libexecdir}/%{name}/server %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/logrotate.d/%{name} %config(noreplace) %{_sysconfdir}/sysconfig/%{name} %attr(0755,root,tomcat) %dir %{basedir} @@ -686,33 +678,19 @@ fi %{appdir}/examples %{appdir}/sample -#%files systemv -#%defattr(755,root,root,0755) -#%{_sbindir}/d%{name} -#%{_initrddir}/%{name} - %files jsvc %defattr(755,root,root,0755) -%{_sbindir}/%{name}-jsvc -%{_sbindir}/%{name}-jsvc-sysd %attr(0644,root,root) %{_unitdir}/%{name}-jsvc.service %changelog -* Tue Jul 22 2014 David Knox - 0:7.0.42-8 -- Resolves: CVE-2013-4590 -- Resolves: CVE-2014-0119 - -* Tue Jul 8 2014 David Knox - 0:7.0.42-7 -- Related: CVE-2014-0099 incrementing release so rpmdiff doesn't complain about -- no new entries in the changelog - -* Wed Jun 11 2014 David Knox - 0:7.0.42-6 -- Resolves: CVE-2014-0099 Fix possible overflow when parsing -- long values from byte array -- Resolves: CVE-2014-0096 Information discloser process XSLT -- files not subject to same constraint running under -- java security manager -- Resolves: CVE-2014-0075 Avoid overflow in ChunkedInputFilter. +* Wed Sep 17 2014 David Knox - 0:7.0.54-1 +- Resolves: rhbz#1141372 - Remove systemv artifacts. Add new systemd +- artifacts. Rebase on 7.0.54. + +* Wed Jun 18 2014 David Knox - 0:7.0.43-6 +- Resolves: CVE-2014-0099 +- Resolves: CVE-2014-0096 +- Resolves: CVE-2014-0075 * Wed Apr 16 2014 David Knox - 0:7.0.42-5 - Related: CVE-2013-4286