github.com/AntonOrnatskyi/goproxy@v0.0.0-20190205095733-4526a9fa18b4/core/proxy/server/socks5/server.go (about) 1 package socks5 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "io" 8 "net" 9 "strconv" 10 "strings" 11 "time" 12 13 socks5c "github.com/AntonOrnatskyi/goproxy/core/lib/socks5" 14 ) 15 16 type BasicAuther interface { 17 CheckUserPass(username, password, userIP, localIP, toTarget string) bool 18 } 19 type Request struct { 20 ver uint8 21 cmd uint8 22 reserve uint8 23 addressType uint8 24 dstAddr string 25 dstPort string 26 dstHost string 27 bytes []byte 28 rw io.ReadWriter 29 } 30 31 func NewRequest(rw io.ReadWriter, header ...[]byte) (req Request, err interface{}) { 32 var b = make([]byte, 1024) 33 var n int 34 req = Request{rw: rw} 35 if header != nil && len(header) == 1 && len(header[0]) > 1 { 36 b = header[0] 37 n = len(header[0]) 38 } else { 39 n, err = rw.Read(b[:]) 40 if err != nil { 41 err = fmt.Errorf("read req data fail,ERR: %s", err) 42 return 43 } 44 } 45 req.ver = uint8(b[0]) 46 req.cmd = uint8(b[1]) 47 req.reserve = uint8(b[2]) 48 req.addressType = uint8(b[3]) 49 if b[0] != 0x5 { 50 err = fmt.Errorf("sosck version supported") 51 req.TCPReply(socks5c.REP_REQ_FAIL) 52 return 53 } 54 switch b[3] { 55 case 0x01: //IP V4 56 req.dstHost = net.IPv4(b[4], b[5], b[6], b[7]).String() 57 case 0x03: //域名 58 req.dstHost = string(b[5 : n-2]) //b[4]表示域名的长度 59 case 0x04: //IP V6 60 req.dstHost = net.IP{b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15], b[16], b[17], b[18], b[19]}.String() 61 } 62 req.dstPort = strconv.Itoa(int(b[n-2])<<8 | int(b[n-1])) 63 req.dstAddr = net.JoinHostPort(req.dstHost, req.dstPort) 64 req.bytes = b[:n] 65 return 66 } 67 func (s *Request) Bytes() []byte { 68 return s.bytes 69 } 70 func (s *Request) Addr() string { 71 return s.dstAddr 72 } 73 func (s *Request) Host() string { 74 return s.dstHost 75 } 76 func (s *Request) Port() string { 77 return s.dstPort 78 } 79 func (s *Request) AType() uint8 { 80 return s.addressType 81 } 82 func (s *Request) CMD() uint8 { 83 return s.cmd 84 } 85 86 func (s *Request) TCPReply(rep uint8) (err error) { 87 _, err = s.rw.Write(s.NewReply(rep, "0.0.0.0:0")) 88 return 89 } 90 func (s *Request) UDPReply(rep uint8, addr string) (err error) { 91 _, err = s.rw.Write(s.NewReply(rep, addr)) 92 return 93 } 94 func (s *Request) NewReply(rep uint8, addr string) []byte { 95 var response bytes.Buffer 96 host, port, _ := net.SplitHostPort(addr) 97 ip := net.ParseIP(host) 98 ipb := ip.To4() 99 atyp := socks5c.ATYP_IPV4 100 ipv6 := ip.To16() 101 zeroiIPv6 := fmt.Sprintf("%d%d%d%d%d%d%d%d%d%d%d%d", 102 ipv6[0], ipv6[1], ipv6[2], ipv6[3], 103 ipv6[4], ipv6[5], ipv6[6], ipv6[7], 104 ipv6[8], ipv6[9], ipv6[10], ipv6[11], 105 ) 106 if ipb == nil && ipv6 != nil && "0000000000255255" != zeroiIPv6 { 107 atyp = socks5c.ATYP_IPV6 108 ipb = ip.To16() 109 } 110 porti, _ := strconv.Atoi(port) 111 portb := make([]byte, 2) 112 binary.BigEndian.PutUint16(portb, uint16(porti)) 113 // log.Printf("atyp : %v", atyp) 114 // log.Printf("ip : %v", []byte(ip)) 115 response.WriteByte(socks5c.VERSION_V5) 116 response.WriteByte(rep) 117 response.WriteByte(socks5c.RSV) 118 response.WriteByte(atyp) 119 response.Write(ipb) 120 response.Write(portb) 121 return response.Bytes() 122 } 123 124 type MethodsRequest struct { 125 ver uint8 126 methodsCount uint8 127 methods []uint8 128 bytes []byte 129 rw *io.ReadWriter 130 } 131 132 func NewMethodsRequest(r io.ReadWriter, header ...[]byte) (s MethodsRequest, err interface{}) { 133 defer func() { 134 if err == nil { 135 err = recover() 136 } 137 }() 138 s = MethodsRequest{} 139 s.rw = &r 140 var buf = make([]byte, 300) 141 var n int 142 if header != nil && len(header) == 1 && len(header[0]) > 1 { 143 buf = header[0] 144 n = len(header[0]) 145 } else { 146 n, err = r.Read(buf) 147 if err != nil { 148 return 149 } 150 } 151 if buf[0] != 0x05 { 152 err = fmt.Errorf("socks version not supported") 153 return 154 } 155 if n != int(buf[1])+int(2) { 156 err = fmt.Errorf("socks methods data length error") 157 return 158 } 159 s.ver = buf[0] 160 s.methodsCount = buf[1] 161 s.methods = buf[2:n] 162 s.bytes = buf[:n] 163 return 164 } 165 func (s *MethodsRequest) Version() uint8 { 166 return s.ver 167 } 168 func (s *MethodsRequest) MethodsCount() uint8 { 169 return s.methodsCount 170 } 171 func (s *MethodsRequest) Methods() []uint8 { 172 return s.methods 173 } 174 func (s *MethodsRequest) Select(method uint8) bool { 175 for _, m := range s.methods { 176 if m == method { 177 return true 178 } 179 } 180 return false 181 } 182 func (s *MethodsRequest) Reply(method uint8) (err error) { 183 _, err = (*s.rw).Write([]byte{byte(socks5c.VERSION_V5), byte(method)}) 184 return 185 } 186 func (s *MethodsRequest) Bytes() []byte { 187 return s.bytes 188 } 189 190 type ServerConn struct { 191 target string 192 user string 193 password string 194 conn *net.Conn 195 timeout time.Duration 196 auth *BasicAuther 197 header []byte 198 ver uint8 199 //method 200 methodsCount uint8 201 methods []uint8 202 method uint8 203 //request 204 cmd uint8 205 reserve uint8 206 addressType uint8 207 dstAddr string 208 dstPort string 209 dstHost string 210 udpAddress string 211 } 212 213 func NewServerConn(conn *net.Conn, timeout time.Duration, auth *BasicAuther, udpAddress string, header []byte) *ServerConn { 214 if udpAddress == "" { 215 udpAddress = "0.0.0.0:16666" 216 } 217 s := &ServerConn{ 218 conn: conn, 219 timeout: timeout, 220 auth: auth, 221 header: header, 222 ver: socks5c.VERSION_V5, 223 udpAddress: udpAddress, 224 } 225 return s 226 227 } 228 func (s *ServerConn) Close() { 229 (*s.conn).Close() 230 } 231 func (s *ServerConn) AuthData() socks5c.UsernamePassword { 232 return socks5c.UsernamePassword{s.user, s.password} 233 } 234 func (s *ServerConn) Method() uint8 { 235 return s.method 236 } 237 func (s *ServerConn) Target() string { 238 return s.target 239 } 240 func (s *ServerConn) Handshake() (err error) { 241 remoteAddr := (*s.conn).RemoteAddr() 242 localAddr := (*s.conn).LocalAddr() 243 //协商开始 244 //method select request 245 var methodReq MethodsRequest 246 (*s.conn).SetReadDeadline(time.Now().Add(s.timeout)) 247 248 methodReq, e := NewMethodsRequest((*s.conn), s.header) 249 (*s.conn).SetReadDeadline(time.Time{}) 250 if e != nil { 251 (*s.conn).SetReadDeadline(time.Now().Add(s.timeout)) 252 methodReq.Reply(socks5c.Method_NONE_ACCEPTABLE) 253 (*s.conn).SetReadDeadline(time.Time{}) 254 err = fmt.Errorf("new methods request fail,ERR: %s", e) 255 return 256 } 257 //log.Printf("%v,s.auth == %v && methodReq.Select(Method_NO_AUTH) %v", methodReq.methods, s.auth, methodReq.Select(Method_NO_AUTH)) 258 if s.auth == nil && methodReq.Select(socks5c.Method_NO_AUTH) && !methodReq.Select(socks5c.Method_USER_PASS) { 259 // if !methodReq.Select(Method_NO_AUTH) { 260 // (*s.conn).SetReadDeadline(time.Now().Add(time.Second * s.timeout)) 261 // methodReq.Reply(Method_NONE_ACCEPTABLE) 262 // (*s.conn).SetReadDeadline(time.Time{}) 263 // err = fmt.Errorf("none method found : Method_NO_AUTH") 264 // return 265 // } 266 s.method = socks5c.Method_NO_AUTH 267 //method select reply 268 (*s.conn).SetReadDeadline(time.Now().Add(s.timeout)) 269 err = methodReq.Reply(socks5c.Method_NO_AUTH) 270 (*s.conn).SetReadDeadline(time.Time{}) 271 if err != nil { 272 err = fmt.Errorf("reply answer data fail,ERR: %s", err) 273 return 274 } 275 // err = fmt.Errorf("% x", methodReq.Bytes()) 276 } else { 277 //auth 278 if !methodReq.Select(socks5c.Method_USER_PASS) { 279 (*s.conn).SetReadDeadline(time.Now().Add(s.timeout)) 280 methodReq.Reply(socks5c.Method_NONE_ACCEPTABLE) 281 (*s.conn).SetReadDeadline(time.Time{}) 282 err = fmt.Errorf("none method found : Method_USER_PASS") 283 return 284 } 285 s.method = socks5c.Method_USER_PASS 286 //method reply need auth 287 (*s.conn).SetReadDeadline(time.Now().Add(s.timeout)) 288 err = methodReq.Reply(socks5c.Method_USER_PASS) 289 (*s.conn).SetReadDeadline(time.Time{}) 290 if err != nil { 291 err = fmt.Errorf("reply answer data fail,ERR: %s", err) 292 return 293 } 294 //read auth 295 buf := make([]byte, 500) 296 var n int 297 (*s.conn).SetReadDeadline(time.Now().Add(s.timeout)) 298 n, err = (*s.conn).Read(buf) 299 (*s.conn).SetReadDeadline(time.Time{}) 300 if err != nil { 301 err = fmt.Errorf("read auth info fail,ERR: %s", err) 302 return 303 } 304 r := buf[:n] 305 s.user = string(r[2 : r[1]+2]) 306 s.password = string(r[2+r[1]+1:]) 307 //err = fmt.Errorf("user:%s,pass:%s", user, pass) 308 //auth 309 _userAddr := strings.Split(remoteAddr.String(), ":") 310 _localAddr := strings.Split(localAddr.String(), ":") 311 if s.auth == nil || (*s.auth).CheckUserPass(s.user, s.password, _userAddr[0], _localAddr[0], "") { 312 (*s.conn).SetDeadline(time.Now().Add(s.timeout)) 313 _, err = (*s.conn).Write([]byte{0x01, 0x00}) 314 (*s.conn).SetDeadline(time.Time{}) 315 if err != nil { 316 err = fmt.Errorf("answer auth success to %s fail,ERR: %s", remoteAddr, err) 317 return 318 } 319 } else { 320 (*s.conn).SetDeadline(time.Now().Add(s.timeout)) 321 _, err = (*s.conn).Write([]byte{0x01, 0x01}) 322 (*s.conn).SetDeadline(time.Time{}) 323 if err != nil { 324 err = fmt.Errorf("answer auth fail to %s fail,ERR: %s", remoteAddr, err) 325 return 326 } 327 err = fmt.Errorf("auth fail from %s", remoteAddr) 328 return 329 } 330 } 331 //request detail 332 (*s.conn).SetReadDeadline(time.Now().Add(s.timeout)) 333 request, e := NewRequest(*s.conn) 334 (*s.conn).SetReadDeadline(time.Time{}) 335 if e != nil { 336 err = fmt.Errorf("read request data fail,ERR: %s", e) 337 return 338 } 339 //协商结束 340 341 switch request.CMD() { 342 case socks5c.CMD_BIND: 343 err = request.TCPReply(socks5c.REP_UNKNOWN) 344 if err != nil { 345 err = fmt.Errorf("TCPReply REP_UNKNOWN to %s fail,ERR: %s", remoteAddr, err) 346 return 347 } 348 err = fmt.Errorf("cmd bind not supported, form: %s", remoteAddr) 349 return 350 case socks5c.CMD_CONNECT: 351 err = request.TCPReply(socks5c.REP_SUCCESS) 352 if err != nil { 353 err = fmt.Errorf("TCPReply REP_SUCCESS to %s fail,ERR: %s", remoteAddr, err) 354 return 355 } 356 case socks5c.CMD_ASSOCIATE: 357 err = request.UDPReply(socks5c.REP_SUCCESS, s.udpAddress) 358 if err != nil { 359 err = fmt.Errorf("UDPReply REP_SUCCESS to %s fail,ERR: %s", remoteAddr, err) 360 return 361 } 362 } 363 364 //fill socks info 365 s.target = request.Addr() 366 s.methodsCount = methodReq.MethodsCount() 367 s.methods = methodReq.Methods() 368 s.cmd = request.CMD() 369 s.reserve = request.reserve 370 s.addressType = request.addressType 371 s.dstAddr = request.dstAddr 372 s.dstHost = request.dstHost 373 s.dstPort = request.dstPort 374 return 375 }