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

8
src/nodes/send_node.rs

@ -18,7 +18,6 @@ use crate::args::parser::DataType;
use crate::crypt;
use crate::protocol::packets;
use crate::protocol::packets::{send_packet, read_next_packet};
use crate::protocol::specs::PacketType;
use crate::protocol::specs;
use crate::protocol::specs::Packet;
use std::thread;
@ -75,8 +74,6 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
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(_) => {
if verbose_output {
@ -86,7 +83,6 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
Err(error) => {
packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0));
return Err(
Error::new(format!("could not send handshake: {}", error.text).as_str())
);
@ -96,7 +92,7 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
// see if the handshake has been accepted
match read_next_packet(&mut connection, handshake.encryption_type, &handshake.encryption_key) {
Ok(packet) => {
if packet.get_type() != PacketType::HandshakeAccept {
if packet.header != specs::HANDSHAKE_ACCEPT_PACKET_ID {
// not approved or entirely not according to the protocol
packets::close_connection(&mut connection, specs::ENCRYPTION_NO_ENCRYPTION, &vec!(0));
return Err(
@ -165,7 +161,7 @@ pub fn start(options: SendOptions, verbose_output: bool) -> Result<(), Error> {
DataType::TEXT => {
if let Err(error) = send_packet(
&mut connection,
&packets::Text::new(&options.text_to_send),
&packets::Text::new(&options.text_to_send).as_raw(),
handshake.encryption_type,
&handshake.encryption_key
) {

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

13
src/protocol/specs.rs

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

Loading…
Cancel
Save