mirror of https://github.com/apache/lucene.git
SOLR-3854: Allows the test harness to perform two-way SSL handshakes, the two-way SSL will now be randomly selected during test runs. Also, cleaned up some of the code by breaking out the SSLConfig into a separate class. Also try and address failing the statics retained check.
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1566515 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fcfc592785
commit
f5a1519069
|
@ -18,16 +18,14 @@
|
|||
package org.apache.solr.client.solrj.embedded;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.net.URL;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
|
@ -200,15 +198,6 @@ public class JettySolrRunner {
|
|||
this.init(solrHome, context, port, stopAtShutdown);
|
||||
}
|
||||
|
||||
public static class SSLConfig {
|
||||
public boolean useSsl;
|
||||
public boolean clientAuth;
|
||||
public String keyStore;
|
||||
public String keyStorePassword;
|
||||
public String trustStore;
|
||||
public String trustStorePassword;
|
||||
}
|
||||
|
||||
private void init(String solrHome, String context, int port, boolean stopAtShutdown) {
|
||||
this.context = context;
|
||||
server = new Server(port);
|
||||
|
@ -232,7 +221,7 @@ public class JettySolrRunner {
|
|||
// the server as well as any client actions taken by this JVM in
|
||||
// talking to that server, but for the purposes of testing that should
|
||||
// be good enough
|
||||
final boolean useSsl = sslConfig == null ? false : sslConfig.useSsl;
|
||||
final boolean useSsl = sslConfig == null ? false : sslConfig.isSSLMode();
|
||||
final SslContextFactory sslcontext = new SslContextFactory(false);
|
||||
sslInit(useSsl, sslcontext);
|
||||
|
||||
|
@ -356,20 +345,20 @@ public class JettySolrRunner {
|
|||
|
||||
private void sslInit(final boolean useSsl, final SslContextFactory sslcontext) {
|
||||
if (useSsl && sslConfig != null) {
|
||||
if (null != sslConfig.keyStore) {
|
||||
sslcontext.setKeyStorePath(sslConfig.keyStore);
|
||||
if (null != sslConfig.getKeyStore()) {
|
||||
sslcontext.setKeyStorePath(sslConfig.getKeyStore());
|
||||
}
|
||||
if (null != sslConfig.keyStorePassword) {
|
||||
sslcontext.setKeyStorePassword(sslConfig.keyStorePassword);
|
||||
if (null != sslConfig.getKeyStorePassword()) {
|
||||
sslcontext.setKeyStorePassword(sslConfig.getKeyStorePassword());
|
||||
}
|
||||
if (null != sslConfig.trustStore) {
|
||||
if (null != sslConfig.getTrustStore()) {
|
||||
sslcontext.setTrustStore(System
|
||||
.getProperty(sslConfig.trustStore));
|
||||
.getProperty(sslConfig.getTrustStore()));
|
||||
}
|
||||
if (null != sslConfig.trustStorePassword) {
|
||||
sslcontext.setTrustStorePassword(sslConfig.trustStorePassword);
|
||||
if (null != sslConfig.getTrustStorePassword()) {
|
||||
sslcontext.setTrustStorePassword(sslConfig.getTrustStorePassword());
|
||||
}
|
||||
sslcontext.setNeedClientAuth(sslConfig.clientAuth);
|
||||
sslcontext.setNeedClientAuth(sslConfig.isClientAuthMode());
|
||||
} else {
|
||||
boolean jettySsl = Boolean.getBoolean(System.getProperty("tests.jettySsl"));
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package org.apache.solr.client.solrj.embedded;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
public class SSLConfig {
|
||||
|
||||
private boolean useSsl;
|
||||
private boolean clientAuth;
|
||||
private String keyStore;
|
||||
private String keyStorePassword;
|
||||
private String trustStore;
|
||||
private String trustStorePassword;
|
||||
|
||||
public SSLConfig(boolean useSSL, boolean clientAuth, String keyStore, String keyStorePassword, String trustStore, String trustStorePassword) {
|
||||
this.useSsl = useSSL;
|
||||
this.clientAuth = clientAuth;
|
||||
this.keyStore = keyStore;
|
||||
this.keyStorePassword = keyStorePassword;
|
||||
this.trustStore = trustStore;
|
||||
this.trustStorePassword = trustStorePassword;
|
||||
}
|
||||
|
||||
public void setUseSSL(boolean useSSL) {
|
||||
this.useSsl = useSSL;
|
||||
}
|
||||
|
||||
public void setClientAuth(boolean clientAuth) {
|
||||
this.clientAuth = clientAuth;
|
||||
}
|
||||
|
||||
public boolean isSSLMode() {
|
||||
return useSsl;
|
||||
}
|
||||
|
||||
public boolean isClientAuthMode() {
|
||||
return clientAuth;
|
||||
}
|
||||
|
||||
public String getKeyStore() {
|
||||
return keyStore;
|
||||
}
|
||||
|
||||
public String getKeyStorePassword() {
|
||||
return keyStorePassword;
|
||||
}
|
||||
|
||||
public String getTrustStore() {
|
||||
return trustStore;
|
||||
}
|
||||
|
||||
public String getTrustStorePassword() {
|
||||
return trustStorePassword;
|
||||
}
|
||||
}
|
|
@ -45,7 +45,8 @@ public class OverseerRolesTest extends AbstractFullDistribZkTestBase{
|
|||
private CloudSolrServer client;
|
||||
|
||||
static {
|
||||
sslConfig = null;
|
||||
// SSL does not work with this feature for some reason
|
||||
ALLOW_SSL = false;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
|
|
@ -102,7 +102,7 @@ public class TestReplicationHandler extends SolrTestCaseJ4 {
|
|||
|
||||
static {
|
||||
// does not yet work with ssl
|
||||
sslConfig = null;
|
||||
ALLOW_SSL = false;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
|
|
@ -70,8 +70,8 @@ public class DistributedDebugComponentTest extends SolrJettyTestBase {
|
|||
|
||||
String urlCollection1 = jetty.getBaseUrl().toString() + "/" + "collection1";
|
||||
String urlCollection2 = jetty.getBaseUrl().toString() + "/" + "collection2";
|
||||
shard1 = urlCollection1.replaceAll("http" + (sslConfig == null || !sslConfig.useSsl ? "" : "s") + "://", "");
|
||||
shard2 = urlCollection2.replaceAll("http" + (sslConfig == null || !sslConfig.useSsl ? "" : "s") + "://", "");
|
||||
shard1 = urlCollection1.replaceAll("https?://", "");
|
||||
shard2 = urlCollection2.replaceAll("https?://", "");
|
||||
|
||||
//create second core
|
||||
CoreAdminRequest.Create req = new CoreAdminRequest.Create();
|
||||
|
|
|
@ -50,8 +50,8 @@ public class TestRemoteStreaming extends SolrJettyTestBase {
|
|||
private static final File solrHomeDirectory = new File(TEMP_DIR, "TestRemoteStreaming");
|
||||
|
||||
static {
|
||||
// does not yet work with ssl
|
||||
sslConfig = null;
|
||||
// does not yet work with ssl - uses raw URL
|
||||
ALLOW_SSL = false;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
|
|
@ -40,11 +40,6 @@ import com.google.common.base.Charsets;
|
|||
*/
|
||||
public class CacheHeaderTest extends CacheHeaderTestBase {
|
||||
private static final File solrHomeDirectory = new File(TEMP_DIR, "CacheHeaderTest");
|
||||
|
||||
static {
|
||||
// does not yet work with ssl
|
||||
sslConfig = null;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeTest() throws Exception {
|
||||
|
|
|
@ -62,7 +62,7 @@ public class SolrCmdDistributorTest extends BaseDistributedSearchTestCase {
|
|||
|
||||
static {
|
||||
// no ssl currently because distrib updates read scheme from zk and no zk in this test
|
||||
sslConfig = null;
|
||||
ALLOW_SSL = false;
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.apache.solr.common.SolrException.ErrorCode;
|
|||
import org.apache.solr.common.params.CommonParams;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.solr.util.ExternalPaths;
|
||||
import org.apache.solr.util.SSLTestConfig;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -506,8 +507,8 @@ public class BasicHttpSolrServerTest extends SolrJettyTestBase {
|
|||
|
||||
/**
|
||||
* A trivial test that verifies the example keystore used for SSL testing can be
|
||||
* found using the base class. this helps future-proof against hte possibility of
|
||||
* something moving/breaking thekeystore path in a way that results in the SSL
|
||||
* found using the base class. this helps future-proof against the possibility of
|
||||
* something moving/breaking the keystore path in a way that results in the SSL
|
||||
* randomization logic being forced to silently never use SSL. (We can't enforce
|
||||
* this type of check in the base class because then it would not be usable by client
|
||||
* code depending on the test framework
|
||||
|
@ -516,7 +517,7 @@ public class BasicHttpSolrServerTest extends SolrJettyTestBase {
|
|||
assertNotNull("Example keystore is null, meaning that something has changed in the " +
|
||||
"structure of the example configs and/or ExternalPaths.java - " +
|
||||
"SSL randomization is broken",
|
||||
getExampleKeystoreFile());
|
||||
SSLTestConfig.TEST_KEYSTORE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,9 +24,7 @@ import org.apache.commons.io.FileUtils;
|
|||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
|
||||
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
|
||||
import org.apache.solr.client.solrj.embedded.JettySolrRunner.SSLConfig;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
import org.apache.solr.util.ExternalPaths;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
|
|
@ -24,10 +24,6 @@ import java.io.IOException;
|
|||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
@ -46,11 +42,6 @@ import javax.xml.xpath.XPathExpressionException;
|
|||
|
||||
import org.apache.commons.codec.Charsets;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.lucene.analysis.MockAnalyzer;
|
||||
import org.apache.lucene.analysis.MockTokenizer;
|
||||
import org.apache.lucene.index.IndexWriterConfig;
|
||||
|
@ -58,7 +49,6 @@ import org.apache.lucene.util.IOUtils;
|
|||
import org.apache.lucene.util.LuceneTestCase;
|
||||
import org.apache.lucene.util.QuickPatchThreadsFilter;
|
||||
import org.apache.lucene.util._TestUtil;
|
||||
import org.apache.solr.client.solrj.embedded.JettySolrRunner.SSLConfig;
|
||||
import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
|
||||
import org.apache.solr.client.solrj.impl.HttpClientUtil;
|
||||
import org.apache.solr.client.solrj.util.ClientUtils;
|
||||
|
@ -89,8 +79,8 @@ import org.apache.solr.schema.SchemaField;
|
|||
import org.apache.solr.search.SolrIndexSearcher;
|
||||
import org.apache.solr.servlet.DirectSolrConnection;
|
||||
import org.apache.solr.util.AbstractSolrTestCase;
|
||||
import org.apache.solr.util.ExternalPaths;
|
||||
import org.apache.solr.util.RevertDefaultThreadHandlerRule;
|
||||
import org.apache.solr.util.SSLTestConfig;
|
||||
import org.apache.solr.util.TestHarness;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
|
@ -123,7 +113,10 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
private static String coreName = ConfigSolrXmlOld.DEFAULT_DEFAULT_CORE_NAME;
|
||||
public static int DEFAULT_CONNECTION_TIMEOUT = 45000; // default socket connection timeout in ms
|
||||
|
||||
protected static volatile SSLConfig sslConfig = new SSLConfig();
|
||||
// these are meant to be accessed sequentially, but are volatile just to ensure any test
|
||||
// thread will read the latest value
|
||||
protected static volatile boolean ALLOW_SSL = true;
|
||||
protected static volatile SSLTestConfig sslConfig;
|
||||
|
||||
@ClassRule
|
||||
public static TestRule solrClassRules =
|
||||
|
@ -146,31 +139,13 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
startTrackingZkClients();
|
||||
ignoreException("ignore_exception");
|
||||
newRandomConfig();
|
||||
sslConfig = getSSLConfig();
|
||||
|
||||
|
||||
if(sslConfig != null && sslConfig.useSsl) {
|
||||
sslConfig = buildSSLConfig();
|
||||
//will use ssl specific or default depending on sslConfig
|
||||
HttpClientUtil.setConfigurer(sslConfig.getHttpClientConfigurer());
|
||||
if(isSSLMode()) {
|
||||
// SolrCloud tests should usually clear this
|
||||
System.setProperty("urlScheme", "https");
|
||||
|
||||
// Turn off two-way SSL since it isn't configured below...
|
||||
sslConfig.clientAuth = false;
|
||||
HttpClientUtil.setConfigurer(new HttpClientConfigurer(){
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void configure(DefaultHttpClient httpClient, SolrParams config) {
|
||||
super.configure(httpClient, config);
|
||||
SchemeRegistry registry = httpClient.getConnectionManager().getSchemeRegistry();
|
||||
// Make sure no tests cheat by using HTTP
|
||||
registry.unregister("http");
|
||||
try {
|
||||
// Don't complain that we are using self-signed certs during the test
|
||||
registry.register(new Scheme("https", 443, new SSLSocketFactory(new TrustSelfSignedStrategy())));
|
||||
} catch (KeyManagementException | UnrecoverableKeyException
|
||||
| NoSuchAlgorithmException | KeyStoreException ex) {
|
||||
throw new IllegalStateException("Unable to setup https scheme for HTTPClient to test SSL.", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,41 +164,16 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
System.clearProperty("useCompoundFile");
|
||||
System.clearProperty("urlScheme");
|
||||
|
||||
if(sslConfig != null && sslConfig.useSsl) {
|
||||
if(isSSLMode()) {
|
||||
HttpClientUtil.setConfigurer(new HttpClientConfigurer());
|
||||
}
|
||||
|
||||
// clean up static
|
||||
sslConfig = null;
|
||||
IpTables.unblockAllPorts();
|
||||
}
|
||||
|
||||
private static File TEST_KEYSTORE;
|
||||
static {
|
||||
TEST_KEYSTORE = (null == ExternalPaths.SOURCE_HOME)
|
||||
? null : new File(ExternalPaths.SOURCE_HOME, "example/etc/solrtest.keystore");
|
||||
}
|
||||
|
||||
protected boolean isSSLMode() {
|
||||
return sslConfig != null && sslConfig.useSsl;
|
||||
}
|
||||
|
||||
private static void initSSLConfig(SSLConfig sslConfig, String keystorePath) {
|
||||
sslConfig.useSsl = false;
|
||||
sslConfig.clientAuth = false;
|
||||
sslConfig.keyStore = keystorePath;
|
||||
sslConfig.keyStorePassword = "secret";
|
||||
sslConfig.trustStore = keystorePath;
|
||||
sslConfig.trustStorePassword = "secret";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the File object for the example keystore used when this baseclass randomly
|
||||
* uses SSL. May be null ifthis test does not appear to be running as part of the
|
||||
* standard solr distribution and does not have access to the example configs.
|
||||
*
|
||||
* @lucene.internal
|
||||
*/
|
||||
protected static File getExampleKeystoreFile() {
|
||||
return TEST_KEYSTORE;
|
||||
protected static boolean isSSLMode() {
|
||||
return sslConfig != null && sslConfig.isSSLMode();
|
||||
}
|
||||
|
||||
private static boolean changedFactory = false;
|
||||
|
@ -252,38 +202,19 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
private static SSLConfig getSSLConfig() {
|
||||
// test has disabled
|
||||
if (sslConfig == null) {
|
||||
SSLConfig sslConfig = new SSLConfig();
|
||||
return sslConfig;
|
||||
private static SSLTestConfig buildSSLConfig() {
|
||||
// test has been disabled
|
||||
if (!ALLOW_SSL) {
|
||||
return new SSLTestConfig();
|
||||
}
|
||||
|
||||
// only randomize SSL if we are a solr test with access to the example keystore
|
||||
if (null == getExampleKeystoreFile()) {
|
||||
log.info("Solr's example keystore not defined (not a solr test?) skipping SSL randomization");
|
||||
return null;
|
||||
}
|
||||
|
||||
assertTrue("test keystore does not exist, randomized ssl testing broken: " +
|
||||
getExampleKeystoreFile().getAbsolutePath(),
|
||||
getExampleKeystoreFile().exists() );
|
||||
|
||||
SSLConfig sslConfig = new SSLConfig();
|
||||
|
||||
final boolean trySsl = random().nextBoolean();
|
||||
final boolean trySslClientAuth = false; // TODO: random().nextBoolean();
|
||||
final boolean trySslClientAuth = random().nextBoolean();
|
||||
|
||||
log.info("Randomized ssl ({}) and clientAuth ({})", trySsl,
|
||||
trySslClientAuth);
|
||||
String keystorePath = null == TEST_KEYSTORE ? null : TEST_KEYSTORE
|
||||
.getAbsolutePath();
|
||||
initSSLConfig(sslConfig, keystorePath);
|
||||
|
||||
sslConfig.useSsl = trySsl;
|
||||
sslConfig.clientAuth = trySslClientAuth;
|
||||
|
||||
return sslConfig;
|
||||
return new SSLTestConfig(trySsl, trySslClientAuth);
|
||||
}
|
||||
|
||||
protected static MockTokenizer whitespaceMockTokenizer(Reader input) throws IOException {
|
||||
|
|
|
@ -41,13 +41,11 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.http.params.CoreConnectionPNames;
|
||||
import org.apache.lucene.util.LuceneTestCase.Slow;
|
||||
import org.apache.solr.SolrJettyTestBase;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.SolrRequest;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
|
||||
import org.apache.solr.client.solrj.embedded.JettySolrRunner.SSLConfig;
|
||||
import org.apache.solr.client.solrj.impl.CloudSolrServer;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
import org.apache.solr.client.solrj.request.QueryRequest;
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.apache.solr.common.params.MultiMapSolrParams;
|
|||
import org.apache.solr.common.util.StrUtils;
|
||||
import org.apache.solr.servlet.SolrRequestParsers;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.BeforeClass;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.SAXException;
|
||||
|
@ -38,11 +37,6 @@ abstract public class RestTestBase extends SolrJettyTestBase {
|
|||
private static final Logger log = LoggerFactory.getLogger(RestTestBase.class);
|
||||
protected static RestTestHarness restTestHarness;
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
// sslConfig = null;
|
||||
}
|
||||
|
||||
public static void createJettyAndHarness
|
||||
(String solrHome, String configFile, String schemaFile, String context,
|
||||
boolean stopAtShutdown, SortedMap<ServletHolder,String> extraServlets) throws Exception {
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package org.apache.solr.util;
|
||||
|
||||
/*
|
||||
* 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.io.File;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||
import org.apache.http.conn.ssl.SSLContexts;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.solr.client.solrj.embedded.SSLConfig;
|
||||
import org.apache.solr.client.solrj.impl.HttpClientConfigurer;
|
||||
import org.apache.solr.common.params.SolrParams;
|
||||
import org.eclipse.jetty.util.security.CertificateUtils;
|
||||
|
||||
public class SSLTestConfig extends SSLConfig {
|
||||
public static File TEST_KEYSTORE = ExternalPaths.SOURCE_HOME == null ? null
|
||||
: new File(ExternalPaths.SOURCE_HOME, "example/etc/solrtest.keystore");
|
||||
|
||||
private static String TEST_KEYSTORE_PATH = TEST_KEYSTORE != null
|
||||
&& TEST_KEYSTORE.exists() ? TEST_KEYSTORE.getAbsolutePath() : null;
|
||||
private static String TEST_KEYSTORE_PASSWORD = "secret";
|
||||
private static HttpClientConfigurer DEFAULT_CONFIGURER = new HttpClientConfigurer();
|
||||
|
||||
public SSLTestConfig() {
|
||||
this(false, false);
|
||||
}
|
||||
|
||||
public SSLTestConfig(boolean useSSL, boolean clientAuth) {
|
||||
super(useSSL, clientAuth, TEST_KEYSTORE_PATH, TEST_KEYSTORE_PASSWORD, TEST_KEYSTORE_PATH, TEST_KEYSTORE_PASSWORD);
|
||||
}
|
||||
|
||||
public SSLTestConfig(boolean useSSL, boolean clientAuth, String keyStore, String keyStorePassword, String trustStore, String trustStorePassword) {
|
||||
super(useSSL, clientAuth, keyStore, keyStorePassword, trustStore, trustStorePassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will provide an HttpClientConfigurer for SSL support (adds https and
|
||||
* removes http schemes) is SSL is enabled, otherwise return the default
|
||||
* configurer
|
||||
*/
|
||||
public HttpClientConfigurer getHttpClientConfigurer() {
|
||||
return isSSLMode() ? new SSLHttpClientConfigurer() : DEFAULT_CONFIGURER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new SSLContext with the given configuration and allows the uses of
|
||||
* self-signed certificates during testing.
|
||||
*/
|
||||
protected SSLContext buildSSLContext() throws KeyManagementException,
|
||||
UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException {
|
||||
|
||||
return SSLContexts.custom()
|
||||
.loadKeyMaterial(buildKeyStore(getKeyStore(), getKeyStorePassword()), getKeyStorePassword().toCharArray())
|
||||
.loadTrustMaterial(buildKeyStore(getTrustStore(), getTrustStorePassword()), new TrustSelfSignedStrategy()).build();
|
||||
}
|
||||
|
||||
|
||||
protected static KeyStore buildKeyStore(String keyStoreLocation, String password) {
|
||||
try {
|
||||
return CertificateUtils.getKeyStore(null, keyStoreLocation, "JKS", null, password);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException("Unable to build KeyStore from file: " + keyStoreLocation, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private class SSLHttpClientConfigurer extends HttpClientConfigurer {
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void configure(DefaultHttpClient httpClient, SolrParams config) {
|
||||
super.configure(httpClient, config);
|
||||
SchemeRegistry registry = httpClient.getConnectionManager().getSchemeRegistry();
|
||||
// Make sure no tests cheat by using HTTP
|
||||
registry.unregister("http");
|
||||
try {
|
||||
registry.register(new Scheme("https", 443, new SSLSocketFactory(buildSSLContext())));
|
||||
} catch (KeyManagementException | UnrecoverableKeyException
|
||||
| NoSuchAlgorithmException | KeyStoreException ex) {
|
||||
throw new IllegalStateException("Unable to setup https scheme for HTTPClient to test SSL.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void cleanStatics() {
|
||||
DEFAULT_CONFIGURER = null;
|
||||
TEST_KEYSTORE = null;
|
||||
TEST_KEYSTORE_PASSWORD = null;
|
||||
TEST_KEYSTORE_PATH = null;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue