From 0fb89f17e1312523a768163db88730b5a0c9191c Mon Sep 17 00:00:00 2001 From: Mark Miller Date: Tue, 16 May 2017 13:59:29 -0300 Subject: [PATCH] SOLR-10307: Allow Passing SSL passwords through environment variables. --- solr/CHANGES.txt | 5 + solr/bin/solr | 34 ++--- solr/bin/solr.cmd | 34 ++--- solr/bin/solr.in.cmd | 3 + solr/bin/solr.in.sh | 3 + .../solr/servlet/SolrDispatchFilter.java | 2 + .../java/org/apache/solr/util/SolrCLI.java | 7 + .../util/configuration/SSLConfigurations.java | 78 +++++++++++ .../SSLConfigurationsFactory.java | 49 +++++++ .../solr/util/configuration/package-info.java | 23 ++++ .../configuration/SSLConfigurationsTest.java | 121 ++++++++++++++++++ solr/server/etc/jetty-ssl.xml | 4 +- 12 files changed, 318 insertions(+), 45 deletions(-) create mode 100644 solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java create mode 100644 solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java create mode 100644 solr/core/src/java/org/apache/solr/util/configuration/package-info.java create mode 100644 solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt index 16c91af094a..85810ab4ec1 100644 --- a/solr/CHANGES.txt +++ b/solr/CHANGES.txt @@ -171,6 +171,11 @@ Jetty 9.3.14.v20161028 Detailed Change List ---------------------- +New Features +---------------------- + +* SOLR-10307: Allow Passing SSL passwords through environment variables. (Mano Kovacs via Mark Miller) + Other Changes ---------------------- diff --git a/solr/bin/solr b/solr/bin/solr index 14d3f59ebb4..621ac96ec8a 100755 --- a/solr/bin/solr +++ b/solr/bin/solr @@ -163,13 +163,20 @@ fi SOLR_URL_SCHEME=http SOLR_JETTY_CONFIG=() SOLR_SSL_OPTS="" -if [ -n "$SOLR_SSL_KEY_STORE" ]; then +if [ -z "$SOLR_SSL_ENABLED" ]; then + if [ -n "$SOLR_SSL_KEY_STORE" ]; then + SOLR_SSL_ENABLED="true" # implicitly from earlier behaviour + else + SOLR_SSL_ENABLED="false" + fi +fi +if [ "$SOLR_SSL_ENABLED" == "true" ]; then SOLR_JETTY_CONFIG+=("--module=https") SOLR_URL_SCHEME=https - SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE" - if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then - SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.password=$SOLR_SSL_KEY_STORE_PASSWORD" + if [ -n "$SOLR_SSL_KEY_STORE" ]; then + SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore=$SOLR_SSL_KEY_STORE" fi + if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then SOLR_SSL_OPTS+=" -Dsolr.jetty.keystore.type=$SOLR_SSL_KEY_STORE_TYPE" fi @@ -177,9 +184,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then if [ -n "$SOLR_SSL_TRUST_STORE" ]; then SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore=$SOLR_SSL_TRUST_STORE" fi - if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then - SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.password=$SOLR_SSL_TRUST_STORE_PASSWORD" - fi if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then SOLR_SSL_OPTS+=" -Dsolr.jetty.truststore.type=$SOLR_SSL_TRUST_STORE_TYPE" fi @@ -194,9 +198,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then if [ -n "$SOLR_SSL_CLIENT_KEY_STORE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_CLIENT_KEY_STORE" - if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD" ]; then - SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStorePassword=$SOLR_SSL_CLIENT_KEY_STORE_PASSWORD" - fi if [ -n "$SOLR_SSL_CLIENT_KEY_STORE_TYPE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_CLIENT_KEY_STORE_TYPE" fi @@ -204,9 +205,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then if [ -n "$SOLR_SSL_KEY_STORE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStore=$SOLR_SSL_KEY_STORE" fi - if [ -n "$SOLR_SSL_KEY_STORE_PASSWORD" ]; then - SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStorePassword=$SOLR_SSL_KEY_STORE_PASSWORD" - fi if [ -n "$SOLR_SSL_KEY_STORE_TYPE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.keyStoreType=$SOLR_SSL_KEYSTORE_TYPE" fi @@ -215,10 +213,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_CLIENT_TRUST_STORE" - if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD" ]; then - SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStorePassword=$SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD" - fi - if [ -n "$SOLR_SSL_CLIENT_TRUST_STORE_TYPE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_CLIENT_TRUST_STORE_TYPE" fi @@ -227,10 +221,6 @@ if [ -n "$SOLR_SSL_KEY_STORE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStore=$SOLR_SSL_TRUST_STORE" fi - if [ -n "$SOLR_SSL_TRUST_STORE_PASSWORD" ]; then - SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStorePassword=$SOLR_SSL_TRUST_STORE_PASSWORD" - fi - if [ -n "$SOLR_SSL_TRUST_STORE_TYPE" ]; then SOLR_SSL_OPTS+=" -Djavax.net.ssl.trustStoreType=$SOLR_SSL_TRUST_STORE_TYPE" fi @@ -1836,7 +1826,7 @@ function launch_solr() { # If SSL-related system props are set, add them to SOLR_OPTS - if [ -n "$SOLR_SSL_OPTS" ]; then + if [ "$SOLR_SSL_ENABLED" ]; then # If using SSL and solr.jetty.https.port not set explicitly, use the jetty.port SSL_PORT_PROP="-Dsolr.jetty.https.port=$SOLR_PORT" SOLR_OPTS+=($SOLR_SSL_OPTS "$SSL_PORT_PROP") diff --git a/solr/bin/solr.cmd b/solr/bin/solr.cmd index 1d093b9b403..820b89f0328 100644 --- a/solr/bin/solr.cmd +++ b/solr/bin/solr.cmd @@ -42,13 +42,21 @@ REM Select HTTP OR HTTPS related configurations set SOLR_URL_SCHEME=http set "SOLR_JETTY_CONFIG=--module=http" set "SOLR_SSL_OPTS= " -IF DEFINED SOLR_SSL_KEY_STORE ( + +IF NOT DEFINED SOLR_SSL_ENABLED ( + IF DEFINED SOLR_SSL_KEY_STORE ( + set "SOLR_SSL_ENABLED=true" + ) ELSE ( + set "SOLR_SSL_ENABLED=false" + ) +) +IF "%SOLR_SSL_ENABLED%"=="true" ( set "SOLR_JETTY_CONFIG=--module=https" set SOLR_URL_SCHEME=https - set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%" - IF DEFINED SOLR_SSL_KEY_STORE_PASSWORD ( - set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.password=%SOLR_SSL_KEY_STORE_PASSWORD%" + IF DEFINED SOLR_SSL_KEY_STORE ( + set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore=%SOLR_SSL_KEY_STORE%" ) + IF DEFINED SOLR_SSL_KEY_STORE_TYPE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.keystore.type=%SOLR_SSL_KEY_STORE_TYPE%" ) @@ -56,9 +64,6 @@ IF DEFINED SOLR_SSL_KEY_STORE ( IF DEFINED SOLR_SSL_TRUST_STORE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore=%SOLR_SSL_TRUST_STORE%" ) - IF DEFINED SOLR_SSL_TRUST_STORE_PASSWORD ( - set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.password=%SOLR_SSL_TRUST_STORE_PASSWORD%" - ) IF DEFINED SOLR_SSL_TRUST_STORE_TYPE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Dsolr.jetty.truststore.type=%SOLR_SSL_TRUST_STORE_TYPE%" ) @@ -73,9 +78,6 @@ IF DEFINED SOLR_SSL_KEY_STORE ( IF DEFINED SOLR_SSL_CLIENT_KEY_STORE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_CLIENT_KEY_STORE%" - IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_PASSWORD ( - set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStorePassword=%SOLR_SSL_CLIENT_KEY_STORE_PASSWORD%" - ) IF DEFINED SOLR_SSL_CLIENT_KEY_STORE_TYPE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_CLIENT_KEY_STORE_TYPE%" ) @@ -83,9 +85,6 @@ IF DEFINED SOLR_SSL_KEY_STORE ( IF DEFINED SOLR_SSL_KEY_STORE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStore=%SOLR_SSL_KEY_STORE%" ) - IF DEFINED SOLR_SSL_KEY_STORE_PASSWORD ( - set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStorePassword=%SOLR_SSL_KEY_STORE_PASSWORD%" - ) IF DEFINED SOLR_SSL_KEY_STORE_TYPE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.keyStoreType=%SOLR_SSL_KEY_STORE_TYPE%" ) @@ -94,10 +93,6 @@ IF DEFINED SOLR_SSL_KEY_STORE ( IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_CLIENT_TRUST_STORE%" - IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD ( - set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStorePassword=%SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD%" - ) - IF DEFINED SOLR_SSL_CLIENT_TRUST_STORE_TYPE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_CLIENT_TRUST_STORE_TYPE%" ) @@ -105,9 +100,6 @@ IF DEFINED SOLR_SSL_KEY_STORE ( IF DEFINED SOLR_SSL_TRUST_STORE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStore=%SOLR_SSL_TRUST_STORE%" ) - IF DEFINED SOLR_SSL_TRUST_STORE_PASSWORD ( - set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStorePassword=%SOLR_SSL_TRUST_STORE_PASSWORD%" - ) IF DEFINED SOLR_SSL_TRUST_STORE_TYPE ( set "SOLR_SSL_OPTS=!SOLR_SSL_OPTS! -Djavax.net.ssl.trustStoreType=%SOLR_SSL_TRUST_STORE_TYPE%" ) @@ -1139,7 +1131,7 @@ IF NOT "%REMOTE_JMX_OPTS%"=="" set "START_OPTS=%START_OPTS% %REMOTE_JMX_OPTS%" IF NOT "%SOLR_ADDL_ARGS%"=="" set "START_OPTS=%START_OPTS% %SOLR_ADDL_ARGS%" IF NOT "%SOLR_HOST_ARG%"=="" set "START_OPTS=%START_OPTS% %SOLR_HOST_ARG%" IF NOT "%SOLR_OPTS%"=="" set "START_OPTS=%START_OPTS% %SOLR_OPTS%" -IF NOT "%SOLR_SSL_OPTS%"=="" ( +IF "%SOLR_SSL_ENABLED%"=="true" ( set "SSL_PORT_PROP=-Dsolr.jetty.https.port=%SOLR_PORT%" set "START_OPTS=%START_OPTS% %SOLR_SSL_OPTS% !SSL_PORT_PROP!" ) diff --git a/solr/bin/solr.in.cmd b/solr/bin/solr.in.cmd index 279e03ec38e..077b68d2f46 100644 --- a/solr/bin/solr.in.cmd +++ b/solr/bin/solr.in.cmd @@ -87,6 +87,9 @@ REM set SOLR_JETTY_HOST=0.0.0.0 REM Sets the port Solr binds to, default is 8983 REM set SOLR_PORT=8983 +REM Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config +REM to enable https module with custom jetty configuration. +REM set SOLR_SSL_ENABLED=true REM Uncomment to set SSL-related system properties REM Be sure to update the paths to the correct keystore for your environment REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks diff --git a/solr/bin/solr.in.sh b/solr/bin/solr.in.sh index 67839f95cf1..6c6c2298eaa 100644 --- a/solr/bin/solr.in.sh +++ b/solr/bin/solr.in.sh @@ -106,6 +106,9 @@ # Sets the port Solr binds to, default is 8983 #SOLR_PORT=8983 +# Enables HTTPS. It is implictly true if you set SOLR_SSL_KEY_STORE. Use this config +# to enable https module with custom jetty configuration. +#SOLR_SSL_ENABLED=true # Uncomment to set SSL-related system properties # Be sure to update the paths to the correct keystore for your environment #SOLR_SSL_KEY_STORE=/home/shalin/work/oss/shalin-lusolr/solr/server/etc/solr-ssl.keystore.jks diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java index 79e476c5e37..e58a3d86da8 100644 --- a/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java +++ b/solr/core/src/java/org/apache/solr/servlet/SolrDispatchFilter.java @@ -73,6 +73,7 @@ import org.apache.solr.request.SolrRequestInfo; import org.apache.solr.security.AuthenticationPlugin; import org.apache.solr.security.PKIAuthenticationPlugin; import org.apache.solr.util.SolrFileCleaningTracker; +import org.apache.solr.util.configuration.SSLConfigurationsFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -139,6 +140,7 @@ public class SolrDispatchFilter extends BaseSolrFilter { @Override public void init(FilterConfig config) throws ServletException { + SSLConfigurationsFactory.current().init(); log.trace("SolrDispatchFilter.init(): {}", this.getClass().getClassLoader()); CoreContainer coresInit = null; try{ diff --git a/solr/core/src/java/org/apache/solr/util/SolrCLI.java b/solr/core/src/java/org/apache/solr/util/SolrCLI.java index aedb9edd22f..833e3b4fd20 100644 --- a/solr/core/src/java/org/apache/solr/util/SolrCLI.java +++ b/solr/core/src/java/org/apache/solr/util/SolrCLI.java @@ -61,6 +61,8 @@ import java.util.stream.Stream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import javax.net.ssl.SSLPeerUnverifiedException; + import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.GnuParser; import org.apache.commons.cli.HelpFormatter; @@ -114,6 +116,7 @@ import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.ContentStreamBase; import org.apache.solr.common.util.NamedList; import org.apache.solr.security.Sha256AuthenticationProvider; +import org.apache.solr.util.configuration.SSLConfigurationsFactory; import org.noggit.CharArr; import org.noggit.JSONParser; import org.noggit.JSONWriter; @@ -253,6 +256,8 @@ public class SolrCLI { exit(0); } + SSLConfigurationsFactory.current().init(); + Tool tool = findTool(args); CommandLine cli = parseCmdLine(args, tool.getOptions()); System.exit(tool.runTool(cli)); @@ -867,6 +872,8 @@ public class SolrCLI { while (System.nanoTime() < timeout) { try { return getStatus(solrUrl); + } catch (SSLPeerUnverifiedException exc) { + throw exc; } catch (Exception exc) { if (exceptionIsAuthRelated(exc)) { throw exc; diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java new file mode 100644 index 00000000000..bfa518659bf --- /dev/null +++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurations.java @@ -0,0 +1,78 @@ +/* + * 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.solr.util.configuration; + +import java.lang.invoke.MethodHandles; +import java.util.Map; + +import org.apache.solr.common.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Dedicated object to handle Solr configurations + */ +public class SSLConfigurations { + private final Map envVars; + + private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); + + public static class SysProps { + public static final String SSL_KEY_STORE_PASSWORD = "javax.net.ssl.keyStorePassword"; + public static final String SSL_TRUST_STORE_PASSWORD = "javax.net.ssl.trustStorePassword"; + } + + public static class EnvVars { + public static final String SOLR_SSL_CLIENT_KEY_STORE_PASSWORD = "SOLR_SSL_CLIENT_KEY_STORE_PASSWORD"; + public static final String SOLR_SSL_KEY_STORE_PASSWORD = "SOLR_SSL_KEY_STORE_PASSWORD"; + public static final String SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD = "SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD"; + public static final String SOLR_SSL_TRUST_STORE_PASSWORD = "SOLR_SSL_TRUST_STORE_PASSWORD"; + } + + /** + * @param envVars Map of environment variables to use + */ + public SSLConfigurations(Map envVars) { + this.envVars = envVars; + } + + /** Initiates javax.net.ssl.* system properties from the proper sources. */ + public void init() { + + String clientKeystorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD); + String keystorePassword = envVars.get(EnvVars.SOLR_SSL_KEY_STORE_PASSWORD); + + String clientTruststorePassword = envVars.get(EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD); + String truststorePassword = envVars.get(EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD); + + if (isEmpty(System.getProperty(SysProps.SSL_KEY_STORE_PASSWORD)) + && !(isEmpty(clientKeystorePassword) && isEmpty(keystorePassword))) { + log.debug("Setting {} based on env var", SysProps.SSL_KEY_STORE_PASSWORD); + System.setProperty(SysProps.SSL_KEY_STORE_PASSWORD, clientKeystorePassword != null ? clientKeystorePassword : keystorePassword); + } + if (isEmpty(System.getProperty(SysProps.SSL_TRUST_STORE_PASSWORD)) + && !(isEmpty(clientTruststorePassword) && isEmpty(truststorePassword))) { + log.debug("Setting {} based on env var", SysProps.SSL_TRUST_STORE_PASSWORD); + System.setProperty(SysProps.SSL_TRUST_STORE_PASSWORD, clientTruststorePassword != null ? clientTruststorePassword : truststorePassword); + } + } + + private boolean isEmpty(String str) { + return StringUtils.isEmpty(str); + } +} diff --git a/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java new file mode 100644 index 00000000000..1da7c019dcf --- /dev/null +++ b/solr/core/src/java/org/apache/solr/util/configuration/SSLConfigurationsFactory.java @@ -0,0 +1,49 @@ +/* + * 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.solr.util.configuration; + +import com.google.common.annotations.VisibleForTesting; + +public class SSLConfigurationsFactory { + static private SSLConfigurations currentConfigurations; + + /** + * Creates if necessary and returns singleton object of Configurations. Can be used for + * static accessor of application-wide instance. + * @return Configurations object + */ + static public SSLConfigurations current() { + if (currentConfigurations == null) { + synchronized (SSLConfigurationsFactory.class) { + if (currentConfigurations == null) { + currentConfigurations = getInstance(); + } + } + } + return currentConfigurations; + } + + private static SSLConfigurations getInstance() { + return new SSLConfigurations(System.getenv()); + } + + @VisibleForTesting + static public synchronized void setCurrent(SSLConfigurations configurations) { + currentConfigurations = configurations; + } +} diff --git a/solr/core/src/java/org/apache/solr/util/configuration/package-info.java b/solr/core/src/java/org/apache/solr/util/configuration/package-info.java new file mode 100644 index 00000000000..68b7db36d04 --- /dev/null +++ b/solr/core/src/java/org/apache/solr/util/configuration/package-info.java @@ -0,0 +1,23 @@ +/* + * 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. + */ + +/** + * Common Util APIs related to Solr configuration. + */ +package org.apache.solr.util.configuration; + + diff --git a/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java b/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java new file mode 100644 index 00000000000..a1d4696489a --- /dev/null +++ b/solr/core/src/test/org/apache/solr/util/configuration/SSLConfigurationsTest.java @@ -0,0 +1,121 @@ +/* + * 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.solr.util.configuration; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.lucene.util.TestRuleRestoreSystemProperties; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class SSLConfigurationsTest { + private Map envs; + private SSLConfigurations sut; + + public static final String SAMPLE_PW1 = "pw123"; + public static final String SAMPLE_PW2 = "pw456"; + public static final String SAMPLE_PW3 = "pw789"; + public static final String KEY_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD; + public static final String TRUST_STORE_PASSWORD = SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD; + + @Rule + public TestRule syspropRestore = new TestRuleRestoreSystemProperties( + SSLConfigurations.SysProps.SSL_KEY_STORE_PASSWORD, + SSLConfigurations.SysProps.SSL_TRUST_STORE_PASSWORD + ); + + @Before + public void setUp() { + envs = new HashMap<>(); + } + + private SSLConfigurations createSut() { + sut = new SSLConfigurations(envs); + return sut; + } + + @Test + public void testSslConfigKeystorePwFromKeystoreEnvVar() { + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1); + createSut().init(); + assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW1)); + } + + @Test + public void testSslConfigKeystorePwFromClientKeystoreEnvVar() { + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2); + createSut().init(); + assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2)); + } + + @Test + public void testSslConfigKeystorePwFromBothEnvVars() { + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1); + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2); + createSut().init(); + assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW2)); + } + + @Test + public void testSslConfigKeystorePwNotOverwrittenIfExists() { + System.setProperty(KEY_STORE_PASSWORD, SAMPLE_PW3); + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_KEY_STORE_PASSWORD, SAMPLE_PW1); + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_KEY_STORE_PASSWORD, SAMPLE_PW2); + createSut().init(); + assertThat(System.getProperty(KEY_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged + } + + + @Test + public void testSslConfigTruststorePwFromKeystoreEnvVar() { + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1); + createSut().init(); + assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW1)); + } + + @Test + public void testSslConfigTruststorePwFromClientKeystoreEnvVar() { + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2); + createSut().init(); + assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2)); + } + + @Test + public void testSslConfigTruststorePwFromBothEnvVars() { + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1); + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2); + createSut().init(); + assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW2)); + } + + @Test + public void testSslConfigTruststorePwNotOverwrittenIfExists() { + System.setProperty(TRUST_STORE_PASSWORD, SAMPLE_PW3); + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_TRUST_STORE_PASSWORD, SAMPLE_PW1); + envs.put(SSLConfigurations.EnvVars.SOLR_SSL_CLIENT_TRUST_STORE_PASSWORD, SAMPLE_PW2); + createSut().init(); + assertThat(System.getProperty(TRUST_STORE_PASSWORD), is(SAMPLE_PW3)); // unchanged + } + +} diff --git a/solr/server/etc/jetty-ssl.xml b/solr/server/etc/jetty-ssl.xml index 4d85de6e8b3..741ac480788 100644 --- a/solr/server/etc/jetty-ssl.xml +++ b/solr/server/etc/jetty-ssl.xml @@ -8,9 +8,9 @@ - + - +