diff options
| author | David Lönnhager <david.l@mullvad.net> | 2020-05-29 09:45:17 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-07-02 09:54:19 +0200 |
| commit | e5baa0e08816d535a031b3d8575701b8d43fb0c2 (patch) | |
| tree | c4bf2ec1956977676bc25c2630bd38789f43dade /mullvad-cli/src | |
| parent | 207ab239223686ff72c43a8a5d615565ab81b5ab (diff) | |
| download | mullvadvpn-e5baa0e08816d535a031b3d8575701b8d43fb0c2.tar.xz mullvadvpn-e5baa0e08816d535a031b3d8575701b8d43fb0c2.zip | |
Support Windows split tunneling driver
Diffstat (limited to 'mullvad-cli/src')
| -rw-r--r-- | mullvad-cli/src/cmds/mod.rs | 6 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/split_tunnel/mod.rs | 6 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/split_tunnel/windows.rs | 112 |
3 files changed, 120 insertions, 4 deletions
diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs index bd7ca97372..2ceb3bfdcf 100644 --- a/mullvad-cli/src/cmds/mod.rs +++ b/mullvad-cli/src/cmds/mod.rs @@ -37,9 +37,9 @@ pub use self::relay::Relay; mod reset; pub use self::reset::Reset; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", windows))] mod split_tunnel; -#[cfg(target_os = "linux")] +#[cfg(any(target_os = "linux", windows))] pub use self::split_tunnel::SplitTunnel; mod status; @@ -66,7 +66,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> { Box::new(Lan), Box::new(Relay), Box::new(Reset), - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", windows))] Box::new(SplitTunnel), Box::new(Status), Box::new(Tunnel), diff --git a/mullvad-cli/src/cmds/split_tunnel/mod.rs b/mullvad-cli/src/cmds/split_tunnel/mod.rs index c7c366d6ea..c9e87f5d7c 100644 --- a/mullvad-cli/src/cmds/split_tunnel/mod.rs +++ b/mullvad-cli/src/cmds/split_tunnel/mod.rs @@ -2,5 +2,9 @@ #[path = "linux.rs"] mod imp; -#[cfg(target_os = "linux")] +#[cfg(windows)] +#[path = "windows.rs"] +mod imp; + +#[cfg(any(target_os = "linux", windows))] pub use imp::*; diff --git a/mullvad-cli/src/cmds/split_tunnel/windows.rs b/mullvad-cli/src/cmds/split_tunnel/windows.rs new file mode 100644 index 0000000000..5f6fa8878e --- /dev/null +++ b/mullvad-cli/src/cmds/split_tunnel/windows.rs @@ -0,0 +1,112 @@ +use crate::{new_rpc_client, Command, Result}; +use clap::value_t_or_exit; + +pub struct SplitTunnel; + +#[mullvad_management_interface::async_trait] +impl Command for SplitTunnel { + fn name(&self) -> &'static str { + "split-tunnel" + } + + fn clap_subcommand(&self) -> clap::App<'static, 'static> { + clap::SubCommand::with_name(self.name()) + .about("Set options for applications to exclude from the tunnel") + .setting(clap::AppSettings::SubcommandRequiredElseHelp) + .subcommand(create_app_subcommand()) + .subcommand( + clap::SubCommand::with_name("set") + .about("Enable or disable split tunnel") + .arg( + clap::Arg::with_name("policy") + .required(true) + .possible_values(&["on", "off"]), + ), + ) + .subcommand(clap::SubCommand::with_name("get").about("Display the split tunnel status")) + } + + async fn run(&self, matches: &clap::ArgMatches<'_>) -> Result<()> { + match matches.subcommand() { + ("app", Some(matches)) => Self::handle_app_subcommand(matches).await, + ("get", _) => self.get().await, + ("set", Some(matches)) => { + let enabled = value_t_or_exit!(matches.value_of("policy"), String); + self.set(enabled == "on").await + } + _ => { + unreachable!("unhandled command"); + } + } + } +} + +fn create_app_subcommand() -> clap::App<'static, 'static> { + clap::SubCommand::with_name("app") + .about("Manage applications to exclude from the tunnel") + .setting(clap::AppSettings::SubcommandRequiredElseHelp) + .subcommand(clap::SubCommand::with_name("list")) + .subcommand( + clap::SubCommand::with_name("add").arg(clap::Arg::with_name("path").required(true)), + ) + .subcommand( + clap::SubCommand::with_name("remove").arg(clap::Arg::with_name("path").required(true)), + ) + .subcommand(clap::SubCommand::with_name("clear")) +} + +impl SplitTunnel { + async fn handle_app_subcommand(matches: &clap::ArgMatches<'_>) -> Result<()> { + match matches.subcommand() { + ("list", Some(_)) => { + let mut paths = new_rpc_client() + .await? + .get_split_tunnel_apps(()) + .await? + .into_inner(); + + println!("Excluded applications:"); + while let Some(path) = paths.message().await? { + println!(" {}", path); + } + + Ok(()) + } + ("add", Some(matches)) => { + let path = value_t_or_exit!(matches.value_of("path"), String); + new_rpc_client().await?.add_split_tunnel_app(path).await?; + Ok(()) + } + ("remove", Some(matches)) => { + let path = value_t_or_exit!(matches.value_of("path"), String); + new_rpc_client() + .await? + .remove_split_tunnel_app(path) + .await?; + Ok(()) + } + ("clear", Some(_)) => { + new_rpc_client().await?.clear_split_tunnel_apps(()).await?; + Ok(()) + } + _ => unreachable!("unhandled subcommand"), + } + } + + async fn set(&self, enabled: bool) -> Result<()> { + let mut rpc = new_rpc_client().await?; + rpc.set_split_tunnel_state(enabled).await?; + println!("Changed split tunnel setting"); + Ok(()) + } + + async fn get(&self) -> Result<()> { + let mut rpc = new_rpc_client().await?; + let enabled = rpc.get_settings(()).await?.into_inner().split_tunnel; + println!( + "Split tunnel status: {}", + if enabled { "on" } else { "off" } + ); + Ok(()) + } +} |
