1
0
forked from GRIN/grim

Write encrypted money-seed file with 0600 permissions on Unix

WalletSeed::init_file now creates wallet.seed owner-only (0600) via
OpenOptionsExt, mirroring the Nostr nsec in src/nostr/identity.rs, so
other local users cannot read it for an offline password grind. Uses
#[cfg(unix)] so non-Unix still compiles. KDF unchanged.
This commit is contained in:
2ro
2026-07-10 13:41:43 -04:00
parent d49cf5c82c
commit 4baba58dc3
+26 -4
View File
@@ -18,7 +18,6 @@ use grin_wallet_impls::Error;
use rand::{Rng, rng};
use serde_derive::{Deserialize, Serialize};
use serde_json;
use std::fs::File;
use std::io::Write;
use ring::aead;
@@ -48,9 +47,32 @@ impl WalletSeed {
let seed = WalletSeed::from_mnemonic(recovery_phrase)?;
let enc_seed = EncryptedWalletSeed::from_seed(&seed, password)?;
let enc_seed_json = serde_json::to_string_pretty(&enc_seed).map_err(|_| Error::Format)?;
let mut file = File::create(seed_file_path).map_err(|_| Error::IO)?;
file.write_all(&enc_seed_json.as_bytes())
.map_err(|_| Error::IO)?;
// The encrypted seed is the wallet's highest-value secret. Write it
// owner-only (0600) on Unix, mirroring the Nostr nsec (see
// src/nostr/identity.rs write_private), so other local users can't read
// it and attempt an offline password grind. Non-Unix keeps default perms.
#[cfg(unix)]
{
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
let mut file = std::fs::OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.mode(0o600)
.open(seed_file_path)
.map_err(|_| Error::IO)?;
file.write_all(&enc_seed_json.as_bytes())
.map_err(|_| Error::IO)?;
// Tighten perms if the file already existed with a looser mode.
let _ =
std::fs::set_permissions(seed_file_path, std::fs::Permissions::from_mode(0o600));
}
#[cfg(not(unix))]
{
let mut file = std::fs::File::create(seed_file_path).map_err(|_| Error::IO)?;
file.write_all(&enc_seed_json.as_bytes())
.map_err(|_| Error::IO)?;
}
Ok(seed)
}
}