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 <zjx001202@gmail.com>
This commit is contained in:
Burning_TNT
2024-01-20 16:15:28 +08:00
committed by GitHub
parent b9a6401ef3
commit 931808d808
3 changed files with 26 additions and 21 deletions

View File

@@ -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);
}
}

View File

@@ -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");
}

View File

@@ -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<Path> 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<String> commandline = new ArrayList<>();
commandline.add(JavaVersion.fromCurrentEnvironment().getBinary().toString());
for (Map.Entry<Object, Object> 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));