mirror of
https://github.com/Astatin3/unshell-nodes-rs.git
synced 2026-06-08 16:18:08 -06:00
binary data transfer, begin CLI, packet routing
This commit is contained in:
+55
-25
@@ -1,21 +1,29 @@
|
||||
use std::{io::Write, net::SocketAddr};
|
||||
|
||||
use unshell_rs_lib::{
|
||||
Error,
|
||||
connection::{ConnectionConfig, Node},
|
||||
nodes::{ConnectionConfig, Node},
|
||||
};
|
||||
|
||||
use crate::C2Packet;
|
||||
|
||||
pub struct Cli;
|
||||
|
||||
impl Cli {
|
||||
pub fn connect(
|
||||
id: String,
|
||||
clients: Vec<ConnectionConfig>,
|
||||
listeners: Vec<ConnectionConfig>,
|
||||
) -> Result<(), Error> {
|
||||
pub fn connect(socket: SocketAddr) -> Result<(), Error> {
|
||||
// let mut client = build_client(TCPClient::connect(&addr)?, vec![])?;
|
||||
|
||||
// let stdin = std::io::stdin();
|
||||
// let mut stdout = std::io::stdout();
|
||||
let stdin = std::io::stdin();
|
||||
let mut stdout = std::io::stdout();
|
||||
|
||||
Node::run_node(id, clients, listeners)
|
||||
let node = Node::<C2Packet>::run_node(
|
||||
"Client".to_string(),
|
||||
vec![ConnectionConfig {
|
||||
socket,
|
||||
layers: vec![],
|
||||
}],
|
||||
vec![],
|
||||
)?;
|
||||
|
||||
// let mut client_clone = client.try_clone()?;
|
||||
// thread::spawn(move || {
|
||||
@@ -48,24 +56,46 @@ impl Cli {
|
||||
// }
|
||||
// });
|
||||
|
||||
// loop {
|
||||
// print!("> ");
|
||||
// stdout.flush()?;
|
||||
let selected_node: Option<usize> = None;
|
||||
|
||||
// let mut input = String::new();
|
||||
// stdin.read_line(&mut input)?;
|
||||
// let input = input.trim();
|
||||
loop {
|
||||
print!("> ");
|
||||
stdout.flush()?;
|
||||
|
||||
// match input.split(" ").nth(0).unwrap() {
|
||||
// "ping" => {
|
||||
// // client.write(Packets::GetConnections.encode()?.as_str())?;
|
||||
// }
|
||||
// _ => {
|
||||
// warn!("Invalid command!")
|
||||
// }
|
||||
// }
|
||||
let mut input = String::new();
|
||||
stdin.read_line(&mut input)?;
|
||||
let input = input.trim();
|
||||
|
||||
// // client.write(input)?;
|
||||
// }
|
||||
let mut node_state = node.state.lock().unwrap();
|
||||
|
||||
let mut split = input.split(" ");
|
||||
|
||||
match split.next().unwrap() {
|
||||
"nodes" => {
|
||||
for (i, node) in node_state.get_all_nodes().iter().enumerate() {
|
||||
println!("{} -> {}", i, node);
|
||||
}
|
||||
}
|
||||
"ping" => {
|
||||
// if split.count().clone() <= 1 {
|
||||
// warn!("You must specify an option");
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if let Ok(i) = str::parse::<usize>(split.next().unwrap()) {
|
||||
let nodes = node_state.get_all_nodes();
|
||||
let node = nodes.get(i).unwrap().clone();
|
||||
node_state.send_unrouted(node, &C2Packet::Aa).unwrap();
|
||||
} else {
|
||||
println!("");
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
warn!("Invalid command!")
|
||||
}
|
||||
}
|
||||
|
||||
// client.write(input)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use unshell_rs_lib::{
|
||||
Error,
|
||||
nodes::{ConnectionConfig, Node},
|
||||
};
|
||||
|
||||
use crate::C2Packet;
|
||||
|
||||
pub fn run_endpoint(socket: SocketAddr) -> Result<(), Error> {
|
||||
let node = Node::<C2Packet>::run_node(
|
||||
"Server".to_string(),
|
||||
vec![],
|
||||
vec![ConnectionConfig {
|
||||
socket,
|
||||
layers: vec![],
|
||||
}],
|
||||
)?;
|
||||
|
||||
loop {
|
||||
match node.rx.recv()? {
|
||||
C2Packet::Aa => {
|
||||
info!("1");
|
||||
}
|
||||
C2Packet::Bb => {
|
||||
info!("2");
|
||||
}
|
||||
C2Packet::Cc => {
|
||||
info!("3");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
mod endpoint;
|
||||
|
||||
pub use endpoint::run_endpoint;
|
||||
+6
-2
@@ -1,11 +1,15 @@
|
||||
// #[macro_use]
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
mod client;
|
||||
// mod server;
|
||||
mod endpoint;
|
||||
mod packets;
|
||||
|
||||
pub use client::Cli;
|
||||
|
||||
pub use endpoint::run_endpoint;
|
||||
pub use packets::C2Packet;
|
||||
|
||||
// pub use client::UnshellClient;
|
||||
// pub use client::UnshellGui;
|
||||
// pub use server::UnshellServer;
|
||||
|
||||
+114
-115
@@ -7,8 +7,8 @@ use std::{
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
use log::error;
|
||||
use unshell_rs::Cli;
|
||||
use unshell_rs_lib::connection::ConnectionConfig;
|
||||
use unshell_rs::{Cli, run_endpoint};
|
||||
use unshell_rs_lib::nodes::ConnectionConfig;
|
||||
|
||||
pub static DEFAULT_CONFIG_FILEPATH: &'static str = "server_config.json";
|
||||
|
||||
@@ -30,42 +30,32 @@ struct Args {
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
enum Commands {
|
||||
// Start,
|
||||
// Middle,
|
||||
// End,
|
||||
//
|
||||
Test1,
|
||||
Test2,
|
||||
Test3,
|
||||
Test4,
|
||||
Test5,
|
||||
Test6,
|
||||
// Run as a service, and potentially hosting a website
|
||||
// #[command(arg_required_else_help = true)]
|
||||
// Relay {
|
||||
// /// IPv4 to listen for clients on.
|
||||
// host: String,
|
||||
Relay {
|
||||
/// IPv4 to listen for clients on.
|
||||
#[arg(short, long, default_value_t = ("0.0.0.0".to_string()))]
|
||||
host: String,
|
||||
|
||||
// /// Port listen to for command clients
|
||||
// #[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
||||
// port: u16,
|
||||
/// Port listen to for command clients
|
||||
#[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
||||
port: u16,
|
||||
|
||||
// /// Json file to store config
|
||||
// #[arg(short, long, default_value_t = DEFAULT_CONFIG_FILEPATH.to_string())]
|
||||
// config_filepath: String,
|
||||
// // /// Port to listen for website traffic (0 is disabled)
|
||||
// // #[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
||||
// // web_port: u16,
|
||||
// },
|
||||
// /// Connect to remote server
|
||||
// Connect {
|
||||
// /// Remote server to connect to
|
||||
// host: String,
|
||||
/// Json file to store config
|
||||
#[arg(short, long, default_value_t = DEFAULT_CONFIG_FILEPATH.to_string())]
|
||||
config_filepath: String,
|
||||
// /// Port to listen for website traffic (0 is disabled)
|
||||
// #[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
||||
// web_port: u16,
|
||||
},
|
||||
/// Connect to remote server
|
||||
Connect {
|
||||
/// Remote server to connect on
|
||||
host: String,
|
||||
|
||||
// /// Port listen to for command clients
|
||||
// #[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
||||
// port: u16,
|
||||
// },
|
||||
#[arg(short, long, default_value_t = DEFAULT_SERVICE_PORT)]
|
||||
/// Port listen to for command clients
|
||||
port: u16,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn Error>> {
|
||||
@@ -83,87 +73,96 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
// error!("{}", e);
|
||||
// }
|
||||
// }
|
||||
Commands::Test1 {} => Cli::connect(
|
||||
"Test1".to_string(),
|
||||
vec![],
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
),
|
||||
Commands::Test2 {} => Cli::connect(
|
||||
"Test2".to_string(),
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
),
|
||||
Commands::Test3 {} => Cli::connect(
|
||||
"Test3".to_string(),
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13373")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
),
|
||||
Commands::Test4 {} => Cli::connect(
|
||||
"Test4".to_string(),
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13374")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
),
|
||||
Commands::Test5 {} => Cli::connect(
|
||||
"Test5".to_string(),
|
||||
vec![
|
||||
ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
||||
layers: vec![],
|
||||
},
|
||||
ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13374")?,
|
||||
layers: vec![],
|
||||
},
|
||||
],
|
||||
vec![ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13375")?,
|
||||
layers: vec![],
|
||||
}],
|
||||
),
|
||||
Commands::Test6 {} => Cli::connect(
|
||||
"Test6".to_string(),
|
||||
vec![
|
||||
ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13373")?,
|
||||
layers: vec![],
|
||||
},
|
||||
ConnectionConfig {
|
||||
socket: SocketAddr::from_str("127.0.0.1:13375")?,
|
||||
layers: vec![],
|
||||
},
|
||||
],
|
||||
vec![],
|
||||
),
|
||||
// Commands::Connect { host, port } => {
|
||||
// let addr = SocketAddr::from_str(format!("{}:{}", host, port).as_str());
|
||||
// Cli::connect(if let Ok(addr) = addr {
|
||||
// addr
|
||||
// } else {
|
||||
// error!("Could not parse address!");
|
||||
// return Ok(());
|
||||
// })
|
||||
// }
|
||||
// Commands::Test1 {} => Cli::connect(
|
||||
// "Test1".to_string(),
|
||||
// vec![],
|
||||
// vec![ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
||||
// layers: vec![],
|
||||
// }],
|
||||
// ),
|
||||
// Commands::Test2 {} => Cli::connect(
|
||||
// "Test2".to_string(),
|
||||
// vec![ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
||||
// layers: vec![],
|
||||
// }],
|
||||
// vec![ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
||||
// layers: vec![],
|
||||
// }],
|
||||
// ),
|
||||
// Commands::Test3 {} => Cli::connect(
|
||||
// "Test3".to_string(),
|
||||
// vec![ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
||||
// layers: vec![],
|
||||
// }],
|
||||
// vec![],
|
||||
// ), // Commands::Test4 {} => Cli::connect(
|
||||
// "Test4".to_string(),
|
||||
// vec![ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13371")?,
|
||||
// layers: vec![],
|
||||
// }],
|
||||
// vec![ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13374")?,
|
||||
// layers: vec![],
|
||||
// }],
|
||||
// ),
|
||||
// Commands::Test5 {} => Cli::connect(
|
||||
// "Test5".to_string(),
|
||||
// vec![
|
||||
// ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13372")?,
|
||||
// layers: vec![],
|
||||
// },
|
||||
// ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13374")?,
|
||||
// layers: vec![],
|
||||
// },
|
||||
// ],
|
||||
// vec![ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13375")?,
|
||||
// layers: vec![],
|
||||
// }],
|
||||
// ),
|
||||
// Commands::Test6 {} => Cli::connect(
|
||||
// "Test6".to_string(),
|
||||
// vec![
|
||||
// ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13373")?,
|
||||
// layers: vec![],
|
||||
// },
|
||||
// ConnectionConfig {
|
||||
// socket: SocketAddr::from_str("127.0.0.1:13375")?,
|
||||
// layers: vec![],
|
||||
// },
|
||||
// ],
|
||||
// vec![],
|
||||
// ),
|
||||
Commands::Connect { host, port } => {
|
||||
let addr = SocketAddr::from_str(format!("{}:{}", host, port).as_str());
|
||||
Cli::connect(if let Ok(addr) = addr {
|
||||
addr
|
||||
} else {
|
||||
error!("Could not parse address!");
|
||||
return Ok(());
|
||||
})
|
||||
}
|
||||
Commands::Relay {
|
||||
host,
|
||||
port,
|
||||
config_filepath,
|
||||
} => {
|
||||
let addr = SocketAddr::from_str(format!("{}:{}", host, port).as_str());
|
||||
run_endpoint(if let Ok(addr) = addr {
|
||||
addr
|
||||
} else {
|
||||
error!("Could not parse address!");
|
||||
return Ok(());
|
||||
})
|
||||
}
|
||||
} {
|
||||
error!("{}", e);
|
||||
};
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
mod cli;
|
||||
|
||||
pub use cli::Cli;
|
||||
@@ -0,0 +1,8 @@
|
||||
use bincode::{Decode, Encode};
|
||||
|
||||
#[derive(Debug, Encode, Decode, Clone)]
|
||||
pub enum C2Packet {
|
||||
Aa,
|
||||
Bb,
|
||||
Cc,
|
||||
}
|
||||
Reference in New Issue
Block a user