summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs142
1 files changed, 50 insertions, 92 deletions
diff --git a/src/main.rs b/src/main.rs
index 28f08cd..56df611 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,142 +1,100 @@
use std::env;
use std::process::ExitCode;
-use pwd::Passwd;
-use nix::unistd;
-extern crate time;
-const ERROR_ARGS: 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;
-
-mod persist;
+mod auth;
mod flags;
-mod help;
+mod persist;
mod secure;
+
+const ERROR_ARGS: u8 = 1;
+const ERROR_CONFIG: u8 = 2;
+const ERROR_NOT_AUTHORIZED: u8 = 3;
+const ERROR_AUTH_FAILED: u8 = 4;
+const ERROR_ELEVATE_PRIVILEGES: u8 = 5;
+
+
fn main() -> ExitCode {
+
+ // gets the arguments from the env
let args: Vec<String> = env::args().collect();
+
+ // pase the arguments into valid flags that are usuable by crab
let flags = match flags::parse(&args[1..]) {
Some(data) => data,
+ // if there is an invalid flag, print the help message and exit
None => {
- help::help();
+ help();
return ExitCode::from(ERROR_ARGS);
}
};
+
+ // If the version arg flag is set, print the crab version
if flags.version {
- println!("crab version 0.0.5");
+ println!("crab version 0.0.6");
return ExitCode::SUCCESS;
}
+
+ // If the help arg flag is set, print the crab help message
if flags.help {
- help::help();
+ help();
return ExitCode::SUCCESS;
}
+
+ // If the amount of acutal command arguments is less than two, a.k.a just `crab`, print the command usage
if args.len() - flags.arg_count < 2 {
println!("usage: crab [-d] command [args]");
return ExitCode::SUCCESS;
}
- let config = match config("/etc/crab.conf") {
+
+ // Load the command config from /etc
+ let configs = match auth::load_config_file("/etc/crab.conf") {
Some(data) => data,
None => return ExitCode::from(ERROR_CONFIG)
};
- let user = match Passwd::current_user() {
+
+
+ // check if the user is authorized
+ let auth = match auth::authorize(&configs, nix::unistd::getuid()) {
Some(data) => data,
None => {
- eprintln!("You dont exist.");
- return ExitCode::from(ERROR_NO_USER);
- }
- };
- let persist = match allowed(&config, &user.name) {
- Some(data) => data && !flags.dont_persist,
- None => {
eprintln!("Operation Not Permitted.");
return ExitCode::from(ERROR_NOT_AUTHORIZED);
}
};
- if !validate(&user.name, persist) {
+ // authenticate the user
+ if !auth::authenticate(&configs[auth], flags.dont_persist, nix::unistd::getuid()) {
eprintln!("Authentication failed.");
return ExitCode::from(ERROR_AUTH_FAILED);
}
- if !unistd::setuid(unistd::geteuid()).is_ok() || !unistd::setgid(unistd::getegid()).is_ok() {
- eprintln!("Failed to set root permissions");
- return ExitCode::from(ERROR_RUN_ROOT);
+ // elevate privileges
+ if nix::unistd::setuid(configs[auth].privlaged_uid).is_err() {
+ eprintln!("Failed to elevate privileges.");
+ return ExitCode::from(ERROR_ELEVATE_PRIVILEGES);
};
+
+ // execute the passed command
let start = 1 + flags.arg_count;
let err = exec::execvp(&args[start], &args[start..]);
+ // print an error if an error was returned
eprintln!("{}", err);
ExitCode::SUCCESS
}
-struct Config {
- users: Vec<(String, bool)>
-}
-fn validate(user: &str, persist: bool) -> bool {
- if persist && persist::get_persist(user) {
- return true;
- }
- let input = match rpassword::prompt_password(format!("crab ({}) password: ", user)) {
- Ok(data) => data,
- Err(_) => return false
- };
- let mut auth = match pam::Authenticator::with_password("crab") {
- Ok(data) => data,
- Err(_) => return false
- };
- auth.get_handler().set_credentials(user.to_owned(), input);
- if !auth.authenticate().is_ok() || !auth.open_session().is_ok() {
- return false;
- }
- if persist {
- persist::set_persist(user);
- }
- return true;
-}
-
-fn allowed(config: &Config, user: &str) -> Option<bool> {
- for (name, persist) in &config.users {
- if name == user {
- return Some(persist.clone());
- }
- }
- None
-}
-
-fn config(path: &str) -> Option<Config> {
- let file = match std::fs::read_to_string(path) {
- Err(e) => {
- eprintln!("{}: {}", &path, e);
- return None
- },
- Ok(data) => data
- };
-
- let mut users = vec![];
- for (line_num, line) in file.split("\n").enumerate() {
- let args: Vec<&str> = line.split(" ").collect();
- if line.trim() == "" {
- continue;
- }
- if args.len() < 2 {
- eprintln!("Error in config at line {}: Not enough arguments", line_num);
- continue;
- }
- let user: String = args[0].to_string();
- let persist: bool = match args[1].parse() {
- Err(e) => {
- eprintln!("Error in config at line {}: {}", line_num, e);
- continue;
- },
- Ok(data) => data
- };
- users.push((user, persist));
- }
- Some(Config{users})
+/// Prints the help message to the standard output
+fn help() {
+ let help =
+"Usage:
+ crab [-d] command [args]
+Options:
+ -v --version Get the current version of the package
+ -h --help Generates the crab help message
+ -d If your user is set to persist, dont save persistance";
+ println!("{}", help);
}