diff options
Diffstat (limited to 'mullvad-cli/src')
| -rw-r--r-- | mullvad-cli/src/cmds/api_access.rs | 237 |
1 files changed, 106 insertions, 131 deletions
diff --git a/mullvad-cli/src/cmds/api_access.rs b/mullvad-cli/src/cmds/api_access.rs index efb1e7bfd8..260f0c4496 100644 --- a/mullvad-cli/src/cmds/api_access.rs +++ b/mullvad-cli/src/cmds/api_access.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Result}; use mullvad_management_interface::MullvadProxyClient; -use mullvad_types::api_access::{AccessMethod, AccessMethodSetting, CustomAccessMethod}; +use mullvad_types::access_method::{AccessMethod, AccessMethodSetting, CustomAccessMethod}; use std::net::IpAddr; use clap::{Args, Subcommand}; @@ -72,8 +72,10 @@ impl ApiAccess { /// Add a custom API access method. async fn add(cmd: AddCustomCommands) -> Result<()> { let mut rpc = MullvadProxyClient::new().await?; - let access_method = AccessMethodSetting::try_from(cmd)?; - rpc.add_access_method(access_method).await?; + let name = cmd.name(); + let enabled = cmd.enabled(); + let access_method = AccessMethod::try_from(cmd)?; + rpc.add_access_method(name, enabled, access_method).await?; Ok(()) } @@ -89,60 +91,46 @@ impl ApiAccess { /// Edit the data of an API access method. async fn edit(cmd: EditCustomCommands) -> Result<()> { let mut rpc = MullvadProxyClient::new().await?; - let api_access_method = Self::get_access_method(&mut rpc, &cmd.item).await?; - let id = api_access_method.get_id(); - let access_method = api_access_method - .as_custom() - .cloned() - .ok_or(anyhow!("Can not edit built-in access method"))?; + let mut api_access_method = Self::get_access_method(&mut rpc, &cmd.item).await?; // Create a new access method combining the new params with the previous values - let edited_access_method: AccessMethodSetting = match access_method { - CustomAccessMethod::Shadowsocks(shadowsocks) => { - let ip = cmd.params.ip.unwrap_or(shadowsocks.peer.ip()).to_string(); - let port = cmd.params.port.unwrap_or(shadowsocks.peer.port()); - let password = cmd.params.password.unwrap_or(shadowsocks.password); - let cipher = cmd.params.cipher.unwrap_or(shadowsocks.cipher); - let name = cmd.params.name.unwrap_or(api_access_method.name); - let enabled = api_access_method.enabled; - mullvad_types::api_access::Shadowsocks::from_args(ip, port, cipher, password).map( - |shadowsocks| { - AccessMethodSetting::new(name, enabled, AccessMethod::from(shadowsocks)) - }, - ) - } - CustomAccessMethod::Socks5(socks) => match socks { - mullvad_types::api_access::Socks5::Local(local) => { - let ip = cmd.params.ip.unwrap_or(local.peer.ip()).to_string(); - let port = cmd.params.port.unwrap_or(local.peer.port()); - let local_port = cmd.params.local_port.unwrap_or(local.port); - let name = cmd.params.name.unwrap_or(api_access_method.get_name()); - let enabled = api_access_method.enabled(); - mullvad_types::api_access::Socks5Local::from_args(ip, port, local_port).map( - |socks| AccessMethodSetting::new(name, enabled, AccessMethod::from(socks)), - ) - } - mullvad_types::api_access::Socks5::Remote(remote) => { - let ip = cmd.params.ip.unwrap_or(remote.peer.ip()).to_string(); - let port = cmd.params.port.unwrap_or(remote.peer.port()); - let name = cmd.params.name.unwrap_or(api_access_method.get_name()); - let enabled = api_access_method.enabled(); - mullvad_types::api_access::Socks5Remote::from_args(ip, port).map(|socks| { - AccessMethodSetting::new(name, enabled, AccessMethod::from(socks)) - }) + let access_method = match api_access_method.as_custom() { + None => return Err(anyhow!("Can not edit built-in access method")), + Some(x) => match x.clone() { + CustomAccessMethod::Shadowsocks(shadowsocks) => { + let ip = cmd.params.ip.unwrap_or(shadowsocks.peer.ip()).to_string(); + let port = cmd.params.port.unwrap_or(shadowsocks.peer.port()); + let password = cmd.params.password.unwrap_or(shadowsocks.password); + let cipher = cmd.params.cipher.unwrap_or(shadowsocks.cipher); + mullvad_types::access_method::Shadowsocks::from_args(ip, port, cipher, password) + .map(AccessMethod::from) } + CustomAccessMethod::Socks5(socks) => match socks { + mullvad_types::access_method::Socks5::Local(local) => { + let ip = cmd.params.ip.unwrap_or(local.peer.ip()).to_string(); + let port = cmd.params.port.unwrap_or(local.peer.port()); + let local_port = cmd.params.local_port.unwrap_or(local.port); + mullvad_types::access_method::Socks5Local::from_args(ip, port, local_port) + .map(AccessMethod::from) + } + mullvad_types::access_method::Socks5::Remote(remote) => { + let ip = cmd.params.ip.unwrap_or(remote.peer.ip()).to_string(); + let port = cmd.params.port.unwrap_or(remote.peer.port()); + mullvad_types::access_method::Socks5Remote::from_args(ip, port) + .map(AccessMethod::from) + } + }, }, + }; + + if let Some(name) = cmd.params.name { + api_access_method.name = name; + }; + if let Some(access_method) = access_method { + api_access_method.access_method = access_method; } - .ok_or(anyhow!( - "Could not edit access method {}, reverting changes.", - cmd.item - ))?; - rpc.update_access_method(ApiAccessMethodUpdate { - id, - access_method: edited_access_method, - }) - .await?; + rpc.update_access_method(api_access_method).await?; Ok(()) } @@ -169,7 +157,7 @@ impl ApiAccess { let access_method = Self::get_access_method(&mut rpc, &item).await?; rpc.set_access_method(access_method.get_id()).await?; // Make the daemon perform an network request which involves talking to the Mullvad API. - match rpc.get_api_addressess().await { + match rpc.get_api_addresses().await { Ok(_) => println!("Connected to the Mullvad API!"), Err(_) => println!( "Could *not* connect to the Mullvad API using access method \"{}\"", @@ -204,32 +192,8 @@ impl ApiAccess { #[derive(Subcommand, Debug, Clone)] pub enum AddCustomCommands { - /// Configure SOCKS5 proxy - #[clap(subcommand)] - Socks5(Socks5AddCommands), - - /// Configure Shadowsocks proxy - Shadowsocks { - /// An easy to remember name for this custom proxy - name: String, - /// The IP of the remote Shadowsocks server - remote_ip: IpAddr, - /// The port of the remote Shadowsocks server - #[arg(default_value = "443")] - remote_port: u16, - /// Password for authentication - #[arg(default_value = "mullvad")] - password: String, - /// Cipher to use - #[arg(value_parser = SHADOWSOCKS_CIPHERS, default_value = "aes-256-gcm")] - cipher: String, - }, -} - -#[derive(Subcommand, Debug, Clone)] -pub enum Socks5AddCommands { /// Configure a local SOCKS5 proxy - Local { + Socks5Local { /// An easy to remember name for this custom proxy name: String, /// The port that the server on localhost is listening on @@ -240,7 +204,7 @@ pub enum Socks5AddCommands { remote_port: u16, }, /// Configure a remote SOCKS5 proxy - Remote { + Socks5Remote { /// An easy to remember name for this custom proxy name: String, /// The IP of the remote proxy server @@ -248,6 +212,37 @@ pub enum Socks5AddCommands { /// The port of the remote proxy server remote_port: u16, }, + /// Configure Shadowsocks proxy + Shadowsocks { + /// An easy to remember name for this custom proxy + name: String, + /// The IP of the remote Shadowsocks server + remote_ip: IpAddr, + /// The port of the remote Shadowsocks server + #[arg(default_value = "443")] + remote_port: u16, + /// Password for authentication + #[arg(default_value = "mullvad")] + password: String, + /// Cipher to use + #[arg(value_parser = SHADOWSOCKS_CIPHERS, default_value = "aes-256-gcm")] + cipher: String, + }, +} + +impl AddCustomCommands { + fn name(&self) -> String { + match self { + AddCustomCommands::Socks5Local { name, .. } => name, + AddCustomCommands::Socks5Remote { name, .. } => name, + AddCustomCommands::Shadowsocks { name, .. } => name, + } + .clone() + } + /// TODO: Actually add an `enabled` flag to the variants of `AddCustomCommands` + fn enabled(&self) -> bool { + true + } } /// A minimal wrapper type allowing the user to supply a list index to some @@ -311,65 +306,50 @@ pub struct EditParams { /// we define them in a hidden-away module. mod conversions { use anyhow::{anyhow, Error}; - use mullvad_types::api_access as daemon_types; + use mullvad_types::access_method as daemon_types; - use super::{AddCustomCommands, Socks5AddCommands}; + use super::AddCustomCommands; - impl TryFrom<AddCustomCommands> for daemon_types::AccessMethodSetting { + impl TryFrom<AddCustomCommands> for daemon_types::AccessMethod { type Error = Error; fn try_from(value: AddCustomCommands) -> Result<Self, Self::Error> { - // All api proxies are automatically enabled from the start. - let enabled = true; Ok(match value { - AddCustomCommands::Socks5(variant) => match variant { - Socks5AddCommands::Local { - local_port, - remote_ip, - remote_port, - name, - } => { - println!("Adding Local SOCKS5-proxy: localhost:{local_port} => {remote_ip}:{remote_port}"); - let socks_proxy = daemon_types::Socks5::Local( - daemon_types::Socks5Local::from_args( - remote_ip.to_string(), - remote_port, - local_port, - ) - .ok_or(anyhow!("Could not create a local Socks5 api proxy"))?, - ); - daemon_types::AccessMethodSetting::new( - name, - enabled, - daemon_types::AccessMethod::from(socks_proxy), + AddCustomCommands::Socks5Local { + local_port, + remote_ip, + remote_port, + name: _, + } => { + println!("Adding Local SOCKS5-proxy: localhost:{local_port} => {remote_ip}:{remote_port}"); + let socks_proxy = daemon_types::Socks5::Local( + daemon_types::Socks5Local::from_args( + remote_ip.to_string(), + remote_port, + local_port, ) - } - Socks5AddCommands::Remote { - remote_ip, - remote_port, - name, - } => { - println!("Adding SOCKS5-proxy: {remote_ip}:{remote_port}"); - let socks_proxy = daemon_types::Socks5::Remote( - daemon_types::Socks5Remote::from_args( - remote_ip.to_string(), - remote_port, - ) + .ok_or(anyhow!("Could not create a local Socks5 api proxy"))?, + ); + daemon_types::AccessMethod::from(socks_proxy) + } + AddCustomCommands::Socks5Remote { + remote_ip, + remote_port, + name: _, + } => { + println!("Adding SOCKS5-proxy: {remote_ip}:{remote_port}"); + let socks_proxy = daemon_types::Socks5::Remote( + daemon_types::Socks5Remote::from_args(remote_ip.to_string(), remote_port) .ok_or(anyhow!("Could not create a remote Socks5 api proxy"))?, - ); - daemon_types::AccessMethodSetting::new( - name, - enabled, - daemon_types::AccessMethod::from(socks_proxy), - ) - } - }, + ); + daemon_types::AccessMethod::from(socks_proxy) + } AddCustomCommands::Shadowsocks { remote_ip, remote_port, password, cipher, - name, + name: _, } => { println!( "Adding Shadowsocks-proxy: {password} @ {remote_ip}:{remote_port} using {cipher}" @@ -381,12 +361,7 @@ mod conversions { password, ) .ok_or(anyhow!("Could not create a Shadowsocks api proxy"))?; - - daemon_types::AccessMethodSetting::new( - name, - enabled, - daemon_types::AccessMethod::from(shadowsocks_proxy), - ) + daemon_types::AccessMethod::from(shadowsocks_proxy) } }) } @@ -395,7 +370,7 @@ mod conversions { /// Pretty printing of [`ApiAccessMethod`]s mod pp { - use mullvad_types::api_access::{ + use mullvad_types::access_method::{ AccessMethod, AccessMethodSetting, CustomAccessMethod, Socks5, }; |
