diff --git a/apps/artcraft-launcher/src/logging.rs b/apps/artcraft-launcher/src/logging.rs index 271ff0c3..fcd13c51 100644 --- a/apps/artcraft-launcher/src/logging.rs +++ b/apps/artcraft-launcher/src/logging.rs @@ -45,10 +45,19 @@ pub fn rotate(dir: &Path) -> std::io::Result<(PathBuf, File)> { } } let path = numbered(dir, 0); - let file = File::create(&path)?; + let file = create_private(&path)?; Ok((path, file)) } +/// A log names the user's folders, so only the user may read it. +fn create_private(path: &Path) -> std::io::Result { + let mut options = std::fs::OpenOptions::new(); + options.write(true).create(true).truncate(true); + #[cfg(unix)] + std::os::unix::fs::OpenOptionsExt::mode(&mut options, 0o600); + options.open(path) +} + /// Where formatted records go besides standard error: kept in memory until a file is attached, /// then appended to it until it reaches its size cap. pub struct Sink { @@ -255,6 +264,16 @@ mod tests { let _ = std::fs::remove_dir_all(&dir); } + #[cfg(unix)] + #[test] + fn only_the_user_can_read_the_log() { + use std::os::unix::fs::PermissionsExt; + let dir = temp_dir("private"); + let (path, _file) = rotate(&dir).unwrap(); + assert_eq!(std::fs::metadata(&path).unwrap().permissions().mode() & 0o777, 0o600); + let _ = std::fs::remove_dir_all(&dir); + } + #[test] fn rotation_into_an_unusable_directory_is_an_error_not_a_panic() { let dir = temp_dir("blocked");