endpoint_sec/event/
event_authorization_judgement.rs

1//! [`EventAuthorizationJudgement`]
2
3use std::ffi::OsStr;
4
5use endpoint_sec_sys::{es_authorization_result_t, es_authorization_rule_class_t, es_event_authorization_judgement_t};
6
7use crate::Process;
8
9/// Notification that a process had it's right petition judged
10#[doc(alias = "es_event_authorization_judgement_t")]
11pub struct EventAuthorizationJudgement<'a> {
12    /// The raw reference.
13    pub(crate) raw: &'a es_event_authorization_judgement_t,
14    /// The version of the message.
15    pub(crate) version: u32,
16}
17
18impl<'a> EventAuthorizationJudgement<'a> {
19    /// Process that submitted the petition (XPC caller)
20    #[inline(always)]
21    pub fn instigator(&self) -> Process<'a> {
22        // Safety: 'a tied to self, object obtained through ES
23        Process::new(unsafe { self.raw.instigator.as_ref() }, self.version)
24    }
25
26    /// Process that created the petition
27    #[inline(always)]
28    pub fn petitioner(&self) -> Option<Process<'a>> {
29        Some(Process::new(
30            // Safety: 'a tied to self, object obtained through ES
31            unsafe { self.raw.petitioner.as_ref()? },
32            self.version,
33        ))
34    }
35
36    /// The overall result of the petition. 0 indicates success.
37    ///
38    /// Possible return codes are defined in Security framework "Authorization/Authorization.h"
39    #[inline(always)]
40    pub fn return_code(&self) -> i32 {
41        self.raw.return_code
42    }
43
44    /// Number of results.
45    #[inline(always)]
46    pub fn result_count(&self) -> usize {
47        self.raw.result_count
48    }
49
50    /// Iterator over the results
51    #[inline(always)]
52    pub fn rights<'event>(&'event self) -> AuthorizationJudgementResults<'event, 'a> {
53        AuthorizationJudgementResults::new(self)
54    }
55}
56
57// Safety: safe to send across threads: does not contain any interior mutability nor depend on current thread state
58unsafe impl Send for EventAuthorizationJudgement<'_> {}
59// Safety: safe to share across threads: does not contain any interior mutability nor depend on current thread state
60unsafe impl Sync for EventAuthorizationJudgement<'_> {}
61
62impl_debug_eq_hash_with_functions!(EventAuthorizationJudgement<'a> with version; instigator, petitioner, return_code, result_count);
63
64/// Describes, for a single right, the class of that right and if it was granted
65#[doc(alias = "es_authorization_result_t")]
66pub struct AuthorizationResult<'a> {
67    /// The raw reference.
68    pub(crate) raw: &'a es_authorization_result_t,
69}
70
71impl<'a> AuthorizationResult<'a> {
72    /// The name of the right being considered
73    #[inline(always)]
74    pub fn right_name(&self) -> &'a OsStr {
75        // Safety: 'a tied to self, object obtained through ES
76        unsafe { self.raw.right_name.as_os_str() }
77    }
78
79    /// The class of the right being considered
80    ///
81    /// The rule class determines how the operating system determines if it should be granted or not
82    #[inline(always)]
83    pub fn rule_class(&self) -> es_authorization_rule_class_t {
84        self.raw.rule_class
85    }
86    /// Indicates if the right was granted or not
87    #[inline(always)]
88    pub fn granted(&self) -> bool {
89        self.raw.granted
90    }
91}
92
93// Safety: safe to send across threads: does not contain any interior mutability nor depend on current thread state
94unsafe impl Send for AuthorizationResult<'_> {}
95
96impl_debug_eq_hash_with_functions!(AuthorizationResult<'a>; right_name, rule_class, granted);
97
98/// Read the `idx` result of `raw`
99///
100/// # Safety
101///
102/// Must be called with a valid event for which `idx` is in range `0..raw.result_count`
103unsafe fn read_nth_result(raw: &es_event_authorization_judgement_t, idx: usize) -> *const es_authorization_result_t {
104    raw.results.add(idx).cast_const()
105}
106
107/// See [`super::as_os_str()`] for lifetime and safety docs
108unsafe fn make_result<'a>(result: *const es_authorization_result_t) -> AuthorizationResult<'a> {
109    assert!(!result.is_null());
110    AuthorizationResult {
111        raw: unsafe { &*result },
112    }
113}
114
115make_event_data_iterator!(
116    EventAuthorizationJudgement;
117    /// Iterator over the rights of an [`EventAuthorizationJudgement`]
118    AuthorizationJudgementResults with result_count (usize);
119    AuthorizationResult<'raw>;
120    read_nth_result,
121    make_result,
122);