1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
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;
const PERSIST_TIME: u64 = 60 * 3;
pub fn get_persist(user: &str) -> bool {
let json = match get_terminal_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 < now();
}
pub fn set_persist(user: &str) {
let mut json = match get_terminal_config() {
Some(data) => data,
None => return
};
json[user] = Value::from(now());
let id = match get_terminal_process() {
Some(data) => data,
None => return
};
match write_terminal_config(&id, &json.to_string()) {
Ok(_) => {},
Err(e) => {
eprintln!("Internal Error: {}", e)
}
};
}
fn get_terminal_process() -> Option<i32> {
let id: i32 = match std::process::id().try_into() {
Ok(data) => data,
Err(_) => return None
};
let stat = match procinfo::pid::stat(id) {
Ok(data) => data,
Err(_) => return None
};
Some(stat.session)
}
fn get_terminal_config() -> Option<Value> {
let id = match get_terminal_process() {
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 json: Value = match serde_json::from_str(&data) {
Ok(data) => data,
Err(_) => return None
};
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 {
return SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs();
}
fn path(id: &i32) -> String {
return format!("/var/run/crab/{}", id);
}
|