diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-04-08 14:13:50 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-04-08 14:13:50 +0200 |
| commit | 041f348a07b3044499f79aea413668ef82b8381e (patch) | |
| tree | 35341a9ba060706af4c7894c2f92dfd9e30bc8dd | |
| parent | eb0c1ddff764f77c3960b041e63527cfbbe668fb (diff) | |
| parent | 24d8ce38d0d39810780c80a842b6bfeda1aaed8a (diff) | |
| download | mullvadvpn-041f348a07b3044499f79aea413668ef82b8381e.tar.xz mullvadvpn-041f348a07b3044499f79aea413668ef82b8381e.zip | |
Merge branch 'restrict-socket-perms'
| -rw-r--r-- | CHANGELOG.md | 2 | ||||
| -rw-r--r-- | Cargo.lock | 2 | ||||
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | mullvad-management-interface/Cargo.toml | 4 | ||||
| -rw-r--r-- | mullvad-management-interface/src/lib.rs | 38 | ||||
| -rw-r--r-- | talpid-core/src/tunnel/openvpn/mod.rs | 5 |
6 files changed, 44 insertions, 11 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 760fe1b88f..ac2bb198a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ Line wrap the file at 100 chars. Th ## [Unreleased] ### Added - Preserve log of old daemon instance when upgrading on Desktop. +- When `MULLVAD_MANAGEMENT_SOCKET_GROUP` is set, only allow the specified group to access the + management interface UDS socket. This means that only users in that group can use the CLI and GUI. #### Linux - Always enable `src_valid_mark` config option when connecting to allow policty based routing. diff --git a/Cargo.lock b/Cargo.lock index 93fe8d713f..f6ee1fbb81 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1331,7 +1331,9 @@ version = "0.1.0" dependencies = [ "err-derive 0.3.0", "futures", + "lazy_static", "mullvad-paths", + "nix 0.19.1", "parity-tokio-ipc", "prost", "prost-types", @@ -434,6 +434,10 @@ echo "org.gradle.jvmargs=-Xmx4608M" >> ~/.gradle/gradle.properties servers are used. * `TALPID_DISABLE_OFFLINE_MONITOR` - Forces the daemon to always assume the host is online. +* `MULLVAD_MANAGEMENT_SOCKET_GROUP` - On Linux and macOS, this restricts access to the management + interface UDS socket to users in the specified group. This means that only users in that group can + use the CLI and GUI. By default, everyone has access to the socket. + #### Setting environment variable - On Windows, one can use `setx` from an elevated shell, like so ```bat diff --git a/mullvad-management-interface/Cargo.toml b/mullvad-management-interface/Cargo.toml index 2219fc728f..cb28f4b9ed 100644 --- a/mullvad-management-interface/Cargo.toml +++ b/mullvad-management-interface/Cargo.toml @@ -19,5 +19,9 @@ futures = "0.3" tokio = { version = "0.2", features = [ "rt-util" ] } triggered = "0.1.1" +[target.'cfg(unix)'.dependencies] +nix = "0.19" +lazy_static = "1.0" + [build-dependencies] tonic-build = { version = "0.3", default-features = false, features = ["transport", "prost"] } diff --git a/mullvad-management-interface/src/lib.rs b/mullvad-management-interface/src/lib.rs index 8b16aff46e..abf4282923 100644 --- a/mullvad-management-interface/src/lib.rs +++ b/mullvad-management-interface/src/lib.rs @@ -6,7 +6,7 @@ pub mod types { use parity_tokio_ipc::Endpoint as IpcEndpoint; #[cfg(unix)] -use std::{fs, os::unix::fs::PermissionsExt}; +use std::{env, fs, os::unix::fs::PermissionsExt}; use std::{ io, pin::Pin, @@ -22,6 +22,12 @@ pub type ManagementServiceClient = types::management_service_client::ManagementServiceClient<Channel>; pub use types::management_service_server::{ManagementService, ManagementServiceServer}; +#[cfg(unix)] +lazy_static::lazy_static! { + static ref MULLVAD_MANAGEMENT_SOCKET_GROUP: Option<String> = env::var("MULLVAD_MANAGEMENT_SOCKET_GROUP") + .ok(); +} + #[derive(err_derive::Error, Debug)] #[error(no_from)] pub enum Error { @@ -36,6 +42,18 @@ pub enum Error { #[error(display = "Unable to set permissions for IPC endpoint")] PermissionsError(#[error(source)] io::Error), + + #[cfg(unix)] + #[error(display = "Group not found")] + NoGidError, + + #[cfg(unix)] + #[error(display = "Failed to obtain group ID")] + ObtainGidError(#[error(source)] nix::Error), + + #[cfg(unix)] + #[error(display = "Failed to set group ID")] + SetGidError(#[error(source)] nix::Error), } pub async fn new_rpc_client() -> Result<ManagementServiceClient, Error> { @@ -60,22 +78,26 @@ pub async fn spawn_rpc_server<T: ManagementService>( use futures::stream::TryStreamExt; use parity_tokio_ipc::SecurityAttributes; - let socket_path = mullvad_paths::get_rpc_socket_path() - .to_string_lossy() - .to_string(); + let socket_path = mullvad_paths::get_rpc_socket_path(); - let mut endpoint = IpcEndpoint::new(socket_path.to_string()); + let mut endpoint = IpcEndpoint::new(socket_path.to_string_lossy().to_string()); endpoint.set_security_attributes( SecurityAttributes::allow_everyone_create() .map_err(Error::SecurityAttributes)? - .set_mode(777) + .set_mode(0o766) .map_err(Error::SecurityAttributes)?, ); let incoming = endpoint.incoming().map_err(Error::StartServerError)?; #[cfg(unix)] - fs::set_permissions(&socket_path, PermissionsExt::from_mode(0o766)) - .map_err(Error::PermissionsError)?; + if let Some(group_name) = &*MULLVAD_MANAGEMENT_SOCKET_GROUP { + let group = nix::unistd::Group::from_name(group_name) + .map_err(Error::ObtainGidError)? + .ok_or(Error::NoGidError)?; + nix::unistd::chown(&socket_path, None, Some(group.gid)).map_err(Error::SetGidError)?; + fs::set_permissions(&socket_path, PermissionsExt::from_mode(0o760)) + .map_err(Error::PermissionsError)?; + } let _ = server_start_tx.send(()); diff --git a/talpid-core/src/tunnel/openvpn/mod.rs b/talpid-core/src/tunnel/openvpn/mod.rs index 520181d3cc..cbb89f912e 100644 --- a/talpid-core/src/tunnel/openvpn/mod.rs +++ b/talpid-core/src/tunnel/openvpn/mod.rs @@ -901,7 +901,7 @@ impl ProcessHandle for OpenVpnProcHandle { mod event_server { use futures::stream::TryStreamExt; - use parity_tokio_ipc::{Endpoint as IpcEndpoint, SecurityAttributes}; + use parity_tokio_ipc::Endpoint as IpcEndpoint; use std::{ collections::HashMap, convert::TryFrom, @@ -973,8 +973,7 @@ mod event_server { where L: Fn(openvpn_plugin::EventType, HashMap<String, String>) + Send + Sync + 'static, { - let mut endpoint = IpcEndpoint::new(ipc_path.clone()); - endpoint.set_security_attributes(SecurityAttributes::allow_everyone_create().unwrap()); + let endpoint = IpcEndpoint::new(ipc_path); let incoming = endpoint.incoming().map_err(Error::StartServer)?; let _ = server_start_tx.send(()); |
