diff options
| author | Emīls Piņķis <emils@mullvad.net> | 2018-08-28 16:44:09 +0100 |
|---|---|---|
| committer | Emīls Piņķis <emils@mullvad.net> | 2018-08-29 16:28:17 +0100 |
| commit | c3104f8a5ec79827c56e71732e867d836428357b (patch) | |
| tree | 923fa2ec1c866fa4667962ddc476bfd516765517 | |
| parent | a933aee2472cdeb7b1e3d382879a0a36c2d9121a (diff) | |
| download | mullvadvpn-c3104f8a5ec79827c56e71732e867d836428357b.tar.xz mullvadvpn-c3104f8a5ec79827c56e71732e867d836428357b.zip | |
Use IPC transport for management interface in daemon
| -rw-r--r-- | mullvad-daemon/Cargo.toml | 1 | ||||
| -rw-r--r-- | mullvad-daemon/src/main.rs | 31 | ||||
| -rw-r--r-- | mullvad-daemon/src/management_interface.rs | 147 | ||||
| -rw-r--r-- | mullvad-daemon/src/relays.rs | 9 | ||||
| -rw-r--r-- | mullvad-daemon/src/rpc_address_file.rs | 88 | ||||
| -rw-r--r-- | mullvad-daemon/src/rpc_uniqueness_check.rs | 3 |
6 files changed, 40 insertions, 239 deletions
diff --git a/mullvad-daemon/Cargo.toml b/mullvad-daemon/Cargo.toml index 9f491e2dd4..b6cd7a9884 100644 --- a/mullvad-daemon/Cargo.toml +++ b/mullvad-daemon/Cargo.toml @@ -18,7 +18,6 @@ log-panics = "2.0.0" jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc", branch = "master" } jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc", branch = "master" } jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc", branch = "master" } -jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc", branch = "master" } jsonrpc-ipc-server = { git = "https://github.com/paritytech/jsonrpc", branch = "master" } uuid = { version = "0.6", features = ["v4"] } lazy_static = "1.0" diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index a859baec4c..373aca1715 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -27,7 +27,6 @@ extern crate jsonrpc_core; extern crate jsonrpc_macros; extern crate jsonrpc_ipc_server; extern crate jsonrpc_pubsub; -extern crate jsonrpc_ws_server; extern crate rand; extern crate tokio_core; extern crate tokio_timer; @@ -51,7 +50,6 @@ mod geoip; mod logging; mod management_interface; mod relays; -mod rpc_address_file; mod rpc_uniqueness_check; mod settings; mod shutdown; @@ -126,7 +124,6 @@ pub enum DaemonEvent { TunnelStateTransition(TunnelStateTransition), /// An event coming from the JSONRPC-2.0 management interface. ManagementInterfaceEvent(ManagementCommand), - // TODO(emilsp): try and get an error from the management interface /// Triggered if the server hosting the JSONRPC-2.0 management interface dies unexpectedly. ManagementInterfaceExited, /// Daemon shutdown triggered by a signal, ctrl-c or similar. @@ -288,18 +285,13 @@ impl Daemon { event_tx: IntoSender<ManagementCommand, DaemonEvent>, cache_dir: PathBuf, ) -> Result<ManagementInterfaceServer> { - let shared_secret = uuid::Uuid::new_v4().to_string(); - - let server = ManagementInterfaceServer::start(event_tx, shared_secret.clone(), cache_dir) + let server = ManagementInterfaceServer::start(event_tx, cache_dir) .chain_err(|| ErrorKind::ManagementInterfaceError("Failed to start server"))?; info!( "Mullvad management interface listening on {}", - server.address() + server.socket_path() ); - rpc_address_file::write(server.address(), &shared_secret).chain_err(|| { - ErrorKind::ManagementInterfaceError("Failed to write RPC connection info to file") - })?; Ok(server) } @@ -308,7 +300,7 @@ impl Daemon { exit_tx: mpsc::Sender<DaemonEvent>, ) { thread::spawn(move || { - let result = server.wait(); + server.wait(); error!("Mullvad management interface shut down"); let _ = exit_tx.send(DaemonEvent::ManagementInterfaceExited); }); @@ -601,15 +593,6 @@ impl Daemon { } } - // TODO: (emilsp) fix this - // fn handle_management_interface_exited(&self, result: talpid_ipc_ws::Result<()>) -> - // Result<()> { let error = ErrorKind::ManagementInterfaceError("Server exited - // unexpectedly"); match result { - // Ok(()) => Err(error.into()), - // Err(e) => Err(e).chain_err(|| error), - // } - // } - fn handle_management_interface_exited(&self) -> Result<()> { Err(ErrorKind::ManagementInterfaceError("Server exited unexpectedly").into()) } @@ -728,10 +711,12 @@ impl DaemonShutdownHandle { impl Drop for Daemon { fn drop(self: &mut Daemon) { - if let Err(e) = - rpc_address_file::remove().chain_err(|| "Unable to clean up rpc address file") + #[cfg(unix)] { - error!("{}", e.display_chain()); + use std::fs; + if let Err(e) = fs::remove_file(mullvad_paths::get_rpc_socket_path()) { + error!("Failed to remove RPC socket: {}", e); + } } } } diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index bb2e540cc1..4d7a509018 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -22,7 +22,6 @@ use serde; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::path::PathBuf; -use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Mutex, RwLock}; use talpid_core::mpsc::IntoSender; @@ -41,10 +40,6 @@ build_rpc_trait! { pub trait ManagementInterfaceApi { type Metadata; - /// Authenticate the client towards this daemon instance. This method must be called once - /// before any other call based on the same connection will work. - #[rpc(meta, name = "auth")] - fn auth(&self, Self::Metadata, String) -> BoxFuture<(), Error>; /// Fetches and returns metadata about an account. Returns an error on non-existing /// accounts. @@ -226,13 +221,12 @@ pub struct ManagementInterfaceServer { impl ManagementInterfaceServer { pub fn start<T>( tunnel_tx: IntoSender<ManagementCommand, T>, - shared_secret: String, cache_dir: PathBuf, ) -> talpid_ipc::Result<Self> where T: From<ManagementCommand> + 'static + Send, { - let rpc = ManagementInterface::new(tunnel_tx, shared_secret, cache_dir); + let rpc = ManagementInterface::new(tunnel_tx, cache_dir); let subscriptions = rpc.subscriptions.clone(); let mut io = PubSubHandler::default(); @@ -250,7 +244,7 @@ impl ManagementInterfaceServer { }) } - pub fn address(&self) -> &str { + pub fn socket_path(&self) -> &str { self.server.path() } @@ -267,15 +261,6 @@ impl ManagementInterfaceServer { } } -fn ipc_path() -> String { - if cfg!(windows) { - "//./pipe/mullvad_daemon_socket".to_owned() - } else { - "/tmp/mullvad_daemon_socket".to_owned() - } -} - - /// A handle that allows broadcasting messages to all subscribers of the management interface. pub struct EventBroadcaster { subscriptions: Arc<ActiveSubscriptions>, @@ -314,20 +299,14 @@ impl EventBroadcaster { struct ManagementInterface<T: From<ManagementCommand> + 'static + Send> { subscriptions: Arc<ActiveSubscriptions>, tx: Mutex<IntoSender<ManagementCommand, T>>, - shared_secret: String, cache_dir: PathBuf, } impl<T: From<ManagementCommand> + 'static + Send> ManagementInterface<T> { - pub fn new( - tx: IntoSender<ManagementCommand, T>, - shared_secret: String, - cache_dir: PathBuf, - ) -> Self { + pub fn new(tx: IntoSender<ManagementCommand, T>, cache_dir: PathBuf) -> Self { ManagementInterface { subscriptions: Default::default(), tx: Mutex::new(tx), - shared_secret, cache_dir, } } @@ -393,17 +372,6 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterface<T> { } } - fn check_auth(&self, meta: &Meta) -> Result<(), Error> { - Ok(()) - // if meta.authenticated.load(Ordering::SeqCst) { - // trace!("auth success"); - // Ok(()) - // } else { - // trace!("auth failed"); - // Err(Error::invalid_request()) - // } - } - fn load_history(&self) -> Result<AccountHistory, AccountHistoryError> { let mut account_history = AccountHistory::new(&self.cache_dir); account_history.load()?; @@ -411,41 +379,17 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterface<T> { } } -/// Evaluates a Result and early returns an error. -/// If it is `Ok(val)`, evaluates to `val`. -/// If it is `Err(e)` it early returns `Box<Future>` where the future will result in `e`. -macro_rules! try_future { - ($result:expr) => { - match $result { - ::std::result::Result::Ok(val) => val, - ::std::result::Result::Err(e) => return Box::new(future::err(e)), - } - }; -} - impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi for ManagementInterface<T> { type Metadata = Meta; - fn auth(&self, meta: Self::Metadata, shared_secret: String) -> BoxFuture<(), Error> { - let authenticated = shared_secret == self.shared_secret; - meta.authenticated.store(authenticated, Ordering::SeqCst); - debug!("authenticated: {}", authenticated); - if authenticated { - Box::new(future::ok(())) - } else { - Box::new(future::err(Error::internal_error())) - } - } - fn get_account_data( &self, - meta: Self::Metadata, + _: Self::Metadata, account_token: AccountToken, ) -> BoxFuture<AccountData, Error> { trace!("get_account_data"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetAccountData(tx, account_token)) @@ -462,9 +406,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_relay_locations(&self, meta: Self::Metadata) -> BoxFuture<RelayList, Error> { + fn get_relay_locations(&self, _: Self::Metadata) -> BoxFuture<RelayList, Error> { trace!("get_relay_locations"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetRelayLocations(tx)) @@ -474,11 +417,10 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi fn set_account( &self, - meta: Self::Metadata, + _: Self::Metadata, account_token: Option<AccountToken>, ) -> BoxFuture<(), Error> { trace!("set_account"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::SetAccount(tx, account_token.clone())) @@ -498,9 +440,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_account(&self, meta: Self::Metadata) -> BoxFuture<Option<AccountToken>, Error> { + fn get_account(&self, _: Self::Metadata) -> BoxFuture<Option<AccountToken>, Error> { trace!("get_account"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetAccount(tx)) @@ -510,11 +451,10 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi fn update_relay_settings( &self, - meta: Self::Metadata, + _: Self::Metadata, constraints_update: RelaySettingsUpdate, ) -> BoxFuture<(), Error> { trace!("update_relay_settings"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let message = ManagementCommand::UpdateRelaySettings(tx, constraints_update); @@ -524,9 +464,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_relay_settings(&self, meta: Self::Metadata) -> BoxFuture<RelaySettings, Error> { + fn get_relay_settings(&self, _: Self::Metadata) -> BoxFuture<RelaySettings, Error> { trace!("get_relay_settings"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetRelaySettings(tx)) @@ -534,9 +473,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn set_allow_lan(&self, meta: Self::Metadata, allow_lan: bool) -> BoxFuture<(), Error> { + fn set_allow_lan(&self, _: Self::Metadata, allow_lan: bool) -> BoxFuture<(), Error> { trace!("set_allow_lan"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::SetAllowLan(tx, allow_lan)) @@ -544,9 +482,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_allow_lan(&self, meta: Self::Metadata) -> BoxFuture<bool, Error> { + fn get_allow_lan(&self, _: Self::Metadata) -> BoxFuture<bool, Error> { trace!("get_allow_lan"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetAllowLan(tx)) @@ -554,9 +491,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn set_auto_connect(&self, meta: Self::Metadata, auto_connect: bool) -> BoxFuture<(), Error> { + fn set_auto_connect(&self, _: 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(ManagementCommand::SetAutoConnect(tx, auto_connect)) @@ -564,9 +500,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_auto_connect(&self, meta: Self::Metadata) -> BoxFuture<bool, Error> { + fn get_auto_connect(&self, _: Self::Metadata) -> BoxFuture<bool, Error> { trace!("get_auto_connect"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetAutoConnect(tx)) @@ -574,21 +509,18 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn connect(&self, meta: Self::Metadata) -> BoxFuture<(), Error> { + fn connect(&self, _: Self::Metadata) -> BoxFuture<(), Error> { trace!("connect"); - try_future!(self.check_auth(&meta)); self.send_command_to_daemon(ManagementCommand::SetTargetState(TargetState::Secured)) } - fn disconnect(&self, meta: Self::Metadata) -> BoxFuture<(), Error> { + fn disconnect(&self, _: Self::Metadata) -> BoxFuture<(), Error> { trace!("disconnect"); - try_future!(self.check_auth(&meta)); self.send_command_to_daemon(ManagementCommand::SetTargetState(TargetState::Unsecured)) } - fn get_state(&self, meta: Self::Metadata) -> BoxFuture<DaemonState, Error> { + fn get_state(&self, _: Self::Metadata) -> BoxFuture<DaemonState, Error> { trace!("get_state"); - try_future!(self.check_auth(&meta)); let (state_tx, state_rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetState(state_tx)) @@ -596,9 +528,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_current_location(&self, meta: Self::Metadata) -> BoxFuture<GeoIpLocation, Error> { + fn get_current_location(&self, _: Self::Metadata) -> BoxFuture<GeoIpLocation, Error> { trace!("get_current_location"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetCurrentLocation(tx)) @@ -606,15 +537,13 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn shutdown(&self, meta: Self::Metadata) -> BoxFuture<(), Error> { + fn shutdown(&self, _: Self::Metadata) -> BoxFuture<(), Error> { trace!("shutdown"); - try_future!(self.check_auth(&meta)); self.send_command_to_daemon(ManagementCommand::Shutdown) } - fn get_account_history(&self, meta: Self::Metadata) -> BoxFuture<Vec<AccountToken>, Error> { + fn get_account_history(&self, _: Self::Metadata) -> BoxFuture<Vec<AccountToken>, Error> { trace!("get_account_history"); - try_future!(self.check_auth(&meta)); Box::new(future::result( self.load_history() .map(|history| history.get_accounts().to_vec()) @@ -627,11 +556,10 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi fn remove_account_from_history( &self, - meta: Self::Metadata, + _: Self::Metadata, account_token: AccountToken, ) -> BoxFuture<(), Error> { trace!("remove_account_from_history"); - try_future!(self.check_auth(&meta)); Box::new(future::result( self.load_history() .and_then(|mut history| history.remove_account_token(account_token)) @@ -645,13 +573,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi )) } - fn set_openvpn_mssfix( - &self, - meta: Self::Metadata, - mssfix: Option<u16>, - ) -> BoxFuture<(), Error> { + fn set_openvpn_mssfix(&self, _: Self::Metadata, mssfix: Option<u16>) -> BoxFuture<(), Error> { trace!("set_openvpn_mssfix"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::SetOpenVpnMssfix(tx, mssfix)) @@ -662,11 +585,10 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi fn set_openvpn_enable_ipv6( &self, - meta: Self::Metadata, + _: Self::Metadata, enable_ipv6: bool, ) -> BoxFuture<(), Error> { trace!("set_openvpn_enable_ipv6"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::SetOpenVpnEnableIpv6(tx, enable_ipv6)) @@ -675,9 +597,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_tunnel_options(&self, meta: Self::Metadata) -> BoxFuture<TunnelOptions, Error> { + fn get_tunnel_options(&self, _: Self::Metadata) -> BoxFuture<TunnelOptions, Error> { trace!("get_tunnel_options"); - try_future!(self.check_auth(&meta)); let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetTunnelOptions(tx)) @@ -685,8 +606,7 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_current_version(&self, meta: Self::Metadata) -> BoxFuture<String, Error> { - try_future!(self.check_auth(&meta)); + fn get_current_version(&self, _: Self::Metadata) -> BoxFuture<String, Error> { let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetCurrentVersion(tx)) @@ -695,8 +615,7 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn get_version_info(&self, meta: Self::Metadata) -> BoxFuture<version::AppVersionInfo, Error> { - try_future!(self.check_auth(&meta)); + fn get_version_info(&self, _: Self::Metadata) -> BoxFuture<version::AppVersionInfo, Error> { let (tx, rx) = sync::oneshot::channel(); let future = self .send_command_to_daemon(ManagementCommand::GetVersionInfo(tx)) @@ -714,15 +633,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Box::new(future) } - fn new_state_subscribe( - &self, - meta: Self::Metadata, - subscriber: pubsub::Subscriber<DaemonState>, - ) { + fn new_state_subscribe(&self, _: Self::Metadata, subscriber: pubsub::Subscriber<DaemonState>) { trace!("new_state_subscribe"); - if self.check_auth(&meta).is_err() { - return; - } Self::subscribe(subscriber, &self.subscriptions.new_state_subscriptions); } @@ -731,11 +643,8 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi Self::unsubscribe(id, &self.subscriptions.new_state_subscriptions) } - fn error_subscribe(&self, meta: Self::Metadata, subscriber: pubsub::Subscriber<Vec<String>>) { + fn error_subscribe(&self, _: Self::Metadata, subscriber: pubsub::Subscriber<Vec<String>>) { trace!("error_subscribe"); - if self.check_auth(&meta).is_err() { - return; - } Self::subscribe(subscriber, &self.subscriptions.error_subscriptions); } @@ -752,7 +661,6 @@ impl<T: From<ManagementCommand> + 'static + Send> ManagementInterfaceApi #[derive(Clone, Debug, Default)] pub struct Meta { session: Option<Arc<Session>>, - authenticated: Arc<AtomicBool>, } /// Make the `Meta` type possible to use as jsonrpc metadata type. @@ -769,6 +677,5 @@ impl PubSubMetadata for Meta { fn meta_extractor(context: &jsonrpc_ipc_server::RequestContext) -> Meta { Meta { session: Some(Arc::new(Session::new(context.sender.clone()))), - authenticated: Arc::new(AtomicBool::new(false)), } } diff --git a/mullvad-daemon/src/relays.rs b/mullvad-daemon/src/relays.rs index 28edaff9cc..4b0b07217e 100644 --- a/mullvad-daemon/src/relays.rs +++ b/mullvad-daemon/src/relays.rs @@ -24,18 +24,15 @@ use rand::{self, Rng, ThreadRng}; use tokio_timer::{TimeoutError, Timer}; const RELAYS_FILENAME: &str = "relays.json"; -const DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(30); -const UPDATE_INTERVAL: Duration = Duration::from_secs(15); +const DOWNLOAD_TIMEOUT: Duration = Duration::from_secs(15); +const UPDATE_INTERVAL: Duration = Duration::from_secs(60 * 60); const MAX_CACHE_AGE: Duration = Duration::from_secs(60 * 60 * 24); error_chain! { errors { RelayCacheError { description("Error with relay cache on disk") } DownloadError { description("Error when trying to download the list of relays") } - DownloadTimeoutError(error: tokio_timer::Error) { - display("Timer error - {}", error) - description("Timed out when trying to download the list of relays") - } + DownloadTimeoutError { description("Timed out when trying to download the list of relays") } NoRelay { description("No relays matching current constraints") } SerializationError { description("Error in serialization of relaylist") } } diff --git a/mullvad-daemon/src/rpc_address_file.rs b/mullvad-daemon/src/rpc_address_file.rs deleted file mode 100644 index d0df2c1919..0000000000 --- a/mullvad-daemon/src/rpc_address_file.rs +++ /dev/null @@ -1,88 +0,0 @@ -use std::fs::{self, File, OpenOptions}; -use std::io::{self, Write}; -use std::path::{Path, PathBuf}; - -use mullvad_paths; - -#[cfg(windows)] -extern crate winapi; - -error_chain! { - errors { - UnknownFilePath { - description("Failed to find path for RPC connection info file") - } - CreateDirFailed(path: PathBuf) { - description("Failed to create directory for RPC connection info file") - display( - "Failed to create directory for RPC connection info file: {}", - path.display(), - ) - } - WriteFailed(path: PathBuf) { - description("Failed to write RPC connection info to file") - display("Failed to write RPC connection info to {}", path.display()) - } - RemoveFailed(path: PathBuf) { - description("Failed to remove file") - display("Failed to remove {}", path.display()) - } - } -} - -/// Writes down the RPC connection info to the RPC file. -pub fn write(rpc_address: &str, shared_secret: &str) -> Result<()> { - // Avoids opening an existing file owned by another user and writing sensitive data to it. - remove()?; - - let file_path = - mullvad_paths::get_rpc_address_path().chain_err(|| ErrorKind::UnknownFilePath)?; - - if let Some(parent_dir) = file_path.parent() { - fs::create_dir_all(parent_dir) - .chain_err(|| ErrorKind::CreateDirFailed(parent_dir.to_owned()))?; - } - - open_file(&file_path) - .and_then(|mut file| write!(file, "{}\n{}\n", rpc_address, shared_secret)) - .chain_err(|| ErrorKind::WriteFailed(file_path.clone()))?; - - debug!("Wrote RPC connection info to {}", file_path.display()); - Ok(()) -} - -/// Removes the RPC file, if it exists. -pub fn remove() -> Result<()> { - let file_path = - mullvad_paths::get_rpc_address_path().chain_err(|| ErrorKind::UnknownFilePath)?; - - if let Err(error) = fs::remove_file(&file_path) { - if error.kind() == io::ErrorKind::NotFound { - // No previously existing file - Ok(()) - } else { - Err(error).chain_err(|| ErrorKind::RemoveFailed(file_path)) - } - } else { - Ok(()) - } -} - -fn open_file(path: &Path) -> io::Result<File> { - let mut open_options = OpenOptions::new(); - open_options.write(true).truncate(true).create(true); - - #[cfg(windows)] - { - use std::os::windows::fs::OpenOptionsExt; - open_options.share_mode(winapi::um::winnt::FILE_SHARE_READ); - } - - let file = open_options.open(path)?; - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - file.set_permissions(PermissionsExt::from_mode(0o644))?; - } - Ok(file) -} diff --git a/mullvad-daemon/src/rpc_uniqueness_check.rs b/mullvad-daemon/src/rpc_uniqueness_check.rs index 2766aa9199..37bf8a3f60 100644 --- a/mullvad-daemon/src/rpc_uniqueness_check.rs +++ b/mullvad-daemon/src/rpc_uniqueness_check.rs @@ -2,6 +2,7 @@ use error_chain::ChainedError; use log::Level; use mullvad_ipc_client::new_standalone_ipc_client; +use mullvad_paths; /// Checks if there is another instance of the daemon running. @@ -9,7 +10,7 @@ use mullvad_ipc_client::new_standalone_ipc_client; /// Tries to connect to another daemon and perform a simple RPC call. If it fails, assumes the /// other daemon has stopped. pub fn is_another_instance_running() -> bool { - match new_standalone_ipc_client() { + match new_standalone_ipc_client(&mullvad_paths::get_rpc_socket_path()) { Ok(_) => true, Err(error) => { let msg = |
