feat: adding packet handling to server

This commit is contained in:
Andrew Rioux 2023-09-04 19:10:43 -04:00
parent fb43a27ba3
commit 1e5f515a25
Signed by: andrew.rioux
GPG Key ID: 9B8BAC47C17ABB94
7 changed files with 112 additions and 29 deletions

View File

@ -0,0 +1,27 @@
use ansi_term::{Color, Style};
use structopt::StructOpt;
use crate::commands::connect::shell::SparseCommands;
pub fn print_help(arg: Option<SparseCommands>) {
match arg {
Some(SparseCommands::Exit) => println!(
"Exits from the shell and disconnects from the binary"
),
Some(SparseCommands::SysInfo) => println!(
"Prints system information from the system you are connecting to"
),
None => println!(
"\n{}{}\n\
\n\
The following shell commands are available:\n\
\n\
- #sysinfo\t\tprint information about the system you are connecting to
- #help\t\tprints this help page, or alternatively prints info about a command passed as an argument\n\
- #exit\t\texit from the shell and disconnect from the binary\n\
",
Style::new().bold().paint("SHELL COMMANDS"),
Style::new().paint(""),
)
}
}

View File

@ -1 +1,2 @@
pub mod help;
pub mod sysinfo; pub mod sysinfo;

View File

