Skip to main content

endpoint_sec/
event.rs

1//! Definitions of Endpoint Security events.
2
3use endpoint_sec_sys::{es_event_type_t, es_events_t};
4
5/// Helper macro to define the whole Event enum at once, avoiding endless repetitions of the CFGs
6macro_rules! define_event_enum {
7    (
8        $(#[$enum_meta: meta])*
9        pub enum $enum_name: ident from ($raw_ev: ident, $version: ident) {
10            $(
11                $(#[$b_v_doc: meta])*
12                $b_v_const: ident => $b_v_name: ident($b_v_inner: ident [$b_v_var: pat => $b_v_expected_resp_type: expr] {
13                    $($b_v_new_name: ident $(: $b_v_new_expr: expr)?,)+
14                }),
15            )*
16            $(
17                == #[$v_cfg: meta]
18                $(
19                    $(#[$v_doc: meta])*
20                    $v_const: ident => $v_name: ident($v_inner: ident [$v_var: pat => $v_expected_resp_type: expr] {
21                        $($v_new_name: ident $(: $v_new_expr: expr)?,)+
22                    }),
23                )+
24            )*
25        }
26    ) => {
27        $(#[$enum_meta])*
28        pub enum $enum_name<'a> {
29            $( $(#[$b_v_doc])* $b_v_name($b_v_inner<'a>), )*
30            $( $( #[$v_cfg] $(#[$v_doc])* $v_name($v_inner<'a>), )* )*
31        }
32
33        #[cfg(feature = "static_assertions")]
34        ::static_assertions::assert_impl_all!(Event<'_>: Send);
35
36        impl<'a> $enum_name<'a> {
37            /// Create an instance from raw parts.
38            ///
39            /// # Safety
40            ///
41            /// `event_type`, `raw_event` and `version` must be coming from the same [`crate::message::Message`].
42            #[inline(always)]
43            pub(crate) unsafe fn from_raw_parts(
44                event_type: es_event_type_t,
45                $raw_ev: &'a es_events_t,
46                $version: u32,
47            ) -> Option<Self> {
48                // Safety: Safe as we select the union field corresponding to that type and the
49                // caller must have respected the calling condition.
50                let v = unsafe {
51                    match event_type {
52                        $( es_event_type_t::$b_v_const => Self::$b_v_name($b_v_inner { $( $b_v_new_name $(: $b_v_new_expr)? ),* }), )*
53                        $( $( #[$v_cfg] es_event_type_t::$v_const => Self::$v_name($v_inner { $( $v_new_name $(: $v_new_expr)? ),* }), )* )*
54                        _ => return None,
55                    }
56                };
57                Some(v)
58            }
59
60            /// For `Auth` events, returns the type of response to use when allowing or denying.
61            pub fn expected_response_type(&self) -> Option<ExpectedResponseType> {
62                match self {
63                    $( Self::$b_v_name($b_v_var) => $b_v_expected_resp_type, )*
64                    $( $( #[$v_cfg] Self::$v_name($v_var) => $v_expected_resp_type, )* )*
65                }
66            }
67        }
68    };
69}
70
71define_event_enum!(
72    /// Information related to an event.
73    #[derive(Debug, PartialEq, Eq, Hash)]
74    #[non_exhaustive]
75    pub enum Event from (raw_event, version) {
76        /// Authorization request for a process execution.
77        ES_EVENT_TYPE_AUTH_EXEC => AuthExec(EventExec [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.exec, version, }),
78        /// Authorization request for a file system object being opened.
79        ES_EVENT_TYPE_AUTH_OPEN => AuthOpen(EventOpen [e => Some(ExpectedResponseType::Flags { flags: e.fflag() as u32, }) ] { raw: &raw_event.open, }),
80        /// Authorization request for a kernel extension being loaded.
81        ES_EVENT_TYPE_AUTH_KEXTLOAD => AuthKextLoad(EventKextLoad [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.kextload, }),
82        /// Authorization request for a memory map of a file.
83        ES_EVENT_TYPE_AUTH_MMAP => AuthMmap(EventMmap [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.mmap, }),
84        /// Authorization request for a change of protection for pages.
85        ES_EVENT_TYPE_AUTH_MPROTECT => AuthMprotect(EventMprotect [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.mprotect, }),
86        /// Authorization request for a file system being mounted.
87        ES_EVENT_TYPE_AUTH_MOUNT => AuthMount(EventMount [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.mount, version, }),
88        /// Authorization request for a file system object being renamed.
89        ES_EVENT_TYPE_AUTH_RENAME => AuthRename(EventRename [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.rename, }),
90        /// Authorization request for a signal being sent to a process.
91        ES_EVENT_TYPE_AUTH_SIGNAL => AuthSignal(EventSignal [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.signal, version, }),
92        /// Authorization request for a file system object being unlinked.
93        ES_EVENT_TYPE_AUTH_UNLINK => AuthUnlink(EventUnlink [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.unlink, }),
94        /// Notify a process execution.
95        ES_EVENT_TYPE_NOTIFY_EXEC => NotifyExec(EventExec [_ => None ] { raw: &raw_event.exec, version, }),
96        /// Notify a file system object being open.
97        ES_EVENT_TYPE_NOTIFY_OPEN => NotifyOpen(EventOpen [_ => None ] { raw: &raw_event.open, }),
98        /// Notify a new process being forked.
99        ES_EVENT_TYPE_NOTIFY_FORK => NotifyFork(EventFork [_ => None ] { raw: &raw_event.fork, version, }),
100        /// Notify a new file system object being closed.
101        ES_EVENT_TYPE_NOTIFY_CLOSE => NotifyClose(EventClose [_ => None ] { raw: &raw_event.close, version, }),
102        /// Notify a file system object being created.
103        ES_EVENT_TYPE_NOTIFY_CREATE => NotifyCreate(EventCreate [_ => None ] { raw: &raw_event.create, version, }),
104        /// Notify data being atomically exchanged between two files.
105        ES_EVENT_TYPE_NOTIFY_EXCHANGEDATA => NotifyExchangeData(EventExchangeData [_ => None ] { raw: &raw_event.exchangedata, }),
106        /// Notify a process termination.
107        ES_EVENT_TYPE_NOTIFY_EXIT => NotifyExit(EventExit [_ => None ] { raw: &raw_event.exit, }),
108        /// Notify a process's task control port event.
109        ES_EVENT_TYPE_NOTIFY_GET_TASK => NotifyGetTask(EventGetTask [_ => None ] { raw: &raw_event.get_task, version, }),
110        /// Notify a kernel extension being loaded.
111        ES_EVENT_TYPE_NOTIFY_KEXTLOAD => NotifyKextLoad(EventKextLoad [_ => None ] { raw: &raw_event.kextload, }),
112        /// Notify a kernel extension being unloaded.
113        ES_EVENT_TYPE_NOTIFY_KEXTUNLOAD => NotifyKextUnload(EventKextUnload[_ => None ]{ raw: &raw_event.kextunload, }),
114        /// Notify a file system object being linked.
115        ES_EVENT_TYPE_NOTIFY_LINK => NotifyLink(EventLink[_ => None ]{ raw: &raw_event.link, }),
116        /// Notify a memory map of a file.
117        ES_EVENT_TYPE_NOTIFY_MMAP => NotifyMmap(EventMmap [_ => None ] { raw: &raw_event.mmap, }),
118        /// Notify a change of protection for pages.
119        ES_EVENT_TYPE_NOTIFY_MPROTECT => NotifyMprotect(EventMprotect [_ => None ] { raw: &raw_event.mprotect, }),
120        /// Notify a file system being mounted.
121        ES_EVENT_TYPE_NOTIFY_MOUNT => NotifyMount(EventMount [_ => None ] { raw: &raw_event.mount, version, }),
122        /// Notify a file system being unmounted.
123        ES_EVENT_TYPE_NOTIFY_UNMOUNT => NotifyUnmount(EventUnmount [_ => None ] { raw: &raw_event.unmount, }),
124        /// Notify a connection being opened to an I/O Kit IOService.
125        ES_EVENT_TYPE_NOTIFY_IOKIT_OPEN => NotifyIoKitOpen(EventIoKitOpen [_ => None ] { raw: &raw_event.iokit_open, }),
126        /// Notify a file system object being renamed.
127        ES_EVENT_TYPE_NOTIFY_RENAME => NotifyRename(EventRename [_ => None ] { raw: &raw_event.rename, }),
128        /// Notify when file system attributes are being modified.
129        ES_EVENT_TYPE_NOTIFY_SETATTRLIST => NotifySetAttrlist(EventSetAttrlist [_ => None ] { raw: &raw_event.setattrlist, }),
130        /// Notify when extended attribute are being set.
131        ES_EVENT_TYPE_NOTIFY_SETEXTATTR => NotifySetExtAttr(EventSetExtAttr[_ => None ]{ raw: &raw_event.setextattr, }),
132        /// Notify when a file system object flags are being modified.
133        ES_EVENT_TYPE_NOTIFY_SETFLAGS => NotifySetFlags(EventSetFlags [_ => None ] { raw: &raw_event.setflags, }),
134        /// Notify when a file system object mode is being modified.
135        ES_EVENT_TYPE_NOTIFY_SETMODE => NotifySetMode(EventSetMode [_ => None ] { raw: &raw_event.setmode, }),
136        /// Notify when a file system object owner is being modified.
137        ES_EVENT_TYPE_NOTIFY_SETOWNER => NotifySetOwner(EventSetOwner [_ => None ] { raw: &raw_event.setowner, }),
138        /// Notify a signal being sent to a process.
139        ES_EVENT_TYPE_NOTIFY_SIGNAL => NotifySignal(EventSignal [_ => None ] { raw: &raw_event.signal, version, }),
140        /// Notify a file system object being unlinked.
141        ES_EVENT_TYPE_NOTIFY_UNLINK => NotifyUnlink(EventUnlink [_ => None ] { raw: &raw_event.unlink, }),
142        /// Notify a write to a file.
143        ES_EVENT_TYPE_NOTIFY_WRITE => NotifyWrite(EventWrite [_ => None ] { raw: &raw_event.write, }),
144        /// Authorization request for a file being materialize via the FileProvider framework.
145        ES_EVENT_TYPE_AUTH_FILE_PROVIDER_MATERIALIZE => AuthFileProviderMaterialize( EventFileProviderMaterialize [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.file_provider_materialize, version, } ),
146        /// Notify a file being materialize via the FileProvider framework.
147        ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_MATERIALIZE => NotifyFileProviderMaterialize(EventFileProviderMaterialize [_ => None ] { raw: &raw_event.file_provider_materialize, version, }),
148        /// Authorization request for file contents being updated via the FileProvider framework.
149        ES_EVENT_TYPE_AUTH_FILE_PROVIDER_UPDATE => AuthFileProviderUpdate( EventFileProviderUpdate [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.file_provider_update, } ),
150        /// Notify a file contents being updated via the FileProvider framework.
151        ES_EVENT_TYPE_NOTIFY_FILE_PROVIDER_UPDATE => NotifyFileProviderUpdate( EventFileProviderUpdate [_ => None ] { raw: &raw_event.file_provider_update, } ),
152        /// Authorization request for a symbolic link being resolved.
153        ES_EVENT_TYPE_AUTH_READLINK => AuthReadLink(EventReadLink [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.readlink, }),
154        /// Notify a symbolic link being resolved.
155        ES_EVENT_TYPE_NOTIFY_READLINK => NotifyReadLink(EventReadLink [_ => None ] { raw: &raw_event.readlink, }),
156        /// Authorization request for a file being truncated.
157        ES_EVENT_TYPE_AUTH_TRUNCATE => AuthTruncate(EventTruncate [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.truncate, }),
158        /// Notify a file being truncated.
159        ES_EVENT_TYPE_NOTIFY_TRUNCATE => NotifyTruncate(EventTruncate [_ => None ] { raw: &raw_event.truncate, }),
160        /// Authorization request for a file system object being linked.
161        ES_EVENT_TYPE_AUTH_LINK => AuthLink(EventLink[_ => Some(ExpectedResponseType::Auth) ]{ raw: &raw_event.link, }),
162        /// Notify a file system object being lookup.
163        ES_EVENT_TYPE_NOTIFY_LOOKUP => NotifyLookup(EventLookup [_ => None ] { raw: &raw_event.lookup, }),
164        /// Authorization request for a file system object being created.
165        ES_EVENT_TYPE_AUTH_CREATE => AuthCreate(EventCreate [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.create, version, }),
166        /// Authorization request for file system attributes being modified.
167        ES_EVENT_TYPE_AUTH_SETATTRLIST => AuthSetAttrlist(EventSetAttrlist [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.setattrlist, }),
168        /// Authorization request for an extended attribute being set.
169        ES_EVENT_TYPE_AUTH_SETEXTATTR => AuthSetExtAttr(EventSetExtAttr [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.setextattr, }),
170        /// Authorization request for a file system object flags being modified.
171        ES_EVENT_TYPE_AUTH_SETFLAGS => AuthSetFlags(EventSetFlags [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.setflags, }),
172        /// Authorization request for a file system object mode being modified.
173        ES_EVENT_TYPE_AUTH_SETMODE => AuthSetMode(EventSetMode [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.setmode, }),
174        /// Authorization request for a file system object owner being modified.
175        ES_EVENT_TYPE_AUTH_SETOWNER => AuthSetOwner(EventSetOwner [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.setowner, }),
176
177        == #[cfg(feature = "macos_10_15_1")]
178        /// Authorization request for when the current working directory of a process is being changed.
179        ES_EVENT_TYPE_AUTH_CHDIR => AuthChdir(EventChdir [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.chdir, }),
180        /// Notify when the current working directory change for a process.
181        ES_EVENT_TYPE_NOTIFY_CHDIR => NotifyChdir(EventChdir [_ => None ] { raw: &raw_event.chdir, }),
182        /// Authorization request for file system attributes being retrieved.
183        ES_EVENT_TYPE_AUTH_GETATTRLIST => AuthGetAttrlist(EventGetAttrlist [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.getattrlist, }),
184        /// Notify when file system attributes are being retrieved.
185        ES_EVENT_TYPE_NOTIFY_GETATTRLIST => NotifyGetAttrlist(EventGetAttrlist [_ => None ] { raw: &raw_event.getattrlist, }),
186        /// Notify when a file is being stat.
187        ES_EVENT_TYPE_NOTIFY_STAT => NotifyStat(EventStat [_ => None ] { raw: &raw_event.stat, }),
188        /// Notify when a file access test is performed.
189        ES_EVENT_TYPE_NOTIFY_ACCESS => NotifyAccess(EventAccess [_ => None ] { raw: &raw_event.access, }),
190        /// Authorization request for a chroot.
191        ES_EVENT_TYPE_AUTH_CHROOT => AuthChroot(EventChroot [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.chroot, }),
192        /// Notify when a chroot is performed.
193        ES_EVENT_TYPE_NOTIFY_CHROOT => NotifyChroot(EventChroot [_ => None ] { raw: &raw_event.chroot, }),
194        /// Authorization request for a file access and modification times change.
195        ES_EVENT_TYPE_AUTH_UTIMES => AuthUTimes(EventUTimes [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.utimes, }),
196        /// Notify when a file access and modification times changed.
197        ES_EVENT_TYPE_NOTIFY_UTIMES => NotifyUTimes(EventUTimes [_ => None ] { raw: &raw_event.utimes, }),
198        /// Authorization request for a file being cloned.
199        ES_EVENT_TYPE_AUTH_CLONE => AuthClone(EventClone [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.clone, }),
200        /// Notify for a file being cloned.
201        ES_EVENT_TYPE_NOTIFY_CLONE => NotifyClone(EventClone [_ => None ] { raw: &raw_event.clone, }),
202        /// Notify for a file control event.
203        ES_EVENT_TYPE_NOTIFY_FCNTL => NotifyFcntl(EventFcntl [_ => None ] { raw: &raw_event.fcntl, }),
204        /// Authorization request for extended attribute being retrieved.
205        ES_EVENT_TYPE_AUTH_GETEXTATTR => AuthGetExtAttr(EventGetExtAttr [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.getextattr, }),
206        /// Notify when extended attribute are being retrieved.
207        ES_EVENT_TYPE_NOTIFY_GETEXTATTR => NotifyGetExtAttr(EventGetExtAttr[_ => None ]{ raw: &raw_event.getextattr, }),
208        /// Authorization request for extended attributes being listed.
209        ES_EVENT_TYPE_AUTH_LISTEXTATTR => AuthListExtAttr(EventListExtAttr [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.listextattr, }),
210        /// Notify when extended attributes are being listed.
211        ES_EVENT_TYPE_NOTIFY_LISTEXTATTR => NotifyListExtAttr(EventListExtAttr [_ => None ] { raw: &raw_event.listextattr , }),
212        /// Authorization request for directory entries being read.
213        ES_EVENT_TYPE_AUTH_READDIR => AuthReadDir(EventReadDir [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.readdir, }),
214        /// Notify when directory entries are being read.
215        ES_EVENT_TYPE_NOTIFY_READDIR => NotifyReadDir(EventReadDir [_ => None ] { raw: &raw_event.readdir, }),
216        /// Authorization request for an extended attribute being deleted.
217        ES_EVENT_TYPE_AUTH_DELETEEXTATTR => AuthDeleteExtAttr(EventDeleteExtAttr [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.deleteextattr , }),
218        /// Notify when an extended attribute are being deleted.
219        ES_EVENT_TYPE_NOTIFY_DELETEEXTATTR => NotifyDeleteExtAttr( EventDeleteExtAttr [_ => None ] { raw: &raw_event.deleteextattr, } ),
220        /// Authorization request for a file system path being retrieved based on FSID.
221        ES_EVENT_TYPE_AUTH_FSGETPATH => AuthFsGetPath(EventFsGetPath [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.fsgetpath, }),
222        /// Notify when a file system path is retrieved based on FSID.
223        ES_EVENT_TYPE_NOTIFY_FSGETPATH => NotifyFsGetPath(EventFsGetPath [_ => None ] { raw: &raw_event.fsgetpath, }),
224        /// Notify when a file descriptor is being duplicated.
225        ES_EVENT_TYPE_NOTIFY_DUP => NotifyDup(EventDup [_ => None ] { raw: &raw_event.dup, }),
226        /// Authorization request for the system time being modified.
227        ES_EVENT_TYPE_AUTH_SETTIME => AuthSetTime(EventSetTime [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.settime, }),
228        /// Notify the system time being modified.
229        ES_EVENT_TYPE_NOTIFY_SETTIME => NotifySetTime(EventSetTime [_ => None ] { raw: &raw_event.settime, }),
230        /// Notify a UNIX-domain socket is about to be bound to a path.
231        ES_EVENT_TYPE_NOTIFY_UIPC_BIND => NotifyUipcBind(EventUipcBind [_ => None ] { raw: &raw_event.uipc_bind, }),
232        /// Authorization request to bind a UNIX-domain socket to a path.
233        ES_EVENT_TYPE_AUTH_UIPC_BIND => AuthUipcBind(EventUipcBind [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.uipc_bind, }),
234        /// Notify a UNIX-domain socket is about to be connected.
235        ES_EVENT_TYPE_NOTIFY_UIPC_CONNECT => NotifyUipcConnect(EventUipcConnect [_ => None ] { raw: &raw_event.uipc_connect , }),
236        /// Authorization request to connect a UNIX-domain socket.
237        ES_EVENT_TYPE_AUTH_UIPC_CONNECT => AuthUipcConnect(EventUipcConnect[_ => Some(ExpectedResponseType::Auth) ]{ raw: &raw_event.uipc_connect, }),
238        /// Authorization request for data being atomically exchanged between two files.
239        ES_EVENT_TYPE_AUTH_EXCHANGEDATA => AuthExchangeData(EventExchangeData [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.exchangedata , }),
240        /// Authorization request to set a file's ACL.
241        ES_EVENT_TYPE_AUTH_SETACL => AuthSetAcl(EventSetAcl [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.setacl, }),
242        /// Notify a file's ACL was set.
243        ES_EVENT_TYPE_NOTIFY_SETACL => NotifySetAcl(EventSetAcl [_ => None ] { raw: &raw_event.setacl, }),
244
245        == #[cfg(feature = "macos_10_15_4")]
246        /// Notify a pseudoterminal control device was granted.
247        ES_EVENT_TYPE_NOTIFY_PTY_GRANT => NotifyPtyGrant(EventPtyGrant [_ => None ] { raw: &raw_event.pty_grant, }),
248        /// Notify a pseudoterminal control device was closed.
249        ES_EVENT_TYPE_NOTIFY_PTY_CLOSE => NotifyPtyClose(EventPtyClose [_ => None ] { raw: &raw_event.pty_close, }),
250        /// Authorization request for retrieving process information.
251        ES_EVENT_TYPE_AUTH_PROC_CHECK => AuthProcCheck(EventProcCheck [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.proc_check, version, }),
252        /// Notify about retrieval of process information.
253        ES_EVENT_TYPE_NOTIFY_PROC_CHECK => NotifyProcCheck(EventProcCheck [_ => None ] { raw: &raw_event.proc_check, version, }),
254        /// Authorization request for a process's task control port event.
255        ES_EVENT_TYPE_AUTH_GET_TASK => AuthGetTask(EventGetTask [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.get_task, version, }),
256
257        == #[cfg(feature = "macos_11_0_0")]
258        /// Authorization request for an access control check being performed when searching a volume or mounted filesystem.
259        ES_EVENT_TYPE_AUTH_SEARCHFS => AuthSearchFs(EventSearchFs [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.searchfs, }),
260        /// Notify for an access control check performed when searching a volume or mounted filesystem.
261        ES_EVENT_TYPE_NOTIFY_SEARCHFS => NotifySearchFs(EventSearchFs [_ => None ] { raw: &raw_event.searchfs, }),
262        /// Authorization request for a file control.
263        ES_EVENT_TYPE_AUTH_FCNTL => AuthFcntl(EventFcntl [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.fcntl, }),
264        /// Authorization request for a connection being opened to an I/O Kit IOService.
265        ES_EVENT_TYPE_AUTH_IOKIT_OPEN => AuthIoKitOpen(EventIoKitOpen [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.iokit_open, }),
266        /// Authorization request for one of `pid_suspend()`, `pid_resume()` or `pid_shutdown_sockets()` to be called
267        ES_EVENT_TYPE_AUTH_PROC_SUSPEND_RESUME => AuthProcSuspendResume( EventProcSuspendResume [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.proc_suspend_resume, version, } ),
268        /// called on a process.
269        ES_EVENT_TYPE_NOTIFY_PROC_SUSPEND_RESUME => NotifyProcSuspendResume( EventProcSuspendResume [_ => None ] { raw: &raw_event.proc_suspend_resume, version, } ),
270        /// Notify for one of `pid_suspend()`, `pid_resume()` or `pid_shutdown_sockets()` is being
271        ES_EVENT_TYPE_NOTIFY_CS_INVALIDATED => NotifyCSInvalidated( EventCSInvalidated [_ => None ] { raw: &raw_event.cs_invalidated, } ),
272        /// called on a process.
273        ES_EVENT_TYPE_NOTIFY_GET_TASK_NAME => NotifyGetTaskName(EventGetTaskName [_ => None ] { raw: &raw_event.get_task_name, version, }),
274        /// Notify for a code signing status for a process being invalidated.
275        ES_EVENT_TYPE_NOTIFY_TRACE => NotifyTrace(EventTrace [_ => None ] { raw: &raw_event.trace, version, }),
276        /// Notify for the recuperation of a process's task name port.
277        ES_EVENT_TYPE_NOTIFY_REMOTE_THREAD_CREATE => NotifyRemoteThreadCreate( EventRemoteThreadCreate [_ => None ] { raw: &raw_event.remote_thread_create, version, } ),
278        /// Notify for an attempt to attach another process.
279        ES_EVENT_TYPE_AUTH_REMOUNT => AuthRemount(EventRemount [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.remount, version, }),
280        /// Notify a process has attempted to create a thread in another process.
281        ES_EVENT_TYPE_NOTIFY_REMOUNT => NotifyRemount(EventRemount [_ => None ] { raw: &raw_event.remount, version, }),
282
283        == #[cfg(feature = "macos_11_3_0")]
284        /// Authorization request for a file system being remounted.
285        ES_EVENT_TYPE_AUTH_GET_TASK_READ => AuthGetTaskRead(EventGetTaskRead [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.get_task_read, version, }),
286        /// Notify a file system being remounted.
287        ES_EVENT_TYPE_NOTIFY_GET_TASK_READ => NotifyGetTaskRead(EventGetTaskRead [_ => None ] { raw: &raw_event.get_task_read, version, }),
288        /// Authorization request for the recuperation of a process's task read port.
289        ES_EVENT_TYPE_NOTIFY_GET_TASK_INSPECT => NotifyGetTaskInspect(EventGetTaskInspect [_ => None ]{ raw: &raw_event.get_task_inspect, version, }),
290
291        == #[cfg(feature = "macos_12_0_0")]
292        /// Notify for the recuperation of a process's task read port.
293        ES_EVENT_TYPE_NOTIFY_SETUID => NotifySetuid(EventSetuid [_ => None ] { raw: &raw_event.setuid, }),
294        /// Notify for the recuperation of a process's task inspect port.
295        ES_EVENT_TYPE_NOTIFY_SETGID => NotifySetgid(EventSetgid [_ => None ] { raw: &raw_event.setgid, }),
296        /// Notify a process has called `setuid()`.
297        ES_EVENT_TYPE_NOTIFY_SETEUID => NotifySeteuid(EventSeteuid [_ => None ] { raw: &raw_event.seteuid, }),
298        /// Notify a process has called `setgid()`.
299        ES_EVENT_TYPE_NOTIFY_SETEGID => NotifySetegid(EventSetegid [_ => None ] { raw: &raw_event.setegid, }),
300        /// Notify a process has called `seteuid()`.
301        ES_EVENT_TYPE_NOTIFY_SETREUID => NotifySetreuid(EventSetreuid [_ => None ] { raw: &raw_event.setreuid, }),
302        /// Notify a process has called `setegid()`.
303        ES_EVENT_TYPE_NOTIFY_SETREGID => NotifySetregid(EventSetregid [_ => None ] { raw: &raw_event.setregid, }),
304        /// Notify a process has called `setreuid()`.
305        ES_EVENT_TYPE_AUTH_COPYFILE => AuthCopyFile(EventCopyFile [_ => Some(ExpectedResponseType::Auth) ] { raw: &raw_event.copyfile, }),
306        /// Notify a process has called `setregid()`.
307        ES_EVENT_TYPE_NOTIFY_COPYFILE => NotifyCopyFile(EventCopyFile [_ => None ] { raw: &raw_event.copyfile, }),
308
309        == #[cfg(feature = "macos_13_0_0")]
310        /// Notify an authentication was performed.
311        ES_EVENT_TYPE_NOTIFY_AUTHENTICATION => NotifyAuthentication(EventAuthentication [_ => None] { raw: raw_event.authentication.as_opt()?, version, }),
312        /// Notify that XProtect detected malware.
313        ES_EVENT_TYPE_NOTIFY_XP_MALWARE_DETECTED => NotifyXpMalwareDetected(EventXpMalwareDetected [_ => None] { raw: raw_event.xp_malware_detected.as_opt()?, }),
314        /// Notify that XProtect remediated malware.
315        ES_EVENT_TYPE_NOTIFY_XP_MALWARE_REMEDIATED => NotifyXpMalwareRemediated(EventXpMalwareRemediated [_ => None] { raw: raw_event.xp_malware_remediated.as_opt()?, }),
316        /// Notify that LoginWindow has logged in a user.
317        ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGIN => NotifyLwSessionLogin(EventLwSessionLogin [_ => None] { raw: raw_event.lw_session_login.as_opt()?, }),
318        /// Notify that LoginWindow has logged out a user.
319        ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOGOUT => NotifyLwSessionLogout(EventLwSessionLogout [_ => None] { raw: raw_event.lw_session_logout.as_opt()?, }),
320        /// Notify that LoginWindow locked the screen of a session.
321        ES_EVENT_TYPE_NOTIFY_LW_SESSION_LOCK => NotifyLwSessionLock(EventLwSessionLock [_ => None] { raw: raw_event.lw_session_lock.as_opt()?, }),
322        /// Notify that LoginWindow unlocked the screen of a session.
323        ES_EVENT_TYPE_NOTIFY_LW_SESSION_UNLOCK => NotifyLwSessionUnlock(EventLwSessionUnlock [_ => None] { raw: raw_event.lw_session_unlock.as_opt()?, }),
324        /// that Screen Sharing has attached to a graphical session.
325        ES_EVENT_TYPE_NOTIFY_SCREENSHARING_ATTACH => NotifyScreensharingAttach(EventScreensharingAttach [_ => None] { raw: raw_event.screensharing_attach.as_opt()?, }),
326        /// Notify that Screen Sharing has detached from a graphical session.
327        ES_EVENT_TYPE_NOTIFY_SCREENSHARING_DETACH => NotifyScreensharingDetach(EventScreensharingDetach [_ => None] { raw: raw_event.screensharing_detach.as_opt()?, }),
328        /// Notify about an OpenSSH login event.
329        ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGIN => NotifyOpensshLogin(EventOpensshLogin [_ => None] { raw: raw_event.openssh_login.as_opt()?, }),
330        /// Notify about an OpenSSH logout event.
331        ES_EVENT_TYPE_NOTIFY_OPENSSH_LOGOUT => NotifyOpensshLogout(EventOpensshLogout [_ => None] { raw: raw_event.openssh_logout.as_opt()?, }),
332        /// Notify about an authenticated login event from `/usr/bin/login`.
333        ES_EVENT_TYPE_NOTIFY_LOGIN_LOGIN => NotifyLoginLogin(EventLoginLogin [_ => None] { raw: raw_event.login_login.as_opt()?, }),
334        /// Notify about an authenticated logout event from `/usr/bin/login`.
335        ES_EVENT_TYPE_NOTIFY_LOGIN_LOGOUT => NotifyLoginLogout(EventLoginLogout [_ => None] { raw: raw_event.login_logout.as_opt()?, }),
336        /// Notify for a launch item being made known to background task management.
337        ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_ADD => NotifyBtmLaunchItemAdd(EventBtmLaunchItemAdd [_ => None] { raw: raw_event.btm_launch_item_add.as_opt()?, version, }),
338        /// Notify for a launch item being removed from background task management.
339        ES_EVENT_TYPE_NOTIFY_BTM_LAUNCH_ITEM_REMOVE => NotifyBtmLaunchItemRemove(EventBtmLaunchItemRemove [_ => None] { raw: raw_event.btm_launch_item_remove.as_opt()?, version, }),
340
341        == #[cfg(feature = "macos_14_0_0")]
342        /// Notify about Profiles installed on the system.
343        ES_EVENT_TYPE_NOTIFY_PROFILE_ADD => NotifyProfileAdd (EventProfileAdd [_ => None] { raw: raw_event.profile_add.as_opt()?, version, }),
344        /// Notify about Profiles removed on the system.
345        ES_EVENT_TYPE_NOTIFY_PROFILE_REMOVE => NotifyProfileRemove (EventProfileRemove [_ => None] { raw: raw_event.profile_remove.as_opt()?, version, }),
346        /// Notify about a su policy decisions event.
347        ES_EVENT_TYPE_NOTIFY_SU => NotifySu(EventSu [_ => None] { raw: raw_event.su.as_opt()?, }),
348        /// Notify about a process petitioned for certain authorization rights.
349        ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_PETITION => NotifyAuthorizationPetition (EventAuthorizationPetition [_ => None] { raw: raw_event.authorization_petition.as_opt()?, version, }),
350        /// Notification that a process had it's right petition judged
351        ES_EVENT_TYPE_NOTIFY_AUTHORIZATION_JUDGEMENT => NotifyAuthorizationJudgement (EventAuthorizationJudgement [_ => None] { raw: raw_event.authorization_judgement.as_opt()?, version, }),
352        /// Notification about a sudo event.
353        ES_EVENT_TYPE_NOTIFY_SUDO => NotifySudo (EventSudo [_ => None] { raw: raw_event.sudo.as_opt()?, }),
354        /// Notification about an OD group add event.
355        ES_EVENT_TYPE_NOTIFY_OD_GROUP_ADD => NotifyOdGroupAdd (EventOdGroupAdd [_ => None] { raw: raw_event.od_group_add.as_opt()?, version, }),
356        /// Notification about an OD group remove event.
357        ES_EVENT_TYPE_NOTIFY_OD_GROUP_REMOVE => NotifyOdGroupRemove (EventOdGroupRemove [_ => None] { raw: raw_event.od_group_remove.as_opt()?, version, }),
358        /// Notification about a group that had its members initialised or replaced.
359        ES_EVENT_TYPE_NOTIFY_OD_GROUP_SET => NotifyOdGroupSet (EventOdGroupSet [_ => None] { raw: raw_event.od_group_set.as_opt()?, version, }),
360        /// Notification about a account that had its password modified.
361        ES_EVENT_TYPE_NOTIFY_OD_MODIFY_PASSWORD => NotifyOdModifyPassword (EventOdModifyPassword [_ => None] { raw: raw_event.od_modify_password.as_opt()?, version, }),
362        /// Notification about a user account that was disabled.
363        ES_EVENT_TYPE_NOTIFY_OD_DISABLE_USER => NotifyOdDisableUser (EventOdDisableUser [_ => None] { raw: raw_event.od_disable_user.as_opt()?, version, }),
364        /// Notification about a user account that was enabled.
365        ES_EVENT_TYPE_NOTIFY_OD_ENABLE_USER => NotifyOdEnableUser (EventOdEnableUser [_ => None] { raw: raw_event.od_enable_user.as_opt()?, version, }),
366        /// Notification about an attribute value that was added to a record.
367        ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_VALUE_ADD => NotifyOdAttributeValueAdd (EventOdAttributeValueAdd [_ => None] { raw: raw_event.od_attribute_value_add.as_opt()?, version, }),
368        /// Notification about an attribute value that was removed from a record.
369        ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_VALUE_REMOVE => NotifyOdAttributeValueRemove (EventOdAttributeValueRemove [_ => None] { raw: raw_event.od_attribute_value_remove.as_opt()?, version, }),
370        /// Notification about an attribute that was set.
371        ES_EVENT_TYPE_NOTIFY_OD_ATTRIBUTE_SET => NotifyOdAttributeSet (EventOdAttributeSet [_ => None] { raw: raw_event.od_attribute_set.as_opt()?, version, }),
372        /// Notification about an account that was created.
373        ES_EVENT_TYPE_NOTIFY_OD_CREATE_USER => NotifyOdCreateUser (EventOdCreateUser [_ => None] { raw: raw_event.od_create_user.as_opt()?, version, }),
374        /// Notification about a group that was created.
375        ES_EVENT_TYPE_NOTIFY_OD_CREATE_GROUP => NotifyOdCreateGroup (EventOdCreateGroup [_ => None] { raw: raw_event.od_create_group.as_opt()?, version, }),
376        /// Notification about an account that was deleted.
377        ES_EVENT_TYPE_NOTIFY_OD_DELETE_USER => NotifyOdDeleteUser (EventOdDeleteUser [_ => None] { raw: raw_event.od_delete_user.as_opt()?, version, }),
378        /// Notification about a group that was deleted.
379        ES_EVENT_TYPE_NOTIFY_OD_DELETE_GROUP => NotifyOdDeleteGroup (EventOdDeleteGroup [_ => None] { raw: raw_event.od_delete_group.as_opt()?, version, }),
380        /// Notification for an XPC connection being established to a named service.
381        ES_EVENT_TYPE_NOTIFY_XPC_CONNECT => NotifyXpcConnect (EventXpcConnect [_ => None] { raw: raw_event.xpc_connect.as_opt()?, }),
382
383        == #[cfg(feature = "macos_15_0_0")]
384        /// Notification for a gatekeeper_user_override event.
385        ES_EVENT_TYPE_NOTIFY_GATEKEEPER_USER_OVERRIDE => NotifyGatekeeperUserOverride (EventGatekeeperUserOverride [_ => None] { raw: raw_event.gatekeeper_user_override.as_opt()?, }),
386
387        == #[cfg(feature = "macos_15_4_0")]
388        /// Notification for a gatekeeper_user_override event.
389        ES_EVENT_TYPE_NOTIFY_TCC_MODIFY => NotifyTccModify (EventTccModify [_ => None] { raw: raw_event.tcc_modify.as_opt()?, version, }),
390    }
391);
392
393/// Type of response function to use for this event.
394///
395/// - [`Client::respond_auth_result()`][crate::Client::respond_auth_result]
396/// - [`Client::respond_flags_result()`][crate::Client::respond_flags_result]
397#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
398pub enum ExpectedResponseType {
399    /// Respond with [`Client::respond_auth_result()`][crate::Client::respond_auth_result]
400    Auth,
401    /// Respond with [`Client::respond_flags_result()`][crate::Client::respond_flags_result]
402    Flags {
403        /// Flags used by the original event
404        flags: u32,
405    },
406}
407
408/// Generate an iterator implementation for an array component of an event.
409///
410/// Safety:
411///
412/// - `raw_element_func` will be called like this: `raw_element_func(&raw_es_event, valid index)`,
413///   it must be safe to call under these conditions.
414/// - `raw_to_wrapped` will be called with the result of the preceding operation like this:
415///   `raw_to_wrapped(raw_token)`. This token COULD be null if `raw_element_func` can return `null`
416///   when called in the conditions described above. Usually Apple documents that if the event is
417///   a valid pointer and the index is correct, the function cannot return `null` and that calling
418///   outside the bounds is undefined behaviour.
419macro_rules! make_event_data_iterator {
420    ($wrapped_event: ident; $(#[$enum_doc:meta])+ $name:ident with $element_count: ident ($count_ty: ty); $item: ty; $raw_element_func: ident, $raw_to_wrapped: path$(,)?) => {
421        $(#[$enum_doc])*
422        pub struct $name<'event, 'raw> {
423            /// Wrapped event
424            ev: &'event $wrapped_event<'raw>,
425            /// Element count. When `current >= count`, the iterator is done and will only return
426            /// `None` for all subsequent calls to `next`.
427            count: $count_ty,
428            /// A call to `next` will yield element `current`
429            current: $count_ty,
430        }
431
432        impl $name<'_, '_> {
433            /// New iterator from event
434            fn new<'ev, 'raw>(ev: &'ev $wrapped_event<'raw>) -> $name<'ev, 'raw> {
435                $name {
436                    ev,
437                    count: ev.$element_count(),
438                    current: 0,
439                }
440            }
441        }
442
443        impl<'raw> std::iter::Iterator for $name<'_, 'raw> {
444            type Item = $item;
445
446            #[allow(unused_unsafe)]
447            fn next(&mut self) -> Option<Self::Item> {
448                if self.current < self.count {
449                    // Safety: Safe as raw is a reference and therefore cannot be null
450                    let raw_token = unsafe { $raw_element_func(self.ev.raw, self.current) };
451
452                    self.current = self.current.saturating_add(1);
453                    // Safety: Safe as we ensure the lifetime is rebound correctly in our wrappers
454                    Some(unsafe { $raw_to_wrapped(raw_token) })
455                } else {
456                    None
457                }
458            }
459
460            #[inline(always)]
461            fn nth(&mut self, n: usize) -> Option<Self::Item> {
462                // Overflow: the only `count_ty` used are u32 and usize. Since Apple machines are
463                // always 64-bits now (or more in the future, but that's still not a problem) it
464                // works out okay:
465                //
466                // - usize: the line does not change anything: `self.current = n`
467                // - u32: if `n > u32::MAX` is true, we clamp to `u32::MAX` to avoid something like
468                //   `.nth((u32::MAX + 1) as usize)` yielding `0` because of the truncation of
469                //   `as $count_ty`. Since the check in `.next()` is `<`, not `<=`, this will always
470                //   return `None` in that case and work correctly for valid `n`s.
471                self.current = n.min(<$count_ty>::MAX as usize) as $count_ty;
472                self.next()
473            }
474
475            #[inline(always)]
476            fn last(mut self) -> Option<Self::Item>
477            where
478                Self: Sized,
479            {
480                self.current = self.count.saturating_sub(1);
481                self.next()
482            }
483
484            #[inline(always)]
485            fn size_hint(&self) -> (usize, Option<usize>) {
486                let len = self.len();
487                (len, Some(len))
488            }
489
490            #[inline(always)]
491            fn count(mut self) -> usize {
492                let len = self.len();
493                self.current = self.count;
494                len
495            }
496        }
497
498        impl std::iter::ExactSizeIterator for $name<'_, '_> {
499            #[inline(always)]
500            fn len(&self) -> usize {
501                // Casting to usize if ok: all macOS machines are 64 bits now so a u32 will always
502                // fit into a usize
503                self.count.saturating_sub(self.current) as usize
504            }
505        }
506
507        impl std::iter::FusedIterator for $name<'_, '_> {}
508    };
509}
510
511/// Wrapper for the `.as_ref()` call on `es_string_token_t` with lifetime extension.
512///
513/// This is **only** intended for `make_event_data_iterator!`, which ensures lifetimes are correctly
514/// bound to avoid use-after-free shenanigans.
515///
516/// # Safety
517///
518/// This is a horrible horrible hack. Apple documents that the `es_string_token_t` returned by
519/// both [`es_exec_env`] and [`es_exec_arg`] are zero-allocation when in bounds and that the
520/// returned string token must not outlive the original event, which it cannot do in our
521/// iterator so it's safe. Thanks Rust for references and the borrow checker.
522unsafe fn as_os_str<'a>(x: endpoint_sec_sys::es_string_token_t) -> &'a std::ffi::OsStr {
523    // Safety: this is only called inside the iterator where `'a` will be the lifetime of `&mut self`
524    unsafe { &*(x.as_os_str() as *const _) }
525}
526
527/// Helper macro to define the event modules without copying the cfgs dozens of times.
528macro_rules! cfg_mod {
529    (
530        $( mod $b_name: ident; )*
531        $(
532            == #[$cfg: meta];
533            $( mod $name: ident; )+
534        )*
535    ) => {
536        $( mod $b_name; pub use $b_name::*; )*
537        $( $( #[$cfg] mod $name; #[$cfg] pub use $name::*; )+ )*
538    };
539}
540
541cfg_mod! {
542    mod event_close;
543    mod event_create;
544    mod event_exchangedata;
545    mod event_exec;
546    mod event_exit;
547    mod event_file_provider_materialize;
548    mod event_file_provider_update;
549    mod event_fork;
550    mod event_get_task;
551    mod event_iokit_open;
552    mod event_kextload;
553    mod event_kextunload;
554    mod event_link;
555    mod event_lookup;
556    mod event_mmap;
557    mod event_mount;
558    mod event_mprotect;
559    mod event_open;
560    mod event_read_link;
561    mod event_rename;
562    mod event_setattrlist;
563    mod event_setextattr;
564    mod event_setflags;
565    mod event_setmode;
566    mod event_setowner;
567    mod event_signal;
568    mod event_truncate;
569    mod event_unlink;
570    mod event_unmount;
571    mod event_write;
572
573    == #[cfg(feature = "macos_10_15_1")];
574    mod event_access;
575    mod event_chdir;
576    mod event_chroot;
577    mod event_clone;
578    mod event_deleteextattr;
579    mod event_dup;
580    mod event_fcntl;
581    mod event_fsgetpath;
582    mod event_getattrlist;
583    mod event_getextattr;
584    mod event_listextattr;
585    mod event_readdir;
586    mod event_setacl;
587    mod event_settime;
588    mod event_stat;
589    mod event_uipc_bind;
590    mod event_uipc_connect;
591    mod event_utimes;
592
593    == #[cfg(feature = "macos_10_15_4")];
594    mod event_pty_grant;
595    mod event_proc_check;
596    mod event_pty_close;
597
598    == #[cfg(feature = "macos_11_0_0")];
599    mod event_cs_invalidated;
600    mod event_get_task_name;
601    mod event_proc_suspend_resume;
602    mod event_remote_thread_create;
603    mod event_remount;
604    mod event_searchfs;
605    mod event_trace;
606
607    == #[cfg(feature = "macos_11_3_0")];
608    mod event_get_task_inspect;
609    mod event_get_task_read;
610
611    == #[cfg(feature = "macos_12_0_0")];
612    mod event_copyfile;
613    mod event_setegid;
614    mod event_seteuid;
615    mod event_setgid;
616    mod event_setregid;
617    mod event_setreuid;
618    mod event_setuid;
619
620    == #[cfg(feature = "macos_13_0_0")];
621    mod event_authentication;
622    mod event_xp_malware_detected;
623    mod event_xp_malware_remediated;
624    mod event_lw_session_login;
625    mod event_lw_session_logout;
626    mod event_lw_session_lock;
627    mod event_lw_session_unlock;
628    mod event_screesharing_attach;
629    mod event_screesharing_detach;
630    mod event_openssh_login;
631    mod event_openssh_logout;
632    mod event_login_login;
633    mod event_login_logout;
634    mod event_btm_launch_item_add;
635    mod event_btm_launch_item_remove;
636
637    == #[cfg(feature = "macos_14_0_0")];
638    mod event_profile_add;
639    mod event_profile_remove;
640    mod event_su;
641    mod event_authorization_petition;
642    mod event_authorization_judgement;
643    mod event_sudo;
644    mod event_od_group_add;
645    mod event_od_group_remove;
646    mod event_od_group_set;
647    mod event_od_modify_password;
648    mod event_od_disable_user;
649    mod event_od_enable_user;
650    mod event_od_attribute_value_add;
651    mod event_od_attribute_value_remove;
652    mod event_od_attribute_set;
653    mod event_od_create_user;
654    mod event_od_create_group;
655    mod event_od_delete_user;
656    mod event_od_delete_group;
657    mod event_xpc_connect;
658
659    == #[cfg(feature = "macos_15_0_0")];
660    mod event_gatekeeper_user_override;
661
662    == #[cfg(feature = "macos_15_4_0")];
663    mod event_tcc_modify;
664}