mirror of
https://github.com/OpenListTeam/OpenList-Desktop.git
synced 2025-11-25 03:14:56 +08:00
feat: add Windows firewall management for openlist port #49
This commit is contained in:
120
src-tauri/src/cmd/firewall.rs
Normal file
120
src-tauri/src/cmd/firewall.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
#[cfg(target_os = "windows")]
|
||||
use std::os::windows::process::CommandExt;
|
||||
use std::process::{Command, ExitStatus};
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
#[cfg(target_os = "windows")]
|
||||
use runas::Command as RunasCommand;
|
||||
use tauri::State;
|
||||
|
||||
use crate::object::structs::AppState;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const RULE: &str = "OpenList Core";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn netsh_with_elevation(args: &[String]) -> Result<ExitStatus, String> {
|
||||
let token = Token::with_current_process().map_err(|e| format!("token: {e}"))?;
|
||||
let elevated = !matches!(
|
||||
token
|
||||
.privilege_level()
|
||||
.map_err(|e| format!("privilege: {e}"))?,
|
||||
PrivilegeLevel::NotPrivileged
|
||||
);
|
||||
|
||||
if elevated {
|
||||
Command::new("netsh")
|
||||
.args(args)
|
||||
.creation_flags(0x08000000)
|
||||
.status()
|
||||
} else {
|
||||
RunasCommand::new("netsh").args(args).show(false).status()
|
||||
}
|
||||
.map_err(|e| format!("netsh: {e}"))
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn firewall_rule(verb: &str, port: Option<u16>) -> Result<bool, String> {
|
||||
let mut args: Vec<String> = vec![
|
||||
"advfirewall".into(),
|
||||
"firewall".into(),
|
||||
verb.into(),
|
||||
"rule".into(),
|
||||
format!("name={RULE}"),
|
||||
];
|
||||
if let Some(p) = port {
|
||||
args.extend([
|
||||
"dir=in".into(),
|
||||
"action=allow".into(),
|
||||
"protocol=TCP".into(),
|
||||
format!("localport={p}"),
|
||||
"description=Allow OpenList Core web interface access".into(),
|
||||
]);
|
||||
}
|
||||
Ok(netsh_with_elevation(&args)?.success())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn rule_stdout() -> Result<Option<String>, String> {
|
||||
let out = Command::new("netsh")
|
||||
.args([
|
||||
"advfirewall",
|
||||
"firewall",
|
||||
"show",
|
||||
"rule",
|
||||
&format!("name={RULE}"),
|
||||
])
|
||||
.output()
|
||||
.map_err(|e| format!("netsh: {e}"))?;
|
||||
if out.status.success() {
|
||||
Ok(Some(String::from_utf8_lossy(&out.stdout).into()))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn firewall_rule(_: &str, _: Option<u16>) -> Result<bool, String> {
|
||||
Ok(true)
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn rule_stdout() -> Result<Option<String>, String> {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn check_firewall_rule(state: State<'_, AppState>) -> Result<bool, String> {
|
||||
let port = state
|
||||
.app_settings
|
||||
.read()
|
||||
.clone()
|
||||
.ok_or("read settings")?
|
||||
.openlist
|
||||
.port;
|
||||
|
||||
if let Some(out) = rule_stdout()? {
|
||||
Ok(out.contains(&port.to_string()))
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn add_firewall_rule(state: State<'_, AppState>) -> Result<bool, String> {
|
||||
let port = state
|
||||
.app_settings
|
||||
.read()
|
||||
.clone()
|
||||
.ok_or("read settings")?
|
||||
.openlist
|
||||
.port;
|
||||
|
||||
let _ = firewall_rule("delete", None);
|
||||
firewall_rule("add", Some(port))
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn remove_firewall_rule(_state: State<'_, AppState>) -> Result<bool, String> {
|
||||
firewall_rule("delete", None)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
pub mod binary;
|
||||
pub mod config;
|
||||
pub mod custom_updater;
|
||||
pub mod firewall;
|
||||
pub mod http_api;
|
||||
pub mod logs;
|
||||
pub mod openlist_core;
|
||||
|
||||
@@ -13,6 +13,7 @@ use cmd::custom_updater::{
|
||||
check_for_updates, download_update, get_current_version, install_update_and_restart,
|
||||
is_auto_check_enabled, set_auto_check_enabled,
|
||||
};
|
||||
use cmd::firewall::{add_firewall_rule, check_firewall_rule, remove_firewall_rule};
|
||||
use cmd::http_api::{
|
||||
delete_process, get_process_list, restart_process, start_process, stop_process, update_process,
|
||||
};
|
||||
@@ -159,6 +160,9 @@ pub fn run() {
|
||||
check_service_status,
|
||||
stop_service,
|
||||
start_service,
|
||||
check_firewall_rule,
|
||||
add_firewall_rule,
|
||||
remove_firewall_rule,
|
||||
check_for_updates,
|
||||
download_update,
|
||||
install_update_and_restart,
|
||||
|
||||
Reference in New Issue
Block a user