mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 09:28:55 -04:00
[Entitlements] Network access checks on Sockets (#120093)
This commit is contained in:
parent
1448f12d23
commit
1848d6bb93
13 changed files with 356 additions and 31 deletions
|
@ -20,8 +20,11 @@ import java.net.FileNameMap;
|
|||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
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.SocketAddress;
|
||||
import java.net.SocketImplFactory;
|
||||
import java.net.URL;
|
||||
|
@ -215,4 +218,40 @@ public interface EntitlementChecker {
|
|||
void check$java_net_MulticastSocket$leaveGroup(Class<?> callerClass, MulticastSocket that, SocketAddress addr, NetworkInterface ni);
|
||||
|
||||
void check$java_net_MulticastSocket$send(Class<?> callerClass, MulticastSocket that, DatagramPacket p, byte ttl);
|
||||
|
||||
// Binding/connecting ctor
|
||||
void check$java_net_ServerSocket$(Class<?> callerClass, int port);
|
||||
|
||||
void check$java_net_ServerSocket$(Class<?> callerClass, int port, int backlog);
|
||||
|
||||
void check$java_net_ServerSocket$(Class<?> callerClass, int port, int backlog, InetAddress bindAddr);
|
||||
|
||||
void check$java_net_ServerSocket$accept(Class<?> callerClass, ServerSocket that);
|
||||
|
||||
void check$java_net_ServerSocket$implAccept(Class<?> callerClass, ServerSocket that, Socket s);
|
||||
|
||||
void check$java_net_ServerSocket$bind(Class<?> callerClass, ServerSocket that, SocketAddress endpoint);
|
||||
|
||||
void check$java_net_ServerSocket$bind(Class<?> callerClass, ServerSocket that, SocketAddress endpoint, int backlog);
|
||||
|
||||
// Binding/connecting ctors
|
||||
void check$java_net_Socket$(Class<?> callerClass, Proxy proxy);
|
||||
|
||||
void check$java_net_Socket$(Class<?> callerClass, String host, int port);
|
||||
|
||||
void check$java_net_Socket$(Class<?> callerClass, InetAddress address, int port);
|
||||
|
||||
void check$java_net_Socket$(Class<?> callerClass, String host, int port, InetAddress localAddr, int localPort);
|
||||
|
||||
void check$java_net_Socket$(Class<?> callerClass, InetAddress address, int port, InetAddress localAddr, int localPort);
|
||||
|
||||
void check$java_net_Socket$(Class<?> callerClass, String host, int port, boolean stream);
|
||||
|
||||
void check$java_net_Socket$(Class<?> callerClass, InetAddress host, int port, boolean stream);
|
||||
|
||||
void check$java_net_Socket$bind(Class<?> callerClass, Socket that, SocketAddress endpoint);
|
||||
|
||||
void check$java_net_Socket$connect(Class<?> callerClass, Socket that, SocketAddress endpoint);
|
||||
|
||||
void check$java_net_Socket$connect(Class<?> callerClass, Socket that, SocketAddress endpoint, int backlog);
|
||||
}
|
||||
|
|
|
@ -10,14 +10,18 @@
|
|||
package org.elasticsearch.entitlement.qa.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.DatagramSocketImpl;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.SocketImpl;
|
||||
import java.security.cert.Certificate;
|
||||
import java.text.BreakIterator;
|
||||
import java.text.Collator;
|
||||
|
@ -297,6 +301,81 @@ class DummyImplementations {
|
|||
}
|
||||
}
|
||||
|
||||
private static class DummySocketImpl extends SocketImpl {
|
||||
@Override
|
||||
protected void create(boolean stream) {}
|
||||
|
||||
@Override
|
||||
protected void connect(String host, int port) {}
|
||||
|
||||
@Override
|
||||
protected void connect(InetAddress address, int port) {}
|
||||
|
||||
@Override
|
||||
protected void connect(SocketAddress address, int timeout) {}
|
||||
|
||||
@Override
|
||||
protected void bind(InetAddress host, int port) {}
|
||||
|
||||
@Override
|
||||
protected void listen(int backlog) {}
|
||||
|
||||
@Override
|
||||
protected void accept(SocketImpl s) {}
|
||||
|
||||
@Override
|
||||
protected InputStream getInputStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OutputStream getOutputStream() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int available() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close() {}
|
||||
|
||||
@Override
|
||||
protected void sendUrgentData(int data) {}
|
||||
|
||||
@Override
|
||||
public void setOption(int optID, Object value) {}
|
||||
|
||||
@Override
|
||||
public Object getOption(int optID) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static class DummySocket extends Socket {
|
||||
DummySocket() throws SocketException {
|
||||
super(new DummySocketImpl());
|
||||
}
|
||||
}
|
||||
|
||||
static class DummyServerSocket extends ServerSocket {
|
||||
DummyServerSocket() {
|
||||
super(new DummySocketImpl());
|
||||
}
|
||||
}
|
||||
|
||||
static class DummyBoundServerSocket extends ServerSocket {
|
||||
DummyBoundServerSocket() {
|
||||
super(new DummySocketImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBound() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static class DummySSLSocketFactory extends SSLSocketFactory {
|
||||
@Override
|
||||
public Socket createSocket(String host, int port) {
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the "Elastic License
|
||||
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
|
||||
* Public License v 1"; you may not use this file except in compliance with, at
|
||||
* your election, the "Elastic License 2.0", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
package org.elasticsearch.entitlement.qa.common;
|
||||
|
||||
import org.elasticsearch.core.SuppressForbidden;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Proxy;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
class NetworkAccessCheckActions {
|
||||
|
||||
static void serverSocketAccept() throws IOException {
|
||||
try (ServerSocket socket = new DummyImplementations.DummyBoundServerSocket()) {
|
||||
try {
|
||||
socket.accept();
|
||||
} catch (IOException e) {
|
||||
// Our dummy socket cannot accept connections unless we tell the JDK how to create a socket for it.
|
||||
// But Socket.setSocketImplFactory(); is one of the methods we always forbid, so we cannot use it.
|
||||
// Still, we can check accept is called (allowed/denied), we don't care if it fails later for this
|
||||
// known reason.
|
||||
assert e.getMessage().contains("client socket implementation factory not set");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void serverSocketBind() throws IOException {
|
||||
try (ServerSocket socket = new DummyImplementations.DummyServerSocket()) {
|
||||
socket.bind(null);
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
|
||||
static void socketBind() throws IOException {
|
||||
try (Socket socket = new DummyImplementations.DummySocket()) {
|
||||
socket.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
|
||||
}
|
||||
}
|
||||
|
||||
@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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -149,7 +149,13 @@ public class RestEntitlementsCheckAction extends BaseRestHandler {
|
|||
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("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))
|
||||
);
|
||||
|
||||
private static void createURLStreamHandlerProvider() {
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.elasticsearch.entitlement.runtime.api.ElasticsearchEntitlementChecker
|
|||
import org.elasticsearch.entitlement.runtime.policy.CreateClassLoaderEntitlement;
|
||||
import org.elasticsearch.entitlement.runtime.policy.Entitlement;
|
||||
import org.elasticsearch.entitlement.runtime.policy.ExitVMEntitlement;
|
||||
import org.elasticsearch.entitlement.runtime.policy.NetworkEntitlement;
|
||||
import org.elasticsearch.entitlement.runtime.policy.Policy;
|
||||
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
|
||||
import org.elasticsearch.entitlement.runtime.policy.PolicyParser;
|
||||
|
@ -44,6 +45,9 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.entitlement.runtime.policy.NetworkEntitlement.ACCEPT_ACTION;
|
||||
import static org.elasticsearch.entitlement.runtime.policy.NetworkEntitlement.CONNECT_ACTION;
|
||||
import static org.elasticsearch.entitlement.runtime.policy.NetworkEntitlement.LISTEN_ACTION;
|
||||
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ALL_UNNAMED;
|
||||
|
||||
/**
|
||||
|
@ -97,7 +101,15 @@ public class EntitlementInitialization {
|
|||
List.of(
|
||||
new Scope("org.elasticsearch.base", List.of(new CreateClassLoaderEntitlement())),
|
||||
new Scope("org.elasticsearch.xcontent", List.of(new CreateClassLoaderEntitlement())),
|
||||
new Scope("org.elasticsearch.server", List.of(new ExitVMEntitlement(), new CreateClassLoaderEntitlement()))
|
||||
new Scope(
|
||||
"org.elasticsearch.server",
|
||||
List.of(
|
||||
new ExitVMEntitlement(),
|
||||
new CreateClassLoaderEntitlement(),
|
||||
new NetworkEntitlement(LISTEN_ACTION | CONNECT_ACTION | ACCEPT_ACTION)
|
||||
)
|
||||
),
|
||||
new Scope("org.apache.httpcomponents.httpclient", List.of(new NetworkEntitlement(CONNECT_ACTION)))
|
||||
)
|
||||
);
|
||||
// agents run without a module, so this is a special hack for the apm agent
|
||||
|
|
|
@ -24,8 +24,11 @@ import java.net.FileNameMap;
|
|||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
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.SocketAddress;
|
||||
import java.net.SocketImplFactory;
|
||||
import java.net.URL;
|
||||
|
@ -414,4 +417,91 @@ public class ElasticsearchEntitlementChecker implements EntitlementChecker {
|
|||
public void check$java_net_MulticastSocket$send(Class<?> callerClass, MulticastSocket that, DatagramPacket p, byte ttl) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION | NetworkEntitlement.ACCEPT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_ServerSocket$(Class<?> callerClass, int port) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_ServerSocket$(Class<?> callerClass, int port, int backlog) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_ServerSocket$(Class<?> callerClass, int port, int backlog, InetAddress bindAddr) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_ServerSocket$accept(Class<?> callerClass, ServerSocket that) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.ACCEPT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_ServerSocket$implAccept(Class<?> callerClass, ServerSocket that, Socket s) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.ACCEPT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_ServerSocket$bind(Class<?> callerClass, ServerSocket that, SocketAddress endpoint) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_ServerSocket$bind(Class<?> callerClass, ServerSocket that, SocketAddress endpoint, int backlog) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$(Class<?> callerClass, Proxy proxy) {
|
||||
if (proxy.type() == Proxy.Type.SOCKS || proxy.type() == Proxy.Type.HTTP) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$(Class<?> callerClass, String host, int port) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION | NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$(Class<?> callerClass, InetAddress address, int port) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION | NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$(Class<?> callerClass, String host, int port, InetAddress localAddr, int localPort) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION | NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$(Class<?> callerClass, InetAddress address, int port, InetAddress localAddr, int localPort) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION | NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$(Class<?> callerClass, String host, int port, boolean stream) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION | NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$(Class<?> callerClass, InetAddress host, int port, boolean stream) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION | NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$bind(Class<?> callerClass, Socket that, SocketAddress endpoint) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.LISTEN_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$connect(Class<?> callerClass, Socket that, SocketAddress endpoint) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check$java_net_Socket$connect(Class<?> callerClass, Socket that, SocketAddress endpoint, int backlog) {
|
||||
policyManager.checkNetworkAccess(callerClass, NetworkEntitlement.CONNECT_ACTION);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,11 @@ public class NetworkEntitlement implements Entitlement {
|
|||
this.actions = actionsInt;
|
||||
}
|
||||
|
||||
public static Object printActions(int actions) {
|
||||
public NetworkEntitlement(int actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public static String printActions(int actions) {
|
||||
var joiner = new StringJoiner(",");
|
||||
for (var entry : ACTION_MAP.entrySet()) {
|
||||
var action = entry.getValue();
|
||||
|
|
|
@ -200,21 +200,21 @@ public class PolicyManager {
|
|||
return;
|
||||
}
|
||||
|
||||
ModuleEntitlements entitlements = getEntitlements(requestingClass);
|
||||
ModuleEntitlements entitlements = getEntitlements(requestingClass, NetworkEntitlement.class);
|
||||
if (entitlements.getEntitlements(NetworkEntitlement.class).anyMatch(n -> n.matchActions(actions))) {
|
||||
logger.debug(
|
||||
() -> Strings.format(
|
||||
"Entitled: class [%s], module [%s], entitlement [Network], actions [Ox%X]",
|
||||
"Entitled: class [%s], module [%s], entitlement [network], actions [%s]",
|
||||
requestingClass,
|
||||
requestingClass.getModule().getName(),
|
||||
actions
|
||||
NetworkEntitlement.printActions(actions)
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
throw new NotEntitledException(
|
||||
Strings.format(
|
||||
"Missing entitlement: class [%s], module [%s], entitlement [Network], actions [%s]",
|
||||
"Missing entitlement: class [%s], module [%s], entitlement [network], actions [%s]",
|
||||
requestingClass,
|
||||
requestingClass.getModule().getName(),
|
||||
NetworkEntitlement.printActions(actions)
|
||||
|
@ -228,14 +228,14 @@ public class PolicyManager {
|
|||
return;
|
||||
}
|
||||
|
||||
ModuleEntitlements entitlements = getEntitlements(requestingClass);
|
||||
ModuleEntitlements entitlements = getEntitlements(requestingClass, entitlementClass);
|
||||
if (entitlements.hasEntitlement(entitlementClass)) {
|
||||
logger.debug(
|
||||
() -> Strings.format(
|
||||
"Entitled: class [%s], module [%s], entitlement [%s]",
|
||||
requestingClass,
|
||||
requestingClass.getModule().getName(),
|
||||
entitlementClass.getSimpleName()
|
||||
PolicyParser.getEntitlementTypeName(entitlementClass)
|
||||
)
|
||||
);
|
||||
return;
|
||||
|
@ -245,19 +245,22 @@ public class PolicyManager {
|
|||
"Missing entitlement: class [%s], module [%s], entitlement [%s]",
|
||||
requestingClass,
|
||||
requestingClass.getModule().getName(),
|
||||
entitlementClass.getSimpleName()
|
||||
PolicyParser.getEntitlementTypeName(entitlementClass)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
ModuleEntitlements getEntitlements(Class<?> requestingClass) {
|
||||
return moduleEntitlementsMap.computeIfAbsent(requestingClass.getModule(), m -> computeEntitlements(requestingClass));
|
||||
ModuleEntitlements getEntitlements(Class<?> requestingClass, Class<? extends Entitlement> entitlementClass) {
|
||||
return moduleEntitlementsMap.computeIfAbsent(
|
||||
requestingClass.getModule(),
|
||||
m -> computeEntitlements(requestingClass, entitlementClass)
|
||||
);
|
||||
}
|
||||
|
||||
private ModuleEntitlements computeEntitlements(Class<?> requestingClass) {
|
||||
private ModuleEntitlements computeEntitlements(Class<?> requestingClass, Class<? extends Entitlement> entitlementClass) {
|
||||
Module requestingModule = requestingClass.getModule();
|
||||
if (isServerModule(requestingModule)) {
|
||||
return getModuleScopeEntitlements(requestingClass, serverEntitlements, requestingModule.getName());
|
||||
return getModuleScopeEntitlements(requestingClass, serverEntitlements, requestingModule.getName(), "server", entitlementClass);
|
||||
}
|
||||
|
||||
// plugins
|
||||
|
@ -271,7 +274,7 @@ public class PolicyManager {
|
|||
} else {
|
||||
scopeName = requestingModule.getName();
|
||||
}
|
||||
return getModuleScopeEntitlements(requestingClass, pluginEntitlements, scopeName);
|
||||
return getModuleScopeEntitlements(requestingClass, pluginEntitlements, scopeName, pluginName, entitlementClass);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,11 +290,19 @@ public class PolicyManager {
|
|||
private ModuleEntitlements getModuleScopeEntitlements(
|
||||
Class<?> callerClass,
|
||||
Map<String, List<Entitlement>> scopeEntitlements,
|
||||
String moduleName
|
||||
String moduleName,
|
||||
String component,
|
||||
Class<? extends Entitlement> entitlementClass
|
||||
) {
|
||||
var entitlements = scopeEntitlements.get(moduleName);
|
||||
if (entitlements == null) {
|
||||
logger.warn("No applicable entitlement policy for module [{}], class [{}]", moduleName, callerClass);
|
||||
logger.warn(
|
||||
"No applicable entitlement policy for entitlement [{}] in [{}], module [{}], class [{}]",
|
||||
PolicyParser.getEntitlementTypeName(entitlementClass),
|
||||
component,
|
||||
moduleName,
|
||||
callerClass
|
||||
);
|
||||
return ModuleEntitlements.NONE;
|
||||
}
|
||||
return ModuleEntitlements.from(entitlements);
|
||||
|
|
|
@ -38,7 +38,7 @@ import static org.hamcrest.Matchers.sameInstance;
|
|||
public class PolicyManagerTests extends ESTestCase {
|
||||
/**
|
||||
* A module you can use for test cases that don't actually care about the
|
||||
* entitlements module.
|
||||
* entitlement module.
|
||||
*/
|
||||
private static Module NO_ENTITLEMENTS_MODULE;
|
||||
|
||||
|
@ -66,7 +66,11 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
var callerClass = this.getClass();
|
||||
var requestingModule = callerClass.getModule();
|
||||
|
||||
assertEquals("No policy for the unnamed module", ModuleEntitlements.NONE, policyManager.getEntitlements(callerClass));
|
||||
assertEquals(
|
||||
"No policy for the unnamed module",
|
||||
ModuleEntitlements.NONE,
|
||||
policyManager.getEntitlements(callerClass, Entitlement.class)
|
||||
);
|
||||
|
||||
assertEquals(Map.of(requestingModule, ModuleEntitlements.NONE), policyManager.moduleEntitlementsMap);
|
||||
}
|
||||
|
@ -78,7 +82,7 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
var callerClass = this.getClass();
|
||||
var requestingModule = callerClass.getModule();
|
||||
|
||||
assertEquals("No policy for this plugin", ModuleEntitlements.NONE, policyManager.getEntitlements(callerClass));
|
||||
assertEquals("No policy for this plugin", ModuleEntitlements.NONE, policyManager.getEntitlements(callerClass, Entitlement.class));
|
||||
|
||||
assertEquals(Map.of(requestingModule, ModuleEntitlements.NONE), policyManager.moduleEntitlementsMap);
|
||||
}
|
||||
|
@ -90,11 +94,11 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
var callerClass = this.getClass();
|
||||
var requestingModule = callerClass.getModule();
|
||||
|
||||
assertEquals(ModuleEntitlements.NONE, policyManager.getEntitlements(callerClass));
|
||||
assertEquals(ModuleEntitlements.NONE, policyManager.getEntitlements(callerClass, Entitlement.class));
|
||||
assertEquals(Map.of(requestingModule, ModuleEntitlements.NONE), policyManager.moduleEntitlementsMap);
|
||||
|
||||
// A second time
|
||||
assertEquals(ModuleEntitlements.NONE, policyManager.getEntitlements(callerClass));
|
||||
assertEquals(ModuleEntitlements.NONE, policyManager.getEntitlements(callerClass, Entitlement.class));
|
||||
|
||||
// Nothing new in the map
|
||||
assertEquals(Map.of(requestingModule, ModuleEntitlements.NONE), policyManager.moduleEntitlementsMap);
|
||||
|
@ -112,7 +116,7 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
// Any class from the current module (unnamed) will do
|
||||
var callerClass = this.getClass();
|
||||
|
||||
var entitlements = policyManager.getEntitlements(callerClass);
|
||||
var entitlements = policyManager.getEntitlements(callerClass, Entitlement.class);
|
||||
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
|
||||
}
|
||||
|
||||
|
@ -126,7 +130,11 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
var mockServerClass = ModuleLayer.boot().findLoader("jdk.httpserver").loadClass("com.sun.net.httpserver.HttpServer");
|
||||
var requestingModule = mockServerClass.getModule();
|
||||
|
||||
assertEquals("No policy for this module in server", ModuleEntitlements.NONE, policyManager.getEntitlements(mockServerClass));
|
||||
assertEquals(
|
||||
"No policy for this module in server",
|
||||
ModuleEntitlements.NONE,
|
||||
policyManager.getEntitlements(mockServerClass, Entitlement.class)
|
||||
);
|
||||
|
||||
assertEquals(Map.of(requestingModule, ModuleEntitlements.NONE), policyManager.moduleEntitlementsMap);
|
||||
}
|
||||
|
@ -145,9 +153,8 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
// So we use a random module in the boot layer, and a random class from that module (not java.base -- it is
|
||||
// loaded too early) to mimic a class that would be in the server module.
|
||||
var mockServerClass = ModuleLayer.boot().findLoader("jdk.httpserver").loadClass("com.sun.net.httpserver.HttpServer");
|
||||
var requestingModule = mockServerClass.getModule();
|
||||
|
||||
var entitlements = policyManager.getEntitlements(mockServerClass);
|
||||
var entitlements = policyManager.getEntitlements(mockServerClass, Entitlement.class);
|
||||
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
|
||||
assertThat(entitlements.hasEntitlement(ExitVMEntitlement.class), is(true));
|
||||
}
|
||||
|
@ -167,9 +174,8 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
|
||||
var layer = createLayerForJar(jar, "org.example.plugin");
|
||||
var mockPluginClass = layer.findLoader("org.example.plugin").loadClass("q.B");
|
||||
var requestingModule = mockPluginClass.getModule();
|
||||
|
||||
var entitlements = policyManager.getEntitlements(mockPluginClass);
|
||||
var entitlements = policyManager.getEntitlements(mockPluginClass, Entitlement.class);
|
||||
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
|
||||
assertThat(
|
||||
entitlements.getEntitlements(FileEntitlement.class).toList(),
|
||||
|
@ -189,11 +195,11 @@ public class PolicyManagerTests extends ESTestCase {
|
|||
// Any class from the current module (unnamed) will do
|
||||
var callerClass = this.getClass();
|
||||
|
||||
var entitlements = policyManager.getEntitlements(callerClass);
|
||||
var entitlements = policyManager.getEntitlements(callerClass, Entitlement.class);
|
||||
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
|
||||
assertThat(policyManager.moduleEntitlementsMap, aMapWithSize(1));
|
||||
var cachedResult = policyManager.moduleEntitlementsMap.values().stream().findFirst().get();
|
||||
var entitlementsAgain = policyManager.getEntitlements(callerClass);
|
||||
var cachedResult = policyManager.moduleEntitlementsMap.values().stream().findFirst().orElseThrow();
|
||||
var entitlementsAgain = policyManager.getEntitlements(callerClass, Entitlement.class);
|
||||
|
||||
// Nothing new in the map
|
||||
assertThat(policyManager.moduleEntitlementsMap, aMapWithSize(1));
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
ALL-UNNAMED:
|
||||
- network:
|
||||
actions:
|
||||
- connect
|
|
@ -0,0 +1,4 @@
|
|||
org.apache.httpcomponents.httpclient:
|
||||
- network:
|
||||
actions:
|
||||
- connect # for URLHttpClient
|
|
@ -0,0 +1,4 @@
|
|||
ALL-UNNAMED:
|
||||
- network:
|
||||
actions:
|
||||
- connect
|
|
@ -0,0 +1,4 @@
|
|||
org.apache.httpcomponents.httpclient:
|
||||
- network:
|
||||
actions:
|
||||
- connect # For SamlRealm
|
Loading…
Add table
Add a link
Reference in a new issue