From 82dcd8d07671999dbb849e94f1f0bde0e2172e0a Mon Sep 17 00:00:00 2001 From: Jeff Mitchell Date: Mon, 13 Nov 2017 11:22:22 -0500 Subject: [PATCH] Plumb more seal wrap stuff through and move to outside layer of mount options (#3572) --- api/sys_mounts.go | 4 +- http/handler_test.go | 32 ++--- http/sys_auth_test.go | 20 +++- http/sys_mount_test.go | 224 +++++++++++++++++------------------ vault/logical_system.go | 29 +++-- vault/logical_system_test.go | 140 ++++++++++++++++++++-- vault/mount.go | 3 +- 7 files changed, 298 insertions(+), 154 deletions(-) diff --git a/api/sys_mounts.go b/api/sys_mounts.go index 4a85917294..ab3ab752ee 100644 --- a/api/sys_mounts.go +++ b/api/sys_mounts.go @@ -125,6 +125,7 @@ type MountInput struct { Config MountConfigInput `json:"config" structs:"config"` Local bool `json:"local" structs:"local"` PluginName string `json:"plugin_name,omitempty" structs:"plugin_name"` + SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"` } type MountConfigInput struct { @@ -132,7 +133,6 @@ type MountConfigInput struct { MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"` PluginName string `json:"plugin_name,omitempty" structs:"plugin_name,omitempty" mapstructure:"plugin_name"` - SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"` } type MountOutput struct { @@ -141,6 +141,7 @@ type MountOutput struct { Accessor string `json:"accessor" structs:"accessor"` Config MountConfigOutput `json:"config" structs:"config"` Local bool `json:"local" structs:"local"` + SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"` } type MountConfigOutput struct { @@ -148,5 +149,4 @@ type MountConfigOutput struct { MaxLeaseTTL int `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"` PluginName string `json:"plugin_name,omitempty" structs:"plugin_name,omitempty" mapstructure:"plugin_name"` - SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"` } diff --git a/http/handler_test.go b/http/handler_test.go index e5908d88fc..d16581b8e0 100644 --- a/http/handler_test.go +++ b/http/handler_test.go @@ -164,9 +164,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -176,9 +176,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -188,9 +188,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -200,9 +200,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "secret/": map[string]interface{}{ @@ -213,9 +213,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -225,9 +225,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -237,9 +237,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -249,9 +249,9 @@ func TestSysMounts_headerAuth(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) diff --git a/http/sys_auth_test.go b/http/sys_auth_test.go index fa3c692b3d..58e70963a7 100644 --- a/http/sys_auth_test.go +++ b/http/sys_auth_test.go @@ -32,7 +32,8 @@ func TestSysAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "token/": map[string]interface{}{ @@ -42,7 +43,8 @@ func TestSysAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) @@ -92,7 +94,8 @@ func TestSysEnableAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": false, + "seal_wrap": false, }, "token/": map[string]interface{}{ "description": "token based credentials", @@ -101,7 +104,8 @@ func TestSysEnableAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "foo/": map[string]interface{}{ @@ -111,7 +115,8 @@ func TestSysEnableAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": false, + "seal_wrap": false, }, "token/": map[string]interface{}{ "description": "token based credentials", @@ -120,7 +125,8 @@ func TestSysEnableAuth(t *testing.T) { "default_lease_ttl": json.Number("0"), "max_lease_ttl": json.Number("0"), }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) @@ -174,6 +180,7 @@ func TestSysDisableAuth(t *testing.T) { "description": "token based credentials", "type": "token", "local": false, + "seal_wrap": false, }, }, "token/": map[string]interface{}{ @@ -184,6 +191,7 @@ func TestSysDisableAuth(t *testing.T) { "description": "token based credentials", "type": "token", "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) diff --git a/http/sys_mount_test.go b/http/sys_mount_test.go index 96094d0b29..75f2981b0a 100644 --- a/http/sys_mount_test.go +++ b/http/sys_mount_test.go @@ -34,9 +34,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -46,9 +46,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -58,9 +58,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -70,9 +70,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "secret/": map[string]interface{}{ @@ -83,9 +83,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -95,9 +95,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -107,9 +107,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -119,9 +119,9 @@ func TestSysMounts(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) @@ -171,9 +171,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -183,9 +183,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -195,9 +195,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -207,9 +207,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -219,9 +219,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "foo/": map[string]interface{}{ @@ -232,9 +232,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -244,9 +244,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -256,9 +256,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -268,9 +268,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -280,9 +280,9 @@ func TestSysMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) @@ -354,9 +354,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -366,9 +366,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -378,9 +378,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -390,9 +390,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -402,9 +402,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "bar/": map[string]interface{}{ @@ -415,9 +415,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -427,9 +427,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -439,9 +439,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -451,9 +451,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -463,9 +463,9 @@ func TestSysRemount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) @@ -518,9 +518,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -530,9 +530,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -542,9 +542,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -554,9 +554,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "secret/": map[string]interface{}{ @@ -567,9 +567,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -579,9 +579,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -591,9 +591,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -603,9 +603,9 @@ func TestSysUnmount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) @@ -655,9 +655,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -667,9 +667,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -679,9 +679,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -691,9 +691,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -703,9 +703,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "foo/": map[string]interface{}{ @@ -716,9 +716,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -728,9 +728,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -740,9 +740,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -752,9 +752,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -764,9 +764,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } testResponseStatus(t, resp, 200) @@ -837,9 +837,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("259200000"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -849,9 +849,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -861,9 +861,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -873,9 +873,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -885,9 +885,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, }, "foo/": map[string]interface{}{ @@ -898,9 +898,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("259200000"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "secret/": map[string]interface{}{ "description": "key/value secret storage", @@ -910,9 +910,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "description": "system endpoints used for control, policy and debugging", @@ -922,9 +922,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -934,9 +934,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -946,9 +946,9 @@ func TestSysTuneMount(t *testing.T) { "max_lease_ttl": json.Number("0"), "force_no_cache": false, "plugin_name": "", - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } diff --git a/vault/logical_system.go b/vault/logical_system.go index 3638e5cdce..96884bfe6d 100644 --- a/vault/logical_system.go +++ b/vault/logical_system.go @@ -308,6 +308,11 @@ func NewSystemBackend(core *Core) *SystemBackend { Default: false, Description: strings.TrimSpace(sysHelp["mount_local"][0]), }, + "seal_wrap": &framework.FieldSchema{ + Type: framework.TypeBool, + Default: false, + Description: strings.TrimSpace(sysHelp["seal_wrap"][0]), + }, "plugin_name": &framework.FieldSchema{ Type: framework.TypeString, Description: strings.TrimSpace(sysHelp["mount_plugin_name"][0]), @@ -523,6 +528,11 @@ func NewSystemBackend(core *Core) *SystemBackend { Default: false, Description: strings.TrimSpace(sysHelp["mount_local"][0]), }, + "seal_wrap": &framework.FieldSchema{ + Type: framework.TypeBool, + Default: false, + Description: strings.TrimSpace(sysHelp["seal_wrap"][0]), + }, "plugin_name": &framework.FieldSchema{ Type: framework.TypeString, Description: strings.TrimSpace(sysHelp["auth_plugin"][0]), @@ -1363,9 +1373,9 @@ func (b *SystemBackend) handleMountTable( "max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()), "force_no_cache": entry.Config.ForceNoCache, "plugin_name": entry.Config.PluginName, - "seal_wrap": entry.Config.SealWrap, }, - "local": entry.Local, + "local": entry.Local, + "seal_wrap": entry.SealWrap, } resp.Data[entry.Path] = info } @@ -1388,6 +1398,7 @@ func (b *SystemBackend) handleMount( logicalType := data.Get("type").(string) description := data.Get("description").(string) pluginName := data.Get("plugin_name").(string) + sealWrap := data.Get("seal_wrap").(bool) path = sanitizeMountPath(path) @@ -1463,10 +1474,6 @@ func (b *SystemBackend) handleMount( } } - if apiConfig.SealWrap { - config.SealWrap = true - } - // Copy over the force no cache if set if apiConfig.ForceNoCache { config.ForceNoCache = true @@ -1480,6 +1487,7 @@ func (b *SystemBackend) handleMount( Description: description, Config: config, Local: local, + SealWrap: sealWrap, } // Attempt mount @@ -1904,7 +1912,8 @@ func (b *SystemBackend) handleAuthTable( "default_lease_ttl": int64(entry.Config.DefaultLeaseTTL.Seconds()), "max_lease_ttl": int64(entry.Config.MaxLeaseTTL.Seconds()), }, - "local": entry.Local, + "local": entry.Local, + "seal_wrap": entry.SealWrap, } resp.Data[entry.Path] = info } @@ -1925,6 +1934,7 @@ func (b *SystemBackend) handleEnableAuth( logicalType := data.Get("type").(string) description := data.Get("description").(string) pluginName := data.Get("plugin_name").(string) + sealWrap := data.Get("seal_wrap").(bool) var config MountConfig var apiConfig APIMountConfig @@ -1970,6 +1980,7 @@ func (b *SystemBackend) handleEnableAuth( Description: description, Config: config, Local: local, + SealWrap: sealWrap, } // Attempt enabling @@ -2964,6 +2975,10 @@ and is unaffected by replication.`, in the plugin catalog.`, }, + "seal_wrap": { + `Whether to turn on seal wrapping for the mount.`, + }, + "tune_default_lease_ttl": { `The default lease TTL for this mount.`, }, diff --git a/vault/logical_system_test.go b/vault/logical_system_test.go index d03dcf300e..5d643280ad 100644 --- a/vault/logical_system_test.go +++ b/vault/logical_system_test.go @@ -126,9 +126,9 @@ func TestSystemBackend_mounts(t *testing.T) { "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), "plugin_name": "", "force_no_cache": false, - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "sys/": map[string]interface{}{ "type": "system", @@ -139,9 +139,9 @@ func TestSystemBackend_mounts(t *testing.T) { "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), "plugin_name": "", "force_no_cache": false, - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, "cubbyhole/": map[string]interface{}{ "description": "per-token private secret storage", @@ -152,9 +152,9 @@ func TestSystemBackend_mounts(t *testing.T) { "max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), "plugin_name": "", "force_no_cache": false, - "seal_wrap": false, }, - "local": true, + "local": true, + "seal_wrap": false, }, "identity/": map[string]interface{}{ "description": "identity store", @@ -165,9 +165,9 @@ func TestSystemBackend_mounts(t *testing.T) { "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), "plugin_name": "", "force_no_cache": false, - "seal_wrap": false, }, - "local": false, + "local": false, + "seal_wrap": false, }, } if !reflect.DeepEqual(resp.Data, exp) { @@ -180,6 +180,8 @@ func TestSystemBackend_mount(t *testing.T) { req := logical.TestRequest(t, logical.UpdateOperation, "mounts/prod/secret/") req.Data["type"] = "kv" + req.Data["local"] = true + req.Data["seal_wrap"] = true resp, err := b.HandleRequest(req) if err != nil { @@ -188,6 +190,86 @@ func TestSystemBackend_mount(t *testing.T) { if resp != nil { t.Fatalf("bad: %v", resp) } + + req = logical.TestRequest(t, logical.ReadOperation, "mounts") + resp, err = b.HandleRequest(req) + if err != nil { + t.Fatalf("err: %v", err) + } + + // We can't know the pointer address ahead of time so simply + // copy what's given + exp := map[string]interface{}{ + "secret/": map[string]interface{}{ + "type": "kv", + "description": "key/value secret storage", + "accessor": resp.Data["secret/"].(map[string]interface{})["accessor"], + "config": map[string]interface{}{ + "default_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), + "max_lease_ttl": resp.Data["secret/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), + "plugin_name": "", + "force_no_cache": false, + }, + "local": false, + "seal_wrap": false, + }, + "sys/": map[string]interface{}{ + "type": "system", + "description": "system endpoints used for control, policy and debugging", + "accessor": resp.Data["sys/"].(map[string]interface{})["accessor"], + "config": map[string]interface{}{ + "default_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), + "max_lease_ttl": resp.Data["sys/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), + "plugin_name": "", + "force_no_cache": false, + }, + "local": false, + "seal_wrap": false, + }, + "cubbyhole/": map[string]interface{}{ + "description": "per-token private secret storage", + "type": "cubbyhole", + "accessor": resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], + "config": map[string]interface{}{ + "default_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), + "max_lease_ttl": resp.Data["cubbyhole/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), + "plugin_name": "", + "force_no_cache": false, + }, + "local": true, + "seal_wrap": false, + }, + "identity/": map[string]interface{}{ + "description": "identity store", + "type": "identity", + "accessor": resp.Data["identity/"].(map[string]interface{})["accessor"], + "config": map[string]interface{}{ + "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), + "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), + "plugin_name": "", + "force_no_cache": false, + }, + "local": false, + "seal_wrap": false, + }, + "prod/secret/": map[string]interface{}{ + "description": "", + "type": "kv", + "accessor": resp.Data["prod/secret/"].(map[string]interface{})["accessor"], + "config": map[string]interface{}{ + "default_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["default_lease_ttl"].(int64), + "max_lease_ttl": resp.Data["identity/"].(map[string]interface{})["config"].(map[string]interface{})["max_lease_ttl"].(int64), + "plugin_name": "", + "force_no_cache": false, + }, + "local": true, + "seal_wrap": true, + }, + } + if !reflect.DeepEqual(resp.Data, exp) { + t.Fatalf("bad: got\n%#v\nexpected\n%#v\n", resp.Data, exp) + } + } func TestSystemBackend_mount_force_no_cache(t *testing.T) { @@ -1145,7 +1227,8 @@ func TestSystemBackend_authTable(t *testing.T) { "default_lease_ttl": int64(0), "max_lease_ttl": int64(0), }, - "local": false, + "local": false, + "seal_wrap": false, }, } if !reflect.DeepEqual(resp.Data, exp) { @@ -1161,6 +1244,8 @@ func TestSystemBackend_enableAuth(t *testing.T) { req := logical.TestRequest(t, logical.UpdateOperation, "auth/foo") req.Data["type"] = "noop" + req.Data["local"] = true + req.Data["seal_wrap"] = true resp, err := b.HandleRequest(req) if err != nil { @@ -1169,6 +1254,43 @@ func TestSystemBackend_enableAuth(t *testing.T) { if resp != nil { t.Fatalf("bad: %v", resp) } + + req = logical.TestRequest(t, logical.ReadOperation, "auth") + resp, err = b.HandleRequest(req) + if err != nil { + t.Fatalf("err: %v", err) + } + if resp == nil { + t.Fatal("resp is nil") + } + + exp := map[string]interface{}{ + "foo/": map[string]interface{}{ + "type": "noop", + "description": "", + "accessor": resp.Data["foo/"].(map[string]interface{})["accessor"], + "config": map[string]interface{}{ + "default_lease_ttl": int64(0), + "max_lease_ttl": int64(0), + }, + "local": true, + "seal_wrap": true, + }, + "token/": map[string]interface{}{ + "type": "token", + "description": "token based credentials", + "accessor": resp.Data["token/"].(map[string]interface{})["accessor"], + "config": map[string]interface{}{ + "default_lease_ttl": int64(0), + "max_lease_ttl": int64(0), + }, + "local": false, + "seal_wrap": false, + }, + } + if !reflect.DeepEqual(resp.Data, exp) { + t.Fatalf("got: %#v expect: %#v", resp.Data, exp) + } } func TestSystemBackend_enableAuth_invalid(t *testing.T) { diff --git a/vault/mount.go b/vault/mount.go index 484c3595b4..b45a1afe44 100644 --- a/vault/mount.go +++ b/vault/mount.go @@ -181,6 +181,7 @@ type MountEntry struct { Config MountConfig `json:"config"` // Configuration related to this mount (but not backend-derived) Options map[string]string `json:"options"` // Backend options Local bool `json:"local"` // Local mounts are not replicated or affected by replication + SealWrap bool `json:"seal_wrap"` // Whether to wrap CSPs Tainted bool `json:"tainted,omitempty"` // Set as a Write-Ahead flag for unmount/remount } @@ -190,7 +191,6 @@ type MountConfig struct { MaxLeaseTTL time.Duration `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` // Override for global default ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"` // Override for global default PluginName string `json:"plugin_name,omitempty" structs:"plugin_name,omitempty" mapstructure:"plugin_name"` - SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"` } // APIMountConfig is an embedded struct of api.MountConfigInput @@ -199,7 +199,6 @@ type APIMountConfig struct { MaxLeaseTTL string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"` ForceNoCache bool `json:"force_no_cache" structs:"force_no_cache" mapstructure:"force_no_cache"` PluginName string `json:"plugin_name,omitempty" structs:"plugin_name,omitempty" mapstructure:"plugin_name"` - SealWrap bool `json:"seal_wrap" structs:"seal_wrap" mapstructure:"seal_wrap"` } // Clone returns a deep copy of the mount entry