{client,server}: enforce permissions on directories and files
This may become a warning rather than an action later, but for now let's make sure older installations that had incorrect permissions are taken care of.pull/48/head
parent
ee890ccaa7
commit
72dc14c49c
|
@ -1,4 +1,5 @@
|
|||
use crate::Error;
|
||||
use colored::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use shared::{ensure_dirs_exist, Cidr, IoErrorContext, Peer, CLIENT_DATA_PATH};
|
||||
use std::{
|
||||
|
@ -23,12 +24,18 @@ pub enum Contents {
|
|||
|
||||
impl DataStore {
|
||||
pub(self) fn open_with_path<P: AsRef<Path>>(path: P, create: bool) -> Result<Self, Error> {
|
||||
let path = path.as_ref();
|
||||
let mut file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.create(create)
|
||||
.open(&path)
|
||||
.with_path(&path)?;
|
||||
.open(path)
|
||||
.with_path(path)?;
|
||||
|
||||
if shared::chmod(&file, 0o600)? {
|
||||
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
|
||||
}
|
||||
|
||||
let mut json = String::new();
|
||||
file.read_to_string(&mut json).with_path(path)?;
|
||||
let contents = serde_json::from_str(&json).unwrap_or_else(|_| Contents::V1 {
|
||||
|
|
|
@ -114,6 +114,7 @@ pub struct ConfigFile {
|
|||
impl ConfigFile {
|
||||
pub fn write_to_path<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
|
||||
let mut invitation_file = File::create(&path).with_path(&path)?;
|
||||
shared::chmod(&invitation_file, 0o600)?;
|
||||
invitation_file
|
||||
.write_all(toml::to_string(self).unwrap().as_bytes())
|
||||
.with_path(path)?;
|
||||
|
@ -121,6 +122,11 @@ impl ConfigFile {
|
|||
}
|
||||
|
||||
pub fn from_file<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
|
||||
let path = path.as_ref();
|
||||
let file = File::open(path).with_path(path)?;
|
||||
if shared::chmod(&file, 0o600)? {
|
||||
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
|
||||
}
|
||||
Ok(toml::from_slice(&std::fs::read(&path).with_path(path)?)?)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{ensure_dirs_exist, Error, IoErrorContext, CLIENT_CONFIG_PATH};
|
||||
use colored::*;
|
||||
use indoc::writedoc;
|
||||
use ipnetwork::IpNetwork;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -58,12 +59,16 @@ impl InterfaceConfig {
|
|||
comments: bool,
|
||||
mode: Option<u32>,
|
||||
) -> Result<(), Error> {
|
||||
let path = path.as_ref();
|
||||
let mut target_file = OpenOptions::new()
|
||||
.create_new(true)
|
||||
.write(true)
|
||||
.open(&path)
|
||||
.with_path(&path)?;
|
||||
.open(path)
|
||||
.with_path(path)?;
|
||||
if let Some(val) = mode {
|
||||
if crate::chmod(&target_file, 0o600)? {
|
||||
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
|
||||
}
|
||||
let metadata = target_file.metadata()?;
|
||||
let mut permissions = metadata.permissions();
|
||||
permissions.set_mode(val);
|
||||
|
@ -106,7 +111,12 @@ impl InterfaceConfig {
|
|||
}
|
||||
|
||||
pub fn from_interface(interface: &InterfaceName) -> Result<Self, Error> {
|
||||
Self::from_file(Self::build_config_file_path(interface)?)
|
||||
let path = Self::build_config_file_path(interface)?;
|
||||
let file = File::open(&path).with_path(&path)?;
|
||||
if crate::chmod(&file, 0o600)? {
|
||||
println!("{} updated permissions for {} to 0600.", "[!]".yellow(), path.display());
|
||||
}
|
||||
Self::from_file(path)
|
||||
}
|
||||
|
||||
fn build_config_file_path(interface: &InterfaceName) -> Result<PathBuf, Error> {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use colored::*;
|
||||
use ipnetwork::IpNetwork;
|
||||
use lazy_static::lazy_static;
|
||||
use prompts::hostname_validator;
|
||||
|
@ -362,21 +363,37 @@ pub static WG_DIR: &str = "/etc/wireguard";
|
|||
pub fn ensure_dirs_exist(dirs: &[&Path]) -> Result<(), Error> {
|
||||
for dir in dirs {
|
||||
match fs::create_dir(dir) {
|
||||
Ok(()) => {
|
||||
let target_file = File::open(dir).with_path(dir)?;
|
||||
let metadata = target_file.metadata().with_path(dir)?;
|
||||
let mut permissions = metadata.permissions();
|
||||
permissions.set_mode(0o700);
|
||||
},
|
||||
Err(e) if e.kind() != io::ErrorKind::AlreadyExists => {
|
||||
return Err(e.into());
|
||||
},
|
||||
_ => {},
|
||||
_ => {
|
||||
let target_file = File::open(dir).with_path(dir)?;
|
||||
if chmod(&target_file, 0o700)? {
|
||||
println!("{} updated permissions for {} to 0700.", "[!]".yellow(), dir.display());
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Updates the permissions of a file or directory. Returns `Ok(true)` if
|
||||
/// permissions had to be changed, `Ok(false)` if permissions were already
|
||||
/// correct.
|
||||
pub fn chmod(file: &File, mode: u32) -> Result<bool, Error> {
|
||||
let metadata = file.metadata()?;
|
||||
let mut permissions = metadata.permissions();
|
||||
let updated = if permissions.mode() != mode {
|
||||
permissions.set_mode(mode);
|
||||
file.set_permissions(permissions)?;
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
||||
Ok(updated)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
Loading…
Reference in New Issue