1package vault
2
3import (
4	"context"
5	"crypto/sha256"
6	"encoding/base64"
7	"encoding/hex"
8	"fmt"
9	"io/ioutil"
10	"os"
11	"path/filepath"
12	"reflect"
13	"strings"
14	"testing"
15	"time"
16
17	"github.com/fatih/structs"
18	"github.com/go-test/deep"
19	hclog "github.com/hashicorp/go-hclog"
20	"github.com/hashicorp/vault/audit"
21	"github.com/hashicorp/vault/helper/builtinplugins"
22	"github.com/hashicorp/vault/helper/identity"
23	"github.com/hashicorp/vault/helper/namespace"
24	"github.com/hashicorp/vault/sdk/framework"
25	"github.com/hashicorp/vault/sdk/helper/consts"
26	"github.com/hashicorp/vault/sdk/helper/jsonutil"
27	"github.com/hashicorp/vault/sdk/helper/salt"
28	"github.com/hashicorp/vault/sdk/logical"
29	"github.com/hashicorp/vault/sdk/version"
30	"github.com/mitchellh/mapstructure"
31)
32
33func TestSystemBackend_RootPaths(t *testing.T) {
34	expected := []string{
35		"auth/*",
36		"remount",
37		"audit",
38		"audit/*",
39		"raw",
40		"raw/*",
41		"replication/primary/secondary-token",
42		"replication/performance/primary/secondary-token",
43		"replication/dr/primary/secondary-token",
44		"replication/reindex",
45		"replication/dr/reindex",
46		"replication/performance/reindex",
47		"rotate",
48		"config/cors",
49		"config/auditing/*",
50		"config/ui/headers/*",
51		"plugins/catalog/*",
52		"revoke-prefix/*",
53		"revoke-force/*",
54		"leases/revoke-prefix/*",
55		"leases/revoke-force/*",
56		"leases/lookup/*",
57	}
58
59	b := testSystemBackend(t)
60	actual := b.SpecialPaths().Root
61	if !reflect.DeepEqual(actual, expected) {
62		t.Fatalf("bad: mismatch\nexpected:\n%#v\ngot:\n%#v", expected, actual)
63	}
64}
65
66func TestSystemConfigCORS(t *testing.T) {
67	b := testSystemBackend(t)
68	_, barrier, _ := mockBarrier(t)
69	view := NewBarrierView(barrier, "")
70	b.(*SystemBackend).Core.systemBarrierView = view
71
72	req := logical.TestRequest(t, logical.UpdateOperation, "config/cors")
73	req.Data["allowed_origins"] = "http://www.example.com"
74	req.Data["allowed_headers"] = "X-Custom-Header"
75	_, err := b.HandleRequest(namespace.RootContext(nil), req)
76	if err != nil {
77		t.Fatal(err)
78	}
79
80	expected := &logical.Response{
81		Data: map[string]interface{}{
82			"enabled":         true,
83			"allowed_origins": []string{"http://www.example.com"},
84			"allowed_headers": append(StdAllowedHeaders, "X-Custom-Header"),
85		},
86	}
87
88	req = logical.TestRequest(t, logical.ReadOperation, "config/cors")
89	actual, err := b.HandleRequest(namespace.RootContext(nil), req)
90	if err != nil {
91		t.Fatalf("err: %v", err)
92	}
93
94	if !reflect.DeepEqual(actual, expected) {
95		t.Fatalf("bad: %#v", actual)
96	}
97
98	// Do it again. Bug #6182
99	req = logical.TestRequest(t, logical.UpdateOperation, "config/cors")
100	req.Data["allowed_origins"] = "http://www.example.com"
101	req.Data["allowed_headers"] = "X-Custom-Header"
102	_, err = b.HandleRequest(namespace.RootContext(nil), req)
103	if err != nil {
104		t.Fatal(err)
105	}
106
107	req = logical.TestRequest(t, logical.ReadOperation, "config/cors")
108	actual, err = b.HandleRequest(namespace.RootContext(nil), req)
109	if err != nil {
110		t.Fatalf("err: %v", err)
111	}
112
113	if !reflect.DeepEqual(actual, expected) {
114		t.Fatalf("bad: %#v", actual)
115	}
116
117	req = logical.TestRequest(t, logical.DeleteOperation, "config/cors")
118	_, err = b.HandleRequest(namespace.RootContext(nil), req)
119	if err != nil {
120		t.Fatalf("err: %v", err)
121	}
122
123	req = logical.TestRequest(t, logical.ReadOperation, "config/cors")
124	actual, err = b.HandleRequest(namespace.RootContext(nil), req)
125	if err != nil {
126		t.Fatalf("err: %v", err)
127	}
128
129	expected = &logical.Response{
130		Data: map[string]interface{}{
131			"enabled": false,
132		},
133	}
134
135	if !reflect.DeepEqual(actual, expected) {
136		t.Fatalf("DELETE FAILED -- bad: %#v", actual)
137	}
138
139}
140
141func TestSystemBackend_mounts(t *testing.T) {
142	b := testSystemBackend(t)
143	req := logical.TestRequest(t, logical.ReadOperation, "mounts")
144	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
145	if err != nil {
146		t.Fatalf("err: %v", err)
147	}
148
149	// We can't know the pointer address ahead of time so simply
150	// copy what's given
151	exp := map[string]interface{}{
152		"secret/": map[string]interface{}{
153			"type":        "kv",
154			"description": "key/value secret storage",
155			"accessor":    resp.Data["secret/"].(map[string]interface{})["accessor"],
156			"uuid":        resp.Data["secret/"].(map[string]interface{})["uuid"],
157			"config": map[string]interface{}{
158				"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
159				"max_lease_ttl":     resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
160				"force_no_cache":    false,
161			},
162			"local":     false,
163			"seal_wrap": false,
164			"options": map[string]string{
165				"version": "1",
166			},
167		},
168		"sys/": map[string]interface{}{
169			"type":        "system",
170			"description": "system endpoints used for control, policy and debugging",
171			"accessor":    resp.Data["sys/"].(map[string]interface{})["accessor"],
172			"uuid":        resp.Data["sys/"].(map[string]interface{})["uuid"],
173			"config": map[string]interface{}{
174				"default_lease_ttl":           resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
175				"max_lease_ttl":               resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
176				"force_no_cache":              false,
177				"passthrough_request_headers": []string{"Accept"},
178			},
179			"local":     false,
180			"seal_wrap": false,
181			"options":   map[string]string(nil),
182		},
183		"cubbyhole/": map[string]interface{}{
184			"description": "per-token private secret storage",
185			"type":        "cubbyhole",
186			"accessor":    resp.Data["cubbyhole/"].(map[string]interface{})["accessor"],
187			"uuid":        resp.Data["cubbyhole/"].(map[string]interface{})["uuid"],
188			"config": map[string]interface{}{
189				"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
190				"max_lease_ttl":     resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
191				"force_no_cache":    false,
192			},
193			"local":     true,
194			"seal_wrap": false,
195			"options":   map[string]string(nil),
196		},
197		"identity/": map[string]interface{}{
198			"description": "identity store",
199			"type":        "identity",
200			"accessor":    resp.Data["identity/"].(map[string]interface{})["accessor"],
201			"uuid":        resp.Data["identity/"].(map[string]interface{})["uuid"],
202			"config": map[string]interface{}{
203				"default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
204				"max_lease_ttl":     resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
205				"force_no_cache":    false,
206			},
207			"local":     false,
208			"seal_wrap": false,
209			"options":   map[string]string(nil),
210		},
211	}
212	if diff := deep.Equal(resp.Data, exp); len(diff) > 0 {
213		t.Fatalf("bad, diff: %#v", diff)
214	}
215}
216
217func TestSystemBackend_mount(t *testing.T) {
218	b := testSystemBackend(t)
219
220	req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/")
221	req.Data["type"] = "kv"
222	req.Data["config"] = map[string]interface{}{
223		"default_lease_ttl": "35m",
224		"max_lease_ttl":     "45m",
225	}
226	req.Data["local"] = true
227	req.Data["seal_wrap"] = true
228	req.Data["options"] = map[string]string{
229		"version": "1",
230	}
231
232	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
233	if err != nil {
234		t.Fatalf("err: %v", err)
235	}
236	if resp != nil {
237		t.Fatalf("bad: %v", resp)
238	}
239
240	req = logical.TestRequest(t, logical.ReadOperation, "mounts")
241	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
242	if err != nil {
243		t.Fatalf("err: %v", err)
244	}
245
246	// We can't know the pointer address ahead of time so simply
247	// copy what's given
248	exp := map[string]interface{}{
249		"secret/": map[string]interface{}{
250			"type":        "kv",
251			"description": "key/value secret storage",
252			"accessor":    resp.Data["secret/"].(map[string]interface{})["accessor"],
253			"uuid":        resp.Data["secret/"].(map[string]interface{})["uuid"],
254			"config": map[string]interface{}{
255				"default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
256				"max_lease_ttl":     resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
257				"force_no_cache":    false,
258			},
259			"local":     false,
260			"seal_wrap": false,
261			"options": map[string]string{
262				"version": "1",
263			},
264		},
265		"sys/": map[string]interface{}{
266			"type":        "system",
267			"description": "system endpoints used for control, policy and debugging",
268			"accessor":    resp.Data["sys/"].(map[string]interface{})["accessor"],
269			"uuid":        resp.Data["sys/"].(map[string]interface{})["uuid"],
270			"config": map[string]interface{}{
271				"default_lease_ttl":           resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
272				"max_lease_ttl":               resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
273				"force_no_cache":              false,
274				"passthrough_request_headers": []string{"Accept"},
275			},
276			"local":     false,
277			"seal_wrap": false,
278			"options":   map[string]string(nil),
279		},
280		"cubbyhole/": map[string]interface{}{
281			"description": "per-token private secret storage",
282			"type":        "cubbyhole",
283			"accessor":    resp.Data["cubbyhole/"].(map[string]interface{})["accessor"],
284			"uuid":        resp.Data["cubbyhole/"].(map[string]interface{})["uuid"],
285			"config": map[string]interface{}{
286				"default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
287				"max_lease_ttl":     resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
288				"force_no_cache":    false,
289			},
290			"local":     true,
291			"seal_wrap": false,
292			"options":   map[string]string(nil),
293		},
294		"identity/": map[string]interface{}{
295			"description": "identity store",
296			"type":        "identity",
297			"accessor":    resp.Data["identity/"].(map[string]interface{})["accessor"],
298			"uuid":        resp.Data["identity/"].(map[string]interface{})["uuid"],
299			"config": map[string]interface{}{
300				"default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
301				"max_lease_ttl":     resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
302				"force_no_cache":    false,
303			},
304			"local":     false,
305			"seal_wrap": false,
306			"options":   map[string]string(nil),
307		},
308		"prod/secret/": map[string]interface{}{
309			"description": "",
310			"type":        "kv",
311			"accessor":    resp.Data["prod/secret/"].(map[string]interface{})["accessor"],
312			"uuid":        resp.Data["prod/secret/"].(map[string]interface{})["uuid"],
313			"config": map[string]interface{}{
314				"default_lease_ttl": int64(2100),
315				"max_lease_ttl":     int64(2700),
316				"force_no_cache":    false,
317			},
318			"local":     true,
319			"seal_wrap": true,
320			"options": map[string]string{
321				"version": "1",
322			},
323		},
324	}
325	if diff := deep.Equal(resp.Data, exp); len(diff) > 0 {
326		t.Fatalf("bad: diff: %#v", diff)
327	}
328
329}
330
331func TestSystemBackend_mount_force_no_cache(t *testing.T) {
332	core, b, _ := testCoreSystemBackend(t)
333
334	req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/")
335	req.Data["type"] = "kv"
336	req.Data["config"] = map[string]interface{}{
337		"force_no_cache": true,
338	}
339
340	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
341	if err != nil {
342		t.Fatalf("err: %v", err)
343	}
344	if resp != nil {
345		t.Fatalf("bad: %v", resp)
346	}
347
348	mountEntry := core.router.MatchingMountEntry(namespace.RootContext(nil), "prod/secret/")
349	if mountEntry == nil {
350		t.Fatalf("missing mount entry")
351	}
352	if !mountEntry.Config.ForceNoCache {
353		t.Fatalf("bad config %#v", mountEntry)
354	}
355}
356
357func TestSystemBackend_mount_invalid(t *testing.T) {
358	b := testSystemBackend(t)
359
360	req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/")
361	req.Data["type"] = "nope"
362	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
363	if err != logical.ErrInvalidRequest {
364		t.Fatalf("err: %v", err)
365	}
366	if resp.Data["error"] != `plugin not found in the catalog: nope` {
367		t.Fatalf("bad: %v", resp)
368	}
369}
370
371func TestSystemBackend_unmount(t *testing.T) {
372	b := testSystemBackend(t)
373
374	req := logical.TestRequest(t, logical.DeleteOperation, "mounts/secret/")
375	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
376	if err != nil {
377		t.Fatalf("err: %v", err)
378	}
379	if resp != nil {
380		t.Fatalf("bad: %v", resp)
381	}
382}
383
384var capabilitiesPolicy = `
385name = "test"
386path "foo/bar*" {
387	capabilities = ["create", "sudo", "update"]
388}
389path "sys/capabilities*" {
390	capabilities = ["update"]
391}
392path "bar/baz" {
393	capabilities = ["read", "update"]
394}
395path "bar/baz" {
396	capabilities = ["delete"]
397}
398`
399
400func TestSystemBackend_PathCapabilities(t *testing.T) {
401	var resp *logical.Response
402	var err error
403
404	core, b, rootToken := testCoreSystemBackend(t)
405
406	policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy)
407	err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy)
408	if err != nil {
409		t.Fatalf("err: %v", err)
410	}
411
412	path1 := "foo/bar"
413	path2 := "foo/bar/sample"
414	path3 := "sys/capabilities"
415	path4 := "bar/baz"
416
417	rootCheckFunc := func(t *testing.T, resp *logical.Response) {
418		// All the paths should have "root" as the capability
419		expectedRoot := []string{"root"}
420		if !reflect.DeepEqual(resp.Data[path1], expectedRoot) ||
421			!reflect.DeepEqual(resp.Data[path2], expectedRoot) ||
422			!reflect.DeepEqual(resp.Data[path3], expectedRoot) ||
423			!reflect.DeepEqual(resp.Data[path4], expectedRoot) {
424			t.Fatalf("bad: capabilities; expected: %#v, actual: %#v", expectedRoot, resp.Data)
425		}
426	}
427
428	// Check the capabilities using the root token
429	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
430		Path:      "capabilities",
431		Operation: logical.UpdateOperation,
432		Data: map[string]interface{}{
433			"paths": []string{path1, path2, path3, path4},
434			"token": rootToken,
435		},
436	})
437	if err != nil || (resp != nil && resp.IsError()) {
438		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
439	}
440	rootCheckFunc(t, resp)
441
442	// Check the capabilities using capabilities-self
443	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
444		ClientToken: rootToken,
445		Path:        "capabilities-self",
446		Operation:   logical.UpdateOperation,
447		Data: map[string]interface{}{
448			"paths": []string{path1, path2, path3, path4},
449		},
450	})
451	if err != nil || (resp != nil && resp.IsError()) {
452		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
453	}
454	rootCheckFunc(t, resp)
455
456	// Lookup the accessor of the root token
457	te, err := core.tokenStore.Lookup(namespace.RootContext(nil), rootToken)
458	if err != nil {
459		t.Fatal(err)
460	}
461
462	// Check the capabilities using capabilities-accessor endpoint
463	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
464		Path:      "capabilities-accessor",
465		Operation: logical.UpdateOperation,
466		Data: map[string]interface{}{
467			"paths":    []string{path1, path2, path3, path4},
468			"accessor": te.Accessor,
469		},
470	})
471	if err != nil || (resp != nil && resp.IsError()) {
472		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
473	}
474	rootCheckFunc(t, resp)
475
476	// Create a non-root token
477	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"})
478
479	nonRootCheckFunc := func(t *testing.T, resp *logical.Response) {
480		expected1 := []string{"create", "sudo", "update"}
481		expected2 := expected1
482		expected3 := []string{"update"}
483		expected4 := []string{"delete", "read", "update"}
484
485		if !reflect.DeepEqual(resp.Data[path1], expected1) ||
486			!reflect.DeepEqual(resp.Data[path2], expected2) ||
487			!reflect.DeepEqual(resp.Data[path3], expected3) ||
488			!reflect.DeepEqual(resp.Data[path4], expected4) {
489			t.Fatalf("bad: capabilities; actual: %#v", resp.Data)
490		}
491	}
492
493	// Check the capabilities using a non-root token
494	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
495		Path:      "capabilities",
496		Operation: logical.UpdateOperation,
497		Data: map[string]interface{}{
498			"paths": []string{path1, path2, path3, path4},
499			"token": "tokenid",
500		},
501	})
502	if err != nil || (resp != nil && resp.IsError()) {
503		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
504	}
505	nonRootCheckFunc(t, resp)
506
507	// Check the capabilities of a non-root token using capabilities-self
508	// endpoint
509	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
510		ClientToken: "tokenid",
511		Path:        "capabilities-self",
512		Operation:   logical.UpdateOperation,
513		Data: map[string]interface{}{
514			"paths": []string{path1, path2, path3, path4},
515		},
516	})
517	if err != nil || (resp != nil && resp.IsError()) {
518		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
519	}
520	nonRootCheckFunc(t, resp)
521
522	// Lookup the accessor of the non-root token
523	te, err = core.tokenStore.Lookup(namespace.RootContext(nil), "tokenid")
524	if err != nil {
525		t.Fatal(err)
526	}
527
528	// Check the capabilities using a non-root token using
529	// capabilities-accessor endpoint
530	resp, err = b.HandleRequest(namespace.RootContext(nil), &logical.Request{
531		Path:      "capabilities-accessor",
532		Operation: logical.UpdateOperation,
533		Data: map[string]interface{}{
534			"paths":    []string{path1, path2, path3, path4},
535			"accessor": te.Accessor,
536		},
537	})
538	if err != nil || (resp != nil && resp.IsError()) {
539		t.Fatalf("bad: resp: %#v\nerr: %v", resp, err)
540	}
541	nonRootCheckFunc(t, resp)
542}
543
544func TestSystemBackend_Capabilities_BC(t *testing.T) {
545	testCapabilities(t, "capabilities")
546	testCapabilities(t, "capabilities-self")
547}
548
549func testCapabilities(t *testing.T, endpoint string) {
550	core, b, rootToken := testCoreSystemBackend(t)
551	req := logical.TestRequest(t, logical.UpdateOperation, endpoint)
552	if endpoint == "capabilities-self" {
553		req.ClientToken = rootToken
554	} else {
555		req.Data["token"] = rootToken
556	}
557	req.Data["path"] = "any_path"
558
559	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
560	if err != nil {
561		t.Fatal(err)
562	}
563	if resp == nil {
564		t.Fatalf("bad: %v", resp)
565	}
566
567	actual := resp.Data["capabilities"]
568	expected := []string{"root"}
569	if !reflect.DeepEqual(actual, expected) {
570		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
571	}
572
573	policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy)
574	err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy)
575	if err != nil {
576		t.Fatalf("err: %v", err)
577	}
578
579	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"})
580	req = logical.TestRequest(t, logical.UpdateOperation, endpoint)
581	if endpoint == "capabilities-self" {
582		req.ClientToken = "tokenid"
583	} else {
584		req.Data["token"] = "tokenid"
585	}
586	req.Data["path"] = "foo/bar"
587
588	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
589	if err != nil {
590		t.Fatalf("err: %v", err)
591	}
592	if resp == nil {
593		t.Fatalf("bad: %v", resp)
594	}
595
596	actual = resp.Data["capabilities"]
597	expected = []string{"create", "sudo", "update"}
598	if !reflect.DeepEqual(actual, expected) {
599		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
600	}
601}
602
603func TestSystemBackend_CapabilitiesAccessor_BC(t *testing.T) {
604	core, b, rootToken := testCoreSystemBackend(t)
605	te, err := core.tokenStore.Lookup(namespace.RootContext(nil), rootToken)
606	if err != nil {
607		t.Fatal(err)
608	}
609
610	req := logical.TestRequest(t, logical.UpdateOperation, "capabilities-accessor")
611	// Accessor of root token
612	req.Data["accessor"] = te.Accessor
613	req.Data["path"] = "any_path"
614
615	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
616	if err != nil {
617		t.Fatalf("err: %v", err)
618	}
619	if resp == nil {
620		t.Fatalf("bad: %v", resp)
621	}
622
623	actual := resp.Data["capabilities"]
624	expected := []string{"root"}
625	if !reflect.DeepEqual(actual, expected) {
626		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
627	}
628
629	policy, _ := ParseACLPolicy(namespace.RootNamespace, capabilitiesPolicy)
630	err = core.policyStore.SetPolicy(namespace.RootContext(nil), policy)
631	if err != nil {
632		t.Fatalf("err: %v", err)
633	}
634
635	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"test"})
636
637	te, err = core.tokenStore.Lookup(namespace.RootContext(nil), "tokenid")
638	if err != nil {
639		t.Fatal(err)
640	}
641
642	req = logical.TestRequest(t, logical.UpdateOperation, "capabilities-accessor")
643	req.Data["accessor"] = te.Accessor
644	req.Data["path"] = "foo/bar"
645
646	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
647	if err != nil {
648		t.Fatalf("err: %v", err)
649	}
650	if resp == nil {
651		t.Fatalf("bad: %v", resp)
652	}
653
654	actual = resp.Data["capabilities"]
655	expected = []string{"create", "sudo", "update"}
656	if !reflect.DeepEqual(actual, expected) {
657		t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", actual, expected)
658	}
659}
660
661func TestSystemBackend_remount(t *testing.T) {
662	b := testSystemBackend(t)
663
664	req := logical.TestRequest(t, logical.UpdateOperation, "remount")
665	req.Data["from"] = "secret"
666	req.Data["to"] = "foo"
667	req.Data["config"] = structs.Map(MountConfig{})
668	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
669	if err != nil {
670		t.Fatalf("err: %v", err)
671	}
672	if resp != nil {
673		t.Fatalf("bad: %v", resp)
674	}
675}
676
677func TestSystemBackend_remount_invalid(t *testing.T) {
678	b := testSystemBackend(t)
679
680	req := logical.TestRequest(t, logical.UpdateOperation, "remount")
681	req.Data["from"] = "unknown"
682	req.Data["to"] = "foo"
683	req.Data["config"] = structs.Map(MountConfig{})
684	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
685	if err != logical.ErrInvalidRequest {
686		t.Fatalf("err: %v", err)
687	}
688	if resp.Data["error"] != `no matching mount at "unknown/"` {
689		t.Fatalf("bad: %v", resp)
690	}
691}
692
693func TestSystemBackend_remount_system(t *testing.T) {
694	b := testSystemBackend(t)
695
696	req := logical.TestRequest(t, logical.UpdateOperation, "remount")
697	req.Data["from"] = "sys"
698	req.Data["to"] = "foo"
699	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
700	if err != logical.ErrInvalidRequest {
701		t.Fatalf("err: %v", err)
702	}
703	if resp.Data["error"] != `cannot remount "sys/"` {
704		t.Fatalf("bad: %v", resp)
705	}
706}
707
708func TestSystemBackend_leases(t *testing.T) {
709	core, b, root := testCoreSystemBackend(t)
710
711	// Create a key with a lease
712	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
713	req.Data["foo"] = "bar"
714	req.ClientToken = root
715	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
716	if err != nil {
717		t.Fatalf("err: %v", err)
718	}
719	if resp != nil {
720		t.Fatalf("bad: %#v", resp)
721	}
722
723	// Read a key with a LeaseID
724	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
725	req.ClientToken = root
726	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
727	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
728	if err != nil {
729		t.Fatalf("err: %v", err)
730	}
731	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
732		t.Fatalf("bad: %#v", resp)
733	}
734
735	// Read lease
736	req = logical.TestRequest(t, logical.UpdateOperation, "leases/lookup")
737	req.Data["lease_id"] = resp.Secret.LeaseID
738	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
739	if err != nil {
740		t.Fatalf("err: %v", err)
741	}
742	if resp.Data["renewable"] == nil || resp.Data["renewable"].(bool) {
743		t.Fatal("kv leases are not renewable")
744	}
745
746	// Invalid lease
747	req = logical.TestRequest(t, logical.UpdateOperation, "leases/lookup")
748	req.Data["lease_id"] = "invalid"
749	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
750	if err != logical.ErrInvalidRequest {
751		t.Fatalf("expected invalid request, got err: %v", err)
752	}
753}
754
755func TestSystemBackend_leases_list(t *testing.T) {
756	core, b, root := testCoreSystemBackend(t)
757
758	// Create a key with a lease
759	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
760	req.Data["foo"] = "bar"
761	req.ClientToken = root
762	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
763	if err != nil {
764		t.Fatalf("err: %v", err)
765	}
766	if resp != nil {
767		t.Fatalf("bad: %#v", resp)
768	}
769
770	// Read a key with a LeaseID
771	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
772	req.ClientToken = root
773	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
774	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
775	if err != nil {
776		t.Fatalf("err: %v", err)
777	}
778	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
779		t.Fatalf("bad: %#v", resp)
780	}
781
782	// List top level
783	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/")
784	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
785	if err != nil {
786		t.Fatalf("err: %v", err)
787	}
788	if resp == nil || resp.Data == nil {
789		t.Fatalf("bad: %#v", resp)
790	}
791	var keys []string
792	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
793		t.Fatalf("err: %v", err)
794	}
795	if len(keys) != 1 {
796		t.Fatalf("Expected 1 subkey lease, got %d: %#v", len(keys), keys)
797	}
798	if keys[0] != "secret/" {
799		t.Fatal("Expected only secret subkey")
800	}
801
802	// List lease
803	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret/foo")
804	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
805	if err != nil {
806		t.Fatalf("err: %v", err)
807	}
808	if resp == nil || resp.Data == nil {
809		t.Fatalf("bad: %#v", resp)
810	}
811	keys = []string{}
812	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
813		t.Fatalf("err: %v", err)
814	}
815	if len(keys) != 1 {
816		t.Fatalf("Expected 1 secret lease, got %d: %#v", len(keys), keys)
817	}
818
819	// Generate multiple leases
820	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
821	req.ClientToken = root
822	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
823	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
824	if err != nil {
825		t.Fatalf("err: %v", err)
826	}
827	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
828		t.Fatalf("bad: %#v", resp)
829	}
830
831	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
832	req.ClientToken = root
833	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
834	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
835	if err != nil {
836		t.Fatalf("err: %v", err)
837	}
838	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
839		t.Fatalf("bad: %#v", resp)
840	}
841
842	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret/foo")
843	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
844	if err != nil {
845		t.Fatalf("err: %v", err)
846	}
847	if resp == nil || resp.Data == nil {
848		t.Fatalf("bad: %#v", resp)
849	}
850	keys = []string{}
851	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
852		t.Fatalf("err: %v", err)
853	}
854	if len(keys) != 3 {
855		t.Fatalf("Expected 3 secret lease, got %d: %#v", len(keys), keys)
856	}
857
858	// Listing subkeys
859	req = logical.TestRequest(t, logical.UpdateOperation, "secret/bar")
860	req.Data["foo"] = "bar"
861	req.ClientToken = root
862	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
863	if err != nil {
864		t.Fatalf("err: %v", err)
865	}
866	if resp != nil {
867		t.Fatalf("bad: %#v", resp)
868	}
869
870	// Read a key with a LeaseID
871	req = logical.TestRequest(t, logical.ReadOperation, "secret/bar")
872	req.ClientToken = root
873	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
874	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
875	if err != nil {
876		t.Fatalf("err: %v", err)
877	}
878	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
879		t.Fatalf("bad: %#v", resp)
880	}
881
882	req = logical.TestRequest(t, logical.ListOperation, "leases/lookup/secret")
883	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
884	if err != nil {
885		t.Fatalf("err: %v", err)
886	}
887	if resp == nil || resp.Data == nil {
888		t.Fatalf("bad: %#v", resp)
889	}
890	keys = []string{}
891	if err := mapstructure.WeakDecode(resp.Data["keys"], &keys); err != nil {
892		t.Fatalf("err: %v", err)
893	}
894	if len(keys) != 2 {
895		t.Fatalf("Expected 2 secret lease, got %d: %#v", len(keys), keys)
896	}
897	expected := []string{"bar/", "foo/"}
898	if !reflect.DeepEqual(expected, keys) {
899		t.Fatalf("exp: %#v, act: %#v", expected, keys)
900	}
901}
902
903func TestSystemBackend_renew(t *testing.T) {
904	core, b, root := testCoreSystemBackend(t)
905
906	// Create a key with a lease
907	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
908	req.Data["foo"] = "bar"
909	req.ClientToken = root
910	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
911	if err != nil {
912		t.Fatalf("err: %v", err)
913	}
914	if resp != nil {
915		t.Fatalf("bad: %#v", resp)
916	}
917
918	// Read a key with a LeaseID
919	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
920	req.ClientToken = root
921	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
922	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
923	if err != nil {
924		t.Fatalf("err: %v", err)
925	}
926	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
927		t.Fatalf("bad: %#v", resp)
928	}
929
930	// Attempt renew
931	req2 := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID)
932	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
933	if err != logical.ErrInvalidRequest {
934		t.Fatalf("err: %v", err)
935	}
936
937	// Should get error about non-renewability
938	if resp2.Data["error"] != "lease is not renewable" {
939		t.Fatalf("bad: %#v", resp)
940	}
941
942	// Add a TTL to the lease
943	req = logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
944	req.Data["foo"] = "bar"
945	req.Data["ttl"] = "180s"
946	req.ClientToken = root
947	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
948	if err != nil {
949		t.Fatalf("err: %v", err)
950	}
951	if resp != nil {
952		t.Fatalf("bad: %#v", resp)
953	}
954
955	// Read a key with a LeaseID
956	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
957	req.ClientToken = root
958	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
959	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
960	if err != nil {
961		t.Fatalf("err: %v", err)
962	}
963	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
964		t.Fatalf("bad: %#v", resp)
965	}
966
967	// Attempt renew
968	req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID)
969	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
970	if err != nil {
971		t.Fatalf("err: %v", err)
972	}
973	if resp2.IsError() {
974		t.Fatalf("got an error")
975	}
976	if resp2.Data == nil {
977		t.Fatal("nil data")
978	}
979	if resp.Secret.TTL != 180*time.Second {
980		t.Fatalf("bad lease duration: %v", resp.Secret.TTL)
981	}
982
983	// Test the other route path
984	req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/renew")
985	req2.Data["lease_id"] = resp.Secret.LeaseID
986	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
987	if err != nil {
988		t.Fatalf("err: %v", err)
989	}
990	if resp2.IsError() {
991		t.Fatalf("got an error")
992	}
993	if resp2.Data == nil {
994		t.Fatal("nil data")
995	}
996	if resp.Secret.TTL != 180*time.Second {
997		t.Fatalf("bad lease duration: %v", resp.Secret.TTL)
998	}
999
1000	// Test orig path
1001	req2 = logical.TestRequest(t, logical.UpdateOperation, "renew")
1002	req2.Data["lease_id"] = resp.Secret.LeaseID
1003	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
1004	if err != nil {
1005		t.Fatalf("err: %v", err)
1006	}
1007	if resp2.IsError() {
1008		t.Fatalf("got an error")
1009	}
1010	if resp2.Data == nil {
1011		t.Fatal("nil data")
1012	}
1013	if resp.Secret.TTL != time.Second*180 {
1014		t.Fatalf("bad lease duration: %v", resp.Secret.TTL)
1015	}
1016}
1017
1018func TestSystemBackend_renew_invalidID(t *testing.T) {
1019	b := testSystemBackend(t)
1020
1021	// Attempt renew
1022	req := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/foobarbaz")
1023	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1024	if err != logical.ErrInvalidRequest {
1025		t.Fatalf("err: %v", err)
1026	}
1027	if resp.Data["error"] != "lease not found" {
1028		t.Fatalf("bad: %v", resp)
1029	}
1030
1031	// Attempt renew with other method
1032	req = logical.TestRequest(t, logical.UpdateOperation, "leases/renew")
1033	req.Data["lease_id"] = "foobarbaz"
1034	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1035	if err != logical.ErrInvalidRequest {
1036		t.Fatalf("err: %v", err)
1037	}
1038	if resp.Data["error"] != "lease not found" {
1039		t.Fatalf("bad: %v", resp)
1040	}
1041}
1042
1043func TestSystemBackend_renew_invalidID_origUrl(t *testing.T) {
1044	b := testSystemBackend(t)
1045
1046	// Attempt renew
1047	req := logical.TestRequest(t, logical.UpdateOperation, "renew/foobarbaz")
1048	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1049	if err != logical.ErrInvalidRequest {
1050		t.Fatalf("err: %v", err)
1051	}
1052	if resp.Data["error"] != "lease not found" {
1053		t.Fatalf("bad: %v", resp)
1054	}
1055
1056	// Attempt renew with other method
1057	req = logical.TestRequest(t, logical.UpdateOperation, "renew")
1058	req.Data["lease_id"] = "foobarbaz"
1059	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1060	if err != logical.ErrInvalidRequest {
1061		t.Fatalf("err: %v", err)
1062	}
1063	if resp.Data["error"] != "lease not found" {
1064		t.Fatalf("bad: %v", resp)
1065	}
1066}
1067
1068func TestSystemBackend_revoke(t *testing.T) {
1069	core, b, root := testCoreSystemBackend(t)
1070
1071	// Create a key with a lease
1072	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
1073	req.Data["foo"] = "bar"
1074	req.Data["lease"] = "1h"
1075	req.ClientToken = root
1076	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
1077	if err != nil {
1078		t.Fatalf("err: %v", err)
1079	}
1080	if resp != nil {
1081		t.Fatalf("bad: %#v", resp)
1082	}
1083
1084	// Read a key with a LeaseID
1085	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1086	req.ClientToken = root
1087	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1088	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1089	if err != nil {
1090		t.Fatalf("err: %v", err)
1091	}
1092	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1093		t.Fatalf("bad: %#v", resp)
1094	}
1095
1096	// Attempt revoke
1097	req2 := logical.TestRequest(t, logical.UpdateOperation, "revoke/"+resp.Secret.LeaseID)
1098	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
1099	if err != nil {
1100		t.Fatalf("err: %v %#v", err, resp2)
1101	}
1102	if resp2 != nil {
1103		t.Fatalf("bad: %#v", resp)
1104	}
1105
1106	// Attempt renew
1107	req3 := logical.TestRequest(t, logical.UpdateOperation, "renew/"+resp.Secret.LeaseID)
1108	resp3, err := b.HandleRequest(namespace.RootContext(nil), req3)
1109	if err != logical.ErrInvalidRequest {
1110		t.Fatalf("err: %v", err)
1111	}
1112	if resp3.Data["error"] != "lease not found" {
1113		t.Fatalf("bad: %v", *resp3)
1114	}
1115
1116	// Read a key with a LeaseID
1117	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1118	req.ClientToken = root
1119	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1120	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1121	if err != nil {
1122		t.Fatalf("err: %v", err)
1123	}
1124	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1125		t.Fatalf("bad: %#v", resp)
1126	}
1127
1128	// Test the other route path
1129	req2 = logical.TestRequest(t, logical.UpdateOperation, "revoke")
1130	req2.Data["lease_id"] = resp.Secret.LeaseID
1131	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
1132	if err != nil {
1133		t.Fatalf("err: %v %#v", err, resp2)
1134	}
1135	if resp2 != nil {
1136		t.Fatalf("bad: %#v", resp)
1137	}
1138
1139	// Read a key with a LeaseID
1140	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1141	req.ClientToken = root
1142	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1143	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1144	if err != nil {
1145		t.Fatalf("err: %v", err)
1146	}
1147	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1148		t.Fatalf("bad: %#v", resp)
1149	}
1150
1151	// Test the other route path
1152	req2 = logical.TestRequest(t, logical.UpdateOperation, "leases/revoke")
1153	req2.Data["lease_id"] = resp.Secret.LeaseID
1154	resp2, err = b.HandleRequest(namespace.RootContext(nil), req2)
1155	if err != nil {
1156		t.Fatalf("err: %v %#v", err, resp2)
1157	}
1158	if resp2 != nil {
1159		t.Fatalf("bad: %#v", resp)
1160	}
1161}
1162
1163func TestSystemBackend_revoke_invalidID(t *testing.T) {
1164	b := testSystemBackend(t)
1165
1166	// Attempt revoke
1167	req := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke/foobarbaz")
1168	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1169	if err != nil {
1170		t.Fatalf("err: %v", err)
1171	}
1172	if resp != nil {
1173		t.Fatalf("bad: %v", resp)
1174	}
1175
1176	// Attempt revoke with other method
1177	req = logical.TestRequest(t, logical.UpdateOperation, "leases/revoke")
1178	req.Data["lease_id"] = "foobarbaz"
1179	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1180	if err != nil {
1181		t.Fatalf("err: %v", err)
1182	}
1183	if resp != nil {
1184		t.Fatalf("bad: %v", resp)
1185	}
1186}
1187
1188func TestSystemBackend_revoke_invalidID_origUrl(t *testing.T) {
1189	b := testSystemBackend(t)
1190
1191	// Attempt revoke
1192	req := logical.TestRequest(t, logical.UpdateOperation, "revoke/foobarbaz")
1193	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1194	if err != nil {
1195		t.Fatalf("err: %v", err)
1196	}
1197	if resp != nil {
1198		t.Fatalf("bad: %v", resp)
1199	}
1200
1201	// Attempt revoke with other method
1202	req = logical.TestRequest(t, logical.UpdateOperation, "revoke")
1203	req.Data["lease_id"] = "foobarbaz"
1204	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1205	if err != nil {
1206		t.Fatalf("err: %v", err)
1207	}
1208	if resp != nil {
1209		t.Fatalf("bad: %v", resp)
1210	}
1211}
1212
1213func TestSystemBackend_revokePrefix(t *testing.T) {
1214	core, b, root := testCoreSystemBackend(t)
1215
1216	// Create a key with a lease
1217	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
1218	req.Data["foo"] = "bar"
1219	req.Data["lease"] = "1h"
1220	req.ClientToken = root
1221	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
1222	if err != nil {
1223		t.Fatalf("err: %v", err)
1224	}
1225	if resp != nil {
1226		t.Fatalf("bad: %#v", resp)
1227	}
1228
1229	// Read a key with a LeaseID
1230	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1231	req.ClientToken = root
1232	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1233	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1234	if err != nil {
1235		t.Fatalf("err: %v", err)
1236	}
1237	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1238		t.Fatalf("bad: %#v", resp)
1239	}
1240
1241	// Attempt revoke
1242	req2 := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke-prefix/secret/")
1243	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
1244	if err != nil {
1245		t.Fatalf("err: %v %#v", err, resp2)
1246	}
1247	if resp2 != nil {
1248		t.Fatalf("bad: %#v", resp)
1249	}
1250
1251	// Attempt renew
1252	req3 := logical.TestRequest(t, logical.UpdateOperation, "leases/renew/"+resp.Secret.LeaseID)
1253	resp3, err := b.HandleRequest(namespace.RootContext(nil), req3)
1254	if err != logical.ErrInvalidRequest {
1255		t.Fatalf("err: %v", err)
1256	}
1257	if resp3.Data["error"] != "lease not found" {
1258		t.Fatalf("bad: %v", *resp3)
1259	}
1260}
1261
1262func TestSystemBackend_revokePrefix_origUrl(t *testing.T) {
1263	core, b, root := testCoreSystemBackend(t)
1264
1265	// Create a key with a lease
1266	req := logical.TestRequest(t, logical.UpdateOperation, "secret/foo")
1267	req.Data["foo"] = "bar"
1268	req.Data["lease"] = "1h"
1269	req.ClientToken = root
1270	resp, err := core.HandleRequest(namespace.RootContext(nil), req)
1271	if err != nil {
1272		t.Fatalf("err: %v", err)
1273	}
1274	if resp != nil {
1275		t.Fatalf("bad: %#v", resp)
1276	}
1277
1278	// Read a key with a LeaseID
1279	req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
1280	req.ClientToken = root
1281	req.SetTokenEntry(&logical.TokenEntry{ID: root, NamespaceID: "root", Policies: []string{"root"}})
1282	resp, err = core.HandleRequest(namespace.RootContext(nil), req)
1283	if err != nil {
1284		t.Fatalf("err: %v", err)
1285	}
1286	if resp == nil || resp.Secret == nil || resp.Secret.LeaseID == "" {
1287		t.Fatalf("bad: %#v", resp)
1288	}
1289
1290	// Attempt revoke
1291	req2 := logical.TestRequest(t, logical.UpdateOperation, "revoke-prefix/secret/")
1292	resp2, err := b.HandleRequest(namespace.RootContext(nil), req2)
1293	if err != nil {
1294		t.Fatalf("err: %v %#v", err, resp2)
1295	}
1296	if resp2 != nil {
1297		t.Fatalf("bad: %#v", resp)
1298	}
1299
1300	// Attempt renew
1301	req3 := logical.TestRequest(t, logical.UpdateOperation, "renew/"+resp.Secret.LeaseID)
1302	resp3, err := b.HandleRequest(namespace.RootContext(nil), req3)
1303	if err != logical.ErrInvalidRequest {
1304		t.Fatalf("err: %v", err)
1305	}
1306	if resp3.Data["error"] != "lease not found" {
1307		t.Fatalf("bad: %#v", *resp3)
1308	}
1309}
1310
1311func TestSystemBackend_revokePrefixAuth_newUrl(t *testing.T) {
1312	core, _, _ := TestCoreUnsealed(t)
1313
1314	ts := core.tokenStore
1315	bc := &logical.BackendConfig{
1316		Logger: core.logger,
1317		System: logical.StaticSystemView{
1318			DefaultLeaseTTLVal: time.Hour * 24,
1319			MaxLeaseTTLVal:     time.Hour * 24 * 32,
1320		},
1321	}
1322	b := NewSystemBackend(core, hclog.New(&hclog.LoggerOptions{}))
1323	err := b.Backend.Setup(namespace.RootContext(nil), bc)
1324	if err != nil {
1325		t.Fatal(err)
1326	}
1327
1328	exp := ts.expiration
1329
1330	te := &logical.TokenEntry{
1331		ID:          "foo",
1332		Path:        "auth/github/login/bar",
1333		TTL:         time.Hour,
1334		NamespaceID: namespace.RootNamespaceID,
1335	}
1336	testMakeTokenDirectly(t, ts, te)
1337
1338	te, err = ts.Lookup(namespace.RootContext(nil), "foo")
1339	if err != nil {
1340		t.Fatal(err)
1341	}
1342	if te == nil {
1343		t.Fatal("token entry was nil")
1344	}
1345
1346	// Create a new token
1347	auth := &logical.Auth{
1348		ClientToken: te.ID,
1349		LeaseOptions: logical.LeaseOptions{
1350			TTL: time.Hour,
1351		},
1352	}
1353	err = exp.RegisterAuth(namespace.RootContext(nil), te, auth)
1354	if err != nil {
1355		t.Fatalf("err: %v", err)
1356	}
1357
1358	req := logical.TestRequest(t, logical.UpdateOperation, "leases/revoke-prefix/auth/github/")
1359	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1360	if err != nil {
1361		t.Fatalf("err: %v %v", err, resp)
1362	}
1363	if resp != nil {
1364		t.Fatalf("bad: %#v", resp)
1365	}
1366
1367	te, err = ts.Lookup(namespace.RootContext(nil), te.ID)
1368	if err != nil {
1369		t.Fatalf("err: %v", err)
1370	}
1371	if te != nil {
1372		t.Fatalf("bad: %v", te)
1373	}
1374}
1375
1376func TestSystemBackend_revokePrefixAuth_origUrl(t *testing.T) {
1377	core, _, _ := TestCoreUnsealed(t)
1378	ts := core.tokenStore
1379	bc := &logical.BackendConfig{
1380		Logger: core.logger,
1381		System: logical.StaticSystemView{
1382			DefaultLeaseTTLVal: time.Hour * 24,
1383			MaxLeaseTTLVal:     time.Hour * 24 * 32,
1384		},
1385	}
1386	b := NewSystemBackend(core, hclog.New(&hclog.LoggerOptions{}))
1387	err := b.Backend.Setup(namespace.RootContext(nil), bc)
1388	if err != nil {
1389		t.Fatal(err)
1390	}
1391
1392	exp := ts.expiration
1393
1394	te := &logical.TokenEntry{
1395		ID:          "foo",
1396		Path:        "auth/github/login/bar",
1397		TTL:         time.Hour,
1398		NamespaceID: namespace.RootNamespaceID,
1399	}
1400	testMakeTokenDirectly(t, ts, te)
1401
1402	te, err = ts.Lookup(namespace.RootContext(nil), "foo")
1403	if err != nil {
1404		t.Fatal(err)
1405	}
1406	if te == nil {
1407		t.Fatal("token entry was nil")
1408	}
1409
1410	// Create a new token
1411	auth := &logical.Auth{
1412		ClientToken: te.ID,
1413		LeaseOptions: logical.LeaseOptions{
1414			TTL: time.Hour,
1415		},
1416	}
1417	err = exp.RegisterAuth(namespace.RootContext(nil), te, auth)
1418	if err != nil {
1419		t.Fatalf("err: %v", err)
1420	}
1421
1422	req := logical.TestRequest(t, logical.UpdateOperation, "revoke-prefix/auth/github/")
1423	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1424	if err != nil {
1425		t.Fatalf("err: %v %v", err, resp)
1426	}
1427	if resp != nil {
1428		t.Fatalf("bad: %#v", resp)
1429	}
1430
1431	te, err = ts.Lookup(namespace.RootContext(nil), te.ID)
1432	if err != nil {
1433		t.Fatalf("err: %v", err)
1434	}
1435	if te != nil {
1436		t.Fatalf("bad: %v", te)
1437	}
1438}
1439
1440func TestSystemBackend_authTable(t *testing.T) {
1441	b := testSystemBackend(t)
1442	req := logical.TestRequest(t, logical.ReadOperation, "auth")
1443	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1444	if err != nil {
1445		t.Fatalf("err: %v", err)
1446	}
1447
1448	exp := map[string]interface{}{
1449		"token/": map[string]interface{}{
1450			"type":        "token",
1451			"description": "token based credentials",
1452			"accessor":    resp.Data["token/"].(map[string]interface{})["accessor"],
1453			"uuid":        resp.Data["token/"].(map[string]interface{})["uuid"],
1454			"config": map[string]interface{}{
1455				"default_lease_ttl": int64(0),
1456				"max_lease_ttl":     int64(0),
1457				"force_no_cache":    false,
1458				"token_type":        "default-service",
1459			},
1460			"local":     false,
1461			"seal_wrap": false,
1462			"options":   map[string]string(nil),
1463		},
1464	}
1465	if diff := deep.Equal(resp.Data, exp); diff != nil {
1466		t.Fatal(diff)
1467	}
1468}
1469
1470func TestSystemBackend_enableAuth(t *testing.T) {
1471	c, b, _ := testCoreSystemBackend(t)
1472	c.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
1473		return &NoopBackend{BackendType: logical.TypeCredential}, nil
1474	}
1475
1476	req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo")
1477	req.Data["type"] = "noop"
1478	req.Data["config"] = map[string]interface{}{
1479		"default_lease_ttl": "35m",
1480		"max_lease_ttl":     "45m",
1481	}
1482	req.Data["local"] = true
1483	req.Data["seal_wrap"] = true
1484
1485	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1486	if err != nil {
1487		t.Fatalf("err: %v", err)
1488	}
1489	if resp != nil {
1490		t.Fatalf("bad: %v", resp)
1491	}
1492
1493	req = logical.TestRequest(t, logical.ReadOperation, "auth")
1494	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1495	if err != nil {
1496		t.Fatalf("err: %v", err)
1497	}
1498	if resp == nil {
1499		t.Fatal("resp is nil")
1500	}
1501
1502	exp := map[string]interface{}{
1503		"foo/": map[string]interface{}{
1504			"type":        "noop",
1505			"description": "",
1506			"accessor":    resp.Data["foo/"].(map[string]interface{})["accessor"],
1507			"uuid":        resp.Data["foo/"].(map[string]interface{})["uuid"],
1508			"config": map[string]interface{}{
1509				"default_lease_ttl": int64(2100),
1510				"max_lease_ttl":     int64(2700),
1511				"force_no_cache":    false,
1512				"token_type":        "default-service",
1513			},
1514			"local":     true,
1515			"seal_wrap": true,
1516			"options":   map[string]string{},
1517		},
1518		"token/": map[string]interface{}{
1519			"type":        "token",
1520			"description": "token based credentials",
1521			"accessor":    resp.Data["token/"].(map[string]interface{})["accessor"],
1522			"uuid":        resp.Data["token/"].(map[string]interface{})["uuid"],
1523			"config": map[string]interface{}{
1524				"default_lease_ttl": int64(0),
1525				"max_lease_ttl":     int64(0),
1526				"force_no_cache":    false,
1527				"token_type":        "default-service",
1528			},
1529			"local":     false,
1530			"seal_wrap": false,
1531			"options":   map[string]string(nil),
1532		},
1533	}
1534	if diff := deep.Equal(resp.Data, exp); diff != nil {
1535		t.Fatal(diff)
1536	}
1537}
1538
1539func TestSystemBackend_enableAuth_invalid(t *testing.T) {
1540	b := testSystemBackend(t)
1541	req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo")
1542	req.Data["type"] = "nope"
1543	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1544	if err != logical.ErrInvalidRequest {
1545		t.Fatalf("err: %v", err)
1546	}
1547	if resp.Data["error"] != `plugin not found in the catalog: nope` {
1548		t.Fatalf("bad: %v", resp)
1549	}
1550}
1551
1552func TestSystemBackend_disableAuth(t *testing.T) {
1553	c, b, _ := testCoreSystemBackend(t)
1554	c.credentialBackends["noop"] = func(context.Context, *logical.BackendConfig) (logical.Backend, error) {
1555		return &NoopBackend{}, nil
1556	}
1557
1558	// Register the backend
1559	req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo")
1560	req.Data["type"] = "noop"
1561	b.HandleRequest(namespace.RootContext(nil), req)
1562
1563	// Deregister it
1564	req = logical.TestRequest(t, logical.DeleteOperation, "auth/foo")
1565	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1566	if err != nil {
1567		t.Fatalf("err: %v", err)
1568	}
1569	if resp != nil {
1570		t.Fatalf("bad: %v", resp)
1571	}
1572}
1573
1574func TestSystemBackend_policyList(t *testing.T) {
1575	b := testSystemBackend(t)
1576	req := logical.TestRequest(t, logical.ReadOperation, "policy")
1577	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1578	if err != nil {
1579		t.Fatalf("err: %v", err)
1580	}
1581
1582	exp := map[string]interface{}{
1583		"keys":     []string{"default", "root"},
1584		"policies": []string{"default", "root"},
1585	}
1586	if !reflect.DeepEqual(resp.Data, exp) {
1587		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1588	}
1589}
1590
1591func TestSystemBackend_policyCRUD(t *testing.T) {
1592	b := testSystemBackend(t)
1593
1594	// Create the policy
1595	rules := `path "foo/" { policy = "read" }`
1596	req := logical.TestRequest(t, logical.UpdateOperation, "policy/Foo")
1597	req.Data["rules"] = rules
1598	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1599	if err != nil {
1600		t.Fatalf("err: %v %#v", err, resp)
1601	}
1602	if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
1603		t.Fatalf("bad: %#v", resp)
1604	}
1605
1606	// Read the policy
1607	req = logical.TestRequest(t, logical.ReadOperation, "policy/foo")
1608	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1609	if err != nil {
1610		t.Fatalf("err: %v", err)
1611	}
1612
1613	exp := map[string]interface{}{
1614		"name":  "foo",
1615		"rules": rules,
1616	}
1617	if !reflect.DeepEqual(resp.Data, exp) {
1618		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1619	}
1620
1621	// Read, and make sure that case has been normalized
1622	req = logical.TestRequest(t, logical.ReadOperation, "policy/Foo")
1623	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1624	if err != nil {
1625		t.Fatalf("err: %v", err)
1626	}
1627
1628	exp = map[string]interface{}{
1629		"name":  "foo",
1630		"rules": rules,
1631	}
1632	if !reflect.DeepEqual(resp.Data, exp) {
1633		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1634	}
1635
1636	// List the policies
1637	req = logical.TestRequest(t, logical.ReadOperation, "policy")
1638	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1639	if err != nil {
1640		t.Fatalf("err: %v", err)
1641	}
1642
1643	exp = map[string]interface{}{
1644		"keys":     []string{"default", "foo", "root"},
1645		"policies": []string{"default", "foo", "root"},
1646	}
1647	if !reflect.DeepEqual(resp.Data, exp) {
1648		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1649	}
1650
1651	// Delete the policy
1652	req = logical.TestRequest(t, logical.DeleteOperation, "policy/foo")
1653	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1654	if err != nil {
1655		t.Fatalf("err: %v", err)
1656	}
1657	if resp != nil {
1658		t.Fatalf("bad: %#v", resp)
1659	}
1660
1661	// Read the policy (deleted)
1662	req = logical.TestRequest(t, logical.ReadOperation, "policy/foo")
1663	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1664	if err != nil {
1665		t.Fatalf("err: %v", err)
1666	}
1667	if resp != nil {
1668		t.Fatalf("bad: %#v", resp)
1669	}
1670
1671	// List the policies (deleted)
1672	req = logical.TestRequest(t, logical.ReadOperation, "policy")
1673	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1674	if err != nil {
1675		t.Fatalf("err: %v", err)
1676	}
1677
1678	exp = map[string]interface{}{
1679		"keys":     []string{"default", "root"},
1680		"policies": []string{"default", "root"},
1681	}
1682	if !reflect.DeepEqual(resp.Data, exp) {
1683		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1684	}
1685}
1686
1687func TestSystemBackend_enableAudit(t *testing.T) {
1688	c, b, _ := testCoreSystemBackend(t)
1689	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1690		return &NoopAudit{
1691			Config: config,
1692		}, nil
1693	}
1694
1695	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1696	req.Data["type"] = "noop"
1697
1698	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1699	if err != nil {
1700		t.Fatalf("err: %v", err)
1701	}
1702	if resp != nil {
1703		t.Fatalf("bad: %v", resp)
1704	}
1705}
1706
1707func TestSystemBackend_auditHash(t *testing.T) {
1708	c, b, _ := testCoreSystemBackend(t)
1709	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1710		view := &logical.InmemStorage{}
1711		view.Put(namespace.RootContext(nil), &logical.StorageEntry{
1712			Key:   "salt",
1713			Value: []byte("foo"),
1714		})
1715		config.SaltView = view
1716		config.SaltConfig = &salt.Config{
1717			HMAC:     sha256.New,
1718			HMACType: "hmac-sha256",
1719			Location: salt.DefaultLocation,
1720		}
1721		return &NoopAudit{
1722			Config: config,
1723		}, nil
1724	}
1725
1726	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1727	req.Data["type"] = "noop"
1728
1729	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1730	if err != nil {
1731		t.Fatalf("err: %v", err)
1732	}
1733	if resp != nil {
1734		t.Fatalf("bad: %v", resp)
1735	}
1736
1737	req = logical.TestRequest(t, logical.UpdateOperation, "audit-hash/foo")
1738	req.Data["input"] = "bar"
1739
1740	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1741	if err != nil {
1742		t.Fatalf("err: %v", err)
1743	}
1744	if resp == nil || resp.Data == nil {
1745		t.Fatalf("response or its data was nil")
1746	}
1747	hash, ok := resp.Data["hash"]
1748	if !ok {
1749		t.Fatalf("did not get hash back in response, response was %#v", resp.Data)
1750	}
1751	if hash.(string) != "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317" {
1752		t.Fatalf("bad hash back: %s", hash.(string))
1753	}
1754}
1755
1756func TestSystemBackend_enableAudit_invalid(t *testing.T) {
1757	b := testSystemBackend(t)
1758	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1759	req.Data["type"] = "nope"
1760	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1761	if err != logical.ErrInvalidRequest {
1762		t.Fatalf("err: %v", err)
1763	}
1764	if resp.Data["error"] != `unknown backend type: "nope"` {
1765		t.Fatalf("bad: %v", resp)
1766	}
1767}
1768
1769func TestSystemBackend_auditTable(t *testing.T) {
1770	c, b, _ := testCoreSystemBackend(t)
1771	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1772		return &NoopAudit{
1773			Config: config,
1774		}, nil
1775	}
1776
1777	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1778	req.Data["type"] = "noop"
1779	req.Data["description"] = "testing"
1780	req.Data["options"] = map[string]interface{}{
1781		"foo": "bar",
1782	}
1783	req.Data["local"] = true
1784	b.HandleRequest(namespace.RootContext(nil), req)
1785
1786	req = logical.TestRequest(t, logical.ReadOperation, "audit")
1787	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1788	if err != nil {
1789		t.Fatalf("err: %v", err)
1790	}
1791
1792	exp := map[string]interface{}{
1793		"foo/": map[string]interface{}{
1794			"path":        "foo/",
1795			"type":        "noop",
1796			"description": "testing",
1797			"options": map[string]string{
1798				"foo": "bar",
1799			},
1800			"local": true,
1801		},
1802	}
1803	if !reflect.DeepEqual(resp.Data, exp) {
1804		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1805	}
1806}
1807
1808func TestSystemBackend_disableAudit(t *testing.T) {
1809	c, b, _ := testCoreSystemBackend(t)
1810	c.auditBackends["noop"] = func(ctx context.Context, config *audit.BackendConfig) (audit.Backend, error) {
1811		return &NoopAudit{
1812			Config: config,
1813		}, nil
1814	}
1815
1816	req := logical.TestRequest(t, logical.UpdateOperation, "audit/foo")
1817	req.Data["type"] = "noop"
1818	req.Data["description"] = "testing"
1819	req.Data["options"] = map[string]interface{}{
1820		"foo": "bar",
1821	}
1822	b.HandleRequest(namespace.RootContext(nil), req)
1823
1824	// Deregister it
1825	req = logical.TestRequest(t, logical.DeleteOperation, "audit/foo")
1826	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1827	if err != nil {
1828		t.Fatalf("err: %v", err)
1829	}
1830	if resp != nil {
1831		t.Fatalf("bad: %v", resp)
1832	}
1833}
1834
1835func TestSystemBackend_rawRead_Compressed(t *testing.T) {
1836	b := testSystemBackendRaw(t)
1837
1838	req := logical.TestRequest(t, logical.ReadOperation, "raw/core/mounts")
1839	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1840	if err != nil {
1841		t.Fatalf("err: %v", err)
1842	}
1843	if !strings.HasPrefix(resp.Data["value"].(string), "{\"type\":\"mounts\"") {
1844		t.Fatalf("bad: %v", resp)
1845	}
1846}
1847
1848func TestSystemBackend_rawRead_Protected(t *testing.T) {
1849	b := testSystemBackendRaw(t)
1850
1851	req := logical.TestRequest(t, logical.ReadOperation, "raw/"+keyringPath)
1852	_, err := b.HandleRequest(namespace.RootContext(nil), req)
1853	if err != logical.ErrInvalidRequest {
1854		t.Fatalf("err: %v", err)
1855	}
1856}
1857
1858func TestSystemBackend_rawWrite_Protected(t *testing.T) {
1859	b := testSystemBackendRaw(t)
1860
1861	req := logical.TestRequest(t, logical.UpdateOperation, "raw/"+keyringPath)
1862	_, err := b.HandleRequest(namespace.RootContext(nil), req)
1863	if err != logical.ErrInvalidRequest {
1864		t.Fatalf("err: %v", err)
1865	}
1866}
1867
1868func TestSystemBackend_rawReadWrite(t *testing.T) {
1869	_, b, _ := testCoreSystemBackendRaw(t)
1870
1871	req := logical.TestRequest(t, logical.UpdateOperation, "raw/sys/policy/test")
1872	req.Data["value"] = `path "secret/" { policy = "read" }`
1873	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1874	if err != nil {
1875		t.Fatalf("err: %v", err)
1876	}
1877	if resp != nil {
1878		t.Fatalf("bad: %v", resp)
1879	}
1880
1881	// Read via raw API
1882	req = logical.TestRequest(t, logical.ReadOperation, "raw/sys/policy/test")
1883	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1884	if err != nil {
1885		t.Fatalf("err: %v", err)
1886	}
1887	if !strings.HasPrefix(resp.Data["value"].(string), "path") {
1888		t.Fatalf("bad: %v", resp)
1889	}
1890
1891	// Note: since the upgrade code is gone that upgraded from 0.1, we can't
1892	// simply parse this out directly via GetPolicy, so the test now ends here.
1893}
1894
1895func TestSystemBackend_rawDelete_Protected(t *testing.T) {
1896	b := testSystemBackendRaw(t)
1897
1898	req := logical.TestRequest(t, logical.DeleteOperation, "raw/"+keyringPath)
1899	_, err := b.HandleRequest(namespace.RootContext(nil), req)
1900	if err != logical.ErrInvalidRequest {
1901		t.Fatalf("err: %v", err)
1902	}
1903}
1904
1905func TestSystemBackend_rawDelete(t *testing.T) {
1906	c, b, _ := testCoreSystemBackendRaw(t)
1907
1908	// set the policy!
1909	p := &Policy{
1910		Name:      "test",
1911		Type:      PolicyTypeACL,
1912		namespace: namespace.RootNamespace,
1913	}
1914	err := c.policyStore.SetPolicy(namespace.RootContext(nil), p)
1915	if err != nil {
1916		t.Fatalf("err: %v", err)
1917	}
1918
1919	// Delete the policy
1920	req := logical.TestRequest(t, logical.DeleteOperation, "raw/sys/policy/test")
1921	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1922	if err != nil {
1923		t.Fatalf("err: %v", err)
1924	}
1925	if resp != nil {
1926		t.Fatalf("bad: %v", resp)
1927	}
1928
1929	// Policy should be gone
1930	c.policyStore.tokenPoliciesLRU.Purge()
1931	out, err := c.policyStore.GetPolicy(namespace.RootContext(nil), "test", PolicyTypeToken)
1932	if err != nil {
1933		t.Fatalf("err: %v", err)
1934	}
1935	if out != nil {
1936		t.Fatalf("policy should be gone")
1937	}
1938}
1939
1940func TestSystemBackend_keyStatus(t *testing.T) {
1941	b := testSystemBackend(t)
1942	req := logical.TestRequest(t, logical.ReadOperation, "key-status")
1943	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1944	if err != nil {
1945		t.Fatalf("err: %v", err)
1946	}
1947
1948	exp := map[string]interface{}{
1949		"term": 1,
1950	}
1951	delete(resp.Data, "install_time")
1952	if !reflect.DeepEqual(resp.Data, exp) {
1953		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1954	}
1955}
1956
1957func TestSystemBackend_rotate(t *testing.T) {
1958	b := testSystemBackend(t)
1959
1960	req := logical.TestRequest(t, logical.UpdateOperation, "rotate")
1961	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
1962	if err != nil {
1963		t.Fatalf("err: %v", err)
1964	}
1965	if resp != nil {
1966		t.Fatalf("bad: %v", resp)
1967	}
1968
1969	req = logical.TestRequest(t, logical.ReadOperation, "key-status")
1970	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
1971	if err != nil {
1972		t.Fatalf("err: %v", err)
1973	}
1974
1975	exp := map[string]interface{}{
1976		"term": 2,
1977	}
1978	delete(resp.Data, "install_time")
1979	if !reflect.DeepEqual(resp.Data, exp) {
1980		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
1981	}
1982}
1983
1984func testSystemBackend(t *testing.T) logical.Backend {
1985	c, _, _ := TestCoreUnsealed(t)
1986	return c.systemBackend
1987}
1988
1989func testSystemBackendRaw(t *testing.T) logical.Backend {
1990	c, _, _ := TestCoreUnsealedRaw(t)
1991	return c.systemBackend
1992}
1993
1994func testCoreSystemBackend(t *testing.T) (*Core, logical.Backend, string) {
1995	c, _, root := TestCoreUnsealed(t)
1996	return c, c.systemBackend, root
1997}
1998
1999func testCoreSystemBackendRaw(t *testing.T) (*Core, logical.Backend, string) {
2000	c, _, root := TestCoreUnsealedRaw(t)
2001	return c, c.systemBackend, root
2002}
2003
2004func TestSystemBackend_PluginCatalog_CRUD(t *testing.T) {
2005	c, b, _ := testCoreSystemBackend(t)
2006	// Bootstrap the pluginCatalog
2007	sym, err := filepath.EvalSymlinks(os.TempDir())
2008	if err != nil {
2009		t.Fatalf("error: %v", err)
2010	}
2011	c.pluginCatalog.directory = sym
2012
2013	req := logical.TestRequest(t, logical.ListOperation, "plugins/catalog/database")
2014	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2015	if err != nil {
2016		t.Fatalf("err: %v", err)
2017	}
2018
2019	if len(resp.Data["keys"].([]string)) != len(c.builtinRegistry.Keys(consts.PluginTypeDatabase)) {
2020		t.Fatalf("Wrong number of plugins, got %d, expected %d", len(resp.Data["keys"].([]string)), len(builtinplugins.Registry.Keys(consts.PluginTypeDatabase)))
2021	}
2022
2023	req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/mysql-database-plugin")
2024	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2025	if err != nil {
2026		t.Fatalf("err: %v", err)
2027	}
2028
2029	actualRespData := resp.Data
2030	expectedRespData := map[string]interface{}{
2031		"name":    "mysql-database-plugin",
2032		"command": "",
2033		"args":    []string(nil),
2034		"sha256":  "",
2035		"builtin": true,
2036	}
2037	if !reflect.DeepEqual(actualRespData, expectedRespData) {
2038		t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actualRespData, expectedRespData)
2039	}
2040
2041	// Set a plugin
2042	file, err := ioutil.TempFile(os.TempDir(), "temp")
2043	if err != nil {
2044		t.Fatal(err)
2045	}
2046	defer file.Close()
2047
2048	// Check we can only specify args in one of command or args.
2049	command := fmt.Sprintf("%s --test", filepath.Base(file.Name()))
2050	req = logical.TestRequest(t, logical.UpdateOperation, "plugins/catalog/database/test-plugin")
2051	req.Data["args"] = []string{"--foo"}
2052	req.Data["sha_256"] = hex.EncodeToString([]byte{'1'})
2053	req.Data["command"] = command
2054	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2055	if err != nil {
2056		t.Fatalf("err: %v", err)
2057	}
2058	if resp.Error().Error() != "must not specify args in command and args field" {
2059		t.Fatalf("err: %v", resp.Error())
2060	}
2061
2062	delete(req.Data, "args")
2063	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2064	if err != nil || resp.Error() != nil {
2065		t.Fatalf("err: %v %v", err, resp.Error())
2066	}
2067
2068	req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/test-plugin")
2069	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2070	if err != nil {
2071		t.Fatalf("err: %v", err)
2072	}
2073
2074	actual := resp.Data
2075	expected := map[string]interface{}{
2076		"name":    "test-plugin",
2077		"command": filepath.Base(file.Name()),
2078		"args":    []string{"--test"},
2079		"sha256":  "31",
2080		"builtin": false,
2081	}
2082	if !reflect.DeepEqual(actual, expected) {
2083		t.Fatalf("expected did not match actual, got %#v\n expected %#v\n", actual, expected)
2084	}
2085
2086	// Delete plugin
2087	req = logical.TestRequest(t, logical.DeleteOperation, "plugins/catalog/database/test-plugin")
2088	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2089	if err != nil {
2090		t.Fatalf("err: %v", err)
2091	}
2092
2093	req = logical.TestRequest(t, logical.ReadOperation, "plugins/catalog/database/test-plugin")
2094	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2095	if resp != nil || err != nil {
2096		t.Fatalf("expected nil response, plugin not deleted correctly got resp: %v, err: %v", resp, err)
2097	}
2098}
2099
2100func TestSystemBackend_ToolsHash(t *testing.T) {
2101	b := testSystemBackend(t)
2102	req := logical.TestRequest(t, logical.UpdateOperation, "tools/hash")
2103	req.Data = map[string]interface{}{
2104		"input": "dGhlIHF1aWNrIGJyb3duIGZveA==",
2105	}
2106	_, err := b.HandleRequest(namespace.RootContext(nil), req)
2107	if err != nil {
2108		t.Fatalf("err: %v", err)
2109	}
2110
2111	doRequest := func(req *logical.Request, errExpected bool, expected string) {
2112		t.Helper()
2113		resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2114		if err != nil && !errExpected {
2115			t.Fatal(err)
2116		}
2117		if resp == nil {
2118			t.Fatal("expected non-nil response")
2119		}
2120		if errExpected {
2121			if !resp.IsError() {
2122				t.Fatalf("bad: got error response: %#v", *resp)
2123			}
2124			return
2125		}
2126		if resp.IsError() {
2127			t.Fatalf("bad: got error response: %#v", *resp)
2128		}
2129		sum, ok := resp.Data["sum"]
2130		if !ok {
2131			t.Fatal("no sum key found in returned data")
2132		}
2133		if sum.(string) != expected {
2134			t.Fatal("mismatched hashes")
2135		}
2136	}
2137
2138	// Test defaults -- sha2-256
2139	doRequest(req, false, "9ecb36561341d18eb65484e833efea61edc74b84cf5e6ae1b81c63533e25fc8f")
2140
2141	// Test algorithm selection in the path
2142	req.Path = "tools/hash/sha2-224"
2143	doRequest(req, false, "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865")
2144
2145	// Reset and test algorithm selection in the data
2146	req.Path = "tools/hash"
2147	req.Data["algorithm"] = "sha2-224"
2148	doRequest(req, false, "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865")
2149
2150	req.Data["algorithm"] = "sha2-384"
2151	doRequest(req, false, "15af9ec8be783f25c583626e9491dbf129dd6dd620466fdf05b3a1d0bb8381d30f4d3ec29f923ff1e09a0f6b337365a6")
2152
2153	req.Data["algorithm"] = "sha2-512"
2154	doRequest(req, false, "d9d380f29b97ad6a1d92e987d83fa5a02653301e1006dd2bcd51afa59a9147e9caedaf89521abc0f0b682adcd47fb512b8343c834a32f326fe9bef00542ce887")
2155
2156	// Test returning as base64
2157	req.Data["format"] = "base64"
2158	doRequest(req, false, "2dOA8puXrWodkumH2D+loCZTMB4QBt0rzVGvpZqRR+nK7a+JUhq8DwtoKtzUf7USuDQ8g0oy8yb+m+8AVCzohw==")
2159
2160	// Test bad input/format/algorithm
2161	req.Data["format"] = "base92"
2162	doRequest(req, true, "")
2163
2164	req.Data["format"] = "hex"
2165	req.Data["algorithm"] = "foobar"
2166	doRequest(req, true, "")
2167
2168	req.Data["algorithm"] = "sha2-256"
2169	req.Data["input"] = "foobar"
2170	doRequest(req, true, "")
2171}
2172
2173func TestSystemBackend_ToolsRandom(t *testing.T) {
2174	b := testSystemBackend(t)
2175	req := logical.TestRequest(t, logical.UpdateOperation, "tools/random")
2176
2177	_, err := b.HandleRequest(namespace.RootContext(nil), req)
2178	if err != nil {
2179		t.Fatalf("err: %v", err)
2180	}
2181
2182	doRequest := func(req *logical.Request, errExpected bool, format string, numBytes int) {
2183		t.Helper()
2184		getResponse := func() []byte {
2185			resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2186			if err != nil && !errExpected {
2187				t.Fatal(err)
2188			}
2189			if resp == nil {
2190				t.Fatal("expected non-nil response")
2191			}
2192			if errExpected {
2193				if !resp.IsError() {
2194					t.Fatalf("bad: got error response: %#v", *resp)
2195				}
2196				return nil
2197			}
2198			if resp.IsError() {
2199				t.Fatalf("bad: got error response: %#v", *resp)
2200			}
2201			if _, ok := resp.Data["random_bytes"]; !ok {
2202				t.Fatal("no random_bytes found in response")
2203			}
2204
2205			outputStr := resp.Data["random_bytes"].(string)
2206			var outputBytes []byte
2207			switch format {
2208			case "base64":
2209				outputBytes, err = base64.StdEncoding.DecodeString(outputStr)
2210			case "hex":
2211				outputBytes, err = hex.DecodeString(outputStr)
2212			default:
2213				t.Fatal("unknown format")
2214			}
2215			if err != nil {
2216				t.Fatal(err)
2217			}
2218
2219			return outputBytes
2220		}
2221
2222		rand1 := getResponse()
2223		// Expected error
2224		if rand1 == nil {
2225			return
2226		}
2227		rand2 := getResponse()
2228		if len(rand1) != numBytes || len(rand2) != numBytes {
2229			t.Fatal("length of output random bytes not what is expected")
2230		}
2231		if reflect.DeepEqual(rand1, rand2) {
2232			t.Fatal("found identical ouputs")
2233		}
2234	}
2235
2236	// Test defaults
2237	doRequest(req, false, "base64", 32)
2238
2239	// Test size selection in the path
2240	req.Path = "tools/random/24"
2241	req.Data["format"] = "hex"
2242	doRequest(req, false, "hex", 24)
2243
2244	// Test bad input/format
2245	req.Path = "tools/random"
2246	req.Data["format"] = "base92"
2247	doRequest(req, true, "", 0)
2248
2249	req.Data["format"] = "hex"
2250	req.Data["bytes"] = -1
2251	doRequest(req, true, "", 0)
2252
2253	req.Data["format"] = "hex"
2254	req.Data["bytes"] = maxBytes + 1
2255	doRequest(req, true, "", 0)
2256
2257}
2258
2259func TestSystemBackend_InternalUIMounts(t *testing.T) {
2260	_, b, rootToken := testCoreSystemBackend(t)
2261
2262	// Ensure no entries are in the endpoint as a starting point
2263	req := logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts")
2264	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2265	if err != nil {
2266		t.Fatalf("err: %v", err)
2267	}
2268
2269	exp := map[string]interface{}{
2270		"secret": map[string]interface{}{},
2271		"auth":   map[string]interface{}{},
2272	}
2273	if !reflect.DeepEqual(resp.Data, exp) {
2274		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
2275	}
2276
2277	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts")
2278	req.ClientToken = rootToken
2279	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2280	if err != nil {
2281		t.Fatalf("err: %v", err)
2282	}
2283
2284	exp = map[string]interface{}{
2285		"secret": map[string]interface{}{
2286			"secret/": map[string]interface{}{
2287				"type":        "kv",
2288				"description": "key/value secret storage",
2289				"accessor":    resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["accessor"],
2290				"uuid":        resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["uuid"],
2291				"config": map[string]interface{}{
2292					"default_lease_ttl": resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2293					"max_lease_ttl":     resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2294					"force_no_cache":    false,
2295				},
2296				"local":     false,
2297				"seal_wrap": false,
2298				"options": map[string]string{
2299					"version": "1",
2300				},
2301			},
2302			"sys/": map[string]interface{}{
2303				"type":        "system",
2304				"description": "system endpoints used for control, policy and debugging",
2305				"accessor":    resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["accessor"],
2306				"uuid":        resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["uuid"],
2307				"config": map[string]interface{}{
2308					"default_lease_ttl":           resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2309					"max_lease_ttl":               resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2310					"force_no_cache":              false,
2311					"passthrough_request_headers": []string{"Accept"},
2312				},
2313				"local":     false,
2314				"seal_wrap": false,
2315				"options":   map[string]string(nil),
2316			},
2317			"cubbyhole/": map[string]interface{}{
2318				"description": "per-token private secret storage",
2319				"type":        "cubbyhole",
2320				"accessor":    resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["accessor"],
2321				"uuid":        resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["uuid"],
2322				"config": map[string]interface{}{
2323					"default_lease_ttl": resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2324					"max_lease_ttl":     resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2325					"force_no_cache":    false,
2326				},
2327				"local":     true,
2328				"seal_wrap": false,
2329				"options":   map[string]string(nil),
2330			},
2331			"identity/": map[string]interface{}{
2332				"description": "identity store",
2333				"type":        "identity",
2334				"accessor":    resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["accessor"],
2335				"uuid":        resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["uuid"],
2336				"config": map[string]interface{}{
2337					"default_lease_ttl": resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64),
2338					"max_lease_ttl":     resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64),
2339					"force_no_cache":    false,
2340				},
2341				"local":     false,
2342				"seal_wrap": false,
2343				"options":   map[string]string(nil),
2344			},
2345		},
2346		"auth": map[string]interface{}{
2347			"token/": map[string]interface{}{
2348				"options": map[string]string(nil),
2349				"config": map[string]interface{}{
2350					"default_lease_ttl": int64(0),
2351					"max_lease_ttl":     int64(0),
2352					"force_no_cache":    false,
2353					"token_type":        "default-service",
2354				},
2355				"type":        "token",
2356				"description": "token based credentials",
2357				"accessor":    resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["accessor"],
2358				"uuid":        resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["uuid"],
2359				"local":       false,
2360				"seal_wrap":   false,
2361			},
2362		},
2363	}
2364	if diff := deep.Equal(resp.Data, exp); diff != nil {
2365		t.Fatal(diff)
2366	}
2367
2368	// Mount-tune an auth mount
2369	req = logical.TestRequest(t, logical.UpdateOperation, "auth/token/tune")
2370	req.Data["listing_visibility"] = "unauth"
2371	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2372	if resp.IsError() || err != nil {
2373		t.Fatalf("resp.Error: %v, err:%v", resp.Error(), err)
2374	}
2375
2376	// Mount-tune a secret mount
2377	req = logical.TestRequest(t, logical.UpdateOperation, "mounts/secret/tune")
2378	req.Data["listing_visibility"] = "unauth"
2379	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2380	if resp.IsError() || err != nil {
2381		t.Fatalf("resp.Error: %v, err:%v", resp.Error(), err)
2382	}
2383
2384	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts")
2385	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2386	if err != nil {
2387		t.Fatalf("err: %v", err)
2388	}
2389
2390	exp = map[string]interface{}{
2391		"secret": map[string]interface{}{
2392			"secret/": map[string]interface{}{
2393				"type":        "kv",
2394				"description": "key/value secret storage",
2395				"options":     map[string]string{"version": "1"},
2396			},
2397		},
2398		"auth": map[string]interface{}{
2399			"token/": map[string]interface{}{
2400				"type":        "token",
2401				"description": "token based credentials",
2402				"options":     map[string]string(nil),
2403			},
2404		},
2405	}
2406	if !reflect.DeepEqual(resp.Data, exp) {
2407		t.Fatalf("got: %#v expect: %#v", resp.Data, exp)
2408	}
2409}
2410
2411func TestSystemBackend_InternalUIMount(t *testing.T) {
2412	core, b, rootToken := testCoreSystemBackend(t)
2413
2414	req := logical.TestRequest(t, logical.UpdateOperation, "policy/secret")
2415	req.ClientToken = rootToken
2416	req.Data = map[string]interface{}{
2417		"rules": `path "secret/foo/*" {
2418    capabilities = ["create", "read", "update", "delete", "list"]
2419}`,
2420	}
2421	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2422	if err != nil || (resp != nil && resp.IsError()) {
2423		t.Fatalf("Bad %#v %#v", err, resp)
2424	}
2425
2426	req = logical.TestRequest(t, logical.UpdateOperation, "mounts/kv")
2427	req.ClientToken = rootToken
2428	req.Data = map[string]interface{}{
2429		"type": "kv",
2430	}
2431	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2432	if err != nil || (resp != nil && resp.IsError()) {
2433		t.Fatalf("Bad %#v %#v", err, resp)
2434	}
2435
2436	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv/bar")
2437	req.ClientToken = rootToken
2438	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2439	if err != nil || (resp != nil && resp.IsError()) {
2440		t.Fatalf("Bad %#v %#v", err, resp)
2441	}
2442	if resp.Data["type"] != "kv" {
2443		t.Fatalf("Bad Response: %#v", resp)
2444	}
2445
2446	testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"secret"})
2447
2448	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv")
2449	req.ClientToken = "tokenid"
2450	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2451	if err != logical.ErrPermissionDenied {
2452		t.Fatal("expected permission denied error")
2453	}
2454
2455	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/secret")
2456	req.ClientToken = "tokenid"
2457	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2458	if err != nil || (resp != nil && resp.IsError()) {
2459		t.Fatalf("Bad %#v %#v", err, resp)
2460	}
2461	if resp.Data["type"] != "kv" {
2462		t.Fatalf("Bad Response: %#v", resp)
2463	}
2464
2465	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/sys")
2466	req.ClientToken = "tokenid"
2467	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2468	if err != nil || (resp != nil && resp.IsError()) {
2469		t.Fatalf("Bad %#v %#v", err, resp)
2470	}
2471	if resp.Data["type"] != "system" {
2472		t.Fatalf("Bad Response: %#v", resp)
2473	}
2474
2475	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/non-existent")
2476	req.ClientToken = "tokenid"
2477	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2478	if err != logical.ErrPermissionDenied {
2479		t.Fatal("expected permission denied error")
2480	}
2481}
2482
2483func TestSystemBackend_OpenAPI(t *testing.T) {
2484	_, b, rootToken := testCoreSystemBackend(t)
2485	var oapi map[string]interface{}
2486
2487	// Ensure no paths are reported if there is no token
2488	req := logical.TestRequest(t, logical.ReadOperation, "internal/specs/openapi")
2489	resp, err := b.HandleRequest(namespace.RootContext(nil), req)
2490	if err != nil {
2491		t.Fatalf("err: %v", err)
2492	}
2493
2494	body := resp.Data["http_raw_body"].([]byte)
2495	err = jsonutil.DecodeJSON(body, &oapi)
2496	if err != nil {
2497		t.Fatalf("err: %v", err)
2498	}
2499	exp := map[string]interface{}{
2500		"openapi": framework.OASVersion,
2501		"info": map[string]interface{}{
2502			"title":       "HashiCorp Vault API",
2503			"description": "HTTP API that gives you full access to Vault. All API routes are prefixed with `/v1/`.",
2504			"version":     version.GetVersion().Version,
2505			"license": map[string]interface{}{
2506				"name": "Mozilla Public License 2.0",
2507				"url":  "https://www.mozilla.org/en-US/MPL/2.0",
2508			},
2509		},
2510		"paths": map[string]interface{}{},
2511	}
2512
2513	if diff := deep.Equal(oapi, exp); diff != nil {
2514		t.Fatal(diff)
2515	}
2516
2517	// Check that default paths are present with a root token
2518	req = logical.TestRequest(t, logical.ReadOperation, "internal/specs/openapi")
2519	req.ClientToken = rootToken
2520	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2521	if err != nil {
2522		t.Fatalf("err: %v", err)
2523	}
2524
2525	body = resp.Data["http_raw_body"].([]byte)
2526	err = jsonutil.DecodeJSON(body, &oapi)
2527	if err != nil {
2528		t.Fatalf("err: %v", err)
2529	}
2530
2531	doc, err := framework.NewOASDocumentFromMap(oapi)
2532	if err != nil {
2533		t.Fatal(err)
2534	}
2535
2536	pathSamples := []struct {
2537		path string
2538		tag  string
2539	}{
2540		{"/auth/token/lookup", "auth"},
2541		{"/cubbyhole/{path}", "secrets"},
2542		{"/identity/group/id", "identity"},
2543		{"/secret/.*", "secrets"}, // TODO update after kv repo update
2544		{"/sys/policy", "system"},
2545	}
2546
2547	for _, path := range pathSamples {
2548		if doc.Paths[path.path] == nil {
2549			t.Fatalf("didn't find expected path '%s'.", path)
2550		}
2551		tag := doc.Paths[path.path].Get.Tags[0]
2552		if tag != path.tag {
2553			t.Fatalf("path: %s; expected tag: %s, actual: %s", path.path, tag, path.tag)
2554		}
2555	}
2556
2557	// Simple sanity check of response size (which is much larger than most
2558	// Vault responses), mainly to catch mass omission of expected path data.
2559	minLen := 70000
2560	if len(body) < minLen {
2561		t.Fatalf("response size too small; expected: min %d, actual: %d", minLen, len(body))
2562	}
2563
2564	// Test path-help response
2565	req = logical.TestRequest(t, logical.HelpOperation, "rotate")
2566	req.ClientToken = rootToken
2567	resp, err = b.HandleRequest(namespace.RootContext(nil), req)
2568	if err != nil {
2569		t.Fatalf("err: %v", err)
2570	}
2571
2572	doc = resp.Data["openapi"].(*framework.OASDocument)
2573	if len(doc.Paths) != 1 {
2574		t.Fatalf("expected 1 path, actual: %d", len(doc.Paths))
2575	}
2576
2577	if doc.Paths["/rotate"] == nil {
2578		t.Fatalf("expected to find path '/rotate'")
2579	}
2580}
2581
2582func TestSystemBackend_PathWildcardPreflight(t *testing.T) {
2583	core, b, _ := testCoreSystemBackend(t)
2584
2585	ctx := namespace.RootContext(nil)
2586
2587	// Add another mount
2588	me := &MountEntry{
2589		Table:   mountTableType,
2590		Path:    sanitizeMountPath("kv-v1"),
2591		Type:    "kv",
2592		Options: map[string]string{"version": "1"},
2593	}
2594	if err := core.mount(ctx, me); err != nil {
2595		t.Fatal(err)
2596	}
2597
2598	// Create the policy, designed to fail
2599	rules := `path "foo" { capabilities = ["read"] }`
2600	req := logical.TestRequest(t, logical.UpdateOperation, "policy/foo")
2601	req.Data["rules"] = rules
2602	resp, err := b.HandleRequest(ctx, req)
2603	if err != nil {
2604		t.Fatalf("err: %v %#v", err, resp)
2605	}
2606	if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
2607		t.Fatalf("bad: %#v", resp)
2608	}
2609
2610	if err := core.identityStore.upsertEntity(ctx, &identity.Entity{
2611		ID:        "abcd",
2612		Name:      "abcd",
2613		BucketKey: "abcd",
2614	}, nil, false); err != nil {
2615		t.Fatal(err)
2616	}
2617
2618	te := &logical.TokenEntry{
2619		TTL:         300 * time.Second,
2620		EntityID:    "abcd",
2621		Policies:    []string{"default", "foo"},
2622		NamespaceID: namespace.RootNamespaceID,
2623	}
2624	if err := core.tokenStore.create(ctx, te); err != nil {
2625		t.Fatal(err)
2626	}
2627	t.Logf("token id: %s", te.ID)
2628
2629	if err := core.expiration.RegisterAuth(ctx, te, &logical.Auth{
2630		LeaseOptions: logical.LeaseOptions{
2631			TTL: te.TTL,
2632		},
2633		ClientToken: te.ID,
2634		Accessor:    te.Accessor,
2635		Orphan:      true,
2636	}); err != nil {
2637		t.Fatal(err)
2638	}
2639
2640	// Check the mount access func
2641	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv-v1/baz")
2642	req.ClientToken = te.ID
2643	resp, err = b.HandleRequest(ctx, req)
2644	if err == nil || !strings.Contains(err.Error(), "permission denied") {
2645		t.Fatalf("expected 403, got err: %v", err)
2646	}
2647
2648	// Modify policy to pass
2649	rules = `path "kv-v1/+" { capabilities = ["read"] }`
2650	req = logical.TestRequest(t, logical.UpdateOperation, "policy/foo")
2651	req.Data["rules"] = rules
2652	resp, err = b.HandleRequest(ctx, req)
2653	if err != nil {
2654		t.Fatalf("err: %v %#v", err, resp)
2655	}
2656	if resp != nil && (resp.IsError() || len(resp.Data) > 0) {
2657		t.Fatalf("bad: %#v", resp)
2658	}
2659
2660	// Check the mount access func again
2661	req = logical.TestRequest(t, logical.ReadOperation, "internal/ui/mounts/kv-v1/baz")
2662	req.ClientToken = te.ID
2663	resp, err = b.HandleRequest(ctx, req)
2664	if err != nil {
2665		t.Fatalf("err: %v", err)
2666	}
2667}
2668