94 lines
2.2 KiB
Go
94 lines
2.2 KiB
Go
//go:build darwin && !ios && !ios_target
|
|
|
|
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"time"
|
|
|
|
"overlord-client/cmd/agent/mutex"
|
|
agentRuntime "overlord-client/cmd/agent/runtime"
|
|
"overlord-client/cmd/agent/wire"
|
|
)
|
|
|
|
func HandleElevate(ctx context.Context, env *agentRuntime.Env, cmdID string, password string) error {
|
|
if os.Getuid() == 0 {
|
|
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
|
Type: "command_result",
|
|
CommandID: cmdID,
|
|
OK: true,
|
|
Message: "already running as root",
|
|
})
|
|
}
|
|
|
|
if password == "" {
|
|
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
|
Type: "command_result",
|
|
CommandID: cmdID,
|
|
OK: false,
|
|
Message: "password required for elevation",
|
|
})
|
|
}
|
|
|
|
exePath, err := os.Executable()
|
|
if err != nil {
|
|
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
|
Type: "command_result",
|
|
CommandID: cmdID,
|
|
OK: false,
|
|
Message: fmt.Sprintf("failed to resolve executable path: %v", err),
|
|
})
|
|
}
|
|
|
|
validateCmd := exec.Command("sudo", "-S", "-k", "true")
|
|
validateCmd.Stdin = strings.NewReader(password + "\n")
|
|
if err := validateCmd.Run(); err != nil {
|
|
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
|
Type: "command_result",
|
|
CommandID: cmdID,
|
|
OK: false,
|
|
Message: "incorrect password",
|
|
})
|
|
}
|
|
|
|
args := os.Args[1:]
|
|
sudoArgs := append([]string{"-S", "-k", exePath}, args...)
|
|
cmd := exec.Command("sudo", sudoArgs...)
|
|
cmd.Stdin = strings.NewReader(password + "\n")
|
|
cmd.Env = os.Environ()
|
|
|
|
nullFile, _ := os.OpenFile(os.DevNull, os.O_RDWR, 0)
|
|
if nullFile != nil {
|
|
cmd.Stdout = nullFile
|
|
cmd.Stderr = nullFile
|
|
}
|
|
|
|
if err := cmd.Start(); err != nil {
|
|
return wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
|
Type: "command_result",
|
|
CommandID: cmdID,
|
|
OK: false,
|
|
Message: fmt.Sprintf("failed to start elevated process: %v", err),
|
|
})
|
|
}
|
|
|
|
mutex.ReleaseGlobal()
|
|
log.Printf("[elevate] started elevated process pid=%d", cmd.Process.Pid)
|
|
|
|
_ = wire.WriteMsg(ctx, env.Conn, wire.CommandResult{
|
|
Type: "command_result",
|
|
CommandID: cmdID,
|
|
OK: true,
|
|
Message: "elevating — new process started as root",
|
|
})
|
|
|
|
time.Sleep(500 * time.Millisecond)
|
|
os.Exit(0)
|
|
return nil
|
|
}
|