docs: update README with desktop requirements, helper builds, and realistic MVP usage notes
Expand README with desktop platform requirements (Windows x86, macOS ARM), helper build commands, gateway utility scripts, and updated local test flow. Add realistic MVP usage section clarifying current platform build status, gateway configuration needs, and admin debug profile behavior with client private key handling.
This commit is contained in:
114
desktop-client/tunnel-helper/src/main.rs
Normal file
114
desktop-client/tunnel-helper/src/main.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
use std::{
|
||||
env,
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, ExitCode},
|
||||
};
|
||||
|
||||
fn main() -> ExitCode {
|
||||
match run() {
|
||||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(err) => {
|
||||
eprintln!("{err}");
|
||||
ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<(), String> {
|
||||
let mut args = env::args().skip(1);
|
||||
let command = args.next().ok_or_else(|| "missing command".to_string())?;
|
||||
let flag = args.next().ok_or_else(|| "missing --profile flag".to_string())?;
|
||||
if flag != "--profile" {
|
||||
return Err("expected --profile flag".into());
|
||||
}
|
||||
let profile = PathBuf::from(args.next().ok_or_else(|| "missing profile path".to_string())?);
|
||||
|
||||
match command.as_str() {
|
||||
"connect" => connect(&profile),
|
||||
"disconnect" => disconnect(&profile),
|
||||
_ => Err("unsupported command".into()),
|
||||
}
|
||||
}
|
||||
|
||||
fn connect(profile: &Path) -> Result<(), String> {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let wireguard = find_windows_wireguard()?;
|
||||
let status = Command::new(wireguard)
|
||||
.arg("/installtunnelservice")
|
||||
.arg(profile)
|
||||
.status()
|
||||
.map_err(|err| format!("unable to launch WireGuard runtime: {err}"))?;
|
||||
if !status.success() {
|
||||
return Err(format!("WireGuard runtime connect failed with status {status}"));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let command = format!("wg-quick up '{}'", profile.display());
|
||||
let status = Command::new("osascript")
|
||||
.arg("-e")
|
||||
.arg(format!("do shell script \"{}\" with administrator privileges", command))
|
||||
.status()
|
||||
.map_err(|err| format!("unable to start tunnel: {err}"))?;
|
||||
if !status.success() {
|
||||
return Err(format!("macOS tunnel connect failed with status {status}"));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
Err("unsupported platform".into())
|
||||
}
|
||||
|
||||
fn disconnect(profile: &Path) -> Result<(), String> {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let wireguard = find_windows_wireguard()?;
|
||||
let tunnel_name = profile
|
||||
.file_stem()
|
||||
.and_then(|value| value.to_str())
|
||||
.ok_or_else(|| "invalid profile filename".to_string())?;
|
||||
let status = Command::new(wireguard)
|
||||
.arg("/uninstalltunnelservice")
|
||||
.arg(tunnel_name)
|
||||
.status()
|
||||
.map_err(|err| format!("unable to launch WireGuard runtime: {err}"))?;
|
||||
if !status.success() {
|
||||
return Err(format!("WireGuard runtime disconnect failed with status {status}"));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
let command = format!("wg-quick down '{}'", profile.display());
|
||||
let status = Command::new("osascript")
|
||||
.arg("-e")
|
||||
.arg(format!("do shell script \"{}\" with administrator privileges", command))
|
||||
.status()
|
||||
.map_err(|err| format!("unable to stop tunnel: {err}"))?;
|
||||
if !status.success() {
|
||||
return Err(format!("macOS tunnel disconnect failed with status {status}"));
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
Err("unsupported platform".into())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn find_windows_wireguard() -> Result<PathBuf, String> {
|
||||
let candidates = [
|
||||
PathBuf::from(r"C:\Program Files\WireGuard\wireguard.exe"),
|
||||
PathBuf::from(r"C:\Program Files (x86)\WireGuard\wireguard.exe"),
|
||||
];
|
||||
|
||||
candidates
|
||||
.into_iter()
|
||||
.find(|path| path.exists())
|
||||
.ok_or_else(|| "required Windows tunnel runtime is not available".to_string())
|
||||
}
|
||||
Reference in New Issue
Block a user