diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2018-07-10 15:23:08 +0200 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2018-07-10 15:23:08 +0200 |
| commit | ad7f1a05a28b883c2e73fbf7b3d6053af98b5c04 (patch) | |
| tree | 9e8624f9a12963aa1b064f2c4916c92d3727c919 | |
| parent | 2a3eef5c14a6d13670ebc503b5b0eda4e2e51df3 (diff) | |
| parent | 527a26d2c77b62b6bac872bad658e0dac5e26c35 (diff) | |
| download | mullvadvpn-ad7f1a05a28b883c2e73fbf7b3d6053af98b5c04.tar.xz mullvadvpn-ad7f1a05a28b883c2e73fbf7b3d6053af98b5c04.zip | |
Merge branch 'autoconnect-on-daemon-start'
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/auto_connect.rs | 58 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/mod.rs | 4 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 23 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 40 | ||||
| -rw-r--r-- | mullvad-daemon/src/settings.rs | 18 | ||||
| -rw-r--r-- | mullvad-ipc-client/src/lib.rs | 16 |
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]) } |
