|
|
|
@ -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<W>(conn: &mut W, packet: &dyn Packet) -> Result<(), Error> where W: Write { |
|
|
|
|
let mut payload: Vec<u8> = Vec::<u8>::new(); |
|
|
|
|
pub fn send_packet<W>(conn: &mut W, packet: &Packet, encr_type: u8, key: &Vec<u8>) -> Result<(), Error> |
|
|
|
|
where W: Write { |
|
|
|
|
let mut packet_bytes: Vec<u8> = Vec::<u8>::new(); |
|
|
|
|
|
|
|
|
|
let packet_bytes: Vec<u8> = packet.as_bytes(); |
|
|
|
|
let packet_len: usize = packet_bytes.len(); |
|
|
|
|
let packet_contents = packet.contents; |
|
|
|
|
|
|
|
|
|
payload.extend_from_slice(&(packet_len as u128).to_be_bytes()); |
|
|
|
|
payload.extend_from_slice(&packet_bytes); |
|
|
|
|
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);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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(()) => { |
|
|
|
|
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]; |
|
|
|
|
loop { |
|
|
|
|
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]]); |
|
|
|
|
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{})); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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())); |
|
|
|
|
// decrypt
|
|
|
|
|
match encr_type { |
|
|
|
|
ECRYPTION_XOR => { |
|
|
|
|
crypt::xor::decrypt(&mut packet_bytes, &crypt::keys::Key8bit::new(key[0])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
None => { |
|
|
|
|
return Ok(Box::new(new_fileinfo_packet)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
_ | ENCRYPTION_NO_ENCRYPTION => {} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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())); |
|
|
|
|
} |
|
|
|
|
let mut packet_contents: Vec<u8> = Vec::with_capacity(packet_bytes[1..].len()); |
|
|
|
|
packet_contents.extend_from_slice(&packet_bytes[1..]); |
|
|
|
|
|
|
|
|
|
None => { |
|
|
|
|
return Ok(Box::new(new_filedata_packet)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_ => { |
|
|
|
|
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<u8>) { |
|
|
|
|
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<u8> { |
|
|
|
|
let mut packet_bytes: Vec<u8> = Vec::<u8>::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::<u8>::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<u8>) -> Option<Error> { |
|
|
|
|
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<Text, Error> { |
|
|
|
|
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<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
|
|
|
|
|
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 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 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() |
|
|
|
|
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<u8>, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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<u8> { |
|
|
|
|
let mut packet_bytes: Vec<u8> = Vec::<u8>::new(); |
|
|
|
|
|
|
|
|
|
packet_bytes.extend_from_slice(&FILEDATA_PACKET_ID.to_be_bytes()); |
|
|
|
|
pub fn as_raw(&self) -> Packet { |
|
|
|
|
let mut raw_packet: Packet = Packet{ |
|
|
|
|
header: FILEDATA_PACKET_ID, |
|
|
|
|
contents: Vec::<u8>::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()); |
|
|
|
|
|
|
|
|
|
// 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<u8>) -> Option<Error> { |
|
|
|
|
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<FileData, Error> { |
|
|
|
|
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<u8> = 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<u8> { |
|
|
|
|
return vec!(CONNECTION_SHUTDOWN_PACKET_ID.to_be_bytes()[0]); |
|
|
|
|
pub fn from_raw(raw_packet: &Packet) -> Result<ConnectionShutdown, Error> { |
|
|
|
|
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 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<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
|
|
|
|
|
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<u8>) -> Option<Error> { |
|
|
|
|
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<Handshake, Error> { |
|
|
|
|
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<u8> = 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<u8> { |
|
|
|
|
return vec!(HANDSHAKE_ACCEPT_PACKET_ID.to_be_bytes()[0]); |
|
|
|
|
pub fn from_raw(raw_packet: &Packet) -> Result<HandshakeAccept, Error> { |
|
|
|
|
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"), |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |