summaryrefslogtreecommitdiffhomepage
path: root/mullvad-api/src
diff options
context:
space:
mode:
authorJonathan <jonathan@mullvad.net>2023-12-05 10:03:08 +0100
committerJonathan <jonathan@mullvad.net>2024-01-03 14:38:41 +0100
commit4fdc34acbba60d5092e45ce3e513d30ec996c317 (patch)
tree80d3a23c1a96bd3d80e05ac66b530e39c252d48a /mullvad-api/src
parentc510df96772b1e4ab7998e739ced42806c78e931 (diff)
downloadmullvadvpn-4fdc34acbba60d5092e45ce3e513d30ec996c317.tar.xz
mullvadvpn-4fdc34acbba60d5092e45ce3e513d30ec996c317.zip
Allow app to use custom socks5 and shadwosocks proxies
This PR has a couple of different purposes - Allow users to use socks5 local proxies with the CLI without having to be root nor use split-tunneling. This only works for OpenVPN. - Unify the types used by different proxy parts of the codebase, such as the Access Methods as well as some already existing OpenVPN proxy code. This PR changes the firewall on all desktop platforms as well as changes the routing table slightly on MacOS and Windows. On Linux the firewall code is modified to apply the appropriate firewall marks to all packages that go to a remote endpoint corresponding to the remote part of a local socks5 proxy. The firewall marks will allow the routing to be done without having to modify the routing table. On MacOS and Windows the routing table is modified to allow packages to go to that same endpoint to pass outside the VPN tunnel, it will additionally punch a hole in the firewall. The PR also migrates the settings file from version 7 to version 8 in order to properly and neatly unify Proxy related types. Finally it provides some slight extensions to the gRPC interface in order to allow for control over the custom proxy settings.
Diffstat (limited to 'mullvad-api/src')
-rw-r--r--mullvad-api/src/https_client_with_sni.rs43
-rw-r--r--mullvad-api/src/proxy.rs37
2 files changed, 33 insertions, 47 deletions
diff --git a/mullvad-api/src/https_client_with_sni.rs b/mullvad-api/src/https_client_with_sni.rs
index 7d559faa7a..3a9bb8d75f 100644
--- a/mullvad-api/src/https_client_with_sni.rs
+++ b/mullvad-api/src/https_client_with_sni.rs
@@ -236,15 +236,15 @@ impl TryFrom<ApiConnectionMode> for InnerConnectionMode {
type Error = ProxyConfigError;
fn try_from(config: ApiConnectionMode) -> Result<Self, Self::Error> {
- use mullvad_types::access_method;
use std::net::Ipv4Addr;
+ use talpid_types::net::proxy;
Ok(match config {
ApiConnectionMode::Direct => InnerConnectionMode::Direct,
ApiConnectionMode::Proxied(proxy_settings) => match proxy_settings {
ProxyConfig::Shadowsocks(config) => {
InnerConnectionMode::Shadowsocks(ShadowsocksConfig {
params: ParsedShadowsocksConfig {
- peer: config.peer,
+ peer: config.endpoint,
password: config.password,
cipher: CipherKind::from_str(&config.cipher)
.map_err(|_| ProxyConfigError::InvalidCipher(config.cipher))?,
@@ -252,29 +252,22 @@ impl TryFrom<ApiConnectionMode> for InnerConnectionMode {
proxy_context: SsContext::new_shared(ServerType::Local),
})
}
- ProxyConfig::Socks(config) => match config {
- access_method::Socks5::Local(config) => {
- InnerConnectionMode::Socks5(SocksConfig {
- peer: SocketAddr::new(
- IpAddr::from(Ipv4Addr::LOCALHOST),
- config.local_port,
- ),
- authentication: SocksAuth::None,
- })
- }
- access_method::Socks5::Remote(config) => {
- let authentication = match config.authentication {
- Some(access_method::SocksAuth { username, password }) => {
- SocksAuth::Password { username, password }
- }
- None => SocksAuth::None,
- };
- InnerConnectionMode::Socks5(SocksConfig {
- peer: config.peer,
- authentication,
- })
- }
- },
+ ProxyConfig::Socks5Local(config) => InnerConnectionMode::Socks5(SocksConfig {
+ peer: SocketAddr::new(IpAddr::from(Ipv4Addr::LOCALHOST), config.local_port),
+ authentication: SocksAuth::None,
+ }),
+ ProxyConfig::Socks5Remote(config) => {
+ let authentication = match config.auth {
+ Some(proxy::SocksAuth { username, password }) => {
+ SocksAuth::Password { username, password }
+ }
+ None => SocksAuth::None,
+ };
+ InnerConnectionMode::Socks5(SocksConfig {
+ peer: config.endpoint,
+ authentication,
+ })
+ }
},
})
}
diff --git a/mullvad-api/src/proxy.rs b/mullvad-api/src/proxy.rs
index 783cc8a157..caf2068abb 100644
--- a/mullvad-api/src/proxy.rs
+++ b/mullvad-api/src/proxy.rs
@@ -1,6 +1,5 @@
use futures::Stream;
use hyper::client::connect::Connected;
-use mullvad_types::access_method;
use serde::{Deserialize, Serialize};
use std::{
fmt, io,
@@ -8,6 +7,7 @@ use std::{
pin::Pin,
task::{self, Poll},
};
+use talpid_types::net::proxy;
use talpid_types::{
net::{AllowedClients, Endpoint, TransportProtocol},
ErrorExt,
@@ -38,8 +38,9 @@ impl fmt::Display for ApiConnectionMode {
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum ProxyConfig {
- Shadowsocks(access_method::Shadowsocks),
- Socks(access_method::Socks5),
+ Shadowsocks(proxy::Shadowsocks),
+ Socks5Local(proxy::Socks5Local),
+ Socks5Remote(proxy::Socks5Remote),
}
impl ProxyConfig {
@@ -47,14 +48,12 @@ impl ProxyConfig {
fn get_endpoint(&self) -> Endpoint {
match self {
ProxyConfig::Shadowsocks(shadowsocks) => {
- Endpoint::from_socket_address(shadowsocks.peer, TransportProtocol::Tcp)
+ Endpoint::from_socket_address(shadowsocks.endpoint, TransportProtocol::Tcp)
+ }
+ ProxyConfig::Socks5Local(local) => local.remote_endpoint,
+ ProxyConfig::Socks5Remote(remote) => {
+ Endpoint::from_socket_address(remote.endpoint, TransportProtocol::Tcp)
}
- ProxyConfig::Socks(socks) => match socks {
- access_method::Socks5::Local(local) => local.remote_endpoint,
- access_method::Socks5::Remote(remote) => {
- Endpoint::from_socket_address(remote.peer, TransportProtocol::Tcp)
- }
- },
}
}
}
@@ -64,12 +63,10 @@ impl fmt::Display for ProxyConfig {
let endpoint = self.get_endpoint();
match self {
ProxyConfig::Shadowsocks(_) => write!(f, "Shadowsocks {}", endpoint),
- ProxyConfig::Socks(socks) => match socks {
- access_method::Socks5::Remote(_) => write!(f, "Socks5 {}", endpoint),
- access_method::Socks5::Local(local) => {
- write!(f, "Socks5 {} via localhost:{}", endpoint, local.local_port)
- }
- },
+ ProxyConfig::Socks5Remote(_) => write!(f, "Socks5 {}", endpoint),
+ ProxyConfig::Socks5Local(local) => {
+ write!(f, "Socks5 {} via localhost:{}", endpoint, local.local_port)
+ }
}
}
}
@@ -145,20 +142,16 @@ impl ApiConnectionMode {
#[cfg(unix)]
pub fn allowed_clients(&self) -> AllowedClients {
- use access_method::Socks5;
match self {
- ApiConnectionMode::Proxied(ProxyConfig::Socks(Socks5::Local(_))) => AllowedClients::All,
+ ApiConnectionMode::Proxied(ProxyConfig::Socks5Local(_)) => AllowedClients::All,
ApiConnectionMode::Direct | ApiConnectionMode::Proxied(_) => AllowedClients::Root,
}
}
#[cfg(windows)]
pub fn allowed_clients(&self) -> AllowedClients {
- use access_method::Socks5;
match self {
- ApiConnectionMode::Proxied(ProxyConfig::Socks(Socks5::Local(_))) => {
- AllowedClients::all()
- }
+ ApiConnectionMode::Proxied(ProxyConfig::Socks5Local(_)) => AllowedClients::all(),
ApiConnectionMode::Direct | ApiConnectionMode::Proxied(_) => {
let daemon_exe = std::env::current_exe().expect("failed to obtain executable path");
vec![