Wrap ServerSocket usage in doPrivileged blocks (elastic/elasticsearch#4631)

This is related to elastic/elasticsearch#22116. In the tests there are multiple usages of
server implementations that `accept()` socket connections. To avoid
throwing `SecurityException` when using the `SecurityManager` these
operations must be privileged. Additionally, x-pack:elasticsearch
requires `accept` permission. This was added in the plugin-security
policy file.

Original commit: elastic/x-pack-elasticsearch@057e2abb1f
This commit is contained in:
Tim Brooks 2017-01-17 09:33:41 -06:00 committed by GitHub
parent 06259f1836
commit 17492777a9
5 changed files with 27 additions and 4 deletions

View File

@ -24,4 +24,7 @@ grant {
// Netty SelectorUtil wants to change this, because of https://bugs.openjdk.java.net/browse/JDK-6427854 // Netty SelectorUtil wants to change this, because of https://bugs.openjdk.java.net/browse/JDK-6427854
// the bug says it only happened rarely, and that its fixed, but apparently it still happens rarely! // the bug says it only happened rarely, and that its fixed, but apparently it still happens rarely!
permission java.util.PropertyPermission "sun.nio.ch.bugLevel", "write"; permission java.util.PropertyPermission "sun.nio.ch.bugLevel", "write";
// needed for multiple server implementations used in tests
permission java.net.SocketPermission "*", "accept";
}; };

View File

@ -13,6 +13,7 @@ import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.env.Environment; import org.elasticsearch.env.Environment;
import org.elasticsearch.mocksocket.MockServerSocket;
import org.elasticsearch.test.ESTestCase; import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.http.MockResponse; import org.elasticsearch.test.http.MockResponse;
import org.elasticsearch.test.http.MockWebServer; import org.elasticsearch.test.http.MockWebServer;
@ -400,7 +401,7 @@ public class HttpClientTests extends ESTestCase {
public void testThatHttpClientFailsOnNonHttpResponse() throws Exception { public void testThatHttpClientFailsOnNonHttpResponse() throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor(); ExecutorService executor = Executors.newSingleThreadExecutor();
AtomicReference<Exception> hasExceptionHappened = new AtomicReference(); AtomicReference<Exception> hasExceptionHappened = new AtomicReference();
try (ServerSocket serverSocket = new ServerSocket(0, 50, InetAddress.getByName("localhost"))) { try (ServerSocket serverSocket = new MockServerSocket(0, 50, InetAddress.getByName("localhost"))) {
executor.execute(() -> { executor.execute(() -> {
try (Socket socket = serverSocket.accept()) { try (Socket socket = serverSocket.accept()) {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8)); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));

View File

@ -16,6 +16,8 @@ import javax.mail.Session;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
@ -75,7 +77,11 @@ public class EmailServer {
} }
public void start() { public void start() {
server.start(); // Must have privileged access because underlying server will accept socket connections
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
server.start();
return null;
});
} }
public void stop() { public void stop() {

View File

@ -34,6 +34,8 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import java.security.AccessController;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -99,7 +101,11 @@ public class ActiveDirectoryRealmTests extends ESTestCase {
directoryServer.add("dc=ad,dc=test,dc=elasticsearch,dc=com", new Attribute("dc", "UnboundID"), directoryServer.add("dc=ad,dc=test,dc=elasticsearch,dc=com", new Attribute("dc", "UnboundID"),
new Attribute("objectClass", "top", "domain", "extensibleObject")); new Attribute("objectClass", "top", "domain", "extensibleObject"));
directoryServer.importFromLDIF(false, getDataPath("ad.ldif").toString()); directoryServer.importFromLDIF(false, getDataPath("ad.ldif").toString());
directoryServer.startListening(); // Must have privileged access because underlying server will accept socket connections
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
directoryServer.startListening();
return null;
});
directoryServers[i] = directoryServer; directoryServers[i] = directoryServer;
} }
threadPool = new TestThreadPool("active directory realm tests"); threadPool = new TestThreadPool("active directory realm tests");

View File

@ -24,6 +24,9 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -52,7 +55,11 @@ public abstract class LdapTestCase extends ESTestCase {
new Attribute("objectClass", "top", "domain", "extensibleObject")); new Attribute("objectClass", "top", "domain", "extensibleObject"));
ldapServer.importFromLDIF(false, ldapServer.importFromLDIF(false,
getDataPath("/org/elasticsearch/xpack/security/authc/ldap/support/seven-seas.ldif").toString()); getDataPath("/org/elasticsearch/xpack/security/authc/ldap/support/seven-seas.ldif").toString());
ldapServer.startListening(); // Must have privileged access because underlying server will accept socket connections
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
ldapServer.startListening();
return null;
});
ldapServers[i] = ldapServer; ldapServers[i] = ldapServer;
} }
} }