Update main.rs

removed hour counting stuff, because it was dumb, and re-worked how it finds the save folders so it doesn't dynamically build them, instead saves them in the settings.  Also re-worked the install script to be better.
This commit is contained in:
Pyro57000
2024-06-11 19:25:50 +00:00
committed by GitHub
parent f383c8b592
commit ec351f733b

View File

@@ -3,9 +3,7 @@ use std::fs;
use std::io::Write; use std::io::Write;
use std::path::PathBuf; use std::path::PathBuf;
use std::process; use std::process;
use std::time; use std::str::FromStr;
use std::time::Duration;
use std::time::SystemTime;
use clearscreen::clear; use clearscreen::clear;
use directories::UserDirs; use directories::UserDirs;
use clearscreen; use clearscreen;
@@ -16,8 +14,6 @@ struct Project{
project_name: String, project_name: String,
notes_folder: PathBuf, notes_folder: PathBuf,
files_folder: PathBuf, files_folder: PathBuf,
activativation_time: SystemTime,
hour_count: Duration,
active: bool, active: bool,
boxname: String, boxname: String,
id: i32, id: i32,
@@ -29,22 +25,45 @@ fn install(config_path: &PathBuf){
let mut config_folder_path: PathBuf = config_path.clone(); let mut config_folder_path: PathBuf = config_path.clone();
config_folder_path.pop(); config_folder_path.pop();
let mut projects_conf_path = config_folder_path.clone(); let mut projects_conf_path = config_folder_path.clone();
let del_on_fail = config_folder_path.clone();
projects_conf_path.push("projects.conf"); projects_conf_path.push("projects.conf");
fs::create_dir_all(config_folder_path).expect("error creating config dir"); fs::create_dir_all(config_folder_path).expect("error creating config dir");
let mut config_file = fs::File::create(config_path).expect("error creating file"); let mut config_file = fs::File::create(config_path).expect("error creating file");
let mut projects_conf_file = fs::File::create(projects_conf_path).expect("error creating projects config file"); let mut projects_conf_file = fs::File::create(projects_conf_path).expect("error creating projects config file");
projects_conf_file.write_all(b"customer:name:time").expect("error writing default project info"); projects_conf_file.write_all(b"customer:name:notes:files:active:box_name\n").expect("error writing default project info");
let mut notes_response = String::new(); let mut notes_response = String::new();
let mut files_response = String::new(); let mut files_response = String::new();
let mut tools_response = String::new(); let mut tools_response = String::new();
let mut template_name = String::new();
let mut have_template = String::new();
println!("path to save project notes?"); println!("path to save project notes?");
std::io::stdin().read_line(&mut notes_response).unwrap(); std::io::stdin().read_line(&mut notes_response).unwrap();
println!("path to save project files?"); println!("path to save project files?");
std::io::stdin().read_line(&mut files_response).unwrap(); std::io::stdin().read_line(&mut files_response).unwrap();
println!("path to folder with your custom tools?"); println!("path to folder with your custom tools?");
std::io::stdin().read_line(&mut tools_response).unwrap(); std::io::stdin().read_line(&mut tools_response).unwrap();
print!("
This tool is mainly to handle distrobox creation and usage.
It's expecting you to have a distrobox that you will use as a template.
Do you have a distrobox set up to function as your template for all new projects?
");
std::io::stdin().read_line(&mut have_template).unwrap();
if have_template.contains("n"){
println!("please set up a distrobox with root as a template and re-run this tool");
println!("example distrobox setup command:");
println!("distrobox create --root --image archlinux --name template");
println!("then enter that distrobox and install all the tools you want and do what ever setup you need");
println!("and re-run this tool.");
process::Command::new("rm").arg(del_on_fail).spawn().expect("ERROR deleting config folder, please manually clean up");
std::process::exit(1);
}
let _list = process::Command::new("distrobox").arg("list").arg("--root").status();
println!("distrobox template name?");
std::io::stdin().read_line(&mut template_name).unwrap();
let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end()); let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end());
config_file.write_all(config_string.as_bytes()).expect("error writing to config file"); config_file.write_all(config_string.as_bytes()).expect("error writing to config file");
let default_projectline = format!("default:default:{}:{}:yes:{}", &notes_response.trim_end(), &files_response.trim_end(), &template_name.trim_end());
projects_conf_file.write_all(default_projectline.as_bytes()).expect("error writing default project line");
println!("config file generated and saved to {}\n", config_path.display()); println!("config file generated and saved to {}\n", config_path.display());
println!("please make sure to install distrobox:\nhttps://github.com/89luca89/distrobox\n\nthis will require either docker or podman as well.\n\n"); println!("please make sure to install distrobox:\nhttps://github.com/89luca89/distrobox\n\nthis will require either docker or podman as well.\n\n");
println!("please rerun the program"); println!("please rerun the program");
@@ -52,7 +71,7 @@ fn install(config_path: &PathBuf){
} }
fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut PathBuf) -> Vec<Project>{ fn get_projects(config_path: &mut PathBuf) -> Vec<Project>{
config_path.pop(); config_path.pop();
config_path.push("projects.conf"); config_path.push("projects.conf");
let mut projects = Vec::new(); let mut projects = Vec::new();
@@ -66,22 +85,17 @@ fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut Pa
let settings: Vec<&str> = line.split(":").collect(); let settings: Vec<&str> = line.split(":").collect();
let customer = settings[0].to_owned(); let customer = settings[0].to_owned();
let project = settings[1].to_owned(); let project = settings[1].to_owned();
let folder_name = format!("{}/{}", customer, project); let notes_string = settings[2].to_owned();
let mut notes_folder = base_notes.clone(); let folder_string = settings[3].to_owned();
let mut project_folder = base_files.clone(); let notes_folder = PathBuf::from_str(&notes_string.trim_end()).expect("error reading notes string");
notes_folder.push(&folder_name); let project_folder = PathBuf::from_str(&folder_string.trim_end()).expect("error reading folding sering");
project_folder.push(&folder_name);
let hours_count:u64 = settings[3].trim_end().parse().expect("error converting to u64");
let secs_count = hours_count * 60;
let hours = Duration::from_secs(secs_count);
let mut active = false; let mut active = false;
let boxname = settings[4].to_owned(); let boxname = settings[5].to_owned();
if settings[2] == "yes"{ if settings[4] == "yes"{
env::set_var("CURRENT_PROJECT_BOX", boxname.clone()); env::set_var("CURRENT_PROJECT_BOX", boxname.clone());
active = true; active = true;
} }
let time = SystemTime::now(); let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, active: active, id: first, boxname: boxname};
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, activativation_time: time, hour_count: hours, active: active, id: first, boxname: boxname};
println!("{} {} LOADED!", &new_project.customer, &new_project.project_name); println!("{} {} LOADED!", &new_project.customer, &new_project.project_name);
projects.push(new_project); projects.push(new_project);
} }
@@ -127,16 +141,15 @@ fn save_projects(projects: &Vec<Project>, config_path: &PathBuf){
save_file_path.pop(); save_file_path.pop();
save_file_path.push("projects.conf"); save_file_path.push("projects.conf");
let mut save_file = fs::File::create(save_file_path).expect("error creating save_file"); let mut save_file = fs::File::create(save_file_path).expect("error creating save_file");
save_file.write_all(b"customer:name:active:hours:box_name\n").expect("error writing first line to file"); save_file.write_all(b"customer:name:notes:files:active:time:box_name\n").expect("error writing first line to file");
for project in projects{ for project in projects{
let default = format!{"{}:{}:", project.customer, project.project_name}; let default = format!{"{}:{}:{}:{}:", project.customer, project.project_name, project.notes_folder.display(), project.files_folder.display()};
let mut _outline = String::new(); let mut _outline = String::new();
if project.active{ if project.active{
let hours = project.hour_count.as_secs()/60 + time::SystemTime::now().duration_since(project.activativation_time).expect("error caclucating hours").as_secs()/60; _outline = format!("{}yes:{}\n", default, project.boxname);
_outline = format!("{}yes:{}:{}\n", default, hours, project.boxname);
} }
else{ else{
_outline = format!("{}no:{}:{}\n", default, project.hour_count.as_secs()/60, project.boxname); _outline = format!("{}no:{}\n", default, project.boxname);
} }
save_file.write_all(_outline.as_bytes()).expect("error writing outline"); save_file.write_all(_outline.as_bytes()).expect("error writing outline");
} }
@@ -231,6 +244,10 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
else{ else{
println!("failed to copy the notes folder, try to move it manually!"); println!("failed to copy the notes folder, try to move it manually!");
} }
new_project_dir.push(&customer_name);
new_note_dir.push(&customer_name);
new_project_dir.push(&project_name);
new_note_dir.push(&project_name);
} }
else{ else{
@@ -240,9 +257,12 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
new_note_dir.push(&project_name); new_note_dir.push(&project_name);
fs::create_dir_all(&new_project_dir).expect("error creating new files folder"); fs::create_dir_all(&new_project_dir).expect("error creating new files folder");
fs::create_dir_all(&new_note_dir).expect("error creating new notes folder"); fs::create_dir_all(&new_note_dir).expect("error creating new notes folder");
} }
let box_name = format!("atarchbox_{}", customer_name); let box_name = format!("atarchbox_{}", customer_name);
let mut box_name_path = new_project_dir.clone();
box_name_path.push("boxname");
let mut box_name_file = fs::File::create(box_name_path).expect("Error creating box name file");
box_name_file.write_all(&box_name.as_bytes()).expect("error writing boxname to box file");
let pentest_volume = format!("{}:/pentest:rw", new_project_dir.display()); let pentest_volume = format!("{}:/pentest:rw", new_project_dir.display());
let toold_volume = format!("{}:/tools:rw", tools_dir.display()); let toold_volume = format!("{}:/tools:rw", tools_dir.display());
println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, toold_volume, pentest_volume, box_name); println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, toold_volume, pentest_volume, box_name);
@@ -265,6 +285,13 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
.arg("enter") .arg("enter")
.arg("--root") .arg("--root")
.arg(&box_name) .arg(&box_name)
.arg("--")
.arg("sudo")
.arg("-s")
.arg("ln")
.arg("-sf")
.arg("/pentest/boxname")
.arg("/etc/boxname")
.status() .status()
.expect("error getting response from distrobox start"); .expect("error getting response from distrobox start");
if distrobox_start_result.success(){ if distrobox_start_result.success(){
@@ -281,8 +308,6 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
project_name: project_name.trim_end().to_owned(), project_name: project_name.trim_end().to_owned(),
notes_folder: new_note_dir, notes_folder: new_note_dir,
files_folder:new_project_dir, files_folder:new_project_dir,
activativation_time: SystemTime::now(),
hour_count: Duration::new(1, 1),
active: false, active: false,
id: new_id, id: new_id,
boxname: box_name, boxname: box_name,
@@ -307,11 +332,12 @@ fn remove_project(projects: &mut Vec<Project>){
if project.id == remove_id{ if project.id == remove_id{
println!("will remove {} {}", project.customer, project.project_name); println!("will remove {} {}", project.customer, project.project_name);
project_set = true; project_set = true;
let _distrobox_stop_status = process::Command::new("distrobox").arg("stop").arg("--root").arg(&project.boxname).status().expect("error stopping distrobox");
let distrobox_rm_status = process::Command::new("distrobox") let distrobox_rm_status = process::Command::new("distrobox")
.arg("rm") .arg("rm")
.arg("--root") .arg("--root")
.arg("-f") .arg("-f")
.arg(project.boxname) .arg(&project.boxname)
.status().expect("error calling distrobox"); .status().expect("error calling distrobox");
if distrobox_rm_status.success(){ if distrobox_rm_status.success(){
println!("Distrobox Removal Successful!!!"); println!("Distrobox Removal Successful!!!");
@@ -410,14 +436,6 @@ fn print_report_information(project: Project){
} }
fn reset_hour_counters(projects: &mut Vec<Project>){
println!("Clearing Counters, please esure these times are in sales force...");
for project in projects{
println!("{} {}: {}", project.customer, project.project_name, project.hour_count.as_secs()/60/60);
project.hour_count = Duration::ZERO;
}
}
fn project_standalone_terminal(project: Project){ fn project_standalone_terminal(project: Project){
@@ -430,6 +448,32 @@ fn project_inline_terminal(project: Project){
} }
fn gnerate_userpass(project: &Project){
let mut outlines = Vec::new();
let mut notes_file = project.notes_folder.clone();
notes_file.push("l00t/creds.md");
let loot_string = fs::read_to_string(notes_file).expect("error reading creds note");
let clear_text = loot_string.split("# hashed").collect::<Vec<&str>>()[0];
let clear_text_table = clear_text.split("| ----------------------------------- | ------------- | ----------------------------- |").collect::<Vec<&str>>()[1];
let table_vec: Vec<&str> = clear_text_table.split("\n").collect();
for line in table_vec{
if line.len() > 1{
let split_line: Vec<&str> = line.split("|").collect();
let user = split_line[2].trim_end().trim_start();
let password = split_line[3].trim_end().trim_start();
let outline = format!("{}:{}\n", user, password);
outlines.push(outline);
}
}
let mut out_file_path = project.files_folder.clone();
out_file_path.push("working/userpass_fromnotes.txt");
let mut out_file = fs::File::create(out_file_path).expect("error creating userpass file");
for line in outlines{
out_file.write_all(line.as_bytes()).expect("error writing to userpass file");
}
}
fn main_menu(mut projects: Vec<Project>, config_path: &PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String){ fn main_menu(mut projects: Vec<Project>, config_path: &PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String){
let mut loopize = true; let mut loopize = true;
loop { loop {
@@ -487,27 +531,24 @@ NOTE SAVE PROJECT INFO BEFORE STOPPING THE APPLICATION, OR HOUR TRACKIGN WON'T B
NOTE OPTION 10 WILL SAVE YOUR PROJECTS BEFORE QUITTING NOTE OPTION 10 WILL SAVE YOUR PROJECTS BEFORE QUITTING
Current Project: {} {} Current Project: {} {}
Current Minutes: {} minutes
Main Menu: Main Menu:
1 .) Show Active Project 1 .) Show Active Project
2 .) List Projects 2 .) List Projects
3 .) Switch Active Project 3 .) Switch Active Project
4 .) Print Active Project Time 4 .) create new project with Pyro's default tool
5 .) Print All Proejct Times 5 .) Save Project Information
6 .) create new project with Pyro's default tool 6 .) Import New Project - and setup new Distrobox
7 .) Save Project Information 7 .) Remove Project
8 .) Import New Project - and setup new Distrobox 8 .) Open A New Terminal in Current Active Project
9 .) Remove Project 9 .) Open A Terminal In this windows for the current active project
10.) Open A New Terminal in Current Active Project 10.) Open Project Files Folder In Dolphin
11.) Open A Terminal In this windows for the current active project 11.) Open Project Notes Folder In Dolphin
12.) Open Project Files Folder In Dolphin 12.) generate userpass file from your obsidian notes
13.) Open Project Notes Folder In Dolphin 13.) Print Project Info For Report
14.) Print Project Info For Report 14.) Stop All Distroboxes
15.) Stop All Distroboxes 15.) Quit Application
16.) Reset Hour Counters \n", active_project.customer, active_project.project_name);
17.) Quit Application
\n", active_project.customer, active_project.project_name, SystemTime::now().duration_since(active_project.activativation_time).unwrap().as_secs() / 60);
std::io::stdin().read_line(&mut response).expect("error getting menu input"); std::io::stdin().read_line(&mut response).expect("error getting menu input");
clear().expect("error clearing screen"); clear().expect("error clearing screen");
match response.as_str().trim_end(){ match response.as_str().trim_end(){
@@ -517,30 +558,18 @@ Current Minutes: {} minutes
println!("++{}|{}++",project.customer ,project.project_name)} println!("++{}|{}++",project.customer ,project.project_name)}
println!("++++++++++++++++++++")}, println!("++++++++++++++++++++")},
"3" => switch_project(&mut projects), "3" => switch_project(&mut projects),
"4" => println!("current Hour Count: {}", active_project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(active_project.activativation_time).expect("error caclucating hours").as_secs()/3600), "4" => start_pentest(),
"5" => {println!("++++++++++++++++++++"); "5" => save_projects(&projects, &config_path),
for project in &projects{ "6" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate),
if project.active == true{ "7" => remove_project(&mut projects),
println!("++{} {}: {}++", project.customer, project.project_name, project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(project.activativation_time).expect("error caclucating hours").as_secs()/3600); "8" => project_standalone_terminal(active_project.clone()),
} "9" => project_inline_terminal(active_project.clone()),
else{ "10" => open_in_dolphin("files", active_project.clone()),
println!("++{} {}:{}++", project.customer, project.project_name, project.hour_count.as_secs()/3600); "11" => open_in_dolphin("notes", active_project.clone()),
} "12" => gnerate_userpass(&active_project),
} "13" => print_report_information(active_project.clone()),
println!("++++++++++++++++++++") "14" => stop_all_boxes(&projects),
}, "15" => {save_projects(&projects, &config_path);
"6" => start_pentest(),
"7" => save_projects(&projects, &config_path),
"8" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate),
"9" => remove_project(&mut projects),
"10" => project_standalone_terminal(active_project.clone()),
"11" => project_inline_terminal(active_project.clone()),
"12" => open_in_dolphin("files", active_project.clone()),
"13" => open_in_dolphin("notes", active_project.clone()),
"14" => print_report_information(active_project.clone()),
"15" => stop_all_boxes(&projects),
"16" => reset_hour_counters(&mut projects),
"17" => {save_projects(&projects, &config_path);
let mut stop = String::new(); let mut stop = String::new();
println!("stop all boxes?\ny/n"); println!("stop all boxes?\ny/n");
std::io::stdin().read_line(&mut stop).unwrap(); std::io::stdin().read_line(&mut stop).unwrap();
@@ -613,7 +642,7 @@ fn main() {
distrobox template: {}\n distrobox template: {}\n
", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template); ", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template);
println!("loading project configs..."); println!("loading project configs...");
let projects = get_projects(&project_base_notes, &project_base_folder, &mut config_path); let projects = get_projects(&mut config_path);
println!("Enter to start main menu"); println!("Enter to start main menu");
let mut enter = String::new(); let mut enter = String::new();
std::io::stdin().read_line(&mut enter).unwrap(); std::io::stdin().read_line(&mut enter).unwrap();