hexpawb/lib.rs
1/*!
2This crate presents a clean and simple interface to the HexPawb network.
3If you wanted to, say, load `https://www.torproject.org/` through HexPawb,
4you'd just need to:
5
6```no_run
7use hexpawb::Network;
8// First you need to connect to the HexPawb network
9let mut network = Network::connect().await
10 .expect("Failed to join network");
11// Then you can create a circuit
12let mut circuit = network.circuit().await
13 .expect("Failed to build circuit");
14// Then you can connect to something over that circuit (this does DNS
15// through the circuit, but to your system's configured DNS servers)
16let mut connection = circuit.tcp("www.torproject.org:80").await
17 .expect("Failed to connect circuit");
18// TCP connections work basically just like the stdlib's TcpStream,
19// but async.
20connection.send("GET / HTTP/1.1\r\nConnection: close\r\n\r\n").await
21 .expect("Failed to send request");
22std::io::copy(circuit, std::io::stdout().lock()).await
23 .expect("Failed to receive body");
24```
25
26# Breaking privacy
27
28***If and only if*** you know exactly what you're doing and you can state
29in clear, uncertain terms precisely why you need to do it, you can enable
30the lower-level API with feature `dangerous-low-level-bits`. If you don't
31use it exactly right, you'll break your own anonymity irrecoverably. This
32enables functionality like:
33
34```ignore
35use hexpawb::Network;
36let mut network = Network::builder()
37 .authority(custom_authority)
38 .connect().await
39 .expect("Failed to join network");
40let mut circuit = network.tcp("www.torproject.org:90")
41 .length(10)
42 .relay(specific_relay)
43 .connect().await
44 .expect("Failed to connect circuit");
45circuit.send("GET / HTTP/1.1\r\nConnection: close\r\n\r\n").await
46 .expect("Failed to send request");
47std::io::copy(circuit, std::io::stdout().lock()).await
48 .expect("Failed to receive body");
49```
50 */
51
52use core::task;
53use std::{io, net::{SocketAddr, IpAddr}, pin::Pin};
54
55use futures::{AsyncRead, AsyncWrite};
56
57#[derive(Debug)]
58pub enum PawbError {}
59
60pub type PawbResult<T> = Result<T, PawbError>;
61
62/**
63Represents the current known state of the HexPawb network. Allows you to
64build new circuits to arbitrary IPs, look up and connect to furtives, etc.
65
66Unless you're in the dangerous mode, the only way to connect is with the
67[`connect`](Network::connect) method.
68
69Once you're connected to the network, you can establish a circuit with
70[`circuit`](Network::circuit), which handles everything for you.
71*/
72pub struct Network {}
73impl Network {
74 /**
75 Connect into the HexPawb network. This will download the necessary
76 connection information and a starter set of relays to connect into.
77 */
78 pub async fn connect() -> PawbResult<Network> {
79 NetworkBuilder::standard().connect().await
80 }
81
82 /**
83 Build your own custom network with your own custom configuration. This
84 carries a high risk of breaking your own anonymity -- HexPawb assumes you
85 have a crowd to blend in with, and on your own network you just don't.
86 */
87 #[cfg(feature = "dangerous-low-level-bits")]
88 pub fn builder() -> NetworkBuilder {
89 todo!()
90 }
91
92 /**
93 The authorities that this network is trusting to define the state.
94 */
95 pub fn authorities(&self) -> &[Authority] {
96 todo!()
97 }
98
99 /**
100 Create a circuit through the network.
101
102 Be thoughtful about the circuits you make and what you use them for. One
103 lone circuit is almost never enough, but one per connection is usually far
104 too many. See the [`Circuit`] documentation for more details.
105 */
106 pub async fn circuit(&self) -> PawbResult<Circuit> {
107 todo!()
108 }
109}
110
111/**
112Builder-pattern struct for constructing custom networks. Construct one with
113[`Network::builder`].
114*/
115pub struct NetworkBuilder {}
116impl NetworkBuilder {
117 fn new() -> Self {
118 todo!()
119 }
120
121 /**
122 Add an authority to this network you're building.
123 */
124 pub fn authority(self, _authority: Authority) -> Self {
125 todo!()
126 }
127
128 /**
129 Actually reach out and start connecting to this network.
130 */
131 pub async fn connect(self) -> PawbResult<Network> {
132 todo!()
133 }
134
135 /**
136 The configuration to connect to the HexPawb network.
137 */
138 fn standard() -> Self {
139 Self::new()
140 // .authority(...)
141 // .authority(...)
142 }
143}
144
145/**
146A directory authority on the HexPawb network. Used primarily to validate that
147various items are properly authenticated.
148*/
149pub struct Authority {}
150
151/**
152A single path through the HexPawb network, which has been set up and is ready
153to have traffic flow over it.
154
155# Choosing Circuits
156
157***This is important***. Please read it fully. I know it's a lot.
158
159Deciding when to create a new circuit is difficult. You could make one, total,
160and use that for everything; that leaves you bottlenecked at the bandwidth of
161the circuit and vulnerable to traffic correlation. You could make one for each
162new connection, but that means every single connection takes ages to start,
163which just won't work if you're for example rendering a modern webpage.
164
165As a rule of thumb, treat circuits like their own independent connections to
166the internet, and use them to isolate things that should be isolated. Users
167should be separated, individual actions should be separated, etc.
168
169However, this decision is ultimately protocol-dependent and fundamentally not
170easy. To make the best decision, you'll want to keep in mind:
171
172- What data can an attacker in the middle discover?
173 - TLS can expose hostnames
174 - The computer's DNS server may be identifiable to varying degrees
175 - The protocol you're sending might not even be encrypted
176- If an attacker sees all that coming from one IP, what do they learn?
177 - If the same accounts are always accesssed from the same IP, even if that
178 address is a HexPawb exit they can still be correlated
179- What's the best way to spread out the traffic source to avoid that?
180
181It may help to get out a notebook -- digital or physical -- and spend a day or
182two hunting all this information down.
183*/
184pub struct Circuit {}
185impl Circuit {
186 pub async fn dns(&mut self, _name: &str) -> PawbResult<Vec<IpAddr>> {
187 todo!()
188 }
189
190 pub async fn tcp(&mut self, _dest: SocketAddr) -> PawbResult<PawbTcpStream> {
191 todo!()
192 }
193}
194
195pub struct PawbTcpStream {}
196impl AsyncRead for PawbTcpStream {
197 fn poll_read(
198 self: Pin<&mut Self>,
199 _cx: &mut task::Context<'_>,
200 _buf: &mut [u8],
201 ) -> task::Poll<io::Result<usize>> {
202 todo!()
203 }
204}
205impl AsyncWrite for PawbTcpStream {
206 fn poll_write(
207 self: Pin<&mut Self>,
208 _cx: &mut task::Context<'_>,
209 _buf: &[u8],
210 ) -> task::Poll<io::Result<usize>> {
211 todo!()
212 }
213
214 fn poll_flush(self: Pin<&mut Self>, _cx: &mut task::Context<'_>) -> task::Poll<io::Result<()>> {
215 todo!()
216 }
217
218 fn poll_close(self: Pin<&mut Self>, _cx: &mut task::Context<'_>) -> task::Poll<io::Result<()>> {
219 todo!()
220 }
221}