use clap::Parser; use std::sync::{Arc, Mutex}; use std::{env, path::PathBuf, process::exit}; use tetanus::funcs::*; use tetanus::server::start_server; use tetanus::{AppState, server}; mod install; #[derive(Parser, Debug)] #[command( author, version, about = "The Tetanus Redteaming tool. This will start the client, server, or both" )] struct Args { #[arg(short, long, help = "start in client mode")] client: bool, #[arg(short, long, help = "start in server mode")] server: bool, #[arg(short, long, help = "start gui client")] gui: bool, #[arg(short, long, help = "for testing stuff...")] test: bool, #[arg( short, long, help = "The IP address for the server, in server mode it will listen on this IP, in client mode it will add this ip as its first server. Default is 127.0.0.1" )] ip: Option, #[arg( short, long, help = "The port for the server, in server mode this will be the port the server listens on, in client mode this will be the default server port it connects to." )] port: Option, #[arg( short = 'C', long, help = "Custom Config file. Give the path to a config file to use." )] config: Option, } #[tokio::main] async fn main() { println!("checking for server or client config files..."); let args = Args::parse(); let mut config_path = PathBuf::new(); let mut config_path_opt = env::home_dir(); if let Some(given_config_path) = args.config { config_path = given_config_path.clone(); } else if let Some(home_config_path) = config_path_opt.as_mut() { println!("made it to home_config_path"); home_config_path.push(".config/tetanus"); if !home_config_path.exists() { println!("no config directory found in home directory..."); config_path = PathBuf::from("/etc/tetanus"); if !config_path.exists() { println!("no config directory found in /etc/tetanus... Installing!"); let install_result = install::install(); if install_result.is_ok() { install_result.unwrap(); println!("install succeeded!"); exit(0); } } } else { println!("found home config_path."); config_path = home_config_path.clone(); } } let mut client_config_path = config_path.clone(); client_config_path.push("client.conf"); if args.client { if !client_config_path.exists() { eprintln!( "error: no client config path found at {}", client_config_path.display() ); exit(1); } let (mut appstate, rx) = AppState::new(); let config_load = appstate.load_config(client_config_path.clone()); if config_load.is_err() { eprintln!("error loading config!"); exit(1); } appstate.initialize_modules(); println!("entering tui..."); let _res = run_tui(appstate, rx).unwrap(); } else if args.server { let mut address = "127.0.0.1:31337".to_string(); let mut certificate_path = config_path.clone(); certificate_path.push("server"); let mut key_path = certificate_path.clone(); certificate_path.push("cert.pem"); key_path.push("key.pem"); println!("key paht: {}", key_path.display()); println!("cert path: {}", certificate_path.display()); if let Some(ip) = args.ip { if let Some(port) = args.port { address = format!("{}:{}", ip.trim(), port.trim()); } } let new_server = server::Server { address, clients: Vec::new(), certificate_path, key_path, }; let res = start_server(Arc::new(Mutex::new(new_server))).await; match res { Ok(_) => {} Err(e) => { println!("error running server {e}"); } } } }