From 58208a126858d14e4d4bf4707e298919d234bc22 Mon Sep 17 00:00:00 2001 From: tylermurphy534 Date: Fri, 11 Nov 2022 01:25:10 -0500 Subject: [PATCH] update config format --- Cargo.lock | 68 +--------- Cargo.toml | 3 +- conf | 6 +- deployments/aur/.SRCINFO | 2 +- deployments/aur/PKGBUILD | 8 +- install.sh | 8 +- src/auth.rs | 277 +++++++++++++++++++++++++++------------ src/flags.rs | 88 ++++++------- src/main.rs | 24 +--- src/persist.rs | 94 ++++++------- src/secure.rs | 78 ++++++----- uninstall.sh | 9 +- 12 files changed, 348 insertions(+), 317 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ba42db..054acb7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,13 +34,12 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "crab" -version = "0.0.5" +version = "0.0.6" dependencies = [ "exec", "nix", "pam", "procinfo", - "pwd", "rpassword", "serde_json", "time", @@ -144,15 +143,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "proc-macro2" -version = "1.0.47" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" -dependencies = [ - "unicode-ident", -] - [[package]] name = "procinfo" version = "0.4.2" @@ -165,25 +155,6 @@ dependencies = [ "rustc_version", ] -[[package]] -name = "pwd" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c71c0c79b9701efe4e1e4b563b2016dd4ee789eb99badcb09d61ac4b92e4a2" -dependencies = [ - "libc", - "thiserror", -] - -[[package]] -name = "quote" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" -dependencies = [ - "proc-macro2", -] - [[package]] name = "rpassword" version = "7.1.0" @@ -241,37 +212,6 @@ dependencies = [ "serde", ] -[[package]] -name = "syn" -version = "1.0.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "thiserror" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "time" version = "0.3.17" @@ -288,12 +228,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" -[[package]] -name = "unicode-ident" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" - [[package]] name = "users" version = "0.8.1" diff --git a/Cargo.toml b/Cargo.toml index 0408f28..e9b9a13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,10 @@ [package] name = "crab" -version = "0.0.5" +version = "0.0.6" edition = "2021" [dependencies] pam = "0.7.0" -pwd = "1.4.0" nix = "0.25.0" exec = "0.3.1" rpassword = "7.1.0" diff --git a/conf b/conf index bebb505..0da97e5 100644 --- a/conf +++ b/conf @@ -1 +1,5 @@ -root true \ No newline at end of file +permit nopass linus as root +deny :docker +#deny jane +permit persist :wheel +permit jane as doe \ No newline at end of file diff --git a/deployments/aur/.SRCINFO b/deployments/aur/.SRCINFO index 66c6ce5..c145393 100644 --- a/deployments/aur/.SRCINFO +++ b/deployments/aur/.SRCINFO @@ -1,6 +1,6 @@ pkgbase = crab pkgdesc = A rusty permission authentication system - pkgver = 0.0.5 + pkgver = 0.0.6 pkgrel = 2 url = https://g.tylerm.dev/tylermurphy534/crab.git arch = x86_64 diff --git a/deployments/aur/PKGBUILD b/deployments/aur/PKGBUILD index b49ce75..6196e48 100644 --- a/deployments/aur/PKGBUILD +++ b/deployments/aur/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: Tyler Murphy pkgname=crab -pkgver=0.0.5 +pkgver=0.0.6 pkgrel=2 pkgdesc="A rusty permission authentication system" arch=('x86_64' 'i686') @@ -18,7 +18,7 @@ build() { package() { cd crab - install -D --mode=6755 --owner=root --group=root ./target/release/crab ${pkgdir}/usr/bin/crab - install -D --mode=660 --owner=root --group=root pam ${pkgdir}/etc/pam.d/crab - install -D --mode=660 --owner=root --group=root conf ${pkgdir}/usr/share/crab/crab.conf + install -D --mode=4755 --owner=root --group=root ./target/release/crab ${pkgdir}/usr/bin/crab + install -D --mode=600 --owner=root --group=root pam ${pkgdir}/etc/pam.d/crab + install -D --mode=600 --owner=root --group=root conf ${pkgdir}/usr/share/crab/crab.conf } diff --git a/install.sh b/install.sh index 716d9b1..6c7b019 100755 --- a/install.sh +++ b/install.sh @@ -8,10 +8,14 @@ fi # Copy executable to bin cp ./target/release/crab /usr/bin/crab chown root:root /bin/crab -chmod 6755 /bin/crab +chmod 4755 /bin/crab # Set up config files cp pam /etc/pam.d/crab +chmod 600 /etc/pam.d/crab + mkdir /usr/share/crab +chmod 600 /usr/share/crab + cp conf /usr/share/crab/crab.conf -chmod 660 /usr/share/crab/crab.conf +chmod 600 /usr/share/crab/crab.conf diff --git a/src/auth.rs b/src/auth.rs index c973921..82a09cb 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,9 +1,15 @@ -use nix::unistd::Group; +use nix::unistd::{User, Group, Uid, Gid}; use crate::{persist, secure}; +#[derive(Debug)] pub struct Config { - pub identitys: Vec<(String, bool)>, + pub permit: bool, + pub persist: bool, + pub nopass: bool, + pub user_uid: Option, + pub user_gid: Option, + pub privlaged_uid: Uid, } @@ -14,37 +20,132 @@ pub struct Config { /// * `path` - The path to the config file /// #### Returns /// * `None` - If the config failed to load -/// * `Some(Config)` - If the config was sucessfully parsed. -pub fn load_config(path: &str) -> Option { - let file = match std::fs::read_to_string(path) { - Err(e) => { - eprintln!("{}: {}", &path, e); - return None - }, - Ok(data) => data - }; +/// * `Some(Vec)` - If the config was sucessfully parsed. +pub fn load_config_file(path: &str) -> Option> { + let file = match std::fs::read_to_string(path) { + Err(e) => { + eprintln!("{}: {}", &path, e); + return None + }, + Ok(data) => data + }; - let mut identitys = vec![]; - for (line_num, line) in file.split("\n").enumerate() { - let args: Vec<&str> = line.split(" ").collect(); - if line.starts_with("#") || line.trim() == "" { - continue; - } - if args.len() < 2 { - eprintln!("Error in config at line {}: Not enough arguments", line_num); - continue; - } - let identity: 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 - }; - identitys.push((identity, persist)); - } - Some(Config{identitys}) + let mut configs = vec![]; + + for (line_num, line) in file.split("\n").enumerate() { + + let args: Vec<&str> = line.split(" ").collect(); + let len = args.len(); + + if line.starts_with("#") || line.trim() == "" { + continue; + } + + if len < 2 { + config_error(line_num, "Not enough arguments"); + continue; + } + + let permit = match args[0] { + "permit" => true, + "deny" => false, + _ => { + config_error(line_num, "The first argument must be `permit` or `deny"); + continue; + } + }; + + let (user_name, privlaged_name, as_index) = match args.iter().position(|&a| a == "as") { + Some(index) => { + if index != len - 2 { + config_error(line_num, "Target user not specified or to many arguments after `as`"); + continue; + } + (args[index-1].to_string(), args[index+1].to_string(), index) + }, + None => (args[len-1].to_string(), "root".to_string(), len-1) + }; + + let persist = args[1..as_index].contains(&"persist"); + + let nopass = args[1..as_index].contains(&"nopass"); + + + let (user_uid, user_gid) = + if user_name.starts_with(":") { + match get_gid_from_name(&user_name[1..]) { + Some(gid) => (None, Some(gid)), + None => { + config_error(line_num, &format!("Group `{}` does not exist", &user_name[1..])); + continue; + } + } + } else { + match get_uid_from_name(&user_name) { + Some(uid) => (Some(uid), None), + None => { + config_error(line_num, &format!("User `{}` does not exist", user_name)); + continue; + } + } + }; + + let privlaged_uid = match get_uid_from_name(&privlaged_name) { + Some(uid) => uid, + None => { + config_error(line_num, &format!("User `{}` does not exist", privlaged_name)); + continue; + } + }; + + configs.push(Config { + permit, + persist, + nopass, + user_uid, + user_gid, + privlaged_uid + }); + } + Some(configs) +} + + +fn config_error(line_num: usize, message: &str) { + eprintln!("Error in config at line {}: {}", line_num, message); +} + + +fn get_uid_from_name(name: &str) -> Option { + return match User::from_name(name) { + Ok(result) => match result { + Some(data) => Some(data.uid), + None => None + }, + Err(_) => None + } +} + + +fn get_name_from_uid(uid: Uid) -> Option { + return match User::from_uid(uid) { + Ok(result) => match result { + Some(data) => Some(data.name), + None => None + }, + Err(_) => None + } +} + + +fn get_gid_from_name(name: &str) -> Option { + return match Group::from_name(name) { + Ok(result) => match result { + Some(data) => Some(data.gid), + None => None + }, + Err(_) => None + } } @@ -53,41 +154,44 @@ pub fn load_config(path: &str) -> Option { /// A vector of strings of the groups the user is in. If the vector is empty, /// either the function coudn't retrieve the users groups, or the user is not in /// any groups. -fn get_groups() -> Vec { - let groups = match nix::unistd::getgroups() { - Ok(data) => data, - Err(_) => return vec![] - }; - let names = groups.iter() - .map(|gid| Group::from_gid(*gid)) - .flatten().flatten() - .map(|group| group.name) - .collect(); - names +fn get_groups() -> Vec { + let groups = match nix::unistd::getgroups() { + Ok(data) => data, + Err(_) => return vec![] + }; + groups } /// Returns if the user is authorized given a sepcific config and user name. /// #### Arguments /// * `config` - A config struct contaning the authorization settings for crab -/// * `user` - The name of the user to check is authorized +/// * `uid` - The uid to check is authorized /// #### Returns -/// * `None` - If the user is not authorized -/// * `Some(bool)` - If the user is authorized, returning the boolean if the -/// user is set to persist -pub fn authorize(config: &Config, user: &str) -> Option { - let groups = get_groups(); - for (identity, persist) in &config.identitys { - if identity.starts_with(":") { - let group = &identity[1..]; - if groups.contains(&group.to_string()) { - return Some(persist.clone()); - }; - } else if identity == user { - return Some(persist.clone()); - } - } - None +/// * `None` - If the uid is not authorized +/// * `Some(Config)` - If the uid is authorized, returns the specific index of the associated config +pub fn authorize(configs: &Vec, uid: Uid) -> Option { + let groups = get_groups(); + for (config_index, config) in configs.iter().enumerate() { + if config.user_gid.is_some() { + if groups.contains(&config.user_gid.unwrap()) { + if config.permit { + return Some(config_index) + } else { + return None + } + } + } else if config.user_uid.is_some() { + if config.user_uid.unwrap() == uid { + if config.permit { + return Some(config_index) + } else { + return None + } + } + } + } + None } @@ -96,31 +200,36 @@ pub fn authorize(config: &Config, user: &str) -> Option { /// read the persist file, and then skip authentication if /// the is still persisted. /// #### Arguments -/// * `user` - The login name of the linux user -/// * `persist` - If the user's login should persist +/// * `config` - The config associated with the user to authenticate with +/// * `force_pass` - Force a password prompt even if persistance is set to true +/// * `uid` - The user uid that is authenticating /// #### Returns -/// * `true` - If the user authenticated sucessfully, or the user is persisted +/// * `true` - If the user authenticated sucessfully /// * `false` - If the user failed to authenticate -pub fn authenticate(user: &str, persist: bool) -> bool { - if persist && persist::get_persist(user) { - secure::elevate_privilages(0, 0); - return true; - } - let input = match rpassword::prompt_password(format!("crab ({}) password: ", user)) { - Ok(data) => data, +pub fn authenticate(config: &Config, force_pass: bool, uid: Uid) -> bool { + let name = match get_name_from_uid(uid) { + Some(data) => data, + None => return false + }; + if config.nopass || ( !force_pass && config.persist && persist::get_persist(&name) ) { + secure::elevate_privilages(config.privlaged_uid); + return true; + } + let input = match rpassword::prompt_password(format!("crab ({}) password: ", &name)) { + Ok(data) => data, + Err(_) => return false + }; + let mut auth = match pam::Authenticator::with_password("crab") { + 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); - } - secure::elevate_privilages(0, 0); - return true; + }; + auth.get_handler().set_credentials(&name, input); + if !auth.authenticate().is_ok() || !auth.open_session().is_ok() { + return false; + } + if config.persist { + persist::set_persist(&name); + } + secure::elevate_privilages(config.privlaged_uid); + return true; } diff --git a/src/flags.rs b/src/flags.rs index c93f3ef..a945483 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -5,10 +5,10 @@ const DONT_PERSIST: &str = "d"; pub struct Flags { - pub help: bool, - pub version: bool, - pub dont_persist: bool, - pub arg_count: usize + pub help: bool, + pub version: bool, + pub dont_persist: bool, + pub arg_count: usize } @@ -19,32 +19,32 @@ pub struct Flags { /// * `None` - If there is an invalid argument in the list /// * `Some(Flags)` - If the arguments were secussfully parsed, returning the flags pub fn parse(args: &[String]) -> Option { - let mut flags = Flags { - help: false, - version: false, - dont_persist: false, - arg_count: 0 - }; - for arg in args { - if !is_arg(&arg) { break; } - flags.arg_count += 1; - if arg.starts_with("--") { - let flag = &arg[2..]; - if !set_flag(&flag, &mut flags) { - eprintln!("Invalid argument: {}", arg); - return None - } - } else { - let flag = &arg[1..]; - for char in flag.chars() { - if !set_flag(&char.to_string(), &mut flags) { - eprintln!("Invalid argument: {}", arg); - return None + let mut flags = Flags { + help: false, + version: false, + dont_persist: false, + arg_count: 0 + }; + for arg in args { + if !is_arg(&arg) { break; } + flags.arg_count += 1; + if arg.starts_with("--") { + let flag = &arg[2..]; + if !set_flag(&flag, &mut flags) { + eprintln!("Invalid argument: {}", arg); + return None + } + } else { + let flag = &arg[1..]; + for char in flag.chars() { + if !set_flag(&char.to_string(), &mut flags) { + eprintln!("Invalid argument: {}", arg); + return None + } + } } - } } - } - Some(flags) + Some(flags) } @@ -62,17 +62,17 @@ fn is_arg(arg: &str) -> bool { /// * `true` - If the argument passed is a valid flag /// * `false` - If the argument passed is not a valid flag fn set_flag(arg: &str, flags: &mut Flags) -> bool { - if has_flag_set(&arg, HELP_FLAG) { - flags.help = true; - return true - } else if has_flag_set(&arg, VERSION_FLAG) { - flags.version = true; - return true - } else if has_flag_set(&arg, DONT_PERSIST) { - flags.dont_persist = true; - return true - } - false + if has_flag_set(&arg, HELP_FLAG) { + flags.help = true; + return true + } else if has_flag_set(&arg, VERSION_FLAG) { + flags.version = true; + return true + } else if has_flag_set(&arg, DONT_PERSIST) { + flags.dont_persist = true; + return true + } + false } @@ -83,10 +83,10 @@ fn set_flag(arg: &str, flags: &mut Flags) -> bool { /// * `true` - If the argument matches the flag /// * `false` - If the argument doesn't match the flag fn has_flag_set(arg: &str, check: &str) -> bool { - for check_arg in check.split(" ") { - if check_arg == arg { - return true + for check_arg in check.split(" ") { + if check_arg == arg { + return true + } } - } - return false + return false } diff --git a/src/main.rs b/src/main.rs index ed89e76..cca85de 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ use std::env; use std::process::ExitCode; -use pwd::Passwd; mod auth; @@ -11,9 +10,8 @@ mod secure; 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_NOT_AUTHORIZED: u8 = 3; +const ERROR_AUTH_FAILED: u8 = 4; fn main() -> ExitCode { @@ -33,7 +31,7 @@ fn main() -> ExitCode { // 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; } @@ -50,23 +48,15 @@ fn main() -> ExitCode { } // Load the command config from /etc - let config = match auth::load_config("/etc/crab.conf") { + let configs = match auth::load_config_file("/etc/crab.conf") { Some(data) => data, None => return ExitCode::from(ERROR_CONFIG) }; - // get the current user login - let user = match Passwd::current_user() { - Some(data) => data, - None => { - eprintln!("You dont exist."); - return ExitCode::from(ERROR_NO_USER); - } - }; // check if the user is authorized - let persist = match auth::authorize(&config, &user.name) { - Some(data) => data && !flags.dont_persist, + let auth = match auth::authorize(&configs, nix::unistd::getuid()) { + Some(data) => data, None => { eprintln!("Operation Not Permitted."); return ExitCode::from(ERROR_NOT_AUTHORIZED); @@ -74,7 +64,7 @@ fn main() -> ExitCode { }; // authenticate the user - if !auth::authenticate(&user.name, persist) { + if !auth::authenticate(&configs[auth], flags.dont_persist, nix::unistd::getuid()) { eprintln!("Authentication failed."); return ExitCode::from(ERROR_AUTH_FAILED); } diff --git a/src/persist.rs b/src/persist.rs index 1cddb7f..762d8b1 100644 --- a/src/persist.rs +++ b/src/persist.rs @@ -16,15 +16,15 @@ const PERSIST_PATH: &str = "/var/run/crab"; /// * `true` - If the user is persisted /// * `false` - If the user is not persisted, or if the persist file is not trusted pub fn get_persist(user: &str) -> bool { - let json = match get_persist_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 && timestamp - 1 < now(); + let json = match get_persist_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 && timestamp - 1 < now(); } @@ -32,21 +32,21 @@ pub fn get_persist(user: &str) -> bool { /// #### Arguments /// * `user` - The user to set persisted pub fn set_persist(user: &str) { - let mut json = match get_persist_config() { - Some(data) => data, - None => return - }; - json[user] = Value::from(now()); - let session = match get_current_session() { - Some(data) => data, - None => return - }; - match secure::write_file(PERSIST_PATH, &format!("{}", session), &json.to_string()) { - Ok(_) => {}, - Err(e) => { - eprintln!("crab: An Internal Has Error: {}", e); - } - }; + let mut json = match get_persist_config() { + Some(data) => data, + None => return + }; + json[user] = Value::from(now()); + let session = match get_current_session() { + Some(data) => data, + None => return + }; + match secure::write_file(PERSIST_PATH, &format!("{}", session), &json.to_string()) { + Ok(_) => {}, + Err(e) => { + eprintln!("crab: An Internal Has Error: {}", e); + } + }; } @@ -55,15 +55,15 @@ pub fn set_persist(user: &str) { /// * `None` - If crab failed to get the current session /// * `Some(i32)` - If the session is retrieved, returns the i32/pid_t session id fn get_current_session() -> Option { - let pid: i32 = match std::process::id().try_into() { - Ok(data) => data, - Err(_) => return None - }; - let pid_stat = match procinfo::pid::stat(pid) { - Ok(data) => data, - Err(_) => return None - }; - Some(pid_stat.session) + let pid: i32 = match std::process::id().try_into() { + Ok(data) => data, + Err(_) => return None + }; + let pid_stat = match procinfo::pid::stat(pid) { + Ok(data) => data, + Err(_) => return None + }; + Some(pid_stat.session) } @@ -72,23 +72,23 @@ fn get_current_session() -> Option { /// * `None` - If the persist file is untrusted or doesnt exist /// * `Some(Value)` - If the persist file is retrieved, returns the serde_json Value of the file fn get_persist_config() -> Option { - let session = match get_current_session() { - Some(data) => data, - None => return None - }; - let data = match secure::read_file(PERSIST_PATH, &format!("{}", session)) { - Some(data) => data, - None => "{}".to_string() - }; - let json: Value = match serde_json::from_str(&data) { - Ok(data) => data, - Err(_) => return None - }; - Some(json) + let session = match get_current_session() { + Some(data) => data, + None => return None + }; + let data = match secure::read_file(PERSIST_PATH, &format!("{}", session)) { + Some(data) => data, + None => "{}".to_string() + }; + let json: Value = match serde_json::from_str(&data) { + Ok(data) => data, + Err(_) => return None + }; + Some(json) } // Gets the current time in seconds since the Unix Epoch fn now() -> u64 { - return SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); + return SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); } diff --git a/src/secure.rs b/src/secure.rs index 13d67b0..018bc4f 100644 --- a/src/secure.rs +++ b/src/secure.rs @@ -1,5 +1,5 @@ use std::{os::{unix::prelude::PermissionsExt, linux::fs::MetadataExt}, fs, io::{self, ErrorKind}}; -use nix::unistd::{self, Uid, Gid}; +use nix::unistd::{self, Uid}; /// Writes a file securly to a specified path with given data @@ -10,12 +10,12 @@ use nix::unistd::{self, Uid, Gid}; /// #### Returns /// A ``io::Result<()>`` if the write succeded or failed pub fn write_file(dir: &str, file: &str, data: &str) -> Result<(), io::Error> { - fs::create_dir_all(dir)?; - set_file_permissions(0, 0, 0o100600, dir)?; - let path = path(dir, file); - fs::write(&path, data)?; - set_file_permissions(0, 0, 0o100600, &path)?; - Ok(()) + fs::create_dir_all(dir)?; + set_file_permissions(0, 0, 0o100600, dir)?; + let path = path(dir, file); + fs::write(&path, data)?; + set_file_permissions(0, 0, 0o100600, &path)?; + Ok(()) } @@ -29,31 +29,27 @@ pub fn write_file(dir: &str, file: &str, data: &str) -> Result<(), io::Error> { /// * `None` - If the files doesnt exist or isnt trusted /// * `Some(String) - If the file is trusted, it returns the file's contents pub fn read_file(dir: &str, file: &str) -> Option { - let path = path(dir,file); - if !check_file_permissions(0, 0, 0o100600, &path) { - return None; - } - match fs::read_to_string(&path) { - Ok(data) => return Some(data), - Err(_) => return None - }; + let path = path(dir,file); + if !check_file_permissions(0, 0, 0o100600, &path) { + return None; + } + match fs::read_to_string(&path) { + Ok(data) => return Some(data), + Err(_) => return None + }; } -/// Ekevate tge oruvukages if the current process +/// Elecate the privlages of the current process /// #### Arguments /// * `uid` - The uid to set the process to -/// * `gid` - The gid to set the process to /// #### Returns -/// If the process failes to elevate, it returns false -pub fn elevate_privilages(uid: u32, gid: u32) -> bool { - if unistd::setuid(Uid::from(uid)).is_err() { - return false; - } - if unistd::setgid(Gid::from(gid)).is_err() { - return false; - } - true +/// If the process fails to elevate, it returns false +pub fn elevate_privilages(uid: Uid) -> bool { + if unistd::setuid(uid).is_err() { + return false; + } + true } @@ -66,12 +62,12 @@ pub fn elevate_privilages(uid: u32, gid: u32) -> bool { /// #### Returns /// A ``io::Result<()>`` if the write succeded or failed fn set_file_permissions(uid: u32, gid: u32, mode: u32, path: &str) -> Result<(), io::Error> { - unistd::chown(std::path::Path::new(path), Some(unistd::Uid::from(uid)), Some(unistd::Gid::from(gid)))?; - let metadata = fs::metadata(path)?; - let mut perms = metadata.permissions(); - perms.set_mode(mode); - fs::set_permissions(path, perms)?; - Ok(()) + unistd::chown(std::path::Path::new(path), Some(unistd::Uid::from(uid)), Some(unistd::Gid::from(gid)))?; + let metadata = fs::metadata(path)?; + let mut perms = metadata.permissions(); + perms.set_mode(mode); + fs::set_permissions(path, perms)?; + Ok(()) } @@ -84,18 +80,18 @@ fn set_file_permissions(uid: u32, gid: u32, mode: u32, path: &str) -> Result<(), /// #### Returns /// True or false if the files permissions match fn check_file_permissions(uid: u32, gid: u32, mode: u32, path: &str) -> bool { - let metadata = match fs::metadata(path) { - Ok(data) => data, - Err(e) => { - return e.kind() == ErrorKind::NotFound; - } - }; - let perms = metadata.permissions(); - return perms.mode() == mode && metadata.st_uid() == uid && metadata.st_gid() == gid; + let metadata = match fs::metadata(path) { + Ok(data) => data, + Err(e) => { + return e.kind() == ErrorKind::NotFound; + } + }; + let perms = metadata.permissions(); + return perms.mode() == mode && metadata.st_uid() == uid && metadata.st_gid() == gid; } /// Get the path of a file given a directory and file name fn path(dir: &str, file: &str) -> String { - return format!("{}/{}.persist", dir, file); + return format!("{}/{}.persist", dir, file); } diff --git a/uninstall.sh b/uninstall.sh index f6cba7f..cf7ade8 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -6,11 +6,6 @@ if [[ $(/usr/bin/id -u) -ne 0 ]]; then fi # Delete crab files +rm /etc/pam.d/crab rm /usr/bin/crab -chown root:root /bin/crab -chmod 6755 /bin/crab - -# Set up config files -cp pam /etc/pam.d/crab -cp -n conf /etc/crab.conf -chmod 660 /etc/crab.conf +rm -fr /usr/share/crab