feat: added mTLS auth for beacons

This commit is contained in:
Andrew Rioux
2025-02-13 01:24:33 -05:00
parent f9ff9f266a
commit 75b53f7191
12 changed files with 504 additions and 432 deletions

View File

@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use libc::{c_char, c_int, c_uchar, c_uint, c_ushort, c_void};
use libc::{c_char, c_int, c_uchar, c_uint, c_ushort};
pub const DLT_NULL: i32 = 0;
pub const DLT_EN10MB: i32 = 1;
@@ -161,17 +161,6 @@ extern "C" {
mask: u32,
) -> c_int;
pub fn pcap_setfilter(dev: *mut PcapDev, fp: *const BpfProgram) -> c_int;
pub fn pcap_loop(
p: *mut PcapDev,
cnt: c_int,
callback: unsafe extern "C" fn(
user: *mut c_void,
header: *const PktHeader,
data: *const u8,
),
user: *mut c_void,
) -> c_int;
pub fn pcap_breakloop(p: *mut PcapDev);
pub fn pcap_sendpacket(p: *mut PcapDev, buf: *const c_uchar, size: c_int) -> c_int;
pub fn pcap_setnonblock(dev: *mut PcapDev, nonblock: c_int, errbuf: *mut c_char) -> c_int;
pub fn pcap_get_selectable_fd(p: *mut PcapDev) -> c_int;

View File

@@ -122,32 +122,19 @@ pub struct BpfProgram {}
pub struct Interface {
dev_name: CString,
dev: *mut ffi::PcapDev,
absorbed: bool,
nonblocking: bool,
state: State,
}
impl Drop for Interface {
fn drop(&mut self) {
if !self.absorbed {
unsafe { ffi::pcap_close(self.dev) };
}
unsafe { ffi::pcap_close(self.dev) };
}
}
unsafe impl Send for Interface {}
unsafe impl Sync for Interface {}
struct ListenHandler<'a, F>
where
F: FnMut(&Interface, packets::EthernetPkt) -> error::Result<bool>,
{
packet_handler: F,
break_on_fail: bool,
fail_error: Option<error::Error>,
interface: &'a Interface,
}
impl Interface {
pub fn new(name: &str) -> error::Result<Interface> {
let mut errbuf = [0i8; ffi::PCAP_ERRBUF_SIZE];
@@ -162,7 +149,6 @@ impl Interface {
Ok(Interface {
dev_name,
dev,
absorbed: false,
nonblocking: false,
state: State::Disabled,
})
@@ -263,7 +249,6 @@ impl Interface {
Err(unsafe { ffi::pcap_geterr(self.dev) })?;
}
self.absorbed = true;
self.state = State::Activated;
Ok(())
@@ -390,85 +375,6 @@ impl Interface {
Ok(packets::EthernetPkt { data: rdata }.to_owned())
}
pub fn listen<F>(
&self,
packet_handler: F,
break_on_fail: bool,
packet_count: i32,
) -> error::Result<(Option<error::Error>, i32)>
where
F: FnMut(&Interface, packets::EthernetPkt) -> error::Result<bool>,
{
if self.state == State::Listening {
return Err(error::Error::IncorrectDeviceState(
State::Activated,
self.state,
));
}
unsafe extern "C" fn cback<F>(
user: *mut libc::c_void,
header: *const ffi::PktHeader,
data: *const u8,
) where
F: FnMut(&Interface, packets::EthernetPkt) -> error::Result<bool>,
{
let info = &mut *(user as *mut ListenHandler<F>);
let data = slice::from_raw_parts(data, (*header).caplen as usize);
if data.len() < 14 {
eprintln!(
" * Failed to get full packet, captured {} bytes",
data.len()
);
}
let result = (info.packet_handler)(info.interface, packets::EthernetPkt { data });
match result {
Err(e) => {
eprintln!(" * Packet handle error: {:?}", e);
if info.break_on_fail {
info.fail_error = Some(e);
ffi::pcap_breakloop(info.interface.dev);
}
}
Ok(b) => {
if b {
ffi::pcap_breakloop(info.interface.dev);
}
}
}
}
let interface = Interface {
dev_name: self.dev_name.clone(),
dev: self.dev,
absorbed: true,
nonblocking: self.nonblocking,
state: State::Listening,
};
let mut info = ListenHandler::<F> {
packet_handler,
break_on_fail,
fail_error: None,
interface: &interface,
};
let count = unsafe {
ffi::pcap_loop(
self.dev,
packet_count,
cback::<F>,
&mut info as *mut ListenHandler<F> as *mut libc::c_void,
)
};
Ok((info.fail_error, count))
}
#[cfg(target_os = "windows")]
pub fn get_wait_ready_callback(&self) -> WaitHandle {
let handle = unsafe { ffi::pcap_getevent(self.dev) };