summaryrefslogtreecommitdiffhomepage
path: root/mullvad-cli/src/cmds
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2023-09-18 09:40:49 +0200
committerDavid Lönnhager <david.l@mullvad.net>2023-10-09 14:40:05 +0200
commitd767d881e69f7a986272303bda833df5769a9d9b (patch)
tree9ca7523e36c9517652e733d4a9b202d7b5a5c158 /mullvad-cli/src/cmds
parent158d9496a7b1e96a77781646ce4f1a26fda27f92 (diff)
downloadmullvadvpn-d767d881e69f7a986272303bda833df5769a9d9b.tar.xz
mullvadvpn-d767d881e69f7a986272303bda833df5769a9d9b.zip
Add `mullvad api-access enable/disable`
Add `mullvad api-access enable/disable`, which allows for toggling API access methods On/Off. Make `ApiConnectionModeProvider` consider status of access method. `ApiConnectionModeProvider` will only be able to return access methods which are enabled, as it will disregard those which are disabled. Add logic to guarantee the invariant that at least one API access method is available for selection by the `ApiConnectionModeProvider`
Diffstat (limited to 'mullvad-cli/src/cmds')
-rw-r--r--mullvad-cli/src/cmds/proxy.rs79
1 files changed, 72 insertions, 7 deletions
diff --git a/mullvad-cli/src/cmds/proxy.rs b/mullvad-cli/src/cmds/proxy.rs
index 4826a571af..74e0e22c22 100644
--- a/mullvad-cli/src/cmds/proxy.rs
+++ b/mullvad-cli/src/cmds/proxy.rs
@@ -1,7 +1,8 @@
use anyhow::{anyhow, Result};
use mullvad_management_interface::MullvadProxyClient;
use mullvad_types::api_access_method::{
- daemon::ApiAccessMethodReplace, AccessMethod, ObfuscationProtocol,
+ daemon::{ApiAccessMethodReplace, ApiAccessMethodToggle},
+ AccessMethod, ObfuscationProtocol,
};
use std::net::IpAddr;
@@ -19,6 +20,10 @@ pub enum Proxy {
Edit(EditCustomCommands),
/// Remove an API proxy
Remove(RemoveCustomCommands),
+ /// Enable an API proxy
+ Enable(ToggleCustomCommands),
+ /// Disable an API proxy
+ Disable(ToggleCustomCommands),
}
impl Proxy {
@@ -42,6 +47,16 @@ impl Proxy {
let index = Self::zero_to_one_based_index(cmd.index)?;
Self::remove(RemoveCustomCommands { index }).await?
}
+ Proxy::Enable(cmd) => {
+ let index = Self::zero_to_one_based_index(cmd.index)?;
+ let enabled = true;
+ Self::toggle(index, enabled).await?;
+ }
+ Proxy::Disable(cmd) => {
+ let index = Self::zero_to_one_based_index(cmd.index)?;
+ let enabled = false;
+ Self::toggle(index, enabled).await?;
+ }
};
Ok(())
}
@@ -50,7 +65,16 @@ impl Proxy {
async fn list() -> Result<()> {
let mut rpc = MullvadProxyClient::new().await?;
for (index, api_access_method) in rpc.get_api_access_methods().await?.iter().enumerate() {
- println!("{}. {:?}", index + 1, api_access_method);
+ println!(
+ "{}. {:?} {}",
+ index + 1,
+ api_access_method,
+ if api_access_method.enabled() {
+ "[enabled]"
+ } else {
+ "[disabled]"
+ }
+ );
}
Ok(())
}
@@ -80,6 +104,7 @@ impl Proxy {
.map_err(Into::<anyhow::Error>::into)
}
+ /// Edit the data of an API access method.
async fn edit(cmd: EditCustomCommands) -> Result<()> {
let mut rpc = MullvadProxyClient::new().await?;
// Retrieve the access method to edit
@@ -105,21 +130,28 @@ impl Proxy {
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::api_access_method::Shadowsocks::from_args(ip, port, cipher, password)
- .map(|x| x.into())
+ let enabled = shadowsocks.enabled;
+ mullvad_types::api_access_method::Shadowsocks::from_args(
+ ip, port, cipher, password, enabled,
+ )
+ .map(|x| x.into())
}
ObfuscationProtocol::Socks5(socks) => match socks {
mullvad_types::api_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::api_access_method::Socks5Local::from_args(ip, port, local_port)
- .map(|x| x.into())
+ let enabled = local.enabled;
+ mullvad_types::api_access_method::Socks5Local::from_args(
+ ip, port, local_port, enabled,
+ )
+ .map(|x| x.into())
}
mullvad_types::api_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::api_access_method::Socks5Remote::from_args(ip, port)
+ let enabled = remote.enabled;
+ mullvad_types::api_access_method::Socks5Remote::from_args(ip, port, enabled)
.map(|x| x.into())
}
},
@@ -138,6 +170,28 @@ impl Proxy {
Ok(())
}
+ /// Toggle a custom API access method to be enabled or disabled.
+ async fn toggle(index: usize, enabled: bool) -> Result<()> {
+ let mut rpc = MullvadProxyClient::new().await?;
+ // Retrieve the access method to edit
+ let access_method = rpc
+ .get_api_access_methods()
+ .await?
+ .get(index)
+ .ok_or(anyhow!(format!(
+ "Access method {} does not exist",
+ index + 1
+ )))?
+ .clone();
+
+ rpc.toggle_access_method(ApiAccessMethodToggle {
+ access_method,
+ enable: enabled,
+ })
+ .await?;
+ Ok(())
+ }
+
fn zero_to_one_based_index(index: usize) -> Result<usize> {
index
.checked_sub(1)
@@ -168,6 +222,12 @@ pub enum AddCustomCommands {
}
#[derive(Args, Debug, Clone)]
+pub struct ToggleCustomCommands {
+ /// Which access method to enable/disable
+ index: usize,
+}
+
+#[derive(Args, Debug, Clone)]
pub struct EditCustomCommands {
/// Which API proxy to edit
index: usize,
@@ -244,6 +304,8 @@ mod conversions {
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 {
@@ -257,6 +319,7 @@ mod conversions {
remote_ip.to_string(),
remote_port,
local_port,
+ enabled,
)
.ok_or(anyhow!("Could not create a local Socks5 api proxy"))?,
);
@@ -273,6 +336,7 @@ mod conversions {
daemon_types::Socks5Remote::from_args(
remote_ip.to_string(),
remote_port,
+ enabled,
)
.ok_or(anyhow!("Could not create a remote Socks5 api proxy"))?,
);
@@ -293,6 +357,7 @@ mod conversions {
remote_port,
cipher,
password,
+ enabled,
)
.ok_or(anyhow!("Could not create a Shadowsocks api proxy"))?;
shadowsocks_proxy.into()