hive-c0re: stop silently dropping errors on credential/marker writes
Add secret_file::write_secret_0600: create the parent dir, write a sibling temp file opened create_new + mode 0600, sync_all, rename over the target. Use it for the matrix sender token, the space/chat room-id files and the forge core token, which previously wrote at the process umask, then chmod-ed with the error discarded, and dropped the create_dir_all error. agent_identity::write_identity uses it too instead of its own open-0600 loop; that loop opened with create + truncate, so a pre-existing file kept its old mode. Also log instead of discarding: - the manager's applied-rev marker write in auto_update - the knowledge `git remote set-url` scrub (spawn error and non-zero exit; the exit status only, since stderr may echo the old URL) - the parent create_dir_all in paths::move_if_legacy Closes #5037
This commit is contained in:
parent
54226e027d
commit
f53ccb2740
8 changed files with 119 additions and 53 deletions
|
|
@ -121,13 +121,12 @@ async fn collect(agent: &str, dir: &Path) -> Result<(), Skipped> {
|
|||
|
||||
/// Write the two private files, replacing whatever was there.
|
||||
///
|
||||
/// `0600` from the moment each file exists rather than after a `chmod`: the
|
||||
/// key is written through a handle opened with that mode, so there is no
|
||||
/// instant where it sits on disk world-readable.
|
||||
/// `0600` from the moment each file exists rather than after a `chmod`
|
||||
/// ([`crate::secret_file::write_secret_0600`]), so there is no instant where
|
||||
/// the key sits on disk world-readable.
|
||||
fn write_identity(dir: &Path, credential: &mtls::Credential) -> anyhow::Result<()> {
|
||||
use anyhow::Context as _;
|
||||
use std::io::Write as _;
|
||||
use std::os::unix::fs::{OpenOptionsExt as _, PermissionsExt as _};
|
||||
use std::os::unix::fs::PermissionsExt as _;
|
||||
|
||||
std::fs::create_dir_all(dir).with_context(|| format!("create {}", dir.display()))?;
|
||||
// The directory too: its own mode is what stops anything but `hive-core`
|
||||
|
|
@ -139,19 +138,7 @@ fn write_identity(dir: &Path, credential: &mtls::Credential) -> anyhow::Result<(
|
|||
(CERT_CREDENTIAL, credential.cert.as_bytes()),
|
||||
(KEY_CREDENTIAL, credential.key.as_bytes()),
|
||||
] {
|
||||
let file = dir.join(name);
|
||||
let mut handle = std::fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.mode(0o600)
|
||||
.open(&file)
|
||||
.with_context(|| format!("open {}", file.display()))?;
|
||||
// The error carries the path and never the bytes — the one line in
|
||||
// this function where a value could otherwise be interpolated.
|
||||
handle
|
||||
.write_all(bytes)
|
||||
.with_context(|| format!("write {}", file.display()))?;
|
||||
crate::secret_file::write_secret_0600(&dir.join(name), bytes)?;
|
||||
}
|
||||
|
||||
// Public material, and `0644` says so — it is the same bundle every host
|
||||
|
|
|
|||
Loading…
Reference in a new issue