diff options
| author | Reiner Herrmann <reiner@reiner-h.de> | 2019-02-24 18:15:34 +0100 |
|---|---|---|
| committer | Reiner Herrmann <reiner@reiner-h.de> | 2019-02-24 18:15:34 +0100 |
| commit | 1c2a97ffdf069b60a696a9825b56e61c08a10147 (patch) | |
| tree | 7045509d6bf8892ed58eb5356b0e6a88138b0d80 /src | |
| parent | fd8e583bf411528989f6d009307056d21451c287 (diff) | |
Bind to real tftp port (69) and drop privileges immediately after
Diffstat (limited to 'src')
| -rw-r--r-- | src/tftpd.rs | 44 |
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 */ |
