diff --git a/hive-c0re/src/gateway_nginx.rs b/hive-c0re/src/gateway_nginx.rs index 1fe2bd8b..4a4b4ca0 100644 --- a/hive-c0re/src/gateway_nginx.rs +++ b/hive-c0re/src/gateway_nginx.rs @@ -406,14 +406,17 @@ mod tests { use super::*; use crate::lifecycle::MANAGER_NAME; - /// The htpasswd file is published `0644` whatever the umask, holds the - /// lines newline-terminated, and leaves no temp file beside it. + /// The htpasswd file is published `0644` even when the temp file it is + /// 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] - 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 path = dir.path().join("htpasswd"); - std::fs::write(&path, "stale\n").expect("seed"); - std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600)).expect("chmod"); + let tmp = path.with_extension("htpasswd.tmp"); + 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"); diff --git a/hivectl/src/wg.rs b/hivectl/src/wg.rs index 61c436c6..b291a622 100644 --- a/hivectl/src/wg.rs +++ b/hivectl/src/wg.rs @@ -300,16 +300,25 @@ mod tests { } } - /// The key lands at `0400` with its bytes intact, replacing whatever was - /// there, and no temp file is left beside it. + /// The key reaches its path only by a rename from a sibling temp: with + /// 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] - 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 _; let dir = std::env::temp_dir().join(format!("hivectl-wg-key-{}", std::process::id())); std::fs::create_dir_all(&dir).expect("mkdir"); 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"); let mode = std::fs::metadata(&path).expect("stat").permissions().mode() & 0o777;