From 931808d808a6228730e93117680240b5d627fd41 Mon Sep 17 00:00:00 2001 From: Burning_TNT <88144530+burningtnt@users.noreply.github.com> Date: Sat, 20 Jan 2024 16:15:28 +0800 Subject: [PATCH] Allow updates when self verification is disabled (#2639) * Allow updates when self verification is disabled * clean up IntegrityChecker * Fix: UpdateHandler would transfer the current command properties to the new HMCL. * Fix. * Fix. * update * update * update * update --------- Co-authored-by: Glavo --- .../hmcl/upgrade/hmcl/IntegrityChecker.java | 29 ++++++++----------- .../hmcl/upgrade/hmcl/UpdateChecker.java | 2 +- .../hmcl/upgrade/hmcl/UpdateHandler.java | 16 ++++++++-- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/IntegrityChecker.java b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/IntegrityChecker.java index a45bc6f1e..8833f94c0 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/IntegrityChecker.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/IntegrityChecker.java @@ -46,6 +46,8 @@ import static org.jackhuang.hmcl.util.Logging.LOG; public final class IntegrityChecker { private IntegrityChecker() {} + public static final boolean DISABLE_SELF_INTEGRITY_CHECK = "true".equals(System.getProperty("hmcl.self_integrity_check.disable")); + private static final String SIGNATURE_FILE = "META-INF/hmcl_signature"; private static final String PUBLIC_KEY_FILE = "assets/hmcl_signature_publickey.der"; @@ -60,7 +62,7 @@ public final class IntegrityChecker { } } - private static boolean verifyJar(Path jarPath) throws IOException { + static void verifyJar(Path jarPath) throws IOException { PublicKey publickey = getPublicKey(); MessageDigest md = DigestUtils.getDigest("SHA-512"); @@ -96,18 +98,14 @@ public final class IntegrityChecker { verifier.update(md.digest(entry.getKey().getBytes(UTF_8))); verifier.update(entry.getValue()); } - return verifier.verify(signature); + if (!verifier.verify(signature)) { + throw new IOException("Invalid signature: " + jarPath); + } } catch (GeneralSecurityException e) { throw new IOException("Failed to verify signature", e); } } - static void requireVerifiedJar(Path jar) throws IOException { - if (!verifyJar(jar)) { - throw new IOException("Invalid signature: " + jar); - } - } - private static volatile Boolean selfVerified = null; /** @@ -125,7 +123,12 @@ public final class IntegrityChecker { } try { - verifySelf(); + Path jarPath = JarUtils.thisJarPath(); + if (jarPath == null) { + throw new IOException("Failed to find current HMCL location"); + } + + verifyJar(jarPath); LOG.info("Successfully verified current JAR"); selfVerified = true; } catch (IOException e) { @@ -140,12 +143,4 @@ public final class IntegrityChecker { public static boolean isOfficial() { return isSelfVerified() || (Metadata.GITHUB_SHA != null && Metadata.BUILD_CHANNEL.equals("nightly")); } - - private static void verifySelf() throws IOException { - Path self = JarUtils.thisJarPath(); - if (self == null) { - throw new IOException("Failed to find current HMCL location"); - } - requireVerifiedJar(self); - } } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateChecker.java b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateChecker.java index d8d3fc708..d26c10a0b 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateChecker.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateChecker.java @@ -81,7 +81,7 @@ public final class UpdateChecker { } private static RemoteVersion checkUpdate(UpdateChannel channel) throws IOException { - if (!IntegrityChecker.isSelfVerified() && !"true".equals(System.getProperty("hmcl.self_integrity_check.disable"))) { + if (!IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK && !IntegrityChecker.isSelfVerified()) { throw new IOException("Self verification failed"); } diff --git a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateHandler.java b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateHandler.java index 9b3fc9e6f..a827f816d 100644 --- a/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateHandler.java +++ b/HMCL/src/main/java/org/jackhuang/hmcl/upgrade/hmcl/UpdateHandler.java @@ -110,7 +110,7 @@ public final class UpdateHandler { if (success) { try { - if (!IntegrityChecker.isSelfVerified()) { + if (!IntegrityChecker.isSelfVerified() && !IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK) { throw new IOException("Current JAR is not verified"); } @@ -138,7 +138,9 @@ public final class UpdateHandler { LOG.info("Applying update to " + target); Path self = getCurrentLocation(); - IntegrityChecker.requireVerifiedJar(self); + if (!IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK && !IntegrityChecker.isSelfVerified()) { + throw new IOException("Self verification failed"); + } ExecutableHeaderHelper.copyWithHeader(self, target); Optional newFilename = tryRename(target, Metadata.VERSION); @@ -156,13 +158,21 @@ public final class UpdateHandler { } private static void requestUpdate(Path updateTo, Path self) throws IOException { - IntegrityChecker.requireVerifiedJar(updateTo); + if (!IntegrityChecker.DISABLE_SELF_INTEGRITY_CHECK) { + IntegrityChecker.verifyJar(updateTo); + } startJava(updateTo, "--apply-to", self.toString()); } private static void startJava(Path jar, String... appArgs) throws IOException { List commandline = new ArrayList<>(); commandline.add(JavaVersion.fromCurrentEnvironment().getBinary().toString()); + for (Map.Entry entry : System.getProperties().entrySet()) { + Object key = entry.getKey(); + if (key instanceof String && ((String) key).startsWith("hmcl.")) { + commandline.add("-D" + key + "=" + entry.getValue()); + } + } commandline.add("-jar"); commandline.add(jar.toAbsolutePath().toString()); commandline.addAll(Arrays.asList(appArgs));