summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2018-07-10 15:23:08 +0200
committerLinus Färnstrand <linus@mullvad.net>2018-07-10 15:23:08 +0200
commitad7f1a05a28b883c2e73fbf7b3d6053af98b5c04 (patch)
tree9e8624f9a12963aa1b064f2c4916c92d3727c919
parent2a3eef5c14a6d13670ebc503b5b0eda4e2e51df3 (diff)
parent527a26d2c77b62b6bac872bad658e0dac5e26c35 (diff)
downloadmullvadvpn-ad7f1a05a28b883c2e73fbf7b3d6053af98b5c04.tar.xz
mullvadvpn-ad7f1a05a28b883c2e73fbf7b3d6053af98b5c04.zip
Merge branch 'autoconnect-on-daemon-start'
-rw-r--r--CHANGELOG.md2
-rw-r--r--mullvad-cli/src/cmds/auto_connect.rs58
-rw-r--r--mullvad-cli/src/cmds/mod.rs4
-rw-r--r--mullvad-daemon/src/main.rs23
-rw-r--r--mullvad-daemon/src/management_interface.rs40
-rw-r--r--mullvad-daemon/src/settings.rs18
-rw-r--r--mullvad-ipc-client/src/lib.rs16
7 files changed, 147 insertions, 14 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f22c5fc380..1741c30caf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,8 @@ Line wrap the file at 100 chars. Th
- Bundle the root CA signing the API and only trust that single one, limiting
trust to a single root CA
- Add a unique UUID to problem reports. Makes it easier for Mullvad support staff to find reports.
+- Add "auto-connect" setting in daemon, and make it configurable from CLI. Determines if the daemon
+ should secure the network and start establishing a tunnel directly when it starts on boot.
### Changed
- App now uses statically linked OpenSSL on all platforms.
diff --git a/mullvad-cli/src/cmds/auto_connect.rs b/mullvad-cli/src/cmds/auto_connect.rs
new file mode 100644
index 0000000000..57c125c4b6
--- /dev/null
+++ b/mullvad-cli/src/cmds/auto_connect.rs
@@ -0,0 +1,58 @@
+use clap;
+use {Command, Result};
+
+use mullvad_ipc_client::DaemonRpcClient;
+
+pub struct AutoConnect;
+
+impl Command for AutoConnect {
+ fn name(&self) -> &'static str {
+ "auto-connect"
+ }
+
+ fn clap_subcommand(&self) -> clap::App<'static, 'static> {
+ clap::SubCommand::with_name(self.name())
+ .about("Control the daemon auto-connect setting")
+ .setting(clap::AppSettings::SubcommandRequired)
+ .subcommand(
+ clap::SubCommand::with_name("set")
+ .about("Change auto-connect setting")
+ .arg(
+ clap::Arg::with_name("policy")
+ .required(true)
+ .possible_values(&["on", "off"]),
+ ),
+ )
+ .subcommand(
+ clap::SubCommand::with_name("get")
+ .about("Display the current auto-connect setting"),
+ )
+ }
+
+ fn run(&self, matches: &clap::ArgMatches) -> Result<()> {
+ if let Some(set_matches) = matches.subcommand_matches("set") {
+ let auto_connect = value_t_or_exit!(set_matches.value_of("policy"), String);
+ self.set(auto_connect == "on")
+ } else if let Some(_matches) = matches.subcommand_matches("get") {
+ self.get()
+ } else {
+ unreachable!("No auto-connect command given");
+ }
+ }
+}
+
+impl AutoConnect {
+ fn set(&self, auto_connect: bool) -> Result<()> {
+ let mut rpc = DaemonRpcClient::new()?;
+ rpc.set_auto_connect(auto_connect)?;
+ println!("Changed auto-connect sharing setting");
+ Ok(())
+ }
+
+ fn get(&self) -> Result<()> {
+ let mut rpc = DaemonRpcClient::new()?;
+ let auto_connect = rpc.get_auto_connect()?;
+ println!("Autoconnect: {}", if auto_connect { "on" } else { "off" });
+ Ok(())
+ }
+}
diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs
index 4e54aadbca..613a1e69d6 100644
--- a/mullvad-cli/src/cmds/mod.rs
+++ b/mullvad-cli/src/cmds/mod.rs
@@ -4,6 +4,9 @@ use Command;
mod account;
pub use self::account::Account;
+mod auto_connect;
+pub use self::auto_connect::AutoConnect;
+
mod status;
pub use self::status::Status;
@@ -29,6 +32,7 @@ pub use self::version::Version;
pub fn get_commands() -> HashMap<&'static str, Box<Command>> {
let commands: Vec<Box<Command>> = vec![
Box::new(Account),
+ Box::new(AutoConnect),
Box::new(Status),
Box::new(Connect),
Box::new(Disconnect),
diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs
index abfc83b764..61c9f84f02 100644
--- a/mullvad-daemon/src/main.rs
+++ b/mullvad-daemon/src/main.rs
@@ -334,6 +334,10 @@ impl Daemon {
/// Consume the `Daemon` and run the main event loop. Blocks until an error happens or a
/// shutdown event is received.
pub fn run(mut self) -> Result<()> {
+ if self.settings.get_auto_connect() {
+ info!("Automatically connecting since auto-connect is turned on");
+ self.set_target_state(TargetState::Secured)?;
+ }
while let Ok(event) = self.rx.recv() {
self.handle_event(event)?;
if self.shutdown && self.state == TunnelState::NotRunning {
@@ -400,6 +404,8 @@ impl Daemon {
UpdateRelaySettings(tx, update) => self.on_update_relay_settings(tx, update),
SetAllowLan(tx, allow_lan) => self.on_set_allow_lan(tx, allow_lan),
GetAllowLan(tx) => Ok(self.on_get_allow_lan(tx)),
+ SetAutoConnect(tx, auto_connect) => self.on_set_auto_connect(tx, auto_connect),
+ GetAutoConnect(tx) => Ok(self.on_get_auto_connect(tx)),
SetOpenVpnMssfix(tx, mssfix_arg) => self.on_set_openvpn_mssfix(tx, mssfix_arg),
GetTunnelOptions(tx) => self.on_get_tunnel_options(tx),
GetRelaySettings(tx) => Ok(self.on_get_relay_settings(tx)),
@@ -564,6 +570,23 @@ impl Daemon {
Self::oneshot_send(tx, self.settings.get_allow_lan(), "allow lan")
}
+ fn on_set_auto_connect(&mut self, tx: OneshotSender<()>, auto_connect: bool) -> Result<()> {
+ let save_result = self.settings.set_auto_connect(auto_connect);
+ match save_result.chain_err(|| "Unable to save settings") {
+ Ok(_settings_changed) => Self::oneshot_send(tx, (), "set auto-connect response"),
+ Err(e) => error!("{}", e.display_chain()),
+ }
+ Ok(())
+ }
+
+ fn on_get_auto_connect(&self, tx: OneshotSender<bool>) {
+ Self::oneshot_send(
+ tx,
+ self.settings.get_auto_connect(),
+ "get auto-connect response",
+ )
+ }
+
fn on_set_openvpn_mssfix(
&mut self,
tx: OneshotSender<()>,
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 63fcadadd3..230e478afb 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -84,9 +84,13 @@ build_rpc_trait! {
#[rpc(meta, name = "get_allow_lan")]
fn get_allow_lan(&self, Self::Metadata) -> BoxFuture<bool, Error>;
- /// Set if the client should automatically establish a tunnel on start or not.
- #[rpc(meta, name = "set_autoconnect")]
- fn set_autoconnect(&self, Self::Metadata, bool) -> BoxFuture<(), Error>;
+ /// Set if the daemon should automatically establish a tunnel on start or not.
+ #[rpc(meta, name = "set_auto_connect")]
+ fn set_auto_connect(&self, Self::Metadata, bool) -> BoxFuture<(), Error>;
+
+ /// Get if the daemon should automatically establish a tunnel on start or not.
+ #[rpc(meta, name = "get_auto_connect")]
+ fn get_auto_connect(&self, Self::Metadata) -> BoxFuture<bool, Error>;
/// Try to connect if disconnected, or do nothing if already connecting/connected.
#[rpc(meta, name = "connect")]
@@ -181,10 +185,14 @@ pub enum TunnelCommand {
UpdateRelaySettings(OneshotSender<()>, RelaySettingsUpdate),
/// Read the constraints put on the tunnel and relay
GetRelaySettings(OneshotSender<RelaySettings>),
- /// Setting if communication with LAN networks should be possible.
+ /// Set the allow LAN setting.
SetAllowLan(OneshotSender<()>, bool),
- /// Request the current allow LAN setting.
+ /// Get the current allow LAN setting.
GetAllowLan(OneshotSender<bool>),
+ /// Set the auto-connect setting.
+ SetAutoConnect(OneshotSender<()>, bool),
+ /// Get the current auto-connect setting.
+ GetAutoConnect(OneshotSender<bool>),
/// Set the mssfix argument for OpenVPN
SetOpenVpnMssfix(OneshotSender<()>, Option<u16>),
/// Get the mssfix argument for OpenVPN
@@ -504,7 +512,7 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem
}
fn set_allow_lan(&self, meta: Self::Metadata, allow_lan: bool) -> BoxFuture<(), Error> {
- trace!("allow_lan");
+ trace!("set_allow_lan");
try_future!(self.check_auth(&meta));
let (tx, rx) = sync::oneshot::channel();
let future = self
@@ -523,10 +531,24 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem
Box::new(future)
}
- fn set_autoconnect(&self, meta: Self::Metadata, _autoconnect: bool) -> BoxFuture<(), Error> {
- trace!("set_autoconnect");
+ fn set_auto_connect(&self, meta: Self::Metadata, auto_connect: bool) -> BoxFuture<(), Error> {
+ trace!("set_auto_connect");
+ try_future!(self.check_auth(&meta));
+ let (tx, rx) = sync::oneshot::channel();
+ let future = self
+ .send_command_to_daemon(TunnelCommand::SetAutoConnect(tx, auto_connect))
+ .and_then(|_| rx.map_err(|_| Error::internal_error()));
+ Box::new(future)
+ }
+
+ fn get_auto_connect(&self, meta: Self::Metadata) -> BoxFuture<bool, Error> {
+ trace!("get_auto_connect");
try_future!(self.check_auth(&meta));
- Box::new(future::ok(()))
+ let (tx, rx) = sync::oneshot::channel();
+ let future = self
+ .send_command_to_daemon(TunnelCommand::GetAutoConnect(tx))
+ .and_then(|_| rx.map_err(|_| Error::internal_error()));
+ Box::new(future)
}
fn connect(&self, meta: Self::Metadata) -> BoxFuture<(), Error> {
diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs
index 4622db15ce..b11b80017a 100644
--- a/mullvad-daemon/src/settings.rs
+++ b/mullvad-daemon/src/settings.rs
@@ -35,8 +35,10 @@ static SETTINGS_FILE: &str = "settings.json";
pub struct Settings {
account_token: Option<String>,
relay_settings: RelaySettings,
- /// If the app should allow communication with private (LAN) networks.
+ /// If the daemon should allow communication with private (LAN) networks.
allow_lan: bool,
+ /// If the daemon should connect the VPN tunnel directly on start or not.
+ auto_connect: bool,
/// Options that should be applied to tunnels of a specific type regardless of where the relays
/// might be located.
tunnel_options: TunnelOptions,
@@ -51,6 +53,7 @@ impl Default for Settings {
tunnel: Constraint::Any,
}),
allow_lan: false,
+ auto_connect: false,
tunnel_options: TunnelOptions::default(),
}
}
@@ -155,6 +158,19 @@ impl Settings {
}
}
+ pub fn get_auto_connect(&self) -> bool {
+ self.auto_connect
+ }
+
+ pub fn set_auto_connect(&mut self, auto_connect: bool) -> Result<bool> {
+ if auto_connect != self.auto_connect {
+ self.auto_connect = auto_connect;
+ self.save().map(|_| true)
+ } else {
+ Ok(false)
+ }
+ }
+
pub fn set_openvpn_mssfix(&mut self, openvpn_mssfix: Option<u16>) -> Result<bool> {
if self.tunnel_options.openvpn.mssfix != openvpn_mssfix {
self.tunnel_options.openvpn.mssfix = openvpn_mssfix;
diff --git a/mullvad-ipc-client/src/lib.rs b/mullvad-ipc-client/src/lib.rs
index cbf6a9b2e5..51cba68eab 100644
--- a/mullvad-ipc-client/src/lib.rs
+++ b/mullvad-ipc-client/src/lib.rs
@@ -155,10 +155,22 @@ impl DaemonRpcClient {
self.call("get_account_data", &[account])
}
+ pub fn set_allow_lan(&mut self, allow_lan: bool) -> Result<()> {
+ self.call("set_allow_lan", &[allow_lan])
+ }
+
pub fn get_allow_lan(&mut self) -> Result<bool> {
self.call("get_allow_lan", &NO_ARGS)
}
+ pub fn set_auto_connect(&mut self, auto_connect: bool) -> Result<()> {
+ self.call("set_auto_connect", &[auto_connect])
+ }
+
+ pub fn get_auto_connect(&mut self) -> Result<bool> {
+ self.call("get_auto_connect", &NO_ARGS)
+ }
+
pub fn get_current_location(&mut self) -> Result<GeoIpLocation> {
self.call("get_current_location", &NO_ARGS)
}
@@ -191,10 +203,6 @@ impl DaemonRpcClient {
self.call("set_account", &[account])
}
- pub fn set_allow_lan(&mut self, allow_lan: bool) -> Result<()> {
- self.call("set_allow_lan", &[allow_lan])
- }
-
pub fn set_openvpn_mssfix(&mut self, mssfix: Option<u16>) -> Result<()> {
self.call("set_openvpn_mssfix", &[mssfix])
}