github.com/sagernet/sing-box@v1.2.7/common/settings/proxy_linux.go (about) 1 //go:build linux && !android 2 3 package settings 4 5 import ( 6 "os" 7 "os/exec" 8 "strings" 9 10 "github.com/sagernet/sing-box/adapter" 11 "github.com/sagernet/sing/common" 12 E "github.com/sagernet/sing/common/exceptions" 13 F "github.com/sagernet/sing/common/format" 14 "github.com/sagernet/sing/common/shell" 15 ) 16 17 var ( 18 hasGSettings bool 19 sudoUser string 20 ) 21 22 func init() { 23 hasGSettings = common.Error(exec.LookPath("gsettings")) == nil 24 if os.Getuid() == 0 { 25 sudoUser = os.Getenv("SUDO_USER") 26 } 27 } 28 29 func runAsUser(name string, args ...string) error { 30 if os.Getuid() != 0 { 31 return shell.Exec(name, args...).Attach().Run() 32 } else if sudoUser != "" { 33 return shell.Exec("su", "-", sudoUser, "-c", F.ToString(name, " ", strings.Join(args, " "))).Attach().Run() 34 } else { 35 return E.New("set system proxy: unable to set as root") 36 } 37 } 38 39 func SetSystemProxy(router adapter.Router, port uint16, isMixed bool) (func() error, error) { 40 if !hasGSettings { 41 return nil, E.New("unsupported desktop environment") 42 } 43 err := runAsUser("gsettings", "set", "org.gnome.system.proxy.http", "enabled", "true") 44 if err != nil { 45 return nil, err 46 } 47 if isMixed { 48 err = setGnomeProxy(port, "ftp", "http", "https", "socks") 49 } else { 50 err = setGnomeProxy(port, "http", "https") 51 } 52 if err != nil { 53 return nil, err 54 } 55 err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "use-same-proxy", F.ToString(isMixed)) 56 if err != nil { 57 return nil, err 58 } 59 err = runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "manual") 60 if err != nil { 61 return nil, err 62 } 63 return func() error { 64 return runAsUser("gsettings", "set", "org.gnome.system.proxy", "mode", "none") 65 }, nil 66 } 67 68 func setGnomeProxy(port uint16, proxyTypes ...string) error { 69 for _, proxyType := range proxyTypes { 70 err := runAsUser("gsettings", "set", "org.gnome.system.proxy."+proxyType, "host", "127.0.0.1") 71 if err != nil { 72 return err 73 } 74 err = runAsUser("gsettings", "set", "org.gnome.system.proxy."+proxyType, "port", F.ToString(port)) 75 if err != nil { 76 return err 77 } 78 } 79 return nil 80 }