use std::{os, process::Stdio}; use owl::Serialize; use rumqttc::AsyncClient; use sage::PersonaIdentity; use crate::api::{ClientAction, ServerResponse, ServerResponses}; // Client MQTT pub async fn handle_mqtt(topic: String, data: Vec) { //println!("got real raw: {}", String::from_utf8_lossy(&data)); let pk = ( String::new(), crate::AGENT.get().unwrap().server_sign.clone(), ); let pk = pk.sign_key().unwrap(); let payload = crate::IDENTITY.get().unwrap().decrypt(&data, &pk).unwrap(); let action: ClientAction = serde_json::from_slice(&payload.payload).unwrap(); log::info!("Got action {action:?}"); match &action.action { crate::api::ClientActions::OSQuery(query) => { // TODO : run osquery log::info!("Doing osquery with {query}"); let res = osquery(&query); send_back( crate::MQTT.get().unwrap(), "respond", ServerResponse::of(&action, ServerResponses::OSQuery(res)), ) .await; } } } pub fn osquery(query: &str) -> String { let cmd = std::process::Command::new("osqueryi") .arg("--csv") .arg(query) .stdout(Stdio::piped()) .output() .unwrap(); String::from_utf8(cmd.stdout).unwrap() } /// Send something back to the server on `topic` pub async fn send_back(client: &AsyncClient, topic: &str, data: T) { let data = serde_json::to_string(&data).unwrap(); let pk = crate::AGENT.get().unwrap(); let pk = (pk.server_age.clone(), String::new()); let rec = pk.enc_key().unwrap(); let machine_id = std::fs::read_to_string("/etc/machine-id") .unwrap() .trim() .to_string(); let payload = crate::IDENTITY .get() .unwrap() .encrypt(data.as_bytes(), &rec); let topic = format!("{machine_id}/{topic}"); log::info!("Publish to {machine_id}{topic}"); client .publish(topic, rumqttc::QoS::AtMostOnce, true, payload) .await .unwrap(); }