use std::time::SystemTime; use serde_json::Value; use crate::secure; const PERSIST_TIME: u64 = 60 * 3; const PERSIST_PATH: &str = "/var/run/crab"; /// Returns true or false if a user is currently persisted from /// a prior authentication. If the persist file had been tampered /// with, or not trusted, it will be ignored, and return false. /// #### Arguments /// * `user` - The user to check if is persisted /// #### Returns /// * `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(); } /// Updates the current sessions persist file /// #### 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); } }; } /// Gets the current session that crab is running in /// #### Returns /// * `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) } /// Gets the current persist file for the current session /// #### Returns /// * `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) } // Gets the current time in seconds since the Unix Epoch fn now() -> u64 { return SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs(); }