summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-10-11 12:36:10 +0200
committerLinus Färnstrand <linus@mullvad.net>2017-10-12 10:22:39 +0200
commit69df55e1ff312d7079a76e5f6685364e54f753d0 (patch)
treeccebf13a78c6e0d21c863e65a76dbdddd64db414
parent5c06a80f3c8d96e1fff453f081197d1692dd8a90 (diff)
downloadmullvadvpn-69df55e1ff312d7079a76e5f6685364e54f753d0.tar.xz
mullvadvpn-69df55e1ff312d7079a76e5f6685364e54f753d0.zip
Add auth() rpc call and shared_secret
-rw-r--r--mullvad-daemon/src/main.rs9
-rw-r--r--mullvad-daemon/src/management_interface.rs26
-rw-r--r--mullvad-daemon/src/rpc_info.rs6
3 files changed, 32 insertions, 9 deletions
diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs
index c0687026a3..7230f81abd 100644
--- a/mullvad-daemon/src/main.rs
+++ b/mullvad-daemon/src/main.rs
@@ -229,14 +229,15 @@ impl Daemon {
fn start_management_interface_server(
event_tx: IntoSender<TunnelCommand, DaemonEvent>,
) -> Result<ManagementInterfaceServer> {
- let server = ManagementInterfaceServer::start(event_tx).chain_err(|| {
- ErrorKind::ManagementInterfaceError("Failed to start server")
- })?;
+ let shared_secret = uuid::Uuid::new_v4().to_string();
+ let server = ManagementInterfaceServer::start(event_tx, shared_secret.clone()).chain_err(
+ || ErrorKind::ManagementInterfaceError("Failed to start server"),
+ )?;
info!(
"Mullvad management interface listening on {}",
server.address()
);
- rpc_info::write(server.address()).chain_err(|| {
+ rpc_info::write(server.address(), &shared_secret).chain_err(|| {
ErrorKind::ManagementInterfaceError("Failed to write RPC address to file")
})?;
Ok(server)
diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs
index 7b222b8504..4bc5cf3fda 100644
--- a/mullvad-daemon/src/management_interface.rs
+++ b/mullvad-daemon/src/management_interface.rs
@@ -33,6 +33,9 @@ build_rpc_trait! {
pub trait ManagementInterfaceApi {
type Metadata;
+ #[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.
#[rpc(async, name = "get_account_data")]
@@ -139,11 +142,14 @@ pub struct ManagementInterfaceServer {
}
impl ManagementInterfaceServer {
- pub fn start<T>(tunnel_tx: IntoSender<TunnelCommand, T>) -> talpid_ipc::Result<Self>
+ pub fn start<T>(
+ tunnel_tx: IntoSender<TunnelCommand, T>,
+ shared_secret: String,
+ ) -> talpid_ipc::Result<Self>
where
T: From<TunnelCommand> + 'static + Send,
{
- let rpc = ManagementInterface::new(tunnel_tx);
+ let rpc = ManagementInterface::new(tunnel_tx, shared_secret);
let subscriptions = rpc.subscriptions.clone();
let mut io = PubSubHandler::default();
@@ -210,13 +216,15 @@ impl EventBroadcaster {
struct ManagementInterface<T: From<TunnelCommand> + 'static + Send> {
subscriptions: Arc<ActiveSubscriptions>,
tx: Mutex<IntoSender<TunnelCommand, T>>,
+ shared_secret: String,
}
impl<T: From<TunnelCommand> + 'static + Send> ManagementInterface<T> {
- pub fn new(tx: IntoSender<TunnelCommand, T>) -> Self {
+ pub fn new(tx: IntoSender<TunnelCommand, T>, shared_secret: String) -> Self {
ManagementInterface {
subscriptions: Default::default(),
tx: Mutex::new(tx),
+ shared_secret,
}
}
@@ -285,6 +293,16 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterface<T> {
impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for ManagementInterface<T> {
type Metadata = Meta;
+ fn auth(&self, mut meta: Self::Metadata, shared_secret: String) -> BoxFuture<(), Error> {
+ meta.authenticated = shared_secret == self.shared_secret;
+ debug!("auth: {}", meta.authenticated);
+ if meta.authenticated {
+ Box::new(future::ok(()))
+ } else {
+ Box::new(future::err(Error::internal_error()))
+ }
+ }
+
fn get_account_data(&self, account_token: AccountToken) -> BoxFuture<AccountData, Error> {
trace!("get_account_data");
let (tx, rx) = sync::oneshot::channel();
@@ -410,6 +428,7 @@ impl<T: From<TunnelCommand> + 'static + Send> ManagementInterfaceApi for Managem
#[derive(Clone, Debug, Default)]
pub struct Meta {
session: Option<Arc<Session>>,
+ authenticated: bool,
}
/// Make the `Meta` type possible to use as jsonrpc metadata type.
@@ -426,5 +445,6 @@ impl PubSubMetadata for Meta {
fn meta_extractor(context: &jsonrpc_ws_server::RequestContext) -> Meta {
Meta {
session: Some(Arc::new(Session::new(context.sender()))),
+ authenticated: false,
}
}
diff --git a/mullvad-daemon/src/rpc_info.rs b/mullvad-daemon/src/rpc_info.rs
index 13d354d9bb..7826b736a8 100644
--- a/mullvad-daemon/src/rpc_info.rs
+++ b/mullvad-daemon/src/rpc_info.rs
@@ -29,9 +29,11 @@ lazy_static! {
/// Writes down the RPC address to some API to a file.
-pub fn write(rpc_address: &str) -> Result<()> {
+pub fn write(rpc_address: &str, shared_secret: &str) -> Result<()> {
open_file(RPC_ADDRESS_FILE_PATH.as_path())
- .and_then(|mut file| file.write_all(rpc_address.as_bytes()))
+ .and_then(|mut file| {
+ write!(file, "{}\n{}", rpc_address, shared_secret)
+ })
.chain_err(|| ErrorKind::WriteFailed(RPC_ADDRESS_FILE_PATH.to_owned()))?;
debug!(