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::path::PathBuf;
use std::process;
use std::time;
use std::time::Duration;
use std::time::SystemTime;
use std::str::FromStr;
use clearscreen::clear;
use directories::UserDirs;
use clearscreen;
@@ -16,8 +14,6 @@ struct Project{
project_name: String,
notes_folder: PathBuf,
files_folder: PathBuf,
activativation_time: SystemTime,
hour_count: Duration,
active: bool,
boxname: String,
id: i32,
@@ -29,22 +25,45 @@ fn install(config_path: &PathBuf){
let mut config_folder_path: PathBuf = config_path.clone();
config_folder_path.pop();
let mut projects_conf_path = config_folder_path.clone();
let del_on_fail = config_folder_path.clone();
projects_conf_path.push("projects.conf");
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 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 files_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?");
std::io::stdin().read_line(&mut notes_response).unwrap();
println!("path to save project files?");
std::io::stdin().read_line(&mut files_response).unwrap();
println!("path to folder with your custom tools?");
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());
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!("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");
@@ -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.push("projects.conf");
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 customer = settings[0].to_owned();
let project = settings[1].to_owned();
let folder_name = format!("{}/{}", customer, project);
let mut notes_folder = base_notes.clone();
let mut project_folder = base_files.clone();
notes_folder.push(&folder_name);
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 notes_string = settings[2].to_owned();
let folder_string = settings[3].to_owned();
let notes_folder = PathBuf::from_str(&notes_string.trim_end()).expect("error reading notes string");
let project_folder = PathBuf::from_str(&folder_string.trim_end()).expect("error reading folding sering");
let mut active = false;
let boxname = settings[4].to_owned();
if settings[2] == "yes"{
let boxname = settings[5].to_owned();
if settings[4] == "yes"{
env::set_var("CURRENT_PROJECT_BOX", boxname.clone());
active = true;
}
let time = SystemTime::now();
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};
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, active: active, id: first, boxname: boxname};
println!("{} {} LOADED!", &new_project.customer, &new_project.project_name);
projects.push(new_project);
}
@@ -127,16 +141,15 @@ fn save_projects(projects: &Vec<Project>, config_path: &PathBuf){
save_file_path.pop();
save_file_path.push("projects.conf");
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{
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();
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, hours, project.boxname);
_outline = format!("{}yes:{}\n", default, project.boxname);
}
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");
}
@@ -231,6 +244,10 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
else{
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{
@@ -240,9 +257,12 @@ fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &P
new_note_dir.push(&project_name);
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");
}
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 toold_volume = format!("{}:/tools:rw", tools_dir.display());
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("--root")
.arg(&box_name)
.arg("--")
.arg("sudo")
.arg("-s")
.arg("ln")
.arg("-sf")
.arg("/pentest/boxname")
.arg("/etc/boxname")
.status()
.expect("error getting response from distrobox start");
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(),
notes_folder: new_note_dir,
files_folder:new_project_dir,
activativation_time: SystemTime::now(),
hour_count: Duration::new(1, 1),
active: false,
id: new_id,
boxname: box_name,
@@ -307,11 +332,12 @@ fn remove_project(projects: &mut Vec<Project>){
if project.id == remove_id{
println!("will remove {} {}", project.customer, project.project_name);
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")
.arg("rm")
.arg("--root")
.arg("-f")
.arg(project.boxname)
.arg(&project.boxname)
.status().expect("error calling distrobox");
if distrobox_rm_status.success(){
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){
@@ -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){
let mut loopize = true;
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
Current Project: {} {}
Current Minutes: {} minutes
Main Menu:
1 .) Show Active Project
2 .) List Projects
3 .) Switch Active Project
4 .) Print Active Project Time
5 .) Print All Proejct Times
6 .) create new project with Pyro's default tool
7 .) Save Project Information
8 .) Import New Project - and setup new Distrobox
9 .) Remove Project
10.) Open A New Terminal in Current Active Project
11.) Open A Terminal In this windows for the current active project
12.) Open Project Files Folder In Dolphin
13.) Open Project Notes Folder In Dolphin
14.) Print Project Info For Report
15.) Stop All Distroboxes
16.) Reset Hour Counters
17.) Quit Application
\n", active_project.customer, active_project.project_name, SystemTime::now().duration_since(active_project.activativation_time).unwrap().as_secs() / 60);
4 .) create new project with Pyro's default tool
5 .) Save Project Information
6 .) Import New Project - and setup new Distrobox
7 .) Remove Project
8 .) Open A New Terminal in Current Active Project
9 .) Open A Terminal In this windows for the current active project
10.) Open Project Files Folder In Dolphin
11.) Open Project Notes Folder In Dolphin
12.) generate userpass file from your obsidian notes
13.) Print Project Info For Report
14.) Stop All Distroboxes
15.) Quit Application
\n", active_project.customer, active_project.project_name);
std::io::stdin().read_line(&mut response).expect("error getting menu input");
clear().expect("error clearing screen");
match response.as_str().trim_end(){
@@ -517,30 +558,18 @@ Current Minutes: {} minutes
println!("++{}|{}++",project.customer ,project.project_name)}
println!("++++++++++++++++++++")},
"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),
"5" => {println!("++++++++++++++++++++");
for project in &projects{
if project.active == true{
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);
}
else{
println!("++{} {}:{}++", project.customer, project.project_name, project.hour_count.as_secs()/3600);
}
}
println!("++++++++++++++++++++")
},
"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);
"4" => start_pentest(),
"5" => save_projects(&projects, &config_path),
"6" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate),
"7" => remove_project(&mut projects),
"8" => project_standalone_terminal(active_project.clone()),
"9" => project_inline_terminal(active_project.clone()),
"10" => open_in_dolphin("files", active_project.clone()),
"11" => open_in_dolphin("notes", active_project.clone()),
"12" => gnerate_userpass(&active_project),
"13" => print_report_information(active_project.clone()),
"14" => stop_all_boxes(&projects),
"15" => {save_projects(&projects, &config_path);
let mut stop = String::new();
println!("stop all boxes?\ny/n");
std::io::stdin().read_line(&mut stop).unwrap();
@@ -613,7 +642,7 @@ fn main() {
distrobox template: {}\n
", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template);
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");
let mut enter = String::new();
std::io::stdin().read_line(&mut enter).unwrap();