Skip to content

Commit

Permalink
Add more Linux tests
Browse files Browse the repository at this point in the history
  • Loading branch information
MEhrn00 committed Feb 25, 2024
1 parent 2146434 commit 2870ffb
Show file tree
Hide file tree
Showing 17 changed files with 801 additions and 392 deletions.
7 changes: 1 addition & 6 deletions Payload_Type/thanatos/agent/cryptolib/src/hash/internal.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(clippy::new_without_default)]
use sha2::Digest;

#[repr(transparent)]
Expand All @@ -17,12 +18,6 @@ impl Sha256 {
}
}

impl Default for Sha256 {
fn default() -> Self {
Self::new()
}
}

#[cfg(test)]
mod tests {
use super::Sha256;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![allow(clippy::new_without_default)]

#[repr(transparent)]
pub struct Sha256(openssl::sha::Sha256);

Expand All @@ -15,12 +17,6 @@ impl Sha256 {
}
}

impl Default for Sha256 {
fn default() -> Self {
Self::new()
}
}

#[cfg(test)]
mod tests {
use super::Sha256;
Expand Down
11 changes: 11 additions & 0 deletions Payload_Type/thanatos/agent/errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,14 @@ impl ThanatosError {
Self::OsError(e.code().0)
}
}

#[cfg(test)]
mod tests {
use crate::ThanatosError;

#[test]
fn debug_coverage() {
let e = ThanatosError::OsError(0);
dbg!(e);
}
}
47 changes: 45 additions & 2 deletions Payload_Type/thanatos/agent/ffiwrappers/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
pub enum FfiError {
OsError(i32),
NoNullTerminator,
InteriorNull,
UserNotFound,

#[cfg(target_os = "linux")]
GaiError(EaiError),
Expand Down Expand Up @@ -37,7 +38,7 @@ impl FfiError {
}
}

