diff --git a/Launcher/Launcher.iml b/Launcher/Launcher.iml index 1c93b9c..1d2bccf 100644 --- a/Launcher/Launcher.iml +++ b/Launcher/Launcher.iml @@ -8,7 +8,7 @@ - + diff --git a/Launcher/source/client/ClientLauncher.java b/Launcher/source/client/ClientLauncher.java index 3a28232..a1cd310 100644 --- a/Launcher/source/client/ClientLauncher.java +++ b/Launcher/source/client/ClientLauncher.java @@ -175,7 +175,7 @@ // Verify ClientLauncher sign and classpath LogHelper.debug("Verifying ClientLauncher sign and classpath"); SecurityHelper.verifySign(LauncherRequest.BINARY_PATH, params.launcherSign, publicKey); - URL[] classpath = JVMHelper.LOADER.getURLs(); + URL[] classpath = JVMHelper.getClassPath(); for (URL classpathURL : classpath) { Path file = Paths.get(classpathURL.toURI()); if (!file.startsWith(IOHelper.JVM_DIR) && !file.equals(LauncherRequest.BINARY_PATH)) { @@ -306,7 +306,7 @@ // Add client classpath URL[] classPath = resolveClassPath(params.clientDir, profile.getClassPath()); for (URL url : classPath) { - JVMHelper.UCP.addURL(url); + JVMHelper.addClassPath(url); } // Resolve main class and method diff --git a/Launcher/source/helper/JVMHelper.java b/Launcher/source/helper/JVMHelper.java index 1d15ae7..8996b5b 100644 --- a/Launcher/source/helper/JVMHelper.java +++ b/Launcher/source/helper/JVMHelper.java @@ -6,13 +6,13 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.net.URLClassLoader; +import java.net.URL; import java.nio.file.Path; +import java.security.cert.Certificate; import java.util.Locale; import com.sun.management.OperatingSystemMXBean; import launcher.LauncherAPI; -import sun.misc.URLClassPath; public final class JVMHelper { // MXBeans exports @@ -29,18 +29,31 @@ // Public static fields @LauncherAPI public static final Runtime RUNTIME = Runtime.getRuntime(); - @LauncherAPI public static final URLClassLoader LOADER = (URLClassLoader) ClassLoader.getSystemClassLoader(); - @LauncherAPI public static final URLClassPath UCP = getURLClassPath(); + @LauncherAPI public static final ClassLoader LOADER = ClassLoader.getSystemClassLoader(); // Useful internal fields and constants private static final String JAVA_LIBRARY_PATH = "java.library.path"; - private static final Field USR_PATHS_FIELD = getUsrPathsField(); - private static final Field SYS_PATHS_FIELD = getSysPathsField(); + private static final Field USR_PATHS_FIELD; + private static final Field SYS_PATHS_FIELD; + private static final Object UCP; + private static final Method UCP_ADDURL_METHOD; + private static final Method UCP_GETURLS_METHOD; + private static final Method UCP_GETRESOURCE_METHOD; + private static final Method RESOURCE_GETCERTS_METHOD; private JVMHelper() { } @LauncherAPI + public static void addClassPath(URL url) { + try { + UCP_ADDURL_METHOD.invoke(UCP, url); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new InternalError(e); + } + } + + @LauncherAPI public static void addNativePath(Path path) { String stringPath = path.toString(); @@ -71,6 +84,25 @@ } @LauncherAPI + public static Certificate[] getCertificates(String resource) { + try { + Object resource0 = UCP_GETRESOURCE_METHOD.invoke(UCP, resource); + return resource0 == null ? null : (Certificate[]) RESOURCE_GETCERTS_METHOD.invoke(resource0); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new InternalError(e); + } + } + + @LauncherAPI + public static URL[] getClassPath() { + try { + return (URL[]) UCP_GETURLS_METHOD.invoke(UCP); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new InternalError(e); + } + } + + @LauncherAPI public static void halt0(int status) { LogHelper.debug("Trying to halt JVM"); try { @@ -131,26 +163,16 @@ return Math.min(physicalRam, OS_BITS == 32 ? 1536 : 4096); // Limit 32-bit OS to 1536 MiB, and 64-bit OS to 4096 MiB (because it's enough) } - private static Field getSysPathsField() { + static { try { - return getField(ClassLoader.class, "sys_paths"); - } catch (NoSuchFieldException e) { - throw new InternalError(e); - } - } - - private static URLClassPath getURLClassPath() { - try { - return (URLClassPath) getField(URLClassLoader.class, "ucp").get(LOADER); - } catch (NoSuchFieldException | IllegalAccessException e) { - throw new InternalError(e); - } - } - - private static Field getUsrPathsField() { - try { - return getField(ClassLoader.class, "usr_paths"); - } catch (NoSuchFieldException e) { + USR_PATHS_FIELD = getField(ClassLoader.class, "usr_paths"); + SYS_PATHS_FIELD = getField(ClassLoader.class, "sys_paths"); + UCP = getField(LOADER.getClass(), "ucp").get(LOADER); + UCP_ADDURL_METHOD = getMethod(UCP.getClass(), "addURL", URL.class); + UCP_GETURLS_METHOD = getMethod(UCP.getClass(), "getURLs"); + UCP_GETRESOURCE_METHOD = getMethod(UCP.getClass(), "getResource", String.class); + RESOURCE_GETCERTS_METHOD = getMethod(UCP_GETRESOURCE_METHOD.getReturnType(), "getCertificates"); + } catch (NoSuchFieldException | NoSuchMethodException | IllegalAccessException e) { throw new InternalError(e); } } diff --git a/Launcher/source/helper/SecurityHelper.java b/Launcher/source/helper/SecurityHelper.java index ca66736..c5f5bd8 100644 --- a/Launcher/source/helper/SecurityHelper.java +++ b/Launcher/source/helper/SecurityHelper.java @@ -31,7 +31,6 @@ import javax.crypto.NoSuchPaddingException; import launcher.LauncherAPI; -import sun.misc.Resource; public final class SecurityHelper { // Algorithm constants @@ -124,8 +123,8 @@ @LauncherAPI public static boolean isValidCertificates(Class clazz) { // Verify META-INF/MANIFEST.MF certificate - Resource metaInf = JVMHelper.UCP.getResource(JarFile.MANIFEST_NAME); - if (metaInf == null || !isValidCertificates(metaInf.getCertificates())) { + Certificate[] certificates = JVMHelper.getCertificates(JarFile.MANIFEST_NAME); + if (certificates == null || !isValidCertificates(certificates)) { return false; }