diff --git a/Cargo.lock b/Cargo.lock index 19d1769e..8b74b3bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4439,6 +4439,7 @@ dependencies = [ "maplit", "ndk", "ndk-glue", + "nix 0.23.1", "no-std-net", "num_cpus", "once_cell", @@ -4469,6 +4470,7 @@ dependencies = [ "webpki-roots 0.22.2", "wee_alloc", "winapi", + "windows-permissions", "ws_stream_wasm", "x25519-dalek-ng", ] @@ -4805,6 +4807,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-permissions" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e2ccdc3c6bf4d4a094e031b63fadd08d8e42abd259940eb8aa5fdc09d4bf9be" +dependencies = [ + "bitflags", + "winapi", +] + [[package]] name = "windows-service" version = "0.4.0" diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index faab93a3..a44b5ebb 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -73,6 +73,7 @@ socket2 = "^0" bugsalot = "^0" chrono = "^0" libc = "^0" +nix = "^0" # Dependencies for WASM builds only [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -129,6 +130,7 @@ rtnetlink = { version = "^0", default-features = false, features = [ "smol_socke # Dependencies for Windows [target.'cfg(target_os = "windows")'.dependencies] winapi = { version = "^0", features = [ "iptypes", "iphlpapi" ] } +windows-permissions = "^0" # Dependencies for iOS [target.'cfg(target_os = "ios")'.dependencies] diff --git a/veilid-core/src/intf/native/block_store.rs b/veilid-core/src/intf/native/block_store.rs index 7e5ae3a3..f8ef955c 100644 --- a/veilid-core/src/intf/native/block_store.rs +++ b/veilid-core/src/intf/native/block_store.rs @@ -23,6 +23,9 @@ impl BlockStore { } pub async fn init(&self) -> Result<(), String> { + // Ensure permissions are correct + // ensure_file_private_owner(&dbpath)?; + Ok(()) } diff --git a/veilid-core/src/intf/native/protected_store.rs b/veilid-core/src/intf/native/protected_store.rs index ac5cc992..67165b87 100644 --- a/veilid-core/src/intf/native/protected_store.rs +++ b/veilid-core/src/intf/native/protected_store.rs @@ -48,6 +48,7 @@ impl ProtectedStore { let c = self.config.get(); let mut inner = self.inner.lock(); if !c.protected_store.always_use_insecure_storage { + // Attempt to open the secure keyring cfg_if! { if #[cfg(target_os = "android")] { inner.keyring_manager = KeyringManager::new_secure(&c.program_name, intf::native::utils::android::get_android_globals()).ok(); @@ -70,6 +71,11 @@ impl ProtectedStore { format!("_{}", c.namespace) } )); + + // Ensure permissions are correct + ensure_file_private_owner(&insecure_keyring_file)?; + + // Open the insecure keyring inner.keyring_manager = Some( KeyringManager::new_insecure(&c.program_name, &insecure_keyring_file) .map_err(map_to_string) diff --git a/veilid-core/src/intf/native/table_store.rs b/veilid-core/src/intf/native/table_store.rs index 7bc04148..0766d439 100644 --- a/veilid-core/src/intf/native/table_store.rs +++ b/veilid-core/src/intf/native/table_store.rs @@ -99,9 +99,17 @@ impl TableStore { } let dbpath = self.get_dbpath(&table_name)?; + + // Ensure permissions are correct + ensure_file_private_owner(&dbpath)?; + let cfg = DatabaseConfig::with_columns(column_count); let db = Database::open(&dbpath, cfg).map_err(|e| format!("failed to open tabledb: {}", e))?; + + // Ensure permissions are correct + ensure_file_private_owner(&dbpath)?; + trace!( "opened table store '{}' at path '{:?}' with {} columns", name, diff --git a/veilid-core/src/xx/tools.rs b/veilid-core/src/xx/tools.rs index d9e696d8..b2b70a4e 100644 --- a/veilid-core/src/xx/tools.rs +++ b/veilid-core/src/xx/tools.rs @@ -1,5 +1,6 @@ use crate::xx::*; use alloc::string::ToString; +use std::path::Path; #[macro_export] macro_rules! assert_err { @@ -185,3 +186,60 @@ impl Dedup for Vec { }) } } + +cfg_if::cfg_if! { + if #[cfg(unix)] { + use std::os::unix::fs::MetadataExt; + use std::os::unix::prelude::PermissionsExt; + use nix::unistd::{chown, Uid, Gid}; + + pub fn ensure_file_private_owner>(path: P) -> Result<(), String> + { + let path = path.as_ref(); + if !path.exists() { + return Ok(()); + } + + let uid = Uid::effective(); + let gid = Gid::effective(); + let meta = std::fs::metadata(path).map_err(|e| format!("unable to get metadata for path '{:?}': {}",path, e))?; + + if meta.mode() != 0o600 { + std::fs::set_permissions(path,std::fs::Permissions::from_mode(0o600)).map_err(|e| format!("unable to set correct permissions on path '{:?}': {}", path, e))?; + } + if meta.uid() != uid.as_raw() || meta.gid() != gid.as_raw() { + chown(path, Some(uid), Some(gid)).map_err(|e| format!("unable to set correct owner on path '{:?}': {}", path, e))?; + } + Ok(()) + } + } else if #[cfg(windows)] { + use std::os::windows::fs::MetadataExt; + use windows_permissions::*; + + pub fn ensure_file_private_owner>(path: P) -> Result<(),String> + { + let path = path.as_ref(); + if !path.exists() { + return Ok(()); + } + + // let uid = Uid::effective(); + // let gid = Gid::effective(); + let meta = std::fs::metadata(path).map_err(|e| format!("unable to get metadata for path '{:?}': {}",path, e))?; + + if meta.mode() != 0o600 { + std::fs::set_permissions(path,std::fs::Permissions::from_mode(0o600)).map_err(|e| format!("unable to set correct permissions on path '{:?}': {}", path, e))?; + } + + // if meta.uid() != uid.as_raw() || meta.gid() != gid.as_raw() { + // chown(path, Some(uid), Some(gid)).map_err(|e| format!("unable to set correct owner on path '{:?}': {}", path, e))?; + // } + Ok(()) + } + } else { + pub fn ensure_file_private_owner>(path: P) -> Result<(),String> + { + Ok(()) + } + } +} diff --git a/veilid-server/src/unix.rs b/veilid-server/src/unix.rs index 01c7e915..62efddda 100644 --- a/veilid-server/src/unix.rs +++ b/veilid-server/src/unix.rs @@ -27,7 +27,7 @@ pub fn run_daemon(settings: Settings, _matches: ArgMatches) -> Result<(), String let mut daemon = daemonize::Daemonize::new(); let s = settings.read(); if let Some(pid_file) = &s.daemon.pid_file { - daemon = daemon.pid_file(pid_file).chown_pid_file(true); + daemon = daemon.pid_file(pid_file); //.chown_pid_file(true); } if let Some(chroot) = &s.daemon.chroot { daemon = daemon.chroot(chroot);