summaryrefslogtreecommitdiffhomepage
path: root/mullvad-api/src
diff options
context:
space:
mode:
authorMarkus Pettersson <markus.pettersson@mullvad.net>2023-09-28 10:41:31 +0200
committerDavid Lönnhager <david.l@mullvad.net>2023-10-09 14:40:15 +0200
commitccc5aaaff23291366b4c0074f57a5096b94cdfce (patch)
treedd30da0b9ac7b1650cb72bbdae6372924a7c18dd /mullvad-api/src
parent998fd39aaebc1435065f1f4886f4bd40f5889e5a (diff)
downloadmullvadvpn-ccc5aaaff23291366b4c0074f57a5096b94cdfce.tar.xz
mullvadvpn-ccc5aaaff23291366b4c0074f57a5096b94cdfce.zip
Add authentication with username+password for SOCKS5 access method
Add the option to authenticate against remote SOCKS5 proxies with a username+password combination. It was an oversight that this was not added from the start.
Diffstat (limited to 'mullvad-api/src')
-rw-r--r--mullvad-api/src/https_client_with_sni.rs47
1 files changed, 38 insertions, 9 deletions
diff --git a/mullvad-api/src/https_client_with_sni.rs b/mullvad-api/src/https_client_with_sni.rs
index 47b6923d37..17d9f7f0d8 100644
--- a/mullvad-api/src/https_client_with_sni.rs
+++ b/mullvad-api/src/https_client_with_sni.rs
@@ -125,11 +125,21 @@ impl InnerConnectionMode {
InnerConnectionMode::Socks5(socks) => {
let first_hop = socks.peer;
let make_proxy_stream = |tcp_stream| async {
- tokio_socks::tcp::Socks5Stream::connect_with_socket(tcp_stream, addr)
- .await
- .map_err(|error| {
- io::Error::new(io::ErrorKind::Other, format!("SOCKS error: {error}"))
- })
+ match socks.authentication {
+ SocksAuth::None => {
+ tokio_socks::tcp::Socks5Stream::connect_with_socket(tcp_stream, addr)
+ .await
+ }
+ SocksAuth::Password { username, password } => {
+ tokio_socks::tcp::Socks5Stream::connect_with_password_and_socket(
+ tcp_stream, addr, &username, &password,
+ )
+ .await
+ }
+ }
+ .map_err(|error| {
+ io::Error::new(io::ErrorKind::Other, format!("SOCKS error: {error}"))
+ })
};
Self::connect_proxied(
first_hop,
@@ -207,6 +217,13 @@ impl From<ParsedShadowsocksConfig> for ServerConfig {
#[derive(Clone)]
struct SocksConfig {
peer: SocketAddr,
+ authentication: SocksAuth,
+}
+
+#[derive(Clone)]
+pub enum SocksAuth {
+ None,
+ Password { username: String, password: String },
}
#[derive(err_derive::Error, Debug)]
@@ -219,6 +236,8 @@ 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;
Ok(match config {
ApiConnectionMode::Direct => InnerConnectionMode::Direct,
ApiConnectionMode::Proxied(proxy_settings) => match proxy_settings {
@@ -234,13 +253,23 @@ impl TryFrom<ApiConnectionMode> for InnerConnectionMode {
})
}
ProxyConfig::Socks(config) => match config {
- mullvad_types::access_method::Socks5::Local(config) => {
+ access_method::Socks5::Local(config) => {
InnerConnectionMode::Socks5(SocksConfig {
- peer: SocketAddr::new("127.0.0.1".parse().unwrap(), config.port),
+ peer: SocketAddr::new(IpAddr::from(Ipv4Addr::LOCALHOST), config.port),
+ authentication: SocksAuth::None,
})
}
- mullvad_types::access_method::Socks5::Remote(config) => {
- InnerConnectionMode::Socks5(SocksConfig { peer: config.peer })
+ 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,
+ })
}
},
},