diff --git a/src/install.rs b/src/install.rs index 43ddfe3..9dffcea 100644 --- a/src/install.rs +++ b/src/install.rs @@ -1,11 +1,12 @@ 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::fs::{File, OpenOptions, create_dir_all, remove_dir_all}; use std::io::Write; +use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; use std::process::Command; use std::process::exit; +use std::{env, fs}; use tetanus::funcs::get_user_input; pub fn install() -> Result<(), Box> { @@ -98,6 +99,7 @@ pub fn client_install() -> Result<(), Box> { 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())?; + let mut version_file = File::create(root_config_folder_path.join("version"))?; println!("\ndefault config files written!"); println!("downloading note templates, victim templates, and modules..."); create_dir_all("./temp")?; @@ -143,15 +145,66 @@ pub fn client_install() -> Result<(), Box> { .status() { if res.success() { + let base_update_string = fs::read_to_string("./tetanus_update.sh")?; + let update_string = base_update_string.replace( + "|||config|||", + &root_config_folder_path.display().to_string(), + ); + let update_path = PathBuf::from("./tetanus_update"); + let mut update_script = OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open(&update_path)?; + update_script.write(update_string.as_bytes())?; + let mut perms = fs::metadata(&update_path)?.permissions(); + perms.set_mode(0o755); + fs::set_permissions(update_path, perms)?; + let _ = Command::new("sudo") + .arg("cp") + .arg("./tetanus_update") + .arg("/usr/bin/tetanus_update") + .status(); + version_file + .write("version: 0.0.7\npath: /usr/bin/tetanus".as_bytes())?; println!("copied to path!"); println!("install completed!"); } else { eprintln!( "error copying to path. please copy this executable to your path manually." ); + eprintln!("please download the update_script to your path manually"); + eprintln!( + "sudo curl https://git.pyro.monster/pyro/tetanus/raw/branch/main/tetanus_update.sh -o /usr/bin/tetanus_update" + ); + eprintln!("sudo chmod +x /usr/bin/tetanus_update"); } } } + } else { + println!( + "Ok, we will keep the tetanus binary where it is. The tetanus_update bash script will be in the same directory." + ); + let base_update_string = fs::read_to_string("./tetanus_update.sh")?; + let update_string = base_update_string.replace( + "|||config|||", + &root_config_folder_path.display().to_string(), + ); + let mut update_path = env::current_exe()?; + update_path.pop(); + update_path.push("tetanus_update"); + let mut update_script = OpenOptions::new() + .create(true) + .truncate(true) + .write(true) + .open(&update_path)?; + update_script.write(update_string.as_bytes())?; + let mut perms = fs::metadata(&update_path)?.permissions(); + perms.set_mode(0o755); + fs::set_permissions(update_path, perms)?; + version_file.write( + format!("version: 0.0.7\npath: {}", env::current_exe()?.display()).as_bytes(), + )?; } env::set_current_dir("../")?; remove_dir_all("./temp")?; diff --git a/src/main.rs b/src/main.rs index 5f68fc5..69c3f69 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,8 @@ use clap::Parser; use keyring::Entry; use rand::RngExt; use rand::distr::Alphanumeric; +use std::fs::OpenOptions; +use std::io::{Write, read_to_string}; use std::sync::{Arc, Mutex}; use std::thread::{sleep, spawn}; use std::time::Duration; @@ -115,6 +117,30 @@ async fn main() { } } } + if let Ok(version_string) = std::fs::read_to_string(config_path.join("version")) { + version_string + .lines() + .into_iter() + .filter(|line| line.contains("path:")) + .for_each(|line| { + if let Some((_, path)) = line.split_once(" ") { + if let Ok(current_exe) = env::current_exe() { + if PathBuf::from(path) != current_exe { + let new_version_string = + version_string.replace(path, ¤t_exe.display().to_string()); + if let Ok(mut version_file) = OpenOptions::new() + .truncate(true) + .write(true) + .open(config_path.join("version")) + { + let _ = version_file.write(new_version_string.as_bytes()); + } + } + } + } + }); + } + if args.client { let banner = " XXXXXXXXXXXXXXXXXXXXXXXXXX diff --git a/tetanus_update.sh b/tetanus_update.sh new file mode 100644 index 0000000..f62f837 --- /dev/null +++ b/tetanus_update.sh @@ -0,0 +1,21 @@ +#!/bin/bash +config_path="|||CONFIG|||" +current_version=$(cat $config_path/version | grep version | cut -d " " -f 2) +path=$(cat $config_path/version | grep path | cut -d " " -f 2) +version=$(curl https://git.pyro.monster/pyro/tetanus/releases/tag/latest | grep "" | cut -d ">" -f 2 | cut -d " " -f 1) + +if [[ "$version" == "$current_version" ]]; then + echo "up to date" +else + echo "update needed" + curl https://git.pyro.monster/pyro/tetanus/releases/download/latest/tetanus -o $config_path/new_tetanus + chmod +x $config_path/new_tetanus + if [ "$(stat -c '%u' $path)" -eq 0 ]; then + sudo cp $config_path/new_tetanus $path + else + cp $config_path/new_tetanus $path + fi + echo "version: $version" > $config_path/version + echo "path: $path" >> $config_path/version + echo update complete! +fi diff --git a/update.sh b/update.sh deleted file mode 100644 index f0a322c..0000000 --- a/update.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -current_version=$(cat ./version | grep version | cut -d " " -f 2) -path=$(cat ./version | grep path | cut -d " " -f 2) -version=$(curl https://git.pyro.monster/pyro/tetanus/releases/tag/latest | grep "<title>" | cut -d ">" -f 2 | cut -d " " -f 1) - -if [[ "$version" == "$current_version" ]]; then - echo "up to date" -else - echo "update needed" - curl https://git.pyro.monster/pyro/tetanus/releases/download/latest/tetanus -o new_tetanus - chmod +x ./new_tetanus - if [ "$(stat -c '%u' $path)" -eq 0 ]; then - sudo cp ./new_tetanus $path - else - cp ./new_tetanus $path - fi - echo "version: $version" > ./version - echo "path: $path" >> ./version - echo update complete! -fi