use fs_extra::dir::{CopyOptions, copy}; use std::env; use std::error::Error; use std::fs::{File, create_dir_all, remove_dir_all}; use std::io::Write; use std::path::PathBuf; use std::process::Command; use std::process::exit; use tetanus::funcs::get_user_input; pub fn install() -> Result<(), Box> { let client = get_user_input("would you like to install the Tetanus on this computer?")?.contains("y"); if client { client_install()?; println!( " " ) } else { println!("Ok then bye... not sure what you wanted here..."); } return Ok(()); } pub fn client_install() -> Result<(), Box> { if let Some(homedir) = env::home_dir() { let mut config_path = homedir.clone(); config_path.push(".config/tetanus"); let root_config_folder_path = config_path.clone(); let mut projects_path = config_path.clone(); projects_path.push("projects"); let mut module_path = config_path.clone(); module_path.push("modules"); let mut note_templates_path = config_path.clone(); note_templates_path.push("note_templates"); create_dir_all(&module_path)?; let current_files_path = PathBuf::from(get_user_input( "enter the path to store currently in progress project files (not notes), or none if you want to be propted everytime", )?); let current_notes_path = PathBuf::from(get_user_input( "enter the path to store currently in progress project notes, or none if you want to be prompted everytime", )?); let upcoming_files_path = PathBuf::from(get_user_input( "enter the path to store upcoming project files (not notes) or none if you want to be prompted everytime", )?); let upcoming_notes_path = PathBuf::from(get_user_input( "enter the path to store upcoming project notes, or none if you want to be prompted everytime", )?); let template_box = get_user_input( "enter the name of your template distrobox, NONE in all caps if you are not using distrobox", )?; println!( "enter the command used to launch your terminal while running a command. Put the place holder |||COMMAND||| where the command would go" ); println!( "if you use a profile to launch the distroboxes, and that profile needs the box name as an environment variable put ENV_NAME= then the name of the variable you use at the end of the command" ); let term_cmd = get_user_input( "for example: konsole -e |||COMMAND||| or konsole --profile profile_name ENV_NAME=CURRENT_PROJECT_BOX", )?; let tools_folder = get_user_input("path where your tools are installed ex /opt or /home/user/tools")?; config_path.push("client.conf"); projects_path.push("default"); create_dir_all(&projects_path)?; projects_path.push("project.conf"); let mut client_config_file = File::create(&config_path)?; client_config_file.write(format!("projects: {}\n", projects_path.display()).as_bytes())?; client_config_file.write("servers: 127.0.0.1:31337\n".as_bytes())?; let mut default_project_file = File::create(projects_path)?; config_path.pop(); let mut server_path = config_path.clone(); server_path.push("server"); create_dir_all(&server_path)?; server_path.push("server.conf"); let mut server_config_file = File::create(&server_path)?; server_config_file.write("address: 127.0.0.1:31337\n".as_bytes())?; server_config_file.write("running: false\n".as_bytes())?; default_project_file.write("org_name: default\n".as_bytes())?; default_project_file.write("name: default\n".as_bytes())?; default_project_file .write(format!("notes: {}\n", current_files_path.display()).as_bytes())?; default_project_file .write(format!("files: {}\n", current_notes_path.display()).as_bytes())?; default_project_file.write("stage: current".as_bytes())?; client_config_file .write(format!("current_files: {}\n", current_files_path.display()).as_bytes())?; client_config_file .write(format!("current_notes: {}\n", current_notes_path.display()).as_bytes())?; client_config_file .write(format!("upcoming_files: {}\n", upcoming_files_path.display()).as_bytes())?; client_config_file .write(format!("upcoming_notes: {}\n", upcoming_notes_path.display()).as_bytes())?; client_config_file.write(format!("module_path: {}\n", module_path.display()).as_bytes())?; client_config_file.write(format!("template_box: {}\n", template_box).as_bytes())?; client_config_file.write(format!("term_cmd: {}\n", term_cmd).as_bytes())?; client_config_file.write(format!("tools: {}\n", tools_folder).as_bytes())?; client_config_file.write("alternate_configs: \n".as_bytes())?; println!("\ndefault config files written!"); println!("downloading note templates, victim templates, and modules..."); create_dir_all("./temp")?; env::set_current_dir("./temp")?; let git_clone_status = Command::new("git") .arg("clone") .arg("https://git.pyro.monster/pyro/tetanus.git") .status()? .success(); if git_clone_status { let mut options = CopyOptions::new(); options.overwrite = true; options.copy_inside = true; println!("copying note_templates..."); copy( "./tetanus/note_templates", root_config_folder_path.clone(), &options, )?; println!("copying default-modules..."); copy( "./tetanus/default-modules", module_path.join("default"), &options, )?; println!("copying default victim templates..."); copy( "./tetanus/victim_templates", root_config_folder_path.join("victim"), &options, )?; if get_user_input( "do you want to copy tetanus to your path so you can run it anywhere?", )? .contains("y") { println!("this will require sudo. Please complete the following sudo prompt."); if let Ok(exe_path) = env::current_exe() { if let Ok(res) = Command::new("sudo") .arg("cp") .arg(exe_path.display().to_string()) .arg("/usr/bin/tetanus") .status() { if res.success() { println!("copied to path!"); println!("install completed!"); } else { eprintln!( "error copying to path. please copy this executable to your path manually." ); } } } } env::set_current_dir("../")?; remove_dir_all("./temp")?; } } else { eprintln!("error finding home directory!"); exit(1); } return Ok(()); }