diff --git a/build.rs b/build.rs index 13a2929..9997442 100644 --- a/build.rs +++ b/build.rs @@ -1,4 +1,4 @@ fn main() { println!("cargo:rustc-link-lib=dylib=EndpointSecurity"); println!("cargo:rustc-link-lib=dylib=bsm"); -} \ No newline at end of file +} diff --git a/examples/process_monitor.rs b/examples/process_monitor.rs index 449f746..04a5bc6 100644 --- a/examples/process_monitor.rs +++ b/examples/process_monitor.rs @@ -1,7 +1,8 @@ -#[macro_use] extern crate log; +#[macro_use] +extern crate log; -use endpointsecurity::*; use crossbeam_channel::unbounded as channel; +use endpointsecurity::*; fn main() { env_logger::init(); @@ -16,7 +17,10 @@ fn main() { } }; - if !client.set_subscriptions_to(&vec![SupportedEsEvent::NotifyExec, SupportedEsEvent::NotifyFork]) { + if !client.set_subscriptions_to(&vec![ + SupportedEsEvent::NotifyExec, + SupportedEsEvent::NotifyFork, + ]) { error!("Could not subscribe to NotifyExec event (not sure why)"); return; } @@ -34,20 +38,20 @@ fn main() { EsEvent::NotifyExec(event) => { match serde_json::to_string(&event) { Ok(json) => println!("{}", json), - Err(e) => error!("Error serializing event: {}", e) + Err(e) => error!("Error serializing event: {}", e), } //println!("Type: Exec, PID: {}, Path: {}, CDHash: {}, Args: {}", event.target.pid, event.target.executable.path, event.target.cdhash, event.args.join(" ")); - }, + } EsEvent::NotifyFork(event) => { match serde_json::to_string(&event) { Ok(json) => println!("{}", json), - Err(e) => error!("Error serializing event: {}", e) + Err(e) => error!("Error serializing event: {}", e), } //println!("Type: Fork, PID: {}, Path: {}, CDHash: {}", event.child.pid, event.child.executable.path, event.child.cdhash); - }, + } _ => { continue; } } } -} \ No newline at end of file +} diff --git a/examples/signal_intercept.rs b/examples/signal_intercept.rs index fa204b3..8c796a1 100644 --- a/examples/signal_intercept.rs +++ b/examples/signal_intercept.rs @@ -1,7 +1,8 @@ -#[macro_use] extern crate log; +#[macro_use] +extern crate log; -use endpointsecurity::*; use crossbeam_channel::unbounded as channel; +use endpointsecurity::*; fn main() { env_logger::init(); @@ -39,7 +40,11 @@ fn main() { // Backout of all signals that don't affect EsClients as quickly as possible // to reduce impact to system responsiveness if !event.target.is_es_client { - client.respond_to_auth_event(&message, &EsAuthResult::Allow, &EsCacheResult::No); + client.respond_to_auth_event( + &message, + &EsAuthResult::Allow, + &EsCacheResult::No, + ); continue; } @@ -48,13 +53,13 @@ fn main() { println!("Received a signal to my EsClient, disallowing that!"); client.respond_to_auth_event(&message, &EsAuthResult::Deny, &EsCacheResult::No); } - + // This is a signal to someone else's EsClient. Don't touch it client.respond_to_auth_event(&message, &EsAuthResult::Allow, &EsCacheResult::No); - }, + } _ => { continue; } } } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 8787e1c..f44bbc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,11 +8,12 @@ include!("./eps_bindings.rs"); mod parsers; extern crate libc; -#[macro_use] extern crate log; +#[macro_use] +extern crate log; +use crossbeam_channel::Sender; use std::collections::HashSet; use std::fmt; -use crossbeam_channel::Sender; use std::sync::{Arc, Mutex}; use serde::{Deserialize, Serialize}; @@ -23,29 +24,25 @@ use block::*; // Values use { - es_clear_cache_result_t_ES_CLEAR_CACHE_RESULT_SUCCESS as ES_CLEAR_CACHE_RESULT_SUCCESS, - es_clear_cache_result_t_ES_CLEAR_CACHE_RESULT_ERR_INTERNAL as ES_CLEAR_CACHE_RESULT_ERR_INTERNAL, - es_clear_cache_result_t_ES_CLEAR_CACHE_RESULT_ERR_THROTTLE as ES_CLEAR_CACHE_RESULT_ERR_THROTTLE, - - es_return_t_ES_RETURN_SUCCESS as ES_RETURN_SUCCESS, - es_auth_result_t_ES_AUTH_RESULT_ALLOW as ES_AUTH_RESULT_ALLOW, es_auth_result_t_ES_AUTH_RESULT_DENY as ES_AUTH_RESULT_DENY, - - es_new_client_result_t_ES_NEW_CLIENT_RESULT_SUCCESS as ES_NEW_CLIENT_SUCCESS, - es_new_client_result_t_ES_NEW_CLIENT_RESULT_ERR_INVALID_ARGUMENT as ES_NEW_CLIENT_ERROR_INVALID_ARGUMENT, + es_clear_cache_result_t_ES_CLEAR_CACHE_RESULT_ERR_INTERNAL as ES_CLEAR_CACHE_RESULT_ERR_INTERNAL, + es_clear_cache_result_t_ES_CLEAR_CACHE_RESULT_ERR_THROTTLE as ES_CLEAR_CACHE_RESULT_ERR_THROTTLE, + es_clear_cache_result_t_ES_CLEAR_CACHE_RESULT_SUCCESS as ES_CLEAR_CACHE_RESULT_SUCCESS, es_new_client_result_t_ES_NEW_CLIENT_RESULT_ERR_INTERNAL as ES_NEW_CLIENT_ERROR_INTERNAL, + es_new_client_result_t_ES_NEW_CLIENT_RESULT_ERR_INVALID_ARGUMENT as ES_NEW_CLIENT_ERROR_INVALID_ARGUMENT, es_new_client_result_t_ES_NEW_CLIENT_RESULT_ERR_NOT_ENTITLED as ES_NEW_CLIENT_ERROR_NOT_ENTITLED, es_new_client_result_t_ES_NEW_CLIENT_RESULT_ERR_NOT_PERMITTED as ES_NEW_CLIENT_ERROR_NOT_PERMITTED, es_new_client_result_t_ES_NEW_CLIENT_RESULT_ERR_NOT_PRIVILEGED as ES_NEW_CLIENT_ERROR_NOT_PRIVILEGED, es_new_client_result_t_ES_NEW_CLIENT_RESULT_ERR_TOO_MANY_CLIENTS as ES_NEW_CLIENT_ERROR_TOO_MANY_CLIENTS, - - es_respond_result_t_ES_RESPOND_RESULT_SUCCESS as ES_RESPOND_RESULT_SUCCESS, - es_respond_result_t_ES_RESPOND_RESULT_ERR_INVALID_ARGUMENT as ES_RESPONSE_RESULT_ERROR_INVALID_ARGUMENT, - es_respond_result_t_ES_RESPOND_RESULT_ERR_INTERNAL as ES_RESPOND_RESULT_ERROR_INTERNAL, - es_respond_result_t_ES_RESPOND_RESULT_NOT_FOUND as ES_RESPOND_RESULT_NOT_FOUND, + es_new_client_result_t_ES_NEW_CLIENT_RESULT_SUCCESS as ES_NEW_CLIENT_SUCCESS, es_respond_result_t_ES_RESPOND_RESULT_ERR_DUPLICATE_RESPONSE as ES_RESPOND_RESULT_ERROR_DUPLICATE_RESPONSE, es_respond_result_t_ES_RESPOND_RESULT_ERR_EVENT_TYPE as ES_RESPONSE_RESULT_ERROR_EVENT_TYPE, + es_respond_result_t_ES_RESPOND_RESULT_ERR_INTERNAL as ES_RESPOND_RESULT_ERROR_INTERNAL, + es_respond_result_t_ES_RESPOND_RESULT_ERR_INVALID_ARGUMENT as ES_RESPONSE_RESULT_ERROR_INVALID_ARGUMENT, + es_respond_result_t_ES_RESPOND_RESULT_NOT_FOUND as ES_RESPOND_RESULT_NOT_FOUND, + es_respond_result_t_ES_RESPOND_RESULT_SUCCESS as ES_RESPOND_RESULT_SUCCESS, + es_return_t_ES_RETURN_SUCCESS as ES_RETURN_SUCCESS, }; #[repr(C)] @@ -61,7 +58,7 @@ pub enum FileModes { pub struct EsFile { pub path: String, pub path_truncated: bool, -// pub stat: stat, + // pub stat: stat, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -212,7 +209,7 @@ pub struct EsClientError { impl fmt::Display for EsClientError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f,"{}", self.details) + write!(f, "{}", self.details) } } @@ -417,14 +414,13 @@ pub struct EsMessage { raw_message: *const es_message_t, } - struct EsClientHidden { client: *mut es_client_t, active_subscriptions: HashSet, } // Unfortunately this system is a little over zealous -// because it means we have to lock even to read active subscriptions. +// because it means we have to lock even to read active subscriptions. // Optimize this later if it provides too much contention with responding // to messages. #[derive(Clone)] @@ -455,7 +451,7 @@ pub fn raw_event_to_supportedesevent(event_type: u64) -> Option SupportedEsEvent::AuthLink, 67 => SupportedEsEvent::AuthReadDir, 68 => SupportedEsEvent::NotifyReadDir, - _ => return None + _ => return None, }) } @@ -484,9 +480,16 @@ pub fn supportedesevent_to_raw_event(event_type: &SupportedEsEvent) -> u32 { } } -fn es_notify_callback(_client: *mut es_client_t, message: *mut es_message_t, tx: Sender) { +fn es_notify_callback( + _client: *mut es_client_t, + message: *mut es_message_t, + tx: Sender, +) { let message = match parse_es_message(message) { - Err(e) => { println!("Could not parse message: {}", e); return}, + Err(e) => { + println!("Could not parse message: {}", e); + return; + } Ok(x) => x, }; @@ -500,9 +503,12 @@ pub fn create_es_client(tx: Sender) -> Result as *const std::ffi::c_void) } { ES_NEW_CLIENT_SUCCESS => { @@ -554,19 +560,17 @@ unsafe impl Sync for EsClient {} impl EsClient { // Clear the cache of decisions. This should be done sparringly as it affects ALL // client for the entire system. Doing this too frequently will impact system performace - pub fn clear_cache(&self) -> Result <(), ClearCacheResult> { + pub fn clear_cache(&self) -> Result<(), ClearCacheResult> { let client = (*self.client).lock(); let client = match client { Ok(c) => c, Err(e) => { error!("Could not acquire lock for client: {}", e); - return Err(ClearCacheResult::ErrorInternal) - }, + return Err(ClearCacheResult::ErrorInternal); + } }; - let response = unsafe { - es_clear_cache(client.client) - }; + let response = unsafe { es_clear_cache(client.client) }; match response { ES_CLEAR_CACHE_RESULT_SUCCESS => Ok(()), @@ -591,8 +595,11 @@ impl EsClient { Ok(c) => c, Err(_) => return false, }; - - let events:Vec<&SupportedEsEvent> = events.iter().filter(|x| !client.active_subscriptions.contains(x)).collect(); + + let events: Vec<&SupportedEsEvent> = events + .iter() + .filter(|x| !client.active_subscriptions.contains(x)) + .collect(); if events.len() == 0 { debug!(target: "endpointsecurity-rs", "No new events being subscribed to"); return true; @@ -605,14 +612,14 @@ impl EsClient { i += 1; } - unsafe { + unsafe { match es_subscribe(client.client, &c_events as *const u32, events.len() as u32) { ES_RETURN_SUCCESS => { for event in events { - client.active_subscriptions.insert(*event); + client.active_subscriptions.insert(*event); } true - }, + } _ => false, } } @@ -631,7 +638,10 @@ impl EsClient { Err(_) => return false, }; - let events:Vec<&SupportedEsEvent> = events.iter().filter(|x| client.active_subscriptions.contains(x)).collect(); + let events: Vec<&SupportedEsEvent> = events + .iter() + .filter(|x| client.active_subscriptions.contains(x)) + .collect(); if events.len() == 0 { debug!(target: "endpointsecurity-rs", "Not subscribed to any events request to unsubscribe from"); return true; @@ -648,10 +658,10 @@ impl EsClient { match es_unsubscribe(client.client, &c_events as *const u32, events.len() as u32) { ES_RETURN_SUCCESS => { for event in events { - client.active_subscriptions.remove(event); + client.active_subscriptions.remove(event); } true - }, + } _ => false, } } @@ -663,9 +673,9 @@ impl EsClient { println!("Too many events to unsubscribe to!"); return false; } - let new_subscriptions:Vec; - let remove_subscriptions:Vec; - + let new_subscriptions: Vec; + let remove_subscriptions: Vec; + { let client = (*self.client).lock(); let client = match client { @@ -674,10 +684,19 @@ impl EsClient { }; // Filter out all subscriptions that we already have - new_subscriptions = events.iter().filter(|x| !client.active_subscriptions.contains(x)).copied().collect(); - + new_subscriptions = events + .iter() + .filter(|x| !client.active_subscriptions.contains(x)) + .copied() + .collect(); + // For all subscriptions we have, keep them in this remove list if they are not in our new list - remove_subscriptions = client.active_subscriptions.iter().filter(|x| !events.contains(x)).copied().collect(); + remove_subscriptions = client + .active_subscriptions + .iter() + .filter(|x| !events.contains(x)) + .copied() + .collect(); if !new_subscriptions.is_empty() { info!(target: "endpointsecurity-rs", "Adding subscriptions for: {}", new_subscriptions.iter().fold(String::from(""), |acc, x| acc + &x.to_string() + ", ")); @@ -688,10 +707,16 @@ impl EsClient { remove_subscriptions.iter().fold(String::from(""), |acc, x| acc + &x.to_string() + ", ")); } } - self.unsubscribe_to_events(&remove_subscriptions) && self.subscribe_to_events(&new_subscriptions) + self.unsubscribe_to_events(&remove_subscriptions) + && self.subscribe_to_events(&new_subscriptions) } - pub fn respond_to_flags_event(&self, message: &EsMessage, authorized_flags: u32, should_cache: &EsCacheResult) -> EsRespondResult { + pub fn respond_to_flags_event( + &self, + message: &EsMessage, + authorized_flags: u32, + should_cache: &EsCacheResult, + ) -> EsRespondResult { let cache = match should_cache { EsCacheResult::Yes => true, EsCacheResult::No => false, @@ -703,7 +728,9 @@ impl EsClient { Err(_) => return EsRespondResult::UnknownResponse, // TODO Fix this }; - match unsafe { es_respond_flags_result(client.client, message.raw_message, authorized_flags, cache) } { + match unsafe { + es_respond_flags_result(client.client, message.raw_message, authorized_flags, cache) + } { ES_RESPOND_RESULT_SUCCESS => EsRespondResult::Sucess, ES_RESPONSE_RESULT_ERROR_INVALID_ARGUMENT => EsRespondResult::ErrorInvalidArgument, ES_RESPOND_RESULT_ERROR_INTERNAL => EsRespondResult::ErrorInternal, @@ -714,7 +741,12 @@ impl EsClient { } } - pub fn respond_to_auth_event(&self, message: &EsMessage, response: &EsAuthResult, should_cache: &EsCacheResult) -> EsRespondResult { + pub fn respond_to_auth_event( + &self, + message: &EsMessage, + response: &EsAuthResult, + should_cache: &EsCacheResult, + ) -> EsRespondResult { let cache = match should_cache { EsCacheResult::Yes => true, EsCacheResult::No => false, @@ -730,8 +762,9 @@ impl EsClient { Ok(c) => c, Err(_) => return EsRespondResult::UnknownResponse, // TODO Fix this }; - - match unsafe { es_respond_auth_result(client.client, message.raw_message, response, cache) } { + + match unsafe { es_respond_auth_result(client.client, message.raw_message, response, cache) } + { ES_RESPOND_RESULT_SUCCESS => EsRespondResult::Sucess, ES_RESPONSE_RESULT_ERROR_INVALID_ARGUMENT => EsRespondResult::ErrorInvalidArgument, ES_RESPOND_RESULT_ERROR_INTERNAL => EsRespondResult::ErrorInternal, @@ -757,4 +790,4 @@ impl Drop for EsClient { client.active_subscriptions.clear(); } } -} \ No newline at end of file +} diff --git a/src/parsers.rs b/src/parsers.rs index 0be33c7..5024a88 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -1,50 +1,33 @@ -use std::ffi::CStr; use crate::{ - audit_token_t, - es_action_type_t_ES_ACTION_TYPE_AUTH as ES_ACTION_TYPE_AUTH, - es_action_type_t_ES_ACTION_TYPE_NOTIFY as ES_ACTION_TYPE_NOTIFY, - es_events_t, - es_exec_arg, - es_exec_arg_count, - es_file_t, - es_message_t, - es_message_t__bindgen_ty_1, - es_process_t, - es_string_token_t, - pid_t, + audit_token_t, es_action_type_t_ES_ACTION_TYPE_AUTH as ES_ACTION_TYPE_AUTH, + es_action_type_t_ES_ACTION_TYPE_NOTIFY as ES_ACTION_TYPE_NOTIFY, es_events_t, es_exec_arg, + es_exec_arg_count, es_file_t, es_message_t, es_message_t__bindgen_ty_1, es_process_t, + es_string_token_t, pid_t, }; +use std::ffi::CStr; // Non Event Structures use crate::{ EsAction, EsActionType, + EsDestinationType, EsEvent, - EsEventId, // I know this is inconsistent but I don't have a better name for this struct + EsEventId, // I know this is inconsistent but I don't have a better name for this struct EsFile, EsMessage, + EsProcess, EsRenameDestination, EsRenameDestinationNewPath, EsResult, - EsResultType, EsResultNotifyResult, - EsDestinationType, - EsProcess, + EsResultType, SupportedEsEvent, }; // Event Structures use crate::{ - EsEventClose, - EsEventExec, - EsEventFork, - EsEventKextload, - EsEventKextunload, - EsEventLink, - EsEventOpen, - EsEventReadDir, - EsEventRename, - EsEventSignal, - EsEventUnlink, + EsEventClose, EsEventExec, EsEventFork, EsEventKextload, EsEventKextunload, EsEventLink, + EsEventOpen, EsEventReadDir, EsEventRename, EsEventSignal, EsEventUnlink, }; use crate::raw_event_to_supportedesevent; @@ -55,32 +38,39 @@ extern "C" { /// Take in an es_event_t from the EndpointSecurity Framework, /// and parse it into a safe Rust structure. -fn parse_es_action(action: es_message_t__bindgen_ty_1, action_type: &EsActionType) -> Option { +fn parse_es_action( + action: es_message_t__bindgen_ty_1, + action_type: &EsActionType, +) -> Option { Some(match action_type { - EsActionType::Auth => EsAction::Auth(EsEventId{ - reserved: unsafe {action.auth.reserved}, + EsActionType::Auth => EsAction::Auth(EsEventId { + reserved: unsafe { action.auth.reserved }, }), EsActionType::Notify => EsAction::Notify(EsResult { result_type: { - match unsafe {action.notify.result_type} { + match unsafe { action.notify.result_type } { 0 => EsResultType::Auth, 1 => EsResultType::Flags, _ => { error!("Result Type is broken"); - return None; // At time of writing these are the only types + return None; // At time of writing these are the only types } } }, result: EsResultNotifyResult { flags: unsafe { action.notify.result.flags }, - } - }) + }, + }), }) } /// Take in an es_event_t from the EndpointSecurity Framework, /// and parse it into a safe Rust structure. -fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: &EsActionType) -> EsEvent { +fn parse_es_event( + event_type: SupportedEsEvent, + event: es_events_t, + action_type: &EsActionType, +) -> EsEvent { unsafe { match event_type { SupportedEsEvent::AuthExec | SupportedEsEvent::NotifyExec => { @@ -90,7 +80,10 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: argv.reserve(argc as usize); let mut x = 0; while x < argc { - argv.push(parse_es_string_token(es_exec_arg(&event.exec as *const _, x as u32))); + argv.push(parse_es_string_token(es_exec_arg( + &event.exec as *const _, + x as u32, + ))); x += 1; } @@ -103,7 +96,7 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: EsActionType::Notify => EsEvent::NotifyExec(event), EsActionType::Auth => EsEvent::AuthExec(event), } - }, + } SupportedEsEvent::AuthOpen | SupportedEsEvent::NotifyOpen => { let file = event.open; let event = EsEventOpen { @@ -114,7 +107,7 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: EsActionType::Notify => EsEvent::NotifyOpen(event), EsActionType::Auth => EsEvent::AuthOpen(event), } - }, + } SupportedEsEvent::AuthKextload | SupportedEsEvent::NotifyKextload => { let load = event.kextload; let event = EsEventKextload { @@ -124,7 +117,7 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: EsActionType::Notify => EsEvent::NotifyKextload(event), EsActionType::Auth => EsEvent::AuthKextload(event), } - }, + } SupportedEsEvent::AuthSignal | SupportedEsEvent::NotifySignal => { let target = event.signal.target; let event = EsEventSignal { @@ -135,7 +128,7 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: EsActionType::Notify => EsEvent::NotifySignal(event), EsActionType::Auth => EsEvent::AuthSignal(event), } - }, + } SupportedEsEvent::AuthUnlink | SupportedEsEvent::NotifyUnlink => { let target = event.unlink.target; let parent_dir = event.unlink.target; @@ -143,11 +136,11 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: target: parse_es_file(target), parent_dir: parse_es_file(parent_dir), }; - match action_type { + match action_type { EsActionType::Notify => EsEvent::NotifyUnlink(event), EsActionType::Auth => EsEvent::AuthUnlink(event), } - }, + } SupportedEsEvent::AuthLink | SupportedEsEvent::NotifyLink => { let event = EsEventLink { source: parse_es_file(event.link.source), @@ -158,7 +151,7 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: EsActionType::Notify => EsEvent::NotifyLink(event), EsActionType::Auth => EsEvent::AuthLink(event), } - }, + } SupportedEsEvent::AuthRename | SupportedEsEvent::NotifyRename => { let event = EsEventRename { source: parse_es_file(event.rename.source), @@ -171,15 +164,17 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: existing_file: parse_es_file(event.rename.destination.existing_file), new_path: EsRenameDestinationNewPath { dir: parse_es_file(event.rename.destination.new_path.dir), - filename: parse_es_string_token(event.rename.destination.new_path.filename), + filename: parse_es_string_token( + event.rename.destination.new_path.filename, + ), }, - } + }, }; match action_type { EsActionType::Notify => EsEvent::NotifyRename(event), EsActionType::Auth => EsEvent::AuthRename(event), } - }, + } SupportedEsEvent::AuthReadDir | SupportedEsEvent::NotifyReadDir => { let event = EsEventReadDir { target: parse_es_file(event.readdir.target), @@ -188,23 +183,17 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: EsActionType::Notify => EsEvent::NotifyReadDir(event), EsActionType::Auth => EsEvent::AuthReadDir(event), } - }, - SupportedEsEvent::NotifyFork => { - EsEvent::NotifyFork(EsEventFork { - child: parse_es_process(&*event.fork.child), - }) - }, - SupportedEsEvent::NotifyKextunload => { - EsEvent::NotifyKextunload(EsEventKextunload { - identifier: parse_es_string_token(event.kextunload.identifier), - }) - }, - SupportedEsEvent::NotifyClose => { - EsEvent::NotifyClose(EsEventClose { - modified: event.close.modified, - target: parse_es_file(event.close.target), - }) - }, + } + SupportedEsEvent::NotifyFork => EsEvent::NotifyFork(EsEventFork { + child: parse_es_process(&*event.fork.child), + }), + SupportedEsEvent::NotifyKextunload => EsEvent::NotifyKextunload(EsEventKextunload { + identifier: parse_es_string_token(event.kextunload.identifier), + }), + SupportedEsEvent::NotifyClose => EsEvent::NotifyClose(EsEventClose { + modified: event.close.modified, + target: parse_es_file(event.close.target), + }), } } } @@ -212,7 +201,7 @@ fn parse_es_event(event_type: SupportedEsEvent, event: es_events_t, action_type: /// Take in an es_file_t from the EndpointSecurity Framework, /// and parse it into a safe Rust structure. fn parse_es_file(file: *mut es_file_t) -> EsFile { - let f = unsafe {*file}; + let f = unsafe { *file }; EsFile { path: unsafe { CStr::from_ptr(f.path.data).to_str().unwrap().to_owned() }, path_truncated: { f.path_truncated }, @@ -222,8 +211,8 @@ fn parse_es_file(file: *mut es_file_t) -> EsFile { /// Take in an es_message_t from the EndpointSecurity Framework, /// and parse it into a safe Rust structure. pub fn parse_es_message(message: *mut es_message_t) -> Result { - let message = unsafe {&*message}; - let process = unsafe {&*(message.process)}; + let message = unsafe { &*message }; + let process = unsafe { &*(message.process) }; let action_type = match message.action_type { ES_ACTION_TYPE_AUTH => EsActionType::Auth, ES_ACTION_TYPE_NOTIFY => EsActionType::Notify, @@ -284,16 +273,12 @@ fn parse_es_process(process: &es_process_t) -> EsProcess { /// and parse it into a safe Rust structure. fn parse_es_string_token(string_token: es_string_token_t) -> String { match string_token.length { - x if x <= 0 => { - String::new() - }, - _ => { - match unsafe { CStr::from_ptr(string_token.data).to_str() }{ - Ok(v) => v.to_owned(), - Err(e) => { - error!("String would not parse: {}", e); - String::new() - } + x if x <= 0 => String::new(), + _ => match unsafe { CStr::from_ptr(string_token.data).to_str() } { + Ok(v) => v.to_owned(), + Err(e) => { + error!("String would not parse: {}", e); + String::new() } }, }