mirror of
https://github.com/chatmail/core.git
synced 2026-04-25 01:16:29 +03:00
Implement socks5 support
This adds following settings: - Socks5Enabled - Socks5Host - Socks5Port - Socks5User - Socks5Password Currently http requests and dns requests are not getting executed as they currently can't get tunneled through socks5 proxy. Therefore gmail with oauth2 wont work through tor.
This commit is contained in:
@@ -1,16 +1,24 @@
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::{
|
||||
ops::{Deref, DerefMut},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use async_imap::{
|
||||
error::{Error as ImapError, Result as ImapResult},
|
||||
Client as ImapClient,
|
||||
};
|
||||
|
||||
use async_smtp::ServerAddress;
|
||||
use async_std::net::{self, TcpStream};
|
||||
|
||||
use super::session::Session;
|
||||
use crate::login_param::dc_build_tls;
|
||||
use crate::login_param::{dc_build_tls, Socks5Config};
|
||||
|
||||
use super::session::SessionStream;
|
||||
|
||||
/// IMAP write and read timeout in seconds.
|
||||
const IMAP_TIMEOUT: u64 = 30;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Client {
|
||||
is_secure: bool,
|
||||
@@ -111,6 +119,63 @@ impl Client {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn connect_secure_socks5(
|
||||
target_addr: &ServerAddress,
|
||||
strict_tls: bool,
|
||||
socks5_config: Socks5Config,
|
||||
) -> ImapResult<Self> {
|
||||
let socks5_stream: Box<dyn SessionStream> = Box::new(
|
||||
match socks5_config
|
||||
.connect(target_addr, Some(Duration::from_secs(IMAP_TIMEOUT)))
|
||||
.await
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(e) => return ImapResult::Err(async_imap::error::Error::Bad(e.to_string())),
|
||||
},
|
||||
);
|
||||
|
||||
let tls = dc_build_tls(strict_tls);
|
||||
let tls_stream: Box<dyn SessionStream> =
|
||||
Box::new(tls.connect(target_addr.host.clone(), socks5_stream).await?);
|
||||
let mut client = ImapClient::new(tls_stream);
|
||||
|
||||
let _greeting = client
|
||||
.read_response()
|
||||
.await
|
||||
.ok_or_else(|| ImapError::Bad("failed to read greeting".to_string()))?;
|
||||
|
||||
Ok(Client {
|
||||
is_secure: true,
|
||||
inner: client,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn connect_insecure_socks5(
|
||||
target_addr: &ServerAddress,
|
||||
socks5_config: Socks5Config,
|
||||
) -> ImapResult<Self> {
|
||||
let socks5_stream: Box<dyn SessionStream> = Box::new(
|
||||
match socks5_config
|
||||
.connect(target_addr, Some(Duration::from_secs(IMAP_TIMEOUT)))
|
||||
.await
|
||||
{
|
||||
Ok(s) => s,
|
||||
Err(e) => return ImapResult::Err(async_imap::error::Error::Bad(e.to_string())),
|
||||
},
|
||||
);
|
||||
|
||||
let mut client = ImapClient::new(socks5_stream);
|
||||
let _greeting = client
|
||||
.read_response()
|
||||
.await
|
||||
.ok_or_else(|| ImapError::Bad("failed to read greeting".to_string()))?;
|
||||
|
||||
Ok(Client {
|
||||
is_secure: false,
|
||||
inner: client,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn secure(self, domain: &str, strict_tls: bool) -> ImapResult<Client> {
|
||||
if self.is_secure {
|
||||
Ok(self)
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::ops::{Deref, DerefMut};
|
||||
use async_imap::Session as ImapSession;
|
||||
use async_native_tls::TlsStream;
|
||||
use async_std::net::TcpStream;
|
||||
use fast_socks5::client::Socks5Stream;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Session {
|
||||
@@ -17,6 +18,7 @@ pub(crate) trait SessionStream:
|
||||
impl SessionStream for TlsStream<Box<dyn SessionStream>> {}
|
||||
impl SessionStream for TlsStream<TcpStream> {}
|
||||
impl SessionStream for TcpStream {}
|
||||
impl SessionStream for Socks5Stream<TcpStream> {}
|
||||
|
||||
impl Deref for Session {
|
||||
type Target = ImapSession<Box<dyn SessionStream>>;
|
||||
|
||||
Reference in New Issue
Block a user