socks5_async/
socks.rs

1#[allow(dead_code)]
2use std::{
3    error::Error,
4    fmt,
5    net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs},
6};
7use tokio::{
8    io::{AsyncReadExt, AsyncRead, AsyncWrite},
9    // net::TcpStream
10};
11
12// Const bytes
13pub const VERSION5: u8 = 0x05;
14pub const RESERVED: u8 = 0x00;
15
16// Request command
17pub enum Command {
18    Connect = 0x01,
19    Bind = 0x02,
20    UdpAssosiate = 0x3,
21}
22impl Command {
23    pub fn from(byte: usize) -> Option<Command> {
24        match byte {
25            1 => Some(Command::Connect),
26            2 => Some(Command::Bind),
27            3 => Some(Command::UdpAssosiate),
28            _ => None,
29        }
30    }
31}
32
33// Request address type
34#[derive(PartialEq)]
35pub enum AddrType {
36    V4 = 0x01,
37    Domain = 0x03,
38    V6 = 0x04,
39}
40impl AddrType {
41    pub fn from(byte: usize) -> Option<AddrType> {
42        match byte {
43            1 => Some(AddrType::V4),
44            3 => Some(AddrType::Domain),
45            4 => Some(AddrType::V6),
46            _ => None,
47        }
48    }
49
50    pub async fn get_socket_addrs<S: AsyncRead + AsyncWrite + Unpin>(
51        socket: &mut S,
52    ) -> Result<Vec<SocketAddr>, Box<dyn Error>> {
53        // Read address type
54        let mut addr_type = [0u8; 1];
55        socket.read(&mut addr_type).await?;
56        let addr_type = AddrType::from(addr_type[0] as usize);
57        if let None = addr_type {
58            Err(Response::AddrTypeNotSupported)?;
59        }
60        let addr_type = addr_type.unwrap();
61
62        // Read address
63        let addr;
64        if let AddrType::Domain = addr_type {
65            let mut dlen = [0u8; 1];
66            socket.read_exact(&mut dlen).await?;
67            let mut domain = vec![0u8; dlen[0] as usize];
68            socket.read_exact(&mut domain).await?;
69            addr = domain;
70        } else if let AddrType::V4 = addr_type {
71            let mut v4 = [0u8; 4];
72            socket.read_exact(&mut v4).await?;
73            addr = Vec::from(v4);
74        } else {
75            let mut v6 = [0u8; 16];
76            socket.read_exact(&mut v6).await?;
77            addr = Vec::from(v6);
78        }
79
80        // Read port
81        let mut port = [0u8; 2];
82        socket.read_exact(&mut port).await?;
83        let port = (u16::from(port[0]) << 8) | u16::from(port[1]);
84
85        // Return socket address vector
86        match addr_type {
87            AddrType::V6 => {
88                let new_addr = (0..8)
89                    .map(|x| (u16::from(addr[(x * 2)]) << 8) | u16::from(addr[(x * 2) + 1]))
90                    .collect::<Vec<u16>>();
91                Ok(vec![SocketAddr::from(SocketAddrV6::new(
92                    Ipv6Addr::new(
93                        new_addr[0],
94                        new_addr[1],
95                        new_addr[2],
96                        new_addr[3],
97                        new_addr[4],
98                        new_addr[5],
99                        new_addr[6],
100                        new_addr[7],
101                    ),
102                    port,
103                    0,
104                    0,
105                ))])
106            }
107            AddrType::V4 => Ok(vec![SocketAddr::from(SocketAddrV4::new(
108                Ipv4Addr::new(addr[0], addr[1], addr[2], addr[3]),
109                port,
110            ))]),
111            AddrType::Domain => {
112                let mut domain = String::from_utf8_lossy(&addr[..]).to_string();
113                domain.push_str(&":");
114                domain.push_str(&port.to_string());
115                Ok(domain.to_socket_addrs()?.collect())
116            }
117        }
118    }
119}
120
121// Server response codes
122#[allow(dead_code)]
123#[derive(Debug)]
124pub enum Response {
125    Success = 0x00,
126    Failure = 0x01,
127    RuleFailure = 0x02,
128    NetworkUnreachable = 0x03,
129    HostUnreachable = 0x04,
130    ConnectionRefused = 0x05,
131    TtlExpired = 0x06,
132    CommandNotSupported = 0x07,
133    AddrTypeNotSupported = 0x08,
134}
135impl Error for Response {}
136impl fmt::Display for Response {
137    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
138        write!(f, "Error: {}", self)
139    }
140}
141
142/// Available authentication methods and their hex value
143#[derive(PartialEq)]
144pub enum AuthMethod {
145    NoAuth = 0x00,
146    UserPass = 0x02,
147    NoMethods = 0xFF,
148}
149impl AuthMethod {
150    fn from(byte: u8) -> AuthMethod {
151        if byte == (AuthMethod::NoAuth as u8) {
152            AuthMethod::NoAuth
153        } else if byte == (AuthMethod::UserPass as u8) {
154            AuthMethod::UserPass
155        } else {
156            AuthMethod::NoMethods
157        }
158    }
159    pub async fn get_available_methods<S: AsyncRead + AsyncWrite + Unpin>(
160        methods_count: u8,
161        socket: &mut S,
162    ) -> Result<Vec<AuthMethod>, Box<dyn Error>> {
163        let mut methods: Vec<AuthMethod> = Vec::with_capacity(methods_count as usize);
164        for _ in 0..methods_count {
165            let mut method = [0u8; 1];
166            socket.read_exact(&mut method).await?;
167            methods.push(AuthMethod::from(method[0]));
168        }
169        Ok(methods)
170    }
171}