mirror of
https://github.com/netbirdio/netbird.git
synced 2025-06-21 18:22:37 +02:00
Limit GUI process execution to one per UID (#2267)
replaces PID with checking process name and path and UID checks
This commit is contained in:
parent
bc09348f5a
commit
2577100096
@ -15,7 +15,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
@ -34,6 +33,7 @@ import (
|
|||||||
"github.com/netbirdio/netbird/client/internal"
|
"github.com/netbirdio/netbird/client/internal"
|
||||||
"github.com/netbirdio/netbird/client/proto"
|
"github.com/netbirdio/netbird/client/proto"
|
||||||
"github.com/netbirdio/netbird/client/system"
|
"github.com/netbirdio/netbird/client/system"
|
||||||
|
"github.com/netbirdio/netbird/util"
|
||||||
"github.com/netbirdio/netbird/version"
|
"github.com/netbirdio/netbird/version"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -62,8 +62,25 @@ func main() {
|
|||||||
var errorMSG string
|
var errorMSG string
|
||||||
flag.StringVar(&errorMSG, "error-msg", "", "displays a error message window")
|
flag.StringVar(&errorMSG, "error-msg", "", "displays a error message window")
|
||||||
|
|
||||||
|
tmpDir := "/tmp"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
tmpDir = os.TempDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
var saveLogsInFile bool
|
||||||
|
flag.BoolVar(&saveLogsInFile, "use-log-file", false, fmt.Sprintf("save logs in a file: %s/netbird-ui-PID.log", tmpDir))
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
if saveLogsInFile {
|
||||||
|
logFile := path.Join(tmpDir, fmt.Sprintf("netbird-ui-%d.log", os.Getpid()))
|
||||||
|
err := util.InitLog("trace", logFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("error while initializing log: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
a := app.NewWithID("NetBird")
|
a := app.NewWithID("NetBird")
|
||||||
a.SetIcon(fyne.NewStaticResource("netbird", iconDisconnectedPNG))
|
a.SetIcon(fyne.NewStaticResource("netbird", iconDisconnectedPNG))
|
||||||
|
|
||||||
@ -76,8 +93,12 @@ func main() {
|
|||||||
if showSettings || showRoutes {
|
if showSettings || showRoutes {
|
||||||
a.Run()
|
a.Run()
|
||||||
} else {
|
} else {
|
||||||
if err := checkPIDFile(); err != nil {
|
running, err := isAnotherProcessRunning()
|
||||||
log.Errorf("check PID file: %v", err)
|
if err != nil {
|
||||||
|
log.Errorf("error while checking process: %v", err)
|
||||||
|
}
|
||||||
|
if running {
|
||||||
|
log.Warn("another process is running")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
client.setDefaultFonts()
|
client.setDefaultFonts()
|
||||||
@ -861,19 +882,3 @@ func openURL(url string) error {
|
|||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkPIDFile exists and return error, or write new.
|
|
||||||
func checkPIDFile() error {
|
|
||||||
pidFile := path.Join(os.TempDir(), "wiretrustee-ui.pid")
|
|
||||||
if piddata, err := os.ReadFile(pidFile); err == nil {
|
|
||||||
if pid, err := strconv.Atoi(string(piddata)); err == nil {
|
|
||||||
if process, err := os.FindProcess(pid); err == nil {
|
|
||||||
if err := process.Signal(syscall.Signal(0)); err == nil {
|
|
||||||
return fmt.Errorf("process already exists: %d", pid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return os.WriteFile(pidFile, []byte(fmt.Sprintf("%d", os.Getpid())), 0o664) //nolint:gosec
|
|
||||||
}
|
|
||||||
|
37
client/ui/process.go
Normal file
37
client/ui/process.go
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isAnotherProcessRunning() (bool, error) {
|
||||||
|
processes, err := process.Processes()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
pid := os.Getpid()
|
||||||
|
processName := strings.ToLower(filepath.Base(os.Args[0]))
|
||||||
|
|
||||||
|
for _, p := range processes {
|
||||||
|
if int(p.Pid) == pid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
runningProcessPath, err := p.Exe()
|
||||||
|
// most errors are related to short-lived processes
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(strings.ToLower(runningProcessPath), processName) && isProcessOwnedByCurrentUser(p) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, nil
|
||||||
|
}
|
26
client/ui/process_nonwindows.go
Normal file
26
client/ui/process_nonwindows.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//go:build !windows
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isProcessOwnedByCurrentUser(p *process.Process) bool {
|
||||||
|
currentUserID := os.Getuid()
|
||||||
|
uids, err := p.Uids()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("get process uids: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, id := range uids {
|
||||||
|
log.Debugf("checking process uid: %d", id)
|
||||||
|
if int(id) == currentUserID {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
24
client/ui/process_windows.go
Normal file
24
client/ui/process_windows.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os/user"
|
||||||
|
|
||||||
|
"github.com/shirou/gopsutil/v3/process"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func isProcessOwnedByCurrentUser(p *process.Process) bool {
|
||||||
|
processUsername, err := p.Username()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("get process username error: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
currUser, err := user.Current()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("get current user error: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return processUsername == currUser.Username
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user