Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Atomic create new files with permissions to owner in ethstore (#8896)
Browse files Browse the repository at this point in the history
* Atomic create new files with permissions to owner in ethstore

* Allow replacing existing files

We have two behaviors for `insert_with_filename` depending on whether `dedup` is true.  Add
`replace_file_with_permissions_to_owner` which use `OpenOptions::create(true)` instead of `create_new`.
  • Loading branch information
sorpaas authored and debris committed Jun 14, 2018
1 parent 9546e0c commit fc86b17
Showing 1 changed file with 38 additions and 18 deletions.
56 changes: 38 additions & 18 deletions ethstore/src/accounts_dir/disk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,43 @@ const IGNORED_FILES: &'static [&'static str] = &[
"vault.json",
];

#[cfg(not(windows))]
fn restrict_permissions_to_owner(file_path: &Path) -> Result<(), i32> {
use std::ffi;

#[cfg(unix)]
fn create_new_file_with_permissions_to_owner(file_path: &Path) -> io::Result<fs::File> {
use libc;
use std::os::unix::fs::OpenOptionsExt;

let cstr = ffi::CString::new(&*file_path.to_string_lossy())
.map_err(|_| -1)?;
match unsafe { libc::chmod(cstr.as_ptr(), libc::S_IWUSR | libc::S_IRUSR) } {
0 => Ok(()),
x => Err(x),
}
fs::OpenOptions::new()
.write(true)
.create_new(true)
.mode(libc::S_IWUSR | libc::S_IRUSR)
.open(file_path)
}

#[cfg(windows)]
fn restrict_permissions_to_owner(_file_path: &Path) -> Result<(), i32> {
Ok(())
#[cfg(not(unix))]
fn create_new_file_with_permissions_to_owner(file_path: &Path) -> io::Result<fs::File> {
fs::OpenOptions::new()
.write(true)
.create_new(true)
.open(file_path)
}

#[cfg(unix)]
fn replace_file_with_permissions_to_owner(file_path: &Path) -> io::Result<fs::File> {
use libc;
use std::os::unix::fs::PermissionsExt;

let file = fs::File::create(file_path)?;
let mut permissions = file.metadata()?.permissions();
permissions.set_mode(libc::S_IWUSR | libc::S_IRUSR);
file.set_permissions(permissions)?;

Ok(file)
}

#[cfg(not(unix))]
fn replace_file_with_permissions_to_owner(file_path: &Path) -> io::Result<fs::File> {
fs::File::create(file_path)
}

/// Root keys directory implementation
Expand Down Expand Up @@ -173,17 +194,16 @@ impl<T> DiskDirectory<T> where T: KeyFileManager {

{
// save the file
let mut file = fs::File::create(&keyfile_path)?;
let mut file = if dedup {
create_new_file_with_permissions_to_owner(&keyfile_path)?
} else {
replace_file_with_permissions_to_owner(&keyfile_path)?
};

// write key content
self.key_manager.write(original_account, &mut file).map_err(|e| Error::Custom(format!("{:?}", e)))?;

file.flush()?;

if let Err(_) = restrict_permissions_to_owner(keyfile_path.as_path()) {
return Err(Error::Io(io::Error::last_os_error()));
}

file.sync_all()?;
}

Expand Down

0 comments on commit fc86b17

Please sign in to comment.