Skip to content

Commit a15aee6

Browse files
authored
[Entitlements] Add URLConnection instrumentation for jar protocol (#123861)
Follows #123824 Relates to ES-10994
1 parent 9960863 commit a15aee6

File tree

8 files changed

+356
-122
lines changed

8 files changed

+356
-122
lines changed

libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,34 @@ void checkPathRegister(
12351235

12361236
void check$sun_net_www_protocol_file_FileURLConnection$getInputStream(Class<?> callerClass, java.net.URLConnection that);
12371237

1238+
void check$java_net_JarURLConnection$getManifest(Class<?> callerClass, java.net.JarURLConnection that);
1239+
1240+
void check$java_net_JarURLConnection$getJarEntry(Class<?> callerClass, java.net.JarURLConnection that);
1241+
1242+
void check$java_net_JarURLConnection$getAttributes(Class<?> callerClass, java.net.JarURLConnection that);
1243+
1244+
void check$java_net_JarURLConnection$getMainAttributes(Class<?> callerClass, java.net.JarURLConnection that);
1245+
1246+
void check$java_net_JarURLConnection$getCertificates(Class<?> callerClass, java.net.JarURLConnection that);
1247+
1248+
void check$sun_net_www_protocol_jar_JarURLConnection$getJarFile(Class<?> callerClass, java.net.JarURLConnection that);
1249+
1250+
void check$sun_net_www_protocol_jar_JarURLConnection$getJarEntry(Class<?> callerClass, java.net.JarURLConnection that);
1251+
1252+
void check$sun_net_www_protocol_jar_JarURLConnection$connect(Class<?> callerClass, java.net.JarURLConnection that);
1253+
1254+
void check$sun_net_www_protocol_jar_JarURLConnection$getInputStream(Class<?> callerClass, java.net.JarURLConnection that);
1255+
1256+
void check$sun_net_www_protocol_jar_JarURLConnection$getContentLength(Class<?> callerClass, java.net.JarURLConnection that);
1257+
1258+
void check$sun_net_www_protocol_jar_JarURLConnection$getContentLengthLong(Class<?> callerClass, java.net.JarURLConnection that);
1259+
1260+
void check$sun_net_www_protocol_jar_JarURLConnection$getContent(Class<?> callerClass, java.net.JarURLConnection that);
1261+
1262+
void check$sun_net_www_protocol_jar_JarURLConnection$getContentType(Class<?> callerClass, java.net.JarURLConnection that);
1263+
1264+
void check$sun_net_www_protocol_jar_JarURLConnection$getHeaderField(Class<?> callerClass, java.net.JarURLConnection that, String name);
1265+
12381266
////////////////////
12391267
//
12401268
// Thread management

libs/entitlement/qa/entitled-plugin/src/main/java/org/elasticsearch/entitlement/qa/entitled/EntitledActions.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@
1818
import java.nio.file.Files;
1919
import java.nio.file.Path;
2020
import java.nio.file.Paths;
21+
import java.nio.file.StandardOpenOption;
2122
import java.nio.file.attribute.UserPrincipal;
2223
import java.security.SecureRandom;
24+
import java.util.jar.Attributes;
25+
import java.util.jar.JarEntry;
26+
import java.util.jar.JarOutputStream;
27+
import java.util.jar.Manifest;
2328

2429
@SuppressForbidden(reason = "Exposes forbidden APIs for testing purposes")
2530
public final class EntitledActions {
@@ -81,4 +86,23 @@ public static URLConnection createFileURLConnection() throws IOException {
8186
public static URLConnection createMailToURLConnection() throws URISyntaxException, IOException {
8287
return new URI("mailto", "[email protected]", null).toURL().openConnection();
8388
}
89+
90+
public static Path createJar(Path dir, String name, Manifest manifest, String... files) throws IOException {
91+
Path jarpath = dir.resolve(name);
92+
try (var os = Files.newOutputStream(jarpath, StandardOpenOption.CREATE); var out = new JarOutputStream(os, manifest)) {
93+
for (String file : files) {
94+
out.putNextEntry(new JarEntry(file));
95+
}
96+
}
97+
return jarpath;
98+
}
99+
100+
public static URLConnection createJarURLConnection() throws IOException {
101+
var manifest = new Manifest();
102+
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
103+
var tmpJarFile = createJar(readWriteDir(), "entitlements-" + random.nextLong() + ".jar", manifest, "a", "b");
104+
var jarFileUrl = tmpJarFile.toUri().toURL();
105+
var jarUrl = URI.create("jar:" + jarFileUrl + "!/a").toURL();
106+
return jarUrl.openConnection();
107+
}
84108
}

libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/URLConnectionFileActions.java

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.elasticsearch.entitlement.qa.entitled.EntitledActions;
1414

1515
import java.io.IOException;
16+
import java.net.JarURLConnection;
1617
import java.net.URLConnection;
1718

1819
import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS;
@@ -30,6 +31,13 @@ private static void withJdkFileConnection(CheckedConsumer<URLConnection, Excepti
3031
}
3132
}
3233

34+
private static void withJarConnection(CheckedConsumer<JarURLConnection, Exception> connectionConsumer) throws Exception {
35+
var conn = EntitledActions.createJarURLConnection();
36+
// Be sure we got the connection implementation we want
37+
assert JarURLConnection.class.isAssignableFrom(conn.getClass());
38+
connectionConsumer.accept((JarURLConnection) conn);
39+
}
40+
3341
@EntitlementTest(expectedAccess = PLUGINS)
3442
static void sunFileURLConnectionConnect() throws Exception {
3543
withJdkFileConnection(URLConnection::connect);
@@ -114,4 +122,114 @@ static void sunFileURLConnectionGetContent() throws Exception {
114122
static void sunFileURLConnectionGetContentWithClasses() throws Exception {
115123
withJdkFileConnection(conn -> conn.getContent(new Class<?>[] { String.class }));
116124
}
125+
126+
@EntitlementTest(expectedAccess = PLUGINS)
127+
static void netJarURLConnectionGetManifest() throws Exception {
128+
withJarConnection(JarURLConnection::getManifest);
129+
}
130+
131+
@EntitlementTest(expectedAccess = PLUGINS)
132+
static void netJarURLConnectionGetJarEntry() throws Exception {
133+
withJarConnection(JarURLConnection::getJarEntry);
134+
}
135+
136+
@EntitlementTest(expectedAccess = PLUGINS)
137+
static void netJarURLConnectionGetAttributes() throws Exception {
138+
withJarConnection(JarURLConnection::getAttributes);
139+
}
140+
141+
@EntitlementTest(expectedAccess = PLUGINS)
142+
static void netJarURLConnectionGetMainAttributes() throws Exception {
143+
withJarConnection(JarURLConnection::getMainAttributes);
144+
}
145+
146+
@EntitlementTest(expectedAccess = PLUGINS)
147+
static void netJarURLConnectionGetCertificates() throws Exception {
148+
withJarConnection(JarURLConnection::getCertificates);
149+
}
150+
151+
@EntitlementTest(expectedAccess = PLUGINS)
152+
static void sunJarURLConnectionGetJarFile() throws Exception {
153+
withJarConnection(JarURLConnection::getJarFile);
154+
}
155+
156+
@EntitlementTest(expectedAccess = PLUGINS)
157+
static void sunJarURLConnectionGetJarEntry() throws Exception {
158+
withJarConnection(JarURLConnection::getJarEntry);
159+
}
160+
161+
@EntitlementTest(expectedAccess = PLUGINS)
162+
static void sunJarURLConnectionConnect() throws Exception {
163+
withJarConnection(JarURLConnection::connect);
164+
}
165+
166+
@EntitlementTest(expectedAccess = PLUGINS)
167+
static void sunJarURLConnectionGetInputStream() throws Exception {
168+
withJarConnection(JarURLConnection::getInputStream);
169+
}
170+
171+
@EntitlementTest(expectedAccess = PLUGINS)
172+
static void sunJarURLConnectionGetContentLength() throws Exception {
173+
withJarConnection(JarURLConnection::getContentLength);
174+
}
175+
176+
@EntitlementTest(expectedAccess = PLUGINS)
177+
static void sunJarURLConnectionGetContentLengthLong() throws Exception {
178+
withJarConnection(JarURLConnection::getContentLengthLong);
179+
}
180+
181+
@EntitlementTest(expectedAccess = PLUGINS)
182+
static void sunJarURLConnectionGetContent() throws Exception {
183+
withJarConnection(JarURLConnection::getContent);
184+
}
185+
186+
@EntitlementTest(expectedAccess = PLUGINS)
187+
static void sunJarURLConnectionGetContentType() throws Exception {
188+
withJarConnection(JarURLConnection::getContentType);
189+
}
190+
191+
@EntitlementTest(expectedAccess = PLUGINS)
192+
static void sunJarURLConnectionGetHeaderFieldWithName() throws Exception {
193+
withJarConnection(conn -> conn.getHeaderField("field"));
194+
}
195+
196+
@EntitlementTest(expectedAccess = PLUGINS)
197+
static void netJarURLConnectionGetContentEncoding() throws Exception {
198+
withJarConnection(URLConnection::getContentEncoding);
199+
}
200+
201+
@EntitlementTest(expectedAccess = PLUGINS)
202+
static void netJarURLConnectionGetExpiration() throws Exception {
203+
withJarConnection(URLConnection::getExpiration);
204+
}
205+
206+
@EntitlementTest(expectedAccess = PLUGINS)
207+
static void netJarURLConnectionGetDate() throws Exception {
208+
withJarConnection(URLConnection::getDate);
209+
}
210+
211+
@EntitlementTest(expectedAccess = PLUGINS)
212+
static void netJarURLConnectionGetLastModified() throws Exception {
213+
withJarConnection(URLConnection::getLastModified);
214+
}
215+
216+
@EntitlementTest(expectedAccess = PLUGINS)
217+
static void netJarURLConnectionGetHeaderFieldInt() throws Exception {
218+
withJarConnection(conn -> conn.getHeaderFieldInt("field", 0));
219+
}
220+
221+
@EntitlementTest(expectedAccess = PLUGINS)
222+
static void netJarURLConnectionGetHeaderFieldLong() throws Exception {
223+
withJarConnection(conn -> conn.getHeaderFieldLong("field", 0));
224+
}
225+
226+
@EntitlementTest(expectedAccess = PLUGINS)
227+
static void netJarURLConnectionGetHeaderFieldDate() throws Exception {
228+
withJarConnection(conn -> conn.getHeaderFieldDate("field", 0));
229+
}
230+
231+
@EntitlementTest(expectedAccess = PLUGINS)
232+
static void netJarURLConnectionGetContent() throws Exception {
233+
withJarConnection(conn -> conn.getContent(new Class<?>[] { String.class }));
234+
}
117235
}

libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/EntitlementBootstrap.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public record BootstrapArgs(
4040
Path[] sharedRepoDirs,
4141
Path configDir,
4242
Path libDir,
43+
Path modulesDir,
4344
Path pluginsDir,
4445
Map<String, Path> sourcePaths,
4546
Path logsDir,
@@ -58,6 +59,7 @@ public record BootstrapArgs(
5859
requireNonNull(sharedRepoDirs);
5960
requireNonNull(configDir);
6061
requireNonNull(libDir);
62+
requireNonNull(modulesDir);
6163
requireNonNull(pluginsDir);
6264
requireNonNull(sourcePaths);
6365
requireNonNull(logsDir);
@@ -83,6 +85,7 @@ public static BootstrapArgs bootstrapArgs() {
8385
* @param sharedRepoDirs shared repository directories for Elasticsearch
8486
* @param configDir the config directory for Elasticsearch
8587
* @param libDir the lib directory for Elasticsearch
88+
* @param modulesDir the directory where Elasticsearch modules are
8689
* @param pluginsDir the directory where plugins are installed for Elasticsearch
8790
* @param sourcePaths a map holding the path to each plugin or module jars, by plugin (or module) name.
8891
* @param tempDir the temp directory for Elasticsearch
@@ -98,6 +101,7 @@ public static void bootstrap(
98101
Path[] sharedRepoDirs,
99102
Path configDir,
100103
Path libDir,
104+
Path modulesDir,
101105
Path pluginsDir,
102106
Map<String, Path> sourcePaths,
103107
Path logsDir,
@@ -117,6 +121,7 @@ public static void bootstrap(
117121
sharedRepoDirs,
118122
configDir,
119123
libDir,
124+
modulesDir,
120125
pluginsDir,
121126
sourcePaths,
122127
logsDir,

libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ private static PolicyManager createPolicyManager() {
154154
serverModuleFileDatas,
155155
// Base ES directories
156156
FileData.ofPath(bootstrapArgs.pluginsDir(), READ),
157+
FileData.ofPath(bootstrapArgs.modulesDir(), READ),
157158
FileData.ofPath(bootstrapArgs.configDir(), READ),
158159
FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE),
160+
FileData.ofPath(bootstrapArgs.libDir(), READ),
159161
FileData.ofRelativePath(Path.of(""), DATA, READ_WRITE),
160162
FileData.ofRelativePath(Path.of(""), SHARED_REPO, READ_WRITE),
161163

0 commit comments

Comments
 (0)