package parser import ( "encoding/base64" "fmt" "net/url" "strconv" "strings" "github.com/subconverter-go/internal/logging" ) // ShadowsocksParser Shadowsocks协议解析器 // 实现Shadowsocks代理配置的解析功能 type ShadowsocksParser struct { logger *logging.Logger } // NewShadowsocksParser 创建新的Shadowsocks解析器 // 返回初始化好的ShadowsocksParser实例 func NewShadowsocksParser(logger *logging.Logger) *ShadowsocksParser { return &ShadowsocksParser{ logger: logger, } } // Parse 解析Shadowsocks配置 // 支持标准格式和Base64编码格式 func (p *ShadowsocksParser) Parse(input string) (*ProxyConfig, error) { p.logger.Debugf("Parsing Shadowsocks configuration") // 去除前缀 input = strings.TrimPrefix(input, "ss://") // 解码Base64部分 var decodedBytes []byte var err error // 尝试直接解析 if strings.Contains(input, "@") { decodedBytes = []byte(input) } else { // 尝试Base64解码 decodedBytes, err = base64.StdEncoding.DecodeString(input) if err != nil { // 尝试URL安全的Base64解码 decodedBytes, err = base64.URLEncoding.DecodeString(input) if err != nil { return nil, fmt.Errorf("failed to decode Shadowsocks configuration: %v", err) } } } decoded := string(decodedBytes) // 解析方法:密码@服务器:端口#备注 parts := strings.Split(decoded, "@") if len(parts) != 2 { return nil, fmt.Errorf("invalid Shadowsocks configuration format") } // 解析认证信息 authInfo := parts[0] serverInfo := parts[1] // 解析服务器信息 serverParts := strings.Split(serverInfo, "#") if len(serverParts) == 0 { return nil, fmt.Errorf("invalid server information") } // 解析地址和端口 addrParts := strings.Split(serverParts[0], ":") if len(addrParts) != 2 { return nil, fmt.Errorf("invalid server address format") } config := &ProxyConfig{ Type: "ss", } // 解析认证信息 authParts := strings.Split(authInfo, ":") if len(authParts) == 1 { // 可能是完整的URL格式 return p.parseURLFormat(input) } if len(authParts) != 2 { return nil, fmt.Errorf("invalid authentication information format") } // 创建设置映射 settings := map[string]interface{}{ "method": authParts[0], "password": authParts[1], "udp": true, } // 设置配置 config.Server = addrParts[0] // 解析端口 port, err := strconv.Atoi(addrParts[1]) if err != nil { return nil, fmt.Errorf("invalid port number: %v", err) } config.Port = port // 解析备注 if len(serverParts) > 1 { config.Name = serverParts[1] } else { config.Name = fmt.Sprintf("ss-%s:%d", config.Server, config.Port) } // 设置默认值 config.UDP = true config.Protocol = "ss" config.Settings = settings p.logger.Infof("Successfully parsed Shadowsocks configuration for server: %s:%d", config.Server, config.Port) return config, nil } // parseURLFormat 解析URL格式的Shadowsocks配置 func (p *ShadowsocksParser) parseURLFormat(input string) (*ProxyConfig, error) { // 添加协议前缀 if !strings.HasPrefix(input, "ss://") { input = "ss://" + input } // 解析URL parsedURL, err := url.Parse(input) if err != nil { return nil, fmt.Errorf("failed to parse Shadowsocks URL: %v", err) } config := &ProxyConfig{ Type: "ss", } // 解码用户信息 userInfoBytes, err := base64.StdEncoding.DecodeString(parsedURL.User.String()) if err != nil { // 尝试URL安全的Base64解码 userInfoBytes, err = base64.URLEncoding.DecodeString(parsedURL.User.String()) if err != nil { return nil, fmt.Errorf("failed to decode user info: %v", err) } } userInfo := string(userInfoBytes) // 解析方法和密码 authParts := strings.Split(userInfo, ":") if len(authParts) != 2 { return nil, fmt.Errorf("invalid authentication information") } config.Server = parsedURL.Hostname() // 解析端口 port, err := strconv.Atoi(parsedURL.Port()) if err != nil { return nil, fmt.Errorf("invalid port number: %v", err) } config.Port = port // 解析查询参数 query := parsedURL.Query() if plugin := query.Get("plugin"); plugin != "" { config.Settings = map[string]interface{}{ "method": authParts[0], "password": authParts[1], "plugin": plugin, "udp": true, } } else { config.Settings = map[string]interface{}{ "method": authParts[0], "password": authParts[1], "udp": true, } } // 解析备注 if parsedURL.Fragment != "" { config.Name = parsedURL.Fragment } else { config.Name = fmt.Sprintf("ss-%s:%d", config.Server, config.Port) } // 设置默认值 config.UDP = true config.Protocol = "ss" p.logger.Infof("Successfully parsed Shadowsocks URL configuration for server: %s:%d", config.Server, config.Port) return config, nil } // Validate 验证Shadowsocks配置 func (p *ShadowsocksParser) Validate(config *ProxyConfig) error { p.logger.Debugf("Validating Shadowsocks configuration") // 检查必要字段 method := p.getMethod(config) if method == "" { return fmt.Errorf("encryption method is required") } password := p.getPassword(config) if password == "" { return fmt.Errorf("password is required") } if config.Server == "" { return fmt.Errorf("server address is required") } if config.Port <= 0 || config.Port > 65535 { return fmt.Errorf("invalid port number: %d", config.Port) } // 验证加密方法 supportedMethods := []string{ "aes-256-cfb", "aes-128-cfb", "aes-192-cfb", "aes-256-ctr", "aes-128-ctr", "aes-192-ctr", "aes-256-gcm", "aes-128-gcm", "aes-192-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "rc4-md5", "salsa20", "chacha20", } methodSupported := false for _, method := range supportedMethods { if method == method { methodSupported = true break } } if !methodSupported { p.logger.Warnf("Unsupported encryption method: %s", method) } // 验证插件配置 if plugin, exists := config.Settings["plugin"]; exists { if pluginStr, ok := plugin.(string); ok && pluginStr != "" { p.logger.Debugf("Shadowsocks plugin detected: %s", pluginStr) } } p.logger.Debug("Shadowsocks configuration validation passed") return nil } // getMethod 从配置中获取加密方法 func (p *ShadowsocksParser) getMethod(config *ProxyConfig) string { if method, exists := config.Settings["method"]; exists { if methodStr, ok := method.(string); ok { return methodStr } } return "" } // getPassword 从配置中获取密码 func (p *ShadowsocksParser) getPassword(config *ProxyConfig) string { if password, exists := config.Settings["password"]; exists { if passwordStr, ok := password.(string); ok { return passwordStr } } return "" } // GetSupportedProtocols 获取支持的协议 func (p *ShadowsocksParser) GetSupportedProtocols() []string { return []string{"ss"} }