#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
#[repr(i32)]
#[cfg(target_os = "linux")]
pub enum EaiError {
Expand Down Expand Up @@ -80,3 +81,45 @@ fn libc_errno() -> i32 {
// is guaranteed to be aligned and non-NULL
unsafe { *libc::__errno_location() }
}

#[cfg(test)]
mod tests {
use super::FfiError;

#[test]
fn debug_coverage() {
let d = FfiError::OsError(0);
dbg!(d);
}

#[cfg(target_os = "linux")]
#[test]
fn linux_os_error() {
let c = FfiError::os_error();
assert_eq!(c, FfiError::OsError(0));
}

#[cfg(target_os = "linux")]
#[test]
fn eai_error_code() {
use super::EaiError;

let code_mapping = [
(libc::EAI_BADFLAGS, EaiError::BadFlags),
(libc::EAI_NONAME, EaiError::NoName),
(libc::EAI_AGAIN, EaiError::Again),
(libc::EAI_FAIL, EaiError::Fail),
(libc::EAI_FAMILY, EaiError::Family),
(libc::EAI_SOCKTYPE, EaiError::SockType),
(libc::EAI_SERVICE, EaiError::Service),
(libc::EAI_MEMORY, EaiError::Memory),
(libc::EAI_OVERFLOW, EaiError::Overflow),
(libc::EAI_SYSTEM, EaiError::System(0)),
(0, EaiError::Other(0)),
];

for (code, eai) in code_mapping {
assert_eq!(EaiError::from_code(code), eai);
}
}
}
123 changes: 99 additions & 24 deletions Payload_Type/thanatos/agent/ffiwrappers/src/linux/addrinfo.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use std::{ffi::CStr, marker::PhantomData, ptr::NonNull};
use std::{
ffi::{CStr, CString},
marker::PhantomData,
ptr::NonNull,
};

use crate::errors::{EaiError, FfiError};
use bitflags::bitflags;
Expand Down Expand Up @@ -34,7 +38,38 @@ pub struct AddrInfoList {
}

impl AddrInfoList {
pub fn new(
pub fn new() -> Result<AddrInfoList, FfiError> {
let addr = CString::new("0.0.0.0").map_err(|_| FfiError::InteriorNull)?;
Self::with_opts(
Some(&addr),
None,
Some(Hints {
socktype: SockType::Any,
flags: AiFlags::ALL | AiFlags::V4MAPPED,
family: Family::Unspec,
}),
)
}

pub fn with_nodename(node: &str) -> Result<AddrInfoList, FfiError> {
let nodename = CString::new(node).map_err(|_| FfiError::InteriorNull)?;
Self::with_opts(
Some(&nodename),
None,
Some(Hints {
socktype: SockType::Any,
flags: AiFlags::ALL | AiFlags::V4MAPPED,
family: Family::Unspec,
}),
)
}

pub fn with_hints(hints: Hints) -> Result<AddrInfoList, FfiError> {
let addr = CString::new("0.0.0.0").map_err(|_| FfiError::InteriorNull)?;
Self::with_opts(Some(&addr), None, Some(hints))
}

pub fn with_opts(
node: Option<&CStr>,
service: Option<&CStr>,
hints: Option<Hints>,
Expand Down Expand Up @@ -67,12 +102,19 @@ impl AddrInfoList {
})
}

pub const fn first(&self) -> AddrInfo {
AddrInfo {
pub const fn first(&self) -> AddrInfoEntry {
AddrInfoEntry {
addrinfo: self.addrinfo,
_marker: PhantomData,
}
}

pub const fn iter(&self) -> AddrInfoListIterator {
AddrInfoListIterator {
addrinfo: self.addrinfo.as_ptr(),
_marker: PhantomData,
}
}
}

impl Drop for AddrInfoList {
Expand All @@ -82,12 +124,32 @@ impl Drop for AddrInfoList {
}

#[repr(transparent)]
pub struct AddrInfo<'a> {
pub struct AddrInfoListIterator<'a> {
addrinfo: *mut libc::addrinfo,
_marker: PhantomData<&'a libc::addrinfo>,
}

impl<'a> Iterator for AddrInfoListIterator<'a> {
type Item = AddrInfoEntry<'a>;

fn next(&mut self) -> Option<Self::Item> {
let addrinfo = NonNull::new(self.addrinfo)?;
self.addrinfo = unsafe { addrinfo.as_ref().ai_next };

Some(AddrInfoEntry {
addrinfo,
_marker: PhantomData,
})
}
}

#[repr(transparent)]
pub struct AddrInfoEntry<'a> {
addrinfo: NonNull<libc::addrinfo>,
_marker: PhantomData<&'a libc::addrinfo>,
}

impl<'a> AddrInfo<'a> {
impl<'a> AddrInfoEntry<'a> {
pub const fn ai_flags(&self) -> i32 {
unsafe { self.addrinfo.as_ref().ai_flags }
}
Expand All @@ -104,29 +166,42 @@ impl<'a> AddrInfo<'a> {
unsafe { self.addrinfo.as_ref().ai_protocol }
}

pub fn canonname(&self) -> &str {
unsafe {
CStr::from_ptr(self.addrinfo.as_ref().ai_canonname)
.to_str()
.unwrap_unchecked()
pub fn canonname(&self) -> Result<&str, FfiError> {
let name = unsafe { self.addrinfo.as_ref().ai_canonname };
if name.is_null() {
Err(FfiError::CanonNameNotFound)
} else {
unsafe { CStr::from_ptr(name).to_str() }.map_err(|_| FfiError::CanonNameNotFound)
}
}
}

impl<'a> From<NonNull<libc::addrinfo>> for AddrInfo<'a> {
fn from(value: NonNull<libc::addrinfo>) -> Self {
AddrInfo {
addrinfo: value,
_marker: PhantomData,
}
}
}
#[cfg(test)]
mod tests {
use super::AddrInfoList;

impl<'a> Iterator for AddrInfo<'a> {
type Item = AddrInfo<'a>;
#[test]
fn iter_test() {
let interfaces = AddrInfoList::new().unwrap();

fn next(&mut self) -> Option<Self::Item> {
self.addrinfo = NonNull::new(unsafe { self.addrinfo.as_ref().ai_next })?;
Some(self.addrinfo.into())
let first_interface = interfaces.first();
let first_iter_interface = interfaces.iter().next().unwrap();

assert_eq!(first_interface.ai_flags(), first_iter_interface.ai_flags());

assert_eq!(
first_interface.ai_family(),
first_iter_interface.ai_family()
);

assert_eq!(
first_interface.ai_socktype(),
first_iter_interface.ai_socktype()
);

assert_eq!(
first_interface.ai_protocol(),
first_iter_interface.ai_protocol()
);
}
}
Loading

0 comments on commit 2870ffb

Please sign in to comment.