mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-11 08:27:29 -04:00
updater: download and verify update
This commit is contained in:
parent
e6d48ddfdc
commit
8a0701e854
@ -14,13 +14,10 @@
|
||||
package de.bixilon.minosoft.assets.util
|
||||
|
||||
import com.github.luben.zstd.ZstdInputStream
|
||||
import de.bixilon.kutil.buffer.BufferDefinition
|
||||
import de.bixilon.kutil.random.RandomStringUtil.randomString
|
||||
import de.bixilon.minosoft.terminal.RunConfiguration
|
||||
import de.bixilon.minosoft.util.KUtil
|
||||
import java.io.*
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.security.MessageDigest
|
||||
|
||||
object FileUtil {
|
||||
|
||||
@ -60,31 +57,6 @@ object FileUtil {
|
||||
|
||||
|
||||
fun createTempFile(): File {
|
||||
var file: File
|
||||
|
||||
for (i in 0 until AssetsOptions.MAX_FILE_CHECKING) {
|
||||
file = RunConfiguration.TEMPORARY_FOLDER.resolve(KUtil.RANDOM.randomString(32)).toFile()
|
||||
if (!file.exists()) {
|
||||
return file
|
||||
}
|
||||
}
|
||||
|
||||
throw IOException("Can not find temporary file after ${AssetsOptions.MAX_FILE_CHECKING} tries!")
|
||||
}
|
||||
|
||||
@Deprecated("kutil 1.26")
|
||||
fun InputStream.copy(vararg output: OutputStream, digest: MessageDigest?) {
|
||||
val buffer = ByteArray(BufferDefinition.DEFAULT_BUFFER_SIZE)
|
||||
|
||||
while (true) {
|
||||
val length = read(buffer, 0, buffer.size)
|
||||
if (length < 0) {
|
||||
break
|
||||
}
|
||||
for (stream in output) {
|
||||
stream.write(buffer, 0, length)
|
||||
}
|
||||
digest?.update(buffer, 0, length)
|
||||
}
|
||||
return Files.createTempFile(RunConfiguration.TEMPORARY_FOLDER, "", "").toFile()
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -285,17 +285,11 @@ class OpenGLRenderSystem(
|
||||
}
|
||||
|
||||
override fun getErrors(): List<OpenGLError> {
|
||||
var error: Int = glGetError()
|
||||
if (error == GL_NO_ERROR) {
|
||||
return emptyList()
|
||||
}
|
||||
val errors: MutableList<OpenGLError> = mutableListOf()
|
||||
do {
|
||||
errors += OpenGLError(error)
|
||||
error = glGetError()
|
||||
} while (error != GL_NO_ERROR)
|
||||
val error = glGetError()
|
||||
|
||||
return errors
|
||||
if (error == GL_NO_ERROR) return emptyList()
|
||||
// opengl only supports single error
|
||||
return listOf(OpenGLError(error))
|
||||
}
|
||||
|
||||
private var polygonOffsetFactor: Float = 0.0f
|
||||
|
@ -13,14 +13,20 @@
|
||||
|
||||
package de.bixilon.minosoft.updater
|
||||
|
||||
import com.google.common.io.Files
|
||||
import de.bixilon.kutil.array.ByteArrayUtil.toHex
|
||||
import de.bixilon.kutil.base64.Base64Util.fromBase64
|
||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||
import de.bixilon.kutil.hash.HashUtil
|
||||
import de.bixilon.kutil.observer.DataObserver.Companion.observed
|
||||
import de.bixilon.kutil.os.PlatformInfo
|
||||
import de.bixilon.kutil.string.StringUtil.formatPlaceholder
|
||||
import de.bixilon.kutil.url.URLUtil.toURL
|
||||
import de.bixilon.minosoft.assets.util.FileUtil
|
||||
import de.bixilon.minosoft.config.profile.profiles.other.OtherProfileManager
|
||||
import de.bixilon.minosoft.properties.MinosoftProperties
|
||||
import de.bixilon.minosoft.terminal.RunConfiguration
|
||||
import de.bixilon.minosoft.util.KUtil.copy
|
||||
import de.bixilon.minosoft.util.http.HTTP2.get
|
||||
import de.bixilon.minosoft.util.http.HTTPResponse
|
||||
import de.bixilon.minosoft.util.http.exceptions.HTTPException
|
||||
@ -28,7 +34,11 @@ import de.bixilon.minosoft.util.json.Jackson
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.net.URL
|
||||
import java.security.MessageDigest
|
||||
import java.security.SignatureException
|
||||
|
||||
object MinosoftUpdater {
|
||||
var update: MinosoftUpdate? by observed(null)
|
||||
@ -110,13 +120,36 @@ object MinosoftUpdater {
|
||||
val download = update.download
|
||||
if (download == null) {
|
||||
progress.log?.print("Update is unavailable for download. Please download it manually!")
|
||||
progress.stage = UpdateProgress.UpdateStage.FAILED
|
||||
progress.error = IllegalAccessError("Unavailable...")
|
||||
return
|
||||
}
|
||||
progress.log?.print("Downloading update...")
|
||||
|
||||
progress.log?.print("TODO :)")
|
||||
progress.stage = UpdateProgress.UpdateStage.FAILED
|
||||
// UpdateKey.require(data, signature)
|
||||
try {
|
||||
val stream = download.url.openStream()
|
||||
val digest = MessageDigest.getInstance(HashUtil.SHA_512)
|
||||
val temp = FileUtil.createTempFile()
|
||||
val signature = UpdateKey.createInstance()
|
||||
stream.copy(FileOutputStream(temp), digest = digest, signature = signature)
|
||||
if (digest.digest().toHex() != download.sha512) throw SignatureException("Hash mismatch of downloaded file: Expected ${download.sha512}, got ${digest.digest().toHex()}")
|
||||
if (!signature.verify(download.signature.fromBase64())) throw SignatureException("Signature of downloaded file mismatches!")
|
||||
|
||||
progress.log?.print("Moving temporary file to final destination")
|
||||
|
||||
// move to current directory
|
||||
val output = File(("./Minosoft-${update.id}.jar"))
|
||||
Files.move(temp, output)
|
||||
progress.log?.print("Success, file saved to $output")
|
||||
|
||||
// TODO: restart minosoft
|
||||
} catch (error: Throwable) {
|
||||
if (progress.log == null) {
|
||||
error.printStackTrace()
|
||||
} else {
|
||||
progress.log?.print(error)
|
||||
}
|
||||
progress.error = error
|
||||
throw error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -15,23 +15,11 @@ package de.bixilon.minosoft.updater
|
||||
|
||||
import de.bixilon.kutil.latch.AbstractLatch
|
||||
import de.bixilon.kutil.latch.SimpleLatch
|
||||
import de.bixilon.kutil.observer.DataObserver.Companion.observed
|
||||
import de.bixilon.minosoft.commands.stack.print.PrintTarget
|
||||
|
||||
class UpdateProgress(
|
||||
val progress: AbstractLatch = SimpleLatch(0),
|
||||
var log: PrintTarget? = null,
|
||||
) {
|
||||
var stage by observed(UpdateStage.WAITING)
|
||||
var error: Throwable? = null
|
||||
|
||||
enum class UpdateStage {
|
||||
WAITING,
|
||||
DOWNLOADING,
|
||||
VERIFYING,
|
||||
STORING,
|
||||
|
||||
DONE,
|
||||
FAILED,
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2020-2023 Moritz Zwerger
|
||||
* Copyright (C) 2020-2024 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
@ -21,6 +21,7 @@ import de.bixilon.kotlinglm.vec2.Vec2t
|
||||
import de.bixilon.kotlinglm.vec3.Vec3d
|
||||
import de.bixilon.kotlinglm.vec3.Vec3t
|
||||
import de.bixilon.kotlinglm.vec4.Vec4t
|
||||
import de.bixilon.kutil.buffer.BufferDefinition
|
||||
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedListOf
|
||||
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
|
||||
@ -29,6 +30,7 @@ import de.bixilon.kutil.collections.CollectionUtil.toSynchronizedSet
|
||||
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
|
||||
import de.bixilon.kutil.concurrent.pool.runnable.ForcePooledRunnable
|
||||
import de.bixilon.kutil.concurrent.schedule.TaskScheduler
|
||||
import de.bixilon.kutil.exception.ExceptionUtil
|
||||
import de.bixilon.kutil.primitive.BooleanUtil.decide
|
||||
import de.bixilon.kutil.primitive.DoubleUtil
|
||||
import de.bixilon.kutil.primitive.DoubleUtil.matches
|
||||
@ -69,7 +71,11 @@ import io.netty.channel.SimpleChannelInboundHandler
|
||||
import javafx.application.Platform
|
||||
import org.kamranzafar.jtar.TarHeader
|
||||
import java.io.FileOutputStream
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.security.MessageDigest
|
||||
import java.security.SecureRandom
|
||||
import java.security.Signature
|
||||
import java.util.*
|
||||
import javax.net.ssl.SSLContext
|
||||
|
||||
@ -355,4 +361,29 @@ object KUtil {
|
||||
stream.close()
|
||||
println("Packet dumped to $path")
|
||||
}
|
||||
|
||||
|
||||
@Deprecated("kutil 1.26")
|
||||
fun InputStream.copy(vararg output: OutputStream, digest: MessageDigest? = null, signature: Signature? = null, closeIn: Boolean = true, closeOut: Boolean = true) {
|
||||
val buffer = ByteArray(BufferDefinition.DEFAULT_BUFFER_SIZE)
|
||||
|
||||
while (true) {
|
||||
val length = read(buffer, 0, buffer.size)
|
||||
if (length < 0) {
|
||||
break
|
||||
}
|
||||
for (stream in output) {
|
||||
stream.write(buffer, 0, length)
|
||||
}
|
||||
digest?.update(buffer, 0, length)
|
||||
signature?.update(buffer, 0, length)
|
||||
}
|
||||
|
||||
if (closeIn) ExceptionUtil.ignoreAll { close() }
|
||||
if (closeOut) {
|
||||
for (stream in output) {
|
||||
ExceptionUtil.ignoreAll { stream.close() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ abstract class SignatureSigner(
|
||||
key = keyFactory.generatePublic(spec)
|
||||
}
|
||||
|
||||
protected fun createInstance(): Signature {
|
||||
fun createInstance(): Signature {
|
||||
val instance = Signature.getInstance(algorithm)
|
||||
instance.initVerify(key)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user