Thanks for reviewing. 
Good catch, a null check is needed to prevent NPEs. 
But null passwords are possible so perhaps make it like this:

return password == null ? null : password.toCharArray();


> On Sep 26, 2017, at 1:08, Gary Gregory <[email protected]> wrote:
> 
>> 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>
>> 
>> 

Reply via email to