Bug 577951 - CVE-2021-4104: Remote code execution in Log4j 1.x when
application is configured to use JMSAppender

Change XSLT tranformation logging to bind to Java util logging instead
of Log4j.  Reproduce the log format from the Log4j logger.  Remove Log4j
from the feature, and remove Log4j config file.  Remove defunct debug
log4j config file.

Change-Id: I52a53897c787e1bc09df35561c6f10948297b429
Signed-off-by: Stewart Francis <stewartfrancis@uk.ibm.com>
diff --git a/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/log4j.properties b/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/log4j.properties
deleted file mode 100644
index 2898bb9..0000000
--- a/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/log4j.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-###############################################################################
-# Copyright (c) 2008, 2018 IBM Corporation and others.
-# This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License 2.0
-# which accompanies this distribution, and is available at
-# https://www.eclipse.org/legal/epl-2.0/
-#
-# SPDX-License-Identifier: EPL-2.0
-#
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-# Set root logger level to DEBUG and its appenders are A1 and A2
-log4j.rootLogger=DEBUG, A2
-
-# A2 is set to be a ConsoleAppender
-log4j.appender.A2=org.apache.log4j.ConsoleAppender
-
-# A2 uses PatternLayout.
-log4j.appender.A2.layout=org.apache.log4j.PatternLayout
-log4j.appender.A2.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{1} %x - %m%n
-
diff --git a/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/LogFormatter.java b/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/LogFormatter.java
new file mode 100644
index 0000000..8dffc5b
--- /dev/null
+++ b/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/LogFormatter.java
@@ -0,0 +1,80 @@
+/********************************************************************************
+ * Copyright (c) 2022 IBM
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *   Stewart Francis - initial API and implementation
+ ********************************************************************************/
+package org.eclipse.wst.xsl.jaxp.debug.invoker.internal;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+
+public class LogFormatter extends Formatter {
+
+    @Override
+    public String format(LogRecord record) {
+        StringBuilder builder = new StringBuilder();
+
+        ZonedDateTime zdt = ZonedDateTime.ofInstant(
+        		Instant.ofEpochMilli(record.getMillis()), ZoneId.systemDefault());
+        java.util.Formatter formatter = new java.util.Formatter(builder);
+        try {
+            formatter.format(
+                "%1$tT,%1$tL %2$-7s [%3$s] ", //$NON-NLS-1$
+                zdt,
+                record.getLevel().getLocalizedName(),
+                record.getThreadID());
+		
+            //Only show the last segment of the logger name
+            String loggerName = record.getLoggerName();
+            int lastDot = loggerName.lastIndexOf('.');
+            //If there are no dots append the whole thing
+            if (lastDot < 0) {
+                builder.append(loggerName);
+            } else if (lastDot == loggerName.length() - 1) {
+            	//If last char is a dot, check for a previous dot
+            	int secondLastDot = loggerName.lastIndexOf('.', lastDot - 1);
+            	if (secondLastDot < 0) {
+            		//Append from the previous dot if any
+            		builder.append(loggerName, secondLastDot + 1, loggerName.length());
+            	} else {
+            		//Else append the whole thing
+            		builder.append(loggerName);
+            	}
+            } else {
+            	//Append the last segment
+                builder.append(loggerName, lastDot + 1, loggerName.length());
+            }
+
+			builder.append(" - "); //$NON-NLS-1$
+			builder.append(record.getMessage());
+
+            //Append any exception information
+            String throwable = ""; //$NON-NLS-1$
+	        if (record.getThrown() != null) {
+	            StringWriter sw = new StringWriter();
+	            PrintWriter pw = new PrintWriter(sw);
+	            pw.println();
+	            record.getThrown().printStackTrace(pw);
+	            pw.close();
+	            throwable = sw.toString();
+	        }
+	        
+	        formatter.format("%s%n", throwable); //$NON-NLS-1$
+            return builder.toString();
+        } finally {
+            formatter.close();
+        }
+    } 
+}
diff --git a/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/LoggingConfig.java b/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/LoggingConfig.java
new file mode 100644
index 0000000..09e249e
--- /dev/null
+++ b/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/LoggingConfig.java
@@ -0,0 +1,39 @@
+/********************************************************************************
+ * Copyright (c) 2022 IBM
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *   Stewart Francis - initial API and implementation
+ ********************************************************************************/
+package org.eclipse.wst.xsl.jaxp.debug.invoker.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.LogManager;
+
+public class LoggingConfig {
+    public LoggingConfig() throws SecurityException, IOException {
+        final LogManager logManager = LogManager.getLogManager();
+
+        ByteArrayOutputStream os = new ByteArrayOutputStream();
+        Properties props = new Properties();
+        String consoleHandler = SystemOutConsoleHandler.class.getName();
+
+        props.put("handlers", consoleHandler); //$NON-NLS-1$
+        props.put(".level", Level.FINE.getName()); //$NON-NLS-1$
+        props.put(consoleHandler + ".level", Level.FINE.getName()); //$NON-NLS-1$
+        props.put(consoleHandler + ".formatter", LogFormatter.class.getName()); //$NON-NLS-1$
+
+        props.store(os, null);
+        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
+        logManager.readConfiguration(is);
+    }
+}
diff --git a/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/SystemOutConsoleHandler.java b/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/SystemOutConsoleHandler.java
new file mode 100644
index 0000000..a54f9e7
--- /dev/null
+++ b/xsl/bundles/org.eclipse.wst.xsl.jaxp.debug/src/org/eclipse/wst/xsl/jaxp/debug/invoker/internal/SystemOutConsoleHandler.java
@@ -0,0 +1,22 @@
+/********************************************************************************
+ * Copyright (c) 2022 IBM
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *   Stewart Francis - initial API and implementation
+ ********************************************************************************/
+package org.eclipse.wst.xsl.jaxp.debug.invoker.internal;
+
+import java.io.OutputStream;
+import java.util.logging.ConsoleHandler;
+
+public class SystemOutConsoleHandler extends ConsoleHandler {
+    protected void setOutputStream(OutputStream out) throws SecurityException {
+        super.setOutputStream(System.out);
+    }
+}
\ No newline at end of file
diff --git a/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/log4j.debug.properties b/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/log4j.debug.properties
deleted file mode 100644
index 123f201..0000000
--- a/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/log4j.debug.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-###############################################################################
-# Copyright (c) 2008, 2018 IBM Corporation and others.
-# This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License 2.0
-# which accompanies this distribution, and is available at
-# https://www.eclipse.org/legal/epl-2.0/
-#
-# SPDX-License-Identifier: EPL-2.0
-#
-# Contributors:
-#     IBM Corporation - initial API and implementation
-###############################################################################
-# Set root logger level to DEBUG and its appenders are A1 and A2
-log4j.rootLogger=ERROR, A2
-
-# A2 is set to be a ConsoleAppender
-log4j.appender.A2=org.apache.log4j.ConsoleAppender
-
-# A2 uses PatternLayout.
-log4j.appender.A2.layout=org.apache.log4j.PatternLayout
-log4j.appender.A2.layout.ConversionPattern=%d{HH:mm:ss,SSS} %-5p [%t] %c{1} %x - %m%n
-
diff --git a/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.xml b/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.xml
index e52549f..25b5cea 100644
--- a/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.xml
+++ b/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/plugin.xml
@@ -26,7 +26,7 @@
 	<extension point="org.eclipse.wst.xsl.jaxp.launching.invoke">
 		<invoker id="org.eclipse.wst.xsl.launching.jaxp.invoke"
 			class="org.eclipse.wst.xsl.jaxp.debug.invoker.internal.JAXPSAXProcessorInvoker"
