mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-27 17:10:22 -04:00
Move remaining check methods in RestEntitlementsCheckAction (#125351)
All future check methods should be found reflectively with the EntitlementTest annotation.
This commit is contained in:
parent
d7995975d9
commit
02f12c8e83
5 changed files with 213 additions and 272 deletions
|
@ -9,7 +9,12 @@
|
|||
|
||||
package org.elasticsearch.entitlement.qa.test;
|
||||
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
|
||||
|
||||
@SuppressWarnings({ "unused" /* called via reflection */ })
|
||||
class LoadNativeLibrariesCheckActions {
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void runtimeLoad() {
|
||||
try {
|
||||
Runtime.getRuntime().load(FileCheckActions.readDir().resolve("libSomeLibFile.so").toString());
|
||||
|
@ -18,6 +23,7 @@ class LoadNativeLibrariesCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void systemLoad() {
|
||||
try {
|
||||
System.load(FileCheckActions.readDir().resolve("libSomeLibFile.so").toString());
|
||||
|
@ -26,6 +32,7 @@ class LoadNativeLibrariesCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void runtimeLoadLibrary() {
|
||||
try {
|
||||
Runtime.getRuntime().loadLibrary("SomeLib");
|
||||
|
@ -34,6 +41,7 @@ class LoadNativeLibrariesCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void systemLoadLibrary() {
|
||||
try {
|
||||
System.loadLibrary("SomeLib");
|
||||
|
@ -41,4 +49,6 @@ class LoadNativeLibrariesCheckActions {
|
|||
// The library does not exist, so we expect to fail loading it
|
||||
}
|
||||
}
|
||||
|
||||
private LoadNativeLibrariesCheckActions() {}
|
||||
}
|
||||
|
|
|
@ -12,12 +12,23 @@ package org.elasticsearch.entitlement.qa.test;
|
|||
import org.elasticsearch.core.SuppressForbidden;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.Proxy;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.ResponseCache;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.spi.URLStreamHandlerProvider;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.AsynchronousServerSocketChannel;
|
||||
import java.nio.channels.AsynchronousSocketChannel;
|
||||
|
@ -32,9 +43,17 @@ import java.security.cert.CertStore;
|
|||
import java.util.Arrays;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
|
||||
|
||||
@SuppressForbidden(reason = "Testing entitlement check on forbidden action")
|
||||
@SuppressWarnings({ "unused" /* called via reflection */, "deprecation" })
|
||||
class NetworkAccessCheckActions {
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void serverSocketAccept() throws IOException {
|
||||
try (ServerSocket socket = new DummyImplementations.DummyBoundServerSocket()) {
|
||||
try {
|
||||
|
@ -49,30 +68,35 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void serverSocketBind() throws IOException {
|
||||
try (ServerSocket socket = new DummyImplementations.DummyServerSocket()) {
|
||||
socket.bind(null);
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void createSocketWithProxy() throws IOException {
|
||||
try (Socket socket = new Socket(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(0)))) {
|
||||
assert socket.isBound() == false;
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void socketBind() throws IOException {
|
||||
try (Socket socket = new DummyImplementations.DummySocket()) {
|
||||
socket.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void socketConnect() throws IOException {
|
||||
try (Socket socket = new DummyImplementations.DummySocket()) {
|
||||
socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void createLDAPCertStore() {
|
||||
try {
|
||||
// We pass down null params to provoke a InvalidAlgorithmParameterException
|
||||
|
@ -86,18 +110,21 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void serverSocketChannelBind() throws IOException {
|
||||
try (var serverSocketChannel = ServerSocketChannel.open()) {
|
||||
serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void serverSocketChannelBindWithBacklog() throws IOException {
|
||||
try (var serverSocketChannel = ServerSocketChannel.open()) {
|
||||
serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 50);
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void serverSocketChannelAccept() throws IOException {
|
||||
try (var serverSocketChannel = ServerSocketChannel.open()) {
|
||||
serverSocketChannel.configureBlocking(false);
|
||||
|
@ -110,18 +137,21 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void asynchronousServerSocketChannelBind() throws IOException {
|
||||
try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) {
|
||||
serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void asynchronousServerSocketChannelBindWithBacklog() throws IOException {
|
||||
try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) {
|
||||
serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 50);
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void asynchronousServerSocketChannelAccept() throws IOException {
|
||||
try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) {
|
||||
try {
|
||||
|
@ -134,6 +164,7 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void asynchronousServerSocketChannelAcceptWithHandler() throws IOException {
|
||||
try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) {
|
||||
try {
|
||||
|
@ -153,12 +184,14 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void socketChannelBind() throws IOException {
|
||||
try (var socketChannel = SocketChannel.open()) {
|
||||
socketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void socketChannelConnect() throws IOException {
|
||||
try (var socketChannel = SocketChannel.open()) {
|
||||
try {
|
||||
|
@ -170,12 +203,14 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void asynchronousSocketChannelBind() throws IOException {
|
||||
try (var socketChannel = AsynchronousSocketChannel.open()) {
|
||||
socketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void asynchronousSocketChannelConnect() throws IOException, InterruptedException {
|
||||
try (var socketChannel = AsynchronousSocketChannel.open()) {
|
||||
var future = socketChannel.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
|
@ -189,6 +224,7 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void asynchronousSocketChannelConnectWithCompletion() throws IOException {
|
||||
try (var socketChannel = AsynchronousSocketChannel.open()) {
|
||||
socketChannel.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), null, new CompletionHandler<>() {
|
||||
|
@ -203,12 +239,14 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void datagramChannelBind() throws IOException {
|
||||
try (var channel = DatagramChannel.open()) {
|
||||
channel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void datagramChannelConnect() throws IOException {
|
||||
try (var channel = DatagramChannel.open()) {
|
||||
channel.configureBlocking(false);
|
||||
|
@ -221,6 +259,7 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void datagramChannelSend() throws IOException {
|
||||
try (var channel = DatagramChannel.open()) {
|
||||
channel.configureBlocking(false);
|
||||
|
@ -228,6 +267,7 @@ class NetworkAccessCheckActions {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void datagramChannelReceive() throws IOException {
|
||||
try (var channel = DatagramChannel.open()) {
|
||||
channel.configureBlocking(false);
|
||||
|
@ -235,4 +275,149 @@ class NetworkAccessCheckActions {
|
|||
channel.receive(ByteBuffer.wrap(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void createURLStreamHandlerProvider() {
|
||||
var x = new URLStreamHandlerProvider() {
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void createURLWithURLStreamHandler() throws MalformedURLException {
|
||||
var x = new URL("http", "host", 1234, "file", new URLStreamHandler() {
|
||||
@Override
|
||||
protected URLConnection openConnection(URL u) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void createURLWithURLStreamHandler2() throws MalformedURLException {
|
||||
var x = new URL(null, "spec", new URLStreamHandler() {
|
||||
@Override
|
||||
protected URLConnection openConnection(URL u) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void setDefaultResponseCache() {
|
||||
ResponseCache.setDefault(null);
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void setDefaultProxySelector() {
|
||||
ProxySelector.setDefault(null);
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void setDefaultSSLContext() throws NoSuchAlgorithmException {
|
||||
SSLContext.setDefault(SSLContext.getDefault());
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void setDefaultHostnameVerifier() {
|
||||
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> false);
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void setDefaultSSLSocketFactory() {
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(new DummyImplementations.DummySSLSocketFactory());
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void setHttpsConnectionProperties() {
|
||||
new DummyImplementations.DummyHttpsURLConnection().setSSLSocketFactory(new DummyImplementations.DummySSLSocketFactory());
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void datagramSocket$$setDatagramSocketImplFactory() throws IOException {
|
||||
DatagramSocket.setDatagramSocketImplFactory(() -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void httpURLConnection$$setFollowRedirects() {
|
||||
HttpURLConnection.setFollowRedirects(HttpURLConnection.getFollowRedirects());
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void serverSocket$$setSocketFactory() throws IOException {
|
||||
ServerSocket.setSocketFactory(() -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void socket$$setSocketImplFactory() throws IOException {
|
||||
Socket.setSocketImplFactory(() -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void url$$setURLStreamHandlerFactory() {
|
||||
URL.setURLStreamHandlerFactory(__ -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void urlConnection$$setFileNameMap() {
|
||||
URLConnection.setFileNameMap(__ -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
|
||||
static void urlConnection$$setContentHandlerFactory() {
|
||||
URLConnection.setContentHandlerFactory(__ -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void bindDatagramSocket() throws SocketException {
|
||||
try (var socket = new DatagramSocket(null)) {
|
||||
socket.bind(null);
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void connectDatagramSocket() throws SocketException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.connect(new InetSocketAddress(1234));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void joinGroupDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.joinGroup(
|
||||
new InetSocketAddress(InetAddress.getByAddress(new byte[] { (byte) 230, 0, 0, 1 }), 1234),
|
||||
NetworkInterface.getByIndex(0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void leaveGroupDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.leaveGroup(
|
||||
new InetSocketAddress(InetAddress.getByAddress(new byte[] { (byte) 230, 0, 0, 1 }), 1234),
|
||||
NetworkInterface.getByIndex(0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void sendDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.send(new DatagramPacket(new byte[] { 0 }, 1, InetAddress.getLocalHost(), 1234));
|
||||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void receiveDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.receive(new DatagramPacket(new byte[1], 1, InetAddress.getLocalHost(), 1234));
|
||||
}
|
||||
}
|
||||
|
||||
private NetworkAccessCheckActions() {}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,7 @@ package org.elasticsearch.entitlement.qa.test;
|
|||
import org.elasticsearch.client.internal.node.NodeClient;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.core.CheckedConsumer;
|
||||
import org.elasticsearch.core.CheckedRunnable;
|
||||
import org.elasticsearch.core.SuppressForbidden;
|
||||
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.logging.LogManager;
|
||||
import org.elasticsearch.logging.Logger;
|
||||
|
@ -23,27 +21,9 @@ import org.elasticsearch.rest.RestRequest;
|
|||
import org.elasticsearch.rest.RestResponse;
|
||||
import org.elasticsearch.rest.RestStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.ProxySelector;
|
||||
import java.net.ResponseCache;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.spi.URLStreamHandlerProvider;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -53,16 +33,9 @@ import java.util.function.Function;
|
|||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.net.ssl.HttpsURLConnection;
|
||||
import javax.net.ssl.SSLContext;
|
||||
|
||||
import static java.util.Map.entry;
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_ALLOWED;
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.SERVER_ONLY;
|
||||
import static org.elasticsearch.entitlement.qa.test.RestEntitlementsCheckAction.CheckAction.alwaysDenied;
|
||||
import static org.elasticsearch.entitlement.qa.test.RestEntitlementsCheckAction.CheckAction.forPlugins;
|
||||
import static org.elasticsearch.rest.RestRequest.Method.GET;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
|
@ -74,128 +47,25 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
|
|||
EntitlementTest.ExpectedAccess expectedAccess,
|
||||
Class<? extends Exception> expectedExceptionIfDenied,
|
||||
Integer fromJavaVersion
|
||||
) {
|
||||
/**
|
||||
* These cannot be granted to plugins, so our test plugins cannot test the "allowed" case.
|
||||
*/
|
||||
static CheckAction deniedToPlugins(CheckedRunnable<Exception> action) {
|
||||
return new CheckAction(env -> action.run(), SERVER_ONLY, NotEntitledException.class, null);
|
||||
}
|
||||
|
||||
static CheckAction forPlugins(CheckedRunnable<Exception> action) {
|
||||
return new CheckAction(env -> action.run(), PLUGINS, NotEntitledException.class, null);
|
||||
}
|
||||
|
||||
static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
|
||||
return new CheckAction(env -> action.run(), ALWAYS_DENIED, NotEntitledException.class, null);
|
||||
}
|
||||
}
|
||||
) {}
|
||||
|
||||
private static final Map<String, CheckAction> checkActions = Stream.of(
|
||||
Stream.<Entry<String, CheckAction>>of(
|
||||
entry("set_https_connection_properties", forPlugins(RestEntitlementsCheckAction::setHttpsConnectionProperties)),
|
||||
entry("set_default_ssl_socket_factory", alwaysDenied(RestEntitlementsCheckAction::setDefaultSSLSocketFactory)),
|
||||
entry("set_default_hostname_verifier", alwaysDenied(RestEntitlementsCheckAction::setDefaultHostnameVerifier)),
|
||||
entry("set_default_ssl_context", alwaysDenied(RestEntitlementsCheckAction::setDefaultSSLContext)),
|
||||
|
||||
// This group is a bit nasty: if entitlements don't prevent these, then networking is
|
||||
// irreparably borked for the remainder of the test run.
|
||||
entry(
|
||||
"datagramSocket_setDatagramSocketImplFactory",
|
||||
alwaysDenied(RestEntitlementsCheckAction::datagramSocket$$setDatagramSocketImplFactory)
|
||||
),
|
||||
entry("httpURLConnection_setFollowRedirects", alwaysDenied(RestEntitlementsCheckAction::httpURLConnection$$setFollowRedirects)),
|
||||
entry("serverSocket_setSocketFactory", alwaysDenied(RestEntitlementsCheckAction::serverSocket$$setSocketFactory)),
|
||||
entry("socket_setSocketImplFactory", alwaysDenied(RestEntitlementsCheckAction::socket$$setSocketImplFactory)),
|
||||
entry("url_setURLStreamHandlerFactory", alwaysDenied(RestEntitlementsCheckAction::url$$setURLStreamHandlerFactory)),
|
||||
entry("urlConnection_setFileNameMap", alwaysDenied(RestEntitlementsCheckAction::urlConnection$$setFileNameMap)),
|
||||
entry(
|
||||
"urlConnection_setContentHandlerFactory",
|
||||
alwaysDenied(RestEntitlementsCheckAction::urlConnection$$setContentHandlerFactory)
|
||||
),
|
||||
|
||||
entry("proxySelector_setDefault", alwaysDenied(RestEntitlementsCheckAction::setDefaultProxySelector)),
|
||||
entry("responseCache_setDefault", alwaysDenied(RestEntitlementsCheckAction::setDefaultResponseCache)),
|
||||
entry(
|
||||
"createInetAddressResolverProvider",
|
||||
new CheckAction(
|
||||
env -> VersionSpecificNetworkChecks.createInetAddressResolverProvider(),
|
||||
SERVER_ONLY,
|
||||
NotEntitledException.class,
|
||||
18
|
||||
)
|
||||
),
|
||||
entry("createURLStreamHandlerProvider", alwaysDenied(RestEntitlementsCheckAction::createURLStreamHandlerProvider)),
|
||||
entry("createURLWithURLStreamHandler", alwaysDenied(RestEntitlementsCheckAction::createURLWithURLStreamHandler)),
|
||||
entry("createURLWithURLStreamHandler2", alwaysDenied(RestEntitlementsCheckAction::createURLWithURLStreamHandler2)),
|
||||
entry("datagram_socket_bind", forPlugins(RestEntitlementsCheckAction::bindDatagramSocket)),
|
||||
entry("datagram_socket_connect", forPlugins(RestEntitlementsCheckAction::connectDatagramSocket)),
|
||||
entry("datagram_socket_send", forPlugins(RestEntitlementsCheckAction::sendDatagramSocket)),
|
||||
entry("datagram_socket_receive", forPlugins(RestEntitlementsCheckAction::receiveDatagramSocket)),
|
||||
entry("datagram_socket_join_group", forPlugins(RestEntitlementsCheckAction::joinGroupDatagramSocket)),
|
||||
entry("datagram_socket_leave_group", forPlugins(RestEntitlementsCheckAction::leaveGroupDatagramSocket)),
|
||||
|
||||
entry("create_socket_with_proxy", forPlugins(NetworkAccessCheckActions::createSocketWithProxy)),
|
||||
entry("socket_bind", forPlugins(NetworkAccessCheckActions::socketBind)),
|
||||
entry("socket_connect", forPlugins(NetworkAccessCheckActions::socketConnect)),
|
||||
entry("server_socket_bind", forPlugins(NetworkAccessCheckActions::serverSocketBind)),
|
||||
entry("server_socket_accept", forPlugins(NetworkAccessCheckActions::serverSocketAccept)),
|
||||
|
||||
entry("http_client_send", forPlugins(VersionSpecificNetworkChecks::httpClientSend)),
|
||||
entry("http_client_send_async", forPlugins(VersionSpecificNetworkChecks::httpClientSendAsync)),
|
||||
entry("create_ldap_cert_store", forPlugins(NetworkAccessCheckActions::createLDAPCertStore)),
|
||||
|
||||
entry("server_socket_channel_bind", forPlugins(NetworkAccessCheckActions::serverSocketChannelBind)),
|
||||
entry("server_socket_channel_bind_backlog", forPlugins(NetworkAccessCheckActions::serverSocketChannelBindWithBacklog)),
|
||||
entry("server_socket_channel_accept", forPlugins(NetworkAccessCheckActions::serverSocketChannelAccept)),
|
||||
entry("asynchronous_server_socket_channel_bind", forPlugins(NetworkAccessCheckActions::asynchronousServerSocketChannelBind)),
|
||||
entry(
|
||||
"asynchronous_server_socket_channel_bind_backlog",
|
||||
forPlugins(NetworkAccessCheckActions::asynchronousServerSocketChannelBindWithBacklog)
|
||||
),
|
||||
entry(
|
||||
"asynchronous_server_socket_channel_accept",
|
||||
forPlugins(NetworkAccessCheckActions::asynchronousServerSocketChannelAccept)
|
||||
),
|
||||
entry(
|
||||
"asynchronous_server_socket_channel_accept_with_handler",
|
||||
forPlugins(NetworkAccessCheckActions::asynchronousServerSocketChannelAcceptWithHandler)
|
||||
),
|
||||
entry("socket_channel_bind", forPlugins(NetworkAccessCheckActions::socketChannelBind)),
|
||||
entry("socket_channel_connect", forPlugins(NetworkAccessCheckActions::socketChannelConnect)),
|
||||
entry("asynchronous_socket_channel_bind", forPlugins(NetworkAccessCheckActions::asynchronousSocketChannelBind)),
|
||||
entry("asynchronous_socket_channel_connect", forPlugins(NetworkAccessCheckActions::asynchronousSocketChannelConnect)),
|
||||
entry(
|
||||
"asynchronous_socket_channel_connect_with_completion",
|
||||
forPlugins(NetworkAccessCheckActions::asynchronousSocketChannelConnectWithCompletion)
|
||||
),
|
||||
entry("datagram_channel_bind", forPlugins(NetworkAccessCheckActions::datagramChannelBind)),
|
||||
entry("datagram_channel_connect", forPlugins(NetworkAccessCheckActions::datagramChannelConnect)),
|
||||
entry("datagram_channel_send", forPlugins(NetworkAccessCheckActions::datagramChannelSend)),
|
||||
entry("datagram_channel_receive", forPlugins(NetworkAccessCheckActions::datagramChannelReceive)),
|
||||
|
||||
entry("runtime_load", forPlugins(LoadNativeLibrariesCheckActions::runtimeLoad)),
|
||||
entry("runtime_load_library", forPlugins(LoadNativeLibrariesCheckActions::runtimeLoadLibrary)),
|
||||
entry("system_load", forPlugins(LoadNativeLibrariesCheckActions::systemLoad)),
|
||||
entry("system_load_library", forPlugins(LoadNativeLibrariesCheckActions::systemLoadLibrary))
|
||||
|
||||
// MAINTENANCE NOTE: Please don't add any more entries to this map.
|
||||
// Put new tests into their own "Actions" class using the @EntitlementTest annotation.
|
||||
),
|
||||
getTestEntries(FileCheckActions.class),
|
||||
getTestEntries(FileStoreActions.class),
|
||||
getTestEntries(JvmActions.class),
|
||||
getTestEntries(LoadNativeLibrariesCheckActions.class),
|
||||
getTestEntries(ManageThreadsActions.class),
|
||||
getTestEntries(NativeActions.class),
|
||||
getTestEntries(NetworkAccessCheckActions.class),
|
||||
getTestEntries(NioChannelsActions.class),
|
||||
getTestEntries(NioFilesActions.class),
|
||||
getTestEntries(NioFileSystemActions.class),
|
||||
getTestEntries(OperatingSystemActions.class),
|
||||
getTestEntries(PathActions.class),
|
||||
getTestEntries(SpiActions.class),
|
||||
getTestEntries(SystemActions.class),
|
||||
getTestEntries(URLConnectionFileActions.class),
|
||||
getTestEntries(URLConnectionNetworkActions.class),
|
||||
getTestEntries(JvmActions.class),
|
||||
getTestEntries(OperatingSystemActions.class)
|
||||
getTestEntries(URLConnectionNetworkActions.class)
|
||||
)
|
||||
.flatMap(Function.identity())
|
||||
.filter(entry -> entry.getValue().fromJavaVersion() == null || Runtime.version().feature() >= entry.getValue().fromJavaVersion())
|
||||
|
@ -258,143 +128,11 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
|
|||
throw new AssertionError("Entitlement test method [" + method + "] must have no parameters or 1 parameter (Environment)");
|
||||
}
|
||||
|
||||
private static void createURLStreamHandlerProvider() {
|
||||
var x = new URLStreamHandlerProvider() {
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void createURLWithURLStreamHandler() throws MalformedURLException {
|
||||
var x = new URL("http", "host", 1234, "file", new URLStreamHandler() {
|
||||
@Override
|
||||
protected URLConnection openConnection(URL u) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void createURLWithURLStreamHandler2() throws MalformedURLException {
|
||||
var x = new URL(null, "spec", new URLStreamHandler() {
|
||||
@Override
|
||||
protected URLConnection openConnection(URL u) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void setDefaultResponseCache() {
|
||||
ResponseCache.setDefault(null);
|
||||
}
|
||||
|
||||
private static void setDefaultProxySelector() {
|
||||
ProxySelector.setDefault(null);
|
||||
}
|
||||
|
||||
private static void setDefaultSSLContext() throws NoSuchAlgorithmException {
|
||||
SSLContext.setDefault(SSLContext.getDefault());
|
||||
}
|
||||
|
||||
private static void setDefaultHostnameVerifier() {
|
||||
HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> false);
|
||||
}
|
||||
|
||||
private static void setDefaultSSLSocketFactory() {
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(new DummyImplementations.DummySSLSocketFactory());
|
||||
}
|
||||
|
||||
private static void setHttpsConnectionProperties() {
|
||||
new DummyImplementations.DummyHttpsURLConnection().setSSLSocketFactory(new DummyImplementations.DummySSLSocketFactory());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressForbidden(reason = "We're required to prevent calls to this forbidden API")
|
||||
private static void datagramSocket$$setDatagramSocketImplFactory() throws IOException {
|
||||
DatagramSocket.setDatagramSocketImplFactory(() -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
private static void httpURLConnection$$setFollowRedirects() {
|
||||
HttpURLConnection.setFollowRedirects(HttpURLConnection.getFollowRedirects());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressForbidden(reason = "We're required to prevent calls to this forbidden API")
|
||||
private static void serverSocket$$setSocketFactory() throws IOException {
|
||||
ServerSocket.setSocketFactory(() -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressForbidden(reason = "We're required to prevent calls to this forbidden API")
|
||||
private static void socket$$setSocketImplFactory() throws IOException {
|
||||
Socket.setSocketImplFactory(() -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
private static void url$$setURLStreamHandlerFactory() {
|
||||
URL.setURLStreamHandlerFactory(__ -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
private static void urlConnection$$setFileNameMap() {
|
||||
URLConnection.setFileNameMap(__ -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
private static void urlConnection$$setContentHandlerFactory() {
|
||||
URLConnection.setContentHandlerFactory(__ -> { throw new IllegalStateException(); });
|
||||
}
|
||||
|
||||
private static void bindDatagramSocket() throws SocketException {
|
||||
try (var socket = new DatagramSocket(null)) {
|
||||
socket.bind(null);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "testing entitlements")
|
||||
private static void connectDatagramSocket() throws SocketException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.connect(new InetSocketAddress(1234));
|
||||
}
|
||||
}
|
||||
|
||||
private static void joinGroupDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.joinGroup(
|
||||
new InetSocketAddress(InetAddress.getByAddress(new byte[] { (byte) 230, 0, 0, 1 }), 1234),
|
||||
NetworkInterface.getByIndex(0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void leaveGroupDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.leaveGroup(
|
||||
new InetSocketAddress(InetAddress.getByAddress(new byte[] { (byte) 230, 0, 0, 1 }), 1234),
|
||||
NetworkInterface.getByIndex(0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "testing entitlements")
|
||||
private static void sendDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.send(new DatagramPacket(new byte[] { 0 }, 1, InetAddress.getLocalHost(), 1234));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressForbidden(reason = "testing entitlements")
|
||||
private static void receiveDatagramSocket() throws IOException {
|
||||
try (var socket = new DummyImplementations.DummyDatagramSocket()) {
|
||||
socket.receive(new DatagramPacket(new byte[1], 1, InetAddress.getLocalHost(), 1234));
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> getCheckActionsAllowedInPlugins() {
|
||||
return checkActions.entrySet()
|
||||
.stream()
|
||||
.filter(kv -> kv.getValue().expectedAccess().equals(PLUGINS) || kv.getValue().expectedAccess().equals(ALWAYS_ALLOWED))
|
||||
.map(Entry::getKey)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
@ -402,7 +140,7 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
|
|||
return checkActions.entrySet()
|
||||
.stream()
|
||||
.filter(kv -> kv.getValue().expectedAccess().equals(ALWAYS_ALLOWED))
|
||||
.map(Entry::getKey)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
@ -410,7 +148,7 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
|
|||
return checkActions.entrySet()
|
||||
.stream()
|
||||
.filter(kv -> kv.getValue().expectedAccess().equals(ALWAYS_ALLOWED) == false)
|
||||
.map(Entry::getKey)
|
||||
.map(Map.Entry::getKey)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,13 @@ import java.net.http.HttpResponse;
|
|||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
|
||||
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.SERVER_ONLY;
|
||||
|
||||
@SuppressWarnings({ "unused" /* called via reflection */ })
|
||||
class VersionSpecificNetworkChecks {
|
||||
|
||||
@EntitlementTest(expectedAccess = SERVER_ONLY, fromJavaVersion = 18)
|
||||
static void createInetAddressResolverProvider() {
|
||||
new InetAddressResolverProvider() {
|
||||
@Override
|
||||
|
@ -32,6 +38,7 @@ class VersionSpecificNetworkChecks {
|
|||
};
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void httpClientSend() throws InterruptedException {
|
||||
try (HttpClient httpClient = HttpClient.newBuilder().build()) {
|
||||
// Shutdown the client, so the send action will shortcut before actually executing any network operation
|
||||
|
@ -45,6 +52,7 @@ class VersionSpecificNetworkChecks {
|
|||
}
|
||||
}
|
||||
|
||||
@EntitlementTest(expectedAccess = PLUGINS)
|
||||
static void httpClientSendAsync() {
|
||||
try (HttpClient httpClient = HttpClient.newBuilder().build()) {
|
||||
// Shutdown the client, so the send action will return before actually executing any network operation
|
||||
|
|
|
@ -52,7 +52,7 @@ public class EntitlementsAllowedViaOverrideIT extends AbstractEntitlementsIT {
|
|||
|
||||
@ParametersFactory
|
||||
public static Iterable<Object[]> data() {
|
||||
return Stream.of("runtime_load_library", "fileList").map(action -> new Object[] { action }).toList();
|
||||
return Stream.of("runtimeLoadLibrary", "fileList").map(action -> new Object[] { action }).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue