diff --git a/Cargo.lock b/Cargo.lock index fda0d79..50eda76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,12 +43,6 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" -[[package]] -name = "boxfnonce" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426" - [[package]] name = "bumpalo" version = "3.4.0" @@ -106,16 +100,6 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826" -[[package]] -name = "daemonize" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70c24513e34f53b640819f0ac9f705b673fcf4006d7aab8778bee72ebfc89815" -dependencies = [ - "boxfnonce", - "libc", -] - [[package]] name = "discard" version = "1.0.4" @@ -267,31 +251,6 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -[[package]] -name = "nix" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce" -dependencies = [ - "bitflags", - "cc", - "cfg-if 0.1.10", - "libc", - "void", -] - -[[package]] -name = "nix" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" -dependencies = [ - "bitflags", - "cc", - "cfg-if 1.0.0", - "libc", -] - [[package]] name = "once_cell" version = "1.5.2" @@ -310,16 +269,6 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" -[[package]] -name = "privdrop" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd4c2739642e70439d1c0d9545beec45c1e54128739b3cda29bf2c366028c87" -dependencies = [ - "libc", - "nix 0.19.1", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -555,16 +504,6 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -[[package]] -name = "signal" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f6ce83b159ab6984d2419f495134972b48754d13ff2e3f8c998339942b56ed9" -dependencies = [ - "libc", - "nix 0.14.1", -] - [[package]] name = "smallvec" version = "1.5.1" @@ -838,29 +777,20 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - [[package]] name = "vpncloud" version = "2.0.1" dependencies = [ "byteorder", - "daemonize", "fnv", "igd", "libc", "log", - "privdrop", "rand 0.8.0", "ring", "serde", "serde_derive", "serde_yaml", - "signal", "smallvec", "structopt", "tempfile", diff --git a/Cargo.toml b/Cargo.toml index 9ff9d3a..f21a86a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,15 +18,15 @@ serde = "1.0" serde_derive = "1.0" serde_yaml = "0.8" log = { version = "0.4", features = ["std"] } -signal = "0.7" +#signal = "0.7" libc = "0.2" rand = "0.8" fnv = "1" yaml-rust = "0.4" igd = { version = "0.11", optional = true } -daemonize = "0.4" +#daemonize = "0.4" ring = "0.16" -privdrop = "0.5" +#privdrop = "0.5" byteorder = "1.3" thiserror = "1.0" smallvec = "1.5" diff --git a/WINDOWS.md b/WINDOWS.md new file mode 100644 index 0000000..fb479ca --- /dev/null +++ b/WINDOWS.md @@ -0,0 +1,76 @@ +# VpnCloud for Windows + +## Toolchain + +rustup target add x86_64-pc-windows-gnu +rustup toolchain install stable-x86_64-pc-windows-gnu +apt-get install mingw64 + +## Problems + +### Running VpnCloud + +**Problem:** + +- Library "daemonize" does not compile + - Windows uses "Services" instead of daemonized processes +- Library "privdrop" does not compile + - Is dropping privileges in Windows services even a thing? +- Library "signal" does not compile + - Windows services work differently, no Ctrl-C handling needed +- Normal Windows programs can't stay active when the user logs out + +**Potential solution:** + +- Wrap VpnCloud as Windows service + - https://github.com/mullvad/windows-service-rs +- Do not support dropping privileges under Windows + +### Polling solution + +**Problem:** + +- Epoll is Linux only +- RawFd is Unix only + +**Potential solution:** + +Use multi-threading to remove the need to wait on multiple events at the same time: + +- One thread waits on the device and sends to the socket +- One thread waits on the socket and sends to the device and handles the control traffic + +Problems to solve: + +- Synchronization is slow + - Do not use locking in hot code, cache shared data locally and synchronize periodically + +### Tun/Tap devices + +**Problem:** + +Tun/Tap works completely different on Windows + +- Drivers need to be signed by Microsoft, complicated process + +**Potential solution:** + +Use existing Tun & Tap drivers: + +- (Old) TapWindows from OpenVPN project + - https://community.openvpn.net/openvpn/wiki/GettingTapWindows + - https://github.com/Tazdevil971/tap-windows + +- (New) WinTun from Wireguard + - https://www.wintun.net/ + +### Configuration + +**Problem:** + +- Windows users are not used to write config files and execute commands +- Windows setup is more complicated than in Linux (install Drivers, register Services, etc.) + +**Potential solution:** + +- Create configuration UI diff --git a/src/main.rs b/src/main.rs index 156f17d..d49645e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -189,30 +189,9 @@ fn run(config: Config) { cloud.add_reconnect_peer(addr); } if config.daemonize { - info!("Running process as daemon"); - let mut daemonize = daemonize::Daemonize::new(); - if let Some(user) = config.user { - daemonize = daemonize.user(&user as &str); - } - if let Some(group) = config.group { - daemonize = daemonize.group(&group as &str); - } - if let Some(pid_file) = config.pid_file { - daemonize = daemonize.pid_file(pid_file).chown_pid_file(true); - // Give child process some time to write PID file - daemonize = daemonize.exit_action(|| thread::sleep(std::time::Duration::from_millis(10))); - } - try_fail!(daemonize.start(), "Failed to daemonize: {}"); + error!("Daemonize not supported under windows"); } else if config.user.is_some() || config.group.is_some() { - info!("Dropping privileges"); - let mut pd = privdrop::PrivDrop::default(); - if let Some(user) = config.user { - pd = pd.user(user); - } - if let Some(group) = config.group { - pd = pd.group(group); - } - try_fail!(pd.apply(), "Failed to drop privileges: {}"); + error!("Privdrop not supported under windows"); } cloud.run(); if let Some(script) = config.ifdown { diff --git a/src/util.rs b/src/util.rs index 42a53b1..f690304 100644 --- a/src/util.rs +++ b/src/util.rs @@ -12,7 +12,6 @@ use crate::error::Error; #[cfg(not(target_os = "linux"))] use time; -use signal::{trap::Trap, Signal}; use smallvec::SmallVec; use std::time::Instant; @@ -272,7 +271,6 @@ impl fmt::Display for Bytes { pub struct CtrlC { dummy_time: Instant, - trap: Trap } impl CtrlC { @@ -281,15 +279,14 @@ impl CtrlC { } pub fn was_pressed(&self) -> bool { - self.trap.wait(self.dummy_time).is_some() + false } } impl Default for CtrlC { fn default() -> Self { let dummy_time = Instant::now(); - let trap = Trap::trap(&[Signal::SIGINT, Signal::SIGTERM, Signal::SIGQUIT]); - Self { dummy_time, trap } + Self { dummy_time } } }