Skip to content

Commit

Permalink
fix(firewall): handle firewall rules on windows (#712)
Browse files Browse the repository at this point in the history
Co-authored-by: Brian Pearce <[email protected]>
  • Loading branch information
mmrrnn and brianp authored Nov 22, 2024
1 parent 55f258d commit 49beeec
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 1 deletion.
1 change: 1 addition & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ version = "0.7.4"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[build-dependencies]
embed-resource = "2.5.0"
tauri-build = { version = "1.5.5", features = ["isolation"] }

[dependencies]
Expand Down
34 changes: 33 additions & 1 deletion src-tauri/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
fn main() {
tauri_build::build()
if cfg!(target_os = "windows") {
let mut windows = tauri_build::WindowsAttributes::new();
// Require Administrator permissions to handle Firewall prompts
windows = windows.app_manifest(
r#"
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
"#,
);
let attrs = tauri_build::Attributes::new().windows_attributes(windows);
tauri_build::try_build(attrs).expect("failed to run build script")
} else {
tauri_build::build()
}
}
6 changes: 6 additions & 0 deletions src-tauri/src/gpu_miner_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ use tari_common::configuration::Network;
use tari_common_types::tari_address::TariAddress;
use tari_shutdown::Shutdown;

#[cfg(target_os = "windows")]
use crate::utils::setup_utils::setup_utils::add_firewall_rule;

use crate::{
app_config::MiningMode,
process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor},
Expand Down Expand Up @@ -191,6 +194,9 @@ impl ProcessAdapter for GpuMinerAdapter {
}
}

#[cfg(target_os = "windows")]
add_firewall_rule("xtrgpuminer.exe".to_string(), binary_version_path.clone())?;

Ok((
ProcessInstance {
shutdown: inner_shutdown,
Expand Down
6 changes: 6 additions & 0 deletions src-tauri/src/node_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ use tari_crypto::ristretto::RistrettoPublicKey;
use tari_shutdown::{Shutdown, ShutdownSignal};
use tari_utilities::ByteArray;

#[cfg(target_os = "windows")]
use crate::utils::setup_utils::setup_utils::add_firewall_rule;

const LOG_TARGET: &str = "tari::universe::minotari_node_adapter";

pub(crate) struct MinotariNodeAdapter {
Expand Down Expand Up @@ -160,6 +163,9 @@ impl ProcessAdapter for MinotariNodeAdapter {
// );
}

#[cfg(target_os = "windows")]
add_firewall_rule("minotari_node.exe".to_string(), binary_version_path.clone())?;

Ok((
ProcessInstance {
shutdown: inner_shutdown,
Expand Down
7 changes: 7 additions & 0 deletions src-tauri/src/p2pool_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ use crate::process_adapter::ProcessStartupSpec;
use crate::process_adapter::{ProcessAdapter, ProcessInstance, StatusMonitor};
use crate::utils::file_utils::convert_to_string;

#[cfg(target_os = "windows")]
use crate::utils::setup_utils::setup_utils::add_firewall_rule;

const LOG_TARGET: &str = "tari::universe::p2pool_adapter";

pub struct P2poolAdapter {
Expand Down Expand Up @@ -91,6 +94,10 @@ impl ProcessAdapter for P2poolAdapter {
return Err(anyhow!("Unsupported network"));
}
};

#[cfg(target_os = "windows")]
add_firewall_rule("sha_p2pool.exe".to_string(), binary_version_path.clone())?;

Ok((
ProcessInstance {
shutdown: inner_shutdown,
Expand Down
1 change: 1 addition & 0 deletions src-tauri/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pub mod auto_rollback;
pub mod file_utils;
pub mod logging_utils;
pub mod platform_utils;
pub mod setup_utils;
76 changes: 76 additions & 0 deletions src-tauri/src/utils/setup_utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#[cfg(windows)]
pub mod setup_utils {
use log::{error, info};
use std::io::{self, Write};
use std::os::windows::process::CommandExt;
use std::path::PathBuf;
use std::process::Command;

use crate::consts::PROCESS_CREATION_NO_WINDOW;

const LOG_TARGET: &str = "tari::universe::setup_utils";

fn check_netsh_rule_exists(rule_name: String) -> bool {
let output = Command::new("netsh")
.arg("advfirewall")
.arg("firewall")
.arg("show")
.arg("rule")
.arg(format!("name={}", rule_name))
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.creation_flags(PROCESS_CREATION_NO_WINDOW)
.output()
.expect("Failed to execute netsh command");

if output.status.success() {
let stdout = String::from_utf8_lossy(&output.stdout);
let lines: Vec<&str> = stdout.split('\n').collect();
for line in lines {
if line.contains("Action:") {
let action = line.split(':').nth(1).unwrap_or("").trim();
if action == "Allow" {
return true;
}
}
}
}
false
}

pub fn add_firewall_rule(binary_name: String, binary_path: PathBuf) -> io::Result<()> {
if !check_netsh_rule_exists(binary_name.clone()) {
// Add a firewall rule to allow inbound connections
let output = Command::new("netsh")
.args(&[
"advfirewall",
"firewall",
"add",
"rule",
&format!("name={}", binary_name),
"dir=in",
"action=allow",
&format!(
"program={}.exe",
&binary_path.to_str().expect("Could not get binary path")
),
"profile=public",
])
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.creation_flags(PROCESS_CREATION_NO_WINDOW)
.output()?;

if output.status.success() {
info!(target: LOG_TARGET, "Firewall rule added successfully.");
} else {
io::stderr().write_all(&output.stderr)?;
error!(target: LOG_TARGET, "Failed to add firewall rule.");
}
} else {
info!(target: LOG_TARGET, "Firewall rule already exists.");
}

Ok(())
}
}
9 changes: 9 additions & 0 deletions src-tauri/src/wallet_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ use tari_crypto::ristretto::RistrettoPublicKey;
use tari_shutdown::Shutdown;
use tari_utilities::hex::Hex;

#[cfg(target_os = "windows")]
use crate::utils::setup_utils::setup_utils::add_firewall_rule;

const LOG_TARGET: &str = "tari::universe::wallet_adapter";

pub struct WalletAdapter {
Expand Down Expand Up @@ -145,6 +148,12 @@ impl ProcessAdapter for WalletAdapter {
warn!(target: LOG_TARGET, "Could not clear wallet data folder: {}", e);
}

#[cfg(target_os = "windows")]
add_firewall_rule(
"minotari_console_wallet.exe".to_string(),
binary_version_path.clone(),
)?;

Ok((
ProcessInstance {
shutdown: inner_shutdown,
Expand Down

0 comments on commit 49beeec

Please sign in to comment.