Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/entitlement/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

exports org.elasticsearch.entitlement.runtime.api;
exports org.elasticsearch.entitlement.runtime.policy;
exports org.elasticsearch.entitlement.runtime.policy.entitlements to org.elasticsearch.server;
exports org.elasticsearch.entitlement.instrumentation;
exports org.elasticsearch.entitlement.bootstrap to org.elasticsearch.server;
exports org.elasticsearch.entitlement.initialization to java.base;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@
import org.elasticsearch.entitlement.instrumentation.MethodKey;
import org.elasticsearch.entitlement.instrumentation.Transformer;
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.InboundNetworkEntitlement;
import org.elasticsearch.entitlement.runtime.policy.LoadNativeLibrariesEntitlement;
import org.elasticsearch.entitlement.runtime.policy.OutboundNetworkEntitlement;
import org.elasticsearch.entitlement.runtime.policy.Policy;
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
import org.elasticsearch.entitlement.runtime.policy.Scope;
import org.elasticsearch.entitlement.runtime.policy.entitlements.CreateClassLoaderEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.Entitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.ExitVMEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.InboundNetworkEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.LoadNativeLibrariesEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.OutboundNetworkEntitlement;

import java.lang.instrument.Instrumentation;
import java.lang.reflect.Constructor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

package org.elasticsearch.entitlement.runtime.policy;

import org.elasticsearch.entitlement.runtime.policy.entitlements.Entitlement;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,21 @@

package org.elasticsearch.entitlement.runtime.policy;

import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.entitlement.runtime.policy.entitlements.FileEntitlement;

import java.io.File;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

