From 6675f6bc8d0ed052871912cfd0c0df876ea6d2b2 Mon Sep 17 00:00:00 2001 From: Tim Brooks Date: Fri, 3 Feb 2017 14:48:07 -0600 Subject: [PATCH] Add missing doPrivileged blocks for connect ops (elastic/elasticsearch#4815) This is related to elastic/elasticsearchelastic/elasticsearch#22116. There were a few places where x-pack opens socket connects that were missed in PR elastic/elasticsearch#4701. This commit adds the doPrivileged blocks. Original commit: elastic/x-pack-elasticsearch@32bfa087f0f418b7d65473371f79a09df030111e --- .../ldap/ActiveDirectorySessionFactory.java | 7 ++-- .../authc/ldap/GroupsResolverTestCase.java | 9 +++-- .../xpack/ssl/SSLServiceTests.java | 39 ++++++++++++++----- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authc/ldap/ActiveDirectorySessionFactory.java b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authc/ldap/ActiveDirectorySessionFactory.java index cbdf4dff603..a523f7abc54 100644 --- a/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authc/ldap/ActiveDirectorySessionFactory.java +++ b/elasticsearch/src/main/java/org/elasticsearch/xpack/security/authc/ldap/ActiveDirectorySessionFactory.java @@ -283,10 +283,11 @@ class ActiveDirectorySessionFactory extends SessionFactory { try { Filter filter = createFilter(NETBIOS_NAME_FILTER_TEMPLATE, netBiosDomainName); if (connection.getSSLSession() != null) { - searchConnection = new LDAPConnection(connection.getSocketFactory(), options, - connection.getConnectedAddress(), 636); + searchConnection = LdapUtils.privilegedConnect(() -> new LDAPConnection(connection.getSocketFactory(), options, + connection.getConnectedAddress(), 636)); } else { - searchConnection = new LDAPConnection(options, connection.getConnectedAddress(), 389); + searchConnection = LdapUtils.privilegedConnect(() -> + new LDAPConnection(options, connection.getConnectedAddress(), 389)); } searchConnection.bind(username, new String(password.internalChars())); final LDAPConnection finalConnection = searchConnection; diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java index 8197a5f4650..ce61d5bf8f2 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/security/authc/ldap/GroupsResolverTestCase.java @@ -16,6 +16,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.env.Environment; import org.elasticsearch.xpack.security.authc.ldap.support.LdapSession.GroupsResolver; +import org.elasticsearch.xpack.security.authc.ldap.support.LdapUtils; import org.elasticsearch.xpack.security.authc.ldap.support.SessionFactory; import org.elasticsearch.test.ESTestCase; import org.elasticsearch.xpack.ssl.SSLService; @@ -24,6 +25,9 @@ import org.junit.After; import org.junit.Before; import java.nio.file.Path; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; import java.util.Collection; import java.util.List; @@ -77,9 +81,8 @@ public abstract class GroupsResolverTestCase extends ESTestCase { connectionSettings = Settings.builder().put("keystore.path", keystore) .put("keystore.password", "changeit").build(); } - - ldapConnection = new LDAPConnection(sslService.sslSocketFactory(connectionSettings), options, ldapurl.getHost(), - ldapurl.getPort(), bindDN(), bindPassword()); + ldapConnection = LdapUtils.privilegedConnect(() -> new LDAPConnection(sslService.sslSocketFactory(connectionSettings), options, + ldapurl.getHost(), ldapurl.getPort(), bindDN(), bindPassword())); } @After diff --git a/elasticsearch/src/test/java/org/elasticsearch/xpack/ssl/SSLServiceTests.java b/elasticsearch/src/test/java/org/elasticsearch/xpack/ssl/SSLServiceTests.java index ce7cc61b545..d5005e7d23a 100644 --- a/elasticsearch/src/test/java/org/elasticsearch/xpack/ssl/SSLServiceTests.java +++ b/elasticsearch/src/test/java/org/elasticsearch/xpack/ssl/SSLServiceTests.java @@ -17,15 +17,15 @@ import org.apache.http.impl.nio.client.CloseableHttpAsyncClient; import org.apache.http.impl.nio.client.HttpAsyncClientBuilder; import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy; import org.elasticsearch.ElasticsearchException; +import org.elasticsearch.common.CheckedRunnable; import org.elasticsearch.common.Strings; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.env.Environment; -import org.elasticsearch.test.junit.annotations.Network; import org.elasticsearch.test.ESTestCase; +import org.elasticsearch.test.junit.annotations.Network; import org.elasticsearch.xpack.XPackSettings; - -import org.mockito.ArgumentCaptor; import org.junit.Before; +import org.mockito.ArgumentCaptor; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; @@ -34,11 +34,12 @@ import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import java.nio.file.Path; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Set; -import java.util.concurrent.Future; import static org.hamcrest.Matchers.arrayContainingInAnyOrder; import static org.hamcrest.Matchers.contains; @@ -394,7 +395,7 @@ public class SSLServiceTests extends ESTestCase { // Execute a GET on a site known to have a valid certificate signed by a trusted public CA // This will result in a SSLHandshakeException if the SSLContext does not trust the CA, but the default // truststore trusts all common public CAs so the handshake will succeed - client.execute(new HttpGet("https://www.elastic.co/")).close(); + privilegedConnect(() -> client.execute(new HttpGet("https://www.elastic.co/")).close()); } } @@ -408,7 +409,7 @@ public class SSLServiceTests extends ESTestCase { 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 which will succeed because the JDK // certs are trusted by default - client.execute(new HttpGet("https://www.elastic.co/")).close(); + privilegedConnect(() -> client.execute(new HttpGet("https://www.elastic.co/")).close()); } } @@ -416,7 +417,7 @@ public class SSLServiceTests extends ESTestCase { public void testThatSSLIOSessionStrategyWithoutSettingsWorks() throws Exception { SSLService sslService = new SSLService(Settings.EMPTY, env); SSLIOSessionStrategy sslStrategy = sslService.sslIOSessionStrategy(Settings.EMPTY); - try (CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create().setSSLStrategy(sslStrategy).build()) { + try (CloseableHttpAsyncClient client = getAsyncHttpClient(sslStrategy)) { client.start(); // Execute a GET on a site known to have a valid certificate signed by a trusted public CA @@ -433,7 +434,7 @@ public class SSLServiceTests extends ESTestCase { .put("xpack.ssl.keystore.password", "testclient") .build(); SSLIOSessionStrategy sslStrategy = new SSLService(settings, env).sslIOSessionStrategy(Settings.EMPTY); - try (CloseableHttpAsyncClient client = HttpAsyncClientBuilder.create().setSSLStrategy(sslStrategy).build()) { + try (CloseableHttpAsyncClient client = getAsyncHttpClient(sslStrategy)) { client.start(); // Execute a GET on a site known to have a valid certificate signed by a trusted public CA which will succeed because the JDK @@ -462,4 +463,24 @@ public class SSLServiceTests extends ESTestCase { } } + private CloseableHttpAsyncClient getAsyncHttpClient(SSLIOSessionStrategy sslStrategy) throws Exception { + try { + return AccessController.doPrivileged((PrivilegedExceptionAction) + () -> HttpAsyncClientBuilder.create().setSSLStrategy(sslStrategy).build()); + } catch (PrivilegedActionException e) { + throw (Exception) e.getCause(); + } + } + + private static void privilegedConnect(CheckedRunnable runnable) throws Exception { + try { + AccessController.doPrivileged((PrivilegedExceptionAction) () -> { + runnable.run(); + return null; + }); + } catch (PrivilegedActionException e) { + throw (Exception) e.getCause(); + } + } + }