diff --git a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/SecurityUtils.java b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/SecurityUtils.java index 91dbc026149e..8d3a4c90f9b6 100644 --- a/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/SecurityUtils.java +++ b/jetty-core/jetty-util/src/main/java/org/eclipse/jetty/util/security/SecurityUtils.java @@ -22,20 +22,16 @@ import java.util.concurrent.CompletionException; import javax.security.auth.Subject; -import org.eclipse.jetty.util.JavaVersion; - /** *

Collections of utility methods to deal with the scheduled removal * of the security classes defined by JEP 411.

- *

To enable usage of a {@link SecurityManager}, the system property {@link #USE_SECURITY_MANAGER} must be set to {@code true} - * for JVMs after version 21.

*/ public class SecurityUtils { - public static final boolean USE_SECURITY_MANAGER = Boolean.parseBoolean( - System.getProperty("org.eclipse.jetty.util.security.useSecurityManager", JavaVersion.VERSION.getMajor() <= 21 ? "true" : "false")); private static final MethodHandle callAs = lookupCallAs(); private static final MethodHandle doPrivileged = lookupDoPrivileged(); + private static final MethodHandle getSecurityManager = lookupGetSecurityManager(); + private static final MethodHandle checkPermission = lookupCheckPermission(); private static MethodHandle lookupCallAs() { @@ -51,8 +47,6 @@ private static MethodHandle lookupCallAs() { try { - if (!USE_SECURITY_MANAGER) - return null; // Otherwise (Java 17), lookup the old API. MethodType oldSignature = MethodType.methodType(Object.class, Subject.class, PrivilegedAction.class); MethodHandle doAs = lookup.findStatic(Subject.class, "doAs", oldSignature); @@ -70,8 +64,6 @@ private static MethodHandle lookupCallAs() private static MethodHandle lookupDoPrivileged() { - if (!USE_SECURITY_MANAGER) - return null; try { // Use reflection to work with Java versions that have and don't have AccessController. @@ -85,21 +77,53 @@ private static MethodHandle lookupDoPrivileged() } } + private static MethodHandle lookupGetSecurityManager() + { + try + { + // Use reflection to work with Java versions that have and don't have System.getSecurityManager(). + MethodHandles.Lookup lookup = MethodHandles.lookup(); + return lookup.findStatic(java.lang.System.class, "getSecurityManager", MethodType.methodType(Object.class)); + } + catch (Throwable x) + { + return null; + } + } + + private static MethodHandle lookupCheckPermission() + { + try + { + // Use reflection to work with Java versions that have and don't have java.lang.SecurityManager. + Class klass = ClassLoader.getPlatformClassLoader().loadClass("java.lang.SecurityManager"); + MethodHandles.Lookup lookup = MethodHandles.lookup(); + return lookup.findVirtual(klass, "checkPermission", MethodType.methodType(Void.class, Permission.class)); + } + catch (Throwable x) + { + return null; + } + } + /** * Get the current security manager, if available. * @return the current security manager, if available */ public static Object getSecurityManager() { + if (getSecurityManager == null) + { + // method does not exist in this Java version + return null; + } try { - if (!USE_SECURITY_MANAGER) - return null; - // Use reflection to work with Java versions that have and don't have SecurityManager. - return System.class.getMethod("getSecurityManager").invoke(null); + return getSecurityManager.invoke(); } catch (Throwable ignored) { + // Security manager is not enabled (or maybe some other problem) return null; } } @@ -113,17 +137,18 @@ public static Object getSecurityManager() */ public static void checkPermission(Permission permission) throws SecurityException { - if (!USE_SECURITY_MANAGER) + if (getSecurityManager == null || checkPermission == null) + { return; + } Object securityManager = SecurityUtils.getSecurityManager(); if (securityManager == null) return; try { - securityManager.getClass().getMethod("checkPermission") - .invoke(securityManager, permission); + checkPermission.invoke(securityManager, permission); } - catch (SecurityException x) + catch (SecurityException | NullPointerException x) { throw x; } @@ -142,9 +167,11 @@ public static void checkPermission(Permission permission) throws SecurityExcepti */ public static T doPrivileged(PrivilegedAction action) { - if (!USE_SECURITY_MANAGER || doPrivileged == null) + // Keep this method short and inlineable. + MethodHandle methodHandle = doPrivileged; + if (methodHandle == null) return action.run(); - return doPrivileged(doPrivileged, action); + return doPrivileged(methodHandle, action); } @SuppressWarnings("unchecked")