diff --git a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java index d6a8a01a7ab3f..a01d8f2d17844 100644 --- a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java @@ -33,6 +33,13 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousServerSocketChannel; +import java.nio.channels.AsynchronousSocketChannel; +import java.nio.channels.CompletionHandler; +import java.nio.channels.DatagramChannel; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; import java.security.cert.CertStoreParameters; import java.util.List; @@ -291,4 +298,73 @@ public interface EntitlementChecker { // We need to check the LDAPCertStore, as this will connect, but this is internal/created via SPI, // so we instrument the general factory instead and then filter in the check method implementation void check$java_security_cert_CertStore$$getInstance(Class callerClass, String type, CertStoreParameters params); + + /* NIO + * For NIO, we are sometime able to check a method on the public surface/interface (e.g. AsynchronousServerSocketChannel#bind) + * but most of the time these methods are abstract in the public classes/interfaces (e.g. ServerSocketChannel#accept, + * NetworkChannel#bind), so we are forced to implement the "impl" classes. + * You can distinguish the 2 cases form the namespaces: java_nio_channels for the public ones, sun_nio_ch for the implementation + * classes. When you see a check on a sun_nio_ch class/method, this means the matching method on the public class is abstract + * (not instrumentable). + */ + + // bind + + void check$java_nio_channels_AsynchronousServerSocketChannel$bind( + Class callerClass, + AsynchronousServerSocketChannel that, + SocketAddress local + ); + + void check$sun_nio_ch_AsynchronousServerSocketChannelImpl$bind( + Class callerClass, + AsynchronousServerSocketChannel that, + SocketAddress local, + int backlog + ); + + void check$sun_nio_ch_AsynchronousSocketChannelImpl$bind(Class callerClass, AsynchronousSocketChannel that, SocketAddress local); + + void check$sun_nio_ch_DatagramChannelImpl$bind(Class callerClass, DatagramChannel that, SocketAddress local); + + void check$java_nio_channels_ServerSocketChannel$bind(Class callerClass, ServerSocketChannel that, SocketAddress local); + + void check$sun_nio_ch_ServerSocketChannelImpl$bind(Class callerClass, ServerSocketChannel that, SocketAddress local, int backlog); + + void check$sun_nio_ch_SocketChannelImpl$bind(Class callerClass, SocketChannel that, SocketAddress local); + + // connect + + void check$sun_nio_ch_SocketChannelImpl$connect(Class callerClass, SocketChannel that, SocketAddress remote); + + void check$sun_nio_ch_AsynchronousSocketChannelImpl$connect(Class callerClass, AsynchronousSocketChannel that, SocketAddress remote); + + void check$sun_nio_ch_AsynchronousSocketChannelImpl$connect( + Class callerClass, + AsynchronousSocketChannel that, + SocketAddress remote, + Object attachment, + CompletionHandler handler + ); + + void check$sun_nio_ch_DatagramChannelImpl$connect(Class callerClass, DatagramChannel that, SocketAddress remote); + + // accept + + void check$sun_nio_ch_ServerSocketChannelImpl$accept(Class callerClass, ServerSocketChannel that); + + void check$sun_nio_ch_AsynchronousServerSocketChannelImpl$accept(Class callerClass, AsynchronousServerSocketChannel that); + + void check$sun_nio_ch_AsynchronousServerSocketChannelImpl$accept( + Class callerClass, + AsynchronousServerSocketChannel that, + Object attachment, + CompletionHandler handler + ); + + // send/receive + + void check$sun_nio_ch_DatagramChannelImpl$send(Class callerClass, DatagramChannel that, ByteBuffer src, SocketAddress target); + + void check$sun_nio_ch_DatagramChannelImpl$receive(Class callerClass, DatagramChannel that, ByteBuffer dst); } diff --git a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java index fb8d3a8273ec0..553c025143725 100644 --- a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java +++ b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/NetworkAccessCheckActions.java @@ -17,16 +17,27 @@ import java.net.Proxy; import java.net.ServerSocket; import java.net.Socket; +import java.net.SocketException; import java.net.URI; import java.net.URISyntaxException; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousServerSocketChannel; +import java.nio.channels.AsynchronousSocketChannel; +import java.nio.channels.CompletionHandler; +import java.nio.channels.DatagramChannel; +import java.nio.channels.NotYetBoundException; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertStore; import java.util.Arrays; +import java.util.concurrent.ExecutionException; +@SuppressForbidden(reason = "Testing entitlement check on forbidden action") class NetworkAccessCheckActions { static void serverSocketAccept() throws IOException { @@ -49,7 +60,6 @@ static void serverSocketBind() throws IOException { } } - @SuppressForbidden(reason = "Testing entitlement check on forbidden action") static void createSocketWithProxy() throws IOException { try (Socket socket = new Socket(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(0)))) { assert socket.isBound() == false; @@ -62,14 +72,12 @@ static void socketBind() throws IOException { } } - @SuppressForbidden(reason = "Testing entitlement check on forbidden action") static void socketConnect() throws IOException { try (Socket socket = new DummyImplementations.DummySocket()) { socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); } } - @SuppressForbidden(reason = "Testing entitlement check on forbidden action") static void urlOpenConnectionWithProxy() throws URISyntaxException, IOException { var url = new URI("http://localhost").toURL(); var urlConnection = url.openConnection(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(0))); @@ -90,7 +98,8 @@ static void httpClientSend() throws InterruptedException { try { httpClient.send(HttpRequest.newBuilder(URI.create("http://localhost")).build(), HttpResponse.BodyHandlers.discarding()); } catch (IOException e) { - // Expected, since we shut down the client + // Expected, since we shut down the client. + // "send" will be called and exercise the Entitlement check, we don't care if it fails afterward for this known reason. } } } @@ -121,4 +130,154 @@ static void createLDAPCertStore() throws NoSuchAlgorithmException { assert Arrays.stream(ex.getStackTrace()).anyMatch(e -> e.getClassName().endsWith("LDAPCertStore")); } } + + static void serverSocketChannelBind() throws IOException { + try (var serverSocketChannel = ServerSocketChannel.open()) { + serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } + } + + static void serverSocketChannelBindWithBacklog() throws IOException { + try (var serverSocketChannel = ServerSocketChannel.open()) { + serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 50); + } + } + + static void serverSocketChannelAccept() throws IOException { + try (var serverSocketChannel = ServerSocketChannel.open()) { + serverSocketChannel.configureBlocking(false); + try { + serverSocketChannel.accept(); + } catch (NotYetBoundException e) { + // It's OK, we did not call bind on the socket on purpose so we can just test "accept" + // "accept" will be called and exercise the Entitlement check, we don't care if it fails afterward for this known reason. + } + } + } + + static void asynchronousServerSocketChannelBind() throws IOException { + try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) { + serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } + } + + static void asynchronousServerSocketChannelBindWithBacklog() throws IOException { + try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) { + serverSocketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 50); + } + } + + static void asynchronousServerSocketChannelAccept() throws IOException { + try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) { + try { + var future = serverSocketChannel.accept(); + future.cancel(true); + } catch (NotYetBoundException e) { + // It's OK, we did not call bind on the socket on purpose so we can just test "accept" + // "accept" will be called and exercise the Entitlement check, we don't care if it fails afterward for this known reason. + } + } + } + + static void asynchronousServerSocketChannelAcceptWithHandler() throws IOException { + try (var serverSocketChannel = AsynchronousServerSocketChannel.open()) { + try { + serverSocketChannel.accept(null, new CompletionHandler<>() { + @Override + public void completed(AsynchronousSocketChannel result, Object attachment) {} + + @Override + public void failed(Throwable exc, Object attachment) { + assert exc.getClass().getSimpleName().equals("NotEntitledException") == false; + } + }); + } catch (NotYetBoundException e) { + // It's OK, we did not call bind on the socket on purpose so we can just test "accept" + // "accept" will be called and exercise the Entitlement check, we don't care if it fails afterward for this known reason. + } + } + } + + static void socketChannelBind() throws IOException { + try (var socketChannel = SocketChannel.open()) { + socketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } + } + + static void socketChannelConnect() throws IOException { + try (var socketChannel = SocketChannel.open()) { + try { + socketChannel.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } catch (SocketException e) { + // We expect to fail, not a valid address to connect to. + // "connect" will be called and exercise the Entitlement check, we don't care if it fails afterward for this known reason. + } + } + } + + static void asynchronousSocketChannelBind() throws IOException { + try (var socketChannel = AsynchronousSocketChannel.open()) { + socketChannel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } + } + + static void asynchronousSocketChannelConnect() throws IOException, InterruptedException { + try (var socketChannel = AsynchronousSocketChannel.open()) { + var future = socketChannel.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + try { + future.get(); + } catch (ExecutionException e) { + assert e.getCause().getClass().getSimpleName().equals("NotEntitledException") == false; + } finally { + future.cancel(true); + } + } + } + + static void asynchronousSocketChannelConnectWithCompletion() throws IOException { + try (var socketChannel = AsynchronousSocketChannel.open()) { + socketChannel.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), null, new CompletionHandler<>() { + @Override + public void completed(Void result, Object attachment) {} + + @Override + public void failed(Throwable exc, Object attachment) { + assert exc.getClass().getSimpleName().equals("NotEntitledException") == false; + } + }); + } + } + + static void datagramChannelBind() throws IOException { + try (var channel = DatagramChannel.open()) { + channel.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } + } + + static void datagramChannelConnect() throws IOException { + try (var channel = DatagramChannel.open()) { + channel.configureBlocking(false); + try { + channel.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0)); + } catch (SocketException e) { + // We expect to fail, not a valid address to connect to. + // "connect" will be called and exercise the Entitlement check, we don't care if it fails afterward for this known reason. + } + } + } + + static void datagramChannelSend() throws IOException { + try (var channel = DatagramChannel.open()) { + channel.configureBlocking(false); + channel.send(ByteBuffer.wrap(new byte[] { 0 }), new InetSocketAddress(InetAddress.getLoopbackAddress(), 1234)); + } + } + + static void datagramChannelReceive() throws IOException { + try (var channel = DatagramChannel.open()) { + channel.configureBlocking(false); + var buffer = new byte[1]; + channel.receive(ByteBuffer.wrap(buffer)); + } + } } diff --git a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java index 9c25868254b42..5286430dc25f7 100644 --- a/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java +++ b/libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java @@ -90,7 +90,7 @@ static CheckAction alwaysDenied(CheckedRunnable action) { } } - private static final Map checkActions = Stream.of( + private static final Map checkActions = Stream.>of( entry("runtime_exit", deniedToPlugins(RestEntitlementsCheckAction::runtimeExit)), entry("runtime_halt", deniedToPlugins(RestEntitlementsCheckAction::runtimeHalt)), entry("system_exit", deniedToPlugins(RestEntitlementsCheckAction::systemExit)), @@ -163,7 +163,33 @@ static CheckAction alwaysDenied(CheckedRunnable action) { entry("http_client_builder_build", forPlugins(NetworkAccessCheckActions::httpClientBuilderBuild)), entry("http_client_send", forPlugins(NetworkAccessCheckActions::httpClientSend)), entry("http_client_send_async", forPlugins(NetworkAccessCheckActions::httpClientSendAsync)), - entry("create_ldap_cert_store", forPlugins(NetworkAccessCheckActions::createLDAPCertStore)) + 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)) ) .filter(entry -> entry.getValue().fromJavaVersion() == null || Runtime.version().feature() >= entry.getValue().fromJavaVersion()) .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java index 9b621461403d1..aa16215d0f832 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java @@ -109,7 +109,8 @@ private static PolicyManager createPolicyManager() throws IOException { new NetworkEntitlement(LISTEN_ACTION | CONNECT_ACTION | ACCEPT_ACTION) ) ), - new Scope("org.apache.httpcomponents.httpclient", List.of(new NetworkEntitlement(CONNECT_ACTION))) + new Scope("org.apache.httpcomponents.httpclient", List.of(new NetworkEntitlement(CONNECT_ACTION))), + new Scope("io.netty.transport", List.of(new NetworkEntitlement(LISTEN_ACTION))) ) ); // agents run without a module, so this is a special hack for the apm agent diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java index 779ea103231a2..3748323131e33 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java @@ -22,6 +22,7 @@ import java.net.DatagramSocketImplFactory; import java.net.FileNameMap; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.MulticastSocket; import java.net.NetworkInterface; import java.net.Proxy; @@ -37,6 +38,13 @@ import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; +import java.nio.ByteBuffer; +import java.nio.channels.AsynchronousServerSocketChannel; +import java.nio.channels.AsynchronousSocketChannel; +import java.nio.channels.CompletionHandler; +import java.nio.channels.DatagramChannel; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; import java.security.cert.CertStoreParameters; import java.util.List; @@ -561,4 +569,125 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) { policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); } } + + @Override + public void check$java_nio_channels_AsynchronousServerSocketChannel$bind( + Class callerClass, + AsynchronousServerSocketChannel that, + SocketAddress local + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$sun_nio_ch_AsynchronousServerSocketChannelImpl$bind( + Class callerClass, + AsynchronousServerSocketChannel that, + SocketAddress local, + int backlog + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$sun_nio_ch_AsynchronousSocketChannelImpl$bind( + Class callerClass, + AsynchronousSocketChannel that, + SocketAddress local + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$sun_nio_ch_DatagramChannelImpl$bind(Class callerClass, DatagramChannel that, SocketAddress local) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$java_nio_channels_ServerSocketChannel$bind(Class callerClass, ServerSocketChannel that, SocketAddress local) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$sun_nio_ch_ServerSocketChannelImpl$bind( + Class callerClass, + ServerSocketChannel that, + SocketAddress local, + int backlog + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$sun_nio_ch_SocketChannelImpl$bind(Class callerClass, SocketChannel that, SocketAddress local) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION); + } + + @Override + public void check$sun_nio_ch_SocketChannelImpl$connect(Class callerClass, SocketChannel that, SocketAddress remote) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$sun_nio_ch_AsynchronousSocketChannelImpl$connect( + Class callerClass, + AsynchronousSocketChannel that, + SocketAddress remote + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$sun_nio_ch_AsynchronousSocketChannelImpl$connect( + Class callerClass, + AsynchronousSocketChannel that, + SocketAddress remote, + Object attachment, + CompletionHandler handler + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$sun_nio_ch_DatagramChannelImpl$connect(Class callerClass, DatagramChannel that, SocketAddress remote) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$sun_nio_ch_ServerSocketChannelImpl$accept(Class callerClass, ServerSocketChannel that) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.ACCEPT_ACTION); + } + + @Override + public void check$sun_nio_ch_AsynchronousServerSocketChannelImpl$accept(Class callerClass, AsynchronousServerSocketChannel that) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.ACCEPT_ACTION); + } + + @Override + public void check$sun_nio_ch_AsynchronousServerSocketChannelImpl$accept( + Class callerClass, + AsynchronousServerSocketChannel that, + Object attachment, + CompletionHandler handler + ) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.ACCEPT_ACTION); + } + + @Override + public void check$sun_nio_ch_DatagramChannelImpl$send( + Class callerClass, + DatagramChannel that, + ByteBuffer src, + SocketAddress target + ) { + if (target instanceof InetSocketAddress isa && isa.getAddress().isMulticastAddress()) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.ACCEPT_ACTION | NetworkEntitlement.CONNECT_ACTION); + } + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION); + } + + @Override + public void check$sun_nio_ch_DatagramChannelImpl$receive(Class callerClass, DatagramChannel that, ByteBuffer dst) { + policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.ACCEPT_ACTION); + } } diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java index aeb54d5c1156c..13ac564f67196 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java @@ -114,8 +114,8 @@ public void checkStartProcess(Class callerClass) { } private void neverEntitled(Class callerClass, String operationDescription) { - var requestingModule = requestingClass(callerClass); - if (isTriviallyAllowed(requestingModule)) { + var requestingClass = requestingClass(callerClass); + if (isTriviallyAllowed(requestingClass)) { return; } @@ -123,7 +123,7 @@ private void neverEntitled(Class callerClass, String operationDescription) { Strings.format( "Not entitled: caller [%s], module [%s], operation [%s]", callerClass, - requestingModule.getName(), + requestingClass.getModule() == null ? "" : requestingClass.getModule().getName(), operationDescription ) ); @@ -134,8 +134,8 @@ private void neverEntitled(Class callerClass, String operationDescription) { * therefore, its performance is not a major concern. */ private void neverEntitled(Class callerClass, Supplier operationDescription) { - var requestingModule = requestingClass(callerClass); - if (isTriviallyAllowed(requestingModule)) { + var requestingClass = requestingClass(callerClass); + if (isTriviallyAllowed(requestingClass)) { return; } @@ -143,7 +143,7 @@ private void neverEntitled(Class callerClass, Supplier operationDescr Strings.format( "Not entitled: caller [%s], module [%s], operation [%s]", callerClass, - requestingModule.getName(), + requestingClass.getModule() == null ? "" : requestingClass.getModule().getName(), operationDescription.get() ) ); @@ -206,7 +206,7 @@ public void checkNetworkAccess(Class callerClass, int actions) { () -> Strings.format( "Entitled: class [%s], module [%s], entitlement [network], actions [%s]", requestingClass, - requestingClass.getModule().getName(), + requestingClass.getModule() == null ? "" : requestingClass.getModule().getName(), NetworkEntitlement.printActions(actions) ) ); @@ -216,7 +216,7 @@ public void checkNetworkAccess(Class callerClass, int actions) { Strings.format( "Missing entitlement: class [%s], module [%s], entitlement [network], actions [%s]", requestingClass, - requestingClass.getModule().getName(), + requestingClass.getModule() == null ? "" : requestingClass.getModule().getName(), NetworkEntitlement.printActions(actions) ) ); diff --git a/modules/reindex/src/main/plugin-metadata/entitlement-policy.yaml b/modules/reindex/src/main/plugin-metadata/entitlement-policy.yaml new file mode 100644 index 0000000000000..4c42ec110a257 --- /dev/null +++ b/modules/reindex/src/main/plugin-metadata/entitlement-policy.yaml @@ -0,0 +1,4 @@ +ALL-UNNAMED: + - network: + actions: + - connect diff --git a/modules/repository-azure/src/main/plugin-metadata/entitlement-policy.yaml b/modules/repository-azure/src/main/plugin-metadata/entitlement-policy.yaml new file mode 100644 index 0000000000000..9340655013763 --- /dev/null +++ b/modules/repository-azure/src/main/plugin-metadata/entitlement-policy.yaml @@ -0,0 +1,4 @@ +io.netty.common: + - network: + actions: + - connect diff --git a/modules/transport-netty4/src/main/plugin-metadata/entitlement-policy.yaml b/modules/transport-netty4/src/main/plugin-metadata/entitlement-policy.yaml new file mode 100644 index 0000000000000..4ccf7e0af393e --- /dev/null +++ b/modules/transport-netty4/src/main/plugin-metadata/entitlement-policy.yaml @@ -0,0 +1,9 @@ +io.netty.transport: + - network: + actions: + - listen +io.netty.common: + - network: + actions: + - connect + - accept diff --git a/plugins/repository-hdfs/src/main/plugin-metadata/entitlement-policy.yaml b/plugins/repository-hdfs/src/main/plugin-metadata/entitlement-policy.yaml new file mode 100644 index 0000000000000..4c42ec110a257 --- /dev/null +++ b/plugins/repository-hdfs/src/main/plugin-metadata/entitlement-policy.yaml @@ -0,0 +1,4 @@ +ALL-UNNAMED: + - network: + actions: + - connect diff --git a/x-pack/plugin/core/src/main/plugin-metadata/entitlement-policy.yaml b/x-pack/plugin/core/src/main/plugin-metadata/entitlement-policy.yaml index 8983dd6663e65..ca6f10e526cef 100644 --- a/x-pack/plugin/core/src/main/plugin-metadata/entitlement-policy.yaml +++ b/x-pack/plugin/core/src/main/plugin-metadata/entitlement-policy.yaml @@ -2,3 +2,7 @@ org.apache.httpcomponents.httpclient: - network: actions: - connect # For SamlRealm +org.apache.httpcomponents.httpcore.nio: + - network: + actions: + - connect diff --git a/x-pack/plugin/security/src/main/plugin-metadata/entitlement-policy.yaml b/x-pack/plugin/security/src/main/plugin-metadata/entitlement-policy.yaml index 98c6b81553572..df059585cef44 100644 --- a/x-pack/plugin/security/src/main/plugin-metadata/entitlement-policy.yaml +++ b/x-pack/plugin/security/src/main/plugin-metadata/entitlement-policy.yaml @@ -1,2 +1,11 @@ org.elasticsearch.security: - set_https_connection_properties # for CommandLineHttpClient +io.netty.transport: + - network: + actions: + - listen +io.netty.common: + - network: + actions: + - accept + - connect