From 16f21989b476f6dae5de0cf1607805cfc308a0f5 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Sun, 17 May 2020 22:07:59 +0200 Subject: Elimited Daemonize dependency --- Cargo.lock | 17 ------------ Cargo.toml | 1 - netns.sh | 7 ++++- src/main.rs | 43 ++++++++++++++++++------------- src/util.rs | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 117 insertions(+), 37 deletions(-) create mode 100644 src/util.rs diff --git a/Cargo.lock b/Cargo.lock index 6d036c1..580c719 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -95,11 +95,6 @@ dependencies = [ "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "boxfnonce" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "bumpalo" version = "3.2.1" @@ -212,15 +207,6 @@ dependencies = [ "zeroize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "daemonize" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "boxfnonce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.68 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "digest" version = "0.8.1" @@ -1129,7 +1115,6 @@ dependencies = [ "clear_on_drop 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "cpuprofiler 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1223,7 +1208,6 @@ dependencies = [ "checksum bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4f67931368edf3a9a51d29886d245f1c3db2f1ef0dcc9e35ff70341b78c10d23" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum blake2 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -"checksum boxfnonce 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426" "checksum bumpalo 3.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187" "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" "checksum byteorder 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" @@ -1238,7 +1222,6 @@ dependencies = [ "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" "checksum crypto-mac 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" "checksum curve25519-dalek 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26778518a7f6cffa1d25a44b602b62b979bd88adb9e99ffec546998cf3404839" -"checksum daemonize 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70c24513e34f53b640819f0ac9f705b673fcf4006d7aab8778bee72ebfc89815" "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" "checksum env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" "checksum error-chain 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d371106cc88ffdfb1eabd7111e432da544f16f3e2d7bf1dfe8bf575f1df045cd" diff --git a/Cargo.toml b/Cargo.toml index feea486..c626761 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,6 @@ aead = "^0.2" clear_on_drop = "0.2.3" env_logger = "0.7" num_cpus = "^1.10" -daemonize = "0.4.1" crossbeam-channel = "0.4" cpuprofiler = { version = "*", optional = true } diff --git a/netns.sh b/netns.sh index 54b58c9..d2273a3 100755 --- a/netns.sh +++ b/netns.sh @@ -87,6 +87,9 @@ ip0 link set wg1 netns $netns1 n0 $program wg2 ip0 link set wg2 netns $netns2 +# wait for programs to start +sleep 0.1 + key1="$(pp wg genkey)" key2="$(pp wg genkey)" pub1="$(pp wg pubkey <<<"$key1")" @@ -102,6 +105,8 @@ configure_peers() { ip2 addr add 192.168.241.2/24 dev wg2 ip2 addr add fd00::2/24 dev wg2 + n0 wg + n0 wg set wg1 \ private-key <(echo "$key1") \ listen-port 10000 \ @@ -120,9 +125,9 @@ configure_peers() { ip1 link set up dev wg1 ip2 link set up dev wg2 - sleep 1 echo "ready" } + configure_peers tests() { diff --git a/src/main.rs b/src/main.rs index bf42706..fb5ac2f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,9 +13,9 @@ mod configuration; mod platform; mod wireguard; -use log; +mod util; -use daemonize::Daemonize; +use log; use std::env; use std::process::exit; @@ -62,14 +62,14 @@ fn main() { let mut foreground = false; let mut args = env::args(); - args.next(); // skip path (argv[0]) - + // skip path (argv[0]) + args.next(); for arg in args { match arg.as_str() { "--foreground" | "-f" => { foreground = true; } - "--root" => { + "--disable-drop-privileges" => { drop_privileges = false; } dev => name = Some(dev.to_owned()), @@ -97,16 +97,26 @@ fn main() { exit(-3); }); - // daemonize + // drop privileges + if drop_privileges { + match util::drop_privileges() { + Ok(_) => (), + Err(e) => { + eprintln!("Failed to drop privileges: {}", e); + exit(-4); + } + } + } + + // daemonize to background if !foreground { - let daemonize = Daemonize::new() - .pid_file(format!("/tmp/wireguard-rs-{}.pid", name)) - .chown_pid_file(true) - .working_directory("/tmp") - .user("nobody") - .group("daemon") - .umask(0o777); - daemonize.start().expect("Failed to daemonize"); + match util::daemonize() { + Ok(_) => (), + Err(e) => { + eprintln!("Failed to daemonize: {}", e); + exit(-5); + } + } } // start logging @@ -114,10 +124,7 @@ fn main() { .try_init() .expect("Failed to initialize event logger"); - log::info!("starting {} wireguard device", name); - - // drop privileges - if drop_privileges {} + log::info!("Starting {} WireGuard device.", name); // start profiler (if enabled) #[cfg(feature = "profiler")] diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..dd7a669 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,86 @@ +use std::fmt; +use std::process::exit; + +use libc::{c_char, chdir, chroot, fork, getpwnam, getuid, setgid, setsid, setuid, umask}; + +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone)] +pub enum DaemonizeError { + Fork, + SetSession, + SetGroup, + SetUser, + Chroot, + Chdir, +} + +impl fmt::Display for DaemonizeError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + DaemonizeError::Fork => "unable to fork", + DaemonizeError::SetSession => "unable to create new process session", + DaemonizeError::SetGroup => "unable to set group (drop privileges)", + DaemonizeError::SetUser => "unable to set user (drop privileges)", + DaemonizeError::Chroot => "unable to enter chroot jail", + DaemonizeError::Chdir => "failed to change directory", + } + .fmt(f) + } +} + +fn fork_and_exit() -> Result<(), DaemonizeError> { + let pid = unsafe { fork() }; + if pid < 0 { + Err(DaemonizeError::Fork) + } else if pid == 0 { + Ok(()) + } else { + exit(0); + } +} + +pub fn daemonize() -> Result<(), DaemonizeError> { + // fork from the original parent + fork_and_exit()?; + + // avoid killing the child when this parent dies + if unsafe { setsid() } < 0 { + return Err(DaemonizeError::SetSession); + } + + // fork again to create orphan + fork_and_exit() +} + +pub fn drop_privileges() -> Result<(), DaemonizeError> { + // retrieve nobody's uid & gid + let usr = unsafe { getpwnam("nobody\x00".as_ptr() as *const c_char) }; + if usr.is_null() { + return Err(DaemonizeError::SetGroup); + } + + // change root directory + let uid = unsafe { getuid() }; + if uid == 0 && unsafe { chroot("/tmp\x00".as_ptr() as *const c_char) } != 0 { + return Err(DaemonizeError::Chroot); + } + + // set umask for files + unsafe { umask(0) }; + + // change directory + if unsafe { chdir("/\x00".as_ptr() as *const c_char) } != 0 { + return Err(DaemonizeError::Chdir); + } + + // set group id to nobody + if unsafe { setgid((*usr).pw_gid) } != 0 { + return Err(DaemonizeError::SetGroup); + } + + // set user id to nobody + if unsafe { setuid((*usr).pw_uid) } != 0 { + Err(DaemonizeError::SetUser) + } else { + Ok(()) + } +} -- cgit v1.2.3-59-g8ed1b