Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
enum ExpectedAccess {
PLUGINS,
ES_MODULES_ONLY,
SERVER_ONLY,
ALWAYS_DENIED
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,6 @@
import org.elasticsearch.common.Strings;
import org.elasticsearch.core.CheckedRunnable;
import org.elasticsearch.core.SuppressForbidden;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyBreakIteratorProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyCalendarDataProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyCalendarNameProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyCollatorProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyCurrencyNameProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyDateFormatProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyDateFormatSymbolsProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyDecimalFormatSymbolsProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyLocaleNameProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyLocaleServiceProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyNumberFormatProvider;
import org.elasticsearch.entitlement.qa.test.DummyImplementations.DummyTimeZoneNameProvider;
import org.elasticsearch.logging.LogManager;
import org.elasticsearch.logging.Logger;
import org.elasticsearch.rest.BaseRestHandler;
Expand Down Expand Up @@ -59,6 +47,7 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -75,7 +64,6 @@
@SuppressWarnings("unused")
public class RestEntitlementsCheckAction extends BaseRestHandler {
private static final Logger logger = LogManager.getLogger(RestEntitlementsCheckAction.class);
public static final Thread NO_OP_SHUTDOWN_HOOK = new Thread(() -> {}, "Shutdown hook for testing");

record CheckAction(CheckedRunnable<Exception> action, boolean isAlwaysDeniedToPlugins, Integer fromJavaVersion) {
/**
Expand All @@ -94,39 +82,19 @@ static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
}
}

private static final Map<String, CheckAction> checkActions = Stream.concat(
private static final Map<String, CheckAction> checkActions = Stream.of(
Stream.<Entry<String, CheckAction>>of(
entry("runtime_exit", deniedToPlugins(RestEntitlementsCheckAction::runtimeExit)),
entry("runtime_halt", deniedToPlugins(RestEntitlementsCheckAction::runtimeHalt)),
entry("system_exit", deniedToPlugins(RestEntitlementsCheckAction::systemExit)),
entry("create_classloader", forPlugins(RestEntitlementsCheckAction::createClassLoader)),
entry("processBuilder_start", deniedToPlugins(RestEntitlementsCheckAction::processBuilder_start)),
entry("processBuilder_startPipeline", deniedToPlugins(RestEntitlementsCheckAction::processBuilder_startPipeline)),
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)),
entry("system_setIn", alwaysDenied(RestEntitlementsCheckAction::system$$setIn)),
entry("system_setOut", alwaysDenied(RestEntitlementsCheckAction::system$$setOut)),
entry("system_setErr", alwaysDenied(RestEntitlementsCheckAction::system$$setErr)),
entry("runtime_addShutdownHook", alwaysDenied(RestEntitlementsCheckAction::runtime$addShutdownHook)),
entry("runtime_removeShutdownHook", alwaysDenied(RestEntitlementsCheckAction::runtime$$removeShutdownHook)),
entry(
"thread_setDefaultUncaughtExceptionHandler",
alwaysDenied(RestEntitlementsCheckAction::thread$$setDefaultUncaughtExceptionHandler)
),
entry("localeServiceProvider", alwaysDenied(RestEntitlementsCheckAction::localeServiceProvider$)),
entry("breakIteratorProvider", alwaysDenied(RestEntitlementsCheckAction::breakIteratorProvider$)),
entry("collatorProvider", alwaysDenied(RestEntitlementsCheckAction::collatorProvider$)),
entry("dateFormatProvider", alwaysDenied(RestEntitlementsCheckAction::dateFormatProvider$)),
entry("dateFormatSymbolsProvider", alwaysDenied(RestEntitlementsCheckAction::dateFormatSymbolsProvider$)),
entry("decimalFormatSymbolsProvider", alwaysDenied(RestEntitlementsCheckAction::decimalFormatSymbolsProvider$)),
entry("numberFormatProvider", alwaysDenied(RestEntitlementsCheckAction::numberFormatProvider$)),
entry("calendarDataProvider", alwaysDenied(RestEntitlementsCheckAction::calendarDataProvider$)),
entry("calendarNameProvider", alwaysDenied(RestEntitlementsCheckAction::calendarNameProvider$)),
entry("currencyNameProvider", alwaysDenied(RestEntitlementsCheckAction::currencyNameProvider$)),
entry("localeNameProvider", alwaysDenied(RestEntitlementsCheckAction::localeNameProvider$)),
entry("timeZoneNameProvider", alwaysDenied(RestEntitlementsCheckAction::timeZoneNameProvider$)),
entry("logManager", alwaysDenied(RestEntitlementsCheckAction::logManager$)),

entry("locale_setDefault", alwaysDenied(WritePropertiesCheckActions::setDefaultLocale)),
Expand Down Expand Up @@ -230,8 +198,11 @@ static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
entry("symbol_lookup_name", new CheckAction(VersionSpecificNativeChecks::symbolLookupWithName, false, 22)),
entry("symbol_lookup_path", new CheckAction(VersionSpecificNativeChecks::symbolLookupWithPath, false, 22))
),
getTestEntries(FileCheckActions.class)
getTestEntries(FileCheckActions.class),
getTestEntries(SpiActions.class),
getTestEntries(SystemActions.class)
)
.flatMap(Function.identity())
.filter(entry -> entry.getValue().fromJavaVersion() == null || Runtime.version().feature() >= entry.getValue().fromJavaVersion())
.collect(Collectors.toUnmodifiableMap(Entry::getKey, Entry::getValue));

Expand Down Expand Up @@ -267,7 +238,7 @@ private static Stream<Entry<String, CheckAction>> getTestEntries(Class<?> action
}
}
};
boolean deniedToPlugins = testAnnotation.expectedAccess() == PLUGINS;
boolean deniedToPlugins = testAnnotation.expectedAccess() != PLUGINS;
Integer fromJavaVersion = testAnnotation.fromJavaVersion() == -1 ? null : testAnnotation.fromJavaVersion();
entries.add(entry(method.getName(), new CheckAction(runnable, deniedToPlugins, fromJavaVersion)));
}
Expand Down Expand Up @@ -323,21 +294,6 @@ private static void setDefaultSSLSocketFactory() {
HttpsURLConnection.setDefaultSSLSocketFactory(new DummyImplementations.DummySSLSocketFactory());
}

@SuppressForbidden(reason = "Specifically testing Runtime.exit")
private static void runtimeExit() {
Runtime.getRuntime().exit(123);
}

@SuppressForbidden(reason = "Specifically testing Runtime.halt")
private static void runtimeHalt() {
Runtime.getRuntime().halt(123);
}

@SuppressForbidden(reason = "Specifically testing System.exit")
private static void systemExit() {
System.exit(123);
}

private static void createClassLoader() throws IOException {
try (var classLoader = new URLClassLoader("test", new URL[0], RestEntitlementsCheckAction.class.getClassLoader())) {
logger.info("Created URLClassLoader [{}]", classLoader.getName());
Expand All @@ -356,80 +312,10 @@ private static void setHttpsConnectionProperties() {
new DummyImplementations.DummyHttpsURLConnection().setSSLSocketFactory(new DummyImplementations.DummySSLSocketFactory());
}

private static void system$$setIn() {
System.setIn(System.in);
}

@SuppressForbidden(reason = "This should be a no-op so we don't interfere with system streams")
private static void system$$setOut() {
System.setOut(System.out);
}

@SuppressForbidden(reason = "This should be a no-op so we don't interfere with system streams")
private static void system$$setErr() {
System.setErr(System.err);
}

private static void runtime$addShutdownHook() {
Runtime.getRuntime().addShutdownHook(NO_OP_SHUTDOWN_HOOK);
}

private static void runtime$$removeShutdownHook() {
Runtime.getRuntime().removeShutdownHook(NO_OP_SHUTDOWN_HOOK);
}

private static void thread$$setDefaultUncaughtExceptionHandler() {
Thread.setDefaultUncaughtExceptionHandler(Thread.getDefaultUncaughtExceptionHandler());
}

private static void localeServiceProvider$() {
new DummyLocaleServiceProvider();
}

private static void breakIteratorProvider$() {
new DummyBreakIteratorProvider();
}

private static void collatorProvider$() {
new DummyCollatorProvider();
}

private static void dateFormatProvider$() {
new DummyDateFormatProvider();
}

private static void dateFormatSymbolsProvider$() {
new DummyDateFormatSymbolsProvider();
}

private static void decimalFormatSymbolsProvider$() {
new DummyDecimalFormatSymbolsProvider();
}

private static void numberFormatProvider$() {
new DummyNumberFormatProvider();
}

private static void calendarDataProvider$() {
new DummyCalendarDataProvider();
}

private static void calendarNameProvider$() {
new DummyCalendarNameProvider();
}

private static void currencyNameProvider$() {
new DummyCurrencyNameProvider();
}

private static void localeNameProvider$() {
new DummyLocaleNameProvider();
}

private static void timeZoneNameProvider$() {
new DummyTimeZoneNameProvider();
}

private static void logManager$() {
new java.util.logging.LogManager() {
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* 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.test;

import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;

class SpiActions {
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createBreakIteratorProvider() {
new DummyImplementations.DummyBreakIteratorProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createCollatorProvider() {
new DummyImplementations.DummyCollatorProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createDateFormatProvider() {
new DummyImplementations.DummyDateFormatProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createDateFormatSymbolsProvider() {
new DummyImplementations.DummyDateFormatSymbolsProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createDecimalFormatSymbolsProvider() {
new DummyImplementations.DummyDecimalFormatSymbolsProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createNumberFormatProvider() {
new DummyImplementations.DummyNumberFormatProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createCalendarDataProvider() {
new DummyImplementations.DummyCalendarDataProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createCalendarNameProvider() {
new DummyImplementations.DummyCalendarNameProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createCurrencyNameProvider() {
new DummyImplementations.DummyCurrencyNameProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createLocaleNameProvider() {
new DummyImplementations.DummyLocaleNameProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createTimeZoneNameProvider() {
new DummyImplementations.DummyTimeZoneNameProvider();
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void createLocaleServiceProvider() {
new DummyImplementations.DummyLocaleServiceProvider();
}

private SpiActions() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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.test;

import org.elasticsearch.core.SuppressForbidden;

import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.ALWAYS_DENIED;
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.SERVER_ONLY;

class SystemActions {

@SuppressForbidden(reason = "Specifically testing Runtime.exit")
@EntitlementTest(expectedAccess = SERVER_ONLY)
static void runtimeExit() {
Runtime.getRuntime().exit(123);
}

@SuppressForbidden(reason = "Specifically testing Runtime.halt")
@EntitlementTest(expectedAccess = SERVER_ONLY)
static void runtimeHalt() {
Runtime.getRuntime().halt(123);
}

@SuppressForbidden(reason = "Specifically testing System.exit")
@EntitlementTest(expectedAccess = SERVER_ONLY)
static void systemExit() {
System.exit(123);
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void systemSetIn() {
System.setIn(System.in);
}

@SuppressForbidden(reason = "This should be a no-op so we don't interfere with system streams")
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void systemSetOut() {
System.setOut(System.out);
}

@SuppressForbidden(reason = "This should be a no-op so we don't interfere with system streams")
@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void systemSetErr() {
System.setErr(System.err);
}

private static final Thread NO_OP_SHUTDOWN_HOOK = new Thread(() -> {}, "Shutdown hook for testing");

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void runtimeAddShutdownHook() {
Runtime.getRuntime().addShutdownHook(NO_OP_SHUTDOWN_HOOK);
}

@EntitlementTest(expectedAccess = ALWAYS_DENIED)
static void runtimeRemoveShutdownHook() {
Runtime.getRuntime().removeShutdownHook(NO_OP_SHUTDOWN_HOOK);
}

private SystemActions() {}
}