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:
Jikstra
2021-08-22 19:55:38 +02:00
committed by GitHub
parent a163be9248
commit 90703b0dd2
16 changed files with 355 additions and 42 deletions

View File

@@ -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)