reformat with rustfmt
Αυτή η υποβολή περιλαμβάνεται σε:
γονέας
fe0e531718
υποβολή
3bcf1fee82
2
rust/Cargo.lock
δημιουργημένο
2
rust/Cargo.lock
δημιουργημένο
@ -1,3 +1,5 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
107
rust/src/main.rs
107
rust/src/main.rs
@ -1,70 +1,74 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
use std::io::BufReader;
|
use std::ffi::CString;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
|
use std::io::BufReader;
|
||||||
use std::io::Error;
|
use std::io::Error;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::ffi::CString;
|
|
||||||
|
|
||||||
static PROFILEPATH : &'static str ="/etc/qsni.d/";
|
static PROFILEPATH: &'static str = "/etc/qsni.d/";
|
||||||
static NET_CLS_DIR : &'static str="/sys/fs/cgroup/net_cls/";
|
static NET_CLS_DIR: &'static str = "/sys/fs/cgroup/net_cls/";
|
||||||
extern crate nix;
|
extern crate nix;
|
||||||
|
|
||||||
|
fn ensure_outside_profile() {
|
||||||
fn ensure_outside_profile()
|
let fp =
|
||||||
{
|
std::fs::File::open("/proc/self/cgroup").expect("Error opening cgroups file of process");
|
||||||
let fp = std::fs::File::open("/proc/self/cgroup").expect("Error opening cgroups file of process");
|
|
||||||
let bf = BufReader::new(fp);
|
let bf = BufReader::new(fp);
|
||||||
for line in bf.lines() {
|
for line in bf.lines() {
|
||||||
let currentline = line.expect("Error while reading line");
|
let currentline = line.expect("Error while reading line");
|
||||||
let splitted : Vec<&str> = currentline.split(':').collect();
|
let splitted: Vec<&str> = currentline.split(':').collect();
|
||||||
if splitted.len() < 3 {
|
if splitted.len() < 3 {
|
||||||
panic!("Misformated line in cgroups file!");
|
panic!("Misformated line in cgroups file!");
|
||||||
}
|
}
|
||||||
if splitted[1] == "net_cls" && splitted[2] != "/" {
|
if splitted[1] == "net_cls" && splitted[2] != "/" {
|
||||||
panic!("already assigned to a net class, thus you can't use this binary to change that");
|
panic!(
|
||||||
|
"already assigned to a net class, thus you can't use this binary to change that"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_profile(profilepath : &str)
|
fn init_profile(profilepath: &str) {
|
||||||
{
|
|
||||||
use nix::unistd::*;
|
|
||||||
use nix::sys::wait::*;
|
use nix::sys::wait::*;
|
||||||
match fork()
|
use nix::unistd::*;
|
||||||
{
|
match fork() {
|
||||||
Ok(ForkResult::Parent { child, .. }) => {
|
Ok(ForkResult::Parent { child, .. }) => {
|
||||||
let waitresult = waitpid(child, Some(WaitPidFlag::empty())).expect("waitpid failed");
|
let waitresult = waitpid(child, Some(WaitPidFlag::empty())).expect("waitpid failed");
|
||||||
match waitresult
|
match waitresult {
|
||||||
{
|
WaitStatus::Exited(pid, code) => {
|
||||||
WaitStatus::Exited(pid, code) =>
|
if code != 0 {
|
||||||
{
|
panic!("profile setup script failed");
|
||||||
if code != 0
|
}
|
||||||
{
|
}
|
||||||
panic!("profile setup script failed");
|
_ => {}
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => { },
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(ForkResult::Child) => {
|
|
||||||
unsafe { nix::libc::clearenv(); }
|
|
||||||
nix::unistd::execv(&CString::new(profilepath).unwrap(), &[CString::new(profilepath).unwrap()]).expect("Faileed execv");},
|
|
||||||
Err(_) => println!("Fork failed"),
|
|
||||||
}
|
}
|
||||||
|
Ok(ForkResult::Child) => {
|
||||||
|
unsafe {
|
||||||
|
nix::libc::clearenv();
|
||||||
|
}
|
||||||
|
nix::unistd::execv(
|
||||||
|
&CString::new(profilepath).unwrap(),
|
||||||
|
&[CString::new(profilepath).unwrap()],
|
||||||
|
)
|
||||||
|
.expect("Faileed execv");
|
||||||
|
}
|
||||||
|
Err(_) => println!("Fork failed"),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign_to_profile(profilename : &str)
|
fn assign_to_profile(profilename: &str) {
|
||||||
{
|
|
||||||
let filename = NET_CLS_DIR.to_owned() + "/" + profilename + "/tasks";
|
let filename = NET_CLS_DIR.to_owned() + "/" + profilename + "/tasks";
|
||||||
let mut file = std::fs::OpenOptions::new().write(true).append(true).open(filename).expect("Failed to open net class file for writing");
|
let mut file = std::fs::OpenOptions::new()
|
||||||
|
.write(true)
|
||||||
|
.append(true)
|
||||||
|
.open(filename)
|
||||||
|
.expect("Failed to open net class file for writing");
|
||||||
let mypid = nix::unistd::getpid().to_string();
|
let mypid = nix::unistd::getpid().to_string();
|
||||||
write!(file, "{}", mypid).expect("An error occured while writing the pid");
|
write!(file, "{}", mypid).expect("An error occured while writing the pid");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main()
|
fn main() {
|
||||||
{
|
|
||||||
std::panic::set_hook(Box::new(|pi| {
|
std::panic::set_hook(Box::new(|pi| {
|
||||||
if let Some(s) = pi.payload().downcast_ref::<String>() {
|
if let Some(s) = pi.payload().downcast_ref::<String>() {
|
||||||
eprintln!("{}", s);
|
eprintln!("{}", s);
|
||||||
@ -72,20 +76,20 @@ fn main()
|
|||||||
eprintln!("Details:");
|
eprintln!("Details:");
|
||||||
eprintln!("{}", pi);
|
eprintln!("{}", pi);
|
||||||
}));
|
}));
|
||||||
let args : Vec<String> = std::env::args().collect();
|
let args: Vec<String> = std::env::args().collect();
|
||||||
if args.len() < 3 {
|
if args.len() < 3 {
|
||||||
println!("usage: qsni profile command [arguments...]");
|
println!("usage: qsni profile command [arguments...]");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
ensure_outside_profile();
|
ensure_outside_profile();
|
||||||
|
|
||||||
let profilename : &str = &args[1];
|
let profilename: &str = &args[1];
|
||||||
|
|
||||||
let profilefilepath = PROFILEPATH.to_owned() + profilename;
|
let profilefilepath = PROFILEPATH.to_owned() + profilename;
|
||||||
if ! std::path::Path::new(&profilefilepath).exists(){
|
if !std::path::Path::new(&profilefilepath).exists() {
|
||||||
eprintln!("The specified profile {} does not exist", profilename);
|
eprintln!("The specified profile {} does not exist", profilename);
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentuid = nix::unistd::getuid();
|
let currentuid = nix::unistd::getuid();
|
||||||
let currentgid = nix::unistd::getgid();
|
let currentgid = nix::unistd::getgid();
|
||||||
@ -99,7 +103,12 @@ fn main()
|
|||||||
nix::unistd::setuid(currentuid).expect("setuid failed during drop");
|
nix::unistd::setuid(currentuid).expect("setuid failed during drop");
|
||||||
|
|
||||||
let cmd = &args[2];
|
let cmd = &args[2];
|
||||||
let mut execargs : Vec<CString> = args.iter().skip(3).map(|s| { CString::new(s.as_str()).unwrap() }).collect();
|
let mut execargs: Vec<CString> = args
|
||||||
|
.iter()
|
||||||
|
.skip(3)
|
||||||
|
.map(|s| CString::new(s.as_str()).unwrap())
|
||||||
|
.collect();
|
||||||
execargs.insert(0, CString::new(cmd.as_str()).unwrap());
|
execargs.insert(0, CString::new(cmd.as_str()).unwrap());
|
||||||
nix::unistd::execvp(&CString::new(cmd.as_str()).unwrap(), &execargs).expect("execv failed launching your program");
|
nix::unistd::execvp(&CString::new(cmd.as_str()).unwrap(), &execargs)
|
||||||
|
.expect("execv failed launching your program");
|
||||||
}
|
}
|
||||||
|
Φόρτωση…
Αναφορά σε νέο ζήτημα
Block a user