SSL: make sure SSLService is loaded only when needed

Our two transport impls depend on the SSLService at this point. Although we bind the SSLService only if ssl is enabled, it gets loaded anyway as it's a required dependency for the transports. We need to declare the dependency nullable and bind a null service manually when ssl is off.

Also resolved a couple of compiler warnings in SSLService and renamed some of its variables for better readability.

Closes elastic/elasticsearch#359

Original commit: elastic/x-pack-elasticsearch@2c99b2052e
This commit is contained in:
javanna 2014-11-19 15:24:17 +01:00 committed by Luca Cavanna
parent 50556c120c
commit 34a69cd1cf
4 changed files with 26 additions and 22 deletions

View File

@ -5,6 +5,7 @@
*/ */
package org.elasticsearch.shield.ssl; package org.elasticsearch.shield.ssl;
import org.elasticsearch.common.inject.util.Providers;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.shield.support.AbstractShieldModule; import org.elasticsearch.shield.support.AbstractShieldModule;
@ -21,6 +22,8 @@ public class SSLModule extends AbstractShieldModule {
protected void configure(boolean clientMode) { protected void configure(boolean clientMode) {
if (SSLService.isSSLEnabled(settings)) { if (SSLService.isSSLEnabled(settings)) {
bind(SSLService.class).asEagerSingleton(); bind(SSLService.class).asEagerSingleton();
} else {
bind(SSLService.class).toProvider(Providers.<SSLService>of(null));
} }
} }
} }

View File

