Skip to content

Commit f7f24a9

Browse files
authored
Fix permissions not reset on overwrite with --config-dir. (#2501)
1 parent 6043f0f commit f7f24a9

1 file changed

Lines changed: 50 additions & 12 deletions

File tree

cmd/soroban-cli/src/config/locator.rs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -413,15 +413,18 @@ impl Args {
413413
#[cfg(unix)]
414414
{
415415
use std::io::Write as _;
416-
use std::os::unix::fs::OpenOptionsExt;
416+
use std::os::unix::fs::{OpenOptionsExt, PermissionsExt};
417417
let mut to_file = OpenOptions::new()
418418
.create(true)
419419
.truncate(true)
420420
.write(true)
421421
.mode(0o600)
422422
.open(&path)?;
423423
to_file.write_all(content.as_bytes())?;
424-
fix_config_permissions();
424+
std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o600))?;
425+
if let Ok(root) = self.config_dir() {
426+
fix_config_permissions(root);
427+
}
425428
}
426429

427430
#[cfg(not(unix))]
@@ -526,13 +529,9 @@ impl Pwd for Args {
526529
}
527530

528531
#[cfg(unix)]
529-
fn fix_config_permissions() {
532+
fn fix_config_permissions(root: std::path::PathBuf) {
530533
use std::os::unix::fs::PermissionsExt;
531534

532-
let Ok(root) = global_config_path() else {
533-
return;
534-
};
535-
536535
let mut bad_dirs = Vec::new();
537536
let mut bad_files = Vec::new();
538537
let mut stack = vec![root];
@@ -589,7 +588,7 @@ pub fn ensure_directory(dir: PathBuf) -> Result<PathBuf, Error> {
589588
.mode(0o700)
590589
.create(parent)
591590
.map_err(|_| dir_creation_failed(parent))?;
592-
fix_config_permissions();
591+
fix_config_permissions(parent.to_path_buf());
593592
}
594593

595594
#[cfg(not(unix))]
@@ -630,9 +629,6 @@ impl KeyType {
630629
path: path.to_path_buf(),
631630
})?;
632631

633-
#[cfg(unix)]
634-
fix_config_permissions();
635-
636632
Ok(toml::from_str(&data)?)
637633
}
638634

@@ -704,7 +700,16 @@ impl KeyType {
704700
})?;
705701

706702
#[cfg(unix)]
707-
fix_config_permissions();
703+
{
704+
use std::os::unix::fs::PermissionsExt;
705+
std::fs::set_permissions(&filepath, std::fs::Permissions::from_mode(0o600)).map_err(
706+
|error| Error::IdCreationFailed {
707+
filepath: filepath.clone(),
708+
error,
709+
},
710+
)?;
711+
fix_config_permissions(pwd.to_path_buf());
712+
}
708713

709714
Ok(filepath)
710715
}
@@ -860,6 +865,39 @@ mod tests {
860865
use serial_test::serial;
861866
use std::collections::HashMap;
862867

868+
#[test]
869+
fn overwrite_resets_file_permissions_to_0600() {
870+
use std::os::unix::fs::PermissionsExt;
871+
872+
let dir = tempfile::tempdir().unwrap();
873+
let identity_dir = dir.path().join("identity");
874+
std::fs::create_dir_all(&identity_dir).unwrap();
875+
876+
// Pre-create alice.toml at 0644 to simulate an inherited insecure mode.
877+
let alice = identity_dir.join("alice.toml");
878+
std::fs::write(&alice, "seed_phrase = \"old\"\n").unwrap();
879+
std::fs::set_permissions(&alice, std::fs::Permissions::from_mode(0o644)).unwrap();
880+
881+
assert_eq!(
882+
std::fs::metadata(&alice).unwrap().permissions().mode() & 0o777,
883+
0o644,
884+
"setup: alice.toml should start at 0644"
885+
);
886+
887+
let value: HashMap<String, String> = HashMap::new();
888+
KeyType::Identity
889+
.write("alice", &value, dir.path())
890+
.unwrap();
891+
892+
let perms = std::fs::metadata(&alice).unwrap().permissions();
893+
assert_eq!(
894+
perms.mode() & 0o777,
895+
0o600,
896+
"overwritten identity file should be 0600, got {:o}",
897+
perms.mode() & 0o777
898+
);
899+
}
900+
863901
#[test]
864902
fn test_write_sets_file_permissions_to_0600() {
865903
use std::os::unix::fs::PermissionsExt;

0 commit comments

Comments
 (0)