seal/security/
tempfile.rs1use std::fs::File;
4use std::io::{self, Write};
5use std::path::{Path, PathBuf};
6use tempfile::NamedTempFile;
7use zeroize::Zeroize;
8
9pub struct SecureTempFile {
14 file: NamedTempFile,
15 path: PathBuf,
16}
17
18impl SecureTempFile {
19 pub fn new() -> io::Result<Self> {
21 let file = tempfile::Builder::new()
22 .prefix("seal-secret-")
23 .suffix(".yaml")
24 .rand_bytes(16)
25 .tempfile()?;
26
27 let path = file.path().to_path_buf();
28
29 #[cfg(unix)]
31 {
32 use std::os::unix::fs::PermissionsExt;
33 let mut perms = std::fs::metadata(&path)?.permissions();
34 perms.set_mode(0o600); std::fs::set_permissions(&path, perms)?;
36 }
37
38 Ok(Self { file, path })
39 }
40
41 pub fn write_all(&mut self, data: &[u8]) -> io::Result<()> {
43 self.file.write_all(data)?;
44 self.file.flush()?;
45 Ok(())
46 }
47
48 pub fn path(&self) -> &Path {
50 &self.path
51 }
52
53 pub fn delete(self) -> io::Result<()> {
55 Ok(())
57 }
58}
59
60impl Drop for SecureTempFile {
61 fn drop(&mut self) {
62 if let Ok(metadata) = std::fs::metadata(&self.path) {
64 let file_size = metadata.len() as usize;
65 if file_size > 0 && file_size < 10 * 1024 * 1024 {
66 let mut zeros = vec![0u8; file_size];
68 if let Ok(mut file) = File::create(&self.path) {
69 let _ = file.write_all(&zeros);
70 let _ = file.flush();
71 }
72 zeros.zeroize();
73 }
74 }
75 }
77}
78
79#[cfg(test)]
80mod tests {
81 use super::*;
82
83 #[test]
84 fn test_secure_temp_file_creation() -> io::Result<()> {
85 let temp_file = SecureTempFile::new()?;
86 assert!(temp_file.path().exists());
87 Ok(())
88 }
89
90 #[test]
91 fn test_secure_temp_file_write() -> io::Result<()> {
92 let mut temp_file = SecureTempFile::new()?;
93 temp_file.write_all(b"test data")?;
94 assert!(temp_file.path().exists());
95 Ok(())
96 }
97
98 #[test]
99 fn test_secure_temp_file_cleanup() -> io::Result<()> {
100 let path;
101 {
102 let temp_file = SecureTempFile::new()?;
103 path = temp_file.path().to_path_buf();
104 assert!(path.exists());
105 }
106 assert!(!path.exists());
108 Ok(())
109 }
110}