use serde::{Deserialize, Serialize};
pub const DEFAULT_SOCKET_PATH: &str = "/run/aa-ebpf-loaderd.sock";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum ProbeSet {
FileIo,
Exec,
Tls,
SyscallGuard,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PathRuleWire {
pub pattern: String,
pub deny: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ControlRequest {
LoadProbeSet {
set: ProbeSet,
target_pid: u32,
},
UpdatePathMap {
rules: Vec<PathRuleWire>,
},
UpdateSyscallAllowlist {
syscalls: Vec<u32>,
},
Detach {
set: ProbeSet,
},
Ping,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum ControlResponse {
Ok,
Pong,
Error {
message: String,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn request_round_trips_through_json() {
let req = ControlRequest::UpdatePathMap {
rules: vec![PathRuleWire {
pattern: "/etc".to_string(),
deny: true,
}],
};
let bytes = serde_json::to_vec(&req).unwrap();
let back: ControlRequest = serde_json::from_slice(&bytes).unwrap();
assert_eq!(req, back);
}
#[test]
fn load_request_round_trips() {
let req = ControlRequest::LoadProbeSet {
set: ProbeSet::FileIo,
target_pid: 4321,
};
let bytes = serde_json::to_vec(&req).unwrap();
assert_eq!(serde_json::from_slice::<ControlRequest>(&bytes).unwrap(), req);
}
#[test]
fn response_round_trips() {
for resp in [
ControlResponse::Ok,
ControlResponse::Pong,
ControlResponse::Error {
message: "denied".to_string(),
},
] {
let bytes = serde_json::to_vec(&resp).unwrap();
assert_eq!(serde_json::from_slice::<ControlResponse>(&bytes).unwrap(), resp);
}
}
#[test]
fn default_socket_is_root_owned_run_path() {
assert!(DEFAULT_SOCKET_PATH.starts_with("/run/"));
}
#[test]
fn syscall_guard_requests_round_trip() {
let load = ControlRequest::LoadProbeSet {
set: ProbeSet::SyscallGuard,
target_pid: 99,
};
let bytes = serde_json::to_vec(&load).unwrap();
assert_eq!(serde_json::from_slice::<ControlRequest>(&bytes).unwrap(), load);
let update = ControlRequest::UpdateSyscallAllowlist {
syscalls: vec![0, 1, 3, 60],
};
let bytes = serde_json::to_vec(&update).unwrap();
assert_eq!(serde_json::from_slice::<ControlRequest>(&bytes).unwrap(), update);
let detach = ControlRequest::Detach {
set: ProbeSet::SyscallGuard,
};
let bytes = serde_json::to_vec(&detach).unwrap();
assert_eq!(serde_json::from_slice::<ControlRequest>(&bytes).unwrap(), detach);
}
}