On Mon, Sep 25, 2017 at 10:00 AM, <[email protected]> wrote: > Repository: logging-log4j2 > Updated Branches: > refs/heads/master a73fce2e7 -> 08077cba3 > > > LOG4J2-2054 Provide ways to configure SSL that avoid plain-text passwords > in the log4j configuration. The configuration may now specify a system > environment variable that holds the password, or the path to a file that > holds the password. > > > Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo > Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/ > commit/08077cba > Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/08077cba > Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/08077cba > > Branch: refs/heads/master > Commit: 08077cba385ee376aa44ae33c66833421e9d19bc > Parents: a73fce2 > Author: rpopma <[email protected]> > Authored: Tue Sep 26 01:00:15 2017 +0900 > Committer: rpopma <[email protected]> > Committed: Tue Sep 26 01:00:15 2017 +0900 > > ---------------------------------------------------------------------- > .../net/ssl/EnvironmentPasswordProvider.java | 54 ++++++ > .../core/net/ssl/FilePasswordProvider.java | 83 +++++++++ > .../core/net/ssl/KeyStoreConfiguration.java | 58 +++++-- > .../core/net/ssl/MemoryPasswordProvider.java | 20 ++- > .../core/net/ssl/TrustStoreConfiguration.java | 57 ++++-- > .../log4j/core/appender/HttpAppenderTest.java | 6 +- > .../SecureSocketAppenderSocketOptionsTest.java | 8 +- > .../core/appender/TlsSyslogAppenderTest.java | 4 +- > .../ssl/EnvironmentPasswordProviderTest.java | 38 ++++ > .../core/net/ssl/FilePasswordProviderTest.java | 50 ++++++ > .../core/net/ssl/KeyStoreConfigurationTest.java | 8 +- > .../net/ssl/MemoryPasswordProviderTest.java | 49 ++++++ > .../core/net/ssl/SslConfigurationTest.java | 16 +- > .../log4j/core/net/ssl/TestConstants.java | 10 +- > .../net/ssl/TrustStoreConfigurationTest.java | 8 +- > src/changes/changes.xml | 3 + > src/site/site.xml | 1 + > src/site/xdoc/manual/appenders.xml | 172 +++++++++++++++++-- > 18 files changed, 580 insertions(+), 65 deletions(-) > ---------------------------------------------------------------------- > > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > EnvironmentPasswordProvider.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/EnvironmentPasswordProvider.java b/log4j-core/src/main/java/ > org/apache/logging/log4j/core/net/ssl/EnvironmentPasswordProvider.java > new file mode 100644 > index 0000000..e501c15 > --- /dev/null > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > EnvironmentPasswordProvider.java > @@ -0,0 +1,54 @@ > +/* > + * 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.ssl; > + > +import java.util.Objects; > + > +/** > + * PasswordProvider implementation that obtains the password value from a > system environment variable. > + * <p> > + * This implementation is not very secure because the Java interface to > obtain system environment variable values > + * requires us to use String objects. String objects are immutable and > Java does not provide a way to erase this > + * sensitive data from the application memory. The password data will > stay resident in memory until the String object > + * and its associated char[] array object are garbage collected and the > memory is overwritten by another object. > + * </p><p> > + * This is slightly more secure than {@link MemoryPasswordProvider} > because the actual password string is not pulled > + * into memory until it is needed (so the password string does not need > to be passed in from the command line or in a > + * configuration file). > + * This gives an attacker a smaller window of opportunity to obtain the > password from a memory dump. > + * </p><p> > + * A more secure implementation is {@link FilePasswordProvider}. > + * </p> > + */ > +class EnvironmentPasswordProvider implements PasswordProvider { > + private final String passwordEnvironmentVariable; > + > + /** > + * Constructs a new EnvironmentPasswordProvider with the specified > environment variable name > + * @param passwordEnvironmentVariable name of the system environment > variable that holds the password > + */ > + public EnvironmentPasswordProvider(final String > passwordEnvironmentVariable) { > + this.passwordEnvironmentVariable = Objects.requireNonNull( > + passwordEnvironmentVariable, > "passwordEnvironmentVariable"); > + } > + > + @Override > + public char[] getPassword() { > + String password = System.getenv(passwordEnvironmentVariable); > + return password.toCharArray(); >
Needs a null check IMO with throws IllegalArgumentException message. Gary > + } > +} > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > FilePasswordProvider.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/FilePasswordProvider.java b/log4j-core/src/main/java/ > org/apache/logging/log4j/core/net/ssl/FilePasswordProvider.java > new file mode 100644 > index 0000000..ff59b00 > --- /dev/null > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/FilePasswordProvider.java > @@ -0,0 +1,83 @@ > +/* > + * 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.ssl; > + > +import java.io.IOException; > +import java.nio.ByteBuffer; > +import java.nio.CharBuffer; > +import java.nio.charset.Charset; > +import java.nio.file.Files; > +import java.nio.file.NoSuchFileException; > +import java.nio.file.Path; > +import java.nio.file.Paths; > +import java.util.Arrays; > + > +/** > + * PasswordProvider that reads password from a file. > + * <p> > + * This is a relatively secure way to handle passwords: > + * <ul> > + * <li>Managing file access privileges can be delegated to the > operating system.</li> > + * <li>The password file can be in a separate location from the > logging configuration. > + * This gives flexibility to have different passwords in different > environments while > + * using the same logging configuration. It also allows for > separation of responsibilities: > + * developers don't need to know the password that is used in the > production environment.</li> > + * <li>There is only a small window of opportunity for attackers to > obtain the password from a memory > + * dump: the password data is only resident in memory from the > moment the caller calls the > + * {@link #getPassword()} method and the password file is read > until the moment that the caller > + * completes authentication and overwrites the password char[] > array.</li> > + * </ul> > + * </p><p> > + * Less secure implementations are {@link MemoryPasswordProvider} and > {@link EnvironmentPasswordProvider}. > + * </p> > + */ > +class FilePasswordProvider implements PasswordProvider { > + private final Path passwordPath; > + > + /** > + * Constructs a new FilePasswordProvider with the specified path. > + * @param passwordFile the path to the password file > + * @throws NoSuchFileException if the password file does not exist > when this FilePasswordProvider is constructed > + */ > + public FilePasswordProvider(final String passwordFile) throws > NoSuchFileException { > + this.passwordPath = Paths.get(passwordFile); > + if (!Files.exists(passwordPath)) { > + throw new NoSuchFileException("PasswordFile '" + > passwordFile + "' does not exist"); > + } > + } > + > + @Override > + public char[] getPassword() { > + byte[] bytes = null; > + try { > + bytes = Files.readAllBytes(passwordPath); > + ByteBuffer bb = ByteBuffer.wrap(bytes); > + CharBuffer decoded = Charset.defaultCharset().decode(bb); > + char[] result = new char[decoded.limit()]; > + decoded.get(result, 0, result.length); > + decoded.rewind(); > + decoded.put(new char[result.length]); // erase decoded > CharBuffer > + return result; > + } catch (IOException e) { > + throw new IllegalStateException("Could not read password from > " + passwordPath + ": " + e, e); > + } finally { > + if (bytes != null) { > + Arrays.fill(bytes, (byte) 0x0); > + } > + } > + } > +} > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > KeyStoreConfiguration.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/KeyStoreConfiguration.java b/log4j-core/src/main/java/ > org/apache/logging/log4j/core/net/ssl/KeyStoreConfiguration.java > index 3fc37bd..d0c7bb0 100644 > --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/KeyStoreConfiguration.java > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/KeyStoreConfiguration.java > @@ -59,6 +59,9 @@ public class KeyStoreConfiguration extends > AbstractKeyStoreConfiguration { > final String keyStoreType, > final String keyManagerFactoryAlgorithm) > throws StoreConfigurationException { > this(location, new MemoryPasswordProvider(password), > keyStoreType, keyManagerFactoryAlgorithm); > + if (password != null) { > + Arrays.fill(password, '\0'); > + } > } > > /** > @@ -92,24 +95,54 @@ public class KeyStoreConfiguration extends > AbstractKeyStoreConfiguration { > // @formatter:off > @PluginAttribute("location") final String location, > @PluginAttribute(value = "password", sensitive = true) final > char[] password, > + @PluginAttribute("passwordEnvironmentVariable") final String > passwordEnvironmentVariable, > + @PluginAttribute("passwordFile") final String passwordFile, > @PluginAttribute("type") final String keyStoreType, > @PluginAttribute("keyManagerFactoryAlgorithm") final String > keyManagerFactoryAlgorithm) throws StoreConfigurationException { > // @formatter:on > - return new KeyStoreConfiguration(location, new > MemoryPasswordProvider(password), keyStoreType, > - keyManagerFactoryAlgorithm); > + > + if (password != null && passwordEnvironmentVariable != null && > passwordFile != null) { > + throw new StoreConfigurationException("You MUST set only one > of 'password', 'passwordEnvironmentVariable' or 'passwordFile'."); > + } > + try { > + // @formatter:off > + PasswordProvider provider = passwordFile != null > + ? new FilePasswordProvider(passwordFile) > + : passwordEnvironmentVariable != null > + ? new EnvironmentPasswordProvider( > passwordEnvironmentVariable) > + // the default is memory char[] array, which > may be null > + : new MemoryPasswordProvider(password); > + // @formatter:on > + if (password != null) { > + Arrays.fill(password, '\0'); > + } > + return new KeyStoreConfiguration(location, provider, > keyStoreType, keyManagerFactoryAlgorithm); > + } catch (Exception ex) { > + throw new StoreConfigurationException("Could not configure > KeyStore", ex); > + } > + } > + > + /** > + * @deprecated use {@link #createKeyStoreConfiguration(String, > char[], String, String, String, String)} > + */ > + public static KeyStoreConfiguration createKeyStoreConfiguration( > + // @formatter:off > + final String location, > + final char[] password, > + final String keyStoreType, > + final String keyManagerFactoryAlgorithm) throws > StoreConfigurationException { > + // @formatter:on > + return createKeyStoreConfiguration(location, password, null, > null, keyStoreType, keyManagerFactoryAlgorithm); > } > > /** > * Creates a KeyStoreConfiguration. > * > - * @param location > - * The location of the KeyStore, a file path, URL or resource. > - * @param password > - * The password to access the KeyStore. > - * @param keyStoreType > - * The KeyStore type, null defaults to {@code "JKS"}. > - * @param keyManagerFactoryAlgorithm > - * The standard name of the requested algorithm. See the Java > Secure Socket Extension Reference Guide for information about these names. > + * @param location The location of the KeyStore, a file path, URL or > resource. > + * @param password The password to access the KeyStore. > + * @param keyStoreType The KeyStore type, null defaults to {@code > "JKS"}. > + * @param keyManagerFactoryAlgorithm The standard name of the > requested algorithm. See the Java Secure Socket > + * Extension Reference Guide for information about these names. > * @return a new KeyStoreConfiguration > * @throws StoreConfigurationException Thrown if this call cannot > load the KeyStore. > * @deprecated Use createKeyStoreConfiguration(String, char[], > String, String) > @@ -122,8 +155,9 @@ public class KeyStoreConfiguration extends > AbstractKeyStoreConfiguration { > final String keyStoreType, > final String keyManagerFactoryAlgorithm) throws > StoreConfigurationException { > // @formatter:on > - return new KeyStoreConfiguration(location, > - new MemoryPasswordProvider(password == null ? null : > password.toCharArray()), keyStoreType, > + return createKeyStoreConfiguration(location, > + (password == null ? null : password.toCharArray()), > + keyStoreType, > keyManagerFactoryAlgorithm); > } > > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > MemoryPasswordProvider.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/MemoryPasswordProvider.java b/log4j-core/src/main/java/ > org/apache/logging/log4j/core/net/ssl/MemoryPasswordProvider.java > index 328728d..6fd7ab4 100644 > --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > MemoryPasswordProvider.java > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > MemoryPasswordProvider.java > @@ -16,14 +16,26 @@ > */ > package org.apache.logging.log4j.core.net.ssl; > > +import java.util.Arrays; > + > /** > - * Simple (and not very secure) PasswordProvider implementation that > keeps the password char[] array in memory. > + * Simple PasswordProvider implementation that keeps the password char[] > array in memory. > + * <p> > + * This implementation is not very secure because the password data is > resident in memory during the life of this > + * provider object, giving attackers a large window of opportunity to > obtain the password from a memory dump. > + * A slightly more secure implementation is {@link > EnvironmentPasswordProvider}, > + * and an even more secure implementation is {@link FilePasswordProvider}. > + * </p> > */ > class MemoryPasswordProvider implements PasswordProvider { > private final char[] password; > > public MemoryPasswordProvider(final char[] chars) { > - password = chars; > + if (chars != null) { > + password = chars.clone(); > + } else { > + password = null; > + } > } > > @Override > @@ -33,4 +45,8 @@ class MemoryPasswordProvider implements PasswordProvider > { > } > return password.clone(); > } > + > + public void clearSecrets() { > + Arrays.fill(password, '\0'); > + } > } > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > TrustStoreConfiguration.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/ > net/ssl/TrustStoreConfiguration.java b/log4j-core/src/main/java/ > org/apache/logging/log4j/core/net/ssl/TrustStoreConfiguration.java > index c472186..d884aed 100644 > --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > TrustStoreConfiguration.java > +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/net/ssl/ > TrustStoreConfiguration.java > @@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.net.ssl; > > import java.security.KeyStoreException; > import java.security.NoSuchAlgorithmException; > +import java.util.Arrays; > > import javax.net.ssl.TrustManagerFactory; > > @@ -50,6 +51,9 @@ public class TrustStoreConfiguration extends > AbstractKeyStoreConfiguration { > public TrustStoreConfiguration(final String location, final char[] > password, final String keyStoreType, > final String trustManagerFactoryAlgorithm) throws > StoreConfigurationException { > this(location, new MemoryPasswordProvider(password), > keyStoreType, trustManagerFactoryAlgorithm); > + if (password != null) { > + Arrays.fill(password, '\0'); > + } > } > > /** > @@ -81,24 +85,54 @@ public class TrustStoreConfiguration extends > AbstractKeyStoreConfiguration { > // @formatter:off > @PluginAttribute("location") final String location, > @PluginAttribute(value = "password", sensitive = true) final > char[] password, > + @PluginAttribute("passwordEnvironmentVariable") final String > passwordEnvironmentVariable, > + @PluginAttribute("passwordFile") final String passwordFile, > @PluginAttribute("type") final String keyStoreType, > @PluginAttribute("trustManagerFactoryAlgorithm") final > String trustManagerFactoryAlgorithm) throws StoreConfigurationException { > // @formatter:on > - return new TrustStoreConfiguration(location, new > MemoryPasswordProvider(password), keyStoreType, > - trustManagerFactoryAlgorithm); > + > + if (password != null && passwordEnvironmentVariable != null && > passwordFile != null) { > + throw new IllegalStateException("You MUST set only one of > 'password', 'passwordEnvironmentVariable' or 'passwordFile'."); > + } > + try { > + // @formatter:off > + PasswordProvider provider = passwordFile != null > + ? new FilePasswordProvider(passwordFile) > + : passwordEnvironmentVariable != null > + ? new EnvironmentPasswordProvider( > passwordEnvironmentVariable) > + // the default is memory char[] array, which > may be null > + : new MemoryPasswordProvider(password); > + // @formatter:on > + if (password != null) { > + Arrays.fill(password, '\0'); > + } > + return new TrustStoreConfiguration(location, provider, > keyStoreType, trustManagerFactoryAlgorithm); > + } catch (Exception ex) { > + throw new StoreConfigurationException("Could not configure > TrustStore", ex); > + } > + } > + > + /** > + * @deprecated Use {@link #createKeyStoreConfiguration(String, > char[], String, String, String, String)} > + */ > + public static TrustStoreConfiguration createKeyStoreConfiguration( > + // @formatter:off > + final String location, > + final char[] password, > + final String keyStoreType, > + final String trustManagerFactoryAlgorithm) throws > StoreConfigurationException { > + // @formatter:on > + return createKeyStoreConfiguration(location, password, null, > null, keyStoreType, trustManagerFactoryAlgorithm); > } > > /** > * Creates a KeyStoreConfiguration. > * > - * @param location > - * The location of the KeyStore, a file path, URL or resource. > - * @param password > - * The password to access the KeyStore. > - * @param keyStoreType > - * The KeyStore type, null defaults to {@code "JKS"}. > - * @param trustManagerFactoryAlgorithm > - * The standard name of the requested trust management > algorithm. See the Java Secure Socket Extension Reference Guide for > information these names. > + * @param location The location of the KeyStore, a file path, URL or > resource. > + * @param password The password to access the KeyStore. > + * @param keyStoreType The KeyStore type, null defaults to {@code > "JKS"}. > + * @param trustManagerFactoryAlgorithm The standard name of the > requested trust management algorithm. See the Java > + * Secure Socket Extension Reference Guide for information these > names. > * @return a new TrustStoreConfiguration > * @throws StoreConfigurationException Thrown if this instance cannot > load the KeyStore. > * @deprecated Use createKeyStoreConfiguration(String, char[], > String, String) > @@ -111,7 +145,8 @@ public class TrustStoreConfiguration extends > AbstractKeyStoreConfiguration { > final String keyStoreType, > final String trustManagerFactoryAlgorithm) throws > StoreConfigurationException { > // @formatter:on > - return new TrustStoreConfiguration(location, password, > keyStoreType, trustManagerFactoryAlgorithm); > + return createKeyStoreConfiguration(location, (password == null ? > null : password.toCharArray()), > + null, null, keyStoreType, trustManagerFactoryAlgorithm); > } > > public TrustManagerFactory initTrustManagerFactory() throws > NoSuchAlgorithmException, KeyStoreException { > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > HttpAppenderTest.java > ---------------------------------------------------------------------- > diff --git > a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/HttpAppenderTest.java > b/log4j-core/src/test/java/org/apache/logging/log4j/core/ > appender/HttpAppenderTest.java > index 337a0c0..c50c8ce 100644 > --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > appender/HttpAppenderTest.java > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/ > appender/HttpAppenderTest.java > @@ -82,7 +82,7 @@ public class HttpAppenderTest { > @Rule > public WireMockRule wireMockRule = new WireMockRule(wireMockConfig(). > dynamicPort().dynamicHttpsPort() > .keystorePath(TestConstants.KEYSTORE_FILE) > - .keystorePassword(String.valueOf(TestConstants.KEYSTORE_PWD)) > + .keystorePassword(String.valueOf(TestConstants.KEYSTORE_PWD())) > .keystoreType(TestConstants.KEYSTORE_TYPE)); > > @Test > @@ -115,8 +115,8 @@ public class HttpAppenderTest { > .setConfiguration(ctx.getConfiguration()) > .setUrl(new URL("https://localhost:" + > wireMockRule.httpsPort() + "/test/log4j/")) > .setSslConfiguration(SslConfiguration. > createSSLConfiguration(null, > - > KeyStoreConfiguration.createKeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD, TestConstants.KEYSTORE_TYPE, null), > - > TrustStoreConfiguration.createKeyStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD, TestConstants.TRUSTSTORE_TYPE, null))) > + > KeyStoreConfiguration.createKeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD(), TestConstants.KEYSTORE_TYPE, null), > + > TrustStoreConfiguration.createKeyStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD(), TestConstants.TRUSTSTORE_TYPE, null))) > .setVerifyHostname(false) > .build(); > appender.append(createLogEvent()); > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > SecureSocketAppenderSocketOptionsTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > appender/SecureSocketAppenderSocketOptionsTest.java > b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > SecureSocketAppenderSocketOptionsTest.java > index b92e393..abee218 100644 > --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > SecureSocketAppenderSocketOptionsTest.java > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > SecureSocketAppenderSocketOptionsTest.java > @@ -75,13 +75,17 @@ public class SecureSocketAppenderSocketOptionsTest { > public static void initServerSocketFactory() throws > StoreConfigurationException { > final KeyStoreConfiguration ksc = KeyStoreConfiguration. > createKeyStoreConfiguration( > TestConstants.KEYSTORE_FILE, // file > - TestConstants.KEYSTORE_PWD, // password > + TestConstants.KEYSTORE_PWD(), // password > + null, // passwordEnvironmentVariable > + null, // passwordFile > null, // key store type > null); // algorithm > > final TrustStoreConfiguration tsc = TrustStoreConfiguration. > createKeyStoreConfiguration( > TestConstants.TRUSTSTORE_FILE, // file > - TestConstants.TRUSTSTORE_PWD, // password > + TestConstants.TRUSTSTORE_PWD(), // password > + null, // passwordEnvironmentVariable > + null, // passwordFile > null, // key store type > null); // algorithm > sslConfiguration = SslConfiguration.createSSLConfiguration(null, > ksc, tsc); > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > TlsSyslogAppenderTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > appender/TlsSyslogAppenderTest.java b/log4j-core/src/test/java/ > org/apache/logging/log4j/core/appender/TlsSyslogAppenderTest.java > index e025fd8..ae567a0 100644 > --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > TlsSyslogAppenderTest.java > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/ > TlsSyslogAppenderTest.java > @@ -78,8 +78,8 @@ public class TlsSyslogAppenderTest extends > SyslogAppenderTest { > } > > private void initServerSocketFactory() throws > StoreConfigurationException { > - final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD, null, null); > - final TrustStoreConfiguration tsc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD, null, null); > + final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD(), null, null); > + final TrustStoreConfiguration tsc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD(), null, null); > sslConfiguration = SslConfiguration.createSSLConfiguration(null, > ksc, tsc); > serverSocketFactory = sslConfiguration. > getSslServerSocketFactory(); > } > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > EnvironmentPasswordProviderTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/EnvironmentPasswordProviderTest.java b/log4j-core/src/test/java/ > org/apache/logging/log4j/core/net/ssl/EnvironmentPasswordProviderTest.java > new file mode 100644 > index 0000000..a9b266f > --- /dev/null > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > EnvironmentPasswordProviderTest.java > @@ -0,0 +1,38 @@ > +package org.apache.logging.log4j.core.net.ssl;/* > + * 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. > + */ > + > +import org.junit.Test; > + > +import static org.junit.Assert.*; > + > +public class EnvironmentPasswordProviderTest { > + > + @Test(expected = NullPointerException.class) > + public void testConstructorDisallowsNull() { > + new EnvironmentPasswordProvider(null); > + } > + > + @Test > + public void testGetPasswordReturnsEnvironmentVariableValue() { > + final String value = System.getenv("PATH"); > + if (value == null) { > + return; // we cannot test in this environment > + } > + final char[] actual = new EnvironmentPasswordProvider(" > PATH").getPassword(); > + assertArrayEquals(value.toCharArray(), actual); > + } > +} > \ No newline at end of file > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > FilePasswordProviderTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/FilePasswordProviderTest.java b/log4j-core/src/test/java/ > org/apache/logging/log4j/core/net/ssl/FilePasswordProviderTest.java > new file mode 100644 > index 0000000..eaa2d82 > --- /dev/null > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > FilePasswordProviderTest.java > @@ -0,0 +1,50 @@ > +package org.apache.logging.log4j.core.net.ssl;/* > + * 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. > + */ > + > +import java.nio.charset.Charset; > +import java.nio.file.Files; > +import java.nio.file.NoSuchFileException; > +import java.nio.file.Path; > +import java.util.Arrays; > + > +import org.junit.Test; > + > +import static org.junit.Assert.*; > + > +public class FilePasswordProviderTest { > + > + @Test > + public void testGetPassword() throws Exception { > + final String PASSWORD = "myPass123"; > + final Path path = Files.createTempFile("testPass", ".txt"); > + Files.write(path, PASSWORD.getBytes(Charset.defaultCharset())); > + > + char[] actual = new FilePasswordProvider(path. > toString()).getPassword(); > + Files.delete(path); > + assertArrayEquals(PASSWORD.toCharArray(), actual); > + } > + > + @Test(expected = NullPointerException.class) > + public void testConstructorDisallowsNull() throws Exception { > + new FilePasswordProvider(null); > + } > + > + @Test(expected = NoSuchFileException.class) > + public void testConstructorFailsIfFileDoesNotExist() throws > Exception { > + new FilePasswordProvider("nosuchfile"); > + } > +} > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > KeyStoreConfigurationTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/KeyStoreConfigurationTest.java b/log4j-core/src/test/java/ > org/apache/logging/log4j/core/net/ssl/KeyStoreConfigurationTest.java > index ef38483..d5761ac 100644 > --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > KeyStoreConfigurationTest.java > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > KeyStoreConfigurationTest.java > @@ -37,7 +37,7 @@ public class KeyStoreConfigurationTest { > > @Test > public void loadNotEmptyConfigurationDeprecated() throws > StoreConfigurationException { > - final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD, > + final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD(), > TestConstants.KEYSTORE_TYPE, null); > final KeyStore ks = ksc.getKeyStore(); > Assert.assertTrue(ks != null); > @@ -45,7 +45,7 @@ public class KeyStoreConfigurationTest { > > @Test > public void loadNotEmptyConfiguration() throws > StoreConfigurationException { > - final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD), > + final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD()), > TestConstants.KEYSTORE_TYPE, null); > final KeyStore ks = ksc.getKeyStore(); > Assert.assertTrue(ks != null); > @@ -53,7 +53,7 @@ public class KeyStoreConfigurationTest { > > @Test > public void returnTheSameKeyStoreAfterMultipleLoadsDeprecated() > throws StoreConfigurationException { > - final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD, > + final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > TestConstants.KEYSTORE_PWD(), > TestConstants.KEYSTORE_TYPE, null); > final KeyStore ks = ksc.getKeyStore(); > final KeyStore ks2 = ksc.getKeyStore(); > @@ -62,7 +62,7 @@ public class KeyStoreConfigurationTest { > > @Test > public void returnTheSameKeyStoreAfterMultipleLoads() throws > StoreConfigurationException { > - final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD), > + final KeyStoreConfiguration ksc = new > KeyStoreConfiguration(TestConstants.KEYSTORE_FILE, > new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD()), > TestConstants.KEYSTORE_TYPE, null); > final KeyStore ks = ksc.getKeyStore(); > final KeyStore ks2 = ksc.getKeyStore(); > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > MemoryPasswordProviderTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/MemoryPasswordProviderTest.java b/log4j-core/src/test/java/ > org/apache/logging/log4j/core/net/ssl/MemoryPasswordProviderTest.java > new file mode 100644 > index 0000000..df4b5f2 > --- /dev/null > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > MemoryPasswordProviderTest.java > @@ -0,0 +1,49 @@ > +package org.apache.logging.log4j.core.net.ssl;/* > + * 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. > + */ > + > +import java.util.Arrays; > + > +import org.junit.Test; > + > +import static org.junit.Assert.*; > + > +public class MemoryPasswordProviderTest { > + @Test > + public void testConstructorAllowsNull() { > + assertEquals(null, new MemoryPasswordProvider(null). > getPassword()); > + } > + > + @Test > + public void testConstructorDoesNotModifyOriginalParameterArray() { > + char[] initial = "123".toCharArray(); > + new MemoryPasswordProvider(initial); > + assertArrayEquals("123".toCharArray(), initial); > + } > + > + @Test > + public void testGetPasswordReturnsCopyOfConstructorArray() { > + char[] initial = "123".toCharArray(); > + MemoryPasswordProvider provider = new MemoryPasswordProvider( > initial); > + char[] actual = provider.getPassword(); > + assertArrayEquals("123".toCharArray(), actual); > + assertNotSame(initial, actual); > + > + Arrays.fill(initial, 'a'); > + assertArrayEquals("123".toCharArray(), provider.getPassword()); > + assertNotSame(provider.getPassword(), provider.getPassword()); > + } > +} > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > SslConfigurationTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/SslConfigurationTest.java b/log4j-core/src/test/java/ > org/apache/logging/log4j/core/net/ssl/SslConfigurationTest.java > index 936cc66..41349a0 100644 > --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/SslConfigurationTest.java > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/SslConfigurationTest.java > @@ -33,33 +33,33 @@ public class SslConfigurationTest { > > public static SslConfiguration > createTestSslConfigurationResourcesDeprecated() > throws StoreConfigurationException { > final KeyStoreConfiguration ksc = new KeyStoreConfiguration( > TestConstants.KEYSTORE_FILE_RESOURCE, > - TestConstants.KEYSTORE_PWD, TestConstants.KEYSTORE_TYPE, > null); > + TestConstants.KEYSTORE_PWD(), > TestConstants.KEYSTORE_TYPE, null); > final TrustStoreConfiguration tsc = new TrustStoreConfiguration( > TestConstants.TRUSTSTORE_FILE_RESOURCE, > - TestConstants.TRUSTSTORE_PWD, null, null); > + TestConstants.TRUSTSTORE_PWD(), null, null); > return SslConfiguration.createSSLConfiguration(null, ksc, tsc); > } > > public static SslConfiguration createTestSslConfigurationResources() > throws StoreConfigurationException { > final KeyStoreConfiguration ksc = new KeyStoreConfiguration( > TestConstants.KEYSTORE_FILE_RESOURCE, > - new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD), > TestConstants.KEYSTORE_TYPE, null); > + new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD()), > TestConstants.KEYSTORE_TYPE, null); > final TrustStoreConfiguration tsc = new TrustStoreConfiguration( > TestConstants.TRUSTSTORE_FILE_RESOURCE, > - new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), > null, null); > + new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD()), > null, null); > return SslConfiguration.createSSLConfiguration(null, ksc, tsc); > } > > public static SslConfiguration > createTestSslConfigurationFilesDeprecated() > throws StoreConfigurationException { > final KeyStoreConfiguration ksc = new KeyStoreConfiguration( > TestConstants.KEYSTORE_FILE, > - TestConstants.KEYSTORE_PWD, TestConstants.KEYSTORE_TYPE, > null); > + TestConstants.KEYSTORE_PWD(), > TestConstants.KEYSTORE_TYPE, null); > final TrustStoreConfiguration tsc = new TrustStoreConfiguration( > TestConstants.TRUSTSTORE_FILE, > - TestConstants.TRUSTSTORE_PWD, null, null); > + TestConstants.TRUSTSTORE_PWD(), null, null); > return SslConfiguration.createSSLConfiguration(null, ksc, tsc); > } > > public static SslConfiguration createTestSslConfigurationFiles() > throws StoreConfigurationException { > final KeyStoreConfiguration ksc = new KeyStoreConfiguration( > TestConstants.KEYSTORE_FILE, > - new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD), > TestConstants.KEYSTORE_TYPE, null); > + new MemoryPasswordProvider(TestConstants.KEYSTORE_PWD()), > TestConstants.KEYSTORE_TYPE, null); > final TrustStoreConfiguration tsc = new TrustStoreConfiguration( > TestConstants.TRUSTSTORE_FILE, > - new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), > null, null); > + new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD()), > null, null); > return SslConfiguration.createSSLConfiguration(null, ksc, tsc); > } > > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/ > core/net/ssl/TestConstants.java > ---------------------------------------------------------------------- > diff --git > a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/TestConstants.java > b/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/TestConstants.java > index 1fa8572..90b3bed 100644 > --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/TestConstants.java > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/TestConstants.java > @@ -17,24 +17,24 @@ > package org.apache.logging.log4j.core.net.ssl; > > public class TestConstants { > - > + > public static final String SOURCE_FOLDER = "src/test/resources/"; > public static final String RESOURCE_ROOT = "org/apache/logging/log4j/ > core/net/ssl/"; > - > + > public static final String PATH = SOURCE_FOLDER + RESOURCE_ROOT; > public static final String TRUSTSTORE_PATH = PATH; > public static final String TRUSTSTORE_RESOURCE = RESOURCE_ROOT; > public static final String TRUSTSTORE_FILE = TRUSTSTORE_PATH + > "truststore.jks"; > public static final String TRUSTSTORE_FILE_RESOURCE = > TRUSTSTORE_RESOURCE + "truststore.jks"; > - public static final char[] TRUSTSTORE_PWD = "changeit".toCharArray(); > + public static final char[] TRUSTSTORE_PWD() { return > "changeit".toCharArray(); } > public static final String TRUSTSTORE_TYPE = "JKS"; > > public static final String KEYSTORE_PATH = PATH; > public static final String KEYSTORE_RESOURCE = RESOURCE_ROOT; > public static final String KEYSTORE_FILE = KEYSTORE_PATH + > "client.log4j2-keystore.jks"; > public static final String KEYSTORE_FILE_RESOURCE = KEYSTORE_RESOURCE > + "client.log4j2-keystore.jks"; > - public static final char[] KEYSTORE_PWD = "changeit".toCharArray(); > + public static final char[] KEYSTORE_PWD() { return > "changeit".toCharArray(); } > public static final String KEYSTORE_TYPE = "JKS"; > - > + > public static final char[] NULL_PWD = null; > } > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > TrustStoreConfigurationTest.java > ---------------------------------------------------------------------- > diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/ > net/ssl/TrustStoreConfigurationTest.java b/log4j-core/src/test/java/ > org/apache/logging/log4j/core/net/ssl/TrustStoreConfigurationTest.java > index 14c58bb..d27a1fd 100644 > --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > TrustStoreConfigurationTest.java > +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/net/ssl/ > TrustStoreConfigurationTest.java > @@ -37,21 +37,21 @@ public class TrustStoreConfigurationTest { > > @Test > public void loadConfigurationDeprecated() throws > StoreConfigurationException { > - final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD, null, null); > + final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD(), null, null); > final KeyStore ks = ksc.getKeyStore(); > Assert.assertNotNull(ks); > } > > @Test > public void loadConfiguration() throws StoreConfigurationException { > - final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), null, null); > + final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD()), null, null); > final KeyStore ks = ksc.getKeyStore(); > Assert.assertNotNull(ks); > } > > @Test > public void returnTheSameKeyStoreAfterMultipleLoadsDeprecated() > throws StoreConfigurationException { > - final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD, null, null); > + final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > TestConstants.TRUSTSTORE_PWD(), null, null); > final KeyStore ks = ksc.getKeyStore(); > final KeyStore ks2 = ksc.getKeyStore(); > Assert.assertTrue(ks == ks2); > @@ -59,7 +59,7 @@ public class TrustStoreConfigurationTest { > > @Test > public void returnTheSameKeyStoreAfterMultipleLoads() throws > StoreConfigurationException { > - final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD), null, null); > + final TrustStoreConfiguration ksc = new > TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE, > new MemoryPasswordProvider(TestConstants.TRUSTSTORE_PWD()), null, null); > final KeyStore ks = ksc.getKeyStore(); > final KeyStore ks2 = ksc.getKeyStore(); > Assert.assertTrue(ks == ks2); > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/src/changes/changes.xml > ---------------------------------------------------------------------- > diff --git a/src/changes/changes.xml b/src/changes/changes.xml > index 55b18f9..94b1033 100644 > --- a/src/changes/changes.xml > +++ b/src/changes/changes.xml > @@ -31,6 +31,9 @@ > - "remove" - Removed > --> > <release version="2.9.2" date="2017-XX-XX" description="GA Release > 2.9.2"> > + <action issue="LOG4J2-2054" dev="rpopma" type="add"> > + Provide ways to configure SSL that avoid plain-text passwords in > the log4j configuration. The configuration may now specify a system > environment variable that holds the password, or the path to a file that > holds the password. > + </action> > <action issue="LOG4J2-2057" dev="rgoers" type="update"> > Support new SLF4J binding mechanism introduced in SLF4J 1.8. > </action> > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/src/site/site.xml > ---------------------------------------------------------------------- > diff --git a/src/site/site.xml b/src/site/site.xml > index dca832a..6de65be 100644 > --- a/src/site/site.xml > +++ b/src/site/site.xml > @@ -147,6 +147,7 @@ > <item name="SMTP" href="/manual/appenders.html#SMTPAppender"/> > <item name="ScriptAppenderSelector" href="/manual/appenders.html# > ScriptAppenderSelector"/> > <item name="Socket" href="/manual/appenders.html# > SocketAppender"/> > + <item name="SSL" href="/manual/appenders.html#SSL"/> > <item name="Syslog" href="/manual/appenders.html# > SyslogAppender"/> > <item name="ZeroMQ/JeroMQ" href="/manual/appenders.html# > JeroMQAppender"/> > </item> > > http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/ > 08077cba/src/site/xdoc/manual/appenders.xml > ---------------------------------------------------------------------- > diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/ > appenders.xml > index c4982c0..b9ef28a 100644 > --- a/src/site/xdoc/manual/appenders.xml > +++ b/src/site/xdoc/manual/appenders.xml > @@ -1658,7 +1658,7 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > <td>Ssl</td> > <td>SslConfiguration</td> > <td>Contains the configuration for the KeyStore and > TrustStore for https. > - Optional, uses Java runtime defaults if not > specified.</td> > + Optional, uses Java runtime defaults if not specified. > See <a href="#SSL">SSL</a></td> > </tr> > <tr> > <td>verifyHostname</td> > @@ -1710,8 +1710,8 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > <Property name="X-Java-Runtime" value="$${java:runtime}" /> > <JsonLayout properties="true"/> > <SSL> > - <KeyStore location="log4j2-keystore.jks" password="changeme"/> > - <TrustStore location="truststore.jks" password="changeme"/> > + <KeyStore location="log4j2-keystore.jks" > passwordEnvironmentVariable="KEYSTORE_PASSWORD"/> > + <TrustStore location="truststore.jks" > passwordFile="${sys:user.home}/truststore.pwd"/> > </SSL> > </Http> > </Appenders>]]></pre> > @@ -4355,7 +4355,7 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > <p> > 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. > - You can optionally secure communication with SSL. > + You can optionally secure communication with <a > href="#SSL">SSL</a>. > </p> > <table> > <caption align="top"><code>SocketAppender</code> > Parameters</caption> > @@ -4387,7 +4387,7 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > <tr> > <td>SSL</td> > <td>SslConfiguration</td> > - <td>Contains the configuration for the KeyStore and > TrustStore.</td> > + <td>Contains the configuration for the KeyStore and > TrustStore. See <a href="#SSL">SSL</a>.</td> > </tr> > <tr> > <td>filter</td> > @@ -4467,7 +4467,7 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > </Configuration>]]></pre> > > <p> > - This is a secured SSL configuration: > + This is a secured <a href="#SSL">SSL</a> configuration: > </p> > <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" > encoding="UTF-8"?> > <Configuration status="warn" name="MyApp" packages=""> > @@ -4475,8 +4475,8 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > <Socket name="socket" host="localhost" port="9500"> > <JsonLayout properties="true"/> > <SSL> > - <KeyStore location="log4j2-keystore.jks" password="changeme"/> > - <TrustStore location="truststore.jks" password="changeme"/> > + <KeyStore location="log4j2-keystore.jks" > passwordEnvironmentVariable="KEYSTORE_PASSWORD"/> > + <TrustStore location="truststore.jks" > passwordFile="${sys:user.home}/truststore.pwd"/> > </SSL> > </Socket> > </Appenders> > @@ -4488,6 +4488,154 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > </Configuration>]]></pre> > > </subsection> > + <a name="SSL" /> > + <subsection name="SSL Configuration"> > + <p> > + Several appenders can be configured to use either a plain > network connection or a Secure Socket Layer (SSL) > + connection. This section documents the parameters available > for SSL configuration. > + </p> > + <table> > + <caption align="top">SSL Configuration Parameters</caption> > + <tr> > + <th>Parameter Name</th> > + <th>Type</th> > + <th>Description</th> > + </tr> > + <tr> > + <td>protocol</td> > + <td>String</td> > + <td><code>SSL</code> if omitted. > + See also <a href="http://docs.oracle.com/ > javase/7/docs/technotes/guides/security/StandardNames.html#SSLContext">Standard > names</a>.</td> > + </tr> > + <tr> > + <td>KeyStore</td> > + <td>KeyStore</td> > + <td>Contains your private keys and certificates, > + and determines which authentication credentials to send to > the remote host.</td> > + </tr> > + <tr> > + <td>TrustStore</td> > + <td>TrustStore</td> > + <td>Contains the CA certificates of the remote counterparty. > + Determines whether the remote authentication credentials > + (and thus the connection) should be trusted.</td> > + </tr> > + </table> > + > + <h4>KeyStore</h4> > + The keystore is meant to contain your private keys and > certificates, > + and determines which authentication credentials to send to the > remote host. > + > + <table> > + <caption align="top">KeyStore Configuration > Parameters</caption> > + <tr> > + <th>Parameter Name</th> > + <th>Type</th> > + <th>Description</th> > + </tr> > + <tr> > + <td>location</td> > + <td>String</td> > + <td>Path to the keystore file.</td> > + </tr> > + <tr> > + <td>password</td> > + <td>char[]</td> > + <td>Plain text password to access the keystore. Cannot be > combined with either > + <code>passwordEnvironmentVariable</code> or > <code>passwordFile</code>.</td> > + </tr> > + <tr> > + <td>passwordEnvironmentVariable</td> > + <td>String</td> > + <td>Name of an environment variable that holds the > password. Cannot be combined with either > + <code>password</code> or <code>passwordFile</code>.</td> > + </tr> > + <tr> > + <td>passwordFile</td> > + <td>String</td> > + <td>Path to a file that holds the password. Cannot be > combined with either > + <code>password</code> or <code> > passwordEnvironmentVariable</code>.</td> > + </tr> > + <tr> > + <td>type</td> > + <td>String</td> > + <td>Optional KeyStore type, e.g. <code>JKS</code>, > <code>PKCS12</code>, <code>PKCS11</code>, > + <code>BKS</code>, <code>Windows-MY/Windows-ROOT</code>, > <code>KeychainStore</code>, etc. > + The default is JKS. See also <a href=" > http://docs.oracle.com/javase/7/docs/technotes/ > guides/security/StandardNames.html#KeyStore">Standard types</a>.</td> > + </tr> > + <tr> > + <td>keyManagerFactoryAlgorithm</td> > + <td>String</td> > + <td>Optional KeyManagerFactory algorithm. The default is > <code>SunX509</code>. > + See also <a href="http://docs.oracle.com/ > javase/7/docs/technotes/guides/security/StandardNames. > html#KeyManagerFactory">Standard algorithms</a>.</td> > + </tr> > + </table> > + > + <h4>TrustStore</h4> > + <p> > + The trust store is meant to contain the CA certificates you > are willing to trust > + when a remote party presents its certificate. Determines > whether the remote authentication credentials > + (and thus the connection) should be trusted. > + </p><p> > + In some cases, they can be one and the same store, > + although it is often better practice to use distinct stores > (especially when they are file-based). > + </p> > + > + <table> > + <caption align="top">TrustStore Configuration > Parameters</caption> > + <tr> > + <th>Parameter Name</th> > + <th>Type</th> > + <th>Description</th> > + </tr> > + <tr> > + <td>location</td> > + <td>String</td> > + <td>Path to the keystore file.</td> > + </tr> > + <tr> > + <td>password</td> > + <td>char[]</td> > + <td>Plain text password to access the keystore. Cannot be > combined with either > + <code>passwordEnvironmentVariable</code> or > <code>passwordFile</code>.</td> > + </tr> > + <tr> > + <td>passwordEnvironmentVariable</td> > + <td>String</td> > + <td>Name of an environment variable that holds the > password. Cannot be combined with either > + <code>password</code> or <code>passwordFile</code>.</td> > + </tr> > + <tr> > + <td>passwordFile</td> > + <td>String</td> > + <td>Path to a file that holds the password. Cannot be > combined with either > + <code>password</code> or <code> > passwordEnvironmentVariable</code>.</td> > + </tr> > + <tr> > + <td>type</td> > + <td>String</td> > + <td>Optional KeyStore type, e.g. <code>JKS</code>, > <code>PKCS12</code>, <code>PKCS11</code>, > + <code>BKS</code>, <code>Windows-MY/Windows-ROOT</code>, > <code>KeychainStore</code>, etc. > + The default is JKS. See also <a href=" > http://docs.oracle.com/javase/7/docs/technotes/ > guides/security/StandardNames.html#KeyStore">Standard types</a>.</td> > + </tr> > + <tr> > + <td>trustManagerFactoryAlgorithm</td> > + <td>String</td> > + <td>Optional TrustManagerFactory algorithm. The default is > <code>SunX509</code>. > + See also <a href="http://docs.oracle.com/ > javase/7/docs/technotes/guides/security/StandardNames. > html#TrustManagerFactory">Standard algorithms</a>.</td> > + </tr> > + </table> > + > + <h4>Example</h4> > + <pre class="prettyprint linenums"><![CDATA[ > + ... > + <SSL> > + <KeyStore location="log4j2-keystore.jks" > passwordEnvironmentVariable="KEYSTORE_PASSWORD"/> > + <TrustStore location="truststore.jks" > passwordFile="${sys:user.home}/truststore.pwd"/> > + </SSL> > + ...]]></pre> > + > + </subsection> > <a name="SyslogAppender"/> > <subsection name="SyslogAppender"> > <p> > @@ -4659,7 +4807,7 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > <tr> > <td>SSL</td> > <td>SslConfiguration</td> > - <td>Contains the configuration for the KeyStore and > TrustStore.</td> > + <td>Contains the configuration for the KeyStore and > TrustStore. See <a href="#SSL">SSL</a>.</td> > </tr> > <tr> > <td>reconnectionDelayMillis</td> > @@ -4695,7 +4843,7 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > </Configuration>]]></pre> > > <p> > - For SSL this appender writes its output to a remote > destination specified by a host and port over SSL in > + For <a href="#SSL">SSL</a> this appender 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. > </p> > > @@ -4704,8 +4852,8 @@ public class JpaLogEntity extends > AbstractLogEventWrapperEntity { > <Appenders> > <TLSSyslog name="bsd" host="localhost" port="6514"> > <SSL> > - <KeyStore location="log4j2-keystore.jks" password="changeme"/> > - <TrustStore location="truststore.jks" password="changeme"/> > + <KeyStore location="log4j2-keystore.jks" > passwordEnvironmentVariable="KEYSTORE_PASSWORD"/> > + <TrustStore location="truststore.jks" > passwordFile="${sys:user.home}/truststore.pwd"/> > </SSL> > </TLSSyslog> > </Appenders> > >
