From f3bdb6bc2a90bc815154f00a27844924c722a11b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20Frosteg=C3=A5rd?= Date: Sat, 23 May 2020 16:59:23 +0200 Subject: [PATCH] aquatic_ws: privilege dropping; cli_helpers: show error context --- Cargo.lock | 1 + TODO.md | 1 - aquatic_ws/Cargo.toml | 1 + aquatic_ws/src/lib/config.rs | 5 ++--- aquatic_ws/src/lib/lib.rs | 14 +++++++++++++- cli_helpers/src/lib.rs | 8 ++++---- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f186c39..635d0b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -107,6 +107,7 @@ dependencies = [ "native-tls", "net2", "parking_lot", + "privdrop", "quickcheck", "quickcheck_macros", "rand", diff --git a/TODO.md b/TODO.md index 77dfc16..f05637e 100644 --- a/TODO.md +++ b/TODO.md @@ -3,7 +3,6 @@ ## aquatic_ws * is it even necessary to check if event is readable in poll, since that is all we're listening for? -* privdrop * add sensible logging method, maybe stderrlog with quiet as default ## aquatic_udp diff --git a/aquatic_ws/Cargo.toml b/aquatic_ws/Cargo.toml index 69c992d..3037d6d 100644 --- a/aquatic_ws/Cargo.toml +++ b/aquatic_ws/Cargo.toml @@ -27,6 +27,7 @@ mio = { version = "0.7", features = ["tcp", "os-poll", "os-util"] } native-tls = "0.2" net2 = "0.2" parking_lot = "0.10" +privdrop = "0.3" rand = { version = "0.7", features = ["small_rng"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/aquatic_ws/src/lib/config.rs b/aquatic_ws/src/lib/config.rs index 6f7f6e1..eca22e3 100644 --- a/aquatic_ws/src/lib/config.rs +++ b/aquatic_ws/src/lib/config.rs @@ -13,7 +13,7 @@ pub struct Config { pub network: NetworkConfig, pub handlers: HandlerConfig, pub cleaning: CleaningConfig, - // pub privileges: PrivilegeConfig, + pub privileges: PrivilegeConfig, } @@ -61,7 +61,6 @@ pub struct CleaningConfig { } -// FIXME: implement #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(default)] pub struct PrivilegeConfig { @@ -81,7 +80,7 @@ impl Default for Config { network: NetworkConfig::default(), handlers: HandlerConfig::default(), cleaning: CleaningConfig::default(), - // privileges: PrivilegeConfig::default(), + privileges: PrivilegeConfig::default(), } } } diff --git a/aquatic_ws/src/lib/lib.rs b/aquatic_ws/src/lib/lib.rs index be1527c..3ccd343 100644 --- a/aquatic_ws/src/lib/lib.rs +++ b/aquatic_ws/src/lib/lib.rs @@ -2,8 +2,11 @@ use std::time::Duration; use std::fs::File; use std::io::Read; use std::sync::Arc; + +use anyhow::Context; use native_tls::{Identity, TlsAcceptor}; use parking_lot::Mutex; +use privdrop::PrivDrop; pub mod common; pub mod config; @@ -58,7 +61,8 @@ pub fn run(config: Config) -> anyhow::Result<()> { } // Wait for socket worker statuses. On error from any, quit program. - // On success from all, continue program. + // On success from all, drop privileges if corresponding setting is set + // and continue program. loop { ::std::thread::sleep(::std::time::Duration::from_millis(10)); @@ -73,6 +77,14 @@ pub fn run(config: Config) -> anyhow::Result<()> { } if statuses.iter().all(Option::is_some){ + if config.privileges.drop_privileges { + PrivDrop::default() + .chroot(config.privileges.chroot_path.clone()) + .user(config.privileges.user.clone()) + .apply() + .context("Couldn't drop root privileges")?; + } + break } } diff --git a/cli_helpers/src/lib.rs b/cli_helpers/src/lib.rs index 858cd34..3946909 100644 --- a/cli_helpers/src/lib.rs +++ b/cli_helpers/src/lib.rs @@ -1,7 +1,7 @@ use std::fs::File; use std::io::Read; -use anyhow; +use anyhow::Context; use gumdrop::Options; use serde::{Serialize, de::DeserializeOwned}; use toml; @@ -26,7 +26,7 @@ pub fn run_app_with_cli_and_config( ::std::process::exit(match run_inner(title, app_fn) { Ok(()) => 0, Err(err) => { - print_help(title, Some(err)); + eprintln!("Error: {:#}", err); 1 }, @@ -68,7 +68,7 @@ fn config_from_toml_file(path: String) -> anyhow::Result let mut data = String::new(); file.read_to_string(&mut data)?; - toml::from_str(&data).map_err(|e| anyhow::anyhow!("Parse failed: {}", e)) + toml::from_str(&data).context("Couldn't parse config file") } @@ -84,7 +84,7 @@ fn print_help(title: &str, opt_error: Option){ println!("{}", title); if let Some(error) = opt_error { - println!("\nError: {}.", error); + println!("\nError: {:#}.", error); } println!("\n{}", AppOptions::usage());