diff options
| -rw-r--r-- | src/lib.rs | 81 | ||||
| -rw-r--r-- | src/tftpc.rs | 43 | ||||
| -rw-r--r-- | src/tftpd.rs | 40 |
3 files changed, 77 insertions, 87 deletions
@@ -3,12 +3,12 @@ * License: GPL-3+ */ -use std::net::{SocketAddr,UdpSocket}; -use std::fs::File; use std::collections::HashMap; -use std::path::{Path,PathBuf}; +use std::fs::File; use std::io; use std::io::prelude::*; +use std::net::{SocketAddr, UdpSocket}; +use std::path::{Path, PathBuf}; use std::time::Duration; #[repr(u16)] @@ -41,7 +41,7 @@ fn default_options() -> TftpOptions { impl Default for Tftp { fn default() -> Tftp { - Tftp{ + Tftp { options: default_options(), } } @@ -59,7 +59,7 @@ impl Tftp { Some(l) => l, None => return None, }; - let val = match String::from_utf8(buf[0 .. len].to_vec()) { + let val = match String::from_utf8(buf[0..len].to_vec()) { Ok(v) => v, Err(_) => return None, }; @@ -88,7 +88,7 @@ impl Tftp { } let errorcode = u16::from_be_bytes([buf[2], buf[3]]); - error = match String::from_utf8(buf[4 ..].to_vec()) { + error = match String::from_utf8(buf[4..].to_vec()) { Ok(e) => e, Err(_) => return std::io::Error::new(kind, error), }; @@ -125,9 +125,9 @@ impl Tftp { let block_nr = u16::from_be_bytes([buf[2], buf[3]]); if opcode == Opcodes::ACK as u16 && block_nr == expected_block { - return Ok(true) + return Ok(true); } else if opcode == Opcodes::ERROR as u16 { - return Err(self.parse_error(&buf[4 ..])); + return Err(self.parse_error(&buf[4..])); } Ok(false) @@ -139,7 +139,7 @@ impl Tftp { /* it's a WRQ, send normal ack to start transfer */ self.send_ack(&sock, 0)?; } - return Ok(()) + return Ok(()); } let mut buf = Vec::with_capacity(512); @@ -170,34 +170,28 @@ impl Tftp { options.retain(|key, val| { let val = val.to_lowercase(); match key.to_lowercase().as_str() { - "blksize" => { - match val.parse() { - Ok(b) if b >= 8 && b <= 65464 => { - self.options.blksize = b; - true - } - _ => false + "blksize" => match val.parse() { + Ok(b) if b >= 8 && b <= 65464 => { + self.options.blksize = b; + true } - } - "timeout" => { - match val.parse() { - Ok(t) if t >= 1 => { - self.options.timeout = t; - true - } - _ => false + _ => false, + }, + "timeout" => match val.parse() { + Ok(t) if t >= 1 => { + self.options.timeout = t; + true } - } - "tsize" => { - match val.parse() { - Ok(t) => { - self.options.tsize = t; - true - } - _ => false + _ => false, + }, + "tsize" => match val.parse() { + Ok(t) => { + self.options.tsize = t; + true } - } - _ => false + _ => false, + }, + _ => false, } }); @@ -211,13 +205,13 @@ impl Tftp { let mut pos = 0; loop { - let (key, len) = match self.get_tftp_str(&buf[pos ..]) { + let (key, len) = match self.get_tftp_str(&buf[pos..]) { Some(args) => args, None => break, }; pos += len + 1; - let (val, len) = match self.get_tftp_str(&buf[pos ..]) { + let (val, len) = match self.get_tftp_str(&buf[pos..]) { Some(args) => args, None => break, }; @@ -233,7 +227,7 @@ impl Tftp { let dataerr = io::Error::new(io::ErrorKind::InvalidData, "invalid data received"); let mut pos = 0; - let (filename, len) = match self.get_tftp_str(&buf[pos ..]) { + let (filename, len) = match self.get_tftp_str(&buf[pos..]) { Some(args) => args, None => return Err(dataerr), }; @@ -241,13 +235,13 @@ impl Tftp { let filename = Path::new(&filename); - let (mode, len) = match self.get_tftp_str(&buf[pos ..]) { - Some((m,l)) => (m.to_lowercase(), l), + let (mode, len) = match self.get_tftp_str(&buf[pos..]) { + Some((m, l)) => (m.to_lowercase(), l), None => return Err(dataerr), }; pos += len + 1; - let options = self.parse_options(&buf[pos ..]); + let options = self.parse_options(&buf[pos..]); Ok((filename.to_path_buf(), mode, options)) } @@ -310,13 +304,13 @@ impl Tftp { Ok(true) => { acked = true; break; - }, + } Ok(false) => continue, Err(e) => return Err(e), }; } if !acked { - return Err(io::Error::new(io::ErrorKind::TimedOut, "ack timeout")) + return Err(io::Error::new(io::ErrorKind::TimedOut, "ack timeout")); } if len < self.options.blksize { @@ -356,7 +350,7 @@ impl Tftp { match u16::from_be_bytes([buf[0], buf[1]]) { // opcode opc if opc == Opcodes::DATA as u16 => (), - opc if opc == Opcodes::ERROR as u16 => return Err(self.parse_error(&buf[.. len])), + opc if opc == Opcodes::ERROR as u16 => return Err(self.parse_error(&buf[..len])), _ => return Err(io::Error::new(io::ErrorKind::Other, "unexpected opcode")), }; if u16::from_be_bytes([buf[2], buf[3]]) != block_nr { @@ -380,5 +374,4 @@ impl Tftp { Ok(()) } - } diff --git a/src/tftpc.rs b/src/tftpc.rs index 669b455..c6b4c0f 100644 --- a/src/tftpc.rs +++ b/src/tftpc.rs @@ -3,11 +3,11 @@ * License: GPL-3+ */ -use std::net::{SocketAddr,UdpSocket,ToSocketAddrs}; -use std::fs::File; -use std::path::{Path,PathBuf}; use std::env; +use std::fs::File; use std::io; +use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; +use std::path::{Path, PathBuf}; use std::time::Duration; extern crate getopts; @@ -56,9 +56,9 @@ impl Tftpc { Err(_) => return None, }; - let mut options = self.tftp.parse_options(&buf[2 .. len]); + let mut options = self.tftp.parse_options(&buf[2..len]); match self.tftp.init_tftp_options(&sock, &mut options) { - Ok(_) => {}, + Ok(_) => {} Err(_) => return None, } @@ -86,7 +86,7 @@ impl Tftpc { if opcode == rtftp::Opcodes::ERROR as u16 { let mut buf = [0; 512]; let len = sock.recv(&mut buf)?; - return Err(self.tftp.parse_error(&buf[ ..len])); + return Err(self.tftp.parse_error(&buf[..len])); } /* first data packet is expected to be block 1 */ @@ -113,7 +113,7 @@ impl Tftpc { Some(f) => match f.to_str() { Some(s) => s, None => return Err(err_invalidpath), - } + }, None => return Err(err_invalidpath), }; let metadata = match file.metadata() { @@ -130,7 +130,7 @@ impl Tftpc { self.append_option_req(&mut buf, metadata.len()); let mut remote = None; - for _ in 1 .. 3 { + for _ in 1..3 { sock.send_to(&buf, self.conf.remote)?; remote = self.wait_for_option_ack(&sock); if remote.is_none() { @@ -153,7 +153,7 @@ impl Tftpc { let error = format!("Sending {} to {} failed ({}).", self.conf.filename.display(), self.conf.remote, err); self.tftp.send_error(&sock, 0, "Sending error")?; Err(io::Error::new(err.kind(), error)) - }, + } } } @@ -178,7 +178,7 @@ impl Tftpc { self.append_option_req(&mut buf, 0); let mut remote = None; - for _ in 1 .. 3 { + for _ in 1..3 { sock.send_to(&buf, self.conf.remote)?; let oack_remote = self.wait_for_option_ack(&sock); if let Some(r) = oack_remote { @@ -202,7 +202,7 @@ impl Tftpc { let error = format!("Receiving {} from {} failed ({}).", self.conf.filename.display(), self.conf.remote, err); self.tftp.send_error(&sock, 0, "Receiving error")?; Err(std::io::Error::new(err.kind(), error)) - }, + } } } @@ -225,9 +225,8 @@ impl Tftpc { } fn usage(opts: Options, program: String, error: Option<String>) { - match error { - None => {}, - Some(err) => println!("{}\n", err), + if let Some(err) = error { + println!("{}\n", err); } println!("{}", opts.usage(format!("RusTFTP\n\n{} [options] <remote>[:port]", program).as_str())); } @@ -272,15 +271,13 @@ fn parse_commandline(args: &[String]) -> Result<Configuration, &str> { let remote_in = matches.free[0].as_str(); let remote = match remote_in.to_socket_addrs() { Ok(mut i) => i.next(), - Err(_) => { - match (remote_in, 69).to_socket_addrs() { - Ok(mut j) => j.next(), - Err(_) => { - usage(opts, program, Some("Failed to parse and lookup specified remote".to_string())); - return Err("lookup"); - }, + Err(_) => match (remote_in, 69).to_socket_addrs() { + Ok(mut j) => j.next(), + Err(_) => { + usage(opts, program, Some("Failed to parse and lookup specified remote".to_string())); + return Err("lookup"); } - } + }, }; blksize = match matches.opt_get_default::<usize>("b", blksize) { @@ -291,7 +288,7 @@ fn parse_commandline(args: &[String]) -> Result<Configuration, &str> { } }; - Ok(Configuration{ + Ok(Configuration { mode: mode.unwrap(), filename: filename.unwrap(), remote: remote.unwrap(), diff --git a/src/tftpd.rs b/src/tftpd.rs index edd0f4c..271ebae 100644 --- a/src/tftpd.rs +++ b/src/tftpd.rs @@ -3,17 +3,17 @@ * License: GPL-3+ */ -use std::net::{SocketAddr,UdpSocket}; -use std::fs::OpenOptions; -use std::fs::File; -use std::path::{Path,PathBuf}; -use std::error::Error; use std::env; +use std::error::Error; +use std::fs::File; +use std::fs::OpenOptions; use std::io; +use std::net::{SocketAddr, UdpSocket}; +use std::path::{Path, PathBuf}; use std::time::Duration; extern crate nix; -use nix::unistd::{Gid,Uid,setresgid,setresuid}; +use nix::unistd::{setresgid, setresuid, Gid, Uid}; extern crate getopts; use getopts::Options; @@ -36,7 +36,7 @@ struct Tftpd { impl Tftpd { pub fn new(conf: Configuration) -> Tftpd { - Tftpd{ + Tftpd { tftp: rtftp::Tftp::new(), conf, } @@ -72,7 +72,6 @@ impl Tftpd { } } - fn handle_wrq(&mut self, socket: &UdpSocket, cl: &SocketAddr, buf: &[u8]) -> Result<(String), io::Error> { let (filename, mode, mut options) = self.tftp.parse_file_mode_options(buf)?; self.tftp.init_tftp_options(&socket, &mut options)?; @@ -100,7 +99,7 @@ impl Tftpd { let error = format!("Receiving {} from {} failed ({}).", path.display(), cl, err); self.tftp.send_error(&socket, 6, "File already exists")?; return Err(io::Error::new(err.kind(), error)); - }, + } Err(err) => { let error = format!("Receiving {} from {} failed ({}).", path.display(), cl, err); self.tftp.send_error(&socket, 6, "Permission denied")?; @@ -146,7 +145,7 @@ impl Tftpd { let err = format!("Sending {} to {} failed ({}).", path.display(), cl, error.to_string()); self.tftp.send_error(&socket, 1, "File not found")?; return Err(io::Error::new(io::ErrorKind::NotFound, err)); - }, + } Err(error) => { let err = format!("Sending {} to {} failed ({}).", path.display(), cl, error.to_string()); self.tftp.send_error(&socket, 2, "Permission denied")?; @@ -184,15 +183,15 @@ impl Tftpd { } else { self.handle_rrq(&socket, &cl, &buf[2..]) } - }, + } o if o == rtftp::Opcodes::WRQ as u16 => { if self.conf.ro { self.tftp.send_error(&socket, 4, "writing not allowed")?; Err(io::Error::new(io::ErrorKind::Other, "unallowed mode")) } else { - self.handle_wrq(&socket, &cl, &buf[2..]) + self.handle_wrq(&socket, &cl, &buf[2..]) } - }, + } o if o == rtftp::Opcodes::ERROR as u16 => Ok(format!("Received ERROR from {}", cl)), _ => { self.tftp.send_error(&socket, 4, "Unexpected opcode")?; @@ -207,8 +206,11 @@ impl Tftpd { let unpriv_uid = Uid::from_raw(uid); let unpriv_gid = Gid::from_raw(gid); - if Gid::current() != root_gid && Gid::effective() != root_gid - && Uid::current() != root_uid && Uid::effective() != root_uid { + if Gid::current() != root_gid + && Gid::effective() != root_gid + && Uid::current() != root_uid + && Uid::effective() != root_uid + { /* already unprivileged user */ return Ok(()); } @@ -263,21 +265,19 @@ impl Tftpd { Err(err) => println!("{}", err), } } - } } fn usage(opts: Options, program: String, error: Option<String>) { - match error { - None => {}, - Some(err) => println!("{}\n", err), + if let Some(err) = error { + println!("{}\n", err); } println!("{}", opts.usage(format!("RusTFTP\n\n{} [options]", program).as_str())); } fn parse_commandline(args: &[String]) -> Result<Configuration, &str> { let program = args[0].clone(); - let mut conf = Configuration{ + let mut conf = Configuration { port: 69, uid: 65534, gid: 65534, |
