[tomcat7] 01/01: Add missing CVE-2013-4590 patch
Miguel Landaeta
nomadium at moszumanska.debian.org
Sat Mar 28 18:07:56 UTC 2015
This is an automated email from the git hooks/post-receive script.
nomadium pushed a commit to branch wheezy
in repository tomcat7.
commit 9263a7a8a64130ce6fa4ab2c3fe0443cfcd5d368
Author: Miguel Landaeta <nomadium at debian.org>
Date: Sat Mar 28 13:49:22 2015 -0300
Add missing CVE-2013-4590 patch
---
debian/patches/0025-CVE-2013-4590.patch | 1119 +++++++++++++++++++++++++++++++
1 file changed, 1119 insertions(+)
diff --git a/debian/patches/0025-CVE-2013-4590.patch b/debian/patches/0025-CVE-2013-4590.patch
new file mode 100644
index 0000000..1ec7a1f
--- /dev/null
+++ b/debian/patches/0025-CVE-2013-4590.patch
@@ -0,0 +1,1119 @@
+b9e06ead01984483af73f48e7861bc7897f5e84f
+ java/org/apache/catalina/Context.java | 19 ++++
+ java/org/apache/catalina/Globals.java | 11 ++
+ java/org/apache/catalina/ant/ValidatorTask.java | 6 +-
+ .../apache/catalina/core/ApplicationContext.java | 17 ++-
+ java/org/apache/catalina/core/StandardContext.java | 19 ++++
+ .../org/apache/catalina/startup/ContextConfig.java | 6 +-
+ .../org/apache/catalina/startup/FailedContext.java | 5 +
+ java/org/apache/catalina/startup/TldConfig.java | 10 +-
+ java/org/apache/jasper/Constants.java | 9 ++
+ java/org/apache/jasper/JspC.java | 15 +++
+ .../jasper/compiler/ImplicitTagLibraryInfo.java | 17 ++-
+ java/org/apache/jasper/compiler/JspConfig.java | 10 +-
+ .../apache/jasper/compiler/JspDocumentParser.java | 38 ++++++-
+ .../apache/jasper/compiler/TagLibraryInfoImpl.java | 17 ++-
+ .../apache/jasper/compiler/TagPluginManager.java | 15 ++-
+ .../apache/jasper/compiler/TldLocationsCache.java | 28 ++++-
+ java/org/apache/jasper/xmlparser/ParserUtils.java | 21 +++-
+ .../tomcat/util/descriptor/DigesterFactory.java | 23 +++-
+ .../tomcat/util/descriptor/LocalResolver.java | 118 +++++++++++++--------
+ .../tomcat/util/descriptor/LocalStrings.properties | 2 +
+ .../servlet/resources/TestSchemaValidation.java | 20 ++--
+ test/org/apache/catalina/core/TesterContext.java | 10 ++
+ .../tomcat/util/descriptor/TestLocalResolver.java | 21 ++--
+ webapps/docs/changelog.xml | 6 ++
+ webapps/docs/config/context.xml | 10 ++
+ webapps/docs/security-howto.xml | 3 +
+ 26 files changed, 374 insertions(+), 102 deletions(-)
+
+diff --git a/java/org/apache/catalina/Context.java b/java/org/apache/catalina/Context.java
+index 03e087b..21517a0 100644
+--- a/java/org/apache/catalina/Context.java
++++ b/java/org/apache/catalina/Context.java
+@@ -675,6 +675,25 @@ public interface Context extends Container {
+
+
+ /**
++ * 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 boolean getXmlBlockExternal();
++
++
++ /**
++ * 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 void setXmlBlockExternal(boolean xmlBlockExternal);
++
++
++ /**
+ * Will the parsing of *.tld files for this Context be performed by a
+ * validating parser?
+ *
+diff --git a/java/org/apache/catalina/Globals.java b/java/org/apache/catalina/Globals.java
+index 56694e7..78210d3 100644
+--- a/java/org/apache/catalina/Globals.java
++++ b/java/org/apache/catalina/Globals.java
+@@ -316,4 +316,15 @@ public final class Globals {
+ */
+ 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.
++ * <p>
++ * 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";
+ }
+diff --git a/java/org/apache/catalina/ant/ValidatorTask.java b/java/org/apache/catalina/ant/ValidatorTask.java
+index 4c2272f..68f2299 100644
+--- a/java/org/apache/catalina/ant/ValidatorTask.java
++++ b/java/org/apache/catalina/ant/ValidatorTask.java
+@@ -21,6 +21,7 @@ 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.tomcat.util.descriptor.DigesterFactory;
+ import org.apache.tomcat.util.digester.Digester;
+@@ -87,7 +88,10 @@ public class ValidatorTask extends BaseRedirectorHelperTask {
+ 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 =
+diff --git a/java/org/apache/catalina/core/ApplicationContext.java b/java/org/apache/catalina/core/ApplicationContext.java
+index 504b5c2..96dd3ec 100644
+--- a/java/org/apache/catalina/core/ApplicationContext.java
++++ b/java/org/apache/catalina/core/ApplicationContext.java
+@@ -320,12 +320,20 @@ public class ApplicationContext
+ */
+ @Override
+ public String getInitParameter(final String name) {
+- // Special handling for XML validation as the context setting must
++ // 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);
+ }
+
+@@ -338,11 +346,14 @@ public class ApplicationContext
+ public Enumeration<String> getInitParameterNames() {
+ Set<String> names = new HashSet<String>();
+ names.addAll(parameters.keySet());
+- // Special handling for XML validation as this attribute will always be
+- // available if validation has been enabled on the context
++ // 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);
+ }
+
+diff --git a/java/org/apache/catalina/core/StandardContext.java b/java/org/apache/catalina/core/StandardContext.java
+index 5314240..f7d0a36 100644
+--- a/java/org/apache/catalina/core/StandardContext.java
++++ b/java/org/apache/catalina/core/StandardContext.java
+@@ -698,6 +698,13 @@ public class StandardContext extends ContainerBase
+ 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.
+ */
+@@ -6625,6 +6632,18 @@ public class StandardContext extends ContainerBase
+
+
+ @Override
++ public void setXmlBlockExternal(boolean xmlBlockExternal) {
++ this.xmlBlockExternal = xmlBlockExternal;
++ }
++
++
++ @Override
++ public boolean getXmlBlockExternal() {
++ return xmlBlockExternal;
++ }
++
++
++ @Override
+ public void setTldValidation(boolean tldValidation){
+ this.tldValidation = tldValidation;
+ }
+diff --git a/java/org/apache/catalina/startup/ContextConfig.java b/java/org/apache/catalina/startup/ContextConfig.java
+index 80080e0..4c8213c 100644
+--- a/java/org/apache/catalina/startup/ContextConfig.java
++++ b/java/org/apache/catalina/startup/ContextConfig.java
+@@ -516,14 +516,16 @@ public class ContextConfig implements LifecycleListener {
+ 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();
+ }
+
+diff --git a/java/org/apache/catalina/startup/FailedContext.java b/java/org/apache/catalina/startup/FailedContext.java
+index 3ece2a9..f8459ef 100644
+--- a/java/org/apache/catalina/startup/FailedContext.java
++++ b/java/org/apache/catalina/startup/FailedContext.java
+@@ -428,6 +428,11 @@ public class FailedContext extends LifecycleMBeanBase implements Context {
+ @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
+diff --git a/java/org/apache/catalina/startup/TldConfig.java b/java/org/apache/catalina/startup/TldConfig.java
+index 8127c0b..cd114fb 100644
+--- a/java/org/apache/catalina/startup/TldConfig.java
++++ b/java/org/apache/catalina/startup/TldConfig.java
+@@ -85,20 +85,21 @@ public final class TldConfig implements LifecycleListener {
+ * Create (if necessary) and return a Digester configured to process the
+ * tld.
+ */
+- private static Digester createTldDigester(boolean validation) {
++ private static Digester createTldDigester(boolean validation,
++ boolean blockExternal) {
+
+ Digester digester = null;
+ if (!validation) {
+ if (tldDigesters[0] == null) {
+ tldDigesters[0] = DigesterFactory.newDigester(validation,
+- true, new TldRuleSet());
++ true, new TldRuleSet(), blockExternal);
+ tldDigesters[0].getParser();
+ }
+ digester = tldDigesters[0];
+ } else {
+ if (tldDigesters[1] == null) {
+ tldDigesters[1] = DigesterFactory.newDigester(validation,
+- true, new TldRuleSet());
++ true, new TldRuleSet(), blockExternal);
+ tldDigesters[1].getParser();
+ }
+ digester = tldDigesters[1];
+@@ -567,7 +568,8 @@ public final class TldConfig implements LifecycleListener {
+
+ private void init() {
+ if (tldDigester == null){
+- tldDigester = createTldDigester(context.getTldValidation());
++ tldDigester = createTldDigester(context.getTldValidation(),
++ context.getXmlBlockExternal());
+ }
+ }
+
+diff --git a/java/org/apache/jasper/Constants.java b/java/org/apache/jasper/Constants.java
+index 75838dc..142c662 100644
+--- a/java/org/apache/jasper/Constants.java
++++ b/java/org/apache/jasper/Constants.java
+@@ -241,4 +241,13 @@ public class Constants {
+ */
+ 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.
++ * <p>
++ * 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";
+ }
+diff --git a/java/org/apache/jasper/JspC.java b/java/org/apache/jasper/JspC.java
+index eac7784..9c88b18 100644
+--- a/java/org/apache/jasper/JspC.java
++++ b/java/org/apache/jasper/JspC.java
+@@ -127,6 +127,7 @@ public class JspC extends Task implements Options {
+ 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;
+@@ -158,6 +159,7 @@ public class JspC extends Task implements Options {
+ 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;
+@@ -367,6 +369,8 @@ public class JspC extends Task implements Options {
+ 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 +
+@@ -854,6 +858,14 @@ public class JspC extends Task implements Options {
+ return validateTld;
+ }
+
++ public void setBlockExternal( boolean b ) {
++ this.blockExternal = b;
++ }
++
++ public boolean isBlockExternal() {
++ return blockExternal;
++ }
++
+ public void setListErrors( boolean b ) {
+ listErrors = b;
+ }
+@@ -1435,6 +1447,9 @@ public class JspC extends Task implements Options {
+ 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);
+diff --git a/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java b/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
+index 91af39e..562f365 100644
+--- a/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
++++ b/java/org/apache/jasper/compiler/ImplicitTagLibraryInfo.java
+@@ -23,6 +23,7 @@ import java.util.Iterator;
+ 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;
+@@ -124,11 +125,21 @@ class ImplicitTagLibraryInfo extends TagLibraryInfo {
+ pi.addDependant(path, ctxt.getLastModified(path));
+ }
+
++ ServletContext servletContext = ctxt.getServletContext();
+ boolean validate = Boolean.parseBoolean(
+- ctxt.getServletContext().getInitParameter(
++ servletContext.getInitParameter(
+ Constants.XML_VALIDATION_TLD_INIT_PARAM));
+-
+- ParserUtils pu = new ParserUtils(validate);
++ 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) {
+diff --git a/java/org/apache/jasper/compiler/JspConfig.java b/java/org/apache/jasper/compiler/JspConfig.java
+index 570a6d5..f74bdce 100644
+--- a/java/org/apache/jasper/compiler/JspConfig.java
++++ b/java/org/apache/jasper/compiler/JspConfig.java
+@@ -80,10 +80,18 @@ public class JspConfig {
+
+ 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(validate);
++ ParserUtils pu = new ParserUtils(validate, blockExternal);
+ webApp = pu.parseXMLDocument(webXml.getSystemId(),
+ webXml.getInputSource());
+ }
+diff --git a/java/org/apache/jasper/compiler/JspDocumentParser.java b/java/org/apache/jasper/compiler/JspDocumentParser.java
+index 08c2477..d42f140 100644
+--- a/java/org/apache/jasper/compiler/JspDocumentParser.java
++++ b/java/org/apache/jasper/compiler/JspDocumentParser.java
+@@ -30,8 +30,11 @@ import javax.servlet.jsp.tagext.TagLibraryInfo;
+ 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;
+@@ -39,6 +42,7 @@ import org.xml.sax.SAXException;
+ import org.xml.sax.SAXParseException;
+ import org.xml.sax.XMLReader;
+ import org.xml.sax.ext.DefaultHandler2;
++import org.xml.sax.ext.EntityResolver2;
+ import org.xml.sax.helpers.AttributesImpl;
+
+ /**
+@@ -91,6 +95,7 @@ class JspDocumentParser
+ private boolean inDTD;
+
+ private boolean isValidating;
++ private final EntityResolver2 entityResolver;
+
+ private ErrorDispatcher err;
+ private boolean isTagFile;
+@@ -119,6 +124,20 @@ class JspDocumentParser
+ 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);
+ }
+
+ /*
+@@ -239,12 +258,29 @@ class JspDocumentParser
+ }
+ }
+
++
++ @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 null;
++ return entityResolver.resolveEntity(name, publicId, baseURI, systemId);
+ }
+
++
+ /*
+ * Receives notification of the start of an element.
+ *
+diff --git a/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java b/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
+index 36fe86f..e830158 100644
+--- a/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
++++ b/java/org/apache/jasper/compiler/TagLibraryInfoImpl.java
+@@ -31,6 +31,7 @@ import java.util.Iterator;
+ 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;
+@@ -213,12 +214,20 @@ class TagLibraryInfoImpl extends TagLibraryInfo implements TagConstants {
+ Vector<TagFileInfo> tagFileVector = new Vector<TagFileInfo>();
+ Hashtable<String, FunctionInfo> functionTable = new Hashtable<String, FunctionInfo>();
+
+- boolean validate = Boolean.parseBoolean(
+- ctxt.getServletContext().getInitParameter(
+- Constants.XML_VALIDATION_TLD_INIT_PARAM));
++ 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 <taglib> element
+- ParserUtils pu = new ParserUtils(validate);
++ ParserUtils pu = new ParserUtils(validate, blockExternal);
+ TreeNode tld = pu.parseXMLDocument(uri, in);
+
+ // Check to see if the <taglib> root element contains a 'version'
+diff --git a/java/org/apache/jasper/compiler/TagPluginManager.java b/java/org/apache/jasper/compiler/TagPluginManager.java
+index c614194..7fb6d80 100644
+--- a/java/org/apache/jasper/compiler/TagPluginManager.java
++++ b/java/org/apache/jasper/compiler/TagPluginManager.java
+@@ -25,6 +25,7 @@ import java.util.Iterator;
+
+ 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;
+@@ -119,8 +120,18 @@ public class TagPluginManager {
+ private void loadTagPlugins(ErrorDispatcher err, InputStream is)
+ throws JasperException {
+
+- TreeNode root =
+- (new ParserUtils(false)).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;
+ }
+diff --git a/java/org/apache/jasper/compiler/TldLocationsCache.java b/java/org/apache/jasper/compiler/TldLocationsCache.java
+index f2ccbd1..f8a68c0 100644
+--- a/java/org/apache/jasper/compiler/TldLocationsCache.java
++++ b/java/org/apache/jasper/compiler/TldLocationsCache.java
+@@ -289,10 +289,20 @@ public class TldLocationsCache {
+ 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(validate).parseXMLDocument(webXml.getSystemId(),
++ webtld = pu.parseXMLDocument(webXml.getSystemId(),
+ webXml.getInputSource());
+
+ // Allow taglib to be an element of the root or jsp-config (JSP2.0)
+@@ -498,9 +508,17 @@ public class TldLocationsCache {
+ boolean validate = Boolean.parseBoolean(
+ ctxt.getInitParameter(
+ Constants.XML_VALIDATION_TLD_INIT_PARAM));
+-
+- TreeNode tld = new ParserUtils(validate).parseXMLDocument(
+- resourcePath, stream);
++ 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();
+diff --git a/java/org/apache/jasper/xmlparser/ParserUtils.java b/java/org/apache/jasper/xmlparser/ParserUtils.java
+index 94a2502..668cfa4 100644
+--- a/java/org/apache/jasper/xmlparser/ParserUtils.java
++++ b/java/org/apache/jasper/xmlparser/ParserUtils.java
+@@ -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;
+@@ -24,9 +23,11 @@ import javax.xml.parsers.DocumentBuilder;
+ import javax.xml.parsers.DocumentBuilderFactory;
+ import javax.xml.parsers.ParserConfigurationException;
+
++import org.apache.jasper.Constants;
+ import org.apache.jasper.JasperException;
+ import org.apache.jasper.compiler.Localizer;
+ 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;
+@@ -49,7 +50,6 @@ import org.xml.sax.SAXParseException;
+ * @author Craig R. McClanahan
+ * @version $Id$
+ */
+-
+ public class ParserUtils {
+
+ /**
+@@ -60,12 +60,25 @@ public class ParserUtils {
+ /**
+ * An entity resolver for use when parsing XML documents.
+ */
+- static EntityResolver entityResolver = DigesterFactory.SERVLET_API_RESOLVER;
++ 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
+@@ -92,7 +105,7 @@ public class ParserUtils {
+ 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) {
+diff --git a/java/org/apache/tomcat/util/descriptor/DigesterFactory.java b/java/org/apache/tomcat/util/descriptor/DigesterFactory.java
+index e094d8f..bf28a09 100644
+--- a/java/org/apache/tomcat/util/descriptor/DigesterFactory.java
++++ b/java/org/apache/tomcat/util/descriptor/DigesterFactory.java
+@@ -17,6 +17,7 @@
+ package org.apache.tomcat.util.descriptor;
+
+ import java.net.URL;
++import java.util.Collections;
+ import java.util.HashMap;
+ import java.util.Map;
+
+@@ -24,6 +25,7 @@ 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
+@@ -32,10 +34,16 @@ import org.apache.tomcat.util.digester.RuleSet;
+ public class DigesterFactory {
+
+ /**
+- * A resolver for the resources packaged in servlet-api.jar
++ * Mapping of well-known public IDs used by the Servlet API to the matching
++ * local resource.
+ */
+- public static final LocalResolver SERVLET_API_RESOLVER;
++ public static final Map<String,String> SERVLET_API_PUBLIC_IDS;
+
++ /**
++ * Mapping of well-known system IDs used by the Servlet API to the matching
++ * local resource.
++ */
++ public static final Map<String,String> SERVLET_API_SYSTEM_IDS;
+
+ static {
+ Map<String, String> publicIds = new HashMap<String, String>();
+@@ -81,7 +89,8 @@ public class DigesterFactory {
+ addSelf(systemIds, "javaee_web_services_1_3.xsd");
+ addSelf(systemIds, "javaee_web_services_client_1_3.xsd");
+
+- SERVLET_API_RESOLVER = new LocalResolver(publicIds, systemIds);
++ SERVLET_API_PUBLIC_IDS = Collections.unmodifiableMap(publicIds);
++ SERVLET_API_SYSTEM_IDS = Collections.unmodifiableMap(systemIds);
+ }
+
+ private static void addSelf(Map<String, String> ids, String id) {
+@@ -103,15 +112,19 @@ public class DigesterFactory {
+ * @param xmlValidation turn on/off xml validation
+ * @param xmlNamespaceAware turn on/off namespace validation
+ * @param rule an instance of <code>RuleSet</code> 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) {
++ RuleSet rule,
++ boolean blockExternal) {
+ Digester digester = new Digester();
+ digester.setNamespaceAware(xmlNamespaceAware);
+ digester.setValidating(xmlValidation);
+ digester.setUseContextClassLoader(true);
+- digester.setEntityResolver(SERVLET_API_RESOLVER);
++ EntityResolver2 resolver = new LocalResolver(SERVLET_API_PUBLIC_IDS,
++ SERVLET_API_SYSTEM_IDS, blockExternal);
++ digester.setEntityResolver(resolver);
+ if (rule != null) {
+ digester.addRuleSet(rule);
+ }
+diff --git a/java/org/apache/tomcat/util/descriptor/LocalResolver.java b/java/org/apache/tomcat/util/descriptor/LocalResolver.java
+index 55edf3d..fb19145 100644
+--- a/java/org/apache/tomcat/util/descriptor/LocalResolver.java
++++ b/java/org/apache/tomcat/util/descriptor/LocalResolver.java
+@@ -16,6 +16,7 @@
+ */
+ package org.apache.tomcat.util.descriptor;
+
++import java.io.FileNotFoundException;
+ import java.io.IOException;
+ import java.net.MalformedURLException;
+ import java.net.URI;
+@@ -23,6 +24,7 @@ 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;
+@@ -32,22 +34,30 @@ import org.xml.sax.ext.EntityResolver2;
+ */
+ public class LocalResolver implements EntityResolver2 {
+
++ private static final StringManager sm =
++ StringManager.getManager(Constants.PACKAGE_NAME);
++
+ private final Map<String,String> publicIds;
+ private final Map<String,String> 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 public identifiers to local resources
+- * @param systemIds mapping of system identifiers to local resources
++ * @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<String,String> publicIds,
+- Map<String,String> systemIds) {
++ Map<String,String> systemIds, boolean blockExternal) {
+ this.publicIds = publicIds;
+ this.systemIds = systemIds;
++ this.blockExternal = blockExternal;
+ }
+
+
+@@ -60,63 +70,77 @@ public class LocalResolver implements EntityResolver2 {
+
+ @Override
+ public InputSource resolveEntity(String name, String publicId,
+- String baseURI, String systemId) throws SAXException, IOException {
+-
+- String resolved = resolve(publicId, systemId, baseURI);
+- if (resolved == null) {
+- return null;
+- }
++ String base, String systemId) throws SAXException, IOException {
+
+- InputSource is = new InputSource(resolved);
+- is.setPublicId(publicId);
+- return is;
+- }
+-
+-
+- @Override
+- public InputSource getExternalSubset(String name, String baseURI)
+- throws SAXException, IOException {
+- return null;
+- }
+-
+-
+- private String resolve(String publicId, String systemId, String baseURI) {
+- // try resolving using the publicId
++ // First try resolving using the publicId
+ String resolved = publicIds.get(publicId);
+ if (resolved != null) {
+- return resolved;
++ InputSource is = new InputSource(resolved);
++ is.setPublicId(publicId);
++ return is;
+ }
+
+- // try resolving using the systemId
++ // If there is no systemId, can't try anything else
+ if (systemId == null) {
+- return null;
++ throw new FileNotFoundException(sm.getString("localResolver.unresolvedEntity",
++ name, publicId, systemId, base));
+ }
+
+- systemId = resolve(baseURI, systemId);
++ // Try resolving with the supplied systemId
+ resolved = systemIds.get(systemId);
+ if (resolved != null) {
+- return resolved;
++ InputSource is = new InputSource(resolved);
++ is.setPublicId(publicId);
++ return is;
+ }
+
+- // fall back to the supplied systemId
+- return systemId;
+- }
+-
+-
+- private static String resolve(String baseURI, String systemId) {
++ // Resolve the supplied systemId against the base
++ URI systemUri;
+ try {
+- if (baseURI == null) {
+- return systemId;
++ 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();
+ }
+- URI systemUri = new URI(systemId);
+- if (systemUri.isAbsolute()) {
+- return systemId;
+- }
+- return new URL(new URL(baseURI), systemId).toString();
++ systemUri = systemUri.normalize();
+ } catch (URISyntaxException e) {
+- return systemId;
+- } catch (MalformedURLException e) {
+- return systemId;
++ // 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;
+ }
+-}
+\ No newline at end of file
++}
+diff --git a/java/org/apache/tomcat/util/descriptor/LocalStrings.properties b/java/org/apache/tomcat/util/descriptor/LocalStrings.properties
+index f7d6891..2e42fc7 100644
+--- a/java/org/apache/tomcat/util/descriptor/LocalStrings.properties
++++ b/java/org/apache/tomcat/util/descriptor/LocalStrings.properties
+@@ -13,5 +13,7 @@
+ # 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}].
+diff --git a/test/javax/servlet/resources/TestSchemaValidation.java b/test/javax/servlet/resources/TestSchemaValidation.java
+index 46ab8ae..59ec8d5 100644
+--- a/test/javax/servlet/resources/TestSchemaValidation.java
++++ b/test/javax/servlet/resources/TestSchemaValidation.java
+@@ -31,8 +31,8 @@ public class TestSchemaValidation {
+
+ @Test
+ public void testWebapp_2_2() throws Exception {
+- Digester digester =
+- DigesterFactory.newDigester(true, true, new WebRuleSet(false));
++ Digester digester = DigesterFactory.newDigester(
++ true, true, new WebRuleSet(false), true);
+ digester.push(new WebXml());
+ WebXml desc = (WebXml) digester.parse(
+ new File("test/webapp-2.2/WEB-INF/web.xml"));
+@@ -42,8 +42,8 @@ public class TestSchemaValidation {
+
+ @Test
+ public void testWebapp_2_3() throws Exception {
+- Digester digester =
+- DigesterFactory.newDigester(true, true, new WebRuleSet(false));
++ Digester digester = DigesterFactory.newDigester(
++ true, true, new WebRuleSet(false), true);
+ digester.push(new WebXml());
+ WebXml desc = (WebXml) digester.parse(
+ new File("test/webapp-2.3/WEB-INF/web.xml"));
+@@ -53,8 +53,8 @@ public class TestSchemaValidation {
+
+ @Test
+ public void testWebapp_2_4() throws Exception {
+- Digester digester =
+- DigesterFactory.newDigester(true, true, new WebRuleSet(false));
++ Digester digester = DigesterFactory.newDigester(
++ true, true, new WebRuleSet(false), true);
+ digester.push(new WebXml());
+ WebXml desc = (WebXml) digester.parse(
+ new File("test/webapp-2.4/WEB-INF/web.xml"));
+@@ -63,8 +63,8 @@ public class TestSchemaValidation {
+
+ @Test
+ public void testWebapp_2_5() throws Exception {
+- Digester digester =
+- DigesterFactory.newDigester(true, true, new WebRuleSet(false));
++ Digester digester = DigesterFactory.newDigester(
++ true, true, new WebRuleSet(false), true);
+ digester.push(new WebXml());
+ WebXml desc = (WebXml) digester.parse(
+ new File("test/webapp-2.5/WEB-INF/web.xml"));
+@@ -73,8 +73,8 @@ public class TestSchemaValidation {
+
+ @Test
+ public void testWebapp_3_0() throws Exception {
+- Digester digester =
+- DigesterFactory.newDigester(true, true, new WebRuleSet(false));
++ Digester digester = DigesterFactory.newDigester(
++ true, true, new WebRuleSet(false), true);
+ digester.push(new WebXml());
+ WebXml desc = (WebXml) digester.parse(
+ new File("test/webapp-3.0/WEB-INF/web.xml"));
+diff --git a/test/org/apache/catalina/core/TesterContext.java b/test/org/apache/catalina/core/TesterContext.java
+index 0c3a802..3c802be 100644
+--- a/test/org/apache/catalina/core/TesterContext.java
++++ b/test/org/apache/catalina/core/TesterContext.java
+@@ -636,6 +636,16 @@ public class TesterContext implements Context {
+ }
+
+ @Override
++ public boolean getXmlBlockExternal() {
++ return false;
++ }
++
++ @Override
++ public void setXmlBlockExternal(boolean xmlBlockExternal) {
++ // NO-OP
++ }
++
++ @Override
+ public boolean getTldNamespaceAware() {
+ return true;
+ }
+diff --git a/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java b/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java
+index b41606b..cf8b6b3 100644
+--- a/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java
++++ b/test/org/apache/tomcat/util/descriptor/TestLocalResolver.java
+@@ -16,6 +16,7 @@
+ */
+ package org.apache.tomcat.util.descriptor;
+
++import java.io.FileNotFoundException;
+ import java.io.IOException;
+ import java.util.HashMap;
+ import java.util.Map;
+@@ -34,7 +35,7 @@ public class TestLocalResolver {
+ private final Map<String, String> publicIds = new HashMap<String, String>();
+ private final Map<String, String> systemIds = new HashMap<String, String>();
+
+- private LocalResolver resolver = new LocalResolver(publicIds, systemIds);
++ private LocalResolver resolver = new LocalResolver(publicIds, systemIds, true);
+ private String WEB_22_LOCAL;
+ private String WEB_30_LOCAL;
+ private String WEBCOMMON_30_LOCAL;
+@@ -53,25 +54,25 @@ public class TestLocalResolver {
+ return ServletContext.class.getResource(id).toExternalForm();
+ }
+
+- @Test
+- public void unknownNullIdIsNull() throws IOException, SAXException {
++ @Test(expected = FileNotFoundException.class)
++ public void unknownNullId() throws IOException, SAXException {
+ Assert.assertNull(resolver.resolveEntity(null, null));
+ }
+
+- @Test
+- public void unknownPublicIdIsNull() throws IOException, SAXException {
++ @Test(expected = FileNotFoundException.class)
++ public void unknownPublicId() throws IOException, SAXException {
+ Assert.assertNull(resolver.resolveEntity("unknown", null));
+ }
+
+- @Test
+- public void unknownSystemIdIsReturned() throws IOException, SAXException {
++ @Test(expected = FileNotFoundException.class)
++ public void unknownSystemId() throws IOException, SAXException {
+ InputSource source = resolver.resolveEntity(null, "unknown");
+ Assert.assertEquals(null, source.getPublicId());
+ Assert.assertEquals("unknown", source.getSystemId());
+ }
+
+- @Test
+- public void unknownSystemIdIsResolvedAgainstBaseURI()
++ @Test(expected = FileNotFoundException.class)
++ public void unknownRelativeSystemId()
+ throws IOException, SAXException {
+ InputSource source = resolver.resolveEntity(
+ null, null, "http://example.com/home.html", "unknown");
+@@ -121,4 +122,4 @@ public class TestLocalResolver {
+ Assert.assertEquals(null, source.getPublicId());
+ Assert.assertEquals(WEB_30_LOCAL, source.getSystemId());
+ }
+-}
+\ No newline at end of file
++}
+diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
+index ea776b3..125dc09 100644
+--- a/webapps/docs/changelog.xml
++++ b/webapps/docs/changelog.xml
+@@ -216,6 +216,12 @@
+ <bug>55851</bug>: Further fixes to enable SPNEGO authentication to work
+ with IBM JDKs. Based on a patch by Arunav Sanyal. (markt)
+ </fix>
++ <add>
++ 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)
++ </add>
+ </changelog>
+ </subsection>
+ <subsection name="Coyote">
+diff --git a/webapps/docs/config/context.xml b/webapps/docs/config/context.xml
+index 15849f4..f0fe76e 100644
+--- a/webapps/docs/config/context.xml
++++ b/webapps/docs/config/context.xml
+@@ -524,6 +524,16 @@
+ Context. If not specified, a standard default value will be used.</p>
+ </attribute>
+
++ <attribute name="xmlBlockExternal" required="false">
++ <p>If the value of this flag is <code>true</code>, the parsing of
++ <code>web.xml</code>, <code>web-fragment.xml</code>, <code>*.tld</code>,
++ <code>*.jspx</code>, <code>*.tagx</code> and <code>tagPlugins.xml</code>
++ files for this web application will not permit external entities to be
++ loaded. If a <code>SecurityManager</code> is configured then the default
++ value of this attribute will be <code>true</code>, else the default
++ value will be <code>false</code>.</p>
++ </attribute>
++
+ <attribute name="xmlNamespaceAware" required="false">
+ <p>If the value of this flag is <code>true</code>, the parsing of
+ <code>web.xml</code> and <code>web-fragment.xml</code> files for this
+diff --git a/webapps/docs/security-howto.xml b/webapps/docs/security-howto.xml
+index 56dc11f..ef4d34a 100644
+--- a/webapps/docs/security-howto.xml
++++ b/webapps/docs/security-howto.xml
+@@ -179,6 +179,9 @@
+ <ul>
+ <li>The default value for the <strong>deployXML</strong> attribute of the
+ <strong>Host</strong> element is changed to <code>false</code>.</li>
++ <li>The default value for the <strong>xmlBlockExternal</strong> attribute
++ of the <strong>Context</strong> element is changed to <code>true</code>.
++ </li>
+ </ul>
+ </section>
+
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/tomcat7.git
More information about the pkg-java-commits
mailing list