Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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/bridge/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
module org.elasticsearch.entitlement.bridge {
requires java.net.http;
requires jdk.net;
requires java.logging;

exports org.elasticsearch.entitlement.bridge;
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
import java.util.concurrent.ForkJoinPool;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.logging.FileHandler;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
Expand Down Expand Up @@ -882,9 +883,34 @@ public interface EntitlementChecker {

void check$java_nio_file_Files$$lines(Class<?> callerClass, Path path);

// file system providers
void check$java_nio_file_spi_FileSystemProvider$(Class<?> callerClass);

void check$java_util_logging_FileHandler$(Class<?> callerClass);

void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern);

void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, boolean append);

void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, int limit, int count);

void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, int limit, int count, boolean append);

void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, long limit, int count, boolean append);

void check$java_util_logging_FileHandler$close(Class<?> callerClass, FileHandler that);

void check$java_net_http_HttpRequest$BodyPublishers$$ofFile(Class<?> callerClass, Path path);

void check$java_net_http_HttpResponse$BodyHandlers$$ofFile(Class<?> callerClass, Path path);

void check$java_net_http_HttpResponse$BodyHandlers$$ofFile(Class<?> callerClass, Path path, OpenOption... options);

void check$java_net_http_HttpResponse$BodyHandlers$$ofFileDownload(Class<?> callerClass, Path directory, OpenOption... openOptions);

void check$java_net_http_HttpResponse$BodySubscribers$$ofFile(Class<?> callerClass, Path directory);

void check$java_net_http_HttpResponse$BodySubscribers$$ofFile(Class<?> callerClass, Path directory, OpenOption... openOptions);

void checkNewFileSystem(Class<?> callerClass, FileSystemProvider that, URI uri, Map<String, ?> env);

void checkNewFileSystem(Class<?> callerClass, FileSystemProvider that, Path path, Map<String, ?> env);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
requires org.elasticsearch.entitlement;
requires org.elasticsearch.base; // SuppressForbidden
requires org.elasticsearch.logging;
requires java.logging;

