summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2018-03-27 15:58:22 +0200
committerLinus Färnstrand <linus@mullvad.net>2018-03-27 15:58:22 +0200
commit5a1d8547668e0d3bbf857822b59d23f8015fc1fe (patch)
tree13002d37f83ffd62dbe471e6dcf402de6162e6f2
parent5d24fd701facb66e94a43ad78fd564df188db9d4 (diff)
parent5061978a720dda7b32054fb0165ba5b784a2eb1a (diff)
downloadmullvadvpn-5a1d8547668e0d3bbf857822b59d23f8015fc1fe.tar.xz
mullvadvpn-5a1d8547668e0d3bbf857822b59d23f8015fc1fe.zip
Merge branch 'feature-version-status'
-rw-r--r--CHANGELOG.md3
-rw-r--r--mullvad-cli/src/cmds/mod.rs3
-rw-r--r--mullvad-cli/src/cmds/version.rs29
-rw-r--r--mullvad-daemon/src/cli.rs7
-rw-r--r--mullvad-daemon/src/main.rs38
-rw-r--r--mullvad-daemon/src/management_interface.rs40
-rw-r--r--mullvad-daemon/src/version.rs9
-rw-r--r--mullvad-rpc/src/lib.rs6
-rw-r--r--mullvad-types/src/lib.rs1
-rw-r--r--mullvad-types/src/version.rs16
10 files changed, 143 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4908520313..3b46c2937d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Warn if daemon is running as a non-root user.
- Include the last two OpenVPN logs in problem reports instead of only the last.
- Prevent two instances of the daemon to run at the same time.
+- Daemon now fetches latest app versions and verifies whether the current
+ version is supported.
+- Add `version` subcommand in the CLI to show information about current versions.
### Fixed
- Fix a bug in account input field that advanced the cursor to the end regardless its prior
diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs
index 4450d9d34f..6de212b7fb 100644
--- a/mullvad-cli/src/cmds/mod.rs
+++ b/mullvad-cli/src/cmds/mod.rs
@@ -25,6 +25,8 @@ pub use self::lan::Lan;
mod tunnel;
pub use self::tunnel::Tunnel;
+mod version;
+pub use self::version::Version;
/// Returns a map of all available subcommands with their name as key.
pub fn get_commands() -> HashMap<&'static str, Box<Command>> {
@@ -37,6 +39,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<Command>> {
Box::new(Relay),
Box::new(Lan),
Box::new(Tunnel),
+ Box::new(Version),
];
let mut map = HashMap::new();
for cmd in commands {
diff --git a/mullvad-cli/src/cmds/version.rs b/mullvad-cli/src/cmds/version.rs
new file mode 100644
index 0000000000..bf754c386a
--- /dev/null
+++ b/mullvad-cli/src/cmds/version.rs
@@ -0,0 +1,29 @@
+use clap;
+use {Command, Result};
+
+use mullvad_types::version;
+use rpc;
+
+pub struct Version;
+
+impl Command for Version {
+ fn name(&self) -> &'static str {
+ "version"
+ }
+
+ fn clap_subcommand(&self) -> clap::App<'static, 'static> {
+ clap::SubCommand::with_name(self.name())
+ .about("Shows current version, and the currently supported versions")
+ }
+
+ fn run(&self, _: &clap::ArgMatches) -> Result<()> {
+ let current_version: String = rpc::call("get_current_version", &[] as &[u8; 0])?;
+ println!("Current version: {}", current_version);
+ let version_info: version::AppVersionInfo = rpc::call("get_version_info", &[] as &[u8; 0])?;
+ println!("Supported: {}", version_info.current_is_supported);
+ println!("Latest releases:");
+ println!("\tlatest stable: {}", version_info.latest.latest_stable);
+ println!("\tlatest: {}", version_info.latest.latest);
+ Ok(())
+ }
+}
diff --git a/mullvad-daemon/src/cli.rs b/mullvad-daemon/src/cli.rs
index 4c0779bf97..8867e42ca2 100644
--- a/mullvad-daemon/src/cli.rs
+++ b/mullvad-daemon/src/cli.rs
@@ -3,6 +3,8 @@ use log;
use std::path::PathBuf;
+use version;
+
pub struct Config {
pub log_level: log::LevelFilter,
pub log_file: Option<PathBuf>,
@@ -36,10 +38,7 @@ pub fn get_config() -> Config {
fn create_app() -> App<'static, 'static> {
App::new(crate_name!())
- .version(include_str!(concat!(
- env!("OUT_DIR"),
- "/git-commit-desc.txt"
- )))
+ .version(version::current())
.author(crate_authors!())
.about(crate_description!())
.arg(
diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs
index c998672897..b1d5b641b9 100644
--- a/mullvad-daemon/src/main.rs
+++ b/mullvad-daemon/src/main.rs
@@ -51,7 +51,7 @@ mod rpc_address_file;
mod rpc_uniqueness_check;
mod settings;
mod shutdown;
-
+mod version;
use app_dirs::AppInfo;
use error_chain::ChainedError;
@@ -59,13 +59,14 @@ use futures::Future;
use jsonrpc_core::futures::sync::oneshot::Sender as OneshotSender;
use management_interface::{BoxFuture, ManagementInterfaceServer, TunnelCommand};
-use mullvad_rpc::{AccountsProxy, HttpHandle};
+use mullvad_rpc::{AccountsProxy, AppVersionProxy, HttpHandle};
use mullvad_types::account::{AccountData, AccountToken};
use mullvad_types::location::GeoIpLocation;
use mullvad_types::relay_constraints::{RelaySettings, RelaySettingsUpdate};
use mullvad_types::relay_list::{Relay, RelayList};
use mullvad_types::states::{DaemonState, SecurityState, TargetState};
+use mullvad_types::version::{AppVersion, AppVersionInfo};
use std::env;
use std::io;
@@ -194,6 +195,7 @@ struct Daemon {
management_interface_broadcaster: management_interface::EventBroadcaster,
settings: settings::Settings,
accounts_proxy: AccountsProxy<HttpHandle>,
+ version_proxy: AppVersionProxy<HttpHandle>,
http_handle: mullvad_rpc::rest::RequestSender,
tokio_remote: tokio_core::reactor::Remote,
relay_selector: relays::RelaySelector,
@@ -247,7 +249,8 @@ impl Daemon {
tx,
management_interface_broadcaster,
settings: settings::Settings::load().chain_err(|| "Unable to read settings")?,
- accounts_proxy: AccountsProxy::new(rpc_handle),
+ accounts_proxy: AccountsProxy::new(rpc_handle.clone()),
+ version_proxy: AppVersionProxy::new(rpc_handle),
http_handle,
tokio_remote,
relay_selector,
@@ -397,6 +400,8 @@ impl Daemon {
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)),
+ GetVersionInfo(tx) => Ok(self.on_get_version_info(tx)),
+ GetCurrentVersion(tx) => Ok(self.on_get_current_version(tx)),
Shutdown => self.handle_trigger_shutdown_event(),
}
}
@@ -480,6 +485,29 @@ impl Daemon {
Ok(())
}
+ fn on_get_version_info(
+ &mut self,
+ tx: OneshotSender<BoxFuture<AppVersionInfo, mullvad_rpc::Error>>,
+ ) {
+ let current_version = version::current().to_owned();
+ let fut = self.version_proxy
+ .latest_app_version()
+ .join(
+ self.version_proxy
+ .is_app_version_supported(&current_version),
+ )
+ .map(|(latest_versions, is_supported)| AppVersionInfo {
+ current_is_supported: is_supported,
+ latest: latest_versions,
+ });
+ Self::oneshot_send(tx, Box::new(fut), "get_version_info response");
+ }
+
+ fn on_get_current_version(&mut self, tx: OneshotSender<AppVersion>) {
+ let current_version = version::current().to_owned();
+ Self::oneshot_send(tx, current_version, "get_current_version response");
+ }
+
fn on_get_account(&self, tx: OneshotSender<Option<String>>) {
Self::oneshot_send(tx, self.settings.get_account_token(), "current account")
}
@@ -843,8 +871,8 @@ fn log_version() {
info!(
"Starting {} - {} {}",
env!("CARGO_PKG_NAME"),
- include_str!(concat!(env!("OUT_DIR"), "/git-commit-desc.txt")),
- include_str!(concat!(env!("OUT_DIR"), "/git-commit-date.txt"))
+ version::current(),
+ version::commit_date(),
)
}
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 6d44528e56..234bfd3d59 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -14,6 +14,7 @@ use mullvad_types::location::GeoIpLocation;
use mullvad_types::relay_constraints::{RelaySettings, RelaySettingsUpdate};
use mullvad_types::relay_list::RelayList;
use mullvad_types::states::{DaemonState, TargetState};
+use mullvad_types::version;
use serde;
@@ -124,6 +125,14 @@ build_rpc_trait! {
#[rpc(meta, name = "get_tunnel_options")]
fn get_tunnel_options(&self, Self::Metadata) -> BoxFuture<TunnelOptions, Error>;
+ /// Retreive version of the app
+ #[rpc(meta, name = "get_current_version")]
+ fn get_current_version(&self, Self::Metadata) -> BoxFuture<String, Error>;
+
+ /// Retrieve information about the currently running and latest versions of the app
+ #[rpc(meta, name = "get_version_info")]
+ fn get_version_info(&self, Self::Metadata) -> BoxFuture<version::AppVersionInfo, Error>;
+
#[pubsub(name = "new_state")] {
/// Subscribes to the `new_state` event notifications.
#[rpc(name = "new_state_subscribe")]
@@ -178,6 +187,10 @@ pub enum TunnelCommand {
SetOpenVpnMssfix(OneshotSender<()>, Option<u16>),
/// Get the mssfix argument for OpenVPN
GetTunnelOptions(OneshotSender<TunnelOptions>),
+ /// Get information about the currently running and latest app versions
+ GetVersionInfo(OneshotSender<BoxFuture<version::AppVersionInfo, mullvad_rpc::Error>>),
+ /// Get current version of the app
+ GetCurrentVersion(OneshotSender<version::AppVersion>),
/// Makes the daemon exit the main loop and quit.
Shutdown,
}
@@ -591,6 +604,33 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem
Box::new(future)
}
+ fn get_current_version(&self, meta: Self::Metadata) -> BoxFuture<String, Error> {
+ try_future!(self.check_auth(&meta));
+ let (tx, rx) = sync::oneshot::channel();
+ let future = self.send_command_to_daemon(TunnelCommand::GetCurrentVersion(tx))
+ .and_then(|_| rx.map_err(|_| Error::internal_error()));
+
+ Box::new(future)
+ }
+
+ fn get_version_info(&self, meta: Self::Metadata) -> BoxFuture<version::AppVersionInfo, Error> {
+ try_future!(self.check_auth(&meta));
+ let (tx, rx) = sync::oneshot::channel();
+ let future = self.send_command_to_daemon(TunnelCommand::GetVersionInfo(tx))
+ .and_then(|_| rx.map_err(|_| Error::internal_error()))
+ .and_then(|version_future| {
+ version_future.map_err(|error| {
+ error!(
+ "Unable to get version data from master: {}",
+ error.display_chain()
+ );
+ Self::map_rpc_error(error)
+ })
+ });
+
+ Box::new(future)
+ }
+
fn new_state_subscribe(
&self,
meta: Self::Metadata,
diff --git a/mullvad-daemon/src/version.rs b/mullvad-daemon/src/version.rs
new file mode 100644
index 0000000000..2252406e5f
--- /dev/null
+++ b/mullvad-daemon/src/version.rs
@@ -0,0 +1,9 @@
+/// Returns a string that identifies the current version of the application
+pub fn current() -> &'static str {
+ include_str!(concat!(env!("OUT_DIR"), "/git-commit-desc.txt"))
+}
+
+/// Current description returns the current build date
+pub fn commit_date() -> &'static str {
+ include_str!(concat!(env!("OUT_DIR"), "/git-commit-date.txt"))
+}
diff --git a/mullvad-rpc/src/lib.rs b/mullvad-rpc/src/lib.rs
index ad20b1a0a3..38327aa148 100644
--- a/mullvad-rpc/src/lib.rs
+++ b/mullvad-rpc/src/lib.rs
@@ -33,6 +33,7 @@ pub use jsonrpc_client_http::{Error as HttpError, HttpHandle};
use mullvad_types::account::AccountToken;
use mullvad_types::relay_list::RelayList;
+use mullvad_types::version;
use std::collections::HashMap;
@@ -77,3 +78,8 @@ impl ProblemReportProxy<HttpHandle> {
jsonrpc_client!(pub struct RelayListProxy {
pub fn relay_list(&mut self) -> RpcRequest<RelayList>;
});
+
+jsonrpc_client!(pub struct AppVersionProxy {
+ pub fn latest_app_version(&mut self) -> RpcRequest<version::LatestReleases>;
+ pub fn is_app_version_supported(&mut self, version: &version::AppVersion) -> RpcRequest<bool>;
+});
diff --git a/mullvad-types/src/lib.rs b/mullvad-types/src/lib.rs
index cd3a3bcb97..6cae36372d 100644
--- a/mullvad-types/src/lib.rs
+++ b/mullvad-types/src/lib.rs
@@ -24,6 +24,7 @@ pub mod location;
pub mod relay_constraints;
pub mod relay_list;
pub mod states;
+pub mod version;
mod custom_tunnel;
pub use custom_tunnel::*;
diff --git a/mullvad-types/src/version.rs b/mullvad-types/src/version.rs
new file mode 100644
index 0000000000..6efa47806e
--- /dev/null
+++ b/mullvad-types/src/version.rs
@@ -0,0 +1,16 @@
+/// AppVersionInfo represents the current stable and the current latest release versions of the
+/// Mullvad VPN app.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct AppVersionInfo {
+ pub current_is_supported: bool,
+ pub latest: LatestReleases,
+}
+
+/// LatestReleases represent the latest released versions of the Mullvad VPN app.
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct LatestReleases {
+ pub latest_stable: AppVersion,
+ pub latest: AppVersion,
+}
+
+pub type AppVersion = String;