Add hash validation for downloaded mods

This commit is contained in:
Warren Hood 2024-08-18 23:43:24 +02:00
parent 9700206b02
commit 76654055e0
3 changed files with 100 additions and 8 deletions

72
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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(