|
41 | 41 | import org.elasticsearch.common.hash.MessageDigests; |
42 | 42 | import org.elasticsearch.common.io.FileSystemUtils; |
43 | 43 | import org.elasticsearch.common.settings.Settings; |
| 44 | +import org.elasticsearch.core.CheckedConsumer; |
44 | 45 | import org.elasticsearch.core.PathUtils; |
45 | 46 | import org.elasticsearch.core.PathUtilsForTesting; |
46 | 47 | import org.elasticsearch.core.Strings; |
47 | 48 | import org.elasticsearch.core.SuppressForbidden; |
48 | 49 | import org.elasticsearch.core.Tuple; |
| 50 | +import org.elasticsearch.entitlement.runtime.policy.PolicyUtils; |
49 | 51 | import org.elasticsearch.env.Environment; |
50 | 52 | import org.elasticsearch.env.TestEnvironment; |
51 | | -import org.elasticsearch.jdk.RuntimeVersionFeature; |
52 | 53 | import org.elasticsearch.plugin.scanner.NamedComponentScanner; |
53 | 54 | import org.elasticsearch.plugins.Platforms; |
54 | 55 | import org.elasticsearch.plugins.PluginDescriptor; |
|
57 | 58 | import org.elasticsearch.test.PosixPermissionsResetter; |
58 | 59 | import org.elasticsearch.test.compiler.InMemoryJavaCompiler; |
59 | 60 | import org.elasticsearch.test.jar.JarUtils; |
| 61 | +import org.elasticsearch.xcontent.XContentBuilder; |
| 62 | +import org.elasticsearch.xcontent.yaml.YamlXContent; |
60 | 63 | import org.junit.After; |
61 | 64 | import org.junit.Before; |
62 | 65 |
|
|
102 | 105 | import java.util.zip.ZipEntry; |
103 | 106 | import java.util.zip.ZipOutputStream; |
104 | 107 |
|
| 108 | +import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ALL_UNNAMED; |
105 | 109 | import static org.elasticsearch.snapshots.AbstractSnapshotIntegTestCase.forEachFileRecursively; |
106 | 110 | import static org.hamcrest.CoreMatchers.equalTo; |
107 | 111 | import static org.hamcrest.Matchers.containsInAnyOrder; |
@@ -137,8 +141,6 @@ public class InstallPluginActionTests extends ESTestCase { |
137 | 141 |
|
138 | 142 | @SuppressForbidden(reason = "sets java.io.tmpdir") |
139 | 143 | public InstallPluginActionTests(FileSystem fs, Function<String, Path> temp) { |
140 | | - assert "false".equals(System.getProperty("tests.security.manager")) : "-Dtests.security.manager=false has to be set"; |
141 | | - |
142 | 144 | this.temp = temp; |
143 | 145 | this.isPosix = fs.supportedFileAttributeViews().contains("posix"); |
144 | 146 | this.isReal = fs == PathUtils.getDefaultFileSystem(); |
@@ -309,15 +311,20 @@ private static String[] pluginProperties(String name, String[] additionalProps, |
309 | 311 | ).flatMap(Function.identity()).toArray(String[]::new); |
310 | 312 | } |
311 | 313 |
|
312 | | - static void writePluginSecurityPolicy(Path pluginDir, String... permissions) throws IOException { |
313 | | - StringBuilder securityPolicyContent = new StringBuilder("grant {\n "); |
314 | | - for (String permission : permissions) { |
315 | | - securityPolicyContent.append("permission java.lang.RuntimePermission \""); |
316 | | - securityPolicyContent.append(permission); |
317 | | - securityPolicyContent.append("\";"); |
| 314 | + static void writePluginEntitlementPolicy(Path pluginDir, String moduleName, CheckedConsumer<XContentBuilder, IOException> policyBuilder) |
| 315 | + throws IOException { |
| 316 | + try (var builder = YamlXContent.contentBuilder()) { |
| 317 | + builder.startObject(); |
| 318 | + builder.field(moduleName); |
| 319 | + builder.startArray(); |
| 320 | + |
| 321 | + policyBuilder.accept(builder); |
| 322 | + builder.endArray(); |
| 323 | + builder.endObject(); |
| 324 | + |
| 325 | + String policy = org.elasticsearch.common.Strings.toString(builder); |
| 326 | + Files.writeString(pluginDir.resolve(PolicyUtils.POLICY_FILE_NAME), policy); |
318 | 327 | } |
319 | | - securityPolicyContent.append("\n};\n"); |
320 | | - Files.write(pluginDir.resolve("plugin-security.policy"), securityPolicyContent.toString().getBytes(StandardCharsets.UTF_8)); |
321 | 328 | } |
322 | 329 |
|
323 | 330 | static InstallablePlugin createStablePlugin(String name, Path structure, boolean hasNamedComponentFile, String... additionalProps) |
@@ -787,10 +794,10 @@ public void testConfig() throws Exception { |
787 | 794 | public void testExistingConfig() throws Exception { |
788 | 795 | Path envConfigDir = env.v2().configDir().resolve("fake"); |
789 | 796 | Files.createDirectories(envConfigDir); |
790 | | - Files.write(envConfigDir.resolve("custom.yml"), "existing config".getBytes(StandardCharsets.UTF_8)); |
| 797 | + Files.writeString(envConfigDir.resolve("custom.yml"), "existing config"); |
791 | 798 | Path configDir = pluginDir.resolve("config"); |
792 | 799 | Files.createDirectory(configDir); |
793 | | - Files.write(configDir.resolve("custom.yml"), "new config".getBytes(StandardCharsets.UTF_8)); |
| 800 | + Files.writeString(configDir.resolve("custom.yml"), "new config"); |
794 | 801 | Files.createFile(configDir.resolve("other.yml")); |
795 | 802 | InstallablePlugin pluginZip = createPluginZip("fake", pluginDir); |
796 | 803 | installPlugin(pluginZip); |
@@ -892,9 +899,8 @@ public void testInstallMisspelledOfficialPlugins() { |
892 | 899 | } |
893 | 900 |
|
894 | 901 | public void testBatchFlag() throws Exception { |
895 | | - assumeTrue("security policy validation only available with SecurityManager", RuntimeVersionFeature.isSecurityManagerAvailable()); |
896 | 902 | installPlugin(true); |
897 | | - assertThat(terminal.getErrorOutput(), containsString("WARNING: plugin requires additional permissions")); |
| 903 | + assertThat(terminal.getErrorOutput(), containsString("WARNING: plugin requires additional entitlements")); |
898 | 904 | assertThat(terminal.getOutput(), containsString("-> Downloading")); |
899 | 905 | // No progress bar in batch mode |
900 | 906 | assertThat(terminal.getOutput(), not(containsString("100%"))); |
@@ -942,12 +948,12 @@ public void testPluginHasDifferentNameThatDescriptor() throws Exception { |
942 | 948 | assertThat(e.getMessage(), equalTo("Expected downloaded plugin to have ID [other-fake] but found [fake]")); |
943 | 949 | } |
944 | 950 |
|
945 | | - private void installPlugin(boolean isBatch, String... additionalProperties) throws Exception { |
946 | | - // if batch is enabled, we also want to add a security policy |
| 951 | + private void installPlugin(boolean isBatch) throws Exception { |
| 952 | + // if batch is enabled, we also want to add an entitlement policy |
947 | 953 | if (isBatch) { |
948 | | - writePluginSecurityPolicy(pluginDir, "setFactory"); |
| 954 | + writePluginEntitlementPolicy(pluginDir, ALL_UNNAMED, builder -> builder.value("manage_threads")); |
949 | 955 | } |
950 | | - InstallablePlugin pluginZip = createPlugin("fake", pluginDir, additionalProperties); |
| 956 | + InstallablePlugin pluginZip = createPlugin("fake", pluginDir); |
951 | 957 | skipJarHellAction.setEnvironment(env.v2()); |
952 | 958 | skipJarHellAction.setBatch(isBatch); |
953 | 959 | skipJarHellAction.execute(List.of(pluginZip)); |
@@ -1033,13 +1039,13 @@ URL openUrl(String urlString) throws IOException { |
1033 | 1039 | Path shaFile = temp.apply("shas").resolve("downloaded.zip" + shaExtension); |
1034 | 1040 | byte[] zipbytes = Files.readAllBytes(pluginZipPath); |
1035 | 1041 | String checksum = shaCalculator.apply(zipbytes); |
1036 | | - Files.write(shaFile, checksum.getBytes(StandardCharsets.UTF_8)); |
| 1042 | + Files.writeString(shaFile, checksum); |
1037 | 1043 | return shaFile.toUri().toURL(); |
1038 | 1044 | } else if ((url + ".asc").equals(urlString)) { |
1039 | 1045 | final Path ascFile = temp.apply("asc").resolve("downloaded.zip" + ".asc"); |
1040 | 1046 | final byte[] zipBytes = Files.readAllBytes(pluginZipPath); |
1041 | 1047 | final String asc = signature.apply(zipBytes, secretKey); |
1042 | | - Files.write(ascFile, asc.getBytes(StandardCharsets.UTF_8)); |
| 1048 | + Files.writeString(ascFile, asc); |
1043 | 1049 | return ascFile.toUri().toURL(); |
1044 | 1050 | } |
1045 | 1051 | return null; |
@@ -1531,11 +1537,13 @@ private void assertPolicyConfirmation(Tuple<Path, Environment> pathEnvironmentTu |
1531 | 1537 | } |
1532 | 1538 |
|
1533 | 1539 | public void testPolicyConfirmation() throws Exception { |
1534 | | - assumeTrue("security policy parsing only available with SecurityManager", RuntimeVersionFeature.isSecurityManagerAvailable()); |
1535 | | - writePluginSecurityPolicy(pluginDir, "getClassLoader", "setFactory"); |
| 1540 | + writePluginEntitlementPolicy(pluginDir, "test.plugin.module", builder -> { |
| 1541 | + builder.value("manage_threads"); |
| 1542 | + builder.value("outbound_network"); |
| 1543 | + }); |
1536 | 1544 | InstallablePlugin pluginZip = createPluginZip("fake", pluginDir); |
1537 | 1545 |
|
1538 | | - assertPolicyConfirmation(env, pluginZip, "plugin requires additional permissions"); |
| 1546 | + assertPolicyConfirmation(env, pluginZip, "plugin requires additional entitlements"); |
1539 | 1547 | assertPlugin("fake", pluginDir, env.v2()); |
1540 | 1548 | } |
1541 | 1549 |
|
|
0 commit comments