Implemented privilege dropping

This commit is contained in:
2023-11-19 01:30:39 +01:00
parent c638acecc2
commit fabbf74206
3 changed files with 55 additions and 7 deletions

11
Cargo.lock generated
View File

@@ -1288,6 +1288,7 @@ dependencies = [
"structopt",
"tokio",
"tokio-util",
"users",
]
[[package]]
@@ -1550,6 +1551,16 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "users"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
dependencies = [
"libc",
"log",
]
[[package]]
name = "uuid"
version = "1.5.0"

View File

@@ -18,4 +18,5 @@ tokio-util = { version = "0.7.10", features = ["io", "io-util", "rt", "compat"]
mlua = { version = "0.9.1", features = ["luau-jit", "vendored", "async", "send"] }
reqwest = { version = "0.11.22", features = ["stream"] }
listenfd = "1.0.1"
libc = "0.2.150"
libc = "0.2.150"
users = "0.11.0"

View File

@@ -35,6 +35,26 @@ struct Options {
async fn main() -> anyhow::Result<()> {
let opts = Options::from_args();
let group = opts.group.map(|name| {
if let Ok(gid) = libc::gid_t::from_str_radix(name.as_str(), 10) {
Ok(gid)
} else {
users::get_group_by_name(name.as_str())
.ok_or(anyhow!("Error dropping privileges: No such group"))
.map(|group| group.gid())
}
}).transpose()?;
let user = opts.user.map(|name| {
if let Ok(uid) = libc::gid_t::from_str_radix(name.as_str(), 10) {
Ok(uid)
} else {
users::get_user_by_name(name.as_str())
.ok_or(anyhow!("Error dropping privileges: No such user"))
.map(|user| user.uid())
}
}).transpose()?;
let local_set = tokio::task::LocalSet::new();
let (engine, mut engine_impl) = engine::Engine::new()?;
@@ -106,15 +126,31 @@ async fn main() -> anyhow::Result<()> {
} else {
net::UdpSocket::bind((host, port))?
}
};
let server = async_tftp::server::TftpServerBuilder::with_handler(handler.clone())
.std_socket(sock)?
.build().await?;
// Drop privileges
if let Some(group) = group {
unsafe {
if libc::setgid(group) < 0 {
return Err(std::io::Error::last_os_error().into())
}
}
}
if let Some(uid) = user {
unsafe {
if libc::setuid(uid) < 0 {
return Err(std::io::Error::last_os_error().into())
}
}
}
let main_task = async move {
let server = async_tftp::server::TftpServerBuilder::with_handler(handler.clone())
.std_socket(sock)?
.build().await?;
server.serve().await?;
Ok::<(), anyhow::Error>(())
};