final class FileAccessTree {
static final FileAccessTree EMPTY = new FileAccessTree(List.of());
public final class FileAccessTree {
public static final FileAccessTree EMPTY = new FileAccessTree(List.of());

private final String[] readPaths;
private final String[] writePaths;

FileAccessTree(List<FileEntitlement> fileEntitlements) {
private FileAccessTree(List<FileEntitlement> fileEntitlements) {
List<String> readPaths = new ArrayList<>();
List<String> writePaths = new ArrayList<>();
for (FileEntitlement fileEntitlement : fileEntitlements) {
Expand All @@ -42,24 +41,18 @@ final class FileAccessTree {
this.writePaths = writePaths.toArray(new String[0]);
}

boolean canRead(Path path) {
return checkPath(normalize(path), readPaths);
public static FileAccessTree of(List<FileEntitlement> fileEntitlements) {
return new FileAccessTree(fileEntitlements);
}

@SuppressForbidden(reason = "Explicitly checking File apis")
boolean canRead(File file) {
return checkPath(normalize(file.toPath()), readPaths);
boolean canRead(Path path) {
return checkPath(normalize(path), readPaths);
}

boolean canWrite(Path path) {
return checkPath(normalize(path), writePaths);
}

@SuppressForbidden(reason = "Explicitly checking File apis")
boolean canWrite(File file) {
return checkPath(normalize(file.toPath()), writePaths);
}

private static String normalize(Path path) {
return path.toAbsolutePath().normalize().toString();
}
Expand All @@ -71,7 +64,7 @@ private static boolean checkPath(String path, String[] paths) {
int ndx = Arrays.binarySearch(paths, path);
if (ndx < -1) {
String maybeParent = paths[-ndx - 2];
return path.startsWith(maybeParent);
return path.startsWith(maybeParent) && path.charAt(maybeParent.length()) == '/';
}
return ndx >= 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@
import org.elasticsearch.core.Strings;
import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.entitlement.runtime.api.NotEntitledException;
import org.elasticsearch.entitlement.runtime.policy.entitlements.CreateClassLoaderEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.Entitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.ExitVMEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.FileEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.InboundNetworkEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.LoadNativeLibrariesEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.OutboundNetworkEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.SetHttpsConnectionPropertiesEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.WriteSystemPropertiesEntitlement;
import org.elasticsearch.logging.LogManager;
import org.elasticsearch.logging.Logger;

Expand Down Expand Up @@ -53,7 +62,7 @@ public static ModuleEntitlements from(List<Entitlement> entitlements) {
.toList();
return new ModuleEntitlements(
entitlements.stream().collect(groupingBy(Entitlement::getClass)),
new FileAccessTree(fileEntitlements)
FileAccessTree.of(fileEntitlements)
);
}

Expand Down Expand Up @@ -127,23 +136,7 @@ private static Map<String, List<Entitlement>> buildScopeEntitlementsMap(Policy p
}

public void checkStartProcess(Class<?> callerClass) {
neverEntitled(callerClass, "start process");
}

private void neverEntitled(Class<?> callerClass, String operationDescription) {
var requestingClass = requestingClass(callerClass);
if (isTriviallyAllowed(requestingClass)) {
return;
}

throw new NotEntitledException(
Strings.format(
"Not entitled: caller [%s], module [%s], operation [%s]",
callerClass,
requestingClass.getModule() == null ? "<none>" : requestingClass.getModule().getName(),
operationDescription
)
);
neverEntitled(callerClass, () -> "start process");
}

/**
Expand Down Expand Up @@ -199,31 +192,9 @@ public void checkChangeNetworkHandling(Class<?> callerClass) {
checkChangeJVMGlobalState(callerClass);
}

/**
* Check for operations that can access sensitive network information, e.g. secrets, tokens or SSL sessions
*/
public void checkReadSensitiveNetworkInformation(Class<?> callerClass) {
neverEntitled(callerClass, "access sensitive network information");
}

@SuppressForbidden(reason = "Explicitly checking File apis")
public void checkFileRead(Class<?> callerClass, File file) {
var requestingClass = requestingClass(callerClass);
if (isTriviallyAllowed(requestingClass)) {
return;
}

ModuleEntitlements entitlements = getEntitlements(requestingClass);
if (entitlements.fileAccess().canRead(file) == false) {
throw new NotEntitledException(
Strings.format(
"Not entitled: caller [%s], module [%s], entitlement [file], operation [read], path [%s]",
callerClass,
requestingClass.getModule(),
file
)
);
}
checkFileRead(callerClass, file.toPath());
}

public void checkFileRead(Class<?> callerClass, Path path) {
Expand All @@ -247,22 +218,7 @@ public void checkFileRead(Class<?> callerClass, Path path) {

@SuppressForbidden(reason = "Explicitly checking File apis")
public void checkFileWrite(Class<?> callerClass, File file) {
var requestingClass = requestingClass(callerClass);
if (isTriviallyAllowed(requestingClass)) {
return;
}

ModuleEntitlements entitlements = getEntitlements(requestingClass);
if (entitlements.fileAccess().canWrite(file) == false) {
throw new NotEntitledException(
Strings.format(
"Not entitled: caller [%s], module [%s], entitlement [file], operation [write], path [%s]",
callerClass,
requestingClass.getModule(),
file
)
);
}
checkFileWrite(callerClass, file.toPath());
}

public void checkFileWrite(Class<?> callerClass, Path path) {
Expand Down Expand Up @@ -409,7 +365,9 @@ private ModuleEntitlements computeEntitlements(Class<?> requestingClass) {
var pluginName = pluginResolver.apply(requestingClass);
if (pluginName != null) {
var pluginEntitlements = pluginsEntitlements.get(pluginName);
if (pluginEntitlements != null) {
if (pluginEntitlements == null) {
return ModuleEntitlements.NONE;
} else {
final String scopeName;
if (requestingModule.isNamed() == false) {
scopeName = ALL_UNNAMED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@

package org.elasticsearch.entitlement.runtime.policy;

import org.elasticsearch.entitlement.runtime.policy.entitlements.CreateClassLoaderEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.Entitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.FileEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.InboundNetworkEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.LoadNativeLibrariesEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.OutboundNetworkEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.SetHttpsConnectionPropertiesEntitlement;
import org.elasticsearch.entitlement.runtime.policy.entitlements.WriteSystemPropertiesEntitlement;
import org.elasticsearch.xcontent.XContentLocation;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentParserConfiguration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
* parser is able to wrap this exception with a line/character number for
* additional useful error information.
*/
class PolicyValidationException extends RuntimeException {
public class PolicyValidationException extends RuntimeException {

PolicyValidationException(String message) {
public PolicyValidationException(String message) {
super(message);
}

PolicyValidationException(String message, Throwable cause) {
public PolicyValidationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

package org.elasticsearch.entitlement.runtime.policy;

import org.elasticsearch.entitlement.runtime.policy.entitlements.Entitlement;

import java.util.List;
import java.util.Objects;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;

public record CreateClassLoaderEntitlement() implements Entitlement {
@ExternalEntitlement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.Policy;

/**
* Marker interface to ensure that only {@link Entitlement} are
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

/**
* Internal policy type (not-parseable -- not available to plugins).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;
import org.elasticsearch.entitlement.runtime.policy.PolicyValidationException;

import java.nio.file.Paths;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;

/**
* Describes an entitlement for inbound network actions (listen/accept/receive)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;

/**
* An Entitlement to allow loading native libraries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;

/**
* Describes an entitlement for outbound network actions (connect/send)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;

/**
* An Entitlement to allow setting properties to a single Https connection after this has been created
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;

/**
* An Entitlement to allow writing all properties such as system properties.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.entitlement.runtime.policy;
package org.elasticsearch.entitlement.runtime.policy.entitlements;

import org.elasticsearch.entitlement.runtime.policy.ExternalEntitlement;

import java.util.List;
import java.util.Set;
Expand Down
Loading