niver
/
maniver
Archived
1
0
Fork 0

Initial commit

main
Miraty 2 years ago
commit 030bbcc100
  1. 116
      Cargo.lock
  2. 11
      Cargo.toml
  3. 262
      src/main.rs

116
Cargo.lock generated

@ -0,0 +1,116 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "colored"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929"
[[package]]
name = "maniver"
version = "0.1.0-dev"
dependencies = [
"colored",
"regex",
]
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "regex"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]]
name = "thread_local"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
dependencies = [
"lazy_static",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

@ -0,0 +1,11 @@
[package]
name = "maniver"
version = "0.1.0-dev"
authors = ["Miraty <miraty@antopie.org>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
regex = "1"
colored = "2"

@ -0,0 +1,262 @@
use std::env;
use regex::Regex;
use std::io::prelude::*;
use std::process::{Command, Stdio};
use colored::*;
use std::fs;
fn main() {
let args: Vec<String> = env::args().collect();
let tool = args[1].to_string();
match tool.as_ref() {
"setup-user" => setup_user(args[2].to_string(), args[3].to_string()),
"reload-nginx" => reload_nginx(),
"reload-tor" => reload_tor(),
"le-install" => le_install(args[2].to_string()),
"export-tor" => export_tor(args[2].to_string(), args[3].to_string()),
_ => println!("{}{}{}{}\n{}{}{}{}{}{}{}{}{}", "maniver : ", "ERREUR : ".red(), tool.red(), " : argument non reconnu".red(), " > Utilisez ", "setup-user <user> <password>".italic().green(), ", ", "reload-nginx".italic().green(), ", ", "reload-tor".italic().green(), " ou ", "le-install <domaine>".italic().green(), " comme argument"),
}
}
fn export_tor(username: String, dir: String) {
let mut src_path: String = "/var/lib/tor/niver/".to_owned();
src_path += &dir.to_string();
src_path += &"/hostname".to_string().to_owned();
let mut dest_path: String = "/srv/hyper/".to_owned();
dest_path += &username.to_string();
dest_path += &"/hyper/".to_string().to_owned();
dest_path += &dir.to_string();
dest_path += &"/hostname".to_string().to_owned();
match fs::copy(src_path, &dest_path) {
Err(why) => panic!("Erreur lors d'une copie de fichier (fs::copy) : {}", why),
Ok(process) => process,
};
let output = Command::new("/usr/bin/chown")
.arg("www-data:www-data")
.arg(dest_path)
.output()
.expect("failed to execute process");
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
//let output = Command::new("/usr/bin/cp")
// .arg(src_path)
// .arg(dest_path)
// .output()
// .expect("failed to execute process");
//println!("status: {}", output.status);
//println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
//println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
//assert!(output.status.success());
}
fn le_install(domain: String) {
let output = Command::new("/usr/bin/certbot")
.arg("--nginx")
.arg("-d")
.arg(&domain)
.output()
.expect("failed to execute process");
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
fn reload_nginx() {
let output = Command::new("/usr/bin/systemctl")
.arg("reload")
.arg("nginx")
.output()
.expect("Error while reloading Nginx config");
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
fn reload_tor() {
Command::new("/usr/bin/systemctl")
.arg("reload")
.arg("tor@default")
.output()
.expect("Error while reloading Tor config");
//let output = Command::new("/usr/bin/chown")
// .arg("-R")
// .arg("www-data:www-data")
// .arg("/var/lib/tor/niver")
// .output()
// .expect("failed to execute process");
//println!("status: {}", output.status);
//println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
//println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
//assert!(output.status.success());
}
fn setup_user(username: String, password: String) {
if username.chars().count() < 32 {
if password.chars().count() < 1024 {
if is_string_lowercase(username.to_string()) {
let username1 = &username;
let username2 = &username;
let username3 = &username;
let username4 = &username;
newser(username1.to_string());
pwd(username2.to_string(), password);
chroot(username3.to_string());
quota(username4.to_string());
} else {
println!("Erreur : l'username doit être composé de lettres minuscules uniquement");
}
} else {
println!("Erreur : le mot de passe doit faire moins de 1024 caractères");
}
} else {
println!("Erreur : l'username doit faire moins de 32 caractères");
}
}
// Set disk usage limit to the user by copying another user quota
fn quota(username: String) {
let output = Command::new("/usr/sbin/edquota")
.arg("-p")
.arg("testfract")
.arg(&username)
.output()
.expect("failed to execute process");
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
// Chown /srv/hyper/username to root:root
fn chroot(username: String) {
if username.chars().count() < 32 {
let mut path = "/srv/hyper/".to_string();
path += &username;
let output = Command::new("/usr/bin/chown")
.arg("root:root")
.arg(&path)
.output()
.expect("Failed to chown /srv/hyper/<username> to root:root");
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
let output = Command::new("/usr/bin/chmod")
.arg("755")
.arg(path)
.output()
.expect("Failed to chmod /srv/hyper/<username> to 755");
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
} else {
println!("Erreur : l'username doit faire moins de 32 caractères");
}
}
// Creates a new user in the group 'hyper', which is available only over SFTP
fn newser(username: String) {
let output = Command::new("/usr/sbin/useradd")
.arg(&username)
.arg("--create-home")
.arg("--base-dir")
.arg("/srv/hyper")
.arg("--gid")
.arg("hyper")
.arg("--shell")
.arg("/usr/sbin/nologin")
.output()
.expect("failed to execute process");
println!("status: {}", output.status);
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
assert!(output.status.success());
}
// Changes password of the newly created user
fn pwd(username: String, password: String) {
// line must be in the form username:password
let mut line: String = username.to_string();
line += &":".to_string().to_owned();
line += &password.to_owned();
let process = match Command::new("/usr/sbin/chpasswd")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn() {
Err(why) => panic!("couldn't spawn chpasswd: {}", why),
Ok(process) => process,
};
match process.stdin.unwrap().write_all(line.as_bytes()) {
Err(why) => panic!("couldn't write to chpasswd stdin: {}", why),
Ok(_) => println!("sent username:password to chpasswd"),
}
let mut s = String::new();
match process.stdout.unwrap().read_to_string(&mut s) {
Err(why) => panic!("couldn't read chpasswd stdout: {}", why),
Ok(_) => print!("chpasswd responded with:\n{}", s),
}
}
fn is_string_lowercase(stri: String) -> bool {
let re = Regex::new("^[[:lower:]]+$").unwrap();
let matching = re.is_match(&stri);
if matching {
return true;
} else {
return false;
}
}