diff --git a/README.md b/README.md index 709ce3fa7a90..e7162e81d5ac 100644 --- a/README.md +++ b/README.md @@ -332,7 +332,7 @@ The settings directory can be changed by setting the `MULLVAD_SETTINGS_DIR` envi | Linux | `/etc/mullvad-vpn/` | | macOS | `/etc/mullvad-vpn/` | | Windows | `%LOCALAPPDATA%\Mullvad VPN\` | -| Android | `/data/data/net.mullvad.mullvadvpn/` | +| Android | [`getFilesDir()`](https://developer.android.com/reference/android/content/Context#getFilesDir()) | #### Logs @@ -343,7 +343,7 @@ The log directory can be changed by setting the `MULLVAD_LOG_DIR` environment va | Linux | `/var/log/mullvad-vpn/` + systemd | | macOS | `/var/log/mullvad-vpn/` | | Windows | `C:\ProgramData\Mullvad VPN\` | -| Android | `/data/data/net.mullvad.mullvadvpn/` | +| Android | [`getFilesDir()`](https://developer.android.com/reference/android/content/Context#getFilesDir()) | #### Cache @@ -354,7 +354,7 @@ The cache directory can be changed by setting the `MULLVAD_CACHE_DIR` environmen | Linux | `/var/cache/mullvad-vpn/` | | macOS | `/Library/Caches/mullvad-vpn/` | | Windows | `C:\ProgramData\Mullvad VPN\cache` | -| Android | `/data/data/net.mullvad.mullvadvpn/cache` | +| Android | [`getCacheDir()`](https://developer.android.com/reference/android/content/Context#getCacheDir()) | #### RPC address file @@ -366,7 +366,7 @@ environment variable. | Linux | `/var/run/mullvad-vpn` | | macOS | `/var/run/mullvad-vpn` | | Windows | `//./pipe/Mullvad VPN` | -| Android | `/data/data/net.mullvad.mullvadvpn/rpc-socket` | +| Android | [`getNoBackupFilesDir()`](https://developer.android.com/reference/android/content/ContextWrapper#getNoBackupFilesDir()) | ### GUI diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/PathConstant.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/PathConstant.kt deleted file mode 100644 index 755e0767213a..000000000000 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/constant/PathConstant.kt +++ /dev/null @@ -1,3 +0,0 @@ -package net.mullvad.mullvadvpn.constant - -const val GRPC_SOCKET_FILE_NAME = "rpc-socket" diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt index a9853250f2ce..6af9ff57cb02 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/AppModule.kt @@ -1,8 +1,10 @@ package net.mullvad.mullvadvpn.di +import java.io.File import kotlinx.coroutines.MainScope import net.mullvad.mullvadvpn.BuildConfig -import net.mullvad.mullvadvpn.constant.GRPC_SOCKET_FILE_NAME +import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAME +import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService import net.mullvad.mullvadvpn.lib.intent.IntentProvider import net.mullvad.mullvadvpn.lib.model.BuildVersion @@ -15,10 +17,12 @@ import org.koin.core.qualifier.named import org.koin.dsl.module val appModule = module { - single(named(RPC_SOCKET_PATH)) { "${androidContext().dataDir.path}/$GRPC_SOCKET_FILE_NAME" } + single(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT)) { + File(androidContext().noBackupFilesDir, GRPC_SOCKET_FILE_NAME) + } single { ManagementService( - rpcSocketPath = get(named(RPC_SOCKET_PATH)), + rpcSocketFile = get(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT)), extensiveLogging = BuildConfig.DEBUG, scope = MainScope(), ) @@ -30,5 +34,3 @@ val appModule = module { single { VpnPermissionRepository(androidContext()) } single { ConnectionProxy(get(), get()) } } - -const val RPC_SOCKET_PATH = "RPC_SOCKET" diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/DiConstant.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/DiConstant.kt new file mode 100644 index 000000000000..0acd41c7ec7e --- /dev/null +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/DiConstant.kt @@ -0,0 +1,3 @@ +package net.mullvad.mullvadvpn.lib.common.constant + +const val GRPC_SOCKET_FILE_NAMED_ARGUMENT = "RPC_SOCKET" diff --git a/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/PathConstant.kt b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/PathConstant.kt new file mode 100644 index 000000000000..4ad0471c867c --- /dev/null +++ b/android/lib/common/src/main/kotlin/net/mullvad/mullvadvpn/lib/common/constant/PathConstant.kt @@ -0,0 +1,3 @@ +package net.mullvad.mullvadvpn.lib.common.constant + +const val GRPC_SOCKET_FILE_NAME = "rpc-socket" diff --git a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt index 987b7e56ea4d..10c240685062 100644 --- a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt +++ b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt @@ -16,6 +16,7 @@ import io.grpc.ConnectivityState import io.grpc.Status import io.grpc.StatusException import io.grpc.android.UdsChannelBuilder +import java.io.File import java.net.InetAddress import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -127,14 +128,19 @@ import net.mullvad.mullvadvpn.lib.model.wireguardConstraints @Suppress("TooManyFunctions") class ManagementService( - rpcSocketPath: String, + rpcSocketFile: File, private val extensiveLogging: Boolean, private val scope: CoroutineScope, ) { private var job: Job? = null + // We expect daemon to create the rpc socket file on the path provided on initialisation private val channel = - UdsChannelBuilder.forPath(rpcSocketPath, LocalSocketAddress.Namespace.FILESYSTEM).build() + UdsChannelBuilder.forPath( + rpcSocketFile.absolutePath, + LocalSocketAddress.Namespace.FILESYSTEM + ) + .build() val connectionState: StateFlow = channel diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt index aa6f07e9bb0e..2c441483f699 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadDaemon.kt @@ -17,6 +17,7 @@ private const val RELAYS_FILE = "relays.json" @SuppressLint("SdCardPath") class MullvadDaemon( vpnService: MullvadVpnService, + rpcSocketFile: File, apiEndpointConfiguration: ApiEndpointConfiguration, migrateSplitTunneling: MigrateSplitTunneling ) { @@ -34,8 +35,9 @@ class MullvadDaemon( initialize( vpnService = vpnService, + rpcSocketPath = rpcSocketFile.absolutePath, + filesDirectory = vpnService.filesDir.absolutePath, cacheDirectory = vpnService.cacheDir.absolutePath, - resourceDirectory = vpnService.filesDir.absolutePath, apiEndpoint = apiEndpointConfiguration.apiEndpoint() ) } @@ -69,8 +71,9 @@ class MullvadDaemon( private external fun initialize( vpnService: MullvadVpnService, + rpcSocketPath: String, + filesDirectory: String, cacheDirectory: String, - resourceDirectory: String, apiEndpoint: ApiEndpoint? ) diff --git a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt index e3940c816679..87f6076c3fd1 100644 --- a/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt +++ b/android/service/src/main/kotlin/net/mullvad/mullvadvpn/service/MullvadVpnService.kt @@ -9,6 +9,7 @@ import android.util.Log import androidx.core.content.getSystemService import androidx.lifecycle.lifecycleScope import arrow.atomic.AtomicInt +import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow @@ -17,6 +18,7 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import net.mullvad.mullvadvpn.lib.common.constant.GRPC_SOCKET_FILE_NAMED_ARGUMENT import net.mullvad.mullvadvpn.lib.common.constant.KEY_CONNECT_ACTION import net.mullvad.mullvadvpn.lib.common.constant.KEY_DISCONNECT_ACTION import net.mullvad.mullvadvpn.lib.common.constant.TAG @@ -36,6 +38,7 @@ import net.mullvad.mullvadvpn.service.notifications.ShouldBeOnForegroundProvider import net.mullvad.talpid.TalpidVpnService import org.koin.android.ext.android.getKoin import org.koin.core.context.loadKoinModules +import org.koin.core.qualifier.named class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider { private val _shouldBeOnForeground = MutableStateFlow(false) @@ -49,6 +52,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider { private lateinit var migrateSplitTunneling: MigrateSplitTunneling private lateinit var intentProvider: IntentProvider private lateinit var connectionProxy: ConnectionProxy + private lateinit var rpcSocketFile: File private lateinit var foregroundNotificationHandler: ForegroundNotificationManager @@ -75,6 +79,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider { migrateSplitTunneling = get() intentProvider = get() connectionProxy = get() + rpcSocketFile = get(named(GRPC_SOCKET_FILE_NAMED_ARGUMENT)) } keyguardManager = getSystemService()!! @@ -88,6 +93,7 @@ class MullvadVpnService : TalpidVpnService(), ShouldBeOnForegroundProvider { daemonInstance = MullvadDaemon( vpnService = this@MullvadVpnService, + rpcSocketFile = rpcSocketFile, apiEndpointConfiguration = intentProvider.getLatestIntent()?.getApiEndpointConfigurationExtras() ?: apiEndpointConfiguration, diff --git a/mullvad-daemon/src/lib.rs b/mullvad-daemon/src/lib.rs index 47e72e07cb25..0395983d2270 100644 --- a/mullvad-daemon/src/lib.rs +++ b/mullvad-daemon/src/lib.rs @@ -2894,8 +2894,8 @@ fn oneshot_map( /// Remove any old RPC socket (if it exists). #[cfg(not(windows))] -pub async fn cleanup_old_rpc_socket() { - if let Err(err) = tokio::fs::remove_file(mullvad_paths::get_rpc_socket_path()).await { +pub async fn cleanup_old_rpc_socket(rpc_socket_path: impl AsRef) { + if let Err(err) = tokio::fs::remove_file(rpc_socket_path).await { if err.kind() != std::io::ErrorKind::NotFound { log::error!("Failed to remove old RPC socket: {}", err); } diff --git a/mullvad-daemon/src/main.rs b/mullvad-daemon/src/main.rs index 510127fd05fa..64396f4f6fac 100644 --- a/mullvad-daemon/src/main.rs +++ b/mullvad-daemon/src/main.rs @@ -5,7 +5,11 @@ use mullvad_daemon::{ management_interface::{ManagementInterfaceEventBroadcaster, ManagementInterfaceServer}, rpc_uniqueness_check, runtime, version, Daemon, DaemonCommandChannel, DaemonCommandSender, }; -use std::{path::PathBuf, thread, time::Duration}; +use std::{ + path::{Path, PathBuf}, + thread, + time::Duration, +}; use talpid_types::ErrorExt; mod cli; @@ -163,7 +167,7 @@ fn get_log_dir(config: &cli::Config) -> Result, String> { async fn run_standalone(log_dir: Option) -> Result<(), String> { #[cfg(not(windows))] - cleanup_old_rpc_socket().await; + cleanup_old_rpc_socket(mullvad_paths::get_rpc_socket_path()).await; if !running_as_admin() { log::warn!("Running daemon as a non-administrator user, clients might refuse to connect"); @@ -192,6 +196,7 @@ async fn run_standalone(log_dir: Option) -> Result<(), String> { async fn create_daemon( log_dir: Option, ) -> Result, String> { + let rpc_socket_path = mullvad_paths::get_rpc_socket_path(); let resource_dir = mullvad_paths::get_resource_dir(); let settings_dir = mullvad_paths::settings_dir() .map_err(|e| e.display_chain_with_msg("Unable to get settings dir"))?; @@ -199,7 +204,7 @@ async fn create_daemon( .map_err(|e| e.display_chain_with_msg("Unable to get cache dir"))?; let command_channel = DaemonCommandChannel::new(); - let event_listener = spawn_management_interface(command_channel.sender())?; + let event_listener = spawn_management_interface(command_channel.sender(), rpc_socket_path)?; Daemon::start( log_dir, @@ -215,13 +220,17 @@ async fn create_daemon( fn spawn_management_interface( command_sender: DaemonCommandSender, + rpc_socket_path: impl AsRef, ) -> Result { - let (socket_path, event_broadcaster) = ManagementInterfaceServer::start(command_sender) + let event_broadcaster = ManagementInterfaceServer::start(command_sender, &rpc_socket_path) .map_err(|error| { error.display_chain_with_msg("Unable to start management interface server") })?; - log::info!("Management interface listening on {}", socket_path); + log::info!( + "Management interface listening on {}", + rpc_socket_path.as_ref().display() + ); Ok(event_broadcaster) } diff --git a/mullvad-daemon/src/management_interface.rs b/mullvad-daemon/src/management_interface.rs index d8f18b573297..269432be305b 100644 --- a/mullvad-daemon/src/management_interface.rs +++ b/mullvad-daemon/src/management_interface.rs @@ -21,6 +21,7 @@ use mullvad_types::{ wireguard::{RotationInterval, RotationIntervalError}, }; use std::{ + path::Path, str::FromStr, sync::{Arc, Mutex}, time::Duration, @@ -1024,21 +1025,22 @@ pub struct ManagementInterfaceServer(()); impl ManagementInterfaceServer { pub fn start( tunnel_tx: DaemonCommandSender, - ) -> Result<(String, ManagementInterfaceEventBroadcaster), Error> { + rpc_socket_path: impl AsRef, + ) -> Result { let subscriptions = Arc::>>::default(); - let socket_path = mullvad_paths::get_rpc_socket_path() - .to_string_lossy() - .to_string(); - let (server_abort_tx, server_abort_rx) = mpsc::channel(0); let server = ManagementServiceImpl { daemon_tx: tunnel_tx, subscriptions: subscriptions.clone(), }; - let join_handle = mullvad_management_interface::spawn_rpc_server(server, async move { - server_abort_rx.into_future().await; - }) + let join_handle = mullvad_management_interface::spawn_rpc_server( + server, + async move { + server_abort_rx.into_future().await; + }, + rpc_socket_path, + ) .map_err(Error::SetupError)?; tokio::spawn(async move { @@ -1048,13 +1050,10 @@ impl ManagementInterfaceServer { log::info!("Management interface shut down"); }); - Ok(( - socket_path, - ManagementInterfaceEventBroadcaster { - subscriptions, - _close_handle: server_abort_tx, - }, - )) + Ok(ManagementInterfaceEventBroadcaster { + subscriptions, + _close_handle: server_abort_tx, + }) } } diff --git a/mullvad-jni/Cargo.toml b/mullvad-jni/Cargo.toml index f1432d49d4db..c964c3adc953 100644 --- a/mullvad-jni/Cargo.toml +++ b/mullvad-jni/Cargo.toml @@ -27,9 +27,9 @@ log-panics = "2" nix = "0.23" rand = "0.8.5" +mullvad-api = { path = "../mullvad-api" } mullvad-daemon = { path = "../mullvad-daemon" } mullvad-problem-report = { path = "../mullvad-problem-report" } mullvad-types = { path = "../mullvad-types" } -mullvad-api = { path = "../mullvad-api" } talpid-tunnel = { path = "../talpid-tunnel" } talpid-types = { path = "../talpid-types" } diff --git a/mullvad-jni/src/lib.rs b/mullvad-jni/src/lib.rs index 66588d603ae1..67e40ea5340e 100644 --- a/mullvad-jni/src/lib.rs +++ b/mullvad-jni/src/lib.rs @@ -65,13 +65,15 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_initial env: JNIEnv<'_>, this: JObject<'_>, vpnService: JObject<'_>, + rpcSocketPath: JObject<'_>, + filesDirectory: JObject<'_>, cacheDirectory: JObject<'_>, - resourceDirectory: JObject<'_>, apiEndpoint: JObject<'_>, ) { let env = JnixEnv::from(env); + let rpc_socket = PathBuf::from(String::from_java(&env, rpcSocketPath)); + let files_dir = PathBuf::from(String::from_java(&env, filesDirectory)); let cache_dir = PathBuf::from(String::from_java(&env, cacheDirectory)); - let resource_dir = PathBuf::from(String::from_java(&env, resourceDirectory)); let api_endpoint = if !apiEndpoint.is_null() { #[cfg(feature = "api-override")] @@ -87,7 +89,7 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_initial None }; - match start_logging(&resource_dir) { + match start_logging(&files_dir) { Ok(()) => { version::log_version(); @@ -97,8 +99,9 @@ pub extern "system" fn Java_net_mullvad_mullvadvpn_service_MullvadDaemon_initial &env, &this, &vpnService, + rpc_socket, + files_dir, cache_dir, - resource_dir, api_endpoint, ) { log::error!("{}", error.display_chain()); @@ -224,8 +227,9 @@ fn initialize( env: &JnixEnv<'_>, this: &JObject<'_>, vpn_service: &JObject<'_>, + rpc_socket: PathBuf, + files_dir: PathBuf, cache_dir: PathBuf, - resource_dir: PathBuf, api_endpoint: Option, ) -> Result<(), Error> { let android_context = create_android_context(env, *vpn_service)?; @@ -235,8 +239,9 @@ fn initialize( spawn_daemon( env, this, + rpc_socket, + files_dir, cache_dir, - resource_dir, api_endpoint, daemon_command_channel, android_context, @@ -259,11 +264,13 @@ fn create_android_context( }) } +#[allow(clippy::too_many_arguments)] fn spawn_daemon( env: &JnixEnv<'_>, this: &JObject<'_>, + rpc_socket: PathBuf, + files_dir: PathBuf, cache_dir: PathBuf, - resource_dir: PathBuf, #[cfg_attr(not(feature = "api-override"), allow(unused_variables))] api_endpoint: Option< mullvad_api::ApiEndpoint, >, @@ -298,10 +305,10 @@ fn spawn_daemon( } } - runtime.block_on(cleanup_old_rpc_socket()); + runtime.block_on(cleanup_old_rpc_socket(&rpc_socket)); let event_listener = match runtime - .block_on(async { spawn_management_interface(command_channel.sender()) }) + .block_on(async { spawn_management_interface(command_channel.sender(), &rpc_socket) }) { Ok(event_listener) => event_listener, Err(error) => { @@ -311,9 +318,9 @@ fn spawn_daemon( }; let daemon = runtime.block_on(Daemon::start( - Some(resource_dir.clone()), - resource_dir.clone(), - resource_dir, + Some(files_dir.clone()), + files_dir.clone(), + files_dir, cache_dir, event_listener, command_channel, @@ -348,8 +355,9 @@ use mullvad_daemon::{ fn spawn_management_interface( command_sender: DaemonCommandSender, + rpc_socket_path: impl AsRef, ) -> Result { - let (socket_path, event_broadcaster) = ManagementInterfaceServer::start(command_sender) + let event_broadcaster = ManagementInterfaceServer::start(command_sender, &rpc_socket_path) .map_err(|error| { log::error!( "{}", @@ -358,7 +366,10 @@ fn spawn_management_interface( Error::SpawnManagementInterface(error) })?; - log::info!("Management interface listening on {}", socket_path); + log::info!( + "Management interface listening on {}", + rpc_socket_path.as_ref().display() + ); Ok(event_broadcaster) } diff --git a/mullvad-management-interface/src/client.rs b/mullvad-management-interface/src/client.rs index 35ffb57622a4..6a3b794b3979 100644 --- a/mullvad-management-interface/src/client.rs +++ b/mullvad-management-interface/src/client.rs @@ -1,32 +1,43 @@ //! Client that returns and takes mullvad types as arguments instead of prost-generated types use crate::types; +#[cfg(not(target_os = "android"))] use futures::{Stream, StreamExt}; #[cfg(target_os = "windows")] use mullvad_types::wireguard::DaitaSettings; use mullvad_types::{ - access_method::{self, AccessMethod, AccessMethodSetting}, + access_method::AccessMethodSetting, + device::{DeviceEvent, RemoveDeviceEvent}, + relay_list::RelayList, + settings::Settings, + states::TunnelState, + version::AppVersionInfo, +}; + +#[cfg(not(target_os = "android"))] +use mullvad_types::{ + access_method::{self, AccessMethod}, account::{AccountData, AccountToken, VoucherSubmission}, custom_list::{CustomList, Id}, - device::{Device, DeviceEvent, DeviceId, DeviceState, RemoveDeviceEvent}, + device::{Device, DeviceId, DeviceState}, relay_constraints::{ BridgeSettings, BridgeState, ObfuscationSettings, RelayOverride, RelaySettings, }, - relay_list::RelayList, - settings::{DnsOptions, Settings}, - states::TunnelState, - version::AppVersionInfo, + settings::DnsOptions, wireguard::{PublicKey, QuantumResistantState, RotationInterval}, }; +#[cfg(not(target_os = "android"))] use std::{path::Path, str::FromStr}; #[cfg(target_os = "windows")] use talpid_types::split_tunnel::ExcludedProcess; +#[cfg(not(target_os = "android"))] use tonic::{Code, Status}; type Error = super::Error; pub type Result = std::result::Result; +#[cfg(not(target_os = "android"))] #[derive(Debug, Clone)] pub struct MullvadProxyClient(crate::ManagementServiceClient); @@ -73,6 +84,7 @@ impl TryFrom for DaemonEvent { } } +#[cfg(not(target_os = "android"))] impl MullvadProxyClient { pub async fn new() -> Result { #[allow(deprecated)] @@ -712,6 +724,7 @@ impl MullvadProxyClient { } } +#[cfg(not(target_os = "android"))] fn map_device_error(status: Status) -> Error { match status.code() { Code::ResourceExhausted => Error::TooManyDevices, @@ -722,6 +735,7 @@ fn map_device_error(status: Status) -> Error { } } +#[cfg(not(target_os = "android"))] fn map_custom_list_error(status: Status) -> Error { match status.code() { Code::NotFound => { diff --git a/mullvad-management-interface/src/lib.rs b/mullvad-management-interface/src/lib.rs index 763d2474ecc7..43b9974d59e0 100644 --- a/mullvad-management-interface/src/lib.rs +++ b/mullvad-management-interface/src/lib.rs @@ -11,7 +11,10 @@ use std::{ task::{Context, Poll}, }; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; -use tonic::transport::{server::Connected, Endpoint, Server, Uri}; +use tonic::transport::{server::Connected, Server}; +#[cfg(not(target_os = "android"))] +use tonic::transport::{Endpoint, Uri}; +#[cfg(not(target_os = "android"))] use tower::service_fn; pub use tonic::{async_trait, transport::Channel, Code, Request, Response, Status}; @@ -111,6 +114,7 @@ pub enum Error { ApiAccessMethodNotFound, } +#[cfg(not(target_os = "android"))] #[deprecated(note = "Prefer MullvadProxyClient")] pub async fn new_rpc_client() -> Result { let ipc_path = mullvad_paths::get_rpc_socket_path(); @@ -126,6 +130,7 @@ pub async fn new_rpc_client() -> Result { Ok(ManagementServiceClient::new(channel)) } +#[cfg(not(target_os = "android"))] pub use client::MullvadProxyClient; pub type ServerJoinHandle = tokio::task::JoinHandle>; @@ -133,13 +138,12 @@ pub type ServerJoinHandle = tokio::task::JoinHandle>; pub fn spawn_rpc_server + Send + 'static>( service: T, abort_rx: F, + rpc_socket_path: impl AsRef, ) -> std::result::Result { use futures::stream::TryStreamExt; use parity_tokio_ipc::SecurityAttributes; - let socket_path = mullvad_paths::get_rpc_socket_path(); - - let mut endpoint = IpcEndpoint::new(socket_path.to_string_lossy().to_string()); + let mut endpoint = IpcEndpoint::new(rpc_socket_path.as_ref().to_string_lossy().to_string()); endpoint.set_security_attributes( SecurityAttributes::allow_everyone_create() .map_err(Error::SecurityAttributes)? @@ -153,8 +157,9 @@ pub fn spawn_rpc_server + Send + 's 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)) + nix::unistd::chown(rpc_socket_path.as_ref(), None, Some(group.gid)) + .map_err(Error::SetGidError)?; + fs::set_permissions(rpc_socket_path, PermissionsExt::from_mode(0o760)) .map_err(Error::PermissionsError)?; } diff --git a/mullvad-paths/Cargo.toml b/mullvad-paths/Cargo.toml index 32f47efdaa7d..4a62bedde713 100644 --- a/mullvad-paths/Cargo.toml +++ b/mullvad-paths/Cargo.toml @@ -12,8 +12,6 @@ workspace = true [dependencies] thiserror = { workspace = true } - -[target.'cfg(not(target_os="android"))'.dependencies] log = { workspace = true } [target.'cfg(windows)'.dependencies] diff --git a/mullvad-paths/src/cache.rs b/mullvad-paths/src/cache.rs index cbd110cd59a0..dfd7a46cae70 100644 --- a/mullvad-paths/src/cache.rs +++ b/mullvad-paths/src/cache.rs @@ -20,28 +20,22 @@ pub fn get_cache_dir() -> Result { } } +#[cfg(target_os = "linux")] pub fn get_default_cache_dir() -> Result { - #[cfg(not(target_os = "android"))] - { - let dir; - #[cfg(target_os = "linux")] - { - dir = PathBuf::from("/var/cache").join(crate::PRODUCT_NAME); - } - #[cfg(windows)] - { - dir = crate::get_allusersprofile_dir()? - .join(crate::PRODUCT_NAME) - .join("cache"); - } - #[cfg(target_os = "macos")] - { - dir = std::path::Path::new("/Library/Caches").join(crate::PRODUCT_NAME); - } - Ok(dir) - } - #[cfg(target_os = "android")] - { - Ok(std::path::Path::new(crate::APP_PATH).join("cache")) - } + let dir = PathBuf::from("/var/cache").join(crate::PRODUCT_NAME); + Ok(dir) +} + +#[cfg(windows)] +pub fn get_default_cache_dir() -> Result { + let dir = crate::get_allusersprofile_dir()? + .join(crate::PRODUCT_NAME) + .join("cache"); + Ok(dir) +} + +#[cfg(target_os = "macos")] +pub fn get_default_cache_dir() -> Result { + let dir = std::path::Path::new("/Library/Caches").join(crate::PRODUCT_NAME); + Ok(dir) } diff --git a/mullvad-paths/src/lib.rs b/mullvad-paths/src/lib.rs index 3cd58a6a51be..05641360c024 100644 --- a/mullvad-paths/src/lib.rs +++ b/mullvad-paths/src/lib.rs @@ -1,4 +1,6 @@ -#[cfg(not(target_os = "windows"))] +#![cfg(not(target_os = "android"))] + +#[cfg(any(target_os = "linux", target_os = "macos"))] use std::fs; use std::{io, path::PathBuf}; @@ -26,6 +28,9 @@ pub enum Error { #[cfg(windows)] #[error("Failed to create security attributes")] GetSecurityAttributes(#[source] io::Error), + + #[error("Device data directory has not been set")] + NoDataDir, } #[cfg(any(target_os = "linux", target_os = "macos"))] @@ -34,9 +39,6 @@ const PRODUCT_NAME: &str = "mullvad-vpn"; #[cfg(windows)] pub const PRODUCT_NAME: &str = "Mullvad VPN"; -#[cfg(target_os = "android")] -const APP_PATH: &str = "/data/data/net.mullvad.mullvadvpn"; - #[cfg(windows)] fn get_allusersprofile_dir() -> Result { match std::env::var_os("ALLUSERSPROFILE") { @@ -45,7 +47,7 @@ fn get_allusersprofile_dir() -> Result { } } -#[cfg(not(target_os = "windows"))] +#[cfg(any(target_os = "linux", target_os = "macos"))] fn create_and_return( dir_fn: fn() -> Result, permissions: Option, diff --git a/mullvad-paths/src/logs.rs b/mullvad-paths/src/logs.rs index d7f2c58f95d7..53f776358954 100644 --- a/mullvad-paths/src/logs.rs +++ b/mullvad-paths/src/logs.rs @@ -1,7 +1,4 @@ use crate::Result; - -#[cfg(unix)] -use std::os::unix::fs::PermissionsExt; use std::{env, path::PathBuf}; /// Creates and returns the logging directory pointed to by `MULLVAD_LOG_DIR`, or the default @@ -9,6 +6,7 @@ use std::{env, path::PathBuf}; pub fn log_dir() -> Result { #[cfg(unix)] { + use std::os::unix::fs::PermissionsExt; let permissions = Some(PermissionsExt::from_mode(0o755)); crate::create_and_return(get_log_dir, permissions) } @@ -26,22 +24,14 @@ pub fn get_log_dir() -> Result { } } +#[cfg(unix)] pub fn get_default_log_dir() -> Result { - #[cfg(not(target_os = "android"))] - { - let dir; - #[cfg(unix)] - { - dir = Ok(PathBuf::from("/var/log")); - } - #[cfg(windows)] - { - dir = crate::get_allusersprofile_dir(); - } - dir.map(|dir| dir.join(crate::PRODUCT_NAME)) - } - #[cfg(target_os = "android")] - { - Ok(PathBuf::from(crate::APP_PATH)) - } + let dir = PathBuf::from("/var/log").join(crate::PRODUCT_NAME); + Ok(dir) +} + +#[cfg(windows)] +pub fn get_default_log_dir() -> Result { + let dir = crate::get_allusersprofile_dir()?.join(crate::PRODUCT_NAME); + Ok(dir) } diff --git a/mullvad-paths/src/resources.rs b/mullvad-paths/src/resources.rs index ed6845bdf08f..533e25217112 100644 --- a/mullvad-paths/src/resources.rs +++ b/mullvad-paths/src/resources.rs @@ -8,24 +8,17 @@ pub fn get_resource_dir() -> PathBuf { } pub fn get_default_resource_dir() -> PathBuf { - #[cfg(not(target_os = "android"))] - { - match env::current_exe() { - Ok(mut path) => { - path.pop(); - path - } - Err(e) => { - log::error!( - "Failed finding the install directory. Using working directory: {}", - e - ); - PathBuf::from(".") - } + match env::current_exe() { + Ok(mut path) => { + path.pop(); + path + } + Err(e) => { + log::error!( + "Failed finding the install directory. Using working directory: {}", + e + ); + PathBuf::from(".") } - } - #[cfg(target_os = "android")] - { - PathBuf::from(crate::APP_PATH) } } diff --git a/mullvad-paths/src/rpc_socket.rs b/mullvad-paths/src/rpc_socket.rs index 8d8bf395f34a..80eb4360d259 100644 --- a/mullvad-paths/src/rpc_socket.rs +++ b/mullvad-paths/src/rpc_socket.rs @@ -1,7 +1,7 @@ -use std::{env, path::PathBuf}; +use std::path::PathBuf; pub fn get_rpc_socket_path() -> PathBuf { - match env::var_os("MULLVAD_RPC_SOCKET_PATH") { + match std::env::var_os("MULLVAD_RPC_SOCKET_PATH") { Some(path) => PathBuf::from(path), None => get_default_rpc_socket_path(), } @@ -16,8 +16,3 @@ pub fn get_default_rpc_socket_path() -> PathBuf { pub fn get_default_rpc_socket_path() -> PathBuf { PathBuf::from("//./pipe/Mullvad VPN") } - -#[cfg(target_os = "android")] -pub fn get_default_rpc_socket_path() -> PathBuf { - PathBuf::from(format!("{}/rpc-socket", crate::APP_PATH)) -} diff --git a/mullvad-paths/src/settings.rs b/mullvad-paths/src/settings.rs index 266721140698..d6ebabe6e744 100644 --- a/mullvad-paths/src/settings.rs +++ b/mullvad-paths/src/settings.rs @@ -22,24 +22,19 @@ fn get_settings_dir() -> Result { } } -#[cfg(not(target_os = "android"))] +#[cfg(windows)] pub fn get_default_settings_dir() -> Result { - let dir; - #[cfg(unix)] - { - dir = Ok(PathBuf::from("/etc")); - } - #[cfg(windows)] - { - dir = crate::windows::get_system_service_appdata().map_err(|error| { + let dir = crate::windows::get_system_service_appdata() + .map_err(|error| { log::error!("Failed to obtain system app data path: {error}"); crate::Error::FindDirError - }) - } - dir.map(|dir| dir.join(crate::PRODUCT_NAME)) + })? + .join(crate::PRODUCT_NAME); + Ok(dir) } -#[cfg(target_os = "android")] +#[cfg(unix)] pub fn get_default_settings_dir() -> Result { - Ok(PathBuf::from(crate::APP_PATH)) + let dir = PathBuf::from("/etc").join(crate::PRODUCT_NAME); + Ok(dir) } diff --git a/mullvad-problem-report/src/lib.rs b/mullvad-problem-report/src/lib.rs index fc8306a8f1f7..74076a8b5a7b 100644 --- a/mullvad-problem-report/src/lib.rs +++ b/mullvad-problem-report/src/lib.rs @@ -72,6 +72,7 @@ pub enum Error { #[error("Unable to spawn Tokio runtime")] CreateRuntime(#[source] io::Error), + #[cfg(not(target_os = "android"))] #[error("Unable to find cache directory")] ObtainCacheDirectory(#[source] mullvad_paths::Error), } @@ -81,6 +82,7 @@ pub enum Error { /// instead of whatever content was supposed to be there. #[derive(thiserror::Error, Debug)] pub enum LogError { + #[cfg(not(target_os = "android"))] #[error("Unable to get log directory")] GetLogDir(#[source] mullvad_paths::Error),