github.com/eagleql/xray-core@v1.4.4/infra/conf/shadowsocks.go (about) 1 package conf 2 3 import ( 4 "strings" 5 6 "github.com/golang/protobuf/proto" 7 8 "github.com/eagleql/xray-core/common/protocol" 9 "github.com/eagleql/xray-core/common/serial" 10 "github.com/eagleql/xray-core/proxy/shadowsocks" 11 ) 12 13 func cipherFromString(c string) shadowsocks.CipherType { 14 switch strings.ToLower(c) { 15 case "aes-256-cfb": 16 return shadowsocks.CipherType_AES_256_CFB 17 case "aes-128-cfb": 18 return shadowsocks.CipherType_AES_128_CFB 19 case "chacha20": 20 return shadowsocks.CipherType_CHACHA20 21 case "chacha20-ietf": 22 return shadowsocks.CipherType_CHACHA20_IETF 23 case "aes-128-gcm", "aead_aes_128_gcm": 24 return shadowsocks.CipherType_AES_128_GCM 25 case "aes-256-gcm", "aead_aes_256_gcm": 26 return shadowsocks.CipherType_AES_256_GCM 27 case "chacha20-poly1305", "aead_chacha20_poly1305", "chacha20-ietf-poly1305": 28 return shadowsocks.CipherType_CHACHA20_POLY1305 29 case "none", "plain": 30 return shadowsocks.CipherType_NONE 31 default: 32 return shadowsocks.CipherType_UNKNOWN 33 } 34 } 35 36 type ShadowsocksUserConfig struct { 37 Cipher string `json:"method"` 38 Password string `json:"password"` 39 Level byte `json:"level"` 40 Email string `json:"email"` 41 } 42 43 type ShadowsocksServerConfig struct { 44 Cipher string `json:"method"` 45 Password string `json:"password"` 46 Level byte `json:"level"` 47 Email string `json:"email"` 48 Users []*ShadowsocksUserConfig `json:"clients"` 49 NetworkList *NetworkList `json:"network"` 50 } 51 52 func (v *ShadowsocksServerConfig) Build() (proto.Message, error) { 53 config := new(shadowsocks.ServerConfig) 54 config.Network = v.NetworkList.Build() 55 56 if v.Users != nil { 57 for _, user := range v.Users { 58 account := &shadowsocks.Account{ 59 Password: user.Password, 60 CipherType: cipherFromString(user.Cipher), 61 } 62 if account.Password == "" { 63 return nil, newError("Shadowsocks password is not specified.") 64 } 65 if account.CipherType < 5 || account.CipherType > 7 { 66 return nil, newError("unsupported cipher method: ", user.Cipher) 67 } 68 config.Users = append(config.Users, &protocol.User{ 69 Email: user.Email, 70 Level: uint32(user.Level), 71 Account: serial.ToTypedMessage(account), 72 }) 73 } 74 } else { 75 account := &shadowsocks.Account{ 76 Password: v.Password, 77 CipherType: cipherFromString(v.Cipher), 78 } 79 if account.Password == "" { 80 return nil, newError("Shadowsocks password is not specified.") 81 } 82 if account.CipherType == shadowsocks.CipherType_UNKNOWN { 83 return nil, newError("unknown cipher method: ", v.Cipher) 84 } 85 config.Users = append(config.Users, &protocol.User{ 86 Email: v.Email, 87 Level: uint32(v.Level), 88 Account: serial.ToTypedMessage(account), 89 }) 90 } 91 92 return config, nil 93 } 94 95 type ShadowsocksServerTarget struct { 96 Address *Address `json:"address"` 97 Port uint16 `json:"port"` 98 Cipher string `json:"method"` 99 Password string `json:"password"` 100 Email string `json:"email"` 101 Level byte `json:"level"` 102 } 103 104 type ShadowsocksClientConfig struct { 105 Servers []*ShadowsocksServerTarget `json:"servers"` 106 } 107 108 func (v *ShadowsocksClientConfig) Build() (proto.Message, error) { 109 config := new(shadowsocks.ClientConfig) 110 111 if len(v.Servers) == 0 { 112 return nil, newError("0 Shadowsocks server configured.") 113 } 114 115 serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers)) 116 for idx, server := range v.Servers { 117 if server.Address == nil { 118 return nil, newError("Shadowsocks server address is not set.") 119 } 120 if server.Port == 0 { 121 return nil, newError("Invalid Shadowsocks port.") 122 } 123 if server.Password == "" { 124 return nil, newError("Shadowsocks password is not specified.") 125 } 126 account := &shadowsocks.Account{ 127 Password: server.Password, 128 } 129 account.CipherType = cipherFromString(server.Cipher) 130 if account.CipherType == shadowsocks.CipherType_UNKNOWN { 131 return nil, newError("unknown cipher method: ", server.Cipher) 132 } 133 134 ss := &protocol.ServerEndpoint{ 135 Address: server.Address.Build(), 136 Port: uint32(server.Port), 137 User: []*protocol.User{ 138 { 139 Level: uint32(server.Level), 140 Email: server.Email, 141 Account: serial.ToTypedMessage(account), 142 }, 143 }, 144 } 145 146 serverSpecs[idx] = ss 147 } 148 149 config.Server = serverSpecs 150 151 return config, nil 152 }