-			classpath="${eclipse_orbit:org.eclipse.wst.xsl.jaxp.debug};${eclipse_orbit:org.apache.commons.logging};${eclipse_orbit:org.apache.log4j}" />
+			classpath="${eclipse_orbit:org.eclipse.wst.xsl.jaxp.debug};${eclipse_orbit:org.apache.commons.logging}" />
 	</extension>
 
   	<extension
diff --git a/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPJavaLaunchConfigurationDelegate.java b/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPJavaLaunchConfigurationDelegate.java
index d4a08c5..b572ade 100644
--- a/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPJavaLaunchConfigurationDelegate.java
+++ b/xsl/bundles/org.eclipse.wst.xsl.jaxp.launching/src/org/eclipse/wst/xsl/jaxp/launching/internal/JAXPJavaLaunchConfigurationDelegate.java
@@ -436,24 +436,9 @@
 			String tfactory = getTransformerFactory(install);
 			if (tfactory != null)
 				vmargs += " -Djavax.xml.transform.TransformerFactory=" + tfactory; //$NON-NLS-1$
-
-			// if (ILaunchManager.DEBUG_MODE.equals(mode))
-			// {
-			// // in debug mode, set the logging to ERROR. This prevents the
-			// console from popping up on top of the result view!
-			// try
-			// {
-			// URL url =
-			// FileLocator.resolve(FileLocator.find(Platform.getBundle(JAXPLaunchingPlugin.PLUGIN_ID),
-			// new Path("/log4j.debug.properties"), null));
-			//					vmargs += " -Dlog4j.configuration=\""+url.toExternalForm()+"\""; //$NON-NLS-1$
-			// }
-			// catch (IOException e)
-			// {
-			// JAXPLaunchingPlugin.log(e);
-			// }
-			// }
 		}
+
+		vmargs += " -Djava.util.logging.config.class=org.eclipse.wst.xsl.jaxp.debug.invoker.internal.LoggingConfig"; //$NON-NLS-1$
 		return vmargs;
 	}
 
diff --git a/xsl/features/org.eclipse.wst.xsl.feature/feature.xml b/xsl/features/org.eclipse.wst.xsl.feature/feature.xml
index ed84828..a10e302 100644
--- a/xsl/features/org.eclipse.wst.xsl.feature/feature.xml
+++ b/xsl/features/org.eclipse.wst.xsl.feature/feature.xml
@@ -41,7 +41,6 @@
       <import plugin="org.apache.xml.serializer" version="0.0.0" match="greaterOrEqual"/>
       <import plugin="org.apache.bcel" version="0.0.0" match="greaterOrEqual"/>
       <import plugin="java_cup.runtime" version="0.0.0" match="greaterOrEqual"/>
-      <import plugin="org.apache.log4j" version="0.0.0" match="greaterOrEqual"/>
    </requires>
 
    <plugin