You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
6.7 KiB
225 lines
6.7 KiB
2 weeks ago
|
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" // 默认端口
|
||
|
}
|