From 5ea42e3463271f0cee2968557e8220a0b39a0bc2 Mon Sep 17 00:00:00 2001 From: Tyler Murphy Date: Wed, 9 Nov 2022 16:48:36 -0500 Subject: [PATCH] move secure files to secure handler --- Cargo.lock | 2 +- Cargo.toml | 2 +- deployments/aur/.SRCINFO | 2 +- deployments/aur/PKGBUILD | 2 +- src/main.rs | 3 +- src/persist.rs | 64 ++++++++-------------------------------- src/secure.rs | 51 ++++++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 57 deletions(-) create mode 100644 src/secure.rs diff --git a/Cargo.lock b/Cargo.lock index bdb9395..5ba42db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,7 +34,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "crab" -version = "0.0.4" +version = "0.0.5" dependencies = [ "exec", "nix", diff --git a/Cargo.toml b/Cargo.toml index f6ba1ac..0408f28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "crab" -version = "0.0.4" +version = "0.0.5" edition = "2021" [dependencies] diff --git a/deployments/aur/.SRCINFO b/deployments/aur/.SRCINFO index 88f79ca..67ce0cb 100644 --- a/deployments/aur/.SRCINFO +++ b/deployments/aur/.SRCINFO @@ -1,6 +1,6 @@ pkgbase = crab pkgdesc = A rusty permission authentication system - pkgver = 0.0.4 + pkgver = 0.0.5 pkgrel = 1 url = https://g.tylerm.dev/tylermurphy534/crab.git arch = x86_64 diff --git a/deployments/aur/PKGBUILD b/deployments/aur/PKGBUILD index e5f9958..e7ed7df 100644 --- a/deployments/aur/PKGBUILD +++ b/deployments/aur/PKGBUILD @@ -1,6 +1,6 @@ # Maintainer: Tyler Murphy pkgname=crab -pkgver=0.0.4 +pkgver=0.0.5 pkgrel=1 pkgdesc="A rusty permission authentication system" arch=('x86_64' 'i686') diff --git a/src/main.rs b/src/main.rs index ede8751..28f08cd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ const ERROR_RUN_ROOT: u8 = 6; mod persist; mod flags; mod help; +mod secure; fn main() -> ExitCode { let args: Vec = env::args().collect(); @@ -26,7 +27,7 @@ fn main() -> ExitCode { } }; if flags.version { - println!("crab version 0.0.4"); + println!("crab version 0.0.5"); return ExitCode::SUCCESS; } if flags.help { diff --git a/src/persist.rs b/src/persist.rs index 68bd22e..6a813dc 100644 --- a/src/persist.rs +++ b/src/persist.rs @@ -1,11 +1,10 @@ -use std::fs; -use std::os::linux::fs::MetadataExt; -use std::os::unix::prelude::PermissionsExt; use std::time::SystemTime; -use nix::unistd; use serde_json::Value; +use crate::secure; + const PERSIST_TIME: u64 = 60 * 3; +const PERSIST_PATH: &str = "/var/run/crab"; pub fn get_persist(user: &str) -> bool { let json = match get_terminal_config() { @@ -16,7 +15,7 @@ pub fn get_persist(user: &str) -> bool { Some(data) => data, None => return false }; - return now() - timestamp < PERSIST_TIME && timestamp < now(); + return now() - timestamp < PERSIST_TIME && timestamp - 1 < now(); } pub fn set_persist(user: &str) { @@ -29,11 +28,11 @@ pub fn set_persist(user: &str) { Some(data) => data, None => return }; - match write_terminal_config(&id, &json.to_string()) { - Ok(_) => {}, - Err(e) => { - eprintln!("Internal Error: {}", e) - } + match secure::write_file(PERSIST_PATH, &format!("{}", id), &json.to_string()) { + Ok(_) => {}, + Err(e) => { + eprintln!("Internal Error: {}", e) + } }; } @@ -54,12 +53,9 @@ fn get_terminal_config() -> Option { Some(data) => data, None => return None }; - if !is_file_root(&path(&id)) { - return None; - } - let data = match std::fs::read_to_string(path(&id)) { - Ok(data) => data, - Err(_) => "{}".to_string() + let data = match secure::read_file(PERSIST_PATH, &format!("{}", id)) { + Some(data) => data, + None => "{}".to_string() }; let json: Value = match serde_json::from_str(&data) { Ok(data) => data, @@ -68,42 +64,6 @@ fn get_terminal_config() -> Option { Some(json) } -fn write_terminal_config(id: &i32, data: &str) -> Result<(), Box> { - std::fs::create_dir_all("/var/run/crab")?; - make_file_root("/var/run/crab")?; - std::fs::write(path(&id), "")?; - make_file_root(&path(&id))?; - std::fs::write(path(&id), data)?; - Ok(()) -} - -fn make_file_root(path: &str) -> Result<(), Box> { - unistd::chown(std::path::Path::new(path), Some(unistd::Uid::from(0)), Some(unistd::Gid::from(0)))?; - let metadata = std::fs::metadata(path)?; - let mut perms = metadata.permissions(); - perms.set_mode(0o100600); - fs::set_permissions(path, perms)?; - Ok(()) -} - -fn is_file_root(path: &str) -> bool { - let metadata = match std::fs::metadata(path) { - 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() == 0o100600 && metadata.st_uid() == 0 && metadata.st_gid() == 0; -} - fn now() -> u64 { return SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); } - -fn path(id: &i32) -> String { - return format!("/var/run/crab/{}", id); -} diff --git a/src/secure.rs b/src/secure.rs new file mode 100644 index 0000000..1fc3a11 --- /dev/null +++ b/src/secure.rs @@ -0,0 +1,51 @@ +use std::{os::{unix::prelude::PermissionsExt, linux::fs::MetadataExt}, fs, io::ErrorKind}; +use nix::unistd; + +pub fn write_file(dir: &str, file: &str, data: &str) -> Result<(), Box> { + std::fs::create_dir_all(dir)?; + make_file_root(dir)?; + let path = path(dir, file); + std::fs::write(&path, "")?; + make_file_root(&path)?; + std::fs::write(&path, data)?; + Ok(()) +} + +pub fn read_file(dir: &str, file: &str) -> Option { + let path = path(dir,file); + if !is_file_root(&path) { + return None; + } + match std::fs::read_to_string(&path) { + Ok(data) => return Some(data), + Err(_) => return None + }; +} + +fn make_file_root(path: &str) -> Result<(), Box> { + unistd::chown(std::path::Path::new(path), Some(unistd::Uid::from(0)), Some(unistd::Gid::from(0)))?; + let metadata = std::fs::metadata(path)?; + let mut perms = metadata.permissions(); + perms.set_mode(0o100600); + fs::set_permissions(path, perms)?; + Ok(()) +} + +fn is_file_root(path: &str) -> bool { + return check_file_permissions(0, 0, 0o100600, path); +} + +fn check_file_permissions(uid: u32, gid: u32, mode: u32, path: &str) -> bool { + let metadata = match std::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; +} + +fn path(dir: &str, file: &str) -> String { + return format!("{}/{}", dir, file); +} \ No newline at end of file