diff --git a/src/nodes/recv_node.rs b/src/nodes/recv_node.rs index b2b5fb1..b6e8009 100644 --- a/src/nodes/recv_node.rs +++ b/src/nodes/recv_node.rs @@ -14,7 +14,6 @@ GNU Affero General Public License for more details. */ use crate::util::error::Error; -use crate::protocol::specs::PacketType; use crate::protocol::specs::Packet; use crate::protocol::packets::{read_next_packet, send_packet}; use crate::protocol::packets; @@ -56,7 +55,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { // reject any connection that doesn't provide handshake information let mut connection: net::TcpStream; let mut address: net::SocketAddr; - let mut handshake: packets::Handshake = packets::Handshake::empty(); + let mut handshake: packets::Handshake; loop { match listener.accept() { Ok((c, a)) => { @@ -75,33 +74,25 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { // read the first packet match read_next_packet(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) { Ok(packet) => { - println!("hea 1"); - match handshake.from_bytes(packet.as_bytes()) { - Some(error) => { - packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); - return Err(Error::new(format!("error constructing handshake from {}: {}", address, error.text).as_str())); - } - - None => { - println!("hea 2"); + match packets::Handshake::from_raw(&packet) { + Ok(h) => { + handshake = h; if verbose_output { println!("Handshake from {}", address); } // accept handshake - println!("local handshake: {:?}", &handshake); match send_packet( &mut connection, - &packets::HandshakeAccept{}, + &packets::HandshakeAccept{}.as_raw(), handshake.encryption_type, &handshake.encryption_key ) { Ok(()) => {} Err(error) => { packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); - return Err( Error::new(format!("error accepting handshake from {}: {}", address, error.text).as_str()) ); @@ -111,6 +102,11 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { // break out of loop break; } + + Err(error) => { + packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); + return Err(Error::new(format!("error constructing handshake from {}: {}", address, error.text).as_str())); + } } } @@ -185,8 +181,8 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { } } - match incoming_packet.get_type() { - PacketType::ConnectionShutdown => { + match incoming_packet.header { + specs::CONNECTION_SHUTDOWN_PACKET_ID => { if verbose_output { println!("{} shuts down the connection", address); } @@ -195,18 +191,16 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { break; } - PacketType::TextData => { - let mut text_packet: packets::Text = packets::Text::empty(); - match text_packet.from_bytes(incoming_packet.as_bytes()) { - None => { + specs::TEXT_PACKET_ID => { + match packets::Text::from_raw(&incoming_packet) { + Ok(text_packet) => { // print received text ! - println!("{}", text_packet.text); + println!("\n{}\n", text_packet.text); } - Some(error) => { + Err(error) => { // close connection and exit packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); - return Err( Error::new(format!("could not get text packet: {}", error.text).as_str()) ); diff --git a/src/nodes/send_node.rs b/src/nodes/send_node.rs index 97ce6b1..efacccf 100644 --- a/src/nodes/send_node.rs +++ b/src/nodes/send_node.rs @@ -18,7 +18,6 @@ use crate::args::parser::DataType; use crate::crypt; use crate::protocol::packets; use crate::protocol::packets::{send_packet, read_next_packet}; -use crate::protocol::specs::PacketType; use crate::protocol::specs; use crate::protocol::specs::Packet; use std::thread; @@ -74,8 +73,6 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { if verbose_output { println!("Using encryption ID: {} with key: {:?}", handshake.encryption_type, handshake.encryption_key); } - - println!("local handshake {:?}", handshake); match send_packet(&mut connection, &handshake.as_raw(), specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) { Ok(_) => { @@ -86,7 +83,6 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { Err(error) => { packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); - return Err( Error::new(format!("could not send handshake: {}", error.text).as_str()) ); @@ -96,7 +92,7 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { // see if the handshake has been accepted match read_next_packet(&mut connection, handshake.encryption_type, &handshake.encryption_key) { Ok(packet) => { - if packet.get_type() != PacketType::HandshakeAccept { + if packet.header != specs::HANDSHAKE_ACCEPT_PACKET_ID { // not approved or entirely not according to the protocol packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); return Err( @@ -165,10 +161,10 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { DataType::TEXT => { if let Err(error) = send_packet( &mut connection, - &packets::Text::new(&options.text_to_send), + &packets::Text::new(&options.text_to_send).as_raw(), handshake.encryption_type, &handshake.encryption_key - ) { + ) { packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); return Err(Error::new(format!("error sending text: {}", error.text).as_str())) } diff --git a/src/protocol/packets.rs b/src/protocol/packets.rs index 8b04be1..f90acd8 100644 --- a/src/protocol/packets.rs +++ b/src/protocol/packets.rs @@ -26,26 +26,29 @@ use crate::crypt; pub fn send_packet(conn: &mut W, packet: &Packet, encr_type: u8, key: &Vec) -> Result<(), Error> where W: Write { - let mut packet_bytes: Vec = Vec::::new(); - - let packet_contents = packet.contents; + // ready-to-transport packet bytes + let mut packet_bytes: Vec = Vec::with_capacity(packet.contents.len() + 1); + packet_bytes.extend_from_slice(&packet.header.to_be_bytes()); + packet_bytes.extend_from_slice(&packet.contents); match encr_type { ECRYPTION_XOR => { - crypt::xor::encrypt(&mut packet_contents, &crypt::keys::Key8bit::new(key[0])); - let packet_len: usize = packet_contents.len(); - packet_bytes.extend_from_slice(&(packet_len as u128).to_be_bytes()); - packet_bytes.extend_from_slice(&packet_contents); + crypt::xor::encrypt(&mut packet_bytes, &crypt::keys::Key8bit::new(key[0])); } - _ | ENCRYPTION_NO_ENCRYPTION => { - let packet_len: usize = packet_contents.len(); - packet_bytes.extend_from_slice(&(packet_len as u128).to_be_bytes()); - packet_bytes.extend_from_slice(&packet_contents); - } + ENCRYPTION_NO_ENCRYPTION | _ => {} } - match conn.write_all(&packet_bytes) { + + // get total length and add it to the beginning + let total_packet_len: u128 = packet_bytes.len() as u128; + + let mut transport_bytes: Vec = Vec::with_capacity((total_packet_len + 16) as usize); + transport_bytes.extend_from_slice(&total_packet_len.to_be_bytes()); + transport_bytes.append(&mut packet_bytes); + + // send packet + match conn.write_all(&transport_bytes) { Ok(()) => { return Ok(()); } @@ -103,16 +106,13 @@ pub fn read_next_packet(conn: &mut R, encr_type: u8, key: &Vec) -> Result crypt::xor::decrypt(&mut packet_bytes, &crypt::keys::Key8bit::new(key[0])); } - _ | ENCRYPTION_NO_ENCRYPTION => {} + ENCRYPTION_NO_ENCRYPTION | _ => {} } - let mut packet_contents: Vec = Vec::with_capacity(packet_bytes[1..].len()); - packet_contents.extend_from_slice(&packet_bytes[1..]); - return Ok( Packet{ header: packet_bytes[0].to_be(), - contents: packet_contents, + contents: Vec::from(&packet_bytes[1..]), } ); } @@ -127,12 +127,6 @@ pub struct Text { } impl Text { - pub fn empty() -> Text { - return Text{ - text: "".to_string(), - }; - } - pub fn new(txt: &str) -> Text { return Text { text: txt.to_string(), @@ -142,7 +136,7 @@ impl Text { pub fn as_raw(&self) -> Packet { let mut raw_packet: Packet = Packet{ header: TEXT_PACKET_ID, - contents: Vec::::new(), + contents: Vec::with_capacity(self.text.len()), }; let text_length: u128 = self.text.len() as u128; @@ -157,29 +151,29 @@ impl Text { return Err(Error::new("it is not a text packet")); } - if raw_packet.contents.len() < 18 { + if raw_packet.contents.len() < 17 { return Err( Error::new(format!("{} bytes is too small for a text packet to be valid", raw_packet.contents.len()).as_str() )); } // get text length - let text_length: u128 = read_u128_slice_be(&raw_packet.contents[1..17]); + let text_length: u128 = read_u128_slice_be(&raw_packet.contents[0..16]); - if text_length as usize > raw_packet.contents[17..].len() { + if text_length as usize > raw_packet.contents[16..16+text_length as usize].len() { return Err( Error::new( format!( "text length ({}) is bigger than provided packet bytes length ({})", text_length, - raw_packet.contents[16..].len() + raw_packet.contents[16..16+text_length as usize].len() ).as_str() ) ); } // extract text - let packet_text = read_utf8_string_slice(&raw_packet.contents[17..]); + let packet_text = read_utf8_string_slice(&raw_packet.contents[16..16+text_length as usize]); return Ok( Text{ @@ -198,7 +192,7 @@ pub struct FileInfo { } impl FileInfo { - pub fn empty() -> FileInfo { + fn empty() -> FileInfo { return FileInfo{ file_id: 0, filename: String::new(), @@ -273,7 +267,7 @@ impl FileInfo { return Err(Error::new("it is not a fileinfo packet")); } - if raw_packet.contents.len() < 16+16+16+16+1+1 { + if raw_packet.contents.len() < 16+16+16+16 { return Err( Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", raw_packet.contents.len()).as_str() )); @@ -284,17 +278,17 @@ impl FileInfo { // get filename let filename_length: u128 = read_u128_slice_be(&raw_packet.contents[16..32]); - let filename = read_utf8_string_slice(&raw_packet.contents[32..(filename_length+32) as usize]); + let filename = read_utf8_string_slice(&raw_packet.contents[32..32+filename_length as usize]); // filesize - let filesize = read_u128_slice_be(&raw_packet.contents[(filename_length+32) as usize..(filename_length+32+16) as usize]); + let filesize = read_u128_slice_be(&raw_packet.contents[32+filename_length as usize..32+16+filename_length as usize]); // relative path let rel_path_length: u128 = read_u128_slice_be( - &raw_packet.contents[(filename_length+32+16) as usize..(filename_length+32+16+16)as usize] + &raw_packet.contents[32+16+filename_length as usize..32+16+16+filename_length as usize] ); let relative_path = read_utf8_string_slice( - &raw_packet.contents[(filename_length+32+16+16) as usize..(filename_length+32+16+16+rel_path_length) as usize] + &raw_packet.contents[32+16+16+filename_length as usize..(filename_length+32+16+16+rel_path_length) as usize] ); return Ok( @@ -316,14 +310,6 @@ pub struct FileData { } impl FileData { - pub fn empty() -> FileData { - return FileData { - file_id: 0, - chunk_no: 0, - chunk: Vec::new(), - } - } - pub fn as_raw(&self) -> Packet { let mut raw_packet: Packet = Packet{ header: FILEDATA_PACKET_ID, @@ -348,7 +334,7 @@ impl FileData { return Err(Error::new("it is not a filedata packet")); } - if raw_packet.contents.len() < 16+16+16+1 { + if raw_packet.contents.len() < 16+16+16 { return Err( Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", raw_packet.contents.len()).as_str() )); @@ -412,14 +398,6 @@ pub struct Handshake { } impl Handshake { - pub fn empty() -> Handshake { - return Handshake{ - protocol_version: PROTOCOL_LATEST_VERSION, - encryption_type: ENCRYPTION_NO_ENCRYPTION, - encryption_key: crypt::keys::Key8bit::new(0).as_bytes(), - }; - } - pub fn as_raw(&self) -> Packet { let mut raw_packet: Packet = Packet{ header: HANDSHAKE_PACKET_ID, @@ -440,7 +418,11 @@ impl Handshake { } pub fn from_raw(raw_packet: &Packet) -> Result { - if raw_packet.contents.len() < 1+1+1+16+1 { + if raw_packet.header != HANDSHAKE_PACKET_ID { + return Err(Error::new("it is not a handshake packet")); + } + + if raw_packet.contents.len() < 1+1+16 { return Err( Error::new(format!("{} bytes is too small for a handshake packet to be valid", raw_packet.contents.len()).as_str()) ); @@ -453,14 +435,16 @@ impl Handshake { let encryption_type = raw_packet.contents[1].to_be(); // key - let key_len: u128 = read_u128_slice_be(&raw_packet.contents[1..17]); - let mut encryption_key: Vec = Vec::with_capacity(key_len as usize); - for i in 17..(17+key_len) as usize { - encryption_key[i-17] = raw_packet.contents[i].to_be(); + let key_len: u128 = read_u128_slice_be(&raw_packet.contents[2..18]); + let mut encryption_key: Vec = vec!(0; key_len as usize); + if key_len == 0 { + encryption_key = Vec::new(); + } else { + for i in 18..(18+key_len) as usize { + encryption_key[i-18] = raw_packet.contents[i].to_be(); + } } - println!("from bytes function handshake bytes: {:?}", raw_packet.contents); - return Ok( Handshake{ protocol_version: protocol_version, diff --git a/src/protocol/specs.rs b/src/protocol/specs.rs index 0792eb9..56ec33a 100644 --- a/src/protocol/specs.rs +++ b/src/protocol/specs.rs @@ -42,18 +42,7 @@ pub enum RunMode { DAEMON, } -#[derive(PartialEq, Eq, Debug)] -pub enum PacketType { - ConnectionShutdown, - TextData, - FileInfo, - FileData, - Handshake, - HandshakeAccept, - FileAccept, - FileReject, -} - +#[derive(Debug)] pub struct Packet { pub header: u8, pub contents: Vec,