From 4b1102c4c8a5a41e5d55bc9d92f111858fcd20ed Mon Sep 17 00:00:00 2001 From: kpcyrd Date: Mon, 19 Jun 2023 13:07:39 +0200 Subject: [PATCH] Fix unit tests --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + README.md | 16 ++++++++++++++++ src/sign/pgp.rs | 30 +++++++++++++++++++++++++++--- 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 78b0cc9..f5cb7af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2445,6 +2445,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" + [[package]] name = "sequoia-openpgp" version = "1.16.0" @@ -2573,6 +2579,7 @@ dependencies = [ "regex", "reqwest", "rust-lzma", + "semver", "sequoia-openpgp", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index d72bce0..9c16b3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,4 +70,5 @@ zip = { version = "0.6.3", default-features = false, features = ["deflate", "bzi zstd = { version = "0.12", features = ["pkg-config"] } [dev-dependencies] +semver = "1.0.17" tempfile = "3.3.0" diff --git a/README.md b/README.md index 95561ba..bef872c 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,22 @@ Have you ever wondered if the update you downloaded is the same one everybody el `sh4d0wup` is a malicious http/https update server that acts as a reverse proxy in front of a legitimate server and can infect + sign various artifact formats. Attacks are configured in `plots` that describe how http request routing works, how artifacts are patched/generated, how they should be signed and with which key. A route can have `selectors` so it matches only if eg. the user-agent matches a pattern or if the client is connecting from a specific ip address. For development and testing, mock signing keys/certificates can be generated and marked as trusted. +## 🏗️ Building sh4d0wup executable + +There's a pre-built binary in the Arch Linux [extra] repository. To build the binary from source on a Debian based system use this (tested with ubuntu 22.04): + +```sh +apt-get install curl git build-essential clang pkg-config libssl-dev libzstd-dev libpcsclite-dev nettle-dev liblzma-dev +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +source "$HOME/.cargo/env" +git clone https://github.com/kpcyrd/sh4d0wup +cd sh4d0wup +cargo build --release + +sudo cp ./target/release/sh4d0wup /usr/bin +sh4d0wup --help +``` + ## 📦 Compile a plot Some plots are more complex to run than others, to avoid long startup time due diff --git a/src/sign/pgp.rs b/src/sign/pgp.rs index b974b74..19f2ee2 100644 --- a/src/sign/pgp.rs +++ b/src/sign/pgp.rs @@ -97,6 +97,27 @@ mod tests { use std::process::{Command, Stdio}; use tempfile::TempDir; + fn sq_signer_file_arg_name() -> Result<&'static str> { + // figure out how to invoke sq correctly + let version = Command::new("sq").arg("-V").output()?; + let version = String::from_utf8(version.stdout)?; + let mut version = version.split(' '); + assert_eq!(version.next(), Some("sq")); + let version = version + .next() + .context("Missing version string from sq -V output")?; + let version = semver::Version::parse(version).context("Failed to parse sq version")?; + let req = semver::VersionReq::parse("<0.30.0").unwrap(); + + if req.matches(&version) { + // legacy name for backwards compat + Ok("--signer-cert") + } else { + // latest argument name + Ok("--signer-file") + } + } + fn sq_verify(args: &[&str], data: &[u8]) -> Result> { let mut child = Command::new("sq") .args(args) @@ -139,7 +160,7 @@ mod tests { let output = sq_verify( &[ "verify", - "--signer-file", + sq_signer_file_arg_name()?, &cert_path, "--detached", &sig_path, @@ -165,7 +186,7 @@ mod tests { let output = sq_verify( &[ "verify", - "--signer-file", + sq_signer_file_arg_name()?, &cert_path, "--detached", &sig_path, @@ -188,7 +209,10 @@ mod tests { let cert_path = temp_put(&dir, "cert.pgp", key.cert.context("Missing public key")?)?; let msg_path = temp_put(&dir, "msg.txt", msg)?; - let output = sq_verify(&["verify", "--signer-file", &cert_path, &msg_path], data)?; + let output = sq_verify( + &["verify", sq_signer_file_arg_name()?, &cert_path, &msg_path], + data, + )?; assert_eq!(output, data); Ok(()) }