add firewall helper util

This commit is contained in:
2025-12-12 03:52:40 -05:00
committed by Sapphire
parent ade95b5c65
commit 4205a332a7
2 changed files with 79 additions and 0 deletions
+1
View File
@@ -1,5 +1,6 @@
pub mod consts;
pub mod countdown;
pub mod firewall;
pub mod logging;
pub mod persistent_state;
pub mod system_info;
+78
View File
@@ -0,0 +1,78 @@
use std::{error::Error, path::PathBuf};
use windows::{
Win32::{
NetworkManagement::WindowsFirewall::{
INetFwPolicy2, INetFwRule, NET_FW_ACTION_BLOCK, NET_FW_IP_PROTOCOL_ANY,
NET_FW_IP_PROTOCOL_TCP, NET_FW_IP_PROTOCOL_UDP, NET_FW_RULE_DIR_IN,
NET_FW_RULE_DIR_OUT, NetFwPolicy2, NetFwRule,
},
System::Com::{CLSCTX_INPROC_SERVER, CoCreateInstance},
},
core::BSTR,
};
pub struct Firewall {
policy: INetFwPolicy2,
}
impl Firewall {
pub fn new() -> Result<Self, Box<dyn Error>> {
Ok(Self {
policy: unsafe { CoCreateInstance(&NetFwPolicy2, None, CLSCTX_INPROC_SERVER) }?,
})
}
pub fn add(
&self,
name: &str,
mode: RuleMode,
direction: RuleDirection,
protocol: RuleProtocol,
) -> Result<(), Box<dyn Error>> {
let rules = unsafe { self.policy.Rules() }?;
unsafe { rules.Remove(&BSTR::from(name)) }?;
let rule: INetFwRule = unsafe { CoCreateInstance(&NetFwRule, None, CLSCTX_INPROC_SERVER) }?;
unsafe { rule.SetName(&BSTR::from(name)) }?;
match mode {
RuleMode::Executable(exe) => {
unsafe { rule.SetApplicationName(&BSTR::from(exe.to_string_lossy().to_string())) }?
}
RuleMode::Address(ip) => unsafe { rule.SetRemoteAddresses(&BSTR::from(ip)) }?,
}
match direction {
RuleDirection::In => unsafe { rule.SetDirection(NET_FW_RULE_DIR_IN) }?,
RuleDirection::Out => unsafe { rule.SetDirection(NET_FW_RULE_DIR_OUT) }?,
}
unsafe { rule.SetEnabled(true.into()) }?;
unsafe { rule.SetAction(NET_FW_ACTION_BLOCK) }?;
match protocol {
RuleProtocol::Any => unsafe { rule.SetProtocol(NET_FW_IP_PROTOCOL_ANY.0) }?,
RuleProtocol::Tcp => unsafe { rule.SetProtocol(NET_FW_IP_PROTOCOL_TCP.0) }?,
RuleProtocol::Udp => unsafe { rule.SetProtocol(NET_FW_IP_PROTOCOL_UDP.0) }?,
}
unsafe { rules.Add(&rule) }?;
Ok(())
}
pub fn remove(&self, name: &str) -> Result<(), Box<dyn Error>> {
let rules = unsafe { self.policy.Rules() }?;
unsafe { rules.Remove(&BSTR::from(name)) }?;
Ok(())
}
}
pub enum RuleMode {
Executable(PathBuf),
Address(String),
}
pub enum RuleDirection {
In,
Out,
}
pub enum RuleProtocol {
Any,
Tcp,
Udp,
}