diff options
| author | Emīls <emils@mullvad.net> | 2021-09-07 16:33:53 +0100 |
|---|---|---|
| committer | Odd Stranne <odd@mullvad.net> | 2022-03-24 10:36:16 +0100 |
| commit | 35d511e205c32312ca8a7a0a9271445bb29df35b (patch) | |
| tree | 9ab798da1c37597ce542231507b522c807dddd16 /mullvad-cli | |
| parent | e7b6106bb86513d99d164a5184ad68f56e44dd32 (diff) | |
| download | mullvadvpn-35d511e205c32312ca8a7a0a9271445bb29df35b.tar.xz mullvadvpn-35d511e205c32312ca8a7a0a9271445bb29df35b.zip | |
Add CLI commands for configuring obfuscation
Diffstat (limited to 'mullvad-cli')
| -rw-r--r-- | mullvad-cli/src/cmds/mod.rs | 4 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/obfuscation.rs | 134 | ||||
| -rw-r--r-- | mullvad-cli/src/format.rs | 21 |
3 files changed, 158 insertions, 1 deletions
diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs index 2ceb3bfdcf..4c374d64ee 100644 --- a/mullvad-cli/src/cmds/mod.rs +++ b/mullvad-cli/src/cmds/mod.rs @@ -28,6 +28,9 @@ pub use self::dns::Dns; mod lan; pub use self::lan::Lan; +mod obfuscation; +pub use self::obfuscation::Obfuscation; + mod reconnect; pub use self::reconnect::Reconnect; @@ -64,6 +67,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> { Box::new(Dns), Box::new(Reconnect), Box::new(Lan), + Box::new(Obfuscation), Box::new(Relay), Box::new(Reset), #[cfg(any(target_os = "linux", windows))] diff --git a/mullvad-cli/src/cmds/obfuscation.rs b/mullvad-cli/src/cmds/obfuscation.rs new file mode 100644 index 0000000000..99887db555 --- /dev/null +++ b/mullvad-cli/src/cmds/obfuscation.rs @@ -0,0 +1,134 @@ +use crate::{new_rpc_client, Command, Result}; + +use mullvad_management_interface::{types as grpc_types, ManagementServiceClient}; + +use mullvad_types::relay_constraints::{ObfuscationSettings, SelectedObfuscation}; + +use std::convert::TryFrom; + +pub struct Obfuscation; + +#[mullvad_management_interface::async_trait] +impl Command for Obfuscation { + fn name(&self) -> &'static str { + "obfuscation" + } + + fn clap_subcommand(&self) -> clap::App<'static> { + clap::App::new(self.name()) + .about("Manage use of obfuscators") + .setting(clap::AppSettings::SubcommandRequiredElseHelp) + .subcommand(create_obfuscation_set_subcommand()) + .subcommand(create_obfuscation_get_subcommand()) + } + + async fn run(&self, matches: &clap::ArgMatches) -> Result<()> { + match matches.subcommand() { + Some(("set", set_matches)) => Self::handle_set(set_matches).await, + Some(("get", get_matches)) => Self::handle_get(get_matches).await, + _ => unreachable!("unhandled command"), + } + } +} + +impl Obfuscation { + async fn handle_set(matches: &clap::ArgMatches) -> Result<()> { + match matches.subcommand() { + Some(("mode", mode_matches)) => { + let obfuscator_type = mode_matches.value_of("mode").unwrap(); + let mut rpc = new_rpc_client().await?; + let mut settings = Self::get_obfuscation_settings(&mut rpc).await?; + settings.selected_obfuscation = match obfuscator_type { + "auto" => SelectedObfuscation::Auto, + "off" => SelectedObfuscation::Off, + "udp2tcp" => SelectedObfuscation::Udp2Tcp, + _ => unreachable!("Unhandled obfuscator mode"), + }; + Self::set_obfuscation_settings(&mut rpc, &settings).await?; + } + Some(("udp2tcp-settings", settings_matches)) => { + let port: String = settings_matches.value_of_t_or_exit("port"); + let mut rpc = new_rpc_client().await?; + let mut settings = Self::get_obfuscation_settings(&mut rpc).await?; + settings.udp2tcp.port = if port == "any" { + mullvad_types::relay_constraints::Constraint::Any + } else { + mullvad_types::relay_constraints::Constraint::Only( + port.parse::<u16>().expect("Invalid port number"), + ) + }; + Self::set_obfuscation_settings(&mut rpc, &settings).await?; + } + _ => unreachable!("unhandled command"), + } + Ok(()) + } + + async fn handle_get(matches: &clap::ArgMatches) -> Result<()> { + let mut rpc = new_rpc_client().await?; + let settings = Self::get_obfuscation_settings(&mut rpc).await?; + match matches.subcommand() { + Some(("udp2tcp-settings", _)) => println!("Udp2Tcp: {}", settings.udp2tcp), + _ => println!("Current settings: {}", settings), + } + Ok(()) + } + + async fn get_obfuscation_settings( + rpc: &mut ManagementServiceClient, + ) -> Result<ObfuscationSettings> { + let settings = rpc.get_settings(()).await?.into_inner(); + + let obfuscation_settings = ObfuscationSettings::try_from( + settings + .obfuscation_settings + .expect("No obfuscation settings"), + ) + .expect("failed to parse obfuscation settings"); + Ok(obfuscation_settings) + } + + async fn set_obfuscation_settings( + rpc: &mut ManagementServiceClient, + settings: &ObfuscationSettings, + ) -> Result<()> { + let grpc_settings: grpc_types::ObfuscationSettings = settings.into(); + let _ = rpc.set_obfuscation_settings(grpc_settings).await?; + Ok(()) + } +} + +fn create_obfuscation_set_subcommand() -> clap::App<'static> { + clap::App::new("set") + .about("Set obfuscation settings") + .setting(clap::AppSettings::SubcommandRequiredElseHelp) + .subcommand( + clap::App::new("mode").about("Set obfuscation mode").arg( + clap::Arg::new("mode") + .help("Specifies what kind of obfuscation should be used, if any") + .required(true) + .index(1) + .possible_values(&["auto", "off", "udp2tcp"]), + ), + ) + .subcommand( + clap::App::new("udp2tcp-settings") + .about("Specifies the config for the udp2tcp obfuscator") + .setting(clap::AppSettings::ArgRequiredElseHelp) + .arg( + clap::Arg::new("port") + .help("TCP port of remote endpoint. Either 'any' or a specific port") + .long("port") + .takes_value(true), + ), + ) +} + +fn create_obfuscation_get_subcommand() -> clap::App<'static> { + clap::App::new("get") + .about("Get obfuscation settings") + .subcommand( + clap::App::new("udp2tcp-settings") + .about("Specifies the config for the udp2tcp obfuscator"), + ) +} diff --git a/mullvad-cli/src/format.rs b/mullvad-cli/src/format.rs index eb91ffcca8..76ffcf7fb1 100644 --- a/mullvad-cli/src/format.rs +++ b/mullvad-cli/src/format.rs @@ -5,7 +5,8 @@ use mullvad_management_interface::types::{ }, tunnel_state, tunnel_state::State::*, - ErrorState, ProxyType, TransportProtocol, TunnelEndpoint, TunnelState, TunnelType, + ErrorState, ObfuscationType, ProxyType, TransportProtocol, TunnelEndpoint, TunnelState, + TunnelType, }; use mullvad_types::auth_failed::AuthFailed; use std::fmt::Write; @@ -83,6 +84,24 @@ fn format_endpoint(endpoint: &TunnelEndpoint) -> String { ) .unwrap(); } + if let Some(ref obfuscation) = endpoint.obfuscation { + write!( + &mut out, + " via {} {}:{} over {}", + match ObfuscationType::from_i32(obfuscation.obfuscation_type) + .expect("invalid obfuscation type") + { + ObfuscationType::Udp2tcp => "Udp2Tcp", + }, + obfuscation.address, + obfuscation.port, + format_protocol( + TransportProtocol::from_i32(obfuscation.protocol) + .expect("invalid transport protocol") + ) + ) + .unwrap(); + } } } |
