package system import ( "fmt" "os/exec" "runtime" "strings" "github.com/azoic/wormhole-client/pkg/logger" ) // SystemProxyManager 系统代理管理器 type SystemProxyManager struct { originalSettings map[string]string } // NewSystemProxyManager 创建系统代理管理器 func NewSystemProxyManager() *SystemProxyManager { return &SystemProxyManager{ originalSettings: make(map[string]string), } } // SetGlobalProxy 设置全局代理 func (s *SystemProxyManager) SetGlobalProxy(httpProxy, httpsProxy, socksProxy string) error { switch runtime.GOOS { case "darwin": return s.setMacOSProxy(httpProxy, httpsProxy, socksProxy) case "windows": return s.setWindowsProxy(httpProxy, httpsProxy, socksProxy) case "linux": return s.setLinuxProxy(httpProxy, httpsProxy, socksProxy) default: return fmt.Errorf("unsupported operating system: %s", runtime.GOOS) } } // RestoreProxy 恢复原始代理设置 func (s *SystemProxyManager) RestoreProxy() error { switch runtime.GOOS { case "darwin": return s.restoreMacOSProxy() case "windows": return s.restoreWindowsProxy() case "linux": return s.restoreLinuxProxy() default: return fmt.Errorf("unsupported operating system: %s", runtime.GOOS) } } // macOS 代理设置 func (s *SystemProxyManager) setMacOSProxy(httpProxy, httpsProxy, socksProxy string) error { logger.Info("Setting macOS system proxy...") // 获取网络服务名称 networkService, err := s.getMacOSNetworkService() if err != nil { return fmt.Errorf("failed to get network service: %v", err) } // 保存原始设置 if err := s.saveMacOSOriginalSettings(networkService); err != nil { logger.Warn("Failed to save original proxy settings: %v", err) } // 设置HTTP代理 if httpProxy != "" { if err := s.runCommand("networksetup", "-setwebproxy", networkService, s.parseProxyHost(httpProxy), s.parseProxyPort(httpProxy)); err != nil { return fmt.Errorf("failed to set HTTP proxy: %v", err) } if err := s.runCommand("networksetup", "-setwebproxystate", networkService, "on"); err != nil { return fmt.Errorf("failed to enable HTTP proxy: %v", err) } } // 设置HTTPS代理 if httpsProxy != "" { if err := s.runCommand("networksetup", "-setsecurewebproxy", networkService, s.parseProxyHost(httpsProxy), s.parseProxyPort(httpsProxy)); err != nil { return fmt.Errorf("failed to set HTTPS proxy: %v", err) } if err := s.runCommand("networksetup", "-setsecurewebproxystate", networkService, "on"); err != nil { return fmt.Errorf("failed to enable HTTPS proxy: %v", err) } } // 设置SOCKS代理 if socksProxy != "" { if err := s.runCommand("networksetup", "-setsocksfirewallproxy", networkService, s.parseProxyHost(socksProxy), s.parseProxyPort(socksProxy)); err != nil { return fmt.Errorf("failed to set SOCKS proxy: %v", err) } if err := s.runCommand("networksetup", "-setsocksfirewallproxystate", networkService, "on"); err != nil { return fmt.Errorf("failed to enable SOCKS proxy: %v", err) } } logger.Info("macOS system proxy configured successfully") return nil } // 获取macOS网络服务名称 func (s *SystemProxyManager) getMacOSNetworkService() (string, error) { output, err := exec.Command("networksetup", "-listallnetworkservices").Output() if err != nil { return "", err } lines := strings.Split(string(output), "\n") for _, line := range lines { line = strings.TrimSpace(line) if line != "" && !strings.HasPrefix(line, "*") && !strings.Contains(line, "An asterisk") { // 优先选择Wi-Fi,否则选择第一个可用的服务 if strings.Contains(strings.ToLower(line), "wi-fi") || strings.Contains(strings.ToLower(line), "wifi") { return line, nil } } } // 如果没找到Wi-Fi,返回第一个可用的服务 for _, line := range lines { line = strings.TrimSpace(line) if line != "" && !strings.HasPrefix(line, "*") && !strings.Contains(line, "An asterisk") { return line, nil } } return "", fmt.Errorf("no network service found") } // 保存macOS原始代理设置 func (s *SystemProxyManager) saveMacOSOriginalSettings(networkService string) error { // 保存HTTP代理状态 if output, err := exec.Command("networksetup", "-getwebproxy", networkService).Output(); err == nil { s.originalSettings["http_proxy"] = string(output) } // 保存HTTPS代理状态 if output, err := exec.Command("networksetup", "-getsecurewebproxy", networkService).Output(); err == nil { s.originalSettings["https_proxy"] = string(output) } // 保存SOCKS代理状态 if output, err := exec.Command("networksetup", "-getsocksfirewallproxy", networkService).Output(); err == nil { s.originalSettings["socks_proxy"] = string(output) } s.originalSettings["network_service"] = networkService return nil } // 恢复macOS代理设置 func (s *SystemProxyManager) restoreMacOSProxy() error { networkService, exists := s.originalSettings["network_service"] if !exists { return fmt.Errorf("no network service information saved") } logger.Info("Restoring macOS system proxy...") // 关闭所有代理 s.runCommand("networksetup", "-setwebproxystate", networkService, "off") s.runCommand("networksetup", "-setsecurewebproxystate", networkService, "off") s.runCommand("networksetup", "-setsocksfirewallproxystate", networkService, "off") logger.Info("macOS system proxy restored") return nil } // Windows 代理设置(简化实现) func (s *SystemProxyManager) setWindowsProxy(httpProxy, httpsProxy, socksProxy string) error { logger.Warn("Windows proxy setting not fully implemented") return fmt.Errorf("Windows proxy setting not implemented yet") } func (s *SystemProxyManager) restoreWindowsProxy() error { logger.Warn("Windows proxy restoration not fully implemented") return nil } // Linux 代理设置(简化实现) func (s *SystemProxyManager) setLinuxProxy(httpProxy, httpsProxy, socksProxy string) error { logger.Warn("Linux proxy setting not fully implemented") return fmt.Errorf("Linux proxy setting not implemented yet") } func (s *SystemProxyManager) restoreLinuxProxy() error { logger.Warn("Linux proxy restoration not fully implemented") return nil } // 辅助函数 func (s *SystemProxyManager) runCommand(name string, args ...string) error { cmd := exec.Command(name, args...) output, err := cmd.CombinedOutput() if err != nil { logger.Error("Command failed: %s %v, output: %s", name, args, string(output)) return err } return nil } func (s *SystemProxyManager) parseProxyHost(proxy string) string { // 简单解析,格式: host:port parts := strings.Split(proxy, ":") if len(parts) >= 1 { return parts[0] } return proxy } func (s *SystemProxyManager) parseProxyPort(proxy string) string { // 简单解析,格式: host:port parts := strings.Split(proxy, ":") if len(parts) >= 2 { return parts[1] } return "8080" // 默认端口 }