fix(P07): remove all password/token paths (REQ-146, R-021, C-34) -- BREAKING
---ci--- project: orca phase: 7 milestone: v0.12 status: execute ---/ci--- R-021 invariant: no passwords, no Orca-issued tokens, no CA-key passphrases anywhere in the system. Removed: - proxmox/bootstrap.go: ssh.Password auth -> ssh.PublicKeys (key-based). --password/ removed from node join; replaced with --ssh-key (default: orca SSH key). Pre-staged key required. - stepca/stepca.go: --password-file /dev/stdin removed from Init and issueCert. Provisioner changed to 'orca-oidc' (OIDC provisioner). - identity/spiffe.go: --password-file removed from MintSVID. Provisioner changed to 'orca-oidc'. Tests: all proxmox, stepca, identity, cli tests updated + pass. 3 new password-rejection regression tests. Fake SSH server gains PublicKeyCallback. go vet clean. Full build green.
This commit is contained in:
@@ -13,6 +13,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.cloudinit.dev/coreci/orca/internal/certpaths"
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/ssh"
|
||||
@@ -89,14 +91,14 @@ func TestOrcaOperatorPrivileges(t *testing.T) {
|
||||
func TestBootstrapProxmox_Validation(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
|
||||
_, err := BootstrapProxmox(ctx, Options{Password: "pw"})
|
||||
_, err := BootstrapProxmox(ctx, Options{SSHKeyPath: certpaths.SSHKeyPath()})
|
||||
if err == nil || !strings.Contains(err.Error(), "host is required") {
|
||||
t.Errorf("expected host-required error, got %v", err)
|
||||
}
|
||||
|
||||
_, err = BootstrapProxmox(ctx, Options{Host: "10.0.0.1"})
|
||||
if err == nil || !strings.Contains(err.Error(), "password is required") {
|
||||
t.Errorf("expected password-required error, got %v", err)
|
||||
if err == nil || !strings.Contains(err.Error(), "SSH key path is required") {
|
||||
t.Errorf("expected SSH-key-required error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,8 +151,8 @@ func TestBootstrapProxmox_SSHAuthFailure(t *testing.T) {
|
||||
setupORCAHome(t)
|
||||
|
||||
_, err := BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.1",
|
||||
Password: "pw",
|
||||
Host: "10.0.0.1",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected error, got nil")
|
||||
@@ -172,9 +174,9 @@ func TestBootstrapProxmox_SSHDialCalledWithCorrectAddr(t *testing.T) {
|
||||
setupORCAHome(t)
|
||||
|
||||
_, _ = BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.42",
|
||||
Password: "pw",
|
||||
SSHPort: 2222,
|
||||
Host: "10.0.0.42",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: 2222,
|
||||
})
|
||||
if dialer.calls != 1 {
|
||||
t.Errorf("dialer calls = %d, want 1", dialer.calls)
|
||||
@@ -193,8 +195,8 @@ func TestBootstrapProxmox_DefaultSSHPort(t *testing.T) {
|
||||
setupORCAHome(t)
|
||||
|
||||
_, _ = BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.99",
|
||||
Password: "pw",
|
||||
Host: "10.0.0.99",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
})
|
||||
if dialer.lastAddr != "10.0.0.99:22" {
|
||||
t.Errorf("dial addr = %q, want 10.0.0.99:22 (default port)", dialer.lastAddr)
|
||||
@@ -210,9 +212,9 @@ func TestBootstrapProxmox_CustomSSHUser(t *testing.T) {
|
||||
setupORCAHome(t)
|
||||
|
||||
_, _ = BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.1",
|
||||
Password: "pw",
|
||||
SSHUser: "custom-admin",
|
||||
Host: "10.0.0.1",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHUser: "custom-admin",
|
||||
})
|
||||
if dialer.calls != 1 {
|
||||
t.Errorf("dialer calls = %d, want 1", dialer.calls)
|
||||
@@ -230,8 +232,8 @@ func TestBootstrapProxmox_SSHKeyGenerated(t *testing.T) {
|
||||
dir := setupORCAHome(t)
|
||||
|
||||
_, _ = BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.1",
|
||||
Password: "pw",
|
||||
Host: "10.0.0.1",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
})
|
||||
|
||||
keyPath := filepath.Join(dir, "orca_ssh_key")
|
||||
@@ -252,8 +254,8 @@ func TestBootstrapProxmox_KnownHostsFileCreated(t *testing.T) {
|
||||
dir := setupORCAHome(t)
|
||||
|
||||
_, _ = BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.1",
|
||||
Password: "pw",
|
||||
Host: "10.0.0.1",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
})
|
||||
|
||||
knownHosts := filepath.Join(dir, "known_hosts")
|
||||
@@ -275,9 +277,9 @@ func TestBootstrapProxmox_NilLogger(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
_, _ = BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.1",
|
||||
Password: "pw",
|
||||
Logger: nil,
|
||||
Host: "10.0.0.1",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
Logger: nil,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -297,9 +299,9 @@ func TestBootstrapProxmox_CustomLogger(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
_, _ = BootstrapProxmox(context.Background(), Options{
|
||||
Host: "10.0.0.1",
|
||||
Password: "pw",
|
||||
Logger: log,
|
||||
Host: "10.0.0.1",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
Logger: log,
|
||||
})
|
||||
_ = buf.String()
|
||||
}
|
||||
@@ -314,8 +316,8 @@ func TestBootstrapProxmox_ContextCancelled(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
_, err := BootstrapProxmox(ctx, Options{
|
||||
Host: "10.0.0.1",
|
||||
Password: "pw",
|
||||
Host: "10.0.0.1",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected error with cancelled context")
|
||||
@@ -362,8 +364,8 @@ func TestBootstrapProxmox_FullFlow_IdempotentReRun(t *testing.T) {
|
||||
for i := 0; i < 2; i++ {
|
||||
sessionRunner = nil
|
||||
if _, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
}); err != nil {
|
||||
t.Fatalf("bootstrap run %d: %v", i+1, err)
|
||||
}
|
||||
@@ -391,9 +393,9 @@ func TestBootstrapProxmox_FullFlow_NoPasswordInLogs(t *testing.T) {
|
||||
|
||||
var logBuf bytes.Buffer
|
||||
_, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "super-secret-pw-12345",
|
||||
Logger: slog.New(slog.NewTextHandler(&logBuf, nil)),
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
Logger: slog.New(slog.NewTextHandler(&logBuf, nil)),
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("BootstrapProxmox: %v", err)
|
||||
@@ -425,8 +427,8 @@ func TestBootstrapProxmox_FullFlow_ValidateSudoersFails(t *testing.T) {
|
||||
host, _, _ := net.SplitHostPort(srv.addr())
|
||||
|
||||
_, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected error for invalid sudoers")
|
||||
@@ -472,7 +474,7 @@ func TestBootstrapProxmox_FullFlow_CreateLinuxUserFails(t *testing.T) {
|
||||
// ProxmoxUser=root exercises the /root home branch in deployPubKey.
|
||||
_, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
ProxmoxUser: "root",
|
||||
})
|
||||
if err != nil {
|
||||
@@ -697,9 +699,9 @@ func TestBootstrapProxmox_PopulatesHostKeyFingerprint(t *testing.T) {
|
||||
portNum, _ := strconv.Atoi(port)
|
||||
|
||||
result, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHPort: portNum,
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("BootstrapProxmox: %v", err)
|
||||
@@ -823,7 +825,7 @@ func TestBootstrapE2E_PinnedFingerprintCorrect(t *testing.T) {
|
||||
|
||||
result, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
HostKeyFingerprint: pin,
|
||||
})
|
||||
@@ -846,7 +848,7 @@ func TestBootstrapE2E_PinnedFingerprintWrong(t *testing.T) {
|
||||
|
||||
_, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
HostKeyFingerprint: wrong,
|
||||
})
|
||||
@@ -878,9 +880,9 @@ func TestBootstrapE2E_TOFUFirstConnectCapturesKey(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHPort: portNum,
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("BootstrapProxmox first connect: %v", err)
|
||||
@@ -909,9 +911,9 @@ func TestBootstrapE2E_TOFUSecondConnectMatches(t *testing.T) {
|
||||
for i := 0; i < 2; i++ {
|
||||
sessionRunner = nil
|
||||
if _, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHPort: portNum,
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
}); err != nil {
|
||||
t.Fatalf("bootstrap run %d: %v", i+1, err)
|
||||
}
|
||||
@@ -947,9 +949,9 @@ func TestBootstrapE2E_TOFUMismatchFails(t *testing.T) {
|
||||
}
|
||||
|
||||
_, err = BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHPort: portNum,
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected MITM/mismatch error, got nil")
|
||||
@@ -980,9 +982,9 @@ func TestBootstrapE2E_PrePopulatedKnownHostsMatches(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHPort: portNum,
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("BootstrapProxmox on pre-populated known_hosts: %v", err)
|
||||
@@ -1009,9 +1011,9 @@ func TestBootstrapE2E_KeyResetThenRePin(t *testing.T) {
|
||||
// First connect: TOFU captures + writes known_hosts.
|
||||
sessionRunner = nil
|
||||
if _, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHPort: portNum,
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
}); err != nil {
|
||||
t.Fatalf("first bootstrap: %v", err)
|
||||
}
|
||||
@@ -1034,9 +1036,9 @@ func TestBootstrapE2E_KeyResetThenRePin(t *testing.T) {
|
||||
// Next connect re-pins via TOFU + succeeds.
|
||||
sessionRunner = nil
|
||||
if _, err := BootstrapProxmox(t.Context(), Options{
|
||||
Host: host,
|
||||
Password: "pw",
|
||||
SSHPort: portNum,
|
||||
Host: host,
|
||||
SSHKeyPath: certpaths.SSHKeyPath(),
|
||||
SSHPort: portNum,
|
||||
}); err != nil {
|
||||
t.Fatalf("re-pin bootstrap after reset: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user