trifid/tfclient/src/nebulaworker.rs

198 lines
6.6 KiB
Rust
Raw Normal View History

2023-03-22 18:34:06 +00:00
// Code to handle the nebula worker
2023-03-30 16:28:34 +00:00
use crate::config::{load_cdata, NebulaConfig, TFClientConfig};
2023-03-22 18:34:06 +00:00
use crate::daemon::ThreadMessageSender;
2023-06-26 02:00:36 +00:00
use crate::dirs::{nebula_yml};
2023-05-14 17:47:49 +00:00
use log::{debug, error, info};
use std::error::Error;
use std::fs;
use std::sync::mpsc::Receiver;
2023-06-26 02:00:36 +00:00
use nebula_ffi::NebulaInstance;
use crate::util::shutdown;
2023-03-22 18:34:06 +00:00
pub enum NebulaWorkerMessage {
Shutdown,
2023-03-31 12:33:02 +00:00
ConfigUpdated,
2023-05-14 17:47:49 +00:00
WakeUp,
2023-03-22 18:34:06 +00:00
}
2023-03-30 14:43:09 +00:00
fn insert_private_key(instance: &str) -> Result<(), Box<dyn Error>> {
2023-06-26 02:00:36 +00:00
if !nebula_yml(instance).exists() {
2023-03-30 16:13:29 +00:00
return Ok(()); // cant insert private key into a file that does not exist - BUT. we can gracefully handle nebula crashing - we cannot gracefully handle this fn failing
}
2023-03-30 14:43:09 +00:00
let cdata = load_cdata(instance)?;
let key = cdata.dh_privkey.ok_or("Missing private key")?;
2023-05-14 17:47:49 +00:00
let config_str = fs::read_to_string(
2023-06-26 02:00:36 +00:00
nebula_yml(instance),
2023-05-14 17:47:49 +00:00
)?;
2023-03-30 14:43:09 +00:00
let mut config: NebulaConfig = serde_yaml::from_str(&config_str)?;
2023-03-30 16:13:29 +00:00
config.pki.key = Some(String::from_utf8(key)?);
2023-03-30 14:43:09 +00:00
debug!("inserted private key into config: {:?}", config);
let config_str = serde_yaml::to_string(&config)?;
2023-05-14 17:47:49 +00:00
fs::write(
2023-06-26 02:00:36 +00:00
nebula_yml(instance),
2023-05-14 17:47:49 +00:00
config_str,
)?;
2023-03-30 14:43:09 +00:00
Ok(())
}
2023-05-14 17:47:49 +00:00
pub fn nebulaworker_main(
_config: TFClientConfig,
instance: String,
2023-06-26 02:00:36 +00:00
transmitter: ThreadMessageSender,
2023-05-14 17:47:49 +00:00
rx: Receiver<NebulaWorkerMessage>,
) {
2023-06-26 02:00:36 +00:00
let cdata = match load_cdata(&instance) {
2023-03-30 11:29:02 +00:00
Ok(data) => data,
Err(e) => {
error!("unable to load cdata: {}", e);
error!("nebula thread exiting with error");
return;
}
};
2023-03-30 14:43:09 +00:00
info!("fixing config...");
match insert_private_key(&instance) {
Ok(_) => {
info!("config fixed (private-key embedded)");
2023-05-14 17:47:49 +00:00
}
2023-03-30 14:43:09 +00:00
Err(e) => {
error!("unable to fix config: {}", e);
error!("nebula thread exiting with error");
return;
}
}
2023-06-26 02:00:36 +00:00
let mut nebula: Option<NebulaInstance> = None;
2023-03-30 16:13:29 +00:00
2023-06-26 02:00:36 +00:00
if cdata.creds.is_none() {
error!("not enrolled, cannot start nebula");
} else {
info!("setting up nebula...");
nebula = Some(match NebulaInstance::new(nebula_yml(&instance).as_path(), false) {
Ok(i) => {
info!("nebula setup");
info!("starting nebula...");
match i.start() {
Ok(_) => (),
2023-03-30 16:13:29 +00:00
Err(e) => {
2023-06-26 02:00:36 +00:00
error!("error starting Nebula: {}", e);
2023-03-30 16:13:29 +00:00
error!("nebula thread exiting with error");
2023-06-26 02:00:36 +00:00
shutdown(&transmitter);
2023-03-30 16:13:29 +00:00
return;
}
2023-06-26 02:00:36 +00:00
}
i
},
Err(e) => {
error!("error setting up Nebula: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
2023-03-30 16:13:29 +00:00
}
2023-06-26 02:00:36 +00:00
});
info!("nebula process started");
}
loop {
2023-03-31 12:33:02 +00:00
match rx.recv() {
2023-05-14 17:47:49 +00:00
Ok(msg) => match msg {
NebulaWorkerMessage::WakeUp => {
continue;
}
NebulaWorkerMessage::Shutdown => {
info!("recv on command socket: shutdown, stopping");
2023-06-26 02:00:36 +00:00
info!("shutting down nebula");
if let Some(i) = nebula.as_ref() {
match i.stop() {
Ok(_) => (),
Err(e) => {
error!("error stopping Nebula: {}", e);
error!("nebula thread exiting with error");
return;
}
2023-03-30 14:43:09 +00:00
}
2023-05-14 17:47:49 +00:00
}
2023-06-26 02:00:36 +00:00
2023-05-14 17:47:49 +00:00
info!("nebula shut down");
break;
}
NebulaWorkerMessage::ConfigUpdated => {
2023-06-26 02:00:36 +00:00
info!("our configuration has been updated - reloading");
2023-05-14 17:47:49 +00:00
debug!("fixing config...");
match insert_private_key(&instance) {
Ok(_) => {
debug!("config fixed (private-key embedded)");
}
Err(e) => {
error!("unable to fix config: {}", e);
error!("nebula thread exiting with error");
return;
}
}
2023-06-26 02:00:36 +00:00
if let Some(i) = nebula.as_ref() {
debug!("reloading nebula");
match i.reload_config() {
Ok(_) => (),
Err(e) => {
error!("error reloading Nebula config: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
2023-05-14 17:47:49 +00:00
}
2023-06-26 02:00:36 +00:00
debug!("config reloaded");
} else {
debug!("detected enrollment, starting nebula for the first time");
info!("setting up nebula...");
nebula = Some(match NebulaInstance::new(nebula_yml(&instance).as_path(), false) {
Ok(i) => {
info!("nebula setup");
info!("starting nebula...");
match i.start() {
Ok(_) => (),
Err(e) => {
error!("error starting Nebula: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
}
i
},
Err(e) => {
error!("error setting up Nebula: {}", e);
error!("nebula thread exiting with error");
shutdown(&transmitter);
return;
}
});
info!("nebula process started");
}
debug!("nebula process reloaded");
}
},
Err(e) => {
2023-03-31 12:33:02 +00:00
error!("nebulaworker command socket errored: {}", e);
2023-06-26 02:00:36 +00:00
shutdown(&transmitter);
2023-03-31 12:33:02 +00:00
return;
}
}
}
2023-05-14 17:47:49 +00:00
}