@ -1,10 +1,10 @@
use std::net::IpAddr; use std::net::IpAddr;
use ansi_term::Colour as Color;
use sparse_05_common::messages::{Capabilities, OperatingSystem}; use sparse_05_common::messages::{Capabilities, OperatingSystem};
pub fn print_capabilities(capabilities: &Capabilities, ip: &IpAddr) { pub fn print_capabilities(capabilities: &Capabilities, ip: &IpAddr) {
use ansi_term::Colour as Color;
println!("Capabilities of remote host:"); println!("Capabilities of remote host:");
println!( println!(
"\tOperating system: \t{}", "\tOperating system: \t{}",
@ -69,6 +69,6 @@ pub fn print_capabilities(capabilities: &Capabilities, ip: &IpAddr) {
println!( println!(
"\tHost name (IP): \t{} ({})", "\tHost name (IP): \t{} ({})",
capabilities.hostname.as_deref().unwrap_or("<unknown>"), capabilities.hostname.as_deref().unwrap_or("<unknown>"),
ip.ip() ip
); );
} }

View File

@ -1,15 +1,23 @@
use std::{ use std::{
io::{self, Read, Write}, io::{self, Read, Write},
os::fd::AsRawFd, os::fd::AsRawFd,
path::PathBuf,
sync::Arc, sync::Arc,
}; };
use sparse_05_common::messages::Capabilities; use sparse_05_common::messages::Capabilities;
use tokio::net::UdpSocket; use structopt::StructOpt;
use super::{commands, Connection}; use super::{commands, Connection};
#[derive(StructOpt)]
#[structopt()]
pub enum SparseCommands {
#[structopt(name = "#sysinfo")]
SysInfo,
#[structopt(name = "#exit")]
Exit,
}
macro_rules! libc_try { macro_rules! libc_try {
($expr:expr) => { ($expr:expr) => {
if unsafe { $expr } == -1 { if unsafe { $expr } == -1 {
@ -41,6 +49,7 @@ pub(super) async fn shell(
connection: Arc<Connection>, connection: Arc<Connection>,
mut capabilities: Capabilities, mut capabilities: Capabilities,
) -> anyhow::Result<()> { ) -> anyhow::Result<()> {
println!("Source code available at https://github.com/r-a303931/sparse (feel free to give it a star!)");
println!("Type #help to view a list of sparse commands\n"); println!("Type #help to view a list of sparse commands\n");
let mut stdin = io::stdin(); let mut stdin = io::stdin();
@ -49,20 +58,6 @@ pub(super) async fn shell(
let mut raw_term_attrs = get_term_attrs(&stdin)?; let mut raw_term_attrs = get_term_attrs(&stdin)?;
convert_termios_raw(&mut raw_term_attrs)?; convert_termios_raw(&mut raw_term_attrs)?;
macro_rules! cmd_matcher {
($input:expr, $(($check:ident, $matcher:expr) => {$($body:tt)*}),+, _ => {$($ebody:tt)*}) => {
match &$input[..] {
$($check if $check.len() >= $matcher.len() && $check[..$matcher.len()] == $matcher[..] => {
let $check = &$check[$matcher.len()..];
$($body)*
}),+
_ => {
$($ebody)*
}
}
}
}
let mut cwd = "/".to_string(); let mut cwd = "/".to_string();
loop { loop {
@ -85,17 +80,33 @@ pub(super) async fn shell(
break; break;
} }
cmd_matcher!( let Ok(input) = std::str::from_utf8(&cmd[..amount]) else {
cmd[..amount], continue;
(_sysinfo, b"#sysinfo") => { };
let (args, help) = if input.starts_with("#help") {
(input.split(" ").collect::<Vec<_>>(), true)
} else {
(
[&[""][..], &input.split(" ").collect::<Vec<_>>()].concat(),
false,
)
};
let parsed = SparseCommands::from_iter_safe(args.iter());
match (parsed, help) {
(help_info, true) => {
commands::help::print_help(help_info.ok());
}
(Ok(SparseCommands::SysInfo), _) => {
commands::sysinfo::print_capabilities(&capabilities, &connection.ip.ip()) commands::sysinfo::print_capabilities(&capabilities, &connection.ip.ip())
}, }
(_help, b"#help") => {}, (Ok(SparseCommands::Exit), _) => {
(_exit, b"#exit") => {
break; break;
}, }
_ => {} _ => {}
); }
} }
Ok(()) Ok(())

View File

@ -20,7 +20,8 @@ pub mod messages {
OpenTTY, OpenTTY,
CloseTTY(u64), CloseTTY(u64),
SendRawData(Vec<u64>, u64), SendTTYData(u64, Vec<u8>),
SendTTYSignal(u64, u64),
StartUploadFile(PathBuf, u64), StartUploadFile(PathBuf, u64),
SendFileSegment(u64, u64, Vec<u64>), SendFileSegment(u64, u64, Vec<u64>),
@ -69,7 +70,7 @@ pub mod messages {
OpenedTTY(u64), OpenedTTY(u64),
ClosedTTY(u64), ClosedTTY(u64),
SendRawData(Vec<u64>, u64), SendTTYData(u64, Vec<u64>),
UploadFileID(u64), UploadFileID(u64),
UploadFileStatus(u64, Result<(), Vec<u64>>), UploadFileStatus(u64, Result<(), Vec<u64>>),

View File

@ -1,4 +1,5 @@
use std::{ use std::{
collections::HashMap,
net::{Ipv4Addr, UdpSocket}, net::{Ipv4Addr, UdpSocket},
sync::{ sync::{
mpsc::{channel, Receiver, Sender}, mpsc::{channel, Receiver, Sender},
@ -214,6 +215,8 @@ fn authenticate<F: Fn()>(
handle_full_connection(capabilities, packet_handler, conninfo, close) handle_full_connection(capabilities, packet_handler, conninfo, close)
} }
mod command;
fn handle_full_connection<F>( fn handle_full_connection<F>(
capabilities: Arc<Capabilities>, capabilities: Arc<Capabilities>,
packet_handler: Receiver<EthernetPacket>, packet_handler: Receiver<EthernetPacket>,
@ -223,8 +226,48 @@ fn handle_full_connection<F>(
where where
F: Fn(), F: Fn(),
{ {
use packets::*;
let mut commands = HashMap::new();
let mut uploaded_files = HashMap::new();
let mut downloaded_files = HashMap::new();
loop { loop {
let msg = packet_handler.recv()?; let msg = packet_handler.recv()?;
let pkt = msg.pkt();
let Layer3Pkt::IPv4Pkt(ip_pkt) = pkt.get_layer3_pkt()?;
let Layer4Pkt::UDP(udp_pkt) = ip_pkt.get_layer4_packet()?;
if ip_pkt.source_ip() != conninfo.srcip || udp_pkt.srcport() != conninfo.srcport {
continue;
}
let Ok(data) = conninfo.try_decrypt_and_verify_comm(udp_pkt.get_data()) else {
continue;
};
match data {
Command::RunCommand(_) => {}
Command::SendStdin(_, _) => {}
Command::Cd(_) => {}
Command::Ls(_) => {}
Command::OpenTTY => {}
Command::CloseTTY(_) => {}
Command::SendTTYData(_, _) => {}
Command::SendTTYSignal(_, _) => {}
Command::StartUploadFile(_, _) => {}
Command::SendFileSegment(_, _, _) => {}
Command::StartDownloadFile(_) => {}
Command::DownloadFileStatus(_) => {}
Command::Disconnect => {
break;
}
}
} }
close(); close();