tor.rs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. use async_std::{
  2. net::{TcpListener, TcpStream},
  3. sync::Arc,
  4. };
  5. use std::{
  6. io,
  7. io::{BufRead, BufReader, Write},
  8. net::SocketAddr,
  9. pin::Pin,
  10. time::Duration,
  11. };
  12. use async_trait::async_trait;
  13. use fast_socks5::{
  14. client::{Config, Socks5Stream},
  15. Result, SocksError,
  16. };
  17. use futures::prelude::*;
  18. use regex::Regex;
  19. use socket2::{Domain, Socket, Type};
  20. use url::Url;
  21. use super::{Transport, TransportError};
  22. /// Implements communication through the tor proxy service.
  23. ///
  24. /// ## Dialing
  25. ///
  26. /// The tor service must be running for dialing to work. Url of it has to be passed to the
  27. /// constructor.
  28. ///
  29. /// ## Listening
  30. ///
  31. /// Two ways of setting up hidden services are allowed: hidden services manually set up by the user
  32. /// in the torc file or ephemereal hidden services created and deleted on the fly. For the latter,
  33. /// the user must set up the tor control port[^controlport].
  34. ///
  35. /// Having manually configured services forces the program to use pre-defined ports, i.e. it has no
  36. /// way of changing them.
  37. ///
  38. /// Before calling [listen_on][transportlisten] on a local address, make sure that either a hidden
  39. /// service pointing to that address was configured or that [create_ehs][torcreateehs] was called
  40. /// with this address.
  41. ///
  42. /// [^controlport] [Open control port](https://wiki.archlinux.org/title/tor#Open_Tor_ControlPort)
  43. ///
  44. /// ### Warning on cloning
  45. /// Cloning this structure increments the reference count to the already open
  46. /// socket, which means ephemereal hidden services opened with the cloned instance will live as
  47. /// long as there are clones. For this reason, I'd clone it only when you are sure you want this
  48. /// behaviour. Don't be lazy!
  49. ///
  50. /// [transportlisten]: Transport
  51. /// [torcreateehs]: TorTransport::create_ehs
  52. #[derive(Clone)]
  53. pub struct TorTransport {
  54. socks_url: Url,
  55. tor_controller: Option<TorController>,
  56. }
  57. /// Represents information needed to communicate with the Tor control socket
  58. #[derive(Clone)]
  59. struct TorController {
  60. socket: Arc<Socket>, // Need to hold this socket open as long as the tor trasport is alive, so ephemeral services are dropped when TorTransport is dropped
  61. auth: String,
  62. }
  63. /// Wraps the errors, because dialing and listening use different communication
  64. #[derive(Debug, thiserror::Error)]
  65. pub enum TorError {
  66. #[error("Transport IO Error: {0}")]
  67. IoError(#[from] io::Error),
  68. #[error("Socks: {0}")]
  69. Socks5Error(#[from] SocksError),
  70. #[error("Url parse error: {0}")]
  71. UrlParseError(#[from] url::ParseError),
  72. #[error("Regex parse error: {0}")]
  73. RegexError(#[from] regex::Error),
  74. #[error("Unexpected response from tor: {0}")]
  75. GeneralError(String),
  76. }
  77. /// Contains the configuration to communicate with the Tor Controler
  78. ///
  79. /// When cloned, the socket is not reopened since we use reference count.
  80. /// The hidden services created live as long as clones of the struct.
  81. impl TorController {
  82. /// Creates a new TorTransport
  83. ///
  84. /// # Arguments
  85. ///
  86. /// * `url` - url to connect to the tor control. For example tcp://127.0.0.1:9051
  87. ///
  88. /// * `auth` - either authentication cookie bytes (32 bytes) as hex in a string
  89. /// or a password as a quoted string.
  90. ///
  91. /// Cookie string: `assert_eq!(auth,"886b9177aec471965abd34b6a846dc32cf617dcff0625cba7a414e31dd4b75a0")`
  92. ///
  93. /// Password string: `assert_eq!(auth,"\"mypassword\"")`
  94. pub fn new_t(url: Url, auth: String) -> Result<Self, io::Error> {
  95. let socket_addr = url.socket_addrs(|| None)?[0];
  96. let domain = if socket_addr.is_ipv4() { Domain::IPV4 } else { Domain::IPV6 };
  97. let socket = Socket::new(domain, Type::STREAM, Some(socket2::Protocol::TCP))?;
  98. if socket_addr.is_ipv6() {
  99. socket.set_only_v6(true)?;
  100. }
  101. match socket.connect(&socket_addr.into()) {
  102. Ok(()) => {}
  103. Err(err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}
  104. Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
  105. Err(err) => return Err(err),
  106. };
  107. Ok(Self { socket: Arc::new(socket), auth })
  108. }
  109. /// Creates an ephemeral hidden service pointing to local address, returns onion address
  110. ///
  111. /// # Arguments
  112. ///
  113. /// * `url` - url that the hidden service maps to.
  114. pub fn create_ehs(&self, url: Url) -> Result<Url, TorError> {
  115. let local_socket = self.socket.try_clone()?;
  116. let mut stream = std::net::TcpStream::from(local_socket);
  117. stream.set_write_timeout(Some(Duration::from_secs(2)))?;
  118. let host = url
  119. .host()
  120. .ok_or_else(|| TorError::GeneralError("No host on url for listening".to_string()))?;
  121. let port = url
  122. .port()
  123. .ok_or_else(|| TorError::GeneralError("No port on url for listening".to_string()))?;
  124. let payload = format!(
  125. "AUTHENTICATE {a}\r\nADD_ONION NEW:BEST Flags=DiscardPK Port={p},{h}:{p}\r\n",
  126. a = self.auth,
  127. p = port,
  128. h = host
  129. );
  130. stream.write_all(payload.as_bytes())?;
  131. stream.set_read_timeout(Some(Duration::from_secs(1)))?; // Maybe a bit too much. Gives tor time to reply
  132. let mut reader = BufReader::new(stream);
  133. let mut repl = String::new();
  134. while let Ok(nbytes) = reader.read_line(&mut repl) {
  135. if nbytes == 0 {
  136. break
  137. }
  138. }
  139. let re = Regex::new(r"250-ServiceID=(\w+*)")?;
  140. let cap: Result<regex::Captures<'_>, TorError> =
  141. re.captures(&repl).ok_or_else(|| TorError::GeneralError(repl.clone()));
  142. let hurl =
  143. cap?.get(1).map_or(Err(TorError::GeneralError(repl.clone())), |m| Ok(m.as_str()))?;
  144. let hurl = format!("tcp://{}.onion:{}", &hurl, port);
  145. Ok(Url::parse(&hurl)?)
  146. }
  147. }
  148. impl TorTransport {
  149. /// Creates a new TorTransport
  150. ///
  151. /// # Arguments
  152. ///
  153. /// * `socks_url` - url to connect to the tor service. For example socks5://127.0.0.1:9050
  154. ///
  155. /// * `control_info` - Possibility to open a control connection to create ephemeral hidden
  156. /// services that live as long as the TorTransport.
  157. /// It is a tuple of the control socket url and authentication cookie as string
  158. /// represented in hex.
  159. pub fn new_t(socks_url: Url, control_info: Option<(Url, String)>) -> Result<Self, TorError> {
  160. match control_info {
  161. Some(info) => {
  162. let (url, auth) = info;
  163. let tor_controller = Some(TorController::new_t(url, auth)?);
  164. Ok(Self { socks_url, tor_controller })
  165. }
  166. None => Ok(Self { socks_url, tor_controller: None }),
  167. }
  168. }
  169. /// Creates an ephemeral hidden service pointing to local address, returns onion address
  170. /// when successful.
  171. ///
  172. /// # Arguments
  173. ///
  174. /// * `url` - url that the hidden service maps to.
  175. pub fn create_ehs(&self, url: Url) -> Result<Url, TorError> {
  176. self.tor_controller
  177. .as_ref()
  178. .ok_or_else(|| {
  179. TorError::GeneralError("No controller configured for this transport".to_string())
  180. })?
  181. .create_ehs(url)
  182. }
  183. pub async fn do_dial(self, url: Url) -> Result<Socks5Stream<TcpStream>, TorError> {
  184. let socks_url_str = self.socks_url.socket_addrs(|| None)?[0].to_string();
  185. let host = url.host().unwrap().to_string();
  186. let port = url.port().unwrap_or(80);
  187. let config = Config::default();
  188. let stream = if !self.socks_url.username().is_empty() && self.socks_url.password().is_some()
  189. {
  190. Socks5Stream::connect_with_password(
  191. socks_url_str,
  192. host,
  193. port,
  194. self.socks_url.username().to_string(),
  195. self.socks_url.password().unwrap().to_string(),
  196. config,
  197. )
  198. .await?
  199. } else {
  200. Socks5Stream::connect(socks_url_str, host, port, config).await?
  201. };
  202. Ok(stream)
  203. }
  204. fn create_socket(&self, socket_addr: SocketAddr) -> io::Result<Socket> {
  205. let domain = if socket_addr.is_ipv4() { Domain::IPV4 } else { Domain::IPV6 };
  206. let socket = Socket::new(domain, Type::STREAM, Some(socket2::Protocol::TCP))?;
  207. if socket_addr.is_ipv6() {
  208. socket.set_only_v6(true)?;
  209. }
  210. Ok(socket)
  211. }
  212. pub async fn do_listen(self, url: Url) -> Result<TcpListener, TorError> {
  213. let socket_addr = url.socket_addrs(|| None)?[0];
  214. let socket = self.create_socket(socket_addr)?;
  215. socket.bind(&socket_addr.into())?;
  216. socket.listen(1024)?;
  217. socket.set_nonblocking(true)?;
  218. Ok(TcpListener::from(std::net::TcpListener::from(socket)))
  219. }
  220. }
  221. #[async_trait]
  222. impl Transport for TorTransport {
  223. type Acceptor = TcpListener;
  224. type Connector = Socks5Stream<TcpStream>;
  225. type Error = TorError;
  226. type Listener =
  227. Pin<Box<dyn Future<Output = Result<Self::Acceptor, Self::Error>> + Send + Sync>>;
  228. type Dial = Pin<Box<dyn Future<Output = Result<Self::Connector, Self::Error>> + Send + Sync>>;
  229. fn listen_on(self, url: Url) -> Result<Self::Listener, TransportError<Self::Error>> {
  230. if url.scheme() != "tcp" {
  231. return Err(TransportError::AddrNotSupported(url))
  232. }
  233. Ok(Box::pin(self.do_listen(url)))
  234. }
  235. fn dial(self, url: Url) -> Result<Self::Dial, TransportError<Self::Error>> {
  236. Ok(Box::pin(self.do_dial(url)))
  237. }
  238. fn new(_ttl: Option<u32>, _backlog: i32) -> Self {
  239. unimplemented!()
  240. }
  241. async fn accept(_listener: Arc<Self::Acceptor>) -> Self::Connector {
  242. unimplemented!()
  243. }
  244. }