From 42c709e7b1647ec240e1b1356be58f99b86d8073 Mon Sep 17 00:00:00 2001 From: link2xt Date: Wed, 18 Jan 2023 10:12:18 +0000 Subject: [PATCH] Fix SOCKS5 usage for IMAP Connect to SOCKS5 server rather than target server and send TCP connect command. --- CHANGELOG.md | 1 + src/imap.rs | 2 +- src/imap/client.rs | 17 +++++++---------- src/socks.rs | 15 +++++++++++---- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c53a141f9..850a05104 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ unread messages increases #3959 - Fix Peerstate comparison #3962 - Log SOCKS5 configuration for IMAP like already done for SMTP #3964 +- Fix SOCKS5 usage for IMAP #3965 ### API-Changes - jsonrpc: add verified-by information to `Contact`-Object diff --git a/src/imap.rs b/src/imap.rs index f8b75574f..0d91da8f7 100644 --- a/src/imap.rs +++ b/src/imap.rs @@ -315,7 +315,7 @@ impl Imap { ) .await } else { - Client::connect_insecure_socks5((imap_server, imap_port), socks5_config.clone()) + Client::connect_insecure_socks5(imap_server, imap_port, socks5_config.clone()) .await } } else if config.lp.security == Socket::Starttls { diff --git a/src/imap/client.rs b/src/imap/client.rs index 74624a119..f4eacd6dc 100644 --- a/src/imap/client.rs +++ b/src/imap/client.rs @@ -124,8 +124,7 @@ impl Client { let tcp_stream = connect_tcp((hostname, port), IMAP_TIMEOUT).await?; // Run STARTTLS command and convert the client back into a stream. - let session_stream: Box = Box::new(tcp_stream); - let mut client = ImapClient::new(session_stream); + let mut client = ImapClient::new(tcp_stream); let _greeting = client .read_response() .await @@ -155,7 +154,7 @@ impl Client { strict_tls: bool, socks5_config: Socks5Config, ) -> Result { - let socks5_stream = socks5_config.connect((domain, port), IMAP_TIMEOUT).await?; + let socks5_stream = socks5_config.connect(domain, port, IMAP_TIMEOUT).await?; let tls = build_tls(strict_tls); let tls_stream = tls.connect(domain, socks5_stream).await?; let buffered_stream = BufWriter::new(tls_stream); @@ -170,10 +169,11 @@ impl Client { } pub async fn connect_insecure_socks5( - target_addr: impl ToSocketAddrs, + domain: &str, + port: u16, socks5_config: Socks5Config, ) -> Result { - let socks5_stream = socks5_config.connect(target_addr, IMAP_TIMEOUT).await?; + let socks5_stream = socks5_config.connect(domain, port, IMAP_TIMEOUT).await?; let buffered_stream = BufWriter::new(socks5_stream); let session_stream: Box = Box::new(buffered_stream); let mut client = ImapClient::new(session_stream); @@ -191,13 +191,10 @@ impl Client { socks5_config: Socks5Config, strict_tls: bool, ) -> Result { - let socks5_stream = socks5_config - .connect((hostname, port), IMAP_TIMEOUT) - .await?; + let socks5_stream = socks5_config.connect(hostname, port, IMAP_TIMEOUT).await?; // Run STARTTLS command and convert the client back into a stream. - let session_stream: Box = Box::new(socks5_stream); - let mut client = ImapClient::new(session_stream); + let mut client = ImapClient::new(socks5_stream); let _greeting = client .read_response() .await diff --git a/src/socks.rs b/src/socks.rs index e7ea20730..4dd1ffcc5 100644 --- a/src/socks.rs +++ b/src/socks.rs @@ -7,12 +7,14 @@ use std::time::Duration; use crate::net::connect_tcp; use anyhow::Result; pub use async_smtp::ServerAddress; -use tokio::net::{self, TcpStream}; +use tokio::net::TcpStream; use tokio_io_timeout::TimeoutStream; use crate::context::Context; use fast_socks5::client::{Config, Socks5Stream}; +use fast_socks5::util::target_addr::ToTargetAddr; use fast_socks5::AuthenticationMethod; +use fast_socks5::Socks5Command; #[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct Socks5Config { @@ -56,10 +58,11 @@ impl Socks5Config { pub async fn connect( &self, - target_addr: impl net::ToSocketAddrs, + target_host: &str, + target_port: u16, timeout_val: Duration, ) -> Result>>>> { - let tcp_stream = connect_tcp(target_addr, timeout_val).await?; + let tcp_stream = connect_tcp((self.host.clone(), self.port), timeout_val).await?; let authentication_method = if let Some((username, password)) = self.user_password.as_ref() { @@ -70,8 +73,12 @@ impl Socks5Config { } else { None }; - let socks_stream = + let mut socks_stream = Socks5Stream::use_stream(tcp_stream, authentication_method, Config::default()).await?; + let target_addr = (target_host, target_port).to_target_addr()?; + socks_stream + .request(Socks5Command::TCPConnect, target_addr) + .await?; Ok(socks_stream) }