inn_network/codec/
socks.rs1use byteorder::BigEndian;
2use byteorder::ByteOrder;
3use bytes::BytesMut;
4
5use crate::server::ProxyServer;
6
7use super::AuthChoice;
8use super::Cmd;
9use super::DstAddress;
10use super::T;
11use super::VisitorDecoder;
21use super::VisitorRequest;
22
23use super::Proto;
24use super::State;
25use std::io::{Error, ErrorKind};
26pub(crate) struct SocksCodec {
27 pub state: State,
28}
29impl Default for SocksCodec {
30 fn default() -> Self {
31 SocksCodec {
32 state: State::Undefined,
33 }
34 }
35}
36
37impl VisitorDecoder for SocksCodec {
38 fn decode(&mut self, src: &mut BytesMut) -> Result<Option<VisitorRequest>, Error> {
39 if src.len() < 3 {
40 return Ok(None);
41 }
42 match &self.state {
43 State::Undefined => {
44 let buf = src.as_ref();
45 if buf[0] == 0x05 {
46 let nauth = buf[1] as usize;
47 if src.len() < (nauth + 2) {
48 Ok(None)
49 } else {
50 let _ = src.split_to(2);
51 let buf = src.split_to(nauth as usize);
52 self.state = State::Auth;
53 match ProxyServer::auth_choice(&buf.to_vec()) {
54 AuthChoice::NoAcceptable => self.state = State::Greeting,
55 AuthChoice::UserNamePwd => self.state = State::Greeting,
56 AuthChoice::NoAuth => self.state = State::Auth,
57 }
58 Ok(Some(VisitorRequest::Greeting {
59 proto: Proto::Socks5,
60 auth: buf.to_vec(),
61 }))
62 }
63 } else {
64 let msg: String = "Invalid socks5 protocol".into();
65 Err(Error::new(ErrorKind::Other, msg))
66 }
67 }
68 State::Greeting => {
69 if src.len() < 2 {
71 return Ok(None);
72 }
73 let buf = src.as_ref();
74 let id_len = buf[1] as usize;
75 if src.len() < id_len + 3 {
76 return Ok(None);
77 }
78 let pwd_len = buf[id_len + 2] as usize;
79 if src.len() < pwd_len + id_len + 3 {
80 return Ok(None);
81 }
82 let _ = src.split_to(2);
83 let id = src.split_to(id_len);
84 let _ = src.split_to(1);
85 let pwd = src.split_to(pwd_len);
86 self.state = State::Auth;
87 Ok(Some(VisitorRequest::Auth {
88 id: String::from_utf8(id.to_vec()).unwrap(),
89 pwd: String::from_utf8(pwd.to_vec()).unwrap(),
90 }))
91 }
92 State::Auth => {
93 if src.len() < 5 {
95 return Ok(None);
96 }
97 let buf = src.as_ref();
98 if buf[1] != 0x01 {
99 return Err(Error::new(
100 ErrorKind::Other,
101 "Client connection Request only support stream Connection",
102 ));
103 }
104 let addr_type = buf[3];
105 match addr_type {
106 0x01 => {
108 if src.len() < 10 {
109 return Ok(None);
110 }
111 let _ = src.split_to(4);
112 let ip = src.split_to(4);
113 let port = BigEndian::read_u16(src.as_ref());
114 self.state = State::Forward;
115 let _ = src.split_to(2);
116 return Ok(Some(VisitorRequest::Connection {
117 cmd: Cmd::Connection,
118 address: DstAddress::new(
119 T::IPv4,
120 &format!("{}.{}.{}.{}", ip[0], ip[1], ip[2], ip[3]),
121 port,
122 ),
123 }));
124 }
125 0x03 => {
127 let name_len = buf[4] as usize;
128 if src.len() < name_len + 7 {
129 return Ok(None);
130 }
131 let _ = src.split_to(5);
132 let name = src.split_to(name_len);
133 let port = BigEndian::read_u16(src.as_ref());
134 let _ = src.split_to(2);
135 self.state = State::Forward;
136 if let Ok(name) = String::from_utf8(name.to_vec()) {
137 Ok(Some(VisitorRequest::Connection {
138 cmd: Cmd::Connection,
139 address: DstAddress::new(T::Domain, &name, port),
140 }))
141 } else {
142 Err(Error::new(
143 ErrorKind::Other,
144 "Client connection Request Domain invalid",
145 ))
146 }
147 }
148 _ => Err(Error::new(
149 ErrorKind::Other,
150 "Client connection Request only support IPv4 or Domain",
151 )),
152 }
153 }
154 State::Forward => Ok(Some(VisitorRequest::Forward(
156 src.split_to(src.len()).to_vec(),
157 ))),
158 }
159 }
160}