diff options
| -rw-r--r-- | talpid-core/Cargo.toml | 2 | ||||
| -rw-r--r-- | talpid-core/src/lib.rs | 4 | ||||
| -rw-r--r-- | talpid-core/src/mktemp.rs | 41 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/mod.rs | 33 |
4 files changed, 68 insertions, 12 deletions
diff --git a/talpid-core/Cargo.toml b/talpid-core/Cargo.toml index 5dcb634b0d..3d93e80713 100644 --- a/talpid-core/Cargo.toml +++ b/talpid-core/Cargo.toml @@ -11,7 +11,7 @@ jsonrpc-core = { git = "https://github.com/paritytech/jsonrpc", tag = "v7.1.0" } jsonrpc-macros = { git = "https://github.com/paritytech/jsonrpc", tag = "v7.1.0" } lazy_static = "0.2" log = "0.3" -mktemp = "0.3" +uuid = { version = "0.5", features = ["v4"] } openvpn-plugin = { version = "0.2", features = ["serialize"] } talpid-ipc = { path = "../talpid-ipc" } diff --git a/talpid-core/src/lib.rs b/talpid-core/src/lib.rs index cbdc08886e..dc37401ebf 100644 --- a/talpid-core/src/lib.rs +++ b/talpid-core/src/lib.rs @@ -12,13 +12,13 @@ extern crate duct; extern crate lazy_static; #[macro_use] extern crate log; -extern crate mktemp; #[macro_use] extern crate error_chain; extern crate jsonrpc_core; #[macro_use] extern crate jsonrpc_macros; +extern crate uuid; extern crate talpid_ipc; extern crate openvpn_plugin; @@ -40,3 +40,5 @@ pub mod mpsc; /// Abstractions over different firewalls pub mod firewall; + +mod mktemp; diff --git a/talpid-core/src/mktemp.rs b/talpid-core/src/mktemp.rs new file mode 100644 index 0000000000..69fa01f97f --- /dev/null +++ b/talpid-core/src/mktemp.rs @@ -0,0 +1,41 @@ +use std::env; +use std::path::{Path, PathBuf}; +use std::fs; + +use uuid::Uuid; + +#[derive(Debug)] +pub struct TempFile { + path: PathBuf, +} + +impl TempFile { + /// Create a new unique `TempFile`. The file will not exist after this. + pub fn new() -> Self { + TempFile { + path: generate_path(), + } + } + + pub fn to_path_buf(&self) -> PathBuf { + self.path.clone() + } +} + +impl AsRef<Path> for TempFile { + fn as_ref(&self) -> &Path { + &self.path.as_path() + } +} + +impl Drop for TempFile { + fn drop(&mut self) { + if let Err(e) = fs::remove_file(&self.path) { + error!("Unable to remove TempFile {}: {:?}", self.path.to_string_lossy(), e); + } + } +} + +fn generate_path() -> PathBuf { + env::temp_dir().join(Uuid::new_v4().to_string()) +} diff --git a/talpid-core/src/tunnel/mod.rs b/talpid-core/src/tunnel/mod.rs index b8d91c567e..489fdc8a94 100644 --- a/talpid-core/src/tunnel/mod.rs +++ b/talpid-core/src/tunnel/mod.rs @@ -1,7 +1,10 @@ use mktemp; use net; + use openvpn_plugin::types::OpenVpnPluginEvent; + use process::openvpn::OpenVpnCommand; + use std::env; use std::ffi::{OsStr, OsString}; use std::fs; @@ -63,7 +66,8 @@ impl TunnelEvent { /// Abstraction for monitoring a generic VPN tunnel. pub struct TunnelMonitor { monitor: OpenVpnMonitor, - _user_pass_file: mktemp::Temp, + /// Keep the `TempFile` for the user-pass file in the struct, so it's removed on drop. + _user_pass_file: mktemp::TempFile, } impl TunnelMonitor { @@ -72,13 +76,22 @@ impl TunnelMonitor { pub fn new<L>(remote: net::Endpoint, account_token: &str, on_event: L) -> Result<Self> where L: Fn(TunnelEvent) + Send + Sync + 'static { - let on_openvpn_event = move |event, _env| match TunnelEvent::from_openvpn_event(&event) { - Some(tunnel_event) => on_event(tunnel_event), - None => debug!("Ignoring OpenVpnEvent {:?}", event), - }; let user_pass_file = Self::create_user_pass_file(account_token) .chain_err(|| ErrorKind::CredentialsWriteError)?; let cmd = Self::create_openvpn_cmd(remote, user_pass_file.as_ref()); + let user_pass_file_path = user_pass_file.to_path_buf(); + + let on_openvpn_event = move |event, _env| { + if event == OpenVpnPluginEvent::Up { + // The user-pass file has been read. Try to delete it early. + let _ = fs::remove_file(&user_pass_file_path); + } + match TunnelEvent::from_openvpn_event(&event) { + Some(tunnel_event) => on_event(tunnel_event), + None => debug!("Ignoring OpenVpnEvent {:?}", event), + } + }; + let monitor = openvpn::OpenVpnMonitor::new(cmd, on_openvpn_event, Self::get_plugin_path()?) .chain_err(|| ErrorKind::TunnelMonitoringError)?; Ok( @@ -168,16 +181,16 @@ impl TunnelMonitor { } } - fn create_user_pass_file(account_token: &str) -> io::Result<mktemp::Temp> { - let path = mktemp::Temp::new_file()?; + fn create_user_pass_file(account_token: &str) -> io::Result<mktemp::TempFile> { + let temp_file = mktemp::TempFile::new(); debug!( "Writing user-pass credentials to {}", - path.as_ref().to_string_lossy() + temp_file.as_ref().to_string_lossy() ); - let mut file = fs::File::create(&path)?; + let mut file = fs::File::create(&temp_file)?; Self::set_user_pass_file_permissions(&file)?; write!(file, "{}\n-\n", account_token)?; - Ok(path) + Ok(temp_file) } #[cfg(unix)] |