@ -27,7 +27,6 @@ public class SSLService extends AbstractComponent {
public static final String SHIELD_TRANSPORT_SSL = "shield.transport.ssl"; public static final String SHIELD_TRANSPORT_SSL = "shield.transport.ssl";
public static final String SHIELD_HTTP_SSL = "shield.http.ssl"; public static final String SHIELD_HTTP_SSL = "shield.http.ssl";
public static final String SHIELD_AUTHC_LDAP_URL = "shield.authc.ldap.url"; public static final String SHIELD_AUTHC_LDAP_URL = "shield.authc.ldap.url";
private final TrustManagerFactory trustFactory;
private final SSLContext sslContext; private final SSLContext sslContext;
private final String[] ciphers; private final String[] ciphers;
@ -35,21 +34,21 @@ public class SSLService extends AbstractComponent {
public SSLService(Settings settings) { public SSLService(Settings settings) {
super(settings); super(settings);
String keyStore = componentSettings.get("keystore", System.getProperty("javax.net.ssl.keyStore")); String keyStorePath = componentSettings.get("keystore", System.getProperty("javax.net.ssl.keyStore"));
String keyStorePassword = componentSettings.get("keystore_password", System.getProperty("javax.net.ssl.keyStorePassword")); String keyStorePassword = componentSettings.get("keystore_password", System.getProperty("javax.net.ssl.keyStorePassword"));
String keyStoreAlgorithm = componentSettings.get("keystore_algorithm", System.getProperty("ssl.KeyManagerFactory.algorithm", KeyManagerFactory.getDefaultAlgorithm())); String keyStoreAlgorithm = componentSettings.get("keystore_algorithm", System.getProperty("ssl.KeyManagerFactory.algorithm", KeyManagerFactory.getDefaultAlgorithm()));
String trustStore = componentSettings.get("truststore", System.getProperty("javax.net.ssl.trustStore")); String trustStorePath = componentSettings.get("truststore", System.getProperty("javax.net.ssl.trustStore"));
String trustStorePassword = componentSettings.get("truststore_password", System.getProperty("javax.net.ssl.trustStorePassword")); String trustStorePassword = componentSettings.get("truststore_password", System.getProperty("javax.net.ssl.trustStorePassword"));
String trustStoreAlgorithm = componentSettings.get("truststore_algorithm", System.getProperty("ssl.TrustManagerFactory.algorithm", TrustManagerFactory.getDefaultAlgorithm())); String trustStoreAlgorithm = componentSettings.get("truststore_algorithm", System.getProperty("ssl.TrustManagerFactory.algorithm", TrustManagerFactory.getDefaultAlgorithm()));
if (trustStore == null) { if (trustStorePath == null) {
//the keystore will also be the truststore //the keystore will also be the truststore
trustStore = keyStore; trustStorePath = keyStorePath;
trustStorePassword = keyStorePassword; trustStorePassword = keyStorePassword;
} }
if (keyStore == null) { if (keyStorePath == null) {
throw new ShieldSettingsException("No keystore configured"); throw new ShieldSettingsException("No keystore configured");
} }
if (keyStorePassword == null) { if (keyStorePassword == null) {
@ -61,30 +60,31 @@ public class SSLService extends AbstractComponent {
String sslProtocol = componentSettings.get("protocol", "TLS"); String sslProtocol = componentSettings.get("protocol", "TLS");
logger.debug("using keyStore[{}], keyAlgorithm[{}], trustStore[{}], truststoreAlgorithm[{}], ciphersuites[{}], TLS protocol[{}]", logger.debug("using keyStore[{}], keyAlgorithm[{}], trustStore[{}], truststoreAlgorithm[{}], ciphersuites[{}], TLS protocol[{}]",
keyStore, keyStoreAlgorithm, trustStore, trustStoreAlgorithm, ciphers, sslProtocol); keyStorePath, keyStoreAlgorithm, trustStorePath, trustStoreAlgorithm, ciphers, sslProtocol);
try (FileInputStream in = new FileInputStream(trustStore)) { final TrustManagerFactory trustFactory;
try (FileInputStream in = new FileInputStream(trustStorePath)) {
// Load TrustStore // Load TrustStore
KeyStore ks = KeyStore.getInstance("jks"); KeyStore trustStore = KeyStore.getInstance("jks");
ks.load(in, trustStorePassword == null ? null : trustStorePassword.toCharArray()); trustStore.load(in, trustStorePassword == null ? null : trustStorePassword.toCharArray());
// Initialize a trust manager factory with the trusted store // Initialize a trust manager factory with the trusted store
trustFactory = TrustManagerFactory.getInstance(trustStoreAlgorithm); trustFactory = TrustManagerFactory.getInstance(trustStoreAlgorithm);
trustFactory.init(ks); trustFactory.init(trustStore);
} catch (Exception e) { } catch (Exception e) {
throw new ElasticsearchException("Failed to initialize a TrustManagerFactory", e); throw new ElasticsearchException("Failed to initialize a TrustManagerFactory", e);
} }
KeyStore ks = null; KeyStore keyStore;
KeyManagerFactory kmf = null; KeyManagerFactory keyManagerFactory;
try (FileInputStream in = new FileInputStream(keyStore)){ try (FileInputStream in = new FileInputStream(keyStorePath)){
// Load KeyStore // Load KeyStore
ks = KeyStore.getInstance("jks"); keyStore = KeyStore.getInstance("jks");
ks.load(in, keyStorePassword.toCharArray()); keyStore.load(in, keyStorePassword.toCharArray());
// Initialize KeyManagerFactory // Initialize KeyManagerFactory
kmf = KeyManagerFactory.getInstance(keyStoreAlgorithm); keyManagerFactory = KeyManagerFactory.getInstance(keyStoreAlgorithm);
kmf.init(ks, keyStorePassword.toCharArray()); keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
} catch (Exception e) { } catch (Exception e) {
throw new ElasticsearchSSLException("Failed to initialize a KeyManagerFactory", e); throw new ElasticsearchSSLException("Failed to initialize a KeyManagerFactory", e);
@ -93,7 +93,7 @@ public class SSLService extends AbstractComponent {
// Initialize sslContext // Initialize sslContext
try { try {
sslContext = SSLContext.getInstance(sslProtocol); sslContext = SSLContext.getInstance(sslProtocol);
sslContext.init(kmf.getKeyManagers(), trustFactory.getTrustManagers(), null); sslContext.init(keyManagerFactory.getKeyManagers(), trustFactory.getTrustManagers(), null);
} catch (Exception e) { } catch (Exception e) {
throw new ElasticsearchSSLException("Failed to initialize the SSLContext", e); throw new ElasticsearchSSLException("Failed to initialize the SSLContext", e);
} }
@ -119,7 +119,6 @@ public class SSLService extends AbstractComponent {
* Http Client-to-Node (inbound): * Http Client-to-Node (inbound):
* - sslEngine.setUserClientMode(false) * - sslEngine.setUserClientMode(false)
* - sslEngine.setNeedClientAuth(false) * - sslEngine.setNeedClientAuth(false)
* @return
*/ */
public SSLEngine createSSLEngine() { public SSLEngine createSSLEngine() {
SSLEngine sslEngine = sslContext.createSSLEngine(); SSLEngine sslEngine = sslContext.createSSLEngine();

View File

@ -29,11 +29,12 @@ public class NettySecuredHttpServerTransport extends NettyHttpServerTransport {
@Inject @Inject
public NettySecuredHttpServerTransport(Settings settings, NetworkService networkService, BigArrays bigArrays, public NettySecuredHttpServerTransport(Settings settings, NetworkService networkService, BigArrays bigArrays,
@Nullable N2NNettyUpstreamHandler shieldUpstreamHandler, SSLService sslService) { @Nullable N2NNettyUpstreamHandler shieldUpstreamHandler, @Nullable SSLService sslService) {
super(settings, networkService, bigArrays); super(settings, networkService, bigArrays);
this.ssl = settings.getAsBoolean("shield.http.ssl", false); this.ssl = settings.getAsBoolean("shield.http.ssl", false);
this.sslService = sslService; this.sslService = sslService;
this.shieldUpstreamHandler = shieldUpstreamHandler; this.shieldUpstreamHandler = shieldUpstreamHandler;
assert !ssl || sslService != null : "ssl is enabled yet the ssl service is null";
} }
@Override @Override

View File

@ -31,11 +31,12 @@ public class NettySecuredTransport extends NettyTransport {
@Inject @Inject
public NettySecuredTransport(Settings settings, ThreadPool threadPool, NetworkService networkService, BigArrays bigArrays, Version version, public NettySecuredTransport(Settings settings, ThreadPool threadPool, NetworkService networkService, BigArrays bigArrays, Version version,
@Nullable N2NNettyUpstreamHandler shieldUpstreamHandler, SSLService sslService) { @Nullable N2NNettyUpstreamHandler shieldUpstreamHandler, @Nullable SSLService sslService) {
super(settings, threadPool, networkService, bigArrays, version); super(settings, threadPool, networkService, bigArrays, version);
this.shieldUpstreamHandler = shieldUpstreamHandler; this.shieldUpstreamHandler = shieldUpstreamHandler;
this.ssl = settings.getAsBoolean("shield.transport.ssl", false); this.ssl = settings.getAsBoolean("shield.transport.ssl", false);
this.sslService = sslService; this.sslService = sslService;
assert !ssl || sslService != null : "ssl is enabled yet the ssl service is null";
} }
@Override @Override