tor_rpc_connect/
client.rs
1use std::{io, net::TcpStream};
4
5#[cfg(unix)]
6use std::os::unix::net::UnixStream;
7
8use fs_mistrust::Mistrust;
9
10use crate::{
11 auth::{cookie::CookieLocation, RpcAuth, RpcCookieSource},
12 ConnectError, ResolvedConnectPoint,
13};
14
15#[non_exhaustive]
17pub struct Connection {
18 pub reader: Box<dyn io::Read + Send>,
20 pub writer: Box<dyn io::Write + Send>,
22
23 pub auth: crate::auth::RpcAuth,
25}
26
27impl ResolvedConnectPoint {
28 pub fn connect(&self, mistrust: &Mistrust) -> Result<Connection, ConnectError> {
33 use crate::connpt::ConnectPointEnum as CptE;
34 match &self.0 {
35 CptE::Connect(connect) => connect.do_connect(mistrust),
36 CptE::Builtin(builtin) => builtin.do_connect(),
37 }
38 }
39}
40impl crate::connpt::Builtin {
41 fn do_connect(&self) -> Result<Connection, ConnectError> {
43 use crate::connpt::BuiltinVariant as BV;
44 match self.builtin {
45 BV::Abort => Err(ConnectError::ExplicitAbort),
46 }
47 }
48}
49impl crate::connpt::Connect<crate::connpt::Resolved> {
50 fn do_connect(&self, mistrust: &Mistrust) -> Result<Connection, ConnectError> {
52 use crate::connpt::Auth;
53 use tor_general_addr::general::SocketAddr as SA;
54 let auth = match &self.auth {
55 Auth::None => RpcAuth::Inherent,
56 Auth::Cookie { path } => {
57 let canonical_addr = self.socket_canonical.as_ref().unwrap_or(&self.socket);
58 RpcAuth::Cookie {
59 secret: RpcCookieSource::Unloaded(CookieLocation {
60 path: path.clone(),
61 mistrust: mistrust.clone(),
62 }),
63 server_address: canonical_addr.as_str().to_string(),
64 }
65 }
66 Auth::Unrecognized(_) => return Err(ConnectError::UnsupportedAuthType),
68 };
69 if let Some(sock_parent_dir) = crate::socket_parent_path(self.socket.as_ref()) {
70 mistrust.check_directory(sock_parent_dir)?;
71 }
72 let (reader, writer): (Box<dyn io::Read + Send>, Box<dyn io::Write + Send>) =
76 match self.socket.as_ref() {
77 SA::Inet(addr) => {
78 let socket = TcpStream::connect(addr)?;
79 (Box::new(socket.try_clone()?), Box::new(socket))
80 }
81 #[cfg(unix)]
82 SA::Unix(addr) => {
83 let socket = UnixStream::connect_addr(addr)?;
84 (Box::new(socket.try_clone()?), Box::new(socket))
85 }
86 _ => return Err(ConnectError::UnsupportedSocketType),
87 };
88
89 Ok(Connection {
90 reader,
91 writer,
92 auth,
93 })
94 }
95}