Browse Source

Fixed packet transmission logical errors; nodes are on "new rails"; back to sending text; working encryption

master
Gitea 2 years ago
parent
commit
f04c96c97f
  1. 40
      src/nodes/recv_node.rs
  2. 10
      src/nodes/send_node.rs
  3. 104
      src/protocol/packets.rs
  4. 13
      src/protocol/specs.rs

40
src/nodes/recv_node.rs

@ -14,7 +14,6 @@ GNU Affero General Public License for more details.
*/ */
use crate::util::error::Error; use crate::util::error::Error;
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;
@ -56,7 +55,7 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
// reject any connection that doesn't provide handshake information // reject any connection that doesn't provide handshake information
let mut connection: net::TcpStream; let mut connection: net::TcpStream;
let mut address: net::SocketAddr; let mut address: net::SocketAddr;
let mut handshake: packets::Handshake = packets::Handshake::empty(); let mut handshake: packets::Handshake;
loop { loop {
match listener.accept() { match listener.accept() {
Ok((c, a)) => { Ok((c, a)) => {
@ -75,33 +74,25 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
// read the first packet // read the first packet
match read_next_packet(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) { match read_next_packet(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) {
Ok(packet) => { Ok(packet) => {
println!("hea 1"); match packets::Handshake::from_raw(&packet) {
match handshake.from_bytes(packet.as_bytes()) { Ok(h) => {
Some(error) => { handshake = h;
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");
if verbose_output { if verbose_output {
println!("Handshake from {}", address); println!("Handshake from {}", address);
} }
// accept handshake // accept handshake
println!("local handshake: {:?}", &handshake);
match send_packet( match send_packet(
&mut connection, &mut connection,
&packets::HandshakeAccept{}, &packets::HandshakeAccept{}.as_raw(),
handshake.encryption_type, handshake.encryption_type,
&handshake.encryption_key &handshake.encryption_key
) { ) {
Ok(()) => {} Ok(()) => {}
Err(error) => { Err(error) => {
packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); 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())
); );
@ -111,6 +102,11 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
// break out of loop // break out of loop
break; 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() { match incoming_packet.header {
PacketType::ConnectionShutdown => { specs::CONNECTION_SHUTDOWN_PACKET_ID => {
if verbose_output { if verbose_output {
println!("{} shuts down the connection", address); println!("{} shuts down the connection", address);
} }
@ -195,18 +191,16 @@ pub fn start(options: RecvOptions, verbose_output: bool) -> Result<(), Error> {
break; break;
} }
PacketType::TextData => { specs::TEXT_PACKET_ID => {
let mut text_packet: packets::Text = packets::Text::empty(); match packets::Text::from_raw(&incoming_packet) {
match text_packet.from_bytes(incoming_packet.as_bytes()) { Ok(text_packet) => {
None => {
// print received text ! // print received text !
println!("{}", text_packet.text); println!("\n{}\n", text_packet.text);
} }
Some(error) => { Err(error) => {
// close connection and exit // close connection and exit
packets::close_connection(&mut connection, handshake.encryption_type, &handshake.encryption_key); 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())
); );

10
src/nodes/send_node.rs

@ -18,7 +18,6 @@ use crate::args::parser::DataType;
use crate::crypt; use crate::crypt;
use crate::protocol::packets; use crate::protocol::packets;
use crate::protocol::packets::{send_packet, read_next_packet}; use crate::protocol::packets::{send_packet, read_next_packet};
use crate::protocol::specs::PacketType;
use crate::protocol::specs; use crate::protocol::specs;
use crate::protocol::specs::Packet; use crate::protocol::specs::Packet;
use std::thread; use std::thread;
@ -74,8 +73,6 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
if verbose_output { if verbose_output {
println!("Using encryption ID: {} with key: {:?}", handshake.encryption_type, handshake.encryption_key); 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)) { match send_packet(&mut connection, &handshake.as_raw(), specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)) {
Ok(_) => { Ok(_) => {
@ -86,7 +83,6 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
Err(error) => { Err(error) => {
packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); 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())
); );
@ -96,7 +92,7 @@ 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, handshake.encryption_type, &handshake.encryption_key) { match read_next_packet(&mut connection, handshake.encryption_type, &handshake.encryption_key) {
Ok(packet) => { 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 // not approved or entirely not according to the protocol
packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0)); packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0));
return Err( return Err(
@ -165,10 +161,10 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
DataType::TEXT => { DataType::TEXT => {
if let Err(error) = send_packet( if let Err(error) = send_packet(
&mut connection, &mut connection,
&packets::Text::new(&options.text_to_send), &packets::Text::new(&options.text_to_send).as_raw(),
handshake.encryption_type, handshake.encryption_type,
&handshake.encryption_key &handshake.encryption_key
) { ) {
packets::close_connection(&mut connection, 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()))
} }

104
src/protocol/packets.rs

@ -26,26 +26,29 @@ use crate::crypt;
pub fn send_packet<W>(conn: &mut W, packet: &Packet, encr_type: u8, key: &Vec<u8>) -> Result<(), Error> pub fn send_packet<W>(conn: &mut W, packet: &Packet, encr_type: u8, key: &Vec<u8>) -> Result<(), Error>
where W: Write { where W: Write {
let mut packet_bytes: Vec<u8> = Vec::<u8>::new(); // ready-to-transport packet bytes
let mut packet_bytes: Vec<u8> = Vec::with_capacity(packet.contents.len() + 1);
let packet_contents = packet.contents; packet_bytes.extend_from_slice(&packet.header.to_be_bytes());
packet_bytes.extend_from_slice(&packet.contents);
match encr_type { match encr_type {
ECRYPTION_XOR => { ECRYPTION_XOR => {
crypt::xor::encrypt(&mut packet_contents, &crypt::keys::Key8bit::new(key[0])); crypt::xor::encrypt(&mut packet_bytes, &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 => { 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) {
// get total length and add it to the beginning
let total_packet_len: u128 = packet_bytes.len() as u128;
let mut transport_bytes: Vec<u8> = 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(()) => { Ok(()) => {
return Ok(()); return Ok(());
} }
@ -103,16 +106,13 @@ pub fn read_next_packet<R>(conn: &mut R, encr_type: u8, key: &Vec<u8>) -> Result
crypt::xor::decrypt(&mut packet_bytes, &crypt::keys::Key8bit::new(key[0])); crypt::xor::decrypt(&mut packet_bytes, &crypt::keys::Key8bit::new(key[0]));
} }
_ | ENCRYPTION_NO_ENCRYPTION => {} ENCRYPTION_NO_ENCRYPTION | _ => {}
} }
let mut packet_contents: Vec<u8> = Vec::with_capacity(packet_bytes[1..].len());
packet_contents.extend_from_slice(&packet_bytes[1..]);
return Ok( return Ok(
Packet{ Packet{
header: packet_bytes[0].to_be(), header: packet_bytes[0].to_be(),
contents: packet_contents, contents: Vec::from(&packet_bytes[1..]),
} }
); );
} }
@ -127,12 +127,6 @@ pub struct Text {
} }
impl Text { impl Text {
pub fn empty() -> Text {
return Text{
text: "".to_string(),
};
}
pub fn new(txt: &str) -> Text { pub fn new(txt: &str) -> Text {
return Text { return Text {
text: txt.to_string(), text: txt.to_string(),
@ -142,7 +136,7 @@ impl Text {
pub fn as_raw(&self) -> Packet { pub fn as_raw(&self) -> Packet {
let mut raw_packet: Packet = Packet{ let mut raw_packet: Packet = Packet{
header: TEXT_PACKET_ID, header: TEXT_PACKET_ID,
contents: Vec::<u8>::new(), contents: Vec::with_capacity(self.text.len()),
}; };
let text_length: u128 = self.text.len() as u128; 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")); return Err(Error::new("it is not a text packet"));
} }
if raw_packet.contents.len() < 18 { if raw_packet.contents.len() < 17 {
return Err( return Err(
Error::new(format!("{} bytes is too small for a text packet to be valid", raw_packet.contents.len()).as_str() Error::new(format!("{} bytes is too small for a text packet to be valid", raw_packet.contents.len()).as_str()
)); ));
} }
// get text length // 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( 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,
raw_packet.contents[16..].len() raw_packet.contents[16..16+text_length as usize].len()
).as_str() ).as_str()
) )
); );
} }
// extract text // 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( return Ok(
Text{ Text{
@ -198,7 +192,7 @@ pub struct FileInfo {
} }
impl FileInfo { impl FileInfo {
pub fn empty() -> FileInfo { fn empty() -> FileInfo {
return FileInfo{ return FileInfo{
file_id: 0, file_id: 0,
filename: String::new(), filename: String::new(),
@ -273,7 +267,7 @@ impl FileInfo {
return Err(Error::new("it is not a fileinfo packet")); 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( return Err(
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", raw_packet.contents.len()).as_str()
)); ));
@ -284,17 +278,17 @@ impl FileInfo {
// get filename // get filename
let filename_length: u128 = read_u128_slice_be(&raw_packet.contents[16..32]); 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 // 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 // relative path
let rel_path_length: u128 = read_u128_slice_be( 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( 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( return Ok(
@ -316,14 +310,6 @@ pub struct FileData {
} }
impl FileData { impl FileData {
pub fn empty() -> FileData {
return FileData {
file_id: 0,
chunk_no: 0,
chunk: Vec::new(),
}
}
pub fn as_raw(&self) -> Packet { pub fn as_raw(&self) -> Packet {
let mut raw_packet: Packet = Packet{ let mut raw_packet: Packet = Packet{
header: FILEDATA_PACKET_ID, header: FILEDATA_PACKET_ID,
@ -348,7 +334,7 @@ impl FileData {
return Err(Error::new("it is not a filedata packet")); 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( return Err(
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", raw_packet.contents.len()).as_str()
)); ));
@ -412,14 +398,6 @@ pub struct Handshake {
} }
impl 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 { pub fn as_raw(&self) -> Packet {
let mut raw_packet: Packet = Packet{ let mut raw_packet: Packet = Packet{
header: HANDSHAKE_PACKET_ID, header: HANDSHAKE_PACKET_ID,
@ -440,7 +418,11 @@ impl Handshake {
} }
pub fn from_raw(raw_packet: &Packet) -> Result<Handshake, Error> { pub fn from_raw(raw_packet: &Packet) -> Result<Handshake, Error> {
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( return Err(
Error::new(format!("{} bytes is too small for a handshake packet to be valid", raw_packet.contents.len()).as_str()) 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(); let encryption_type = raw_packet.contents[1].to_be();
// key // key
let key_len: u128 = read_u128_slice_be(&raw_packet.contents[1..17]); let key_len: u128 = read_u128_slice_be(&raw_packet.contents[2..18]);
let mut encryption_key: Vec<u8> = Vec::with_capacity(key_len as usize); let mut encryption_key: Vec<u8> = vec!(0; key_len as usize);
for i in 17..(17+key_len) as usize { if key_len == 0 {
encryption_key[i-17] = raw_packet.contents[i].to_be(); 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( return Ok(
Handshake{ Handshake{
protocol_version: protocol_version, protocol_version: protocol_version,

13
src/protocol/specs.rs

@ -42,18 +42,7 @@ pub enum RunMode {
DAEMON, DAEMON,
} }
#[derive(PartialEq, Eq, Debug)] #[derive(Debug)]
pub enum PacketType {
ConnectionShutdown,
TextData,
FileInfo,
FileData,
Handshake,
HandshakeAccept,
FileAccept,
FileReject,
}
pub struct Packet { pub struct Packet {
pub header: u8, pub header: u8,
pub contents: Vec<u8>, pub contents: Vec<u8>,

Loading…
Cancel
Save