144 lines
4.4 KiB
Go
144 lines
4.4 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
package vault
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/vault/command/server"
|
|
"github.com/hashicorp/vault/helper/namespace"
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
)
|
|
|
|
func TestInspectRouter(t *testing.T) {
|
|
// Verify that all the expected tables exist when we inspect the router
|
|
coreConfig := &CoreConfig{
|
|
EnableIntrospection: true,
|
|
}
|
|
c, _, root := TestCoreUnsealedWithConfig(t, coreConfig)
|
|
|
|
rootCtx := namespace.RootContext(nil)
|
|
subTrees := map[string][]string{
|
|
"routeEntry": {"root", "storage"},
|
|
"mountEntry": {"uuid", "accessor"},
|
|
}
|
|
subTreeFields := map[string][]string{
|
|
"routeEntry": {"tainted", "storage_prefix", "accessor", "mount_namespace", "mount_path", "mount_type", "uuid"},
|
|
"mountEntry": {"accessor", "mount_namespace", "mount_path", "mount_type", "uuid"},
|
|
}
|
|
for subTreeType, subTreeArray := range subTrees {
|
|
for _, tag := range subTreeArray {
|
|
resp, err := c.HandleRequest(rootCtx, &logical.Request{
|
|
ClientToken: root,
|
|
Operation: logical.ReadOperation,
|
|
Path: "sys/internal/inspect/router/" + tag,
|
|
})
|
|
if err != nil || (resp != nil && resp.IsError()) {
|
|
t.Fatalf("bad: resp: %#v\n err: %v", resp, err)
|
|
}
|
|
// Verify that data exists
|
|
data, ok := resp.Data[tag].([]map[string]interface{})
|
|
if !ok {
|
|
t.Fatalf("Router data is malformed")
|
|
}
|
|
for _, entry := range data {
|
|
for _, field := range subTreeFields[subTreeType] {
|
|
if _, ok := entry[field]; !ok {
|
|
t.Fatalf("Field %s not found in %s", field, tag)
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestInvalidInspectRouterPath(t *testing.T) {
|
|
// Verify that attempting to inspect an invalid tree in the router fails
|
|
coreConfig := &CoreConfig{
|
|
EnableIntrospection: true,
|
|
}
|
|
core, _, rootToken := TestCoreUnsealedWithConfig(t, coreConfig)
|
|
rootCtx := namespace.RootContext(nil)
|
|
_, err := core.HandleRequest(rootCtx, &logical.Request{
|
|
ClientToken: rootToken,
|
|
Operation: logical.ReadOperation,
|
|
Path: "sys/internal/inspect/router/random",
|
|
})
|
|
if !strings.Contains(err.Error(), logical.ErrUnsupportedPath.Error()) {
|
|
t.Fatal("expected unsupported path error")
|
|
}
|
|
}
|
|
|
|
func TestInspectAPIDisabled(t *testing.T) {
|
|
// Verify that the Inspect API is turned off by default
|
|
core, _, rootToken := testCoreSystemBackend(t)
|
|
rootCtx := namespace.RootContext(nil)
|
|
resp, err := core.HandleRequest(rootCtx, &logical.Request{
|
|
ClientToken: rootToken,
|
|
Operation: logical.ReadOperation,
|
|
Path: "sys/internal/inspect/router/root",
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !resp.IsError() || !strings.Contains(resp.Error().Error(), ErrIntrospectionNotEnabled.Error()) {
|
|
t.Fatal("expected invalid configuration error")
|
|
}
|
|
}
|
|
|
|
func TestInspectAPISudoProtect(t *testing.T) {
|
|
// Verify that the Inspect API path is sudo protected
|
|
core, _, rootToken := testCoreSystemBackend(t)
|
|
testMakeServiceTokenViaBackend(t, core.tokenStore, rootToken, "tokenid", "", []string{"secret"})
|
|
rootCtx := namespace.RootContext(nil)
|
|
_, err := core.HandleRequest(rootCtx, &logical.Request{
|
|
ClientToken: "tokenid",
|
|
Operation: logical.ReadOperation,
|
|
Path: "sys/internal/inspect/router/root",
|
|
})
|
|
if !strings.Contains(err.Error(), logical.ErrPermissionDenied.Error()) {
|
|
t.Fatal("expected permission denied error")
|
|
}
|
|
}
|
|
|
|
func TestInspectAPIReload(t *testing.T) {
|
|
// Verify that the Inspect API is turned off by default
|
|
core, _, rootToken := testCoreSystemBackend(t)
|
|
rootCtx := namespace.RootContext(nil)
|
|
resp, err := core.HandleRequest(rootCtx, &logical.Request{
|
|
ClientToken: rootToken,
|
|
Operation: logical.ReadOperation,
|
|
Path: "sys/internal/inspect/router/root",
|
|
})
|
|
if err != nil {
|
|
t.Fatal("Unexpected error")
|
|
}
|
|
if !resp.IsError() {
|
|
t.Fatal("expected invalid configuration error")
|
|
}
|
|
if !strings.Contains(resp.Error().Error(), ErrIntrospectionNotEnabled.Error()) {
|
|
t.Fatalf("expected invalid configuration error but recieved: %s", resp.Error())
|
|
}
|
|
|
|
originalConfig := core.rawConfig.Load().(*server.Config)
|
|
newConfig := originalConfig
|
|
newConfig.EnableIntrospectionEndpointRaw = true
|
|
newConfig.EnableIntrospectionEndpoint = true
|
|
|
|
// Reload Endpoint
|
|
core.SetConfig(newConfig)
|
|
core.ReloadIntrospectionEndpointEnabled()
|
|
|
|
resp, err = core.HandleRequest(rootCtx, &logical.Request{
|
|
ClientToken: rootToken,
|
|
Operation: logical.ReadOperation,
|
|
Path: "sys/internal/inspect/router/root",
|
|
})
|
|
if err != nil || resp.IsError() {
|
|
t.Fatal("Unexpected error after reload")
|
|
}
|
|
}
|