bastion 0.53.2
ci / personal-data (push) Successful in 5s
ci / test (push) Successful in 3m4s
ci / fuzz (push) Successful in 3m45s

This commit is contained in:
Privatae
2026-10-20 04:42:14 +00:00
commit e4c9b69b46
471 changed files with 159794 additions and 0 deletions
+169
View File
@@ -0,0 +1,169 @@
//go:build darwin
package main
// The macOS half of sysservice.go: a launchd daemon in the system domain.
//
// launchctl is run by its absolute path with a fixed argument list. This code
// runs as root, so a launchctl found through PATH would be whatever the
// caller's PATH named first.
import (
"errors"
"fmt"
"io/fs"
"os"
"os/exec"
"path/filepath"
"strings"
"syscall"
"time"
)
const launchctlPath = "/bin/launchctl"
// systemServiceInstalled reports whether the daemon's job file is in place. A
// file that cannot be checked is reported as an error, which the caller treats
// as installed for the guard (adoptSystemServiceState).
func systemServiceInstalled() (bool, error) {
_, err := os.Stat(launchdPlistPath)
if err == nil {
return true, nil
}
if errors.Is(err, fs.ErrNotExist) {
return false, nil
}
return false, err
}
// darwinOwnerMode is pathOwnerMode for this machine: Lstat, so a symlink is
// seen as one rather than followed.
func darwinOwnerMode(p string) (uint32, fs.FileMode, error) {
fi, err := os.Lstat(p)
if err != nil {
return 0, 0, err
}
st, ok := fi.Sys().(*syscall.Stat_t)
if !ok {
return 0, 0, fmt.Errorf("no owner information for %s", p)
}
return st.Uid, fi.Mode(), nil
}
func installSystemService() error {
self, err := resolvedSelf()
if err != nil {
return fmt.Errorf("cannot find this program's own path: %w", err)
}
if err := binaryChainRootOnly(self, darwinOwnerMode); err != nil {
return fmt.Errorf("refusing to register %s as the system service: %w.\n"+
" The installer's --networked option puts the program in a folder only root can change", self, err)
}
plist, err := launchdPlist(self)
if err != nil {
return err
}
if err := writeRootFile(launchdPlistPath, plist, 0o644); err != nil {
return fmt.Errorf("cannot write %s: %w", launchdPlistPath, err)
}
// launchd creates a missing log file readable by everyone. What the bastion
// reports about this machine (the agents it sees, the hosts it serves) is
// the administrator's to read, so the file is made first, root-only, and
// launchd appends to it as it finds it.
if f, err := os.OpenFile(darwinDaemonLog, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600); err == nil {
_ = f.Close()
}
_ = os.Chmod(darwinDaemonLog, 0o600)
// A job already loaded under this label keeps its old definition until it
// is booted out, so a reinstall boots it out first. Not loaded is fine.
_ = exec.Command(launchctlPath, "bootout", "system/"+launchdLabel).Run()
// bootout returns before launchd has finished removing the job, and a
// bootstrap in that window fails. A few short retries cover it.
var out []byte
for i := 0; i < 5; i++ {
out, err = exec.Command(launchctlPath, "bootstrap", "system", launchdPlistPath).CombinedOutput()
if err == nil {
break
}
time.Sleep(time.Second)
}
if err != nil {
return fmt.Errorf("launchctl bootstrap failed: %v: %s", err, strings.TrimSpace(string(out)))
}
_ = exec.Command(launchctlPath, "enable", "system/"+launchdLabel).Run()
fmt.Printf("System service installed: launchd daemon %s, running %s as root.\n", launchdLabel, self)
fmt.Println(" It starts at boot, before anyone signs in, and launchd restarts it whenever it stops.")
fmt.Printf(" Its log is %s.\n", darwinDaemonLog)
return nil
}
func uninstallSystemService() error {
_ = exec.Command(launchctlPath, "bootout", "system/"+launchdLabel).Run()
if err := os.Remove(launchdPlistPath); err != nil && !errors.Is(err, fs.ErrNotExist) {
return fmt.Errorf("cannot remove %s: %w", launchdPlistPath, err)
}
fmt.Printf("System service removed: %s is no longer registered with launchd.\n", launchdLabel)
fmt.Println(" The bastion's state under /var/root is left in place.")
return nil
}
func printSystemServiceStatus() error {
installed, err := systemServiceInstalled()
if err != nil {
return err
}
if !installed {
fmt.Println("No system service is installed on this machine.")
return nil
}
out, err := exec.Command(launchctlPath, "print", "system/"+launchdLabel).CombinedOutput()
if err != nil {
fmt.Printf("System service %s is installed but not loaded (launchctl: %s).\n", launchdLabel, strings.TrimSpace(string(out)))
return nil
}
state, pid := "unknown", ""
for _, line := range strings.Split(string(out), "\n") {
line = strings.TrimSpace(line)
if v, ok := strings.CutPrefix(line, "state = "); ok && state == "unknown" {
state = v
}
if v, ok := strings.CutPrefix(line, "pid = "); ok && pid == "" {
pid = v
}
}
if pid != "" {
fmt.Printf("System service %s: %s (pid %s).\n", launchdLabel, state, pid)
} else {
fmt.Printf("System service %s: %s.\n", launchdLabel, state)
}
return nil
}
// writeRootFile writes a root-owned file with an exact mode, through a temp
// file and a rename in the same directory, so launchd never reads half a job.
func writeRootFile(p string, data []byte, mode os.FileMode) error {
f, err := os.CreateTemp(filepath.Dir(p), ".privatae-bastion-*.tmp")
if err != nil {
return err
}
tmp := f.Name()
defer os.Remove(tmp)
if _, err := f.Write(data); err != nil {
_ = f.Close()
return err
}
if err := f.Sync(); err != nil {
_ = f.Close()
return err
}
if err := f.Close(); err != nil {
return err
}
if err := os.Chown(tmp, 0, 0); err != nil {
return err
}
if err := os.Chmod(tmp, mode); err != nil {
return err
}
return os.Rename(tmp, p)
}