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:
@@ -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:{}", ¬es_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(¬es_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();
|
||||
|
||||
Reference in New Issue
Block a user