use std::fmt;
use std::path::PathBuf;
#[cfg(any(windows, test))]
mod rules;
#[cfg(windows)]
mod windows;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Profile {
Domain,
Private,
Public,
}
impl Profile {
const ALL: [Self; 3] = [Self::Domain, Self::Private, Self::Public];
#[must_use]
pub fn name(self) -> &'static str {
match self {
Self::Domain => "domain",
Self::Private => "private",
Self::Public => "public",
}
}
fn bit(self) -> u32 {
match self {
Self::Domain => 1,
Self::Private => 2,
Self::Public => 4,
}
}
}
impl fmt::Display for Profile {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.name())
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct Profiles(u32);
impl Profiles {
pub fn iter(self) -> impl Iterator<Item = Profile> {
Profile::ALL
.into_iter()
.filter(move |&profile| self.has(profile))
}
fn has(self, profile: Profile) -> bool {
self.0 & profile.bit() != 0
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Problem {
MissingAllow {
program: PathBuf,
ports: Vec<u16>,
profiles: Profiles,
},
Blocked { rule: String, ports: Vec<u16> },
}
#[derive(Debug, thiserror::Error)]
pub enum CheckError {
#[error("cannot find the path of this program: {0}")]
Program(#[from] std::io::Error),
#[error("the firewall could not be queried (HRESULT {0:#010x})")]
Query(i32),
}
pub const SUPPORTED: bool = cfg!(windows);
pub fn check(port: u16) -> Result<Vec<Problem>, CheckError> {
#[cfg(windows)]
return windows::check(port);
#[cfg(not(windows))]
{
let _ = port;
Ok(Vec::new())
}
}