check hash for downloaded mods

This commit is contained in:
matcool 2024-07-20 18:16:06 -03:00
parent af17213798
commit 61e000daa0
3 changed files with 20 additions and 4 deletions

View file

@ -52,6 +52,8 @@ std::string calculateSHA256Text(std::filesystem::path const& path) {
return picosha2::bytes_to_hex_string(hash.begin(), hash.end()); return picosha2::bytes_to_hex_string(hash.begin(), hash.end());
} }
std::string calculateHash(std::filesystem::path const& path) { std::string calculateHash(std::span<const uint8_t> data) {
return calculateSHA3_256(path); std::vector<uint8_t> hash(picosha2::k_digest_size);
picosha2::hash256(data.begin(), data.end(), hash);
return picosha2::bytes_to_hex_string(hash.begin(), hash.end());
} }

View file

@ -2,6 +2,7 @@
#include <string> #include <string>
#include <filesystem> #include <filesystem>
#include <span>
std::string calculateSHA3_256(std::filesystem::path const& path); std::string calculateSHA3_256(std::filesystem::path const& path);
@ -9,4 +10,8 @@ std::string calculateSHA256(std::filesystem::path const& path);
std::string calculateSHA256Text(std::filesystem::path const& path); std::string calculateSHA256Text(std::filesystem::path const& path);
std::string calculateHash(std::filesystem::path const& path); /**
* Calculates the SHA256 hash of the given data,
* used for verifying mods.
*/
std::string calculateHash(std::span<const uint8_t> data);

View file

@ -3,6 +3,7 @@
#include <Geode/loader/Dirs.hpp> #include <Geode/loader/Dirs.hpp>
#include <Geode/utils/map.hpp> #include <Geode/utils/map.hpp>
#include <optional> #include <optional>
#include <hash/hash.hpp>
using namespace server; using namespace server;
@ -103,8 +104,16 @@ public:
m_downloadListener.bind([this, hash = version.hash](web::WebTask::Event* event) { m_downloadListener.bind([this, hash = version.hash](web::WebTask::Event* event) {
if (auto value = event->getValue()) { if (auto value = event->getValue()) {
if (value->ok()) { if (value->ok()) {
if (auto actualHash = ::calculateHash(value->data()); actualHash != hash) {
log::error("Failed to download {}, hash mismatch ({} != {})", m_id, actualHash, hash);
m_status = DownloadStatusError {
.details = "Hash mismatch, downloaded file did not match what was expected",
};
ModDownloadEvent(m_id).post();
return;
}
bool removingInstalledWasError = false; bool removingInstalledWasError = false;
bool disablingReplacedWasError = false;
std::string id = m_replacesMod.has_value() ? m_replacesMod.value() : m_id; std::string id = m_replacesMod.has_value() ? m_replacesMod.value() : m_id;
if (auto mod = Loader::get()->getInstalledMod(id)) { if (auto mod = Loader::get()->getInstalledMod(id)) {
std::error_code ec; std::error_code ec;