|
|
|
package system
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"runtime"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/azoic/wormhole-client/pkg/logger"
|
|
|
|
)
|
|
|
|
|
|
|
|
// SystemProxyManager 系统代理管理器
|
|
|
|
type SystemProxyManager struct {
|
|
|
|
originalSettings map[string]string
|
|
|
|
isEnabled bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewSystemProxyManager 创建系统代理管理器
|
|
|
|
func NewSystemProxyManager() *SystemProxyManager {
|
|
|
|
return &SystemProxyManager{
|
|
|
|
originalSettings: make(map[string]string),
|
|
|
|
isEnabled: false,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetGlobalProxy 设置全局代理
|
|
|
|
func (s *SystemProxyManager) SetGlobalProxy(httpProxy, httpsProxy, socksProxy string) error {
|
|
|
|
logger.Info("Setting system proxy...")
|
|
|
|
logger.Debug("HTTP: %s, HTTPS: %s, SOCKS: %s", httpProxy, httpsProxy, socksProxy)
|
|
|
|
|
|
|
|
var err error
|
|
|
|
switch runtime.GOOS {
|
|
|
|
case "darwin":
|
|
|
|
err = s.setMacOSProxy(httpProxy, httpsProxy, socksProxy)
|
|
|
|
case "windows":
|
|
|
|
err = s.setWindowsProxy(httpProxy, httpsProxy, socksProxy)
|
|
|
|
case "linux":
|
|
|
|
err = s.setLinuxProxy(httpProxy, httpsProxy, socksProxy)
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
s.isEnabled = true
|
|
|
|
logger.Info("✅ System proxy configured successfully")
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// RestoreProxy 恢复原始代理设置
|
|
|
|
func (s *SystemProxyManager) RestoreProxy() error {
|
|
|
|
if !s.isEnabled {
|
|
|
|
logger.Debug("System proxy was not enabled, nothing to restore")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.Info("Restoring system proxy...")
|
|
|
|
|
|
|
|
var err error
|
|
|
|
switch runtime.GOOS {
|
|
|
|
case "darwin":
|
|
|
|
err = s.restoreMacOSProxy()
|
|
|
|
case "windows":
|
|
|
|
err = s.restoreWindowsProxy()
|
|
|
|
case "linux":
|
|
|
|
err = s.restoreLinuxProxy()
|
|
|
|
default:
|
|
|
|
return fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err == nil {
|
|
|
|
s.isEnabled = false
|
|
|
|
logger.Info("✅ System proxy restored successfully")
|
|
|
|
}
|
|
|
|
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// IsEnabled 检查代理是否已启用
|
|
|
|
func (s *SystemProxyManager) IsEnabled() bool {
|
|
|
|
return s.isEnabled
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetCurrentProxy 获取当前代理设置
|
|
|
|
func (s *SystemProxyManager) GetCurrentProxy() (map[string]string, error) {
|
|
|
|
switch runtime.GOOS {
|
|
|
|
case "darwin":
|
|
|
|
return s.getMacOSCurrentProxy()
|
|
|
|
case "windows":
|
|
|
|
return s.getWindowsCurrentProxy()
|
|
|
|
case "linux":
|
|
|
|
return s.getLinuxCurrentProxy()
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("unsupported operating system: %s", runtime.GOOS)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ===================== macOS 实现 =====================
|
|
|
|
|
|
|
|
// macOS 代理设置
|
|
|
|
func (s *SystemProxyManager) setMacOSProxy(httpProxy, httpsProxy, socksProxy string) error {
|
|
|
|
// 获取网络服务名称
|
|
|
|
networkService, err := s.getMacOSNetworkService()
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to get network service: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.Debug("Using network service: %s", networkService)
|
|
|
|
|
|
|
|
// 保存原始设置
|
|
|
|
if err := s.saveMacOSOriginalSettings(networkService); err != nil {
|
|
|
|
logger.Warn("Failed to save original proxy settings: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置HTTP代理
|
|
|
|
if httpProxy != "" {
|
|
|
|
host, port := s.parseProxyHostPort(httpProxy)
|
|
|
|
if err := s.runCommand("networksetup", "-setwebproxy", networkService, host, port); 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)
|
|
|
|
}
|
|
|
|
logger.Debug("HTTP proxy set to %s", httpProxy)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置HTTPS代理
|
|
|
|
if httpsProxy != "" {
|
|
|
|
host, port := s.parseProxyHostPort(httpsProxy)
|
|
|
|
if err := s.runCommand("networksetup", "-setsecurewebproxy", networkService, host, port); 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)
|
|
|
|
}
|
|
|
|
logger.Debug("HTTPS proxy set to %s", httpsProxy)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置SOCKS代理
|
|
|
|
if socksProxy != "" {
|
|
|
|
host, port := s.parseProxyHostPort(socksProxy)
|
|
|
|
if err := s.runCommand("networksetup", "-setsocksfirewallproxy", networkService, host, port); 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.Debug("SOCKS proxy set to %s", socksProxy)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取macOS网络服务名称
|
|
|
|
func (s *SystemProxyManager) getMacOSNetworkService() (string, error) {
|
|
|
|
output, err := exec.Command("networksetup", "-listallnetworkservices").Output()
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("failed to list network services: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
lines := strings.Split(string(output), "\n")
|
|
|
|
|
|
|
|
// 优先查找Wi-Fi服务
|
|
|
|
for _, line := range lines {
|
|
|
|
line = strings.TrimSpace(line)
|
|
|
|
if line != "" && !strings.HasPrefix(line, "*") && !strings.Contains(line, "An asterisk") {
|
|
|
|
lower := strings.ToLower(line)
|
|
|
|
if strings.Contains(lower, "wi-fi") || strings.Contains(lower, "wifi") {
|
|
|
|
return line, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 查找以太网服务
|
|
|
|
for _, line := range lines {
|
|
|
|
line = strings.TrimSpace(line)
|
|
|
|
if line != "" && !strings.HasPrefix(line, "*") && !strings.Contains(line, "An asterisk") {
|
|
|
|
lower := strings.ToLower(line)
|
|
|
|
if strings.Contains(lower, "ethernet") || strings.Contains(lower, "thunderbolt") {
|
|
|
|
return line, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 返回第一个可用的服务
|
|
|
|
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 active network service found")
|
|
|
|
}
|
|
|
|
|
|
|
|
// 保存macOS原始代理设置
|
|
|
|
func (s *SystemProxyManager) saveMacOSOriginalSettings(networkService string) error {
|
|
|
|
commands := map[string][]string{
|
|
|
|
"http_proxy": {"-getwebproxy", networkService},
|
|
|
|
"https_proxy": {"-getsecurewebproxy", networkService},
|
|
|
|
"socks_proxy": {"-getsocksfirewallproxy", networkService},
|
|
|
|
}
|
|
|
|
|
|
|
|
for key, args := range commands {
|
|
|
|
if output, err := exec.Command("networksetup", args...).Output(); err == nil {
|
|
|
|
s.originalSettings[key] = strings.TrimSpace(string(output))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s.originalSettings["network_service"] = networkService
|
|
|
|
logger.Debug("Saved original proxy settings for %s", 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")
|
|
|
|
}
|
|
|
|
|
|
|
|
// 关闭所有代理
|
|
|
|
commands := [][]string{
|
|
|
|
{"-setwebproxystate", networkService, "off"},
|
|
|
|
{"-setsecurewebproxystate", networkService, "off"},
|
|
|
|
{"-setsocksfirewallproxystate", networkService, "off"},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, args := range commands {
|
|
|
|
if err := s.runCommand("networksetup", args...); err != nil {
|
|
|
|
logger.Warn("Failed to restore proxy setting: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取macOS当前代理设置
|
|
|
|
func (s *SystemProxyManager) getMacOSCurrentProxy() (map[string]string, error) {
|
|
|
|
networkService, err := s.getMacOSNetworkService()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
result := make(map[string]string)
|
|
|
|
|
|
|
|
// 获取HTTP代理
|
|
|
|
if output, err := exec.Command("networksetup", "-getwebproxy", networkService).Output(); err == nil {
|
|
|
|
result["http"] = strings.TrimSpace(string(output))
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取HTTPS代理
|
|
|
|
if output, err := exec.Command("networksetup", "-getsecurewebproxy", networkService).Output(); err == nil {
|
|
|
|
result["https"] = strings.TrimSpace(string(output))
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取SOCKS代理
|
|
|
|
if output, err := exec.Command("networksetup", "-getsocksfirewallproxy", networkService).Output(); err == nil {
|
|
|
|
result["socks"] = strings.TrimSpace(string(output))
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ===================== Windows 实现 =====================
|
|
|
|
|
|
|
|
// Windows 代理设置
|
|
|
|
func (s *SystemProxyManager) setWindowsProxy(httpProxy, httpsProxy, socksProxy string) error {
|
|
|
|
// 保存当前设置
|
|
|
|
if err := s.saveWindowsOriginalSettings(); err != nil {
|
|
|
|
logger.Warn("Failed to save Windows proxy settings: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置HTTP/HTTPS代理
|
|
|
|
if httpProxy != "" {
|
|
|
|
// 使用 netsh 或注册表设置代理
|
|
|
|
proxyServer := httpProxy
|
|
|
|
if httpsProxy != "" && httpsProxy != httpProxy {
|
|
|
|
proxyServer = fmt.Sprintf("http=%s;https=%s", httpProxy, httpsProxy)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 使用PowerShell设置代理
|
|
|
|
cmd := fmt.Sprintf(`
|
|
|
|
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
|
|
|
|
Set-ItemProperty -Path $regPath -Name ProxyEnable -Value 1
|
|
|
|
Set-ItemProperty -Path $regPath -Name ProxyServer -Value "%s"
|
|
|
|
`, proxyServer)
|
|
|
|
|
|
|
|
if err := s.runPowerShell(cmd); err != nil {
|
|
|
|
return fmt.Errorf("failed to set Windows proxy: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.Debug("Windows HTTP proxy set to %s", proxyServer)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 保存Windows原始代理设置
|
|
|
|
func (s *SystemProxyManager) saveWindowsOriginalSettings() error {
|
|
|
|
// 读取当前注册表设置
|
|
|
|
cmd := `
|
|
|
|
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
|
|
|
|
$enable = Get-ItemProperty -Path $regPath -Name ProxyEnable -ErrorAction SilentlyContinue
|
|
|
|
$server = Get-ItemProperty -Path $regPath -Name ProxyServer -ErrorAction SilentlyContinue
|
|
|
|
Write-Output "ProxyEnable:$($enable.ProxyEnable)"
|
|
|
|
Write-Output "ProxyServer:$($server.ProxyServer)"
|
|
|
|
`
|
|
|
|
|
|
|
|
output, err := s.runPowerShellWithOutput(cmd)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
lines := strings.Split(output, "\n")
|
|
|
|
for _, line := range lines {
|
|
|
|
if strings.HasPrefix(line, "ProxyEnable:") {
|
|
|
|
s.originalSettings["windows_proxy_enable"] = strings.TrimPrefix(line, "ProxyEnable:")
|
|
|
|
} else if strings.HasPrefix(line, "ProxyServer:") {
|
|
|
|
s.originalSettings["windows_proxy_server"] = strings.TrimPrefix(line, "ProxyServer:")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 恢复Windows代理设置
|
|
|
|
func (s *SystemProxyManager) restoreWindowsProxy() error {
|
|
|
|
enable := s.originalSettings["windows_proxy_enable"]
|
|
|
|
server := s.originalSettings["windows_proxy_server"]
|
|
|
|
|
|
|
|
cmd := fmt.Sprintf(`
|
|
|
|
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
|
|
|
|
Set-ItemProperty -Path $regPath -Name ProxyEnable -Value %s
|
|
|
|
Set-ItemProperty -Path $regPath -Name ProxyServer -Value "%s"
|
|
|
|
`, strings.TrimSpace(enable), strings.TrimSpace(server))
|
|
|
|
|
|
|
|
return s.runPowerShell(cmd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取Windows当前代理设置
|
|
|
|
func (s *SystemProxyManager) getWindowsCurrentProxy() (map[string]string, error) {
|
|
|
|
cmd := `
|
|
|
|
$regPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings"
|
|
|
|
$enable = Get-ItemProperty -Path $regPath -Name ProxyEnable -ErrorAction SilentlyContinue
|
|
|
|
$server = Get-ItemProperty -Path $regPath -Name ProxyServer -ErrorAction SilentlyContinue
|
|
|
|
Write-Output "ProxyEnable:$($enable.ProxyEnable)"
|
|
|
|
Write-Output "ProxyServer:$($server.ProxyServer)"
|
|
|
|
`
|
|
|
|
|
|
|
|
output, err := s.runPowerShellWithOutput(cmd)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
result := make(map[string]string)
|
|
|
|
lines := strings.Split(output, "\n")
|
|
|
|
for _, line := range lines {
|
|
|
|
if strings.HasPrefix(line, "ProxyEnable:") {
|
|
|
|
result["enabled"] = strings.TrimSpace(strings.TrimPrefix(line, "ProxyEnable:"))
|
|
|
|
} else if strings.HasPrefix(line, "ProxyServer:") {
|
|
|
|
result["server"] = strings.TrimSpace(strings.TrimPrefix(line, "ProxyServer:"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ===================== Linux 实现 =====================
|
|
|
|
|
|
|
|
// Linux 代理设置
|
|
|
|
func (s *SystemProxyManager) setLinuxProxy(httpProxy, httpsProxy, socksProxy string) error {
|
|
|
|
// 保存当前环境变量
|
|
|
|
s.saveLinuxOriginalSettings()
|
|
|
|
|
|
|
|
envVars := []string{}
|
|
|
|
|
|
|
|
if httpProxy != "" {
|
|
|
|
envVars = append(envVars, fmt.Sprintf("export http_proxy=%s", httpProxy))
|
|
|
|
envVars = append(envVars, fmt.Sprintf("export HTTP_PROXY=%s", httpProxy))
|
|
|
|
}
|
|
|
|
|
|
|
|
if httpsProxy != "" {
|
|
|
|
envVars = append(envVars, fmt.Sprintf("export https_proxy=%s", httpsProxy))
|
|
|
|
envVars = append(envVars, fmt.Sprintf("export HTTPS_PROXY=%s", httpsProxy))
|
|
|
|
}
|
|
|
|
|
|
|
|
if socksProxy != "" {
|
|
|
|
envVars = append(envVars, fmt.Sprintf("export socks_proxy=%s", socksProxy))
|
|
|
|
envVars = append(envVars, fmt.Sprintf("export SOCKS_PROXY=%s", socksProxy))
|
|
|
|
}
|
|
|
|
|
|
|
|
// 写入到 /etc/environment (需要root权限)
|
|
|
|
envContent := strings.Join(envVars, "\n") + "\n"
|
|
|
|
|
|
|
|
// 尝试写入系统环境变量文件
|
|
|
|
if err := s.writeLinuxSystemProxy(envContent); err != nil {
|
|
|
|
logger.Warn("Failed to write system proxy settings: %v", err)
|
|
|
|
logger.Info("Please manually add the following to your shell profile:")
|
|
|
|
for _, env := range envVars {
|
|
|
|
logger.Info(" %s", env)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 设置当前会话的环境变量
|
|
|
|
for _, env := range envVars {
|
|
|
|
parts := strings.SplitN(strings.TrimPrefix(env, "export "), "=", 2)
|
|
|
|
if len(parts) == 2 {
|
|
|
|
os.Setenv(parts[0], parts[1])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 保存Linux原始代理设置
|
|
|
|
func (s *SystemProxyManager) saveLinuxOriginalSettings() {
|
|
|
|
envVars := []string{"http_proxy", "https_proxy", "socks_proxy", "HTTP_PROXY", "HTTPS_PROXY", "SOCKS_PROXY"}
|
|
|
|
|
|
|
|
for _, env := range envVars {
|
|
|
|
if value := os.Getenv(env); value != "" {
|
|
|
|
s.originalSettings["linux_"+env] = value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 恢复Linux代理设置
|
|
|
|
func (s *SystemProxyManager) restoreLinuxProxy() error {
|
|
|
|
// 清除当前会话的环境变量
|
|
|
|
envVars := []string{"http_proxy", "https_proxy", "socks_proxy", "HTTP_PROXY", "HTTPS_PROXY", "SOCKS_PROXY"}
|
|
|
|
|
|
|
|
for _, env := range envVars {
|
|
|
|
originalKey := "linux_" + env
|
|
|
|
if originalValue, exists := s.originalSettings[originalKey]; exists {
|
|
|
|
os.Setenv(env, originalValue)
|
|
|
|
} else {
|
|
|
|
os.Unsetenv(env)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
logger.Info("Environment variables restored (session only)")
|
|
|
|
logger.Info("Note: You may need to manually remove proxy settings from system files")
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 获取Linux当前代理设置
|
|
|
|
func (s *SystemProxyManager) getLinuxCurrentProxy() (map[string]string, error) {
|
|
|
|
result := make(map[string]string)
|
|
|
|
|
|
|
|
envVars := map[string]string{
|
|
|
|
"http": "http_proxy",
|
|
|
|
"https": "https_proxy",
|
|
|
|
"socks": "socks_proxy",
|
|
|
|
}
|
|
|
|
|
|
|
|
for key, env := range envVars {
|
|
|
|
if value := os.Getenv(env); value != "" {
|
|
|
|
result[key] = value
|
|
|
|
} else if value := os.Getenv(strings.ToUpper(env)); value != "" {
|
|
|
|
result[key] = value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, 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 fmt.Errorf("command '%s %s' failed: %v", name, strings.Join(args, " "), err)
|
|
|
|
}
|
|
|
|
logger.Debug("Command succeeded: %s %v", name, args)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 运行PowerShell命令 (Windows)
|
|
|
|
func (s *SystemProxyManager) runPowerShell(script string) error {
|
|
|
|
cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script)
|
|
|
|
output, err := cmd.CombinedOutput()
|
|
|
|
if err != nil {
|
|
|
|
logger.Error("PowerShell command failed: %s, output: %s", script, string(output))
|
|
|
|
return fmt.Errorf("PowerShell command failed: %v", err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 运行PowerShell命令并获取输出 (Windows)
|
|
|
|
func (s *SystemProxyManager) runPowerShellWithOutput(script string) (string, error) {
|
|
|
|
cmd := exec.Command("powershell", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", script)
|
|
|
|
output, err := cmd.Output()
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("PowerShell command failed: %v", err)
|
|
|
|
}
|
|
|
|
return string(output), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// 写入Linux系统代理设置
|
|
|
|
func (s *SystemProxyManager) writeLinuxSystemProxy(content string) error {
|
|
|
|
// 尝试写入 /etc/environment
|
|
|
|
envFile := "/etc/environment"
|
|
|
|
|
|
|
|
// 检查是否有写权限
|
|
|
|
if _, err := os.Stat(envFile); os.IsNotExist(err) {
|
|
|
|
return fmt.Errorf("file %s does not exist", envFile)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 备份原文件
|
|
|
|
if err := exec.Command("cp", envFile, envFile+".wormhole.backup").Run(); err != nil {
|
|
|
|
logger.Warn("Failed to backup %s: %v", envFile, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// 追加代理设置
|
|
|
|
f, err := os.OpenFile(envFile, os.O_APPEND|os.O_WRONLY, 0644)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
|
|
|
_, err = f.WriteString("\n# Wormhole SOCKS5 Client Proxy Settings\n" + content)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// 解析代理地址
|
|
|
|
func (s *SystemProxyManager) parseProxyHostPort(proxy string) (host, port string) {
|
|
|
|
// 移除协议前缀
|
|
|
|
proxy = strings.TrimPrefix(proxy, "http://")
|
|
|
|
proxy = strings.TrimPrefix(proxy, "https://")
|
|
|
|
proxy = strings.TrimPrefix(proxy, "socks5://")
|
|
|
|
|
|
|
|
parts := strings.Split(proxy, ":")
|
|
|
|
if len(parts) >= 2 {
|
|
|
|
host = parts[0]
|
|
|
|
port = parts[1]
|
|
|
|
} else {
|
|
|
|
host = proxy
|
|
|
|
port = "8080" // 默认端口
|
|
|
|
}
|
|
|
|
|
|
|
|
// 验证端口
|
|
|
|
if _, err := strconv.Atoi(port); err != nil {
|
|
|
|
port = "8080"
|
|
|
|
}
|
|
|
|
|
|
|
|
return host, port
|
|
|
|
}
|