github.com/Uhtred009/v2ray-core-1@v4.31.2+incompatible/proxy/socks/protocol.go (about) 1 // +build !confonly 2 3 package socks 4 5 import ( 6 "encoding/binary" 7 "io" 8 9 "v2ray.com/core/common" 10 "v2ray.com/core/common/buf" 11 "v2ray.com/core/common/net" 12 "v2ray.com/core/common/protocol" 13 ) 14 15 const ( 16 socks5Version = 0x05 17 socks4Version = 0x04 18 19 cmdTCPConnect = 0x01 20 cmdTCPBind = 0x02 21 cmdUDPPort = 0x03 22 cmdTorResolve = 0xF0 23 cmdTorResolvePTR = 0xF1 24 25 socks4RequestGranted = 90 26 socks4RequestRejected = 91 27 28 authNotRequired = 0x00 29 //authGssAPI = 0x01 30 authPassword = 0x02 31 authNoMatchingMethod = 0xFF 32 33 statusSuccess = 0x00 34 statusCmdNotSupport = 0x07 35 ) 36 37 var addrParser = protocol.NewAddressParser( 38 protocol.AddressFamilyByte(0x01, net.AddressFamilyIPv4), 39 protocol.AddressFamilyByte(0x04, net.AddressFamilyIPv6), 40 protocol.AddressFamilyByte(0x03, net.AddressFamilyDomain), 41 ) 42 43 type ServerSession struct { 44 config *ServerConfig 45 port net.Port 46 } 47 48 func (s *ServerSession) handshake4(cmd byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { 49 if s.config.AuthType == AuthType_PASSWORD { 50 writeSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0)) // nolint: errcheck 51 return nil, newError("socks 4 is not allowed when auth is required.") 52 } 53 54 var port net.Port 55 var address net.Address 56 57 { 58 buffer := buf.StackNew() 59 if _, err := buffer.ReadFullFrom(reader, 6); err != nil { 60 buffer.Release() 61 return nil, newError("insufficient header").Base(err) 62 } 63 port = net.PortFromBytes(buffer.BytesRange(0, 2)) 64 address = net.IPAddress(buffer.BytesRange(2, 6)) 65 buffer.Release() 66 } 67 68 if _, err := ReadUntilNull(reader); /* user id */ err != nil { 69 return nil, err 70 } 71 if address.IP()[0] == 0x00 { 72 domain, err := ReadUntilNull(reader) 73 if err != nil { 74 return nil, newError("failed to read domain for socks 4a").Base(err) 75 } 76 address = net.DomainAddress(domain) 77 } 78 79 switch cmd { 80 case cmdTCPConnect: 81 request := &protocol.RequestHeader{ 82 Command: protocol.RequestCommandTCP, 83 Address: address, 84 Port: port, 85 Version: socks4Version, 86 } 87 if err := writeSocks4Response(writer, socks4RequestGranted, net.AnyIP, net.Port(0)); err != nil { 88 return nil, err 89 } 90 return request, nil 91 default: 92 writeSocks4Response(writer, socks4RequestRejected, net.AnyIP, net.Port(0)) // nolint: errcheck 93 return nil, newError("unsupported command: ", cmd) 94 } 95 } 96 97 func (s *ServerSession) auth5(nMethod byte, reader io.Reader, writer io.Writer) (username string, err error) { 98 buffer := buf.StackNew() 99 defer buffer.Release() 100 101 if _, err = buffer.ReadFullFrom(reader, int32(nMethod)); err != nil { 102 return "", newError("failed to read auth methods").Base(err) 103 } 104 105 var expectedAuth byte = authNotRequired 106 if s.config.AuthType == AuthType_PASSWORD { 107 expectedAuth = authPassword 108 } 109 110 if !hasAuthMethod(expectedAuth, buffer.BytesRange(0, int32(nMethod))) { 111 writeSocks5AuthenticationResponse(writer, socks5Version, authNoMatchingMethod) // nolint: errcheck 112 return "", newError("no matching auth method") 113 } 114 115 if err := writeSocks5AuthenticationResponse(writer, socks5Version, expectedAuth); err != nil { 116 return "", newError("failed to write auth response").Base(err) 117 } 118 119 if expectedAuth == authPassword { 120 username, password, err := ReadUsernamePassword(reader) 121 if err != nil { 122 return "", newError("failed to read username and password for authentication").Base(err) 123 } 124 125 if !s.config.HasAccount(username, password) { 126 writeSocks5AuthenticationResponse(writer, 0x01, 0xFF) // nolint: errcheck 127 return "", newError("invalid username or password") 128 } 129 130 if err := writeSocks5AuthenticationResponse(writer, 0x01, 0x00); err != nil { 131 return "", newError("failed to write auth response").Base(err) 132 } 133 return username, nil 134 } 135 136 return "", nil 137 } 138 139 func (s *ServerSession) handshake5(nMethod byte, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { 140 var ( 141 username string 142 err error 143 ) 144 if username, err = s.auth5(nMethod, reader, writer); err != nil { 145 return nil, err 146 } 147 148 var cmd byte 149 { 150 buffer := buf.StackNew() 151 if _, err := buffer.ReadFullFrom(reader, 3); err != nil { 152 buffer.Release() 153 return nil, newError("failed to read request").Base(err) 154 } 155 cmd = buffer.Byte(1) 156 buffer.Release() 157 } 158 159 request := new(protocol.RequestHeader) 160 if username != "" { 161 request.User = &protocol.MemoryUser{Email: username} 162 } 163 switch cmd { 164 case cmdTCPConnect, cmdTorResolve, cmdTorResolvePTR: 165 // We don't have a solution for Tor case now. Simply treat it as connect command. 166 request.Command = protocol.RequestCommandTCP 167 case cmdUDPPort: 168 if !s.config.UdpEnabled { 169 writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) // nolint: errcheck 170 return nil, newError("UDP is not enabled.") 171 } 172 request.Command = protocol.RequestCommandUDP 173 case cmdTCPBind: 174 writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) // nolint: errcheck 175 return nil, newError("TCP bind is not supported.") 176 default: 177 writeSocks5Response(writer, statusCmdNotSupport, net.AnyIP, net.Port(0)) // nolint: errcheck 178 return nil, newError("unknown command ", cmd) 179 } 180 181 request.Version = socks5Version 182 183 addr, port, err := addrParser.ReadAddressPort(nil, reader) 184 if err != nil { 185 return nil, newError("failed to read address").Base(err) 186 } 187 request.Address = addr 188 request.Port = port 189 190 responseAddress := net.AnyIP 191 responsePort := net.Port(1717) 192 if request.Command == protocol.RequestCommandUDP { 193 addr := s.config.Address.AsAddress() 194 if addr == nil { 195 addr = net.LocalHostIP 196 } 197 responseAddress = addr 198 responsePort = s.port 199 } 200 if err := writeSocks5Response(writer, statusSuccess, responseAddress, responsePort); err != nil { 201 return nil, err 202 } 203 204 return request, nil 205 } 206 207 // Handshake performs a Socks4/4a/5 handshake. 208 func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { 209 buffer := buf.StackNew() 210 if _, err := buffer.ReadFullFrom(reader, 2); err != nil { 211 buffer.Release() 212 return nil, newError("insufficient header").Base(err) 213 } 214 215 version := buffer.Byte(0) 216 cmd := buffer.Byte(1) 217 buffer.Release() 218 219 switch version { 220 case socks4Version: 221 return s.handshake4(cmd, reader, writer) 222 case socks5Version: 223 return s.handshake5(cmd, reader, writer) 224 default: 225 return nil, newError("unknown Socks version: ", version) 226 } 227 } 228 229 // ReadUsernamePassword reads Socks 5 username/password message from the given reader. 230 // +----+------+----------+------+----------+ 231 // |VER | ULEN | UNAME | PLEN | PASSWD | 232 // +----+------+----------+------+----------+ 233 // | 1 | 1 | 1 to 255 | 1 | 1 to 255 | 234 // +----+------+----------+------+----------+ 235 func ReadUsernamePassword(reader io.Reader) (string, string, error) { 236 buffer := buf.StackNew() 237 defer buffer.Release() 238 239 if _, err := buffer.ReadFullFrom(reader, 2); err != nil { 240 return "", "", err 241 } 242 nUsername := int32(buffer.Byte(1)) 243 244 buffer.Clear() 245 if _, err := buffer.ReadFullFrom(reader, nUsername); err != nil { 246 return "", "", err 247 } 248 username := buffer.String() 249 250 buffer.Clear() 251 if _, err := buffer.ReadFullFrom(reader, 1); err != nil { 252 return "", "", err 253 } 254 nPassword := int32(buffer.Byte(0)) 255 256 buffer.Clear() 257 if _, err := buffer.ReadFullFrom(reader, nPassword); err != nil { 258 return "", "", err 259 } 260 password := buffer.String() 261 return username, password, nil 262 } 263 264 // ReadUntilNull reads content from given reader, until a null (0x00) byte. 265 func ReadUntilNull(reader io.Reader) (string, error) { 266 b := buf.StackNew() 267 defer b.Release() 268 269 for { 270 _, err := b.ReadFullFrom(reader, 1) 271 if err != nil { 272 return "", err 273 } 274 if b.Byte(b.Len()-1) == 0x00 { 275 b.Resize(0, b.Len()-1) 276 return b.String(), nil 277 } 278 if b.IsFull() { 279 return "", newError("buffer overrun") 280 } 281 } 282 } 283 284 func hasAuthMethod(expectedAuth byte, authCandidates []byte) bool { 285 for _, a := range authCandidates { 286 if a == expectedAuth { 287 return true 288 } 289 } 290 return false 291 } 292 293 func writeSocks5AuthenticationResponse(writer io.Writer, version byte, auth byte) error { 294 return buf.WriteAllBytes(writer, []byte{version, auth}) 295 } 296 297 func writeSocks5Response(writer io.Writer, errCode byte, address net.Address, port net.Port) error { 298 buffer := buf.New() 299 defer buffer.Release() 300 301 common.Must2(buffer.Write([]byte{socks5Version, errCode, 0x00 /* reserved */})) 302 if err := addrParser.WriteAddressPort(buffer, address, port); err != nil { 303 return err 304 } 305 306 return buf.WriteAllBytes(writer, buffer.Bytes()) 307 } 308 309 func writeSocks4Response(writer io.Writer, errCode byte, address net.Address, port net.Port) error { 310 buffer := buf.StackNew() 311 defer buffer.Release() 312 313 common.Must(buffer.WriteByte(0x00)) 314 common.Must(buffer.WriteByte(errCode)) 315 portBytes := buffer.Extend(2) 316 binary.BigEndian.PutUint16(portBytes, port.Value()) 317 common.Must2(buffer.Write(address.IP())) 318 return buf.WriteAllBytes(writer, buffer.Bytes()) 319 } 320 321 func DecodeUDPPacket(packet *buf.Buffer) (*protocol.RequestHeader, error) { 322 if packet.Len() < 5 { 323 return nil, newError("insufficient length of packet.") 324 } 325 request := &protocol.RequestHeader{ 326 Version: socks5Version, 327 Command: protocol.RequestCommandUDP, 328 } 329 330 // packet[0] and packet[1] are reserved 331 if packet.Byte(2) != 0 /* fragments */ { 332 return nil, newError("discarding fragmented payload.") 333 } 334 335 packet.Advance(3) 336 337 addr, port, err := addrParser.ReadAddressPort(nil, packet) 338 if err != nil { 339 return nil, newError("failed to read UDP header").Base(err) 340 } 341 request.Address = addr 342 request.Port = port 343 return request, nil 344 } 345 346 func EncodeUDPPacket(request *protocol.RequestHeader, data []byte) (*buf.Buffer, error) { 347 b := buf.New() 348 common.Must2(b.Write([]byte{0, 0, 0 /* Fragment */})) 349 if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil { 350 b.Release() 351 return nil, err 352 } 353 common.Must2(b.Write(data)) 354 return b, nil 355 } 356 357 type UDPReader struct { 358 reader io.Reader 359 } 360 361 func NewUDPReader(reader io.Reader) *UDPReader { 362 return &UDPReader{reader: reader} 363 } 364 365 func (r *UDPReader) ReadMultiBuffer() (buf.MultiBuffer, error) { 366 b := buf.New() 367 if _, err := b.ReadFrom(r.reader); err != nil { 368 return nil, err 369 } 370 if _, err := DecodeUDPPacket(b); err != nil { 371 return nil, err 372 } 373 return buf.MultiBuffer{b}, nil 374 } 375 376 type UDPWriter struct { 377 request *protocol.RequestHeader 378 writer io.Writer 379 } 380 381 func NewUDPWriter(request *protocol.RequestHeader, writer io.Writer) *UDPWriter { 382 return &UDPWriter{ 383 request: request, 384 writer: writer, 385 } 386 } 387 388 // Write implements io.Writer. 389 func (w *UDPWriter) Write(b []byte) (int, error) { 390 eb, err := EncodeUDPPacket(w.request, b) 391 if err != nil { 392 return 0, err 393 } 394 defer eb.Release() 395 if _, err := w.writer.Write(eb.Bytes()); err != nil { 396 return 0, err 397 } 398 return len(b), nil 399 } 400 401 func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer io.Writer) (*protocol.RequestHeader, error) { 402 authByte := byte(authNotRequired) 403 if request.User != nil { 404 authByte = byte(authPassword) 405 } 406 407 b := buf.New() 408 defer b.Release() 409 410 common.Must2(b.Write([]byte{socks5Version, 0x01, authByte})) 411 if authByte == authPassword { 412 account := request.User.Account.(*Account) 413 414 common.Must(b.WriteByte(0x01)) 415 common.Must(b.WriteByte(byte(len(account.Username)))) 416 common.Must2(b.WriteString(account.Username)) 417 common.Must(b.WriteByte(byte(len(account.Password)))) 418 common.Must2(b.WriteString(account.Password)) 419 } 420 421 if err := buf.WriteAllBytes(writer, b.Bytes()); err != nil { 422 return nil, err 423 } 424 425 b.Clear() 426 if _, err := b.ReadFullFrom(reader, 2); err != nil { 427 return nil, err 428 } 429 430 if b.Byte(0) != socks5Version { 431 return nil, newError("unexpected server version: ", b.Byte(0)).AtWarning() 432 } 433 if b.Byte(1) != authByte { 434 return nil, newError("auth method not supported.").AtWarning() 435 } 436 437 if authByte == authPassword { 438 b.Clear() 439 if _, err := b.ReadFullFrom(reader, 2); err != nil { 440 return nil, err 441 } 442 if b.Byte(1) != 0x00 { 443 return nil, newError("server rejects account: ", b.Byte(1)) 444 } 445 } 446 447 b.Clear() 448 449 command := byte(cmdTCPConnect) 450 if request.Command == protocol.RequestCommandUDP { 451 command = byte(cmdUDPPort) 452 } 453 common.Must2(b.Write([]byte{socks5Version, command, 0x00 /* reserved */})) 454 if err := addrParser.WriteAddressPort(b, request.Address, request.Port); err != nil { 455 return nil, err 456 } 457 458 if err := buf.WriteAllBytes(writer, b.Bytes()); err != nil { 459 return nil, err 460 } 461 462 b.Clear() 463 if _, err := b.ReadFullFrom(reader, 3); err != nil { 464 return nil, err 465 } 466 467 resp := b.Byte(1) 468 if resp != 0x00 { 469 return nil, newError("server rejects request: ", resp) 470 } 471 472 b.Clear() 473 474 address, port, err := addrParser.ReadAddressPort(b, reader) 475 if err != nil { 476 return nil, err 477 } 478 479 if request.Command == protocol.RequestCommandUDP { 480 udpRequest := &protocol.RequestHeader{ 481 Version: socks5Version, 482 Command: protocol.RequestCommandUDP, 483 Address: address, 484 Port: port, 485 } 486 return udpRequest, nil 487 } 488 489 return nil, nil 490 }