socks.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package v4
  2. import (
  3. "encoding/json"
  4. "strings"
  5. "github.com/golang/protobuf/proto"
  6. "github.com/v2fly/v2ray-core/v5/common/net/packetaddr"
  7. "github.com/v2fly/v2ray-core/v5/common/protocol"
  8. "github.com/v2fly/v2ray-core/v5/common/serial"
  9. "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon"
  10. "github.com/v2fly/v2ray-core/v5/proxy/socks"
  11. )
  12. type SocksAccount struct {
  13. Username string `json:"user"`
  14. Password string `json:"pass"`
  15. }
  16. func (v *SocksAccount) Build() *socks.Account {
  17. return &socks.Account{
  18. Username: v.Username,
  19. Password: v.Password,
  20. }
  21. }
  22. const (
  23. AuthMethodNoAuth = "noauth"
  24. AuthMethodUserPass = "password"
  25. )
  26. type SocksServerConfig struct {
  27. AuthMethod string `json:"auth"`
  28. Accounts []*SocksAccount `json:"accounts"`
  29. UDP bool `json:"udp"`
  30. Host *cfgcommon.Address `json:"ip"`
  31. Timeout uint32 `json:"timeout"`
  32. UserLevel uint32 `json:"userLevel"`
  33. PacketEncoding string `json:"packetEncoding"`
  34. }
  35. func (v *SocksServerConfig) Build() (proto.Message, error) {
  36. config := new(socks.ServerConfig)
  37. switch v.AuthMethod {
  38. case AuthMethodNoAuth:
  39. config.AuthType = socks.AuthType_NO_AUTH
  40. case AuthMethodUserPass:
  41. config.AuthType = socks.AuthType_PASSWORD
  42. default:
  43. // newError("unknown socks auth method: ", v.AuthMethod, ". Default to noauth.").AtWarning().WriteToLog()
  44. config.AuthType = socks.AuthType_NO_AUTH
  45. }
  46. if len(v.Accounts) > 0 {
  47. config.Accounts = make(map[string]string, len(v.Accounts))
  48. for _, account := range v.Accounts {
  49. config.Accounts[account.Username] = account.Password
  50. }
  51. }
  52. config.UdpEnabled = v.UDP
  53. if v.Host != nil {
  54. config.Address = v.Host.Build()
  55. }
  56. config.Timeout = v.Timeout
  57. config.UserLevel = v.UserLevel
  58. switch v.PacketEncoding {
  59. case "Packet":
  60. config.PacketEncoding = packetaddr.PacketAddrType_Packet
  61. case "", "None":
  62. config.PacketEncoding = packetaddr.PacketAddrType_None
  63. }
  64. return config, nil
  65. }
  66. type SocksRemoteConfig struct {
  67. Address *cfgcommon.Address `json:"address"`
  68. Port uint16 `json:"port"`
  69. Users []json.RawMessage `json:"users"`
  70. }
  71. type SocksClientConfig struct {
  72. Servers []*SocksRemoteConfig `json:"servers"`
  73. Version string `json:"version"`
  74. }
  75. func (v *SocksClientConfig) Build() (proto.Message, error) {
  76. config := new(socks.ClientConfig)
  77. config.Server = make([]*protocol.ServerEndpoint, len(v.Servers))
  78. switch strings.ToLower(v.Version) {
  79. case "4":
  80. config.Version = socks.Version_SOCKS4
  81. case "4a":
  82. config.Version = socks.Version_SOCKS4A
  83. case "", "5":
  84. config.Version = socks.Version_SOCKS5
  85. default:
  86. return nil, newError("failed to parse socks server version: ", v.Version).AtError()
  87. }
  88. for idx, serverConfig := range v.Servers {
  89. server := &protocol.ServerEndpoint{
  90. Address: serverConfig.Address.Build(),
  91. Port: uint32(serverConfig.Port),
  92. }
  93. for _, rawUser := range serverConfig.Users {
  94. user := new(protocol.User)
  95. if err := json.Unmarshal(rawUser, user); err != nil {
  96. return nil, newError("failed to parse Socks user").Base(err).AtError()
  97. }
  98. account := new(SocksAccount)
  99. if err := json.Unmarshal(rawUser, account); err != nil {
  100. return nil, newError("failed to parse socks account").Base(err).AtError()
  101. }
  102. if config.Version != socks.Version_SOCKS5 && account.Password != "" {
  103. return nil, newError("password is only supported in socks5").AtError()
  104. }
  105. user.Account = serial.ToTypedMessage(account.Build())
  106. server.User = append(server.User, user)
  107. }
  108. config.Server[idx] = server
  109. }
  110. return config, nil
  111. }