feat: added windows support
factored out the packet parsing logic from libpcap will probably come back to linking against libpcap in a later version
This commit is contained in:
@@ -23,6 +23,7 @@ struct cap_user_data_t {
|
||||
inheritable: u32,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn get_username(uid: u32) -> anyhow::Result<Option<String>> {
|
||||
let passwd = std::fs::read_to_string("/etc/passwd")?;
|
||||
|
||||
@@ -41,6 +42,12 @@ fn get_username(uid: u32) -> anyhow::Result<Option<String>> {
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn get_username(uid: u32) -> anyhow::Result<Option<String>> {
|
||||
Ok(std::env::var("USERPROFILE").ok())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
||||
let mut header = cap_user_header_t {
|
||||
version: 0x20080522,
|
||||
@@ -85,6 +92,21 @@ fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn get_current_capabilities() -> anyhow::Result<Capabilities> {
|
||||
let userent = get_username(0)?;
|
||||
|
||||
Ok(Capabilities {
|
||||
operating_system: OperatingSystem::Windows,
|
||||
docker_container: false,
|
||||
docker_breakout: false,
|
||||
setuid: false,
|
||||
root: userent.as_deref() == Some("Administrator"),
|
||||
userent,
|
||||
transport: TransportType::Udp,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_capabilities() -> anyhow::Result<Capabilities> {
|
||||
get_current_capabilities()
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::{
|
||||
|
||||
use anyhow::{anyhow, bail, Context};
|
||||
use ed25519_dalek::{Keypair, Signature, Signer, Verifier};
|
||||
use pcap_sys::packets::EthernetPacket;
|
||||
use packets::EthernetPacket;
|
||||
use sparse_05_common::messages::{Capabilities, Command, Response, CONNECTED_MESSAGE};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -39,7 +39,7 @@ struct ConnectionInformation {
|
||||
|
||||
impl ConnectionInformation {
|
||||
fn format_udp_packet(&self, data: &[u8]) -> EthernetPacket {
|
||||
use pcap_sys::packets::*;
|
||||
use packets::*;
|
||||
|
||||
let udp_packet = UDPPacket::construct(54248, self.srcport, data);
|
||||
let ip_packet =
|
||||
@@ -89,10 +89,8 @@ pub fn spawn_connection_handler(
|
||||
connection_packet: EthernetPacket,
|
||||
connection_killer: Sender<(Ipv4Addr, u16)>,
|
||||
) -> anyhow::Result<ConnectionHandle> {
|
||||
println!("received connection, starting to authenticate");
|
||||
|
||||
let conninfo = {
|
||||
use pcap_sys::packets::*;
|
||||
use packets::*;
|
||||
let packet = connection_packet.pkt();
|
||||
|
||||
let Layer3Pkt::IPv4Pkt(ip_pkt) = packet.get_layer3_pkt()?;
|
||||
@@ -183,7 +181,7 @@ fn authenticate<F: Fn()>(
|
||||
|
||||
match packet_handler.recv_timeout(std::time::Duration::from_millis(250)) {
|
||||
Ok(p) => {
|
||||
use pcap_sys::packets::*;
|
||||
use packets::*;
|
||||
let p = p.pkt();
|
||||
let Layer3Pkt::IPv4Pkt(ip_pkt) = p.get_layer3_pkt()?;
|
||||
let Layer4Pkt::UDP(udp_pkt) = ip_pkt.get_layer4_packet()?;
|
||||
@@ -206,8 +204,19 @@ fn authenticate<F: Fn()>(
|
||||
}
|
||||
}
|
||||
|
||||
println!("Connection made!");
|
||||
handle_full_connection(capabilities, packet_handler, conninfo, packet_sender, close)
|
||||
}
|
||||
|
||||
fn handle_full_connection<F>(
|
||||
capabilities: Arc<Capabilities>,
|
||||
packet_handler: Receiver<EthernetPacket>,
|
||||
conninfo: ConnectionInformation,
|
||||
packet_sender: Sender<EthernetPacket>,
|
||||
close: F,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
F: Fn(),
|
||||
{
|
||||
close();
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -5,10 +5,11 @@ use std::{
|
||||
|
||||
use anyhow::{anyhow, bail};
|
||||
|
||||
use pcap_sys::packets::{self, EthernetPkt};
|
||||
use packets::{self, EthernetPkt};
|
||||
use sparse_05_common::messages::TransportType;
|
||||
|
||||
pub enum Interface {
|
||||
#[cfg(target_os = "linux")]
|
||||
RawUdp(pcap_sys::Interface<pcap_sys::DevActivated>, u16),
|
||||
Udp(UdpSocket, u16),
|
||||
}
|
||||
@@ -16,6 +17,7 @@ pub enum Interface {
|
||||
impl Interface {
|
||||
pub fn new(ttype: TransportType, port: u16) -> anyhow::Result<Interface> {
|
||||
match ttype {
|
||||
#[cfg(target_os = "linux")]
|
||||
TransportType::RawUdp => {
|
||||
let mut interfaces = pcap_sys::PcapDevIterator::new()?;
|
||||
let interface_name = interfaces
|
||||
@@ -61,6 +63,10 @@ impl Interface {
|
||||
|
||||
Ok(Interface::RawUdp(interface, port))
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
TransportType::RawUdp => {
|
||||
panic!("transport not available!");
|
||||
}
|
||||
TransportType::Udp => Ok(Interface::Udp(
|
||||
UdpSocket::bind(&format!("0.0.0.0:{port}"))?,
|
||||
port,
|
||||
@@ -70,6 +76,7 @@ impl Interface {
|
||||
|
||||
pub fn split(self) -> anyhow::Result<(InterfaceSender, InterfaceReceiver)> {
|
||||
match self {
|
||||
#[cfg(target_os = "linux")]
|
||||
Self::RawUdp(interface, port) => {
|
||||
let arc = Arc::new(interface);
|
||||
Ok((
|
||||
@@ -89,6 +96,7 @@ impl Interface {
|
||||
}
|
||||
|
||||
pub enum InterfaceSender {
|
||||
#[cfg(target_os = "linux")]
|
||||
RawUdp(Arc<pcap_sys::Interface<pcap_sys::DevActivated>>),
|
||||
Udp(UdpSocket),
|
||||
}
|
||||
@@ -96,9 +104,10 @@ pub enum InterfaceSender {
|
||||
impl InterfaceSender {
|
||||
pub fn sendpacket(&self, packet: EthernetPkt) -> anyhow::Result<()> {
|
||||
match self {
|
||||
#[cfg(target_os = "linux")]
|
||||
Self::RawUdp(interf) => Ok(interf.sendpacket(packet)?),
|
||||
Self::Udp(interf) => {
|
||||
use pcap_sys::packets::*;
|
||||
use packets::*;
|
||||
let Layer3Pkt::IPv4Pkt(ip_pkt) = packet.get_layer3_pkt()?;
|
||||
let Layer4Pkt::UDP(udp_pkt) = ip_pkt.get_layer4_packet()?;
|
||||
|
||||
@@ -113,6 +122,7 @@ impl InterfaceSender {
|
||||
}
|
||||
|
||||
pub enum InterfaceReceiver {
|
||||
#[cfg(target_os = "linux")]
|
||||
RawUdp(Arc<pcap_sys::Interface<pcap_sys::DevActivated>>),
|
||||
Udp(UdpSocket, u16),
|
||||
}
|
||||
@@ -123,6 +133,7 @@ impl InterfaceReceiver {
|
||||
F: FnMut(packets::EthernetPacket) -> anyhow::Result<()>,
|
||||
{
|
||||
match self {
|
||||
#[cfg(target_os = "linux")]
|
||||
Self::RawUdp(interf) => interf.listen(
|
||||
move |_, packet| {
|
||||
let _ = (f)(packet.to_owned());
|
||||
@@ -132,7 +143,7 @@ impl InterfaceReceiver {
|
||||
-1,
|
||||
),
|
||||
Self::Udp(interf, port) => loop {
|
||||
use pcap_sys::packets::*;
|
||||
use packets::*;
|
||||
|
||||
let mut buf = [0u8; 2000];
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ use std::{
|
||||
use anyhow::{bail, Context};
|
||||
use connection::ConnectionHandle;
|
||||
|
||||
use pcap_sys::packets::EthernetPacket;
|
||||
use packets::EthernetPacket;
|
||||
|
||||
use sparse_05_common::CONFIG_SEPARATOR;
|
||||
|
||||
use crate::connection::spawn_connection_handler;
|
||||
@@ -65,7 +66,7 @@ fn main() -> anyhow::Result<()> {
|
||||
|
||||
interface_receiver
|
||||
.listen(|pkt| {
|
||||
use pcap_sys::packets::*;
|
||||
use packets::*;
|
||||
|
||||
let pkt = pkt.pkt();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user