socks5.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package socks5
  2. import (
  3. "bufio"
  4. "fmt"
  5. "log"
  6. "net"
  7. "os"
  8. "golang.org/x/net/context"
  9. )
  10. const (
  11. socks5Version = uint8(5)
  12. )
  13. // Config is used to setup and configure a Server
  14. type Config struct {
  15. // AuthMethods can be provided to implement custom authentication
  16. // By default, "auth-less" mode is enabled.
  17. // For password-based auth use UserPassAuthenticator.
  18. AuthMethods []Authenticator
  19. // If provided, username/password authentication is enabled,
  20. // by appending a UserPassAuthenticator to AuthMethods. If not provided,
  21. // and AUthMethods is nil, then "auth-less" mode is enabled.
  22. Credentials CredentialStore
  23. // Resolver can be provided to do custom name resolution.
  24. // Defaults to DNSResolver if not provided.
  25. Resolver NameResolver
  26. // Rules is provided to enable custom logic around permitting
  27. // various commands. If not provided, PermitAll is used.
  28. Rules RuleSet
  29. // Rewriter can be used to transparently rewrite addresses.
  30. // This is invoked before the RuleSet is invoked.
  31. // Defaults to NoRewrite.
  32. Rewriter AddressRewriter
  33. // BindIP is used for bind or udp associate
  34. BindIP net.IP
  35. // Logger can be used to provide a custom log target.
  36. // Defaults to stdout.
  37. Logger *log.Logger
  38. // Optional function for dialing out
  39. Dial func(ctx context.Context, network, addr string) (net.Conn, error)
  40. }
  41. // Server is reponsible for accepting connections and handling
  42. // the details of the SOCKS5 protocol
  43. type Server struct {
  44. config *Config
  45. authMethods map[uint8]Authenticator
  46. }
  47. // New creates a new Server and potentially returns an error
  48. func New(conf *Config) (*Server, error) {
  49. // Ensure we have at least one authentication method enabled
  50. if len(conf.AuthMethods) == 0 {
  51. if conf.Credentials != nil {
  52. conf.AuthMethods = []Authenticator{&UserPassAuthenticator{conf.Credentials}}
  53. } else {
  54. conf.AuthMethods = []Authenticator{&NoAuthAuthenticator{}}
  55. }
  56. }
  57. // Ensure we have a DNS resolver
  58. if conf.Resolver == nil {
  59. conf.Resolver = DNSResolver{}
  60. }
  61. // Ensure we have a rule set
  62. if conf.Rules == nil {
  63. conf.Rules = PermitAll()
  64. }
  65. // Ensure we have a log target
  66. if conf.Logger == nil {
  67. conf.Logger = log.New(os.Stdout, "", log.LstdFlags)
  68. }
  69. server := &Server{
  70. config: conf,
  71. }
  72. server.authMethods = make(map[uint8]Authenticator)
  73. for _, a := range conf.AuthMethods {
  74. server.authMethods[a.GetCode()] = a
  75. }
  76. return server, nil
  77. }
  78. // ListenAndServe is used to create a listener and serve on it
  79. func (s *Server) ListenAndServe(network, addr string) error {
  80. l, err := net.Listen(network, addr)
  81. if err != nil {
  82. return err
  83. }
  84. return s.Serve(l)
  85. }
  86. // Serve is used to serve connections from a listener
  87. func (s *Server) Serve(l net.Listener) error {
  88. for {
  89. conn, err := l.Accept()
  90. if err != nil {
  91. return err
  92. }
  93. go s.ServeConn(conn)
  94. }
  95. return nil
  96. }
  97. // ServeConn is used to serve a single connection.
  98. func (s *Server) ServeConn(conn net.Conn) error {
  99. defer conn.Close()
  100. bufConn := bufio.NewReader(conn)
  101. // Read the version byte
  102. version := []byte{0}
  103. if _, err := bufConn.Read(version); err != nil {
  104. s.config.Logger.Printf("[ERR] socks: Failed to get version byte: %v", err)
  105. return err
  106. }
  107. // Ensure we are compatible
  108. if version[0] != socks5Version {
  109. err := fmt.Errorf("Unsupported SOCKS version: %v", version)
  110. s.config.Logger.Printf("[ERR] socks: %v", err)
  111. return err
  112. }
  113. // Authenticate the connection
  114. authContext, err := s.authenticate(conn, bufConn)
  115. if err != nil {
  116. err = fmt.Errorf("Failed to authenticate: %v", err)
  117. s.config.Logger.Printf("[ERR] socks: %v", err)
  118. return err
  119. }
  120. request, err := NewRequest(bufConn)
  121. if err != nil {
  122. if err == unrecognizedAddrType {
  123. if err := sendReply(conn, addrTypeNotSupported, nil); err != nil {
  124. return fmt.Errorf("Failed to send reply: %v", err)
  125. }
  126. }
  127. return fmt.Errorf("Failed to read destination address: %v", err)
  128. }
  129. request.AuthContext = authContext
  130. if client, ok := conn.RemoteAddr().(*net.TCPAddr); ok {
  131. request.RemoteAddr = &AddrSpec{IP: client.IP, Port: client.Port}
  132. }
  133. // Process the client request
  134. if err := s.handleRequest(request, conn); err != nil {
  135. err = fmt.Errorf("Failed to handle request: %v", err)
  136. s.config.Logger.Printf("[ERR] socks: %v", err)
  137. return err
  138. }
  139. return nil
  140. }