carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package rootaws
2
3import (
4 "bytes"
5 "context"
6 "log"
7 "os"
8 "path/filepath"
9 "strings"
10 "testing"
11
12 "golang.org/x/sys/unix"
13)
14
15func TestRootCredentialsRejectUnsafeFiles(t *testing.T) {
16 for _, kind := range []string{"symlink", "dangling", "hardlink", "fifo", "directory", "service-owner", "group-write", "other-write", "process"} {
17 t.Run(kind, func(t *testing.T) {
18 isolatedAWSEnv(t)
19 dir := t.TempDir()
20 path := filepath.Join(dir, "credentials")
21 target := filepath.Join(dir, "target")
22 body := []byte("[default]\naws_access_key_id=ACCESS\naws_secret_access_key=SECRET\n")
23 if err := os.WriteFile(target, body, 0600); err != nil {
24 t.Fatal(err)
25 }
26 var err error
27 switch kind {
28 case "symlink":
29 err = os.Symlink(target, path)
30 case "dangling":
31 err = os.Symlink(filepath.Join(dir, "missing"), path)
32 case "hardlink":
33 err = os.Link(target, path)
34 case "fifo":
35 err = unix.Mkfifo(path, 0600)
36 case "directory":
37 err = os.Mkdir(path, 0700)
38 default:
39 if os.Geteuid() != 0 && kind != "service-owner" {
40 t.Skip("requires root-owned fixture to isolate mode and content checks")
41 }
42 if kind == "process" {
43 body = append(body, []byte("credential_process=bad\n")...)
44 }
45 err = os.WriteFile(path, body, 0600)
46 if err == nil {
47 switch kind {
48 case "service-owner":
49 if os.Geteuid() == 0 {
50 err = os.Chown(path, 65534, 65534)
51 }
52 case "group-write":
53 err = os.Chmod(path, 0660)
54 case "other-write":
55 err = os.Chmod(path, 0602)
56 }
57 }
58 }
59 if err != nil {
60 t.Fatal(err)
61 }
62 var logs bytes.Buffer
63 old := log.Writer()
64 log.SetOutput(&logs)
65 defer log.SetOutput(old)
66 cfg, err := loadRootConfig(context.Background(), path)
67 if err != nil {
68 t.Fatalf("unused unsafe credentials made config loading fatal: %v", err)
69 }
70 if _, err := cfg.Credentials.Retrieve(context.Background()); err == nil {
71 t.Fatal("unsafe file accepted")
72 }
73 if !strings.Contains(logs.String(), "ALERT:") {
74 t.Fatal("unsafe file refusal did not alert")
75 }
76 })
77 }
78}
79
80func TestRootCredentialsEnvironmentKeysIgnoreServiceOwnedFile(t *testing.T) {
81 isolatedAWSEnv(t)
82 t.Setenv("AWS_ACCESS_KEY_ID", "ENV_ACCESS")
83 t.Setenv("AWS_SECRET_ACCESS_KEY", "ENV_SECRET")
84 path := filepath.Join(t.TempDir(), "credentials")
85 if err := os.WriteFile(path, []byte("[default]\naws_access_key_id=FILE\naws_secret_access_key=SECRET\n"), 0600); err != nil {
86 t.Fatal(err)
87 }
88 if os.Geteuid() == 0 {
89 if err := os.Chown(path, 65534, 65534); err != nil {
90 t.Fatal(err)
91 }
92 }
93 // Without environment keys the same file is refused, so the file is unsafe.
94 t.Setenv("AWS_SECRET_ACCESS_KEY", "")
95 unsafeConfig, err := loadRootConfig(context.Background(), path)
96 if err != nil {
97 t.Fatal(err)
98 }
99 if _, err := unsafeConfig.Credentials.Retrieve(context.Background()); err == nil {
100 t.Fatal("service-owned fixture was not unsafe")
101 }
102 t.Setenv("AWS_SECRET_ACCESS_KEY", "ENV_SECRET")
103 cfg, err := loadRootConfig(context.Background(), path)
104 if err != nil {
105 t.Fatalf("service-owned unused file made config fatal: %v", err)
106 }
107 got, err := cfg.Credentials.Retrieve(context.Background())
108 if err != nil || got.AccessKeyID != "ENV_ACCESS" || got.SecretAccessKey != "ENV_SECRET" {
109 t.Fatalf("environment credentials failed: %v", err)
110 }
111}
112
113func TestRootCredentialsStaticProvider(t *testing.T) {
114 if os.Geteuid() != 0 {
115 t.Skip("requires root-owned credentials fixture")
116 }
117 isolatedAWSEnv(t)
118 path := filepath.Join(t.TempDir(), "credentials")
119 if err := os.WriteFile(path, []byte("[default]\naws_access_key_id=STATIC\naws_secret_access_key=SECRET\naws_session_token=TOKEN\n"), 0640); err != nil {
120 t.Fatal(err)
121 }
122 fileCreds, err := offcloudCredentials(path)
123 if err != nil || fileCreds.AccessKeyID != "STATIC" || fileCreds.SecretAccessKey != "SECRET" || fileCreds.SessionToken != "TOKEN" {
124 t.Fatalf("off-cloud file credentials failed: %v", err)
125 }
126 cfg, err := loadRootConfig(context.Background(), path)
127 if err != nil {
128 t.Fatal(err)
129 }
130 // The provider holds the parsed snapshot and never asks the SDK to reread it.
131 if err := os.WriteFile(path, []byte("[default]\ncredential_process=bad\n"), 0640); err != nil {
132 t.Fatal(err)
133 }
134 got, err := cfg.Credentials.Retrieve(context.Background())
135 if err != nil || got.AccessKeyID != "STATIC" || got.SessionToken != "TOKEN" {
136 t.Fatalf("static snapshot failed: %v", err)
137 }
138}
139