diff --git a/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java b/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java index 1e04560fc8d..92fe59f5ff9 100644 --- a/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java +++ b/shield/src/main/java/org/elasticsearch/shield/ssl/AbstractSSLService.java @@ -24,6 +24,7 @@ import java.io.InputStream; import java.net.InetAddress; import java.net.Socket; import java.nio.file.Files; +import java.nio.file.Path; import java.security.KeyStore; import java.util.ArrayList; import java.util.Arrays; @@ -46,8 +47,8 @@ public abstract class AbstractSSLService extends AbstractComponent { static final int DEFAULT_SESSION_CACHE_SIZE = 1000; static final String DEFAULT_PROTOCOL = "TLSv1.2"; - protected final Environment env; protected final LoadingCache sslContexts = CacheBuilder.newBuilder().build(new SSLContextCacheLoader()); + protected Environment env; public AbstractSSLService(Settings settings, Environment environment) { super(settings); @@ -174,6 +175,10 @@ public abstract class AbstractSSLService extends AbstractComponent { return requestedCiphersList.toArray(new String[requestedCiphersList.size()]); } + protected Path resolvePath(String location) { + return env.configFile().resolve(location); + } + private class SSLContextCacheLoader extends CacheLoader { @Override @@ -238,7 +243,7 @@ public abstract class AbstractSSLService extends AbstractComponent { } private KeyStore readKeystore(String path, String password) throws Exception { - try (InputStream in = Files.newInputStream(env.binFile().getParent().resolve(path))) { + try (InputStream in = Files.newInputStream(resolvePath(path))) { // Load TrustStore KeyStore ks = KeyStore.getInstance("jks"); assert password != null; diff --git a/shield/src/main/java/org/elasticsearch/shield/ssl/ClientSSLService.java b/shield/src/main/java/org/elasticsearch/shield/ssl/ClientSSLService.java index f578e072325..d754efac3dd 100644 --- a/shield/src/main/java/org/elasticsearch/shield/ssl/ClientSSLService.java +++ b/shield/src/main/java/org/elasticsearch/shield/ssl/ClientSSLService.java @@ -5,15 +5,26 @@ */ package org.elasticsearch.shield.ssl; +import org.elasticsearch.common.Strings; +import org.elasticsearch.common.SuppressForbidden; import org.elasticsearch.common.inject.Inject; +import org.elasticsearch.common.io.PathUtils; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; +import java.nio.file.Path; + +@SuppressForbidden(reason = "we don't have the environment to resolve files from when running in a transport client") public class ClientSSLService extends AbstractSSLService { @Inject - public ClientSSLService(Settings settings, Environment environment) { - super(settings, environment); + public ClientSSLService(Settings settings) { + super(settings, null); + } + + @Inject(optional = true) + public void setEnvironment(Environment environment) { + this.env = environment; } @Override @@ -34,4 +45,12 @@ public class ClientSSLService extends AbstractSSLService { return sslSettings; } + + @Override + protected Path resolvePath(String location) { + if (env == null) { + return PathUtils.get(Strings.cleanPath(location)); + } + return super.resolvePath(location); + } } diff --git a/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolverTests.java b/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolverTests.java index 4a0c53ec63b..dfadbdb270b 100644 --- a/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolverTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectoryGroupsResolverTests.java @@ -43,7 +43,8 @@ public class ActiveDirectoryGroupsResolverTests extends ESTestCase { ClientSSLService clientSSLService = new ClientSSLService(Settings.builder() .put("shield.ssl.keystore.path", keystore) .put("shield.ssl.keystore.password", "changeit") - .build(), env); + .build()); + clientSSLService.setEnvironment(env); LDAPURL ldapurl = new LDAPURL(ActiveDirectorySessionFactoryTests.AD_LDAP_URL); LDAPConnectionOptions options = new LDAPConnectionOptions(); diff --git a/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactoryTests.java b/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactoryTests.java index 86c8f935058..2b41dbb69ea 100644 --- a/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactoryTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/authc/activedirectory/ActiveDirectorySessionFactoryTests.java @@ -51,7 +51,8 @@ public class ActiveDirectorySessionFactoryTests extends ESTestCase { clientSSLService = new ClientSSLService(Settings.builder() .put("shield.ssl.keystore.path", keystore) .put("shield.ssl.keystore.password", "changeit") - .build(), env); + .build()); + clientSSLService.setEnvironment(env); globalSettings = Settings.builder().put("path.home", createTempDir()).build(); } diff --git a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactoryTests.java b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactoryTests.java index 4ae330e6d42..45c712a9bf2 100644 --- a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactoryTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/LdapUserSearchSessionFactoryTests.java @@ -63,7 +63,8 @@ public class LdapUserSearchSessionFactoryTests extends LdapTestCase { clientSSLService = new ClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", keystore) .put("shield.ssl.keystore.password", "changeit") - .build(), env); + .build()); + clientSSLService.setEnvironment(env); globalSettings = settingsBuilder().put("path.home", createTempDir()).build(); } diff --git a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/OpenLdapTests.java b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/OpenLdapTests.java index 2e4d000ceb0..3da7919f074 100644 --- a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/OpenLdapTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/OpenLdapTests.java @@ -48,7 +48,8 @@ public class OpenLdapTests extends ESTestCase { clientSSLService = new ClientSSLService(Settings.builder() .put("shield.ssl.keystore.path", keystore) .put("shield.ssl.keystore.password", "changeit") - .build(), env); + .build()); + clientSSLService.setEnvironment(env); globalSettings = Settings.builder().put("path.home", createTempDir()).build(); } diff --git a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolverTests.java b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolverTests.java index 8193e70e9fa..08b2a515b4a 100644 --- a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolverTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/SearchGroupsResolverTests.java @@ -43,7 +43,8 @@ public class SearchGroupsResolverTests extends ESTestCase { ClientSSLService clientSSLService = new ClientSSLService(Settings.builder() .put("shield.ssl.keystore.path", keystore) .put("shield.ssl.keystore.password", "changeit") - .build(), env); + .build()); + clientSSLService.setEnvironment(env); LDAPURL ldapurl = new LDAPURL(OpenLdapTests.OPEN_LDAP_URL); LDAPConnectionOptions options = new LDAPConnectionOptions(); diff --git a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolverTests.java b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolverTests.java index 93412aaad1e..7cf803eda47 100644 --- a/shield/src/test/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolverTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/authc/ldap/UserAttributeGroupsResolverTests.java @@ -41,7 +41,8 @@ public class UserAttributeGroupsResolverTests extends ESTestCase { ClientSSLService clientSSLService = new ClientSSLService(Settings.builder() .put("shield.ssl.keystore.path", keystore) .put("shield.ssl.keystore.password", "changeit") - .build(), env); + .build()); + clientSSLService.setEnvironment(env); LDAPURL ldapurl = new LDAPURL(ActiveDirectorySessionFactoryTests.AD_LDAP_URL); LDAPConnectionOptions options = new LDAPConnectionOptions(); diff --git a/shield/src/test/java/org/elasticsearch/shield/ssl/ClientSSLServiceTests.java b/shield/src/test/java/org/elasticsearch/shield/ssl/ClientSSLServiceTests.java index dfa802586e7..11496d1d2b3 100644 --- a/shield/src/test/java/org/elasticsearch/shield/ssl/ClientSSLServiceTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/ssl/ClientSSLServiceTests.java @@ -34,7 +34,7 @@ public class ClientSSLServiceTests extends ESTestCase { @Before public void setup() throws Exception { testclientStore = getDataPath("/org/elasticsearch/shield/transport/ssl/certs/simple/testclient.jks"); - env = new Environment(settingsBuilder().put("path.home", createTempDir()).build()); + env = randomBoolean() ? new Environment(settingsBuilder().put("path.home", createTempDir()).build()) : null; } @Test @@ -46,7 +46,7 @@ public class ClientSSLServiceTests extends ESTestCase { .put("shield.ssl.keystore.password", "testclient") .put("shield.ssl.truststore.path", testclientStore) .put("shield.ssl.truststore.password", "testclient") - .build(), env).createSSLEngine(); + .build()).createSSLEngine(); fail("expected an exception"); } catch (ElasticsearchException e) { assertThat(e.getMessage(), containsString("failed to initialize the SSLContext")); @@ -57,10 +57,10 @@ public class ClientSSLServiceTests extends ESTestCase { public void testThatCustomTruststoreCanBeSpecified() throws Exception { Path testnodeStore = getDataPath("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode.jks"); - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") - .build(), env); + .build()); Settings.Builder settingsBuilder = settingsBuilder() .put("truststore.path", testnodeStore) @@ -75,10 +75,10 @@ public class ClientSSLServiceTests extends ESTestCase { @Test public void testThatSslContextCachingWorks() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") - .build(), env); + .build()); SSLContext sslContext = sslService.sslContext(); SSLContext cachedSslContext = sslService.sslContext(); @@ -89,21 +89,21 @@ public class ClientSSLServiceTests extends ESTestCase { @Test public void testThatKeyStoreAndKeyCanHaveDifferentPasswords() throws Exception { Path differentPasswordsStore = getDataPath("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode-different-passwords.jks"); - new ClientSSLService(settingsBuilder() + createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", differentPasswordsStore) .put("shield.ssl.keystore.password", "testnode") .put("shield.ssl.keystore.key_password", "testnode1") - .build(), env).createSSLEngine(); + .build()).createSSLEngine(); } @Test public void testIncorrectKeyPasswordThrowsException() throws Exception { Path differentPasswordsStore = getDataPath("/org/elasticsearch/shield/transport/ssl/certs/simple/testnode-different-passwords.jks"); try { - new ClientSSLService(settingsBuilder() + createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", differentPasswordsStore) .put("shield.ssl.keystore.password", "testnode") - .build(), env).createSSLEngine(); + .build()).createSSLEngine(); fail("expected an exception"); } catch (ElasticsearchException e) { assertThat(e.getMessage(), containsString("failed to initialize a KeyManagerFactory")); @@ -112,20 +112,20 @@ public class ClientSSLServiceTests extends ESTestCase { @Test public void testThatSSLv3IsNotEnabled() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") - .build(), env); + .build()); SSLEngine engine = sslService.createSSLEngine(); assertThat(Arrays.asList(engine.getEnabledProtocols()), not(hasItem("SSLv3"))); } @Test public void testThatSSLSessionCacheHasDefaultLimits() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") - .build(), env); + .build()); SSLSessionContext context = sslService.sslContext().getServerSessionContext(); assertThat(context.getSessionCacheSize(), equalTo(1000)); assertThat(context.getSessionTimeout(), equalTo((int) TimeValue.timeValueHours(24).seconds())); @@ -133,12 +133,12 @@ public class ClientSSLServiceTests extends ESTestCase { @Test public void testThatSettingSSLSessionCacheLimitsWorks() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") .put("shield.ssl.session.cache_size", "300") .put("shield.ssl.session.cache_timeout", "600s") - .build(), env); + .build()); SSLSessionContext context = sslService.sslContext().getServerSessionContext(); assertThat(context.getSessionCacheSize(), equalTo(300)); assertThat(context.getSessionTimeout(), equalTo(600)); @@ -146,27 +146,27 @@ public class ClientSSLServiceTests extends ESTestCase { @Test public void testThatCreateClientSSLEngineWithoutAnySettingsWorks() throws Exception { - ClientSSLService sslService = new ClientSSLService(Settings.EMPTY, env); + ClientSSLService sslService = createClientSSLService(Settings.EMPTY); SSLEngine sslEngine = sslService.createSSLEngine(); assertThat(sslEngine, notNullValue()); } @Test public void testThatCreateSSLEngineWithOnlyTruststoreWorks() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.truststore.path", testclientStore) .put("shield.ssl.truststore.password", "testclient") - .build(), env); + .build()); SSLEngine sslEngine = sslService.createSSLEngine(); assertThat(sslEngine, notNullValue()); } @Test public void testThatCreateSSLEngineWithOnlyKeystoreWorks() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") - .build(), env); + .build()); SSLEngine sslEngine = sslService.createSSLEngine(); assertThat(sslEngine, notNullValue()); } @@ -174,7 +174,7 @@ public class ClientSSLServiceTests extends ESTestCase { @Test @Network public void testThatSSLContextWithoutSettingsWorks() throws Exception { - ClientSSLService sslService = new ClientSSLService(Settings.EMPTY, env); + ClientSSLService sslService = createClientSSLService(Settings.EMPTY); SSLContext sslContext = sslService.sslContext(); try (CloseableHttpClient client = HttpClients.custom().setSslcontext(sslContext).build()) { // Execute a GET on a site known to have a valid certificate signed by a trusted public CA @@ -187,10 +187,10 @@ public class ClientSSLServiceTests extends ESTestCase { @Test @Network public void testThatSSLContextWithKeystoreDoesNotTrustAllPublicCAs() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") - .build(), env); + .build()); SSLContext sslContext = sslService.sslContext(); try (CloseableHttpClient client = HttpClients.custom().setSslcontext(sslContext).build()) { // Execute a GET on a site known to have a valid certificate signed by a trusted public CA @@ -205,17 +205,17 @@ public class ClientSSLServiceTests extends ESTestCase { @Test(expected = IllegalArgumentException.class) public void testThatTruststorePasswordIsRequired() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.truststore.path", testclientStore) - .build(), env); + .build()); sslService.sslContext(); } @Test(expected = IllegalArgumentException.class) public void testThatKeystorePasswordIsRequired() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) - .build(), env); + .build()); sslService.sslContext(); } @@ -224,9 +224,9 @@ public class ClientSSLServiceTests extends ESTestCase { List ciphers = new ArrayList<>(Arrays.asList(AbstractSSLService.DEFAULT_CIPHERS)); ciphers.add("foo"); ciphers.add("bar"); - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .putArray("shield.ssl.ciphers", ciphers.toArray(new String[ciphers.size()])) - .build(), env); + .build()); SSLEngine engine = sslService.createSSLEngine(); assertThat(engine, is(notNullValue())); String[] enabledCiphers = engine.getEnabledCipherSuites(); @@ -235,18 +235,18 @@ public class ClientSSLServiceTests extends ESTestCase { @Test(expected = IllegalArgumentException.class) public void invalidCiphersOnlyThrowsException() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .putArray("shield.ssl.ciphers", new String[] { "foo", "bar" }) - .build(), env); + .build()); sslService.createSSLEngine(); } @Test public void testThatSSLSocketFactoryHasProperCiphersAndProtocols() throws Exception { - ClientSSLService sslService = new ClientSSLService(settingsBuilder() + ClientSSLService sslService = createClientSSLService(settingsBuilder() .put("shield.ssl.keystore.path", testclientStore) .put("shield.ssl.keystore.password", "testclient") - .build(), env); + .build()); SSLSocketFactory factory = sslService.sslSocketFactory(); assertThat(factory.getDefaultCipherSuites(), is(sslService.ciphers())); @@ -255,4 +255,10 @@ public class ClientSSLServiceTests extends ESTestCase { assertThat(socket.getEnabledProtocols(), is(sslService.supportedProtocols())); } } + + ClientSSLService createClientSSLService(Settings settings) { + ClientSSLService clientSSLService = new ClientSSLService(settings); + clientSSLService.setEnvironment(env); + return clientSSLService; + } } diff --git a/shield/src/test/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransportTests.java b/shield/src/test/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransportTests.java index 61f5ca0dcb5..04424971554 100644 --- a/shield/src/test/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransportTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/transport/netty/ShieldNettyTransportTests.java @@ -49,7 +49,8 @@ public class ShieldNettyTransportTests extends ESTestCase { Environment env = new Environment(settingsBuilder().put("path.home", createTempDir()).build()); settingsFilter = new ShieldSettingsFilter(settings, new SettingsFilter(settings)); serverSSLService = new ServerSSLService(settings, settingsFilter, env); - clientSSLService = new ClientSSLService(settings, env); + clientSSLService = new ClientSSLService(settings); + clientSSLService.setEnvironment(env); } @Test diff --git a/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslClientAuthTests.java b/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslClientAuthTests.java index bb60d946949..20469456e09 100644 --- a/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslClientAuthTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslClientAuthTests.java @@ -13,7 +13,6 @@ import org.elasticsearch.ElasticsearchException; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; -import org.elasticsearch.env.Environment; import org.elasticsearch.http.HttpServerTransport; import org.elasticsearch.node.Node; import org.elasticsearch.shield.ShieldPlugin; @@ -73,8 +72,7 @@ public class SslClientAuthTests extends ShieldIntegTestCase { @Test public void testThatHttpWorksWithSslClientAuth() throws IOException { Settings settings = settingsBuilder().put(ShieldSettingsSource.getSSLSettingsForStore("/org/elasticsearch/shield/transport/ssl/certs/simple/testclient.jks", "testclient")).build(); - Environment env = new Environment(settingsBuilder().put("path.home", createTempDir()).build()); - ClientSSLService sslService = new ClientSSLService(settings, env); + ClientSSLService sslService = new ClientSSLService(settings); SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory( sslService.sslContext(), diff --git a/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslIntegrationTests.java b/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslIntegrationTests.java index dd14087d9fe..804ba27f914 100644 --- a/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslIntegrationTests.java +++ b/shield/src/test/java/org/elasticsearch/shield/transport/ssl/SslIntegrationTests.java @@ -21,7 +21,6 @@ import org.elasticsearch.common.io.Streams; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.InetSocketTransportAddress; import org.elasticsearch.common.transport.TransportAddress; -import org.elasticsearch.env.Environment; import org.elasticsearch.http.HttpServerTransport; import org.elasticsearch.node.Node; import org.elasticsearch.shield.ssl.ClientSSLService; @@ -95,8 +94,7 @@ public class SslIntegrationTests extends ShieldIntegTestCase { @Test public void testThatConnectionToHTTPWorks() throws Exception { Settings settings = ShieldSettingsSource.getSSLSettingsForStore("/org/elasticsearch/shield/transport/ssl/certs/simple/testclient.jks", "testclient"); - Environment env = new Environment(settingsBuilder().put("path.home", createTempDir()).build()); - ClientSSLService service = new ClientSSLService(settings, env); + ClientSSLService service = new ClientSSLService(settings); CredentialsProvider provider = new BasicCredentialsProvider(); provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(nodeClientUsername(), new String(nodeClientPassword().internalChars())));