diff options
author | Tyler Murphy <tylermurphy534@gmail.com> | 2022-11-09 10:49:25 -0500 |
---|---|---|
committer | Tyler Murphy <tylermurphy534@gmail.com> | 2022-11-09 10:49:25 -0500 |
commit | 191632ce0ab810b4773f64eaf80ad67e87200c0b (patch) | |
tree | 51ff03bc25aba69142f0583e52d850424c619b55 /src/main.rs | |
parent | fix session pid, add uninstall sh file (diff) | |
download | crab-191632ce0ab810b4773f64eaf80ad67e87200c0b.tar.gz crab-191632ce0ab810b4773f64eaf80ad67e87200c0b.tar.bz2 crab-191632ce0ab810b4773f64eaf80ad67e87200c0b.zip |
help and version flags
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 137 |
1 files changed, 25 insertions, 112 deletions
diff --git a/src/main.rs b/src/main.rs index 9061ade..5fab1d9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,30 +1,35 @@ -use std::fs; -use std::os::linux::fs::MetadataExt; -use std::{env, os::unix::prelude::PermissionsExt}; +use std::env; use std::process::ExitCode; -use std::time::SystemTime; use pwd::Passwd; use nix::unistd; -use serde_json::Value; extern crate time; -const ERROR_ARGS: u8 = 1; +// const ERROR_COMMAND: u8 = 1; const ERROR_CONFIG: u8 = 2; const ERROR_NO_USER: u8 = 3; const ERROR_NOT_AUTHORIZED: u8 = 4; const ERROR_AUTH_FAILED: u8 = 5; const ERROR_RUN_ROOT: u8 = 6; -const SUCCESS: u8 = 0; - -const PERSIST_TIME: u64 = 60 * 3; +mod persist; +mod flags; +mod help; fn main() -> ExitCode { let args: Vec<String> = env::args().collect(); - if args.len() < 2 { - println!("usage: crab command [args]"); - return ExitCode::from(ERROR_ARGS); + let flags = flags::parse(&args[1..]); + if flags.version { + println!("crab version 0.0.3"); + return ExitCode::SUCCESS; + } + if flags.help { + help::help(); + return ExitCode::SUCCESS; + } + if args.len() - flags.arg_count < 2 { + println!("usage: crab [-d] command [args]"); + return ExitCode::SUCCESS; } let config = match config("/etc/crab.conf") { Some(data) => data, @@ -38,7 +43,7 @@ fn main() -> ExitCode { } }; let persist = match allowed(&config, &user.name) { - Some(data) => data, + Some(data) => data && !flags.dont_persist, None => { eprintln!("Operation Not Permitted."); return ExitCode::from(ERROR_NOT_AUTHORIZED); @@ -54,11 +59,12 @@ fn main() -> ExitCode { eprintln!("Failed to set root permissions"); return ExitCode::from(ERROR_RUN_ROOT); }; - - let err = exec::execvp(&args[1], &args[1..]); - println!("Error: {}", err); + let start = 1 + flags.arg_count; + let err = exec::execvp(&args[start], &args[start..]); + + eprintln!("{}", err); - ExitCode::from(SUCCESS) + ExitCode::SUCCESS } struct Config { @@ -66,7 +72,7 @@ struct Config { } fn validate(user: &str, persist: bool) -> bool { - if persist && get_persist(user) { + if persist && persist::get_persist(user) { return true; } let input = match rpassword::prompt_password(format!("crab ({}) password: ", user)) { @@ -82,7 +88,7 @@ fn validate(user: &str, persist: bool) -> bool { return false; } if persist { - set_persist(user); + persist::set_persist(user); } return true; } @@ -126,97 +132,4 @@ fn config(path: &str) -> Option<Config> { users.push((user, persist)); } Some(Config{users}) -} - -fn get_terminal_process() -> Option<i32> { - let id: i32 = match std::process::id().try_into() { - Ok(data) => data, - Err(_) => return None - }; - let stat = match procinfo::pid::stat(id) { - Ok(data) => data, - Err(_) => return None - }; - Some(stat.session) -} - -fn is_file_root_only(id: &i32) -> bool { - let metadata = match std::fs::metadata(path(&id)) { - Ok(data) => data, - Err(e) => { - if let Some(err) = e.raw_os_error() { - return err == 2; - } - return true - } - }; - let perms = metadata.permissions(); - return perms.mode() == 33200 && metadata.st_uid() == 0 && metadata.st_gid() == 0; -} - -fn get_terminal_config() -> Option<Value> { - let id = match get_terminal_process() { - Some(data) => data, - None => return None - }; - if !is_file_root_only(&id) { - return None; - } - let data = match std::fs::read_to_string(path(&id)) { - Ok(data) => data, - Err(_) => "{}".to_string() - }; - let json: Value = match serde_json::from_str(&data) { - Ok(data) => data, - Err(_) => return None - }; - Some(json) -} - -fn write_terminal_config(id: &i32, data: &str) -> Result<(), Box<dyn std::error::Error>> { - std::fs::write(path(&id), data)?; - unistd::chown(std::path::Path::new(&path(&id)), Some(unistd::Uid::from(0)), Some(unistd::Gid::from(0)))?; - let metadata = std::fs::metadata(path(&id))?; - let mut perms = metadata.permissions(); - perms.set_mode(0o660); - fs::set_permissions(path(&id), perms)?; - Ok(()) -} - -fn get_persist(user: &str) -> bool { - let json = match get_terminal_config() { - Some(data) => data, - None => return false - }; - let timestamp = match json[user].as_u64() { - Some(data) => data, - None => return false - }; - return now() - timestamp < PERSIST_TIME; -} - -fn set_persist(user: &str) { - let mut json = match get_terminal_config() { - Some(data) => data, - None => return - }; - json[user] = Value::from(now()); - let id = match get_terminal_process() { - Some(data) => data, - None => return - }; - match write_terminal_config(&id, &json.to_string()) { - Ok(_) => {}, - Err(e) => { - eprintln!("Internal Error: {}", e) - } - }; -} - -fn now() -> u64 { - return SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); -} - -fn path(id: &i32) -> String { - return format!("/tmp/crab-{}", id); }
\ No newline at end of file |