move secure files to secure handler

This commit is contained in:
Tyler Murphy 2022-11-09 16:48:36 -05:00
parent dcd28fd14a
commit 5ea42e3463
7 changed files with 69 additions and 57 deletions

2
Cargo.lock generated
View file

@ -34,7 +34,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "crab" name = "crab"
version = "0.0.4" version = "0.0.5"
dependencies = [ dependencies = [
"exec", "exec",
"nix", "nix",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "crab" name = "crab"
version = "0.0.4" version = "0.0.5"
edition = "2021" edition = "2021"
[dependencies] [dependencies]

View file

@ -1,6 +1,6 @@
pkgbase = crab pkgbase = crab
pkgdesc = A rusty permission authentication system pkgdesc = A rusty permission authentication system
pkgver = 0.0.4 pkgver = 0.0.5
pkgrel = 1 pkgrel = 1
url = https://g.tylerm.dev/tylermurphy534/crab.git url = https://g.tylerm.dev/tylermurphy534/crab.git
arch = x86_64 arch = x86_64

View file

@ -1,6 +1,6 @@
# Maintainer: Tyler Murphy <tylermurphy534@gmail.com> # Maintainer: Tyler Murphy <tylermurphy534@gmail.com>
pkgname=crab pkgname=crab
pkgver=0.0.4 pkgver=0.0.5
pkgrel=1 pkgrel=1
pkgdesc="A rusty permission authentication system" pkgdesc="A rusty permission authentication system"
arch=('x86_64' 'i686') arch=('x86_64' 'i686')

View file

@ -15,6 +15,7 @@ const ERROR_RUN_ROOT: u8 = 6;
mod persist; mod persist;
mod flags; mod flags;
mod help; mod help;
mod secure;
fn main() -> ExitCode { fn main() -> ExitCode {
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
@ -26,7 +27,7 @@ fn main() -> ExitCode {
} }
}; };
if flags.version { if flags.version {
println!("crab version 0.0.4"); println!("crab version 0.0.5");
return ExitCode::SUCCESS; return ExitCode::SUCCESS;
} }
if flags.help { if flags.help {

View file

@ -1,11 +1,10 @@
use std::fs;
use std::os::linux::fs::MetadataExt;
use std::os::unix::prelude::PermissionsExt;
use std::time::SystemTime; use std::time::SystemTime;
use nix::unistd;
use serde_json::Value; use serde_json::Value;
use crate::secure;
const PERSIST_TIME: u64 = 60 * 3; const PERSIST_TIME: u64 = 60 * 3;
const PERSIST_PATH: &str = "/var/run/crab";
pub fn get_persist(user: &str) -> bool { pub fn get_persist(user: &str) -> bool {
let json = match get_terminal_config() { let json = match get_terminal_config() {
@ -16,7 +15,7 @@ pub fn get_persist(user: &str) -> bool {
Some(data) => data, Some(data) => data,
None => return false None => return false
}; };
return now() - timestamp < PERSIST_TIME && timestamp < now(); return now() - timestamp < PERSIST_TIME && timestamp - 1 < now();
} }
pub fn set_persist(user: &str) { pub fn set_persist(user: &str) {
@ -29,7 +28,7 @@ pub fn set_persist(user: &str) {
Some(data) => data, Some(data) => data,
None => return None => return
}; };
match write_terminal_config(&id, &json.to_string()) { match secure::write_file(PERSIST_PATH, &format!("{}", id), &json.to_string()) {
Ok(_) => {}, Ok(_) => {},
Err(e) => { Err(e) => {
eprintln!("Internal Error: {}", e) eprintln!("Internal Error: {}", e)
@ -54,12 +53,9 @@ fn get_terminal_config() -> Option<Value> {
Some(data) => data, Some(data) => data,
None => return None None => return None
}; };
if !is_file_root(&path(&id)) { let data = match secure::read_file(PERSIST_PATH, &format!("{}", id)) {
return None; Some(data) => data,
} None => "{}".to_string()
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) { let json: Value = match serde_json::from_str(&data) {
Ok(data) => data, Ok(data) => data,
@ -68,42 +64,6 @@ fn get_terminal_config() -> Option<Value> {
Some(json) Some(json)
} }
fn write_terminal_config(id: &i32, data: &str) -> Result<(), Box<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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 { 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();
} }
fn path(id: &i32) -> String {
return format!("/var/run/crab/{}", id);
}

51
src/secure.rs Normal file
View file

@ -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<dyn std::error::Error>> {
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<String> {
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<dyn std::error::Error>> {
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);
}