Hunter0x7c7
2022-08-11 a82f9cb69f63aaeba40c024960deda7d75b9fece
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package v4
 
import (
    "github.com/golang/protobuf/proto"
 
    "github.com/v2fly/v2ray-core/v5/common/protocol"
    "github.com/v2fly/v2ray-core/v5/common/serial"
    "github.com/v2fly/v2ray-core/v5/infra/conf/cfgcommon"
    "github.com/v2fly/v2ray-core/v5/proxy/shadowsocks"
)
 
type ShadowsocksServerConfig struct {
    Cipher      string                 `json:"method"`
    Password    string                 `json:"password"`
    UDP         bool                   `json:"udp"`
    Level       byte                   `json:"level"`
    Email       string                 `json:"email"`
    NetworkList *cfgcommon.NetworkList `json:"network"`
    IVCheck     bool                   `json:"ivCheck"`
}
 
func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
    config := new(shadowsocks.ServerConfig)
    config.UdpEnabled = v.UDP
    config.Network = v.NetworkList.Build()
 
    if v.Password == "" {
        return nil, newError("Shadowsocks password is not specified.")
    }
    account := &shadowsocks.Account{
        Password: v.Password,
        IvCheck:  v.IVCheck,
    }
    account.CipherType = shadowsocks.CipherFromString(v.Cipher)
    if account.CipherType == shadowsocks.CipherType_UNKNOWN {
        return nil, newError("unknown cipher method: ", v.Cipher)
    }
 
    config.User = &protocol.User{
        Email:   v.Email,
        Level:   uint32(v.Level),
        Account: serial.ToTypedMessage(account),
    }
 
    return config, nil
}
 
type ShadowsocksServerTarget struct {
    Address  *cfgcommon.Address `json:"address"`
    Port     uint16             `json:"port"`
    Cipher   string             `json:"method"`
    Password string             `json:"password"`
    Email    string             `json:"email"`
    Ota      bool               `json:"ota"`
    Level    byte               `json:"level"`
    IVCheck  bool               `json:"ivCheck"`
}
 
type ShadowsocksClientConfig struct {
    Servers []*ShadowsocksServerTarget `json:"servers"`
}
 
func (v *ShadowsocksClientConfig) Build() (proto.Message, error) {
    config := new(shadowsocks.ClientConfig)
 
    if len(v.Servers) == 0 {
        return nil, newError("0 Shadowsocks server configured.")
    }
 
    serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers))
    for idx, server := range v.Servers {
        if server.Address == nil {
            return nil, newError("Shadowsocks server address is not set.")
        }
        if server.Port == 0 {
            return nil, newError("Invalid Shadowsocks port.")
        }
        if server.Password == "" {
            return nil, newError("Shadowsocks password is not specified.")
        }
        account := &shadowsocks.Account{
            Password: server.Password,
        }
        account.CipherType = shadowsocks.CipherFromString(server.Cipher)
        if account.CipherType == shadowsocks.CipherType_UNKNOWN {
            return nil, newError("unknown cipher method: ", server.Cipher)
        }
 
        account.IvCheck = server.IVCheck
 
        ss := &protocol.ServerEndpoint{
            Address: server.Address.Build(),
            Port:    uint32(server.Port),
            User: []*protocol.User{
                {
                    Level:   uint32(server.Level),
                    Email:   server.Email,
                    Account: serial.ToTypedMessage(account),
                },
            },
        }
 
        serverSpecs[idx] = ss
    }
 
    config.Server = serverSpecs
 
    return config, nil
}