diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/LoadNativeLibrariesCheckActions.java b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/LoadNativeLibrariesCheckActions.java index 5b3265c5496b..7d2cc98f76f2 100644 --- a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/LoadNativeLibrariesCheckActions.java +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/LoadNativeLibrariesCheckActions.java @@ -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() {} } diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/NetworkAccessCheckActions.java b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/NetworkAccessCheckActions.java index 1158506b5a08..c92551488a77 100644 --- a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/NetworkAccessCheckActions.java +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/NetworkAccessCheckActions.java @@ -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() {} } diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java index 70cca99b0a74..56b2850d35ec 100644 --- a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java @@ -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 expectedExceptionIfDenied, Integer fromJavaVersion - ) { - /** - * These cannot be granted to plugins, so our test plugins cannot test the "allowed" case. - */ - static CheckAction deniedToPlugins(CheckedRunnable action) { - return new CheckAction(env -> action.run(), SERVER_ONLY, NotEntitledException.class, null); - } - - static CheckAction forPlugins(CheckedRunnable action) { - return new CheckAction(env -> action.run(), PLUGINS, NotEntitledException.class, null); - } - - static CheckAction alwaysDenied(CheckedRunnable action) { - return new CheckAction(env -> action.run(), ALWAYS_DENIED, NotEntitledException.class, null); - } - } + ) {} private static final Map checkActions = Stream.of( - Stream.>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 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()); } diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNetworkChecks.java b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNetworkChecks.java index 797b9872c1d2..40bb61375c60 100644 --- a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNetworkChecks.java +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNetworkChecks.java @@ -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 diff --git a/libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/EntitlementsAllowedViaOverrideIT.java b/libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/EntitlementsAllowedViaOverrideIT.java index 4d9de19bb707..37e9a9153922 100644 --- a/libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/EntitlementsAllowedViaOverrideIT.java +++ b/libs/entitlement/qa/src/javaRestTest/java/org/elasticsearch/entitlement/qa/EntitlementsAllowedViaOverrideIT.java @@ -52,7 +52,7 @@ public class EntitlementsAllowedViaOverrideIT extends AbstractEntitlementsIT { @ParametersFactory public static Iterable 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