🛂 Check for required permissions

On Linux, checks for the `CAP_NET_ADMIN` capability.
On macOS, checks for root.
This commit is contained in:
Malted 2023-06-10 17:25:08 +01:00 committed by Ben
parent 6bd8051c78
commit 40cc0ba049
7 changed files with 60 additions and 5 deletions

View file

@ -10,3 +10,9 @@ crate-type = ["lib", "staticlib"]
tokio = { version = "1.21", features = ["rt", "macros"] }
tun = { version = "0.1", path = "../tun" }
clap = { version = "4.3.2", features = ["derive"] }
[target.'cfg(target_os = "linux")'.dependencies]
caps = "0.5.5"
[target.'cfg(target_os = "macos")'.dependencies]
nix = { version = "0.26.2" }

35
burrow/src/ensureroot.rs Normal file
View file

@ -0,0 +1,35 @@
// Check capabilities on Linux
#[cfg(target_os = "linux")]
pub fn ensure_root() {
use caps::{has_cap, CapSet, Capability};
let cap_net_admin = Capability::CAP_NET_ADMIN;
if let Ok(has_cap) = has_cap(None, CapSet::Effective, cap_net_admin) {
if !has_cap {
eprintln!(
"This action needs the CAP_NET_ADMIN permission. Did you mean to run it as root?"
);
std::process::exit(77);
}
} else {
eprintln!("Failed to check capabilities. Please file a bug report!");
std::process::exit(71);
}
}
// Check for root user on macOS
#[cfg(target_os = "macos")]
pub fn ensure_root() {
use nix::unistd::Uid;
let current_uid = Uid::current();
if !current_uid.is_root() {
eprintln!("This action must be run as root!");
std::process::exit(77);
}
}
#[cfg(target_family = "windows")]
pub fn ensure_root() {
todo!()
}

View file

@ -1,3 +1 @@
pub fn hello_world() {
println!("Hello, world!");
}
pub mod ensureroot;

View file

@ -23,6 +23,8 @@ enum Commands {
struct StartArgs {}
async fn try_main() -> Result<()> {
burrow::ensureroot::ensure_root();
let iface = TunInterface::new()?;
println!("{:?}", iface.name());
@ -31,6 +33,8 @@ async fn try_main() -> Result<()> {
#[tokio::main(flavor = "current_thread")]
async fn main() {
println!("Platform: {}", std::env::consts::OS);
let cli = Cli::parse();
match &cli.command {
Commands::Start(..) => {