Files
Privatae e4c9b69b46
ci / personal-data (push) Successful in 5s
ci / test (push) Successful in 3m4s
ci / fuzz (push) Successful in 3m45s
bastion 0.53.2
2026-10-20 04:42:14 +00:00

79 lines
2.7 KiB
Go

//go:build linux || darwin
package main
import (
"errors"
"os"
"path/filepath"
"strings"
"testing"
)
// On macOS an administrator's commands read the launchd daemon's own state,
// so an administrator's `run` beside the daemon holds the same WireGuard keys.
// It must be refused before it starts anything, and a Mac without the daemon
// must not be touched at all. Run here against the real flock.
func TestARunBesideTheMacServiceIsRefusedBeforeItStarts(t *testing.T) {
dir := t.TempDir()
stateDir := func() (string, error) { return dir, nil }
// No service: nothing is locked and nothing is written.
f, err := guardRunBesideService(false, func() (string, error) {
t.Fatal("the state directory was asked for on a machine with no service")
return "", nil
}, tryRunLock)
if err != nil || f != nil {
t.Fatalf("with no service: file %v, err %v; want neither", f, err)
}
// The daemon starts first and takes the lock.
daemon, err := guardRunBesideService(true, stateDir, tryRunLock)
if err != nil || daemon == nil {
t.Fatalf("the first run did not take the lock: %v", err)
}
// An administrator's run beside it is refused, and told how to restart the service.
if _, err := guardRunBesideService(true, stateDir, tryRunLock); err == nil {
t.Fatal("a second run beside the service was allowed: it would bring up the same tunnel")
} else if !strings.Contains(err.Error(), "launchctl kickstart -k system/"+launchdLabel) {
t.Errorf("the refusal does not say how to restart the service: %v", err)
}
// Once the daemon is gone the lock is free again.
_ = daemon.Close()
again, err := guardRunBesideService(true, stateDir, tryRunLock)
if err != nil || again == nil {
t.Fatalf("the lock was not released with its holder: %v", err)
}
_ = again.Close()
// A lock that cannot be opened is a refusal, not a pass.
if _, err := guardRunBesideService(true, func() (string, error) {
return filepath.Join(dir, "missing", "deeper"), nil
}, tryRunLock); err == nil {
t.Error("a run lock that could not be opened let the run go ahead")
}
if _, err := guardRunBesideService(true, func() (string, error) {
return "", errors.New("no state directory")
}, tryRunLock); err == nil {
t.Error("a missing state directory let the run go ahead")
}
}
func TestTryRunLockIsExclusiveAcrossOpens(t *testing.T) {
p := filepath.Join(t.TempDir(), "run.lock")
a, held, err := tryRunLock(p)
if err != nil || held || a == nil {
t.Fatalf("first lock: held=%v err=%v", held, err)
}
defer a.Close()
b, held, err := tryRunLock(p)
if err != nil || !held || b != nil {
t.Fatalf("second lock: held=%v err=%v; want held", held, err)
}
if fi, err := os.Stat(p); err != nil || fi.Mode().Perm()&0o077 != 0 {
t.Errorf("the lock file is not private to its owner: %v %v", fi.Mode(), err)
}
}