hyper_util/client/legacy/connect/proxy/socks/v5/
messages.rs
1use super::super::{ParsingError, SerializeError};
2
3use bytes::{Buf, BufMut, BytesMut};
4use std::net::SocketAddr;
5
6#[derive(Debug)]
12pub struct NegotiationReq<'a>(pub &'a AuthMethod);
13
14#[derive(Debug)]
20pub struct NegotiationRes(pub AuthMethod);
21
22#[derive(Debug)]
28pub struct AuthenticationReq<'a>(pub &'a str, pub &'a str);
29
30#[derive(Debug)]
36pub struct AuthenticationRes(pub bool);
37
38#[derive(Debug)]
44pub struct ProxyReq<'a>(pub &'a Address);
45
46#[derive(Debug)]
52pub struct ProxyRes(pub Status);
53
54#[repr(u8)]
55#[derive(Debug, Copy, Clone, PartialEq)]
56pub enum AuthMethod {
57 NoAuth = 0x00,
58 UserPass = 0x02,
59 NoneAcceptable = 0xFF,
60}
61
62#[derive(Debug)]
63pub enum Address {
64 Socket(SocketAddr),
65 Domain(String, u16),
66}
67
68#[derive(Debug, Copy, Clone, PartialEq)]
69pub enum Status {
70 Success,
71 GeneralServerFailure,
72 ConnectionNotAllowed,
73 NetworkUnreachable,
74 HostUnreachable,
75 ConnectionRefused,
76 TtlExpired,
77 CommandNotSupported,
78 AddressTypeNotSupported,
79}
80
81impl NegotiationReq<'_> {
82 pub fn write_to_buf(&self, buf: &mut BytesMut) -> Result<usize, SerializeError> {
83 if buf.capacity() - buf.len() < 3 {
84 return Err(SerializeError::WouldOverflow);
85 }
86
87 buf.put_u8(0x05); buf.put_u8(0x01); buf.put_u8(*self.0 as u8); Ok(3)
92 }
93}
94
95impl TryFrom<&mut BytesMut> for NegotiationRes {
96 type Error = ParsingError;
97
98 fn try_from(buf: &mut BytesMut) -> Result<Self, ParsingError> {
99 if buf.remaining() < 2 {
100 return Err(ParsingError::Incomplete);
101 }
102
103 if buf.get_u8() != 0x05 {
104 return Err(ParsingError::Other);
105 }
106
107 let method = buf.get_u8().try_into()?;
108 Ok(Self(method))
109 }
110}
111
112impl AuthenticationReq<'_> {
113 pub fn write_to_buf(&self, buf: &mut BytesMut) -> Result<usize, SerializeError> {
114 if buf.capacity() - buf.len() < 3 + self.0.len() + self.1.len() {
115 return Err(SerializeError::WouldOverflow);
116 }
117
118 buf.put_u8(0x01); buf.put_u8(self.0.len() as u8); buf.put_slice(self.0.as_bytes()); buf.put_u8(self.1.len() as u8); buf.put_slice(self.1.as_bytes()); Ok(3 + self.0.len() + self.1.len())
127 }
128}
129
130impl TryFrom<&mut BytesMut> for AuthenticationRes {
131 type Error = ParsingError;
132
133 fn try_from(buf: &mut BytesMut) -> Result<Self, ParsingError> {
134 if buf.remaining() < 2 {
135 return Err(ParsingError::Incomplete);
136 }
137
138 if buf.get_u8() != 0x01 {
139 return Err(ParsingError::Other);
140 }
141
142 if buf.get_u8() == 0 {
143 Ok(Self(true))
144 } else {
145 Ok(Self(false))
146 }
147 }
148}
149
150impl ProxyReq<'_> {
151 pub fn write_to_buf(&self, buf: &mut BytesMut) -> Result<usize, SerializeError> {
152 let addr_len = match self.0 {
153 Address::Socket(SocketAddr::V4(_)) => 1 + 4 + 2,
154 Address::Socket(SocketAddr::V6(_)) => 1 + 16 + 2,
155 Address::Domain(ref domain, _) => 1 + 1 + domain.len() + 2,
156 };
157
158 if buf.capacity() - buf.len() < 3 + addr_len {
159 return Err(SerializeError::WouldOverflow);
160 }
161
162 buf.put_u8(0x05); buf.put_u8(0x01); buf.put_u8(0x00); let _ = self.0.write_to_buf(buf); Ok(3 + addr_len)
168 }
169}
170
171impl TryFrom<&mut BytesMut> for ProxyRes {
172 type Error = ParsingError;
173
174 fn try_from(buf: &mut BytesMut) -> Result<Self, ParsingError> {
175 if buf.remaining() < 2 {
176 return Err(ParsingError::Incomplete);
177 }
178
179 if buf.get_u8() != 0x05 {
181 return Err(ParsingError::Other);
182 }
183
184 let status = buf.get_u8().try_into()?;
186
187 if buf.get_u8() != 0x00 {
189 return Err(ParsingError::Other);
190 }
191
192 Address::try_from(buf)?;
194
195 Ok(Self(status))
196 }
197}
198
199impl Address {
200 pub fn write_to_buf(&self, buf: &mut BytesMut) -> Result<usize, SerializeError> {
201 match self {
202 Self::Socket(SocketAddr::V4(v4)) => {
203 if buf.capacity() - buf.len() < 1 + 4 + 2 {
204 return Err(SerializeError::WouldOverflow);
205 }
206
207 buf.put_u8(0x01);
208 buf.put_slice(&v4.ip().octets());
209 buf.put_u16(v4.port()); Ok(7)
212 }
213
214 Self::Socket(SocketAddr::V6(v6)) => {
215 if buf.capacity() - buf.len() < 1 + 16 + 2 {
216 return Err(SerializeError::WouldOverflow);
217 }
218
219 buf.put_u8(0x04);
220 buf.put_slice(&v6.ip().octets());
221 buf.put_u16(v6.port()); Ok(19)
224 }
225
226 Self::Domain(domain, port) => {
227 if buf.capacity() - buf.len() < 1 + 1 + domain.len() + 2 {
228 return Err(SerializeError::WouldOverflow);
229 }
230
231 buf.put_u8(0x03);
232 buf.put_u8(domain.len() as u8); buf.put_slice(domain.as_bytes());
234 buf.put_u16(*port);
235
236 Ok(4 + domain.len())
237 }
238 }
239 }
240}
241
242impl TryFrom<&mut BytesMut> for Address {
243 type Error = ParsingError;
244
245 fn try_from(buf: &mut BytesMut) -> Result<Self, Self::Error> {
246 if buf.remaining() < 2 {
247 return Err(ParsingError::Incomplete);
248 }
249
250 Ok(match buf.get_u8() {
251 0x01 => {
252 let mut ip = [0; 4];
253
254 if buf.remaining() < 6 {
255 return Err(ParsingError::Incomplete);
256 }
257
258 buf.copy_to_slice(&mut ip);
259 let port = buf.get_u16();
260
261 Self::Socket(SocketAddr::new(ip.into(), port))
262 }
263
264 0x03 => {
265 let len = buf.get_u8();
266
267 if len == 0 {
268 return Err(ParsingError::Other);
269 } else if buf.remaining() < (len as usize) + 2 {
270 return Err(ParsingError::Incomplete);
271 }
272
273 let domain = std::str::from_utf8(&buf[..len as usize])
274 .map_err(|_| ParsingError::Other)?
275 .to_string();
276
277 let port = buf.get_u16();
278
279 Self::Domain(domain, port)
280 }
281
282 0x04 => {
283 let mut ip = [0; 16];
284
285 if buf.remaining() < 6 {
286 return Err(ParsingError::Incomplete);
287 }
288 buf.copy_to_slice(&mut ip);
289 let port = buf.get_u16();
290
291 Self::Socket(SocketAddr::new(ip.into(), port))
292 }
293
294 _ => return Err(ParsingError::Other),
295 })
296 }
297}
298
299impl TryFrom<u8> for Status {
300 type Error = ParsingError;
301
302 fn try_from(byte: u8) -> Result<Self, Self::Error> {
303 Ok(match byte {
304 0x00 => Self::Success,
305
306 0x01 => Self::GeneralServerFailure,
307 0x02 => Self::ConnectionNotAllowed,
308 0x03 => Self::NetworkUnreachable,
309 0x04 => Self::HostUnreachable,
310 0x05 => Self::ConnectionRefused,
311 0x06 => Self::TtlExpired,
312 0x07 => Self::CommandNotSupported,
313 0x08 => Self::AddressTypeNotSupported,
314 _ => return Err(ParsingError::Other),
315 })
316 }
317}
318
319impl TryFrom<u8> for AuthMethod {
320 type Error = ParsingError;
321
322 fn try_from(byte: u8) -> Result<Self, Self::Error> {
323 Ok(match byte {
324 0x00 => Self::NoAuth,
325 0x02 => Self::UserPass,
326 0xFF => Self::NoneAcceptable,
327
328 _ => return Err(ParsingError::Other),
329 })
330 }
331}
332
333impl std::fmt::Display for Status {
334 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
335 f.write_str(match self {
336 Self::Success => "success",
337 Self::GeneralServerFailure => "general server failure",
338 Self::ConnectionNotAllowed => "connection not allowed",
339 Self::NetworkUnreachable => "network unreachable",
340 Self::HostUnreachable => "host unreachable",
341 Self::ConnectionRefused => "connection refused",
342 Self::TtlExpired => "ttl expired",
343 Self::CommandNotSupported => "command not supported",
344 Self::AddressTypeNotSupported => "address type not supported",
345 })
346 }
347}