Elimited Daemonize dependency
This commit is contained in:
43
src/main.rs
43
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")]
|
||||
|
||||
86
src/util.rs
Normal file
86
src/util.rs
Normal file
@@ -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(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user