Browse Source

NOT FOR BUILD: significantly simplified work with packets, nodes are unchanged and need to be fixed

master
Gitea 2 years ago
parent
commit
6561d950d6
  1. 4
      TODO
  2. 4
      src/crypt/keys.rs
  3. 70
      src/nodes/recv_node.rs
  4. 40
      src/nodes/send_node.rs
  5. 389
      src/protocol/packets.rs
  6. 9
      src/protocol/specs.rs

4
TODO

@ -1,5 +1,5 @@
1. Write base foundation for sending and receiving information -1. Write base foundation for sending and receiving information-
2. Wire it all together -2. Wire it all together-
3. Make it encrypted 3. Make it encrypted
4. Allow receiving node to connect as well 4. Allow receiving node to connect as well
5. Daemon 5. Daemon

4
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, k: rand::rand_u16(SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() as u16) as u8,
} }
} }
pub fn as_bytes(&self) -> Vec<u8> {
return vec!(self.k);
}
} }
#[cfg(test)] #[cfg(test)]

70
src/nodes/recv_node.rs

@ -18,6 +18,7 @@ use crate::protocol::specs::PacketType;
use crate::protocol::specs::Packet; use crate::protocol::specs::Packet;
use crate::protocol::packets::{read_next_packet, send_packet}; use crate::protocol::packets::{read_next_packet, send_packet};
use crate::protocol::packets; use crate::protocol::packets;
use crate::protocol::specs;
use std::path; use std::path;
use std::net; use std::net;
use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc::{Sender, Receiver};
@ -72,45 +73,34 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
} }
// read the first packet // read the first packet
let incoming_packet: Box<dyn Packet>; match read_next_packet(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) {
match read_next_packet(&mut connection) {
Ok(packet) => { Ok(packet) => {
incoming_packet = packet; println!("hea 1");
} match handshake.from_bytes(packet.as_bytes()) {
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()) {
Some(error) => { Some(error) => {
packets::close_connection(&mut connection); 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()));
return Err(
Error::new(
format!("error constructing handshake from {}: {}", address, error.text).as_str()
));
}
None => {}
} }
None => {
println!("hea 2");
if verbose_output { if verbose_output {
println!("Handshake from {}", address); println!("Handshake from {}", address);
} }
// accept handshake // accept handshake
match send_packet(&mut connection, &packets::HandshakeAccept{}) { println!("local handshake: {:?}", &handshake);
match send_packet(
&mut connection,
&packets::HandshakeAccept{},
handshake.encryption_type,
&handshake.encryption_key
) {
Ok(()) => {} Ok(()) => {}
Err(error) => { Err(error) => {
packets::close_connection(&mut connection); packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key);
return Err( return Err(
Error::new(format!("error accepting handshake from {}: {}", address, error.text).as_str()) Error::new(format!("error accepting handshake from {}: {}", address, error.text).as_str())
@ -121,12 +111,15 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
// break out of loop // break out of loop
break; break;
} }
}
}
_ => { Err(error) => {
// not a valid packet; it's most probably not another instance
if verbose_output { 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; continue;
} }
} }
@ -135,7 +128,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
// now read and process incoming packets; essentialy receiving something ! // now read and process incoming packets; essentialy receiving something !
// launch a new packet reading thread // launch a new packet reading thread
let (ch_send, ch_recv): (Sender<Box<dyn Packet + Send>>, Receiver<Box<dyn Packet + Send>>) = mpsc::channel(); let (ch_send, ch_recv): (Sender<Packet>, Receiver<Packet>) = mpsc::channel();
let mut cloned_connection: net::TcpStream; let mut cloned_connection: net::TcpStream;
match connection.try_clone() { match connection.try_clone() {
@ -144,7 +137,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
} }
Err(_) => { Err(_) => {
packets::close_connection(&mut connection); packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key);
return Err( return Err(
Error::new("could not clone connection") Error::new("could not clone connection")
@ -152,9 +145,10 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
} }
} }
let handshake_clone: packets::Handshake = handshake.clone();
thread::spawn(move || { thread::spawn(move || {
loop { 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) => { Ok(packet) => {
if let Err(_) = ch_send.send(packet) { if let Err(_) = ch_send.send(packet) {
// the channel has been hung up // the channel has been hung up
@ -176,14 +170,14 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
// handle incoming packets // handle incoming packets
loop { loop {
let incoming_packet: Box<dyn Packet>; let incoming_packet: Packet;
match ch_recv.recv() { match ch_recv.recv() {
Ok(p) => { Ok(p) => {
incoming_packet = p; incoming_packet = p;
} }
Err(error) => { Err(error) => {
packets::close_connection(&mut connection); packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key);
return Err(Error::new( return Err(Error::new(
format!("error receiving a new packet from listener thread: {}", error).as_str() 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 { if verbose_output {
println!("{} shuts down the connection", address); println!("{} shuts down the connection", address);
} }
packets::close_connection(&mut connection); packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key);
break; break;
} }
@ -211,7 +205,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
Some(error) => { Some(error) => {
// close connection and exit // close connection and exit
packets::close_connection(&mut connection); packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key);
return Err( return Err(
Error::new(format!("could not get text packet: {}", error.text).as_str()) Error::new(format!("could not get text packet: {}", error.text).as_str())

40
src/nodes/send_node.rs

@ -46,6 +46,7 @@ impl SendOptions {
} }
pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> { pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
// connect
let mut connection: net::TcpStream; let mut connection: net::TcpStream;
match net::TcpStream::connect(&options.address) { match net::TcpStream::connect(&options.address) {
Ok(conn) => { Ok(conn) => {
@ -67,10 +68,16 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
let handshake: packets::Handshake = packets::Handshake{ let handshake: packets::Handshake = packets::Handshake{
protocol_version: specs::PROTOCOL_VERSION_1, protocol_version: specs::PROTOCOL_VERSION_1,
encryption_type: specs::ECRYPTION_XOR, encryption_type: specs::ECRYPTION_XOR,
encryption_key: vec!(crypt::keys::Key8bit::new_random().k), encryption_key: crypt::keys::Key8bit::new_random().as_bytes(),
}; };
match send_packet(&mut connection, &handshake) { 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(_) => { Ok(_) => {
if verbose_output { if verbose_output {
println!("Sent handshake"); println!("Sent handshake");
@ -78,7 +85,7 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
} }
Err(error) => { Err(error) => {
packets::close_connection(&mut connection); packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0));
return Err( return Err(
Error::new(format!("could not send handshake: {}", error.text).as_str()) 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 // 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) => { Ok(packet) => {
if packet.get_type() != PacketType::HandshakeAccept { if packet.get_type() != PacketType::HandshakeAccept {
// not approved or entirely not according to the protocol // 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( return Err(
Error::new(format!("handshake hasn't been approved").as_str()) 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) => { Err(error) => {
packets::close_connection(&mut connection); packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0));
return Err( return Err(
Error::new(format!("could not receive potential handshake approval: {}", error.text).as_str()) Error::new(format!("could not receive potential handshake approval: {}", error.text).as_str())
); );
} }
} }
// handshake has been accepted
// launch a new packet reading thread // launch a new packet reading thread
let (ch_send, ch_recv): (Sender<Box<dyn Packet + Send>>, Receiver<Box<dyn Packet + Send>>) = mpsc::channel(); let (ch_send, _ch_recv): (Sender<Packet>, Receiver<Packet>) = mpsc::channel();
let mut cloned_connection: net::TcpStream; let mut cloned_connection: net::TcpStream;
match connection.try_clone() { match connection.try_clone() {
@ -120,17 +129,18 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
} }
Err(_) => { Err(_) => {
packets::close_connection(&mut connection); packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key);
return Err( return Err(
Error::new("could not clone connection") Error::new("could not clone connection")
); );
} }
} }
let handshake_clone = handshake.clone();
thread::spawn(move || { thread::spawn(move || {
loop { 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) => { Ok(packet) => {
if let Err(_) = ch_send.send(packet) { if let Err(_) = ch_send.send(packet) {
// the channel has been hung up // 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 { match options.send_type {
DataType::TEXT => { DataType::TEXT => {
if let Err(error) = send_packet(&mut connection, &packets::Text::new(&options.text_to_send)) { if let Err(error) = send_packet(
packets::close_connection(&mut connection); &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())) 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 => { DataType::FILE => {

389
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::util::buf_read::{read_u128_slice_be, read_utf8_string_slice};
use crate::protocol::specs::*; use crate::protocol::specs::*;
use crate::fsys::file::ChunkedFile; use crate::fsys::file::ChunkedFile;
use crate::crypt;
pub fn send_packet<W>(conn: &mut W, packet: &dyn Packet) -> Result<(), Error> where W: Write { pub fn send_packet<W>(conn: &mut W, packet: &Packet, encr_type: u8, key: &Vec<u8>) -> Result<(), Error>
let mut payload: Vec<u8> = Vec::<u8>::new(); where W: Write {
let mut packet_bytes: Vec<u8> = Vec::<u8>::new();
let packet_bytes: Vec<u8> = packet.as_bytes(); let packet_contents = packet.contents;
let packet_len: usize = packet_bytes.len();
payload.extend_from_slice(&(packet_len as u128).to_be_bytes()); match encr_type {
payload.extend_from_slice(&packet_bytes); 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);
}
match conn.write_all(&payload) { _ | 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(&packet_bytes) {
Ok(()) => { Ok(()) => {
return Ok(()); return Ok(());
} }
@ -43,7 +56,8 @@ pub fn send_packet<W>(conn: &mut W, packet: &dyn Packet) -> Result<(), Error> wh
} }
} }
pub fn read_next_packet<R>(conn: &mut R) -> Result<Box<dyn Packet + Send>, Error> where R: Read { pub fn read_next_packet<R>(conn: &mut R, encr_type: u8, key: &Vec<u8>) -> Result<Packet, Error>
where R: Read {
let mut u128_buf: [u8; 16] = [0; 16]; let mut u128_buf: [u8; 16] = [0; 16];
loop { loop {
match conn.read_exact(&mut u128_buf) { match conn.read_exact(&mut u128_buf) {
@ -83,79 +97,28 @@ pub fn read_next_packet<R>(conn: &mut R) -> Result<Box<dyn Packet + Send>, Error
); );
} }
let packet_type_byte: u8 = u8::from_be_bytes([packet_bytes[0]]); // decrypt
match packet_type_byte { match encr_type {
HANDSHAKE_PACKET_ID => { ECRYPTION_XOR => {
let mut new_handshake_packet: Handshake = Handshake::empty(); crypt::xor::decrypt(&mut packet_bytes, &crypt::keys::Key8bit::new(key[0]));
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{}));
}
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 => { _ | ENCRYPTION_NO_ENCRYPTION => {}
return Ok(Box::new(new_fileinfo_packet));
}
}
} }
FILEDATA_PACKET_ID => { let mut packet_contents: Vec<u8> = Vec::with_capacity(packet_bytes[1..].len());
let mut new_filedata_packet: FileData = FileData::empty(); packet_contents.extend_from_slice(&packet_bytes[1..]);
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()));
}
None => { return Ok(
return Ok(Box::new(new_filedata_packet)); Packet{
} header: packet_bytes[0].to_be(),
} contents: packet_contents,
}
_ => {
return Err(Error::new(format!("invalid or unimplemented packet type ID \"{}\"", packet_type_byte).as_str()));
}
} }
);
} }
pub fn close_connection(connection: &mut net::TcpStream) { pub fn close_connection(connection: &mut net::TcpStream, encr_type: u8, key: &Vec<u8>) {
send_packet(connection, &ConnectionShutdown{}); send_packet(connection, &ConnectionShutdown{}.as_raw(), encr_type, key);
connection.shutdown(net::Shutdown::Both); connection.shutdown(net::Shutdown::Both);
} }
@ -175,59 +138,54 @@ impl Text {
text: txt.to_string(), text: txt.to_string(),
} }
} }
}
impl Packet for Text {
fn get_type(&self) -> PacketType {
return PacketType::TextData;
}
fn as_bytes(&self) -> Vec<u8> { pub fn as_raw(&self) -> Packet {
let mut packet_bytes: Vec<u8> = Vec::<u8>::new(); let mut raw_packet: Packet = Packet{
header: TEXT_PACKET_ID,
packet_bytes.extend_from_slice(&TEXT_PACKET_ID.to_be_bytes()); contents: Vec::<u8>::new(),
};
let text_length: u128 = self.text.len() as u128; let text_length: u128 = self.text.len() as u128;
packet_bytes.extend_from_slice(&text_length.to_be_bytes()); raw_packet.contents.extend_from_slice(&text_length.to_be_bytes());
packet_bytes.extend_from_slice(&self.text.as_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<u8>) -> Option<Error> { pub fn from_raw(raw_packet: &Packet) -> Result<Text, Error> {
if packet_bytes.len() < 18 { if raw_packet.header != TEXT_PACKET_ID {
return Some( return Err(Error::new("it is not a text packet"));
Error::new(format!("{} bytes is too small for a text packet to be valid", packet_bytes.len()).as_str()
));
} }
// retrieve and check for packet type byte if raw_packet.contents.len() < 18 {
match packet_bytes[0].to_be() { return Err(
TEXT_PACKET_ID => {} Error::new(format!("{} bytes is too small for a text packet to be valid", raw_packet.contents.len()).as_str()
_ => { ));
return Some(Error::new("packet type is not of a text packet"));
}
} }
// get text length // 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() { if text_length as usize > raw_packet.contents[17..].len() {
return Some( return Err(
Error::new( Error::new(
format!( format!(
"text length ({}) is bigger than provided packet bytes length ({})", "text length ({}) is bigger than provided packet bytes length ({})",
text_length, text_length,
packet_bytes[16..].len() raw_packet.contents[16..].len()
).as_str() ).as_str()
) )
); );
} }
// extract text // 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); return Ok(new_fileinfo_packet);
} }
}
impl Packet for FileInfo {
fn get_type(&self) -> PacketType {
return PacketType::FileInfo;
}
fn as_bytes(&self) -> Vec<u8> {
let mut packet_bytes: Vec<u8> = Vec::<u8>::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::<u8>::new(),
};
// file id // 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 // filename
let filename_bytes_length: u128 = self.filename.len() as u128; let filename_bytes_length: u128 = self.filename.len() as u128;
packet_bytes.extend_from_slice(&filename_bytes_length.to_be_bytes()); raw_packet.contents.extend_from_slice(&filename_bytes_length.to_be_bytes());
packet_bytes.extend_from_slice(&self.filename.as_bytes()); raw_packet.contents.extend_from_slice(&self.filename.as_bytes());
// filesize // filesize
packet_bytes.extend_from_slice(&self.filesize.to_be_bytes()); raw_packet.contents.extend_from_slice(&self.filesize.to_be_bytes());
// relative path // relative path
let relative_path_bytes_length: u128 = self.relative_path.len() as u128; let relative_path_bytes_length: u128 = self.relative_path.len() as u128;
packet_bytes.extend_from_slice(&relative_path_bytes_length.to_be_bytes()); raw_packet.contents.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(&self.relative_path.as_bytes());
return raw_packet;
}
return packet_bytes; pub fn from_raw(raw_packet: &Packet) -> Result<FileInfo, Error> {
if raw_packet.header != FILEINFO_PACKET_ID {
return Err(Error::new("it is not a fileinfo packet"));
} }
fn from_bytes(&mut self, packet_bytes: Vec<u8>) -> Option<Error> { if raw_packet.contents.len() < 16+16+16+16+1+1 {
if packet_bytes.len() < 16+16+16+16+1+1 { return Err(
return Some( Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", raw_packet.contents.len()).as_str()
Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", packet_bytes.len()).as_str()
)); ));
} }
// file id // 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 // get filename
let filename_length: u128 = read_u128_slice_be(&packet_bytes[16..32]); let filename_length: u128 = read_u128_slice_be(&raw_packet.contents[16..32]);
self.filename = read_utf8_string_slice(&packet_bytes[32..(filename_length+32) as usize]); let filename = read_utf8_string_slice(&raw_packet.contents[32..(filename_length+32) as usize]);
// filesize // 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 // relative path
let rel_path_length: u128 = read_u128_slice_be( 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( let 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] &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 struct FileData {
pub file_id: u128, pub file_id: u128,
pub chunk_no: u128, pub chunk_no: u128,
pub chunk: [u8; CHUNK_SIZE], pub chunk: Vec<u8>,
} }
impl FileData { impl FileData {
@ -356,73 +320,91 @@ impl FileData {
return FileData { return FileData {
file_id: 0, file_id: 0,
chunk_no: 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<u8> { pub fn as_raw(&self) -> Packet {
let mut packet_bytes: Vec<u8> = Vec::<u8>::new(); let mut raw_packet: Packet = Packet{
header: FILEDATA_PACKET_ID,
packet_bytes.extend_from_slice(&FILEDATA_PACKET_ID.to_be_bytes()); contents: Vec::<u8>::new(),
};
// file id // 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 // 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 // chunk
packet_bytes.extend_from_slice(&self.chunk.len().to_be_bytes()); raw_packet.contents.extend_from_slice(&self.chunk.len().to_be_bytes());
packet_bytes.extend_from_slice(&self.chunk); raw_packet.contents.extend_from_slice(&self.chunk);
return packet_bytes; return raw_packet;
} }
fn from_bytes(&mut self, packet_bytes: Vec<u8>) -> Option<Error> { pub fn from_raw(raw_packet: &Packet) -> Result<FileData, Error> {
if packet_bytes.len() < 16+16+16+1 { if raw_packet.header != FILEDATA_PACKET_ID {
return Some( return Err(Error::new("it is not a filedata packet"));
Error::new(format!("{} bytes is too small for a fileinfo packet to be valid", packet_bytes.len()).as_str() }
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 // 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 // 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 // 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<u8> = Vec::with_capacity(chunk_length as usize);
for i in 48..(48+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 {} pub struct ConnectionShutdown {}
impl Packet for ConnectionShutdown { impl ConnectionShutdown {
fn get_type(&self) -> PacketType { pub fn as_raw(&self) -> Packet {
return PacketType::ConnectionShutdown; return Packet{
header: CONNECTION_SHUTDOWN_PACKET_ID,
contents: Vec::new(),
};
} }
fn as_bytes(&self) -> Vec<u8> { pub fn from_raw(raw_packet: &Packet) -> Result<ConnectionShutdown, Error> {
return vec!(CONNECTION_SHUTDOWN_PACKET_ID.to_be_bytes()[0]); match raw_packet.header {
CONNECTION_SHUTDOWN_PACKET_ID => {
return Ok(
ConnectionShutdown{},
);
} }
fn from_bytes(&mut self, _packet_bytes: Vec<u8>) -> Option<Error> { _ => {
return None; return Err(
Error::new("this is not a connection shutdown packet"),
)
}
}
} }
} }
#[derive(Clone, Debug)]
pub struct Handshake { pub struct Handshake {
pub protocol_version: u8, pub protocol_version: u8,
pub encryption_type: u8, pub encryption_type: u8,
@ -434,69 +416,82 @@ impl Handshake {
return Handshake{ return Handshake{
protocol_version: PROTOCOL_LATEST_VERSION, protocol_version: PROTOCOL_LATEST_VERSION,
encryption_type: ENCRYPTION_NO_ENCRYPTION, 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<u8> {
let mut packet_bytes: Vec<u8> = Vec::<u8>::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::<u8>::new(),
};
// protocol version // 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 // 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 // encryption key
packet_bytes.extend_from_slice(&(self.encryption_key.len() as u128).to_be_bytes()); raw_packet.contents.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);
return packet_bytes; return raw_packet;
} }
fn from_bytes(&mut self, packet_bytes: Vec<u8>) -> Option<Error> { pub fn from_raw(raw_packet: &Packet) -> Result<Handshake, Error> {
if packet_bytes.len() < 1+1+1+16+1 { if raw_packet.contents.len() < 1+1+1+16+1 {
return Some( return Err(
Error::new(format!("{} bytes is too small for a handshake packet to be valid", packet_bytes.len()).as_str()) Error::new(format!("{} bytes is too small for a handshake packet to be valid", raw_packet.contents.len()).as_str())
); );
} }
// protocol version // protocol version
self.protocol_version = packet_bytes[0].to_be(); let protocol_version = raw_packet.contents[0].to_be();
// encryption type // encryption type
self.encryption_type = packet_bytes[1].to_be(); let encryption_type = raw_packet.contents[1].to_be();
// key // 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<u8> = Vec::with_capacity(key_len as usize);
for i in 17..(17+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 {} pub struct HandshakeAccept {}
impl Packet for HandshakeAccept { impl HandshakeAccept {
fn get_type(&self) -> PacketType { pub fn as_raw(&self) -> Packet {
return PacketType::HandshakeAccept; return Packet{
header: HANDSHAKE_ACCEPT_PACKET_ID,
contents: Vec::new(),
};
} }
fn as_bytes(&self) -> Vec<u8> { pub fn from_raw(raw_packet: &Packet) -> Result<HandshakeAccept, Error> {
return vec!(HANDSHAKE_ACCEPT_PACKET_ID.to_be_bytes()[0]); match raw_packet.header {
HANDSHAKE_ACCEPT_PACKET_ID => {
return Ok(HandshakeAccept{})
} }
fn from_bytes(&mut self, _packet_bytes: Vec<u8>) -> Option<Error> { _ => {
return None; return Err(
Error::new("this is not a handshake accept packet"),
)
}
}
} }
} }

9
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. GNU Affero General Public License for more details.
*/ */
use crate::util::error::Error;
// Versioning // Versioning
pub const PROTOCOL_VERSION_1: u8 = 1; pub const PROTOCOL_VERSION_1: u8 = 1;
pub const PROTOCOL_LATEST_VERSION: u8 = PROTOCOL_VERSION_1; pub const PROTOCOL_LATEST_VERSION: u8 = PROTOCOL_VERSION_1;
@ -56,8 +54,7 @@ pub enum PacketType {
FileReject, FileReject,
} }
pub trait Packet : Send { pub struct Packet {
fn get_type(&self) -> PacketType; pub header: u8,
fn as_bytes(&self) -> Vec<u8>; pub contents: Vec<u8>,
fn from_bytes(&mut self, packet_bytes: Vec<u8>) -> Option<Error>;
} }
Loading…
Cancel
Save