From 6561d950d6ccc356da60fb313d9f69f9e976a6c2 Mon Sep 17 00:00:00 2001 From: Gitea Date: Mon, 25 Jul 2022 18:03:41 +0300 Subject: [PATCH] NOT FOR BUILD: significantly simplified work with packets, nodes are unchanged and need to be fixed --- TODO | 4 +- src/crypt/keys.rs | 4 + src/nodes/recv_node.rs | 100 +++++----- src/nodes/send_node.rs | 40 ++-- src/protocol/packets.rs | 397 ++++++++++++++++++++-------------------- src/protocol/specs.rs | 9 +- 6 files changed, 280 insertions(+), 274 deletions(-) diff --git a/TODO b/TODO index f71714e..82d86c0 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,5 @@ -1. Write base foundation for sending and receiving information -2. Wire it all together +-1. Write base foundation for sending and receiving information- +-2. Wire it all together- 3. Make it encrypted 4. Allow receiving node to connect as well 5. Daemon \ No newline at end of file diff --git a/src/crypt/keys.rs b/src/crypt/keys.rs index 228d02f..d420c7b 100644 --- a/src/crypt/keys.rs +++ b/src/crypt/keys.rs @@ -32,6 +32,10 @@ impl Key8bit { k: rand::rand_u16(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as u16) as u8, } } + + pub fn as_bytes(&self) -> Vec { + return vec!(self.k); + } } #[cfg(test)] diff --git a/src/nodes/recv_node.rs b/src/nodes/recv_node.rs index 69fd270..b2b5fb1 100644 --- a/src/nodes/recv_node.rs +++ b/src/nodes/recv_node.rs @@ -18,6 +18,7 @@ use crate::protocol::specs::PacketType; use crate::protocol::specs::Packet; use crate::protocol::packets::{read_next_packet, send_packet}; use crate::protocol::packets; +use crate::protocol::specs; use std::path; use std::net; use std::sync::mpsc::{Sender, Receiver}; @@ -72,61 +73,53 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { } // read the first packet - let incoming_packet: Box; - match read_next_packet(&mut connection) { + match read_next_packet(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) { Ok(packet) => { - incoming_packet = packet; - } - - Err(error) => { - // not a valid packet; it's most probably not another instance - if verbose_output { - println!("{} did not provide valid handshake packet: {}. Dropping connection...", address, error.text); - } - packets::close_connection(&mut connection); - continue; - } - } - - match incoming_packet.get_type() { - PacketType::Handshake => { - match handshake.from_bytes(incoming_packet.as_bytes()) { + println!("hea 1"); + match handshake.from_bytes(packet.as_bytes()) { Some(error) => { - packets::close_connection(&mut connection); - - return Err( - Error::new( - format!("error constructing handshake from {}: {}", address, error.text).as_str() - )); + 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 => {} - } - if verbose_output { - println!("Handshake from {}", address); - } - - // accept handshake - match send_packet(&mut connection, &packets::HandshakeAccept{}) { - Ok(()) => {} - Err(error) => { - packets::close_connection(&mut connection); - - return Err( - Error::new(format!("error accepting handshake from {}: {}", address, error.text).as_str()) - ); + None => { + println!("hea 2"); + + if verbose_output { + println!("Handshake from {}", address); + } + + // accept handshake + println!("local handshake: {:?}", &handshake); + + match send_packet( + &mut connection, + &packets::HandshakeAccept{}, + 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()) + ); + } + } + + // break out of loop + break; } } - - // break out of loop - break; } - _ => { + Err(error) => { + // not a valid packet; it's most probably not another instance if verbose_output { - println!("{} didn't send a handshake packet, but {:?} packet instead. Dropping connection...", address, incoming_packet.get_type()); + println!("{} did not provide valid handshake packet: {}. Dropping connection...", address, error.text); } - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); continue; } } @@ -135,7 +128,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { // now read and process incoming packets; essentialy receiving something ! // launch a new packet reading thread - let (ch_send, ch_recv): (Sender>, Receiver>) = mpsc::channel(); + let (ch_send, ch_recv): (Sender, Receiver) = mpsc::channel(); let mut cloned_connection: net::TcpStream; match connection.try_clone() { @@ -144,17 +137,18 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { } Err(_) => { - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); return Err( Error::new("could not clone connection") ); } } - + + let handshake_clone: packets::Handshake = handshake.clone(); thread::spawn(move || { loop { - match read_next_packet(&mut cloned_connection) { + match read_next_packet(&mut cloned_connection, handshake_clone.encryption_type, &handshake_clone.encryption_key) { Ok(packet) => { if let Err(_) = ch_send.send(packet) { // the channel has been hung up @@ -176,14 +170,14 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { // handle incoming packets loop { - let incoming_packet: Box; + let incoming_packet: Packet; match ch_recv.recv() { Ok(p) => { incoming_packet = p; } Err(error) => { - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); return Err(Error::new( format!("error receiving a new packet from listener thread: {}", error).as_str() @@ -196,7 +190,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { if verbose_output { println!("{} shuts down the connection", address); } - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); break; } @@ -211,7 +205,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> { Some(error) => { // close connection and exit - packets::close_connection(&mut connection); + 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 47322c2..97ce6b1 100644 --- a/src/nodes/send_node.rs +++ b/src/nodes/send_node.rs @@ -46,6 +46,7 @@ impl SendOptions { } pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { + // connect let mut connection: net::TcpStream; match net::TcpStream::connect(&options.address) { Ok(conn) => { @@ -67,10 +68,16 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { let handshake: packets::Handshake = packets::Handshake{ protocol_version: specs::PROTOCOL_VERSION_1, encryption_type: specs::ECRYPTION_XOR, - encryption_key: vec!(crypt::keys::Key8bit::new_random().k), + encryption_key: crypt::keys::Key8bit::new_random().as_bytes(), }; + + 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) { + match send_packet(&mut connection, &handshake.as_raw(), specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) { Ok(_) => { if verbose_output { println!("Sent handshake"); @@ -78,7 +85,7 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { } Err(error) => { - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); return Err( Error::new(format!("could not send handshake: {}", error.text).as_str()) @@ -87,11 +94,11 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { } // see if the handshake has been accepted - match read_next_packet(&mut connection) { + match read_next_packet(&mut connection, handshake.encryption_type, &handshake.encryption_key) { Ok(packet) => { if packet.get_type() != PacketType::HandshakeAccept { // not approved or entirely not according to the protocol - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); return Err( Error::new(format!("handshake hasn't been approved").as_str()) ); @@ -103,15 +110,17 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { } Err(error) => { - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); return Err( Error::new(format!("could not receive potential handshake approval: {}", error.text).as_str()) ); } } + // handshake has been accepted + // launch a new packet reading thread - let (ch_send, ch_recv): (Sender>, Receiver>) = mpsc::channel(); + let (ch_send, _ch_recv): (Sender, Receiver) = mpsc::channel(); let mut cloned_connection: net::TcpStream; match connection.try_clone() { @@ -120,17 +129,18 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { } Err(_) => { - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); return Err( Error::new("could not clone connection") ); } } + let handshake_clone = handshake.clone(); thread::spawn(move || { loop { - match read_next_packet(&mut cloned_connection) { + match read_next_packet(&mut cloned_connection, handshake_clone.encryption_type, &handshake_clone.encryption_key) { Ok(packet) => { if let Err(_) = ch_send.send(packet) { // the channel has been hung up @@ -150,13 +160,19 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { }); + // now send match options.send_type { DataType::TEXT => { - if let Err(error) = send_packet(&mut connection, &packets::Text::new(&options.text_to_send)) { - packets::close_connection(&mut connection); + if let Err(error) = send_packet( + &mut connection, + &packets::Text::new(&options.text_to_send), + 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())) } - packets::close_connection(&mut connection); + packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); } DataType::FILE => { diff --git a/src/protocol/packets.rs b/src/protocol/packets.rs index 0eb1847..8b04be1 100644 --- a/src/protocol/packets.rs +++ b/src/protocol/packets.rs @@ -21,18 +21,31 @@ use crate::util::error::Error; use crate::util::buf_read::{read_u128_slice_be, read_utf8_string_slice}; use crate::protocol::specs::*; use crate::fsys::file::ChunkedFile; +use crate::crypt; -pub fn send_packet(conn: &mut W, packet: &dyn Packet) -> Result<(), Error> where W: Write { - let mut payload: Vec = Vec::::new(); - - let packet_bytes: Vec = packet.as_bytes(); - let packet_len: usize = packet_bytes.len(); +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(); - payload.extend_from_slice(&(packet_len as u128).to_be_bytes()); - payload.extend_from_slice(&packet_bytes); + let packet_contents = 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); + } + + _ | 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); + } + } - match conn.write_all(&payload) { + match conn.write_all(&packet_bytes) { Ok(()) => { return Ok(()); } @@ -43,7 +56,8 @@ pub fn send_packet(conn: &mut W, packet: &dyn Packet) -> Result<(), Error> wh } } -pub fn read_next_packet(conn: &mut R) -> Result, Error> where R: Read { +pub fn read_next_packet(conn: &mut R, encr_type: u8, key: &Vec) -> Result + where R: Read { let mut u128_buf: [u8; 16] = [0; 16]; loop { match conn.read_exact(&mut u128_buf) { @@ -83,79 +97,28 @@ pub fn read_next_packet(conn: &mut R) -> Result, Error ); } - let packet_type_byte: u8 = u8::from_be_bytes([packet_bytes[0]]); - match packet_type_byte { - HANDSHAKE_PACKET_ID => { - let mut new_handshake_packet: Handshake = Handshake::empty(); - match new_handshake_packet.from_bytes(packet_bytes) { - Some(error) => { - return Err(Error::new(format!("could not construct a new handshake packet: {}", error.text).as_str())); - } - - None => { - return Ok(Box::new(new_handshake_packet)); - } - } - } - - HANDSHAKE_ACCEPT_PACKET_ID => { - return Ok(Box::new(HandshakeAccept{})); + // decrypt + match encr_type { + ECRYPTION_XOR => { + crypt::xor::decrypt(&mut packet_bytes, &crypt::keys::Key8bit::new(key[0])); } - CONNECTION_SHUTDOWN_PACKET_ID => { - return Ok(Box::new(ConnectionShutdown{})); - } - - TEXT_PACKET_ID => { - let mut new_text_packet: Text = Text::empty(); - let result = new_text_packet.from_bytes(packet_bytes); - match result { - Some(error) => { - return Err(Error::new(format!("could not construct new text packet: {}", error.text).as_str())); - } - - None => { - return Ok(Box::new(new_text_packet)); - } - } - } - - FILEINFO_PACKET_ID => { - let mut new_fileinfo_packet: FileInfo = FileInfo::empty(); - let result = new_fileinfo_packet.from_bytes(packet_bytes); - match result { - Some(error) => { - return Err(Error::new(format!("could not construct new fileinfo packet: {}", error.text).as_str())); - } - - None => { - return Ok(Box::new(new_fileinfo_packet)); - } - } - } - - FILEDATA_PACKET_ID => { - let mut new_filedata_packet: FileData = FileData::empty(); - let result = new_filedata_packet.from_bytes(packet_bytes); - match result { - Some(error) => { - return Err(Error::new(format!("could not construct new filedata packet: {}", error.text).as_str())); - } + _ | ENCRYPTION_NO_ENCRYPTION => {} + } - None => { - return Ok(Box::new(new_filedata_packet)); - } - } - } + let mut packet_contents: Vec = Vec::with_capacity(packet_bytes[1..].len()); + packet_contents.extend_from_slice(&packet_bytes[1..]); - _ => { - return Err(Error::new(format!("invalid or unimplemented packet type ID \"{}\"", packet_type_byte).as_str())); + return Ok( + Packet{ + header: packet_bytes[0].to_be(), + contents: packet_contents, } - } + ); } -pub fn close_connection(connection: &mut net::TcpStream) { - send_packet(connection, &ConnectionShutdown{}); +pub fn close_connection(connection: &mut net::TcpStream, encr_type: u8, key: &Vec) { + send_packet(connection, &ConnectionShutdown{}.as_raw(), encr_type, key); connection.shutdown(net::Shutdown::Both); } @@ -175,59 +138,54 @@ impl Text { text: txt.to_string(), } } -} - -impl Packet for Text { - fn get_type(&self) -> PacketType { - return PacketType::TextData; - } - - fn as_bytes(&self) -> Vec { - let mut packet_bytes: Vec = Vec::::new(); - packet_bytes.extend_from_slice(&TEXT_PACKET_ID.to_be_bytes()); + pub fn as_raw(&self) -> Packet { + let mut raw_packet: Packet = Packet{ + header: TEXT_PACKET_ID, + contents: Vec::::new(), + }; let text_length: u128 = self.text.len() as u128; - packet_bytes.extend_from_slice(&text_length.to_be_bytes()); - packet_bytes.extend_from_slice(&self.text.as_bytes()); + raw_packet.contents.extend_from_slice(&text_length.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.text.as_bytes()); - return packet_bytes; + return raw_packet; } - fn from_bytes(&mut self, packet_bytes: Vec) -> Option { - if packet_bytes.len() < 18 { - return Some( - Error::new(format!("{} bytes is too small for a text packet to be valid", packet_bytes.len()).as_str() - )); + pub fn from_raw(raw_packet: &Packet) -> Result { + if raw_packet.header != TEXT_PACKET_ID { + return Err(Error::new("it is not a text packet")); } - // retrieve and check for packet type byte - match packet_bytes[0].to_be() { - TEXT_PACKET_ID => {} - _ => { - return Some(Error::new("packet type is not of a text packet")); - } + if raw_packet.contents.len() < 18 { + 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(&packet_bytes[1..17]); + let text_length: u128 = read_u128_slice_be(&raw_packet.contents[1..17]); - if text_length as usize > packet_bytes[17..].len() { - return Some( + if text_length as usize > raw_packet.contents[17..].len() { + return Err( Error::new( format!( "text length ({}) is bigger than provided packet bytes length ({})", text_length, - packet_bytes[16..].len() + raw_packet.contents[16..].len() ).as_str() ) ); } // extract text - self.text = read_utf8_string_slice(&packet_bytes[17..]); + let packet_text = read_utf8_string_slice(&raw_packet.contents[17..]); - return None; + return Ok( + Text{ + text: packet_text, + } + ); } } @@ -284,63 +242,69 @@ impl FileInfo { return Ok(new_fileinfo_packet); } -} - -impl Packet for FileInfo { - fn get_type(&self) -> PacketType { - return PacketType::FileInfo; - } - fn as_bytes(&self) -> Vec { - let mut packet_bytes: Vec = Vec::::new(); - - packet_bytes.extend_from_slice(&FILEINFO_PACKET_ID.to_be_bytes()); + pub fn as_raw(&self) -> Packet { + let mut raw_packet: Packet = Packet{ + header: TEXT_PACKET_ID, + contents: Vec::::new(), + }; // file id - packet_bytes.extend_from_slice(&self.file_id.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.file_id.to_be_bytes()); // filename let filename_bytes_length: u128 = self.filename.len() as u128; - packet_bytes.extend_from_slice(&filename_bytes_length.to_be_bytes()); - packet_bytes.extend_from_slice(&self.filename.as_bytes()); + raw_packet.contents.extend_from_slice(&filename_bytes_length.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.filename.as_bytes()); // filesize - packet_bytes.extend_from_slice(&self.filesize.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.filesize.to_be_bytes()); // relative path let relative_path_bytes_length: u128 = self.relative_path.len() as u128; - packet_bytes.extend_from_slice(&relative_path_bytes_length.to_be_bytes()); - packet_bytes.extend_from_slice(&self.relative_path.as_bytes()); + raw_packet.contents.extend_from_slice(&relative_path_bytes_length.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.relative_path.as_bytes()); - return packet_bytes; + return raw_packet; } - fn from_bytes(&mut self, packet_bytes: Vec) -> Option { - if packet_bytes.len() < 16+16+16+16+1+1 { - return Some( - Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", packet_bytes.len()).as_str() + pub fn from_raw(raw_packet: &Packet) -> Result { + if raw_packet.header != FILEINFO_PACKET_ID { + return Err(Error::new("it is not a fileinfo packet")); + } + + if raw_packet.contents.len() < 16+16+16+16+1+1 { + return Err( + Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", raw_packet.contents.len()).as_str() )); } // file id - self.file_id = read_u128_slice_be(&packet_bytes[0..16]); + let file_id = read_u128_slice_be(&raw_packet.contents[0..16]); // get filename - let filename_length: u128 = read_u128_slice_be(&packet_bytes[16..32]); - self.filename = read_utf8_string_slice(&packet_bytes[32..(filename_length+32) as usize]); + 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]); // filesize - self.filesize = read_u128_slice_be(&packet_bytes[(filename_length+32) as usize..(filename_length+32+16) as usize]); + let filesize = read_u128_slice_be(&raw_packet.contents[(filename_length+32) as usize..(filename_length+32+16) as usize]); // relative path let rel_path_length: u128 = read_u128_slice_be( - &packet_bytes[(filename_length+32+16) as usize..(filename_length+32+16+16)as usize] + &raw_packet.contents[(filename_length+32+16) as usize..(filename_length+32+16+16)as usize] ); - self.relative_path = read_utf8_string_slice( - &packet_bytes[(filename_length+32+16+16) as usize..(filename_length+32+16+16+rel_path_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] ); - return None; + return Ok( + FileInfo{ + file_id: file_id, + filename: filename, + filesize: filesize, + relative_path: relative_path, + } + ); } } @@ -348,7 +312,7 @@ impl Packet for FileInfo { pub struct FileData { pub file_id: u128, pub chunk_no: u128, - pub chunk: [u8; CHUNK_SIZE], + pub chunk: Vec, } impl FileData { @@ -356,73 +320,91 @@ impl FileData { return FileData { file_id: 0, chunk_no: 0, - chunk: [0; CHUNK_SIZE], + chunk: Vec::new(), } } -} -impl Packet for FileData { - fn get_type(&self) -> PacketType { - return PacketType::FileData; - } - - fn as_bytes(&self) -> Vec { - let mut packet_bytes: Vec = Vec::::new(); + pub fn as_raw(&self) -> Packet { + let mut raw_packet: Packet = Packet{ + header: FILEDATA_PACKET_ID, + contents: Vec::::new(), + }; - packet_bytes.extend_from_slice(&FILEDATA_PACKET_ID.to_be_bytes()); - // file id - packet_bytes.extend_from_slice(&self.file_id.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.file_id.to_be_bytes()); // chunk number - packet_bytes.extend_from_slice(&self.chunk_no.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.chunk_no.to_be_bytes()); // chunk - packet_bytes.extend_from_slice(&self.chunk.len().to_be_bytes()); - packet_bytes.extend_from_slice(&self.chunk); + raw_packet.contents.extend_from_slice(&self.chunk.len().to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.chunk); - return packet_bytes; + return raw_packet; } - fn from_bytes(&mut self, packet_bytes: Vec) -> Option { - if packet_bytes.len() < 16+16+16+1 { - return Some( - Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", packet_bytes.len()).as_str() + pub fn from_raw(raw_packet: &Packet) -> Result { + if raw_packet.header != FILEDATA_PACKET_ID { + return Err(Error::new("it is not a filedata packet")); + } + + if raw_packet.contents.len() < 16+16+16+1 { + return Err( + Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", raw_packet.contents.len()).as_str() )); } // file id - self.file_id = read_u128_slice_be(&packet_bytes[0..16]); + let file_id = read_u128_slice_be(&raw_packet.contents[0..16]); // chunk number - self.chunk_no = read_u128_slice_be(&packet_bytes[16..32]); + let chunk_no = read_u128_slice_be(&raw_packet.contents[16..32]); // chunk bytes - let chunk_length = read_u128_slice_be(&packet_bytes[32..48]); + let chunk_length = read_u128_slice_be(&raw_packet.contents[32..48]); + let mut chunk: Vec = Vec::with_capacity(chunk_length as usize); for i in 48..(48+chunk_length) as usize { - self.chunk[i-48] = packet_bytes[i].to_be(); + chunk[i-48] = raw_packet.contents[i].to_be(); } - return None; + return Ok( + FileData{ + file_id: file_id, + chunk_no: chunk_no, + chunk: chunk, + } + ); } } pub struct ConnectionShutdown {} -impl Packet for ConnectionShutdown { - fn get_type(&self) -> PacketType { - return PacketType::ConnectionShutdown; +impl ConnectionShutdown { + pub fn as_raw(&self) -> Packet { + return Packet{ + header: CONNECTION_SHUTDOWN_PACKET_ID, + contents: Vec::new(), + }; } - fn as_bytes(&self) -> Vec { - return vec!(CONNECTION_SHUTDOWN_PACKET_ID.to_be_bytes()[0]); - } + pub fn from_raw(raw_packet: &Packet) -> Result { + match raw_packet.header { + CONNECTION_SHUTDOWN_PACKET_ID => { + return Ok( + ConnectionShutdown{}, + ); + } - fn from_bytes(&mut self, _packet_bytes: Vec) -> Option { - return None; + _ => { + return Err( + Error::new("this is not a connection shutdown packet"), + ) + } + } } } +#[derive(Clone, Debug)] pub struct Handshake { pub protocol_version: u8, pub encryption_type: u8, @@ -434,69 +416,82 @@ impl Handshake { return Handshake{ protocol_version: PROTOCOL_LATEST_VERSION, encryption_type: ENCRYPTION_NO_ENCRYPTION, - encryption_key: vec!(0, 0, 0, 0, 0, 0, 0, 0), + encryption_key: crypt::keys::Key8bit::new(0).as_bytes(), }; } -} - -impl Packet for Handshake { - fn get_type(&self) -> PacketType { - return PacketType::Handshake; - } - fn as_bytes(&self) -> Vec { - let mut packet_bytes: Vec = Vec::::new(); - - packet_bytes.extend_from_slice(&HANDSHAKE_PACKET_ID.to_be_bytes()); + pub fn as_raw(&self) -> Packet { + let mut raw_packet: Packet = Packet{ + header: HANDSHAKE_PACKET_ID, + contents: Vec::::new(), + }; // protocol version - packet_bytes.extend_from_slice(&PROTOCOL_LATEST_VERSION.to_be_bytes()); + raw_packet.contents.extend_from_slice(&PROTOCOL_LATEST_VERSION.to_be_bytes()); // encryption type - packet_bytes.extend_from_slice(&self.encryption_type.to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.encryption_type.to_be_bytes()); // encryption key - packet_bytes.extend_from_slice(&(self.encryption_key.len() as u128).to_be_bytes()); - packet_bytes.extend_from_slice(&self.encryption_key); + raw_packet.contents.extend_from_slice(&(self.encryption_key.len() as u128).to_be_bytes()); + raw_packet.contents.extend_from_slice(&self.encryption_key); - return packet_bytes; + return raw_packet; } - fn from_bytes(&mut self, packet_bytes: Vec) -> Option { - if packet_bytes.len() < 1+1+1+16+1 { - return Some( - Error::new(format!("{} bytes is too small for a handshake packet to be valid", packet_bytes.len()).as_str()) + pub fn from_raw(raw_packet: &Packet) -> Result { + if raw_packet.contents.len() < 1+1+1+16+1 { + return Err( + Error::new(format!("{} bytes is too small for a handshake packet to be valid", raw_packet.contents.len()).as_str()) ); } // protocol version - self.protocol_version = packet_bytes[0].to_be(); + let protocol_version = raw_packet.contents[0].to_be(); // encryption type - self.encryption_type = packet_bytes[1].to_be(); + let encryption_type = raw_packet.contents[1].to_be(); // key - let key_len: u128 = read_u128_slice_be(&packet_bytes[1..17]); + 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 { - self.encryption_key[i-17] = packet_bytes[i].to_be(); + encryption_key[i-17] = raw_packet.contents[i].to_be(); } - return None; + println!("from bytes function handshake bytes: {:?}", raw_packet.contents); + + return Ok( + Handshake{ + protocol_version: protocol_version, + encryption_type: encryption_type, + encryption_key: encryption_key, + } + ); } } pub struct HandshakeAccept {} -impl Packet for HandshakeAccept { - fn get_type(&self) -> PacketType { - return PacketType::HandshakeAccept; +impl HandshakeAccept { + pub fn as_raw(&self) -> Packet { + return Packet{ + header: HANDSHAKE_ACCEPT_PACKET_ID, + contents: Vec::new(), + }; } - fn as_bytes(&self) -> Vec { - return vec!(HANDSHAKE_ACCEPT_PACKET_ID.to_be_bytes()[0]); - } + pub fn from_raw(raw_packet: &Packet) -> Result { + match raw_packet.header { + HANDSHAKE_ACCEPT_PACKET_ID => { + return Ok(HandshakeAccept{}) + } - fn from_bytes(&mut self, _packet_bytes: Vec) -> Option { - return None; + _ => { + return Err( + Error::new("this is not a handshake accept packet"), + ) + } + } } } \ No newline at end of file diff --git a/src/protocol/specs.rs b/src/protocol/specs.rs index b8c00fa..0792eb9 100644 --- a/src/protocol/specs.rs +++ b/src/protocol/specs.rs @@ -13,8 +13,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. */ -use crate::util::error::Error; - // Versioning pub const PROTOCOL_VERSION_1: u8 = 1; pub const PROTOCOL_LATEST_VERSION: u8 = PROTOCOL_VERSION_1; @@ -56,8 +54,7 @@ pub enum PacketType { FileReject, } -pub trait Packet : Send { - fn get_type(&self) -> PacketType; - fn as_bytes(&self) -> Vec; - fn from_bytes(&mut self, packet_bytes: Vec) -> Option; +pub struct Packet { + pub header: u8, + pub contents: Vec, } \ No newline at end of file