aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorReiner Herrmann <reiner@reiner-h.de>2019-02-24 18:15:34 +0100
committerReiner Herrmann <reiner@reiner-h.de>2019-02-24 18:15:34 +0100
commit1c2a97ffdf069b60a696a9825b56e61c08a10147 (patch)
tree7045509d6bf8892ed58eb5356b0e6a88138b0d80 /src
parentfd8e583bf411528989f6d009307056d21451c287 (diff)
Bind to real tftp port (69) and drop privileges immediately after
Diffstat (limited to 'src')
-rw-r--r--src/tftpd.rs44
1 files changed, 42 insertions, 2 deletions
diff --git a/src/tftpd.rs b/src/tftpd.rs
index 331b27d..68e82c7 100644
--- a/src/tftpd.rs
+++ b/src/tftpd.rs
@@ -1,10 +1,14 @@
use std::net::{SocketAddr,UdpSocket};
use std::fs::File;
use std::path::Path;
+use std::error::Error;
use std::env;
use std::io;
use std::io::prelude::*;
+extern crate nix;
+use nix::unistd::{Gid,Uid,setresgid,setresuid};
+
fn handle_wrq(_cl: &SocketAddr, _buf: &[u8]) -> Result<(), io::Error> {
Ok(())
}
@@ -175,12 +179,48 @@ fn handle_client(cl: &SocketAddr, buf: &[u8]) -> Result<(), io::Error> {
Ok(())
}
+fn drop_privs() -> Result<(), Box<Error>> {
+ let root_uid = Uid::from_raw(0);
+ let root_gid = Gid::from_raw(0);
+ let unpriv_uid = Uid::from_raw(65534);
+ let unpriv_gid = Gid::from_raw(65534);
+
+ if Gid::current() == root_gid || Gid::effective() == root_gid {
+ setresgid(unpriv_gid, unpriv_gid, unpriv_gid)?;
+ }
+
+ if Uid::current() == root_uid || Uid::effective() == root_uid {
+ setresuid(unpriv_uid, unpriv_uid, unpriv_uid)?;
+ }
+
+ Ok(())
+}
+
fn main() {
- let socket = UdpSocket::bind("127.0.0.1:12345").expect("Binding a socket failed.");
+ let socket = match UdpSocket::bind("0.0.0.0:69") {
+ Ok(s) => s,
+ Err(err) => {
+ println!("Binding a socket failed: {}", err);
+ return;
+ }
+ };
+ match drop_privs() {
+ Ok(_) => (),
+ Err(err) => {
+ println!("Dropping privileges failed: {}", err);
+ return;
+ }
+ };
loop {
let mut buf = [0; 2048];
- let (n, src) = socket.recv_from(&mut buf).expect("Receiving from the socket failed.");
+ let (n, src) = match socket.recv_from(&mut buf) {
+ Ok(args) => args,
+ Err(err) => {
+ println!("Receiving data from socket failed: {}", err);
+ break;
+ }
+ };
match handle_client(&src, &buf[0..n]) {
/* errors intentionally ignored */