socks.go 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // Package socks contains protocol definition and io lib for SOCKS5 protocol
  2. package socks
  3. import (
  4. "fmt"
  5. "io"
  6. )
  7. const (
  8. socksVersion = uint8(5)
  9. )
  10. // Authentication request header of Socks5 protocol
  11. type Socks5AuthenticationRequest struct {
  12. version byte
  13. authMethods [256]byte
  14. }
  15. func ReadAuthentication(reader io.Reader) (auth Socks5AuthenticationRequest, err error) {
  16. buffer := make([]byte, 2)
  17. nBytes, err := reader.Read(buffer)
  18. if err != nil {
  19. return
  20. }
  21. if nBytes < 2 {
  22. err = fmt.Errorf("Expected 2 bytes read, but actaully %d bytes read", nBytes)
  23. return
  24. }
  25. auth.version = buffer[0]
  26. if auth.version != socksVersion {
  27. err = fmt.Errorf("Unknown SOCKS version %d", auth.version)
  28. return
  29. }
  30. nMethods := buffer[1]
  31. if nMethods <= 0 {
  32. err = fmt.Errorf("Zero length of authentication methods")
  33. return
  34. }
  35. buffer = make([]byte, nMethods)
  36. nBytes, err = reader.Read(buffer)
  37. copy(auth.authMethods[:nBytes], buffer)
  38. return
  39. }
  40. type Socks5AuthenticationResponse struct {
  41. version byte
  42. authMethod byte
  43. }
  44. func (r *Socks5AuthenticationResponse) ToBytes() []byte {
  45. buffer := make([]byte, 2 /* size of Socks5AuthenticationResponse */)
  46. buffer[0] = r.version
  47. buffer[1] = r.authMethod
  48. return buffer
  49. }
  50. func WriteAuthentication(writer io.Writer, response Socks5AuthenticationResponse) error {
  51. _, err := writer.Write(response.ToBytes())
  52. if err != nil {
  53. return err
  54. }
  55. return nil
  56. }