Watch
0
0
Fork
You've already forked hyperhive
0

hive-c0re, hivectl: make the htpasswd and wg key tests fail on the in-place write

The htpasswd test now seeds the temp path at 0600, so only the explicit
chmod on the temp yields 0644. The wg test blocks the temp path with a
directory and asserts the write fails with the existing key untouched,
which an in-place write cannot satisfy.
This commit is contained in:
atlas 2026-10-09 16:22:34 +02:00 • committed by mara
commit dd172d9cf8
2 changed files with 21 additions and 9 deletions

View file

@ -406,14 +406,17 @@ mod tests {
use super::*; use super::*;
use crate::lifecycle::MANAGER_NAME; use crate::lifecycle::MANAGER_NAME;
/// The htpasswd file is published `0644` whatever the umask, holds the /// The htpasswd file is published `0644` even when the temp file it is
/// lines newline-terminated, and leaves no temp file beside it. /// written through already exists at `0600` (opening an existing file
/// keeps its mode), holds the lines newline-terminated, and leaves no
/// temp file beside it.
#[test] #[test]
fn htpasswd_is_written_0644_with_no_temp_left() { fn htpasswd_is_published_0644_over_a_private_leftover_tmp() {
let dir = tempfile::tempdir().expect("tempdir"); let dir = tempfile::tempdir().expect("tempdir");
let path = dir.path().join("htpasswd"); let path = dir.path().join("htpasswd");
std::fs::write(&path, "stale\n").expect("seed"); let tmp = path.with_extension("htpasswd.tmp");
std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600)).expect("chmod"); std::fs::write(&tmp, "leftover\n").expect("seed tmp");
std::fs::set_permissions(&tmp, std::fs::Permissions::from_mode(0o600)).expect("chmod");
htpasswd_write_at(&path, &["a:x".to_owned(), "b:y".to_owned()]).expect("write"); htpasswd_write_at(&path, &["a:x".to_owned(), "b:y".to_owned()]).expect("write");

View file

@ -300,16 +300,25 @@ mod tests {
} }
} }
/// The key lands at `0400` with its bytes intact, replacing whatever was /// The key reaches its path only by a rename from a sibling temp: with
/// there, and no temp file is left beside it. /// the temp path blocked, the write fails and the existing key is left
/// byte-for-byte as it was. Once unblocked, the key lands at `0400` with
/// its bytes intact and no temp file beside it.
#[test] #[test]
fn key_is_written_0400_with_no_temp_left() { fn key_is_written_through_a_temp_and_lands_0400() {
use std::os::unix::fs::PermissionsExt as _; use std::os::unix::fs::PermissionsExt as _;
let dir = std::env::temp_dir().join(format!("hivectl-wg-key-{}", std::process::id())); let dir = std::env::temp_dir().join(format!("hivectl-wg-key-{}", std::process::id()));
std::fs::create_dir_all(&dir).expect("mkdir"); std::fs::create_dir_all(&dir).expect("mkdir");
let path = dir.join("hive.key"); let path = dir.join("hive.key");
std::fs::write(&path, "stale").expect("seed"); let tmp = dir.join("hive.key.tmp");
std::fs::write(&path, "old-key\n").expect("seed");
std::fs::create_dir(&tmp).expect("block tmp");
let blocked = write_key_0400(&path, b"key-bytes\n");
assert!(blocked.is_err(), "a blocked temp must fail the write");
assert_eq!(std::fs::read(&path).expect("read seed"), b"old-key\n");
std::fs::remove_dir(&tmp).expect("unblock tmp");
write_key_0400(&path, b"key-bytes\n").expect("write"); write_key_0400(&path, b"key-bytes\n").expect("write");
let mode = std::fs::metadata(&path).expect("stat").permissions().mode() & 0o777; let mode = std::fs::metadata(&path).expect("stat").permissions().mode() & 0o777;