summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-06-13 14:17:19 -0300
committerJanito Vaqueiro Ferreira Filho <janito@mullvad.net>2018-06-13 14:17:19 -0300
commit88dea50f85c7b8b546324ca5985f06b43fa815ba (patch)
treecbdcc952f5fe8bfc0a47101552327ae6e7299ab8
parentca69ab47086db77e393769256d1d09e37bbb3802 (diff)
parent6548f4e07471070e3538cc2a9f043f5b2b67545d (diff)
downloadmullvadvpn-88dea50f85c7b8b546324ca5985f06b43fa815ba.tar.xz
mullvadvpn-88dea50f85c7b8b546324ca5985f06b43fa815ba.zip
Merge branch 'talpid-openvpn-plugin-ipc-credentials'
-rw-r--r--talpid-core/src/tunnel/openvpn.rs78
-rw-r--r--talpid-openvpn-plugin/src/lib.rs25
-rw-r--r--talpid-openvpn-plugin/src/processing.rs21
3 files changed, 105 insertions, 19 deletions
diff --git a/talpid-core/src/tunnel/openvpn.rs b/talpid-core/src/tunnel/openvpn.rs
index 58fa15eca2..c63429a4f5 100644
--- a/talpid-core/src/tunnel/openvpn.rs
+++ b/talpid-core/src/tunnel/openvpn.rs
@@ -12,6 +12,7 @@ use std::thread;
use std::time::Duration;
use talpid_ipc;
+use uuid;
mod errors {
error_chain!{
@@ -59,10 +60,14 @@ impl<C: OpenVpnBuilder> OpenVpnMonitor<C> {
L: Fn(OpenVpnPluginEvent, HashMap<String, String>) + Send + Sync + 'static,
P: AsRef<Path>,
{
- let event_dispatcher =
- event_server::start(on_event).chain_err(|| ErrorKind::EventDispatcherError)?;
+ let credentials = uuid::Uuid::new_v4().to_string();
+ let event_dispatcher = event_server::start(credentials.clone(), on_event)
+ .chain_err(|| ErrorKind::EventDispatcherError)?;
- cmd.plugin(plugin_path, vec![event_dispatcher.address().to_owned()]);
+ cmd.plugin(
+ plugin_path,
+ vec![event_dispatcher.address().to_owned(), credentials],
+ );
let child = cmd
.start()
.chain_err(|| ErrorKind::ChildProcessError("Failed to start"))?;
@@ -216,30 +221,41 @@ impl ProcessHandle for OpenVpnProcHandle {
mod event_server {
use super::OpenVpnPluginEvent;
- use jsonrpc_core::{Error, IoHandler};
+ use jsonrpc_core::{Compatibility, Error, MetaIoHandler, Metadata};
use std::collections::HashMap;
+ use std::sync::atomic::{AtomicBool, Ordering};
+ use std::sync::Arc;
use talpid_ipc;
/// Construct and start the IPC server with the given event listener callback.
- pub fn start<L>(on_event: L) -> talpid_ipc::Result<talpid_ipc::IpcServer>
+ pub fn start<L>(credentials: String, on_event: L) -> talpid_ipc::Result<talpid_ipc::IpcServer>
where
L: Fn(OpenVpnPluginEvent, HashMap<String, String>) + Send + Sync + 'static,
{
- let rpc = OpenVpnEventApiImpl { on_event };
- let mut io = IoHandler::new();
+ let rpc = OpenVpnEventApiImpl {
+ credentials,
+ on_event,
+ };
+ let mut io = MetaIoHandler::with_compatibility(Compatibility::V2);
io.extend_with(rpc.to_delegate());
talpid_ipc::IpcServer::start(io.into())
}
build_rpc_trait! {
pub trait OpenVpnEventApi {
- #[rpc(name = "openvpn_event")]
- fn openvpn_event(&self, OpenVpnPluginEvent, HashMap<String, String>)
+ type Metadata;
+
+ #[rpc(meta, name = "authenticate")]
+ fn authenticate(&self, Self::Metadata, String) -> Result<bool, Error>;
+
+ #[rpc(meta, name = "openvpn_event")]
+ fn openvpn_event(&self, Self::Metadata, OpenVpnPluginEvent, HashMap<String, String>)
-> Result<(), Error>;
}
}
struct OpenVpnEventApiImpl<L> {
+ credentials: String,
on_event: L,
}
@@ -247,16 +263,60 @@ mod event_server {
where
L: Fn(OpenVpnPluginEvent, HashMap<String, String>) + Send + Sync + 'static,
{
+ type Metadata = Meta;
+
+ fn authenticate(
+ &self,
+ metadata: Self::Metadata,
+ credentials: String,
+ ) -> Result<bool, Error> {
+ if credentials == self.credentials {
+ metadata.authenticated.store(true, Ordering::Relaxed);
+ Ok(true)
+ } else {
+ Ok(false)
+ }
+ }
+
fn openvpn_event(
&self,
+ metadata: Self::Metadata,
event: OpenVpnPluginEvent,
env: HashMap<String, String>,
) -> Result<(), Error> {
trace!("OpenVPN event {:?}", event);
+ metadata.check_authentication()?;
(self.on_event)(event, env);
Ok(())
}
}
+
+ #[derive(Clone)]
+ struct Meta {
+ authenticated: Arc<AtomicBool>,
+ }
+
+ impl Default for Meta {
+ fn default() -> Self {
+ Meta {
+ authenticated: Arc::new(AtomicBool::new(false)),
+ }
+ }
+ }
+
+ impl Meta {
+ fn check_authentication(&self) -> Result<(), Error> {
+ if self.authenticated.load(Ordering::Relaxed) {
+ trace!("Authenticated");
+ Ok(())
+ } else {
+ trace!("Not authenticated");
+ Err(Error::invalid_request())
+ }
+ }
+ }
+
+ impl Metadata for Meta {}
}
diff --git a/talpid-openvpn-plugin/src/lib.rs b/talpid-openvpn-plugin/src/lib.rs
index 71c332a212..9c6c690339 100644
--- a/talpid-openvpn-plugin/src/lib.rs
+++ b/talpid-openvpn-plugin/src/lib.rs
@@ -57,6 +57,11 @@ openvpn_plugin!(
::EventProcessor
);
+pub struct Arguments {
+ server_id: talpid_ipc::IpcServerId,
+ credentials: String,
+}
+
fn openvpn_open(
args: Vec<CString>,
_env: HashMap<CString, CString>,
@@ -64,22 +69,30 @@ fn openvpn_open(
env_logger::init();
debug!("Initializing plugin");
- let core_server_id = parse_args(&args)?;
- info!("Connecting back to talpid core at {}", core_server_id);
- let processor = EventProcessor::new(&core_server_id).chain_err(|| ErrorKind::InitHandleFailed)?;
+ let arguments = parse_args(&args)?;
+ info!("Connecting back to talpid core at {}", arguments.server_id);
+ let processor = EventProcessor::new(&arguments).chain_err(|| ErrorKind::InitHandleFailed)?;
Ok((INTERESTING_EVENTS.to_vec(), processor))
}
-fn parse_args(args: &[CString]) -> Result<talpid_ipc::IpcServerId> {
+fn parse_args(args: &[CString]) -> Result<Arguments> {
let mut args_iter = openvpn_plugin::ffi::parse::string_array_utf8(args)
.chain_err(|| ErrorKind::ParseArgsFailed)?
.into_iter();
+
let _plugin_path = args_iter.next();
- let core_server_id: talpid_ipc::IpcServerId = args_iter
+ let server_id: talpid_ipc::IpcServerId = args_iter
.next()
.ok_or_else(|| ErrorKind::Msg("No core server id given as first argument".to_owned()))?;
- Ok(core_server_id)
+ let credentials = args_iter
+ .next()
+ .ok_or_else(|| ErrorKind::Msg("No IPC credentials given as second argument".to_owned()))?;
+
+ Ok(Arguments {
+ server_id,
+ credentials,
+ })
}
diff --git a/talpid-openvpn-plugin/src/processing.rs b/talpid-openvpn-plugin/src/processing.rs
index a376665888..cadaf80647 100644
--- a/talpid-openvpn-plugin/src/processing.rs
+++ b/talpid-openvpn-plugin/src/processing.rs
@@ -1,10 +1,15 @@
use openvpn_plugin;
use std::collections::HashMap;
use std::sync::Mutex;
-use talpid_ipc::{IpcServerId, WsIpcClient};
+use talpid_ipc::WsIpcClient;
+
+use super::Arguments;
error_chain! {
errors {
+ AuthDenied {
+ description("Authentication failed with Talpid Core IPC server")
+ }
IpcSendingError {
description("Failed while sending an event over the IPC channel")
}
@@ -18,10 +23,18 @@ pub struct EventProcessor {
}
impl EventProcessor {
- pub fn new(server_id: &IpcServerId) -> Result<EventProcessor> {
+ pub fn new(arguments: &Arguments) -> Result<EventProcessor> {
trace!("Creating EventProcessor");
- let ipc_client =
- WsIpcClient::connect(server_id).chain_err(|| "Unable to create IPC client")?;
+ let mut ipc_client =
+ WsIpcClient::connect(&arguments.server_id).chain_err(|| "Unable to create IPC client")?;
+
+ trace!("Authenticating EventProcessor");
+ match ipc_client.call("authenticate", &[&arguments.credentials]) {
+ Ok(true) => trace!("Credentials accepted"),
+ Ok(false) => bail!(ErrorKind::AuthDenied),
+ Err(error) => bail!(Error::with_chain(error, ErrorKind::AuthDenied)),
+ }
+
Ok(EventProcessor {
ipc_client: Mutex::new(ipc_client),
})