You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2014/05/22 03:32:39 UTC

svn commit: r1596729 - in /logging/log4j/log4j2/trunk: log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ log4j-core/src/main/java/org/apache/logging/log4j/core/net/ log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/ log4j...

Author: ggregory
Date: Thu May 22 01:32:38 2014
New Revision: 1596729

URL: http://svn.apache.org/r1596729
Log:
<action issue="LOG4J2-644" dev="ggregory" type="add">
  Implement a SecureSocketAppender and secure server (SSL/TLS).
</action>

Added:
    logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SecureSocketAppender.java   (with props)
    logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/SecureTcpSocketServer.java   (with props)
    logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/SslXmlSocketServerTest.java   (with props)
Modified:
    logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/Protocol.java
    logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/AbstractSocketServer.java
    logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/TcpSocketServer.java
    logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
    logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java
    logging/log4j/log4j2/trunk/src/changes/changes.xml
    logging/log4j/log4j2/trunk/src/site/site.xml
    logging/log4j/log4j2/trunk/src/site/xdoc/manual/appenders.xml

Added: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SecureSocketAppender.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SecureSocketAppender.java?rev=1596729&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SecureSocketAppender.java (added)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SecureSocketAppender.java Thu May 22 01:32:38 2014
@@ -0,0 +1,132 @@
+/*
+ * 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.logging.log4j.core.appender;
+
+import java.io.Serializable;
+
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
+import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
+import org.apache.logging.log4j.core.config.plugins.PluginElement;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.apache.logging.log4j.core.layout.SerializedLayout;
+import org.apache.logging.log4j.core.net.AbstractSocketManager;
+import org.apache.logging.log4j.core.net.Advertiser;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.apache.logging.log4j.core.net.TlsSocketManager;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.util.Booleans;
+import org.apache.logging.log4j.util.EnglishEnums;
+
+/**
+ * An Appender that delivers events over secure socket connections (SSL/TLS).
+ */
+@Plugin(name = "SecureSocket", category = "Core", elementType = "appender", printObject = true)
+public class SecureSocketAppender extends SocketAppender {
+
+    protected SecureSocketAppender(String name, Layout<? extends Serializable> layout, Filter filter,
+            AbstractSocketManager manager, boolean ignoreExceptions, boolean immediateFlush, Advertiser advertiser) {
+        super(name, layout, filter, manager, ignoreExceptions, immediateFlush, advertiser);
+    }
+
+    /**
+     * 
+     * @param host
+     *        The name of the host to connect to.
+     * @param portNum
+     *        The port to connect to on the target host.
+     * @param sslConfig 
+     * @param protocol
+     *        The Protocol to use.
+     * @param delay
+     *        The interval in which failed writes should be retried.
+     * @param immediateFail
+     *        True if the write should fail if no socket is immediately available.
+     * @param name
+     *        The name of the Appender.
+     * @param immediateFlush
+     *        "true" if data should be flushed on each write.
+     * @param ignore
+     *        If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise they are
+     *        propagated to the caller.
+     * @param layout
+     *        The layout to use (defaults to SerializedLayout).
+     * @param filter
+     *        The Filter or null.
+     * @param advertise
+     *        "true" if the appender configuration should be advertised, "false" otherwise.
+     * @param config
+     *        The Configuration
+     * @return A SocketAppender.
+     */
+    @PluginFactory
+    public static SecureSocketAppender createAppender(
+            // @formatter:off
+            @PluginAttribute("host") final String host,
+            @PluginAttribute("port") final String portNum,
+            @PluginElement("Ssl") final SslConfiguration sslConfig,
+            @PluginAttribute("protocol") final String protocol,
+            @PluginAttribute("reconnectionDelay") final String delay,
+            @PluginAttribute("immediateFail") final String immediateFail,
+            @PluginAttribute("name") final String name,
+            @PluginAttribute("immediateFlush") final String immediateFlush,
+            @PluginAttribute("ignoreExceptions") final String ignore,
+            @PluginElement("Layout") Layout<? extends Serializable> layout,
+            @PluginElement("Filters") final Filter filter,
+            @PluginAttribute("advertise") final String advertise,
+            @PluginConfiguration final Configuration config) {
+            // @formatter:on
+        boolean isFlush = Booleans.parseBoolean(immediateFlush, true);
+        final boolean isAdvertise = Boolean.parseBoolean(advertise);
+        final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
+        final boolean fail = Booleans.parseBoolean(immediateFail, true);
+        final int reconnectDelay = AbstractAppender.parseInt(delay, 0);
+        final int port = AbstractAppender.parseInt(portNum, 0);
+        if (layout == null) {
+            layout = SerializedLayout.createLayout();
+        }
+
+        if (name == null) {
+            LOGGER.error("No name provided for SecureSocketAppender");
+            return null;
+        }
+
+        final Protocol p = EnglishEnums.valueOf(Protocol.class, protocol != null ? protocol : Protocol.TLS.name());
+
+        final AbstractSocketManager manager = createSocketManager(sslConfig, p, host, port, reconnectDelay, fail, layout);
+        if (manager == null) {
+            return null;
+        }
+
+        return new SecureSocketAppender(name, layout, filter, manager, ignoreExceptions, isFlush,
+                isAdvertise ? config.getAdvertiser() : null);
+    }
+
+    protected static AbstractSocketManager createSocketManager(final SslConfiguration sslConfig,
+            final Protocol protocol, final String host, final int port, final int delay, final boolean immediateFail,
+            final Layout<? extends Serializable> layout) {
+        switch (protocol) {
+        case TLS:
+            return TlsSocketManager.getSocketManager(sslConfig, host, port, delay, immediateFail, layout);
+        default:
+            return null;
+        }
+    }
+}

Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SecureSocketAppender.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SecureSocketAppender.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/Protocol.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/Protocol.java?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/Protocol.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/Protocol.java Thu May 22 01:32:38 2014
@@ -22,6 +22,8 @@ package org.apache.logging.log4j.core.ne
 public enum Protocol {
     /** TCP Protocol. */
     TCP,
+    /** TLS Protocol. */
+    TLS,
     /** UDP Protocol. */
     UDP;
 

Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/AbstractSocketServer.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/AbstractSocketServer.java?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/AbstractSocketServer.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/AbstractSocketServer.java Thu May 22 01:32:38 2014
@@ -37,6 +37,8 @@ import org.apache.logging.log4j.core.uti
  * Abstract socket server for TCP and UDP implementations.
  * 
  * @param <T> The kind of input stream read
+ * 
+ * TODO Make a LifeCycle
  */
 public abstract class AbstractSocketServer<T extends InputStream> extends LogEventListener implements Runnable {
 

Added: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/SecureTcpSocketServer.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/SecureTcpSocketServer.java?rev=1596729&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/SecureTcpSocketServer.java (added)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/SecureTcpSocketServer.java Thu May 22 01:32:38 2014
@@ -0,0 +1,37 @@
+/*
+ * 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.logging.log4j.core.net.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+
+/**
+ * Listens for events over a secure socket connection (SSL/TLS).
+ * 
+ * @param <T>
+ *        The kind of input stream read
+ */
+public class SecureTcpSocketServer<T extends InputStream> extends TcpSocketServer<T> {
+
+    public SecureTcpSocketServer(int port, LogEventBridge<T> logEventInput, SslConfiguration sslConfig)
+            throws IOException {
+        super(port, logEventInput, sslConfig.getSSLServerSocketFactory().createServerSocket(port));
+    }
+
+}

Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/SecureTcpSocketServer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/SecureTcpSocketServer.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/TcpSocketServer.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/TcpSocketServer.java?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/TcpSocketServer.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/server/TcpSocketServer.java Thu May 22 01:32:38 2014
@@ -36,7 +36,7 @@ import org.apache.logging.log4j.core.con
  * Listens for events over a socket connection.
  * 
  * @param <T>
- *            The kind of input stream read
+ *        The kind of input stream read
  */
 public class TcpSocketServer<T extends InputStream> extends AbstractSocketServer<T> {
 
@@ -90,10 +90,10 @@ public class TcpSocketServer<T extends I
      * Creates a socket server that reads JSON log events.
      * 
      * @param port
-     *            the port to listen
+     *        the port to listen
      * @return a new a socket server
      * @throws IOException
-     *             if an I/O error occurs when opening the socket.
+     *         if an I/O error occurs when opening the socket.
      */
     public static TcpSocketServer<InputStream> createJsonSocketServer(final int port) throws IOException {
         return new TcpSocketServer<InputStream>(port, new JsonInputStreamLogEventBridge());
@@ -103,10 +103,10 @@ public class TcpSocketServer<T extends I
      * Creates a socket server that reads serialized log events.
      * 
      * @param port
-     *            the port to listen
+     *        the port to listen
      * @return a new a socket server
      * @throws IOException
-     *             if an I/O error occurs when opening the socket.
+     *         if an I/O error occurs when opening the socket.
      */
     public static TcpSocketServer<ObjectInputStream> createSerializedSocketServer(final int port) throws IOException {
         return new TcpSocketServer<ObjectInputStream>(port, new ObjectInputStreamLogEventBridge());
@@ -116,10 +116,10 @@ public class TcpSocketServer<T extends I
      * Creates a socket server that reads XML log events.
      * 
      * @param port
-     *            the port to listen
+     *        the port to listen
      * @return a new a socket server
      * @throws IOException
-     *             if an I/O error occurs when opening the socket.
+     *         if an I/O error occurs when opening the socket.
      */
     public static TcpSocketServer<InputStream> createXmlSocketServer(final int port) throws IOException {
         return new TcpSocketServer<InputStream>(port, new XmlInputStreamLogEventBridge());
@@ -129,9 +129,9 @@ public class TcpSocketServer<T extends I
      * Main startup for the server.
      * 
      * @param args
-     *            The command line arguments.
+     *        The command line arguments.
      * @throws Exception
-     *             if an error occurs.
+     *         if an error occurs.
      */
     public static void main(final String[] args) throws Exception {
         if (args.length < 1 || args.length > 2) {
@@ -176,15 +176,32 @@ public class TcpSocketServer<T extends I
      * Constructor.
      * 
      * @param port
-     *            to listen.
+     *        to listen.
      * @param logEventInput
-     *            the log even input
+     *        the log even input
      * @throws IOException
-     *             if an I/O error occurs when opening the socket.
+     *         if an I/O error occurs when opening the socket.
      */
     public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput) throws IOException {
+        this(port, logEventInput, new ServerSocket(port));
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param port
+     *        to listen.
+     * @param logEventInput
+     *        the log even input
+     * @param serverSocket
+     *        the socket server
+     * @throws IOException
+     *         if an I/O error occurs when opening the socket.
+     */
+    public TcpSocketServer(final int port, final LogEventBridge<T> logEventInput, ServerSocket serverSocket)
+            throws IOException {
         super(port, logEventInput);
-        this.serverSocket = new ServerSocket(port);
+        this.serverSocket = serverSocket;
     }
 
     /**

Modified: logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/SslConfiguration.java Thu May 22 01:32:38 2014
@@ -43,25 +43,19 @@ public class SslConfiguration {
     private static final StatusLogger LOGGER = StatusLogger.getLogger();
     private final KeyStoreConfiguration keyStoreConfig;
     private final TrustStoreConfiguration trustStoreConfig;
-    private SSLContext sslContext;
+    private final SSLContext sslContext;
 
     private SslConfiguration(KeyStoreConfiguration keyStoreConfig, TrustStoreConfiguration trustStoreConfig) {
         this.keyStoreConfig = keyStoreConfig;
         this.trustStoreConfig = trustStoreConfig;
-        this.sslContext = null;
+        this.sslContext = this.createSSLContext();
     }
 
     public SSLSocketFactory getSSLSocketFactory() {
-        if (sslContext == null) {
-            this.sslContext = createSSLContext();
-        }
         return sslContext.getSocketFactory();
     }
 
     public SSLServerSocketFactory getSSLServerSocketFactory() {
-        if (sslContext == null) {
-            this.sslContext = createSSLContext();
-        }
         return sslContext.getServerSocketFactory();
     }
 

Modified: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java (original)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/AbstractSocketServerTest.java Thu May 22 01:32:38 2014
@@ -75,9 +75,9 @@ public abstract class AbstractSocketServ
 
     private final boolean expectLengthException;
 
-    private final String port;
+    protected final String port;
 
-    private final String protocol;
+    protected final String protocol;
 
     private final Logger rootLogger = ctx.getLogger(AbstractSocketServerTest.class.getSimpleName());
 
@@ -168,8 +168,7 @@ public abstract class AbstractSocketServ
         final Filter socketFilter = new ThreadFilter(Filter.Result.NEUTRAL, Filter.Result.DENY);
         final Filter serverFilter = new ThreadFilter(Filter.Result.DENY, Filter.Result.NEUTRAL);
         final Layout<? extends Serializable> socketLayout = createLayout();
-        final SocketAppender socketAppender = SocketAppender.createAppender("localhost", this.port, this.protocol, "-1",
-                null, "Test", "true", "false", socketLayout, socketFilter, null, null);
+        final SocketAppender socketAppender = createSocketAppender(socketFilter, socketLayout);
         socketAppender.start();
         final ListAppender listAppender = new ListAppender("Events", serverFilter, null, false, false);
         listAppender.start();
@@ -209,4 +208,10 @@ public abstract class AbstractSocketServ
         }
     }
 
+    protected SocketAppender createSocketAppender(final Filter socketFilter,
+            final Layout<? extends Serializable> socketLayout) {
+        return SocketAppender.createAppender("localhost", this.port, this.protocol, "-1", null, "Test", "true",
+                "false", socketLayout, socketFilter, null, null);
+    }
+
 }

Added: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/SslXmlSocketServerTest.java
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/SslXmlSocketServerTest.java?rev=1596729&view=auto
==============================================================================
--- logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/SslXmlSocketServerTest.java (added)
+++ logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/SslXmlSocketServerTest.java Thu May 22 01:32:38 2014
@@ -0,0 +1,90 @@
+/*
+ * 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.logging.log4j.core.net.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.nio.charset.Charset;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.Layout;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.SecureSocketAppender;
+import org.apache.logging.log4j.core.appender.SocketAppender;
+import org.apache.logging.log4j.core.net.ssl.KeyStoreConfiguration;
+import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
+import org.apache.logging.log4j.core.net.ssl.TestConstants;
+import org.apache.logging.log4j.core.net.ssl.TrustStoreConfiguration;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class SslXmlSocketServerTest extends AbstractSocketServerTest {
+
+    private static TcpSocketServer<InputStream> server;
+
+    private static SslConfiguration sslConfig;
+
+    private static void initServerSocketFactory() {
+        final KeyStoreConfiguration ksc = new KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, TestConstants.KEYSTORE_PWD);
+        final TrustStoreConfiguration tsc = new TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE,
+                TestConstants.TRUSTSTORE_PWD);
+        sslConfig = SslConfiguration.createSSLConfiguration(ksc, tsc);
+    }
+
+    @Override
+    protected SocketAppender createSocketAppender(final Filter socketFilter,
+            final Layout<? extends Serializable> socketLayout) {
+        return SecureSocketAppender.createAppender("localhost", this.port, sslConfig, this.protocol, "-1", null,
+                "Test", "true", "false", socketLayout, socketFilter, null, null);
+    }
+
+    @BeforeClass
+    public static void setupClass() throws Exception {
+        ((LoggerContext) LogManager.getContext(false)).reconfigure();
+        initServerSocketFactory();
+        // Use a large buffer just to test the code, the UDP test uses a tiny buffer
+        server = new SecureTcpSocketServer<InputStream>(PORT_NUM, new XmlInputStreamLogEventBridge(1024 * 100,
+                Charset.defaultCharset()), sslConfig);
+        thread = server.startNewThread();
+    }
+
+    @AfterClass
+    public static void tearDownClass() {
+        try {
+            server.shutdown();
+        } catch (final IOException e) {
+            e.printStackTrace();
+        }
+        try {
+            thread.join();
+        } catch (final InterruptedException e) {
+            // ignore
+        }
+    }
+
+    public SslXmlSocketServerTest() {
+        super("TLS", PORT, false);
+    }
+
+    @Override
+    protected Layout<String> createLayout() {
+        return super.createXmlLayout();
+    }
+
+}

Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/SslXmlSocketServerTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: logging/log4j/log4j2/trunk/log4j-core/src/test/java/org/apache/logging/log4j/core/net/server/SslXmlSocketServerTest.java
------------------------------------------------------------------------------
    svn:keywords = Id

Modified: logging/log4j/log4j2/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/changes/changes.xml?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/changes/changes.xml (original)
+++ logging/log4j/log4j2/trunk/src/changes/changes.xml Thu May 22 01:32:38 2014
@@ -22,6 +22,9 @@
   </properties>
   <body>
     <release version="2.0-rc2" date="2014-MM-DD" description="Bug fixes and enhancements">
+      <action issue="LOG4J2-644" dev="ggregory" type="add">
+        Implement a SecureSocketAppender and secure server (SSL/TLS).
+      </action>
       <action issue="LOG4J2-620" dev="rgoers" type="fix">
         Perform reconfiguration in a separate thread to prevent deadlocks.
       </action>

Modified: logging/log4j/log4j2/trunk/src/site/site.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/site/site.xml?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/site/site.xml (original)
+++ logging/log4j/log4j2/trunk/src/site/site.xml Thu May 22 01:32:38 2014
@@ -82,13 +82,13 @@
       </item>
 
       <item name="Lookups" href="/manual/lookups.html" collapse="true">
-        <item name="ContextMap" href="/manual/lookups.html#ContextMapLookup"/>
+        <item name="Context Map" href="/manual/lookups.html#ContextMapLookup"/>
         <item name="Date" href="/manual/lookups.html#DateLookcup"/>
         <item name="Environment" href="/manual/lookups.html#EnvironmentLookup"/>
         <item name="JNDI" href="/manual/lookups.html#JNDILookup"/>
         <item name="Map" href="/manual/lookups.html#MapLookup"/>
-        <item name="StructuredData" href="/manual/lookups.html#StructuredDataLookup"/>
-        <item name="SystemProperties" href="/manual/lookups.html#SystemPropertiesLookup"/>
+        <item name="Structured Data" href="/manual/lookups.html#StructuredDataLookup"/>
+        <item name="System Properties" href="/manual/lookups.html#SystemPropertiesLookup"/>
         <item name="Web" href="/manual/lookups.html#WebLookup"/>
       </item>
 
@@ -99,26 +99,27 @@
         <item name="File" href="/manual/appenders.html#FileAppender"/>
         <item name="Flume" href="/manual/appenders.html#FlumeAppender"/>
         <item name="JDBC" href="/manual/appenders.html#JDBCAppender"/>
-        <item name="JMSQueue" href="/manual/appenders.html#JMSQueueAppender"/>
-        <item name="JMSTopic" href="/manual/appenders.html#JMSTopicAppender"/>
+        <item name="JMS Queue" href="/manual/appenders.html#JMSQueueAppender"/>
+        <item name="JMS Topic" href="/manual/appenders.html#JMSTopicAppender"/>
         <item name="JPA" href="/manual/appenders.html#JPAAppender"/>
         <item name="NoSQL" href="/manual/appenders.html#NoSQLAppender"/>
-        <item name="OutputStream" href="/manual/appenders.html#OutputStreamAppender"/>
-        <item name="RandomAccessFile" href="/manual/appenders.html#RandomAccessFileAppender"/>
+        <item name="Output Stream" href="/manual/appenders.html#OutputStreamAppender"/>
+        <item name="Random Access File" href="/manual/appenders.html#RandomAccessFileAppender"/>
         <item name="Rewrite" href="/manual/appenders.html#RewriteAppender"/>
-        <item name="RollingFile" href="/manual/appenders.html#RollingFileAppender"/>
-        <item name="RollingRandomAccessFile" href="/manual/appenders.html#RollingRandomAccessFileAppender"/>
+        <item name="Rolling File" href="/manual/appenders.html#RollingFileAppender"/>
+        <item name="Rolling Random Access File" href="/manual/appenders.html#RollingRandomAccessFileAppender"/>
         <item name="Routing" href="/manual/appenders.html#RoutingAppender"/>
         <item name="SMTP" href="/manual/appenders.html#SMTPAppender"/>
         <item name="Socket" href="/manual/appenders.html#SocketAppender"/>
+        <item name="Secure Socket" href="/manual/appenders.html#SecureSocketAppender"/>
         <item name="Syslog" href="/manual/appenders.html#SyslogAppender"/>
-        <item name="TLSSyslog" href="/manual/appenders.html#TLSSyslogAppender"/>
+        <item name="TLS Syslog" href="/manual/appenders.html#TLSSyslogAppender"/>
       </item>
 
       <item name="Layouts" href="/manual/layouts.html" collapse="true">
         <item name="HTML" href="/manual/layouts.html#HTMLLayout"/>
         <item name="Pattern" href="/manual/layouts.html#PatternLayout"/>
-        <item name="RFC5424" href="/manual/layouts.html#RFC5424Layout"/>
+        <item name="RFC-5424" href="/manual/layouts.html#RFC5424Layout"/>
         <item name="Serialized" href="/manual/layouts.html#SerializedLayout"/>
         <item name="Syslog" href="/manual/layouts.html#SyslogLayout"/>
         <item name="XML" href="/manual/layouts.html#XMLLayout"/>
@@ -127,13 +128,13 @@
 
       <item name="Filters" href="/manual/filters.html" collapse="true">
         <item name="Burst" href="/manual/filters.html#BurstFilter"/>
-        <item name="CompositeFilter" href="/manual/filters.html#CompositeFilter"/>
-        <item name="DynamicThreshold" href="/manual/filters.html#DynamicThresholdFilter"/>
+        <item name="Composite Filter" href="/manual/filters.html#CompositeFilter"/>
+        <item name="Dynamic Threshold" href="/manual/filters.html#DynamicThresholdFilter"/>
         <item name="Map" href="/manual/filters.html#MapFilter"/>
         <item name="Marker" href="/manual/filters.html#MarkerFilter"/>
         <item name="Regex" href="/manual/filters.html#RegexFilter"/>
-        <item name="StructuredData" href="/manual/filters.html#StructuredDataFilter"/>
-        <item name="ThreadContextMap" href="/manual/filters.html#ThreadContextMapFilter"/>
+        <item name="Structured Data" href="/manual/filters.html#StructuredDataFilter"/>
+        <item name="Thread Context Map" href="/manual/filters.html#ThreadContextMapFilter"/>
         <item name="Threshold" href="/manual/filters.html#ThresholdFilter"/>
         <item name="Time" href="/manual/filters.html#TimeFilter"/>
       </item>

Modified: logging/log4j/log4j2/trunk/src/site/xdoc/manual/appenders.xml
URL: http://svn.apache.org/viewvc/logging/log4j/log4j2/trunk/src/site/xdoc/manual/appenders.xml?rev=1596729&r1=1596728&r2=1596729&view=diff
==============================================================================
--- logging/log4j/log4j2/trunk/src/site/xdoc/manual/appenders.xml (original)
+++ logging/log4j/log4j2/trunk/src/site/xdoc/manual/appenders.xml Thu May 22 01:32:38 2014
@@ -2762,13 +2762,13 @@ public class JpaLogEntity extends Abstra
         <a name="SocketAppender"/>
         <subsection name="SocketAppender">
           <p>
-            The SocketAppender is an OutputStreamAppender that writes its output to a remote destination
+            The <code>SocketAppender</code> is an OutputStreamAppender that writes its output to a remote destination
             specified by a host and port. The data can be sent over either TCP or UDP and can be sent in any format.
             The default format is to send a Serialized LogEvent. Log4j 2 contains a SocketServer which is capable
             of receiving serialized LogEvents and routing them through the logging system on the server.
           </p>
           <table>
-            <caption align="top">SocketAppender Parameters</caption>
+            <caption align="top"><code>SocketAppender</code> Parameters</caption>
             <tr>
               <th>Parameter Name</th>
               <th>Type</th>
@@ -2816,7 +2816,7 @@ public class JpaLogEntity extends Abstra
             <tr>
               <td>protocol</td>
               <td>String</td>
-              <td>"TCP" or "UDP". This parameter is required.</td>
+              <td>"TCP" (default) or "UDP".</td>
             </tr>
             <tr>
               <td>reconnectionDelay</td>
@@ -2850,15 +2850,118 @@ public class JpaLogEntity extends Abstra
   </Loggers>
 </Configuration>]]></pre>
         </subsection>
+        <a name="SecureSocketAppender"/>
+        <subsection name="SecureSocketAppender">
+          <p>
+            The <code>SecureSocketAppender</code> is a <code>SocketAppender</code> that securely writes its output to a remote destination
+            specified by a host and port. The data is sent over TLS and can be sent in any format.
+            The default format is to send a Serialized LogEvent. Log4j 2 contains a secure socket server which is capable
+            of receiving serialized LogEvents and routing them through the logging system on the server.
+          </p>
+          <p>
+            The parameters in this table are the same as for the <code>SocketAppender</code> with the addition of the SSL parameter.
+          </p>
+          <table>
+            <caption align="top"><code>SecureSocketAppender</code> Parameters</caption>
+            <tr>
+              <th>Parameter Name</th>
+              <th>Type</th>
+              <th>Description</th>
+            </tr>
+            <tr>
+              <td>SSL</td>
+              <td>SSLConfiguration</td>
+              <td>Contains the configuration for the KeyStore and TrustStore.</td>
+            </tr>
+            <tr>
+              <td>filter</td>
+              <td>Filter</td>
+              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
+              may be used by using a CompositeFilter.</td>
+            </tr>
+            <tr>
+              <td>host</td>
+              <td>String</td>
+              <td>The name or address of the system that is listening for log events. This parameter is required.</td>
+            </tr>
+            <tr>
+              <td>immediateFail</td>
+              <td>boolean</td>
+              <td>When set to true, log events will not wait to try to reconnect and will fail immediately if the
+              socket is not available.</td>
+            </tr>
+            <tr>
+              <td>immediateFlush</td>
+              <td>boolean</td>
+              <td>When set to true - the default, each write will be followed by a flush.
+                This will guarantee the data is written
+                to disk but could impact performance.</td>
+            </tr>
+            <tr>
+              <td>layout</td>
+              <td>Layout</td>
+              <td>The Layout to use to format the LogEvent. The default is SerializedLayout.</td>
+            </tr>
+            <tr>
+              <td>name</td>
+              <td>String</td>
+              <td>The name of the Appender.</td>
+            </tr>
+            <tr>
+              <td>port</td>
+              <td>integer</td>
+              <td>The port on the host that is listening for log events. This parameter must be specified.</td>
+            </tr>
+            <tr>
+              <td>protocol</td>
+              <td>String</td>
+              <td>"TLS" is the only value supported and is optional.</td>
+            </tr>
+            <tr>
+              <td>reconnectionDelay</td>
+              <td>integer</td>
+              <td>If set to a value greater than 0, after an error the SocketManager will attempt to reconnect to
+                the server after waiting the specified number of milliseconds. If the reconnect fails then
+                an exception will be thrown (which can be caught by the application if <code>ignoreExceptions</code> is
+                set to <code>false</code>).</td>
+            </tr>
+            <tr>
+              <td>ignoreExceptions</td>
+              <td>boolean</td>
+              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
+                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
+                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
+                <a href="#FailoverAppender">FailoverAppender</a>.</td>
+            </tr>
+          </table>
+
+          <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp" packages="">
+  <Appenders>
+    <Socket name="socket" host="localhost" port="9500">
+      <SerializedLayout />
+      <SSL>
+        <KeyStore location="log4j2-keystore.jks" password="changeme"/>
+        <TrustStore location="truststore.jks" password="changeme"/>
+      </SSL>
+    </Socket>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="socket"/>
+    </Root>
+  </Loggers>
+</Configuration>]]></pre>
+        </subsection>
         <a name="SyslogAppender"/>
         <subsection name="SyslogAppender">
           <p>
-            The SyslogAppender is a SocketAppender that writes its output to a remote destination
+            The <code>SyslogAppender</code> is a <code>SocketAppender</code> that writes its output to a remote destination
             specified by a host and port in a format that conforms with either the BSD Syslog format or the RFC 5424
             format. The data can be sent over either TCP or UDP.
           </p>
           <table>
-            <caption align="top">SyslogAppender Parameters</caption>
+            <caption align="top"><code>SyslogAppender</code> Parameters</caption>
             <tr>
               <th>Parameter Name</th>
               <th>Type</th>
@@ -3018,7 +3121,7 @@ public class JpaLogEntity extends Abstra
             </tr>
           </table>
           <p>
-            A sample syslogAppender configuration that is configured with two SyslogAppenders, one using the BSD
+            A sample syslogAppender configuration that is configured with two <code>SyslogAppender</code>s, one using the BSD
             format and one using RFC 5424.
           </p>
 
@@ -3044,12 +3147,12 @@ public class JpaLogEntity extends Abstra
         <a name="TLSSyslogAppender"/>
         <subsection name="TLSSyslogAppender">
           <p>
-            The TLSSyslogAppender is a SocketAppender that writes its output to a remote destination
+            The <code>TLSSyslogAppender</code> is a <code>SocketAppender</code> that writes its output to a remote destination
             specified by a host and port over SSL in a format that conforms with either the BSD Syslog format or the
             RFC 5424 format. The data can be sent over either TCP or UDP.
           </p>
           <table>
-            <caption align="top">SyslogAppender Parameters</caption>
+            <caption align="top"><code>SyslogAppender</code> Parameters</caption>
             <tr>
               <th>Parameter Name</th>
               <th>Type</th>