aquatic_ws: privilege dropping; cli_helpers: show error context

This commit is contained in:
Joakim Frostegård 2020-05-23 16:59:23 +02:00
parent a596ee155a
commit f3bdb6bc2a
6 changed files with 21 additions and 9 deletions

1
Cargo.lock generated
View file

@ -107,6 +107,7 @@ dependencies = [
"native-tls", "native-tls",
"net2", "net2",
"parking_lot", "parking_lot",
"privdrop",
"quickcheck", "quickcheck",
"quickcheck_macros", "quickcheck_macros",
"rand", "rand",

View file

@ -3,7 +3,6 @@
## aquatic_ws ## aquatic_ws
* is it even necessary to check if event is readable in poll, since that * is it even necessary to check if event is readable in poll, since that
is all we're listening for? is all we're listening for?
* privdrop
* add sensible logging method, maybe stderrlog with quiet as default * add sensible logging method, maybe stderrlog with quiet as default
## aquatic_udp ## aquatic_udp

View file

@ -27,6 +27,7 @@ mio = { version = "0.7", features = ["tcp", "os-poll", "os-util"] }
native-tls = "0.2" native-tls = "0.2"
net2 = "0.2" net2 = "0.2"
parking_lot = "0.10" parking_lot = "0.10"
privdrop = "0.3"
rand = { version = "0.7", features = ["small_rng"] } rand = { version = "0.7", features = ["small_rng"] }
serde = { version = "1", features = ["derive"] } serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"

View file

@ -13,7 +13,7 @@ pub struct Config {
pub network: NetworkConfig, pub network: NetworkConfig,
pub handlers: HandlerConfig, pub handlers: HandlerConfig,
pub cleaning: CleaningConfig, pub cleaning: CleaningConfig,
// pub privileges: PrivilegeConfig, pub privileges: PrivilegeConfig,
} }
@ -61,7 +61,6 @@ pub struct CleaningConfig {
} }
// FIXME: implement
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)] #[serde(default)]
pub struct PrivilegeConfig { pub struct PrivilegeConfig {
@ -81,7 +80,7 @@ impl Default for Config {
network: NetworkConfig::default(), network: NetworkConfig::default(),
handlers: HandlerConfig::default(), handlers: HandlerConfig::default(),
cleaning: CleaningConfig::default(), cleaning: CleaningConfig::default(),
// privileges: PrivilegeConfig::default(), privileges: PrivilegeConfig::default(),
} }
} }
} }

View file

@ -2,8 +2,11 @@ use std::time::Duration;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::sync::Arc; use std::sync::Arc;
use anyhow::Context;
use native_tls::{Identity, TlsAcceptor}; use native_tls::{Identity, TlsAcceptor};
use parking_lot::Mutex; use parking_lot::Mutex;
use privdrop::PrivDrop;
pub mod common; pub mod common;
pub mod config; 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. // 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 { loop {
::std::thread::sleep(::std::time::Duration::from_millis(10)); ::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 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 break
} }
} }

View file

@ -1,7 +1,7 @@
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use anyhow; use anyhow::Context;
use gumdrop::Options; use gumdrop::Options;
use serde::{Serialize, de::DeserializeOwned}; use serde::{Serialize, de::DeserializeOwned};
use toml; use toml;
@ -26,7 +26,7 @@ pub fn run_app_with_cli_and_config<T>(
::std::process::exit(match run_inner(title, app_fn) { ::std::process::exit(match run_inner(title, app_fn) {
Ok(()) => 0, Ok(()) => 0,
Err(err) => { Err(err) => {
print_help(title, Some(err)); eprintln!("Error: {:#}", err);
1 1
}, },
@ -68,7 +68,7 @@ fn config_from_toml_file<T>(path: String) -> anyhow::Result<T>
let mut data = String::new(); let mut data = String::new();
file.read_to_string(&mut data)?; 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<anyhow::Error>){
println!("{}", title); println!("{}", title);
if let Some(error) = opt_error { if let Some(error) = opt_error {
println!("\nError: {}.", error); println!("\nError: {:#}.", error);
} }
println!("\n{}", AppOptions::usage()); println!("\n{}", AppOptions::usage());