use std::collections::{HashMap, HashSet};
use syscalls::Sysno;
use super::YesReally;
use crate::{Rule, RuleSet};
const NET_IO_SYSCALLS: &[Sysno] = &[
Sysno::epoll_create, Sysno::epoll_create1,
Sysno::epoll_ctl, Sysno::epoll_wait, Sysno::epoll_pwait, Sysno::epoll_pwait2,
Sysno::select, Sysno::pselect6,
Sysno::poll, Sysno::ppoll,
Sysno::accept, Sysno::accept4,
Sysno::eventfd, Sysno::eventfd2,
Sysno::fcntl, Sysno::ioctl,
Sysno::getsockopt,
Sysno::setsockopt,
Sysno::getpeername,
Sysno::getsockname,
];
const NET_READ_SYSCALLS: &[Sysno] = &[Sysno::listen,
Sysno::recvfrom, Sysno::recvmsg, Sysno::recvmmsg,
Sysno::read, Sysno::readv, Sysno::preadv, Sysno::preadv2];
const NET_WRITE_SYSCALLS: &[Sysno] = &[Sysno::sendto, Sysno::sendmsg, Sysno::sendmmsg,
Sysno::sendfile,
Sysno::write, Sysno::writev, Sysno::pwritev, Sysno::pwritev2];
const NET_CREATE_SERVER_SYSCALLS: &[Sysno] = &[Sysno::socket, Sysno::bind];
const NET_CREATE_CLIENT_SYSCALLS: &[Sysno] = &[Sysno::socket, Sysno::connect];
pub struct Networking {
allowed: HashSet<Sysno>,
custom: HashMap<Sysno, Vec<Rule>>,
}
impl Networking {
#[must_use]
pub fn nothing() -> Networking {
Networking {
allowed: HashSet::new(),
custom: HashMap::new(),
}
}
#[must_use]
pub fn allow_running_tcp_servers(mut self) -> Networking {
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
self
}
#[must_use]
pub fn allow_start_tcp_servers(mut self) -> YesReally<Networking> {
self.allowed.extend(NET_CREATE_SERVER_SYSCALLS);
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
YesReally::new(self)
}
#[must_use]
pub fn allow_running_udp_sockets(mut self) -> Networking {
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
self
}
#[must_use]
pub fn allow_start_udp_servers(mut self) -> YesReally<Networking> {
self.allowed.extend(NET_CREATE_SERVER_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
YesReally::new(self)
}
#[must_use]
pub fn allow_start_tcp_clients(mut self) -> Networking {
self.allowed.extend(NET_CREATE_CLIENT_SYSCALLS);
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
self
}
#[must_use]
pub fn allow_running_tcp_clients(mut self) -> Networking {
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
self
}
#[must_use]
pub fn allow_start_unix_server(mut self) -> YesReally<Networking> {
self.allowed.extend(NET_CREATE_SERVER_SYSCALLS);
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
YesReally::new(self)
}
#[must_use]
pub fn allow_running_unix_servers(mut self) -> Networking {
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
self
}
#[must_use]
pub fn allow_running_unix_clients(mut self) -> Networking {
self.allowed.extend(NET_IO_SYSCALLS);
self.allowed.extend(NET_READ_SYSCALLS);
self.allowed.extend(NET_WRITE_SYSCALLS);
self
}
}
impl RuleSet for Networking {
fn simple_rules(&self) -> Vec<syscalls::Sysno> {
self.allowed.iter().copied().collect()
}
fn conditional_rules(&self) -> HashMap<syscalls::Sysno, Vec<Rule>> {
self.custom.clone()
}
fn name(&self) -> &'static str {
"Networking"
}
}