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  }