From 76654055e00df77482580cde5651750a9ccbce73 Mon Sep 17 00:00:00 2001 From: Warren Hood Date: Sun, 18 Aug 2024 23:43:24 +0200 Subject: [PATCH] Add hash validation for downloaded mods --- Cargo.lock | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/resolver.rs | 35 ++++++++++++++++++------ 3 files changed, 100 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf2b246..6c7a85e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -111,6 +111,15 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -200,6 +209,35 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpufeatures" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "encoding_rs" version = "0.8.34" @@ -300,6 +338,16 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -557,6 +605,7 @@ dependencies = [ "reqwest", "semver", "serde", + "sha2", "tokio", "toml", ] @@ -987,6 +1036,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "shlex" version = "1.3.0" @@ -1260,6 +1320,12 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -1310,6 +1376,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 682b737..b0d08a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,5 +9,6 @@ lhash = { version = "1.1.0", features = ["sha1", "sha512"] } reqwest = { version = "0.12.5", features = ["json"] } semver = { version = "1.0.23", features = ["serde"] } serde = { version = "1.0.207", features = ["derive"] } +sha2 = "0.10.8" tokio = { version = "1.39.2", features = ["full"] } toml = "0.8.19" diff --git a/src/resolver.rs b/src/resolver.rs index c86906b..2abff2b 100644 --- a/src/resolver.rs +++ b/src/resolver.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha512}; use std::{ collections::{HashMap, HashSet}, error::Error, @@ -35,7 +36,10 @@ impl PinnedPackMeta { for file in files.into_iter() { let file = file?; if file.file_type()?.is_file() { - println!("Checking if file {:#?} exists in pinned mods...", file.file_name()); + println!( + "Checking if file {:#?} exists in pinned mods...", + file.file_name() + ); let filename = file.file_name(); if !self.file_is_pinned(&filename) { println!( @@ -62,9 +66,24 @@ impl PinnedPackMeta { } println!("Downloading {} from {}", filename, url); let file_contents = reqwest::get(url).await?.bytes().await?; - // TODO: Check hash + let mut hasher = Sha512::new(); + hasher.update(&file_contents); + let sha512_hash = format!("{:X}", hasher.finalize()).to_ascii_lowercase(); + let sha512 = sha512.to_ascii_lowercase(); + if sha512_hash != *sha512 { + eprintln!( + "Sha512 hash mismatch for file {}\nExpected:\n{}\nGot:\n{}", + filename, sha512, sha512_hash + ); + return Err(format!( + "Sha512 hash mismatch for file {}\nExpected:\n{}\nGot:\n{}", + filename, sha512, sha512_hash + ) + .into()); + } + tokio::fs::write(mods_dir.join(filename), file_contents).await?; - }, + } crate::providers::FileSource::Local { path, sha1, @@ -89,9 +108,9 @@ impl PinnedPackMeta { filename, } => { if OsStr::new(filename) == file_name { - return true + return true; } - }, + } crate::providers::FileSource::Local { path, sha1, @@ -99,14 +118,14 @@ impl PinnedPackMeta { filename, } => { if OsStr::new(filename) == file_name { - return true + return true; } - }, + } } } } - return false + return false; } pub async fn pin_mod_and_deps(