exports org.elasticsearch.entitlement.qa.entitled; // Must be unqualified so non-modular IT tests can call us
}
1 change: 1 addition & 0 deletions libs/entitlement/qa/entitlement-test-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ esplugin {
dependencies {
compileOnly project(':server')
compileOnly project(':libs:logging')
compileOnly project(":libs:entitlement")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking, but I wonder why you had to add this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I don't need it anymore. I can remove it.

In an earlier draft, I had one of the tests catch NotEntitledException to make sure that the right part of the test was throwing. That turned out not to be necessary in the end.

compileOnly project(":libs:entitlement:qa:entitled-plugin")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
requires org.elasticsearch.server;
requires org.elasticsearch.base;
requires org.elasticsearch.logging;
requires org.elasticsearch.entitlement;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again not blocking, but I wonder why you had to add this?

requires org.elasticsearch.entitlement.qa.entitled;

// Modules we'll attempt to use in order to exercise entitlements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,22 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.util.Scanner;
import java.util.jar.JarFile;
import java.util.logging.FileHandler;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;

import static java.nio.charset.Charset.defaultCharset;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.WRITE;
import static java.util.zip.ZipFile.OPEN_DELETE;
import static java.util.zip.ZipFile.OPEN_READ;
import static org.elasticsearch.entitlement.qa.entitled.EntitledActions.createTempFileForWrite;
Expand Down Expand Up @@ -477,5 +482,86 @@ static void createScannerFileWithCharsetName() throws FileNotFoundException {
new Scanner(readFile().toFile(), "UTF-8");
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void fileHandler() throws IOException {
new FileHandler();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void fileHandler_String() throws IOException {
new FileHandler(readFile().toString());
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void fileHandler_StringBoolean() throws IOException {
new FileHandler(readFile().toString(), false);
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void fileHandler_StringIntInt() throws IOException {
new FileHandler(readFile().toString(), 1, 2);
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void fileHandler_StringIntIntBoolean() throws IOException {
new FileHandler(readFile().toString(), 1, 2, false);
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void fileHandler_StringLongIntBoolean() throws IOException {
new FileHandler(readFile().toString(), 1L, 2, false);
}

@EntitlementTest(expectedAccess = PLUGINS)
static void httpRequestBodyPublishersOfFile() throws IOException {
HttpRequest.BodyPublishers.ofFile(readFile());
}

@EntitlementTest(expectedAccess = PLUGINS)
static void httpResponseBodyHandlersOfFile() {
HttpResponse.BodyHandlers.ofFile(readWriteFile());
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void httpResponseBodyHandlersOfFile_readOnly() {
HttpResponse.BodyHandlers.ofFile(readFile());
}

@EntitlementTest(expectedAccess = PLUGINS)
static void httpResponseBodyHandlersOfFileDownload() {
HttpResponse.BodyHandlers.ofFileDownload(readWriteDir());
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void httpResponseBodyHandlersOfFileDownload_readOnly() {
HttpResponse.BodyHandlers.ofFileDownload(readDir());
}

@EntitlementTest(expectedAccess = PLUGINS)
static void httpResponseBodySubscribersOfFile_File() {
HttpResponse.BodySubscribers.ofFile(readWriteFile());
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void httpResponseBodySubscribersOfFile_File_readOnly() {
HttpResponse.BodySubscribers.ofFile(readFile());
}

@EntitlementTest(expectedAccess = PLUGINS)
static void httpResponseBodySubscribersOfFile_FileOpenOptions() {
// Note that, unlike other methods like BodyHandlers.ofFile, this is indeed
// an overload distinct from ofFile with no OpenOptions, and so it needs its
// own instrumentation and its own test.
HttpResponse.BodySubscribers.ofFile(readWriteFile(), CREATE, WRITE);
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void httpResponseBodySubscribersOfFile_FileOpenOptions_readOnly() {
// Note that, unlike other methods like BodyHandlers.ofFile, this is indeed
// an overload distinct from ofFile with no OpenOptions, and so it needs its
// own instrumentation and its own test.
HttpResponse.BodySubscribers.ofFile(readFile(), CREATE, WRITE);
}

private FileCheckActions() {}
}
5 changes: 3 additions & 2 deletions libs/entitlement/src/main/java/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
*/

module org.elasticsearch.entitlement {
requires org.elasticsearch.base;
requires org.elasticsearch.xcontent;
requires org.elasticsearch.logging;
requires java.instrument;
requires org.elasticsearch.base;
requires jdk.attach;
requires java.logging;
requires java.net.http;
requires jdk.attach;
requires jdk.net;

requires static org.elasticsearch.entitlement.bridge; // At runtime, this will be in java.base
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
import java.util.concurrent.ForkJoinPool;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.logging.FileHandler;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
Expand Down Expand Up @@ -1845,6 +1846,78 @@ public void checkSelectorProviderInheritedChannel(Class<?> callerClass, Selector
policyManager.checkChangeJVMGlobalState(callerClass);
}

@Override
public void check$java_util_logging_FileHandler$(Class<?> callerClass) {
policyManager.checkLoggingFileHandler(callerClass);
}

@Override
public void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern) {
policyManager.checkLoggingFileHandler(callerClass);
}

@Override
public void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, boolean append) {
policyManager.checkLoggingFileHandler(callerClass);
}

@Override
public void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, int limit, int count) {
policyManager.checkLoggingFileHandler(callerClass);
}

@Override
public void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, int limit, int count, boolean append) {
policyManager.checkLoggingFileHandler(callerClass);
}

@Override
public void check$java_util_logging_FileHandler$(Class<?> callerClass, String pattern, long limit, int count, boolean append) {
policyManager.checkLoggingFileHandler(callerClass);
}

@Override
public void check$java_util_logging_FileHandler$close(Class<?> callerClass, FileHandler that) {
// Note that there's no IT test for this one, because there's no way to create
// a FileHandler. However, we have this check just in case someone does manage
// to get their hands on a FileHandler and uses close() to cause its lock file to be deleted.
policyManager.checkLoggingFileHandler(callerClass);
}

@Override
public void check$java_net_http_HttpRequest$BodyPublishers$$ofFile(Class<?> callerClass, Path path) {
policyManager.checkFileRead(callerClass, path);
}

@Override
public void check$java_net_http_HttpResponse$BodyHandlers$$ofFile(Class<?> callerClass, Path path) {
policyManager.checkFileWrite(callerClass, path);
}

@Override
public void check$java_net_http_HttpResponse$BodyHandlers$$ofFile(Class<?> callerClass, Path path, OpenOption... options) {
policyManager.checkFileWrite(callerClass, path);
}

@Override
public void check$java_net_http_HttpResponse$BodyHandlers$$ofFileDownload(
Class<?> callerClass,
Path directory,
OpenOption... openOptions
) {
policyManager.checkFileWrite(callerClass, directory);
}

@Override
public void check$java_net_http_HttpResponse$BodySubscribers$$ofFile(Class<?> callerClass, Path directory) {
policyManager.checkFileWrite(callerClass, directory);
}

@Override
public void check$java_net_http_HttpResponse$BodySubscribers$$ofFile(Class<?> callerClass, Path directory, OpenOption... openOptions) {
policyManager.checkFileWrite(callerClass, directory);
}

@Override
public void checkNewFileSystem(Class<?> callerClass, FileSystemProvider that, URI uri, Map<String, ?> env) {
policyManager.checkChangeJVMGlobalState(callerClass);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ public void checkChangeJVMGlobalState(Class<?> callerClass) {
neverEntitled(callerClass, () -> walkStackForCheckMethodName().orElse("change JVM global state"));
}

public void checkLoggingFileHandler(Class<?> callerClass) {
neverEntitled(callerClass, () -> walkStackForCheckMethodName().orElse("create logging file handler"));
}

private Optional<String> walkStackForCheckMethodName() {
// Look up the check$ method to compose an informative error message.
// This way, we don't need to painstakingly describe every individual global-state change.
Expand Down