diff --git a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java index eff84a500bcdd..4ead99356ab00 100644 --- a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java @@ -1235,6 +1235,34 @@ void checkPathRegister( void check$sun_net_www_protocol_file_FileURLConnection$getInputStream(Class callerClass, java.net.URLConnection that); + void check$java_net_JarURLConnection$getManifest(Class callerClass, java.net.JarURLConnection that); + + void check$java_net_JarURLConnection$getJarEntry(Class callerClass, java.net.JarURLConnection that); + + void check$java_net_JarURLConnection$getAttributes(Class callerClass, java.net.JarURLConnection that); + + void check$java_net_JarURLConnection$getMainAttributes(Class callerClass, java.net.JarURLConnection that); + + void check$java_net_JarURLConnection$getCertificates(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getJarFile(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getJarEntry(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$connect(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getInputStream(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getContentLength(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getContentLengthLong(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getContent(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getContentType(Class callerClass, java.net.JarURLConnection that); + + void check$sun_net_www_protocol_jar_JarURLConnection$getHeaderField(Class callerClass, java.net.JarURLConnection that, String name); + //////////////////// // // Thread management diff --git a/libs/entitlement/qa/entitled-plugin/src/main/java/org/elasticsearch/entitlement/qa/entitled/EntitledActions.java b/libs/entitlement/qa/entitled-plugin/src/main/java/org/elasticsearch/entitlement/qa/entitled/EntitledActions.java index 2ca8adc885079..2cb01b5354f3b 100644 --- a/libs/entitlement/qa/entitled-plugin/src/main/java/org/elasticsearch/entitlement/qa/entitled/EntitledActions.java +++ b/libs/entitlement/qa/entitled-plugin/src/main/java/org/elasticsearch/entitlement/qa/entitled/EntitledActions.java @@ -18,8 +18,13 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; import java.nio.file.attribute.UserPrincipal; import java.security.SecureRandom; +import java.util.jar.Attributes; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; @SuppressForbidden(reason = "Exposes forbidden APIs for testing purposes") public final class EntitledActions { @@ -81,4 +86,23 @@ public static URLConnection createFileURLConnection() throws IOException { public static URLConnection createMailToURLConnection() throws URISyntaxException, IOException { return new URI("mailto", "email@example.com", null).toURL().openConnection(); } + + public static Path createJar(Path dir, String name, Manifest manifest, String... files) throws IOException { + Path jarpath = dir.resolve(name); + try (var os = Files.newOutputStream(jarpath, StandardOpenOption.CREATE); var out = new JarOutputStream(os, manifest)) { + for (String file : files) { + out.putNextEntry(new JarEntry(file)); + } + } + return jarpath; + } + + public static URLConnection createJarURLConnection() throws IOException { + var manifest = new Manifest(); + manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0"); + var tmpJarFile = createJar(readWriteDir(), "entitlements-" + random.nextLong() + ".jar", manifest, "a", "b"); + var jarFileUrl = tmpJarFile.toUri().toURL(); + var jarUrl = URI.create("jar:" + jarFileUrl + "!/a").toURL(); + return jarUrl.openConnection(); + } } diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/URLConnectionFileActions.java b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/URLConnectionFileActions.java index 582d8296488c1..6638a9659749c 100644 --- a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/URLConnectionFileActions.java +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/URLConnectionFileActions.java @@ -13,6 +13,7 @@ import org.elasticsearch.entitlement.qa.entitled.EntitledActions; import java.io.IOException; +import java.net.JarURLConnection; import java.net.URLConnection; import static org.elasticsearch.entitlement.qa.test.EntitlementTest.ExpectedAccess.PLUGINS; @@ -30,6 +31,13 @@ private static void withJdkFileConnection(CheckedConsumer connectionConsumer) throws Exception { + var conn = EntitledActions.createJarURLConnection(); + // Be sure we got the connection implementation we want + assert JarURLConnection.class.isAssignableFrom(conn.getClass()); + connectionConsumer.accept((JarURLConnection) conn); + } + @EntitlementTest(expectedAccess = PLUGINS) static void sunFileURLConnectionConnect() throws Exception { withJdkFileConnection(URLConnection::connect); @@ -114,4 +122,114 @@ static void sunFileURLConnectionGetContent() throws Exception { static void sunFileURLConnectionGetContentWithClasses() throws Exception { withJdkFileConnection(conn -> conn.getContent(new Class[] { String.class })); } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetManifest() throws Exception { + withJarConnection(JarURLConnection::getManifest); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetJarEntry() throws Exception { + withJarConnection(JarURLConnection::getJarEntry); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetAttributes() throws Exception { + withJarConnection(JarURLConnection::getAttributes); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetMainAttributes() throws Exception { + withJarConnection(JarURLConnection::getMainAttributes); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetCertificates() throws Exception { + withJarConnection(JarURLConnection::getCertificates); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetJarFile() throws Exception { + withJarConnection(JarURLConnection::getJarFile); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetJarEntry() throws Exception { + withJarConnection(JarURLConnection::getJarEntry); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionConnect() throws Exception { + withJarConnection(JarURLConnection::connect); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetInputStream() throws Exception { + withJarConnection(JarURLConnection::getInputStream); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetContentLength() throws Exception { + withJarConnection(JarURLConnection::getContentLength); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetContentLengthLong() throws Exception { + withJarConnection(JarURLConnection::getContentLengthLong); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetContent() throws Exception { + withJarConnection(JarURLConnection::getContent); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetContentType() throws Exception { + withJarConnection(JarURLConnection::getContentType); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void sunJarURLConnectionGetHeaderFieldWithName() throws Exception { + withJarConnection(conn -> conn.getHeaderField("field")); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetContentEncoding() throws Exception { + withJarConnection(URLConnection::getContentEncoding); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetExpiration() throws Exception { + withJarConnection(URLConnection::getExpiration); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetDate() throws Exception { + withJarConnection(URLConnection::getDate); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetLastModified() throws Exception { + withJarConnection(URLConnection::getLastModified); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetHeaderFieldInt() throws Exception { + withJarConnection(conn -> conn.getHeaderFieldInt("field", 0)); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetHeaderFieldLong() throws Exception { + withJarConnection(conn -> conn.getHeaderFieldLong("field", 0)); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetHeaderFieldDate() throws Exception { + withJarConnection(conn -> conn.getHeaderFieldDate("field", 0)); + } + + @EntitlementTest(expectedAccess = PLUGINS) + static void netJarURLConnectionGetContent() throws Exception { + withJarConnection(conn -> conn.getContent(new Class[] { String.class })); + } } diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/EntitlementBootstrap.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/EntitlementBootstrap.java index 6e12d3cc8c30b..bae1a0c463cc9 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/EntitlementBootstrap.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/bootstrap/EntitlementBootstrap.java @@ -40,6 +40,7 @@ public record BootstrapArgs( Path[] sharedRepoDirs, Path configDir, Path libDir, + Path modulesDir, Path pluginsDir, Map sourcePaths, Path logsDir, @@ -58,6 +59,7 @@ public record BootstrapArgs( requireNonNull(sharedRepoDirs); requireNonNull(configDir); requireNonNull(libDir); + requireNonNull(modulesDir); requireNonNull(pluginsDir); requireNonNull(sourcePaths); requireNonNull(logsDir); @@ -83,6 +85,7 @@ public static BootstrapArgs bootstrapArgs() { * @param sharedRepoDirs shared repository directories for Elasticsearch * @param configDir the config directory for Elasticsearch * @param libDir the lib directory for Elasticsearch + * @param modulesDir the directory where Elasticsearch modules are * @param pluginsDir the directory where plugins are installed for Elasticsearch * @param sourcePaths a map holding the path to each plugin or module jars, by plugin (or module) name. * @param tempDir the temp directory for Elasticsearch @@ -98,6 +101,7 @@ public static void bootstrap( Path[] sharedRepoDirs, Path configDir, Path libDir, + Path modulesDir, Path pluginsDir, Map sourcePaths, Path logsDir, @@ -117,6 +121,7 @@ public static void bootstrap( sharedRepoDirs, configDir, libDir, + modulesDir, pluginsDir, sourcePaths, logsDir, diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java index 8463681c53fe9..bdceeca16ae48 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java @@ -154,8 +154,10 @@ private static PolicyManager createPolicyManager() { serverModuleFileDatas, // Base ES directories FileData.ofPath(bootstrapArgs.pluginsDir(), READ), + FileData.ofPath(bootstrapArgs.modulesDir(), READ), FileData.ofPath(bootstrapArgs.configDir(), READ), FileData.ofPath(bootstrapArgs.logsDir(), READ_WRITE), + FileData.ofPath(bootstrapArgs.libDir(), READ), FileData.ofRelativePath(Path.of(""), DATA, READ_WRITE), FileData.ofRelativePath(Path.of(""), SHARED_REPO, READ_WRITE), diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java index 2c8349c4c397c..79416c249a585 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java @@ -39,6 +39,8 @@ import java.net.HttpURLConnection; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.net.JarURLConnection; +import java.net.MalformedURLException; import java.net.MulticastSocket; import java.net.NetworkInterface; import java.net.Proxy; @@ -51,6 +53,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.net.URLConnection; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; import java.net.http.HttpClient; @@ -642,143 +645,162 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) { policyManager.checkOutboundNetworkAccess(callerClass); } - @Override - public void check$java_net_URL$openConnection(Class callerClass, java.net.URL that) { - if (isNetworkUrl(that)) { + @SuppressWarnings("deprecation") + private URL extractJarFileUrl(URL jarUrl) { + String spec = jarUrl.getFile(); + int separator = spec.indexOf("!/"); + + // URL does not handle nested JAR URLs (it would be a MalformedURLException upon connection) + if (separator == -1) { + return null; + } + + try { + return new URL(spec.substring(0, separator)); + } catch (MalformedURLException e) { + return null; + } + } + + private boolean handleNetworkOrFileUrlCheck(Class callerClass, URL url) { + if (isNetworkUrl(url)) { policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrl(that)) { - checkURLFileRead(callerClass, that); + return true; } + if (isFileUrl(url)) { + checkURLFileRead(callerClass, url); + return true; + } + return false; + } + + private void checkJarURLAccess(Class callerClass, JarURLConnection that) { + var jarFileUrl = that.getJarFileURL(); + if (handleNetworkOrFileUrlCheck(callerClass, jarFileUrl)) { + return; + } + policyManager.checkUnsupportedURLProtocolConnection(callerClass, jarFileUrl.getProtocol()); + } + + private void checkEntitlementForUrl(Class callerClass, URL that) { + if (handleNetworkOrFileUrlCheck(callerClass, that)) { + return; + } + if (isJarUrl(that)) { + var jarFileUrl = extractJarFileUrl(that); + if (jarFileUrl == null || handleNetworkOrFileUrlCheck(callerClass, jarFileUrl) == false) { + policyManager.checkUnsupportedURLProtocolConnection(callerClass, "jar with unsupported inner protocol"); + } + } else { + policyManager.checkUnsupportedURLProtocolConnection(callerClass, that.getProtocol()); + } + } + + @Override + public void check$java_net_URL$openConnection(Class callerClass, java.net.URL that) { + checkEntitlementForUrl(callerClass, that); } @Override public void check$java_net_URL$openConnection(Class callerClass, URL that, Proxy proxy) { - if (proxy.type() != Proxy.Type.DIRECT || isNetworkUrl(that)) { + if (proxy.type() != Proxy.Type.DIRECT) { policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrl(that)) { - checkURLFileRead(callerClass, that); } + checkEntitlementForUrl(callerClass, that); } @Override public void check$java_net_URL$openStream(Class callerClass, java.net.URL that) { - if (isNetworkUrl(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrl(that)) { - checkURLFileRead(callerClass, that); - } + checkEntitlementForUrl(callerClass, that); } @Override public void check$java_net_URL$getContent(Class callerClass, java.net.URL that) { - if (isNetworkUrl(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrl(that)) { - checkURLFileRead(callerClass, that); - } + checkEntitlementForUrl(callerClass, that); } @Override public void check$java_net_URL$getContent(Class callerClass, java.net.URL that, Class[] classes) { - if (isNetworkUrl(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrl(that)) { - checkURLFileRead(callerClass, that); - } + checkEntitlementForUrl(callerClass, that); } - // We have to use class names for sun.net.www classes as java.base does not export them - private static final List ADDITIONAL_NETWORK_URL_CONNECT_CLASS_NAMES = List.of( - "sun.net.www.protocol.ftp.FtpURLConnection", - "sun.net.www.protocol.mailto.MailToURLConnection" - ); - - private static final List FILE_URL_CONNECT_CLASS_NAMES = List.of("sun.net.www.protocol.file.FileURLConnection"); - private static final Set NETWORK_PROTOCOLS = Set.of("http", "https", "ftp", "mailto"); - private static final Set FILE_PROTOCOLS = Set.of("file"); - private static boolean isNetworkUrl(java.net.URL url) { return NETWORK_PROTOCOLS.contains(url.getProtocol()); } private static boolean isFileUrl(java.net.URL url) { - return FILE_PROTOCOLS.contains(url.getProtocol()); + return "file".equals(url.getProtocol()); + } + + private static boolean isJarUrl(java.net.URL url) { + return "jar".equals(url.getProtocol()); } + // We have to use class names for sun.net.www classes as java.base does not export them + private static final List ADDITIONAL_NETWORK_URL_CONNECT_CLASS_NAMES = List.of( + "sun.net.www.protocol.ftp.FtpURLConnection", + "sun.net.www.protocol.mailto.MailToURLConnection" + ); + private static boolean isNetworkUrlConnection(java.net.URLConnection urlConnection) { var connectionClass = urlConnection.getClass(); return HttpURLConnection.class.isAssignableFrom(connectionClass) || ADDITIONAL_NETWORK_URL_CONNECT_CLASS_NAMES.contains(connectionClass.getName()); } + // We have to use class names for sun.net.www classes as java.base does not export them private static boolean isFileUrlConnection(java.net.URLConnection urlConnection) { var connectionClass = urlConnection.getClass(); - return FILE_URL_CONNECT_CLASS_NAMES.contains(connectionClass.getName()); + return "sun.net.www.protocol.file.FileURLConnection".equals(connectionClass.getName()); } - @Override - public void check$java_net_URLConnection$getContentLength(Class callerClass, java.net.URLConnection that) { + private void checkEntitlementForURLConnection(Class callerClass, URLConnection that) { if (isNetworkUrlConnection(that)) { policyManager.checkOutboundNetworkAccess(callerClass); } else if (isFileUrlConnection(that)) { checkURLFileRead(callerClass, that.getURL()); + } else if (that instanceof JarURLConnection jarURLConnection) { + checkJarURLAccess(callerClass, jarURLConnection); + } else { + policyManager.checkUnsupportedURLProtocolConnection(callerClass, that.getURL().getProtocol()); } } + @Override + public void check$java_net_URLConnection$getContentLength(Class callerClass, java.net.URLConnection that) { + checkEntitlementForURLConnection(callerClass, that); + } + @Override public void check$java_net_URLConnection$getContentLengthLong(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$java_net_URLConnection$getContentType(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$java_net_URLConnection$getContentEncoding(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$java_net_URLConnection$getExpiration(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$java_net_URLConnection$getDate(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$java_net_URLConnection$getLastModified(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override @@ -788,11 +810,7 @@ private static boolean isFileUrlConnection(java.net.URLConnection urlConnection) String name, int defaultValue ) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override @@ -802,11 +820,7 @@ private static boolean isFileUrlConnection(java.net.URLConnection urlConnection) String name, long defaultValue ) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override @@ -816,29 +830,17 @@ private static boolean isFileUrlConnection(java.net.URLConnection urlConnection) String name, long defaultValue ) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$java_net_URLConnection$getContent(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$java_net_URLConnection$getContent(Class callerClass, java.net.URLConnection that, Class[] classes) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override @@ -864,56 +866,32 @@ private static boolean isFileUrlConnection(java.net.URLConnection urlConnection) // Using java.net.URLConnection for "that" as sun.net.www.URLConnection is not exported @Override public void check$sun_net_www_URLConnection$getHeaderField(Class callerClass, java.net.URLConnection that, String name) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$sun_net_www_URLConnection$getHeaderFields(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$sun_net_www_URLConnection$getHeaderFieldKey(Class callerClass, java.net.URLConnection that, int n) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$sun_net_www_URLConnection$getHeaderField(Class callerClass, java.net.URLConnection that, int n) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$sun_net_www_URLConnection$getContentType(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override public void check$sun_net_www_URLConnection$getContentLength(Class callerClass, java.net.URLConnection that) { - if (isNetworkUrlConnection(that)) { - policyManager.checkOutboundNetworkAccess(callerClass); - } else if (isFileUrlConnection(that)) { - checkURLFileRead(callerClass, that.getURL()); - } + checkEntitlementForURLConnection(callerClass, that); } @Override @@ -2857,4 +2835,78 @@ private void checkURLFileRead(Class callerClass, URL url) { public void check$sun_net_www_protocol_file_FileURLConnection$getInputStream(Class callerClass, java.net.URLConnection that) { checkURLFileRead(callerClass, that.getURL()); } + + @Override + public void check$java_net_JarURLConnection$getManifest(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$java_net_JarURLConnection$getJarEntry(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$java_net_JarURLConnection$getAttributes(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$java_net_JarURLConnection$getMainAttributes(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$java_net_JarURLConnection$getCertificates(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getJarFile(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getJarEntry(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$connect(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getInputStream(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getContentLength(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getContentLengthLong(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getContent(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getContentType(Class callerClass, java.net.JarURLConnection that) { + checkJarURLAccess(callerClass, that); + } + + @Override + public void check$sun_net_www_protocol_jar_JarURLConnection$getHeaderField( + Class callerClass, + java.net.JarURLConnection that, + String name + ) { + checkJarURLAccess(callerClass, that); + } } diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java index 12d9bb4af566a..a822ea89cef4b 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java @@ -441,6 +441,10 @@ public void checkAllNetworkAccess(Class callerClass) { checkFlagEntitlement(classEntitlements, OutboundNetworkEntitlement.class, requestingClass, callerClass); } + public void checkUnsupportedURLProtocolConnection(Class callerClass, String protocol) { + neverEntitled(callerClass, () -> Strings.format("unsupported URL protocol [%s]", protocol)); + } + private void checkFlagEntitlement( ModuleEntitlements classEntitlements, Class entitlementClass, diff --git a/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java b/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java index fb4fcef71ee97..c1b8ed47e6575 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java @@ -257,6 +257,7 @@ private static void initPhase2(Bootstrap bootstrap) throws IOException { nodeEnv.repoDirs(), nodeEnv.configDir(), nodeEnv.libDir(), + nodeEnv.modulesDir(), nodeEnv.pluginsDir(), sourcePaths, nodeEnv.logsDir(),