Files
privatae-bastion/client-go/pair_enrol_test.go
T
Privatae 8822d5df85
ci / personal-data (push) Successful in 5s
ci / test (push) Successful in 3m51s
ci / fuzz (push) Successful in 2m55s
bastion 0.55.3
2026-10-25 23:16:45 +00:00

138 lines
4.7 KiB
Go

//go:build !windows
// Tagged !windows: it borrows setupBox (anchor_test.go) and
// withMachineAuthority (claims_unix_test.go).
package main
// `pair` says to enrol a second factor after every pairing that leaves this
// machine without one, not only after it anchors a networked machine. On a
// local machine a pairing with no factor installs a folder grant on the host's
// signed grant alone, so the person has to be told at the moment they pair.
import (
"crypto/ed25519"
"encoding/base64"
"strings"
"testing"
)
func pairReportOf(cfg *Config, all []*Config, anchored bool) string {
var b strings.Builder
pairReport(&b, cfg, all, anchored)
return b.String()
}
func pairedHere(t *testing.T, host string, set func(*Config)) (*Config, []*Config) {
t.Helper()
all, err := loadPairings()
if err != nil {
t.Fatal(err)
}
cfg := pairingFor(all, host)
if cfg == nil {
t.Fatalf("%s is not paired", host)
}
if set != nil {
set(cfg)
}
return cfg, all
}
func enrolFactor(t *testing.T, cfg *Config) {
t.Helper()
if err := stepupSave(cfg.dcnDir(), &stepupFile{SecretB32: "INVENTEDTESTAAAA", EnrolledAt: "2026-01-02T03:04:05Z"}); err != nil {
t.Fatal(err)
}
if !stepupEnrolled(cfg.dcnDir()) {
t.Fatal("the fixture factor does not read as enrolled")
}
}
// MUTATION: print the hint only when the pairing anchored the machine.
// RESULT: red — the local, TCP, unix and pending forms say nothing.
func TestEveryPairingWithoutAFactorIsToldToEnrolOne(t *testing.T) {
for _, f := range []struct {
name string
set func(*Config)
}{
{"over the tunnel", nil},
{"over TCP", func(c *Config) { c.Transport, c.LaneAddr = transportTCP, "127.0.0.1:8811" }},
{"over a unix socket", func(c *Config) { c.Transport, c.LaneSocket = transportUnix, "/run/privatae-host/lane.sock" }},
} {
t.Run("local machine, "+f.name, func(t *testing.T) {
withMachineAuthority(t, false)
t.Setenv("XDG_CONFIG_HOME", t.TempDir())
writePairing(t, tMember)
cfg, all := pairedHere(t, tMember, f.set)
out := pairReportOf(cfg, all, false)
if !strings.Contains(out, "\n privatae-bastion stepup-enroll\n") {
t.Fatalf("a local pairing with no factor must be told to enrol one, as its own user:\n%s", out)
}
if !strings.Contains(out, "signed grant alone") {
t.Fatalf("the hint says what no factor means here:\n%s", out)
}
enrolFactor(t, cfg)
if out := pairReportOf(cfg, all, false); strings.Contains(out, "stepup-enroll") {
t.Fatalf("a pairing that keeps its factor (a --replace) is not told to enrol again:\n%s", out)
}
})
}
t.Run("anchored by this pairing: said once", func(t *testing.T) {
withMachineAuthority(t, true)
setupBox(t)
cfg, all := pairedHere(t, tAnchor, nil)
out := pairReportOf(cfg, all, true)
if strings.Count(out, "stepup-enroll") != 1 || !strings.Contains(out, "\n sudo -H privatae-bastion stepup-enroll\n") {
t.Fatalf("the anchoring pairing names the factor once, with machine authority:\n%s", out)
}
})
t.Run("a pending host on an anchored machine", func(t *testing.T) {
withMachineAuthority(t, true)
setupBox(t)
writePairingState(t, tMember, pairingPending)
cfg, all := pairedHere(t, tMember, nil)
out := pairReportOf(cfg, all, false)
if !strings.Contains(out, "sudo -H privatae-bastion stepup-enroll --host "+tMember) ||
!strings.Contains(out, "cannot approve") {
t.Fatalf("a second host on an anchored machine is told to enrol a factor for it, by name:\n%s", out)
}
})
t.Run("an approval device pinned is a way to approve", func(t *testing.T) {
withMachineAuthority(t, true)
setupBox(t)
writePairingState(t, tMember, pairingPending)
pub, _, _ := ed25519.GenerateKey(nil)
if err := pinDeviceKey(base64.StdEncoding.EncodeToString(pub)); err != nil {
t.Fatal(err)
}
cfg, all := pairedHere(t, tMember, nil)
if out := pairReportOf(cfg, all, false); strings.Contains(out, "stepup-enroll") {
t.Fatalf("with a device pinned there is a way to approve; no hint:\n%s", out)
}
})
}
// The line is run as whoever ran `pair`, on each platform.
func TestStepupEnrollHintIsRunAsWhoeverPaired(t *testing.T) {
for _, c := range []struct {
goos string
authority bool
paired int
want string
}{
{"linux", false, 1, "privatae-bastion stepup-enroll"},
{"linux", true, 1, "sudo -H privatae-bastion stepup-enroll"},
{"darwin", true, 2, "sudo -H privatae-bastion stepup-enroll --host h1.example.test"},
{"windows", true, 1, "privatae-bastion stepup-enroll (from this Administrator terminal)"},
{"windows", false, 2, "privatae-bastion stepup-enroll --host h1.example.test"},
} {
if got := stepupEnrollHintFor(c.goos, c.authority, "h1.example.test", c.paired); got != c.want {
t.Errorf("%s authority=%v paired=%d: %q, want %q", c.goos, c.authority, c.paired, got, c.want)
}
}
}