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
+167
View File
@@ -0,0 +1,167 @@
package main
import (
"crypto/ecdsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/pem"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
// The managed install signs the agent's manifest in Go (faSignManifest): the
// agent prints `payload`, the bastion signs it with the key it minted, the
// agent records it with `sign --value`. No openssl anywhere — Windows ships
// none, and every Windows agent used to stop at `missing-openssl`.
const fakeAgent = `import base64, sys
args = sys.argv[1:]
if args[0] == "payload":
sys.stdout.buffer.write(open(args[1], "rb").read())
elif args[0] == "sign":
path = args[1]
val = args[args.index("--value") + 1]
cert = args[args.index("--cert") + 1]
base64.b64decode(val, validate=True)
open(path + ".sig", "w").write(val + "\n" + cert)
else:
sys.exit(2)
`
func findPython(t *testing.T) string {
for _, n := range []string{"python3", "python"} {
if p, err := exec.LookPath(n); err == nil {
return p
}
}
t.Skip("no python on PATH")
return ""
}
// pythonOnlyPath: a PATH holding a link to python and NOTHING else, so a step
// that reached for openssl would fail here the way it does on Windows.
func pythonOnlyPath(t *testing.T, py string) string {
d := t.TempDir()
if err := os.Symlink(py, filepath.Join(d, filepath.Base(py))); err != nil {
t.Skip("cannot link python: " + err.Error())
}
if _, err := exec.LookPath("openssl"); err == nil {
old := os.Getenv("PATH")
os.Setenv("PATH", d)
defer os.Setenv("PATH", old)
if _, err := exec.LookPath("openssl"); err == nil {
t.Fatal("openssl still resolvable on the python-only PATH")
}
}
return d
}
func TestFaSignManifestSignsPayloadWithMintedKey(t *testing.T) {
py := findPython(t)
dir := t.TempDir()
cert, key, _, err := faEnsureIdentity(dir, "desk-example")
if err != nil {
t.Fatal(err)
}
agent := filepath.Join(dir, "agent.py")
if err := os.WriteFile(agent, []byte(fakeAgent), 0o600); err != nil {
t.Fatal(err)
}
staged := filepath.Join(dir, "manifest.yaml")
body := []byte("freeagent: 1\nid: t\n")
if err := os.WriteFile(staged, body, 0o600); err != nil {
t.Fatal(err)
}
// PATH without openssl: the step must not need it.
env := []string{"PATH=" + pythonOnlyPath(t, py)}
if err := faSignManifest(py, nil, agent, staged, key, cert, env); err != nil {
t.Fatalf("faSignManifest: %v", err)
}
rec, err := os.ReadFile(staged + ".sig")
if err != nil {
t.Fatal(err)
}
parts := strings.SplitN(string(rec), "\n", 2)
if parts[1] != cert {
t.Fatalf("recorded cert %q, want %q", parts[1], cert)
}
sig, err := base64.StdEncoding.DecodeString(parts[0])
if err != nil {
t.Fatal(err)
}
cb, _ := os.ReadFile(cert)
blk, _ := pem.Decode(cb)
c, err := x509.ParseCertificate(blk.Bytes)
if err != nil {
t.Fatal(err)
}
sum := sha256.Sum256(body)
if !ecdsa.VerifyASN1(c.PublicKey.(*ecdsa.PublicKey), sum[:], sig) {
t.Fatal("signature does not verify against the minted cert over the payload")
}
}
func TestFaSignManifestReportsAgentFailure(t *testing.T) {
py := findPython(t)
dir := t.TempDir()
cert, key, _, err := faEnsureIdentity(dir, "desk-example")
if err != nil {
t.Fatal(err)
}
agent := filepath.Join(dir, "agent.py")
_ = os.WriteFile(agent, []byte("import sys\nsys.stderr.write('bad manifest')\nsys.exit(1)\n"), 0o600)
err = faSignManifest(py, nil, agent, filepath.Join(dir, "m.yaml"), key, cert, nil)
if err == nil || !strings.Contains(err.Error(), "bad manifest") {
t.Fatalf("want the agent's own error, got %v", err)
}
}
// With FA_TEST_AGENT_PYZ pointing at a built agent (bastion_agent/build.py),
// the real `payload` / `sign --value` / gate round-trip runs, openssl-free.
func TestFaSignManifestWithRealAgent(t *testing.T) {
pyz := os.Getenv("FA_TEST_AGENT_PYZ")
if pyz == "" {
t.Skip("FA_TEST_AGENT_PYZ not set")
}
py := findPython(t)
dir := t.TempDir()
cert, key, _, err := faEnsureIdentity(dir, "desk-example")
if err != nil {
t.Fatal(err)
}
root := filepath.Join(dir, "root")
_ = os.MkdirAll(root, 0o700)
staged := filepath.Join(dir, "manifest.yaml")
text := "freeagent: 1\nid: t\nowner:\n host: desk-example\nscope:\n roots:\n - " + root +
"\nmask:\n- read\n- index\nstages:\n- walk\nsweep: manual\nsink:\n catalog: local\n vectors: local\n plaintext: never\n"
_ = os.WriteFile(staged, []byte(text), 0o600)
env := []string{"PATH=" + pythonOnlyPath(t, py), "FREEAGENT_CA_ROOT=" + cert}
if err := faSignManifest(py, nil, pyz, staged, key, cert, env); err != nil {
t.Fatalf("faSignManifest: %v", err)
}
cmd := exec.Command(py, pyz, "sweep", staged, "--out", filepath.Join(dir, "out"), "--once")
cmd.Env = env
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("the real agent's gate refused the Go-signed manifest: %v\n%s", err, out)
}
}
func TestFaVersionLess(t *testing.T) {
for _, c := range []struct {
a, b string
less bool
}{
{"0.1.10", "0.1.11", true}, {"0.1.9", "0.1.11", true}, {"0.1.11", "0.1.11", false},
{"0.1.12", "0.1.11", false}, {"0.2", "0.1.11", false}, {"1.0.0", "0.1.11", false},
{"", "0.1.11", true}, {"dev", "0.1.11", true},
} {
if got := faVersionLess(c.a, c.b); got != c.less {
t.Errorf("faVersionLess(%q, %q) = %v, want %v", c.a, c.b, got, c.less)
}
}
}