2015-03-15 21:42:05 +00:00
package vault
import (
2018-01-08 18:31:38 +00:00
"context"
2015-11-19 01:26:03 +00:00
"crypto/sha256"
2017-10-20 14:59:17 +00:00
"encoding/base64"
2017-04-12 17:39:18 +00:00
"encoding/hex"
"fmt"
"io/ioutil"
"os"
"path/filepath"
2015-03-15 21:42:05 +00:00
"reflect"
2016-04-19 20:26:26 +00:00
"strings"
2015-03-15 21:42:05 +00:00
"testing"
2015-08-31 18:27:49 +00:00
"time"
2015-03-15 21:42:05 +00:00
2015-09-01 22:29:30 +00:00
"github.com/fatih/structs"
2018-10-15 16:56:24 +00:00
"github.com/go-test/deep"
2018-04-03 00:46:59 +00:00
hclog "github.com/hashicorp/go-hclog"
2015-03-31 23:45:00 +00:00
"github.com/hashicorp/vault/audit"
2017-04-12 17:39:18 +00:00
"github.com/hashicorp/vault/helper/builtinplugins"
2019-04-10 21:46:17 +00:00
"github.com/hashicorp/vault/helper/identity"
2018-09-18 03:03:00 +00:00
"github.com/hashicorp/vault/helper/namespace"
2019-04-13 07:44:06 +00:00
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/helper/consts"
"github.com/hashicorp/vault/sdk/helper/jsonutil"
2019-04-12 21:54:35 +00:00
"github.com/hashicorp/vault/sdk/helper/salt"
"github.com/hashicorp/vault/sdk/logical"
"github.com/hashicorp/vault/sdk/version"
2017-05-04 02:03:42 +00:00
"github.com/mitchellh/mapstructure"
2015-03-15 21:42:05 +00:00
)
func TestSystemBackend_RootPaths ( t * testing . T ) {
expected := [ ] string {
2015-03-20 19:48:19 +00:00
"auth/*" ,
2015-03-15 21:42:05 +00:00
"remount" ,
2015-03-31 23:45:00 +00:00
"audit" ,
"audit/*" ,
2017-09-15 04:21:35 +00:00
"raw" ,
2015-04-02 00:44:43 +00:00
"raw/*" ,
2017-02-17 04:36:06 +00:00
"replication/primary/secondary-token" ,
2018-09-18 03:03:00 +00:00
"replication/performance/primary/secondary-token" ,
"replication/dr/primary/secondary-token" ,
2017-02-17 04:36:06 +00:00
"replication/reindex" ,
2018-09-18 03:03:00 +00:00
"replication/dr/reindex" ,
"replication/performance/reindex" ,
2015-05-28 00:53:42 +00:00
"rotate" ,
2017-06-17 05:51:42 +00:00
"config/cors" ,
2017-02-02 19:49:20 +00:00
"config/auditing/*" ,
2018-04-03 18:07:43 +00:00
"config/ui/headers/*" ,
2017-04-24 19:47:40 +00:00
"plugins/catalog/*" ,
2017-05-04 02:03:42 +00:00
"revoke-prefix/*" ,
2017-07-25 15:59:43 +00:00
"revoke-force/*" ,
2017-05-04 02:03:42 +00:00
"leases/revoke-prefix/*" ,
"leases/revoke-force/*" ,
"leases/lookup/*" ,
2015-03-15 21:42:05 +00:00
}
b := testSystemBackend ( t )
2015-03-31 00:46:18 +00:00
actual := b . SpecialPaths ( ) . Root
2015-03-15 21:42:05 +00:00
if ! reflect . DeepEqual ( actual , expected ) {
2018-04-03 18:07:43 +00:00
t . Fatalf ( "bad: mismatch\nexpected:\n%#v\ngot:\n%#v" , expected , actual )
2015-03-15 21:42:05 +00:00
}
}
2017-06-17 04:04:55 +00:00
func TestSystemConfigCORS ( t * testing . T ) {
b := testSystemBackend ( t )
2017-06-17 05:26:25 +00:00
_ , barrier , _ := mockBarrier ( t )
view := NewBarrierView ( barrier , "" )
b . ( * SystemBackend ) . Core . systemBarrierView = view
2017-06-17 04:04:55 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "config/cors" )
req . Data [ "allowed_origins" ] = "http://www.example.com"
2017-08-07 14:03:30 +00:00
req . Data [ "allowed_headers" ] = "X-Custom-Header"
2018-11-05 16:11:32 +00:00
_ , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-06-17 04:04:55 +00:00
if err != nil {
t . Fatal ( err )
}
expected := & logical . Response {
Data : map [ string ] interface { } {
"enabled" : true ,
2017-06-17 05:26:25 +00:00
"allowed_origins" : [ ] string { "http://www.example.com" } ,
2017-08-07 19:02:08 +00:00
"allowed_headers" : append ( StdAllowedHeaders , "X-Custom-Header" ) ,
2017-06-17 04:04:55 +00:00
} ,
}
req = logical . TestRequest ( t , logical . ReadOperation , "config/cors" )
2018-11-05 16:11:32 +00:00
actual , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-06-17 04:04:55 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( actual , expected ) {
2017-06-17 05:26:25 +00:00
t . Fatalf ( "bad: %#v" , actual )
2017-06-17 04:04:55 +00:00
}
2019-02-11 18:10:26 +00:00
// Do it again. Bug #6182
req = logical . TestRequest ( t , logical . UpdateOperation , "config/cors" )
req . Data [ "allowed_origins" ] = "http://www.example.com"
req . Data [ "allowed_headers" ] = "X-Custom-Header"
_ , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatal ( err )
}
req = logical . TestRequest ( t , logical . ReadOperation , "config/cors" )
actual , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "bad: %#v" , actual )
}
2017-06-17 04:04:55 +00:00
req = logical . TestRequest ( t , logical . DeleteOperation , "config/cors" )
2018-11-05 16:11:32 +00:00
_ , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-06-17 04:04:55 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
req = logical . TestRequest ( t , logical . ReadOperation , "config/cors" )
2018-11-05 16:11:32 +00:00
actual , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-06-17 04:04:55 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
expected = & logical . Response {
Data : map [ string ] interface { } {
2017-06-17 05:26:25 +00:00
"enabled" : false ,
2017-06-17 04:04:55 +00:00
} ,
}
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "DELETE FAILED -- bad: %#v" , actual )
}
}
2015-03-15 21:42:05 +00:00
func TestSystemBackend_mounts ( t * testing . T ) {
b := testSystemBackend ( t )
req := logical . TestRequest ( t , logical . ReadOperation , "mounts" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-15 21:42:05 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-09-01 22:29:30 +00:00
// We can't know the pointer address ahead of time so simply
// copy what's given
2015-03-15 21:42:05 +00:00
exp := map [ string ] interface { } {
2015-08-31 18:27:49 +00:00
"secret/" : map [ string ] interface { } {
2017-09-15 13:02:29 +00:00
"type" : "kv" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-09-15 13:02:29 +00:00
"description" : "key/value secret storage" ,
2017-06-26 17:14:36 +00:00
"accessor" : resp . Data [ "secret/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "secret/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2015-08-31 18:27:49 +00:00
"config" : map [ string ] interface { } {
2016-06-21 00:08:12 +00:00
"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 ) ,
2017-03-08 14:20:09 +00:00
"force_no_cache" : false ,
2015-08-31 18:27:49 +00:00
} ,
2017-11-13 16:22:22 +00:00
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string {
2018-04-09 20:14:44 +00:00
"version" : "1" ,
2018-03-21 19:04:27 +00:00
} ,
2015-03-15 21:42:05 +00:00
} ,
2015-08-31 18:27:49 +00:00
"sys/" : map [ string ] interface { } {
2015-03-15 21:42:05 +00:00
"type" : "system" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2015-03-15 21:42:05 +00:00
"description" : "system endpoints used for control, policy and debugging" ,
2017-06-26 17:14:36 +00:00
"accessor" : resp . Data [ "sys/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "sys/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2015-08-31 18:27:49 +00:00
"config" : map [ string ] interface { } {
2019-02-20 20:12:21 +00:00
"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 ) ,
"force_no_cache" : false ,
2019-02-15 19:14:45 +00:00
"passthrough_request_headers" : [ ] string { "Accept" } ,
2015-08-31 18:27:49 +00:00
} ,
2017-11-13 16:22:22 +00:00
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2015-03-15 21:42:05 +00:00
} ,
2015-09-10 01:58:09 +00:00
"cubbyhole/" : map [ string ] interface { } {
"description" : "per-token private secret storage" ,
"type" : "cubbyhole" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-06-26 17:14:36 +00:00
"accessor" : resp . Data [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2015-09-10 01:58:09 +00:00
"config" : map [ string ] interface { } {
2016-06-21 00:08:12 +00:00
"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 ) ,
2017-03-08 14:20:09 +00:00
"force_no_cache" : false ,
2015-09-10 01:58:09 +00:00
} ,
2017-11-13 16:22:22 +00:00
"local" : true ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2015-09-10 01:58:09 +00:00
} ,
2017-10-11 17:21:20 +00:00
"identity/" : map [ string ] interface { } {
"description" : "identity store" ,
"type" : "identity" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-10-11 17:21:20 +00:00
"accessor" : resp . Data [ "identity/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "identity/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-10-11 17:21:20 +00:00
"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 ) ,
"force_no_cache" : false ,
} ,
2017-11-13 16:22:22 +00:00
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2017-10-11 17:21:20 +00:00
} ,
2015-03-15 21:42:05 +00:00
}
2019-02-15 19:14:45 +00:00
if diff := deep . Equal ( resp . Data , exp ) ; len ( diff ) > 0 {
t . Fatalf ( "bad, diff: %#v" , diff )
2015-03-15 21:42:05 +00:00
}
}
func TestSystemBackend_mount ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "mounts/prod/secret/" )
2017-09-15 13:02:29 +00:00
req . Data [ "type" ] = "kv"
2018-02-22 15:26:29 +00:00
req . Data [ "config" ] = map [ string ] interface { } {
"default_lease_ttl" : "35m" ,
"max_lease_ttl" : "45m" ,
}
2017-11-13 16:22:22 +00:00
req . Data [ "local" ] = true
req . Data [ "seal_wrap" ] = true
2018-03-21 19:04:27 +00:00
req . Data [ "options" ] = map [ string ] string {
2018-04-09 20:14:44 +00:00
"version" : "1" ,
2018-03-21 19:04:27 +00:00
}
2015-03-15 21:42:05 +00:00
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-15 21:42:05 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
2017-11-13 16:22:22 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "mounts" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-11-13 16:22:22 +00:00
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" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-11-13 16:22:22 +00:00
"description" : "key/value secret storage" ,
"accessor" : resp . Data [ "secret/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "secret/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-11-13 16:22:22 +00:00
"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 ) ,
"force_no_cache" : false ,
} ,
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string {
2018-04-09 20:14:44 +00:00
"version" : "1" ,
2018-03-21 19:04:27 +00:00
} ,
2017-11-13 16:22:22 +00:00
} ,
"sys/" : map [ string ] interface { } {
"type" : "system" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-11-13 16:22:22 +00:00
"description" : "system endpoints used for control, policy and debugging" ,
"accessor" : resp . Data [ "sys/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "sys/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-11-13 16:22:22 +00:00
"config" : map [ string ] interface { } {
2019-02-20 20:12:21 +00:00
"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 ) ,
"force_no_cache" : false ,
2019-02-15 19:14:45 +00:00
"passthrough_request_headers" : [ ] string { "Accept" } ,
2017-11-13 16:22:22 +00:00
} ,
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2017-11-13 16:22:22 +00:00
} ,
"cubbyhole/" : map [ string ] interface { } {
"description" : "per-token private secret storage" ,
"type" : "cubbyhole" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-11-13 16:22:22 +00:00
"accessor" : resp . Data [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-11-13 16:22:22 +00:00
"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 ) ,
"force_no_cache" : false ,
} ,
"local" : true ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2017-11-13 16:22:22 +00:00
} ,
"identity/" : map [ string ] interface { } {
"description" : "identity store" ,
"type" : "identity" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-11-13 16:22:22 +00:00
"accessor" : resp . Data [ "identity/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "identity/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-11-13 16:22:22 +00:00
"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 ) ,
"force_no_cache" : false ,
} ,
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2017-11-13 16:22:22 +00:00
} ,
"prod/secret/" : map [ string ] interface { } {
"description" : "" ,
"type" : "kv" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-11-13 16:22:22 +00:00
"accessor" : resp . Data [ "prod/secret/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "prod/secret/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-11-13 16:22:22 +00:00
"config" : map [ string ] interface { } {
2018-02-22 15:26:29 +00:00
"default_lease_ttl" : int64 ( 2100 ) ,
"max_lease_ttl" : int64 ( 2700 ) ,
2017-11-13 16:22:22 +00:00
"force_no_cache" : false ,
} ,
"local" : true ,
"seal_wrap" : true ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string {
2018-04-09 20:14:44 +00:00
"version" : "1" ,
2018-03-21 19:04:27 +00:00
} ,
2017-11-13 16:22:22 +00:00
} ,
}
2019-02-15 19:14:45 +00:00
if diff := deep . Equal ( resp . Data , exp ) ; len ( diff ) > 0 {
t . Fatalf ( "bad: diff: %#v" , diff )
2017-11-13 16:22:22 +00:00
}
2015-03-15 21:42:05 +00:00
}
2017-03-08 14:20:09 +00:00
func TestSystemBackend_mount_force_no_cache ( t * testing . T ) {
core , b , _ := testCoreSystemBackend ( t )
req := logical . TestRequest ( t , logical . UpdateOperation , "mounts/prod/secret/" )
2017-09-15 13:02:29 +00:00
req . Data [ "type" ] = "kv"
2017-03-08 14:20:09 +00:00
req . Data [ "config" ] = map [ string ] interface { } {
"force_no_cache" : true ,
}
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-03-08 14:20:09 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
2018-11-05 16:11:32 +00:00
mountEntry := core . router . MatchingMountEntry ( namespace . RootContext ( nil ) , "prod/secret/" )
2017-03-08 14:20:09 +00:00
if mountEntry == nil {
t . Fatalf ( "missing mount entry" )
}
if ! mountEntry . Config . ForceNoCache {
t . Fatalf ( "bad config %#v" , mountEntry )
}
}
2015-03-15 21:42:05 +00:00
func TestSystemBackend_mount_invalid ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "mounts/prod/secret/" )
2015-03-15 21:42:05 +00:00
req . Data [ "type" ] = "nope"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-15 21:53:41 +00:00
if err != logical . ErrInvalidRequest {
2015-03-15 21:42:05 +00:00
t . Fatalf ( "err: %v" , err )
}
2018-11-07 01:21:24 +00:00
if resp . Data [ "error" ] != ` plugin not found in the catalog: nope ` {
2015-03-15 21:42:05 +00:00
t . Fatalf ( "bad: %v" , resp )
}
}
func TestSystemBackend_unmount ( t * testing . T ) {
b := testSystemBackend ( t )
2015-03-16 17:52:35 +00:00
req := logical . TestRequest ( t , logical . DeleteOperation , "mounts/secret/" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-15 21:42:05 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
}
2016-03-18 15:58:06 +00:00
var capabilitiesPolicy = `
name = "test"
path "foo/bar*" {
capabilities = [ "create" , "sudo" , "update" ]
}
path "sys/capabilities*" {
capabilities = [ "update" ]
}
2018-03-01 16:14:56 +00:00
path "bar/baz" {
capabilities = [ "read" , "update" ]
}
path "bar/baz" {
capabilities = [ "delete" ]
}
2016-03-18 15:58:06 +00:00
`
2018-03-01 16:14:56 +00:00
func TestSystemBackend_PathCapabilities ( t * testing . T ) {
var resp * logical . Response
var err error
core , b , rootToken := testCoreSystemBackend ( t )
2018-09-18 03:03:00 +00:00
policy , _ := ParseACLPolicy ( namespace . RootNamespace , capabilitiesPolicy )
2018-11-05 16:11:32 +00:00
err = core . policyStore . SetPolicy ( namespace . RootContext ( nil ) , policy )
2018-03-01 16:14:56 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
path1 := "foo/bar"
path2 := "foo/bar/sample"
path3 := "sys/capabilities"
path4 := "bar/baz"
rootCheckFunc := func ( t * testing . T , resp * logical . Response ) {
// All the paths should have "root" as the capability
expectedRoot := [ ] string { "root" }
if ! reflect . DeepEqual ( resp . Data [ path1 ] , expectedRoot ) ||
! reflect . DeepEqual ( resp . Data [ path2 ] , expectedRoot ) ||
! reflect . DeepEqual ( resp . Data [ path3 ] , expectedRoot ) ||
! reflect . DeepEqual ( resp . Data [ path4 ] , expectedRoot ) {
t . Fatalf ( "bad: capabilities; expected: %#v, actual: %#v" , expectedRoot , resp . Data )
}
}
// Check the capabilities using the root token
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
2018-03-01 16:14:56 +00:00
Path : "capabilities" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"paths" : [ ] string { path1 , path2 , path3 , path4 } ,
"token" : rootToken ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
rootCheckFunc ( t , resp )
// Check the capabilities using capabilities-self
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
2018-03-01 16:14:56 +00:00
ClientToken : rootToken ,
Path : "capabilities-self" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"paths" : [ ] string { path1 , path2 , path3 , path4 } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
rootCheckFunc ( t , resp )
// Lookup the accessor of the root token
2018-11-05 16:11:32 +00:00
te , err := core . tokenStore . Lookup ( namespace . RootContext ( nil ) , rootToken )
2018-03-01 16:14:56 +00:00
if err != nil {
t . Fatal ( err )
}
// Check the capabilities using capabilities-accessor endpoint
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
2018-03-01 16:14:56 +00:00
Path : "capabilities-accessor" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"paths" : [ ] string { path1 , path2 , path3 , path4 } ,
"accessor" : te . Accessor ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
rootCheckFunc ( t , resp )
// Create a non-root token
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , core . tokenStore , rootToken , "tokenid" , "" , [ ] string { "test" } )
2018-03-01 16:14:56 +00:00
nonRootCheckFunc := func ( t * testing . T , resp * logical . Response ) {
expected1 := [ ] string { "create" , "sudo" , "update" }
expected2 := expected1
expected3 := [ ] string { "update" }
expected4 := [ ] string { "delete" , "read" , "update" }
if ! reflect . DeepEqual ( resp . Data [ path1 ] , expected1 ) ||
! reflect . DeepEqual ( resp . Data [ path2 ] , expected2 ) ||
! reflect . DeepEqual ( resp . Data [ path3 ] , expected3 ) ||
! reflect . DeepEqual ( resp . Data [ path4 ] , expected4 ) {
t . Fatalf ( "bad: capabilities; actual: %#v" , resp . Data )
}
}
// Check the capabilities using a non-root token
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
2018-03-01 16:14:56 +00:00
Path : "capabilities" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"paths" : [ ] string { path1 , path2 , path3 , path4 } ,
"token" : "tokenid" ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
nonRootCheckFunc ( t , resp )
// Check the capabilities of a non-root token using capabilities-self
// endpoint
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
2018-03-01 16:14:56 +00:00
ClientToken : "tokenid" ,
Path : "capabilities-self" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"paths" : [ ] string { path1 , path2 , path3 , path4 } ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
nonRootCheckFunc ( t , resp )
// Lookup the accessor of the non-root token
2018-11-05 16:11:32 +00:00
te , err = core . tokenStore . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2018-03-01 16:14:56 +00:00
if err != nil {
t . Fatal ( err )
}
// Check the capabilities using a non-root token using
// capabilities-accessor endpoint
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , & logical . Request {
2018-03-01 16:14:56 +00:00
Path : "capabilities-accessor" ,
Operation : logical . UpdateOperation ,
Data : map [ string ] interface { } {
"paths" : [ ] string { path1 , path2 , path3 , path4 } ,
"accessor" : te . Accessor ,
} ,
} )
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "bad: resp: %#v\nerr: %v" , resp , err )
}
nonRootCheckFunc ( t , resp )
}
func TestSystemBackend_Capabilities_BC ( t * testing . T ) {
2016-03-18 15:58:06 +00:00
testCapabilities ( t , "capabilities" )
testCapabilities ( t , "capabilities-self" )
}
func testCapabilities ( t * testing . T , endpoint string ) {
core , b , rootToken := testCoreSystemBackend ( t )
req := logical . TestRequest ( t , logical . UpdateOperation , endpoint )
2018-03-01 16:14:56 +00:00
if endpoint == "capabilities-self" {
req . ClientToken = rootToken
} else {
req . Data [ "token" ] = rootToken
}
2016-03-18 15:58:06 +00:00
req . Data [ "path" ] = "any_path"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-18 15:58:06 +00:00
if err != nil {
t . Fatal ( err )
}
if resp == nil {
t . Fatalf ( "bad: %v" , resp )
}
actual := resp . Data [ "capabilities" ]
expected := [ ] string { "root" }
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "bad: got\n%#v\nexpected\n%#v\n" , actual , expected )
}
2018-09-18 03:03:00 +00:00
policy , _ := ParseACLPolicy ( namespace . RootNamespace , capabilitiesPolicy )
2018-11-05 16:11:32 +00:00
err = core . policyStore . SetPolicy ( namespace . RootContext ( nil ) , policy )
2016-03-18 15:58:06 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , core . tokenStore , rootToken , "tokenid" , "" , [ ] string { "test" } )
2016-03-18 15:58:06 +00:00
req = logical . TestRequest ( t , logical . UpdateOperation , endpoint )
2018-03-01 16:14:56 +00:00
if endpoint == "capabilities-self" {
req . ClientToken = "tokenid"
} else {
req . Data [ "token" ] = "tokenid"
}
2016-03-18 15:58:06 +00:00
req . Data [ "path" ] = "foo/bar"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-18 15:58:06 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil {
t . Fatalf ( "bad: %v" , resp )
}
actual = resp . Data [ "capabilities" ]
2016-03-18 16:40:17 +00:00
expected = [ ] string { "create" , "sudo" , "update" }
2016-03-18 15:58:06 +00:00
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "bad: got\n%#v\nexpected\n%#v\n" , actual , expected )
}
}
2018-03-01 16:14:56 +00:00
func TestSystemBackend_CapabilitiesAccessor_BC ( t * testing . T ) {
2016-03-18 15:58:06 +00:00
core , b , rootToken := testCoreSystemBackend ( t )
2018-11-05 16:11:32 +00:00
te , err := core . tokenStore . Lookup ( namespace . RootContext ( nil ) , rootToken )
2016-03-18 15:58:06 +00:00
if err != nil {
t . Fatal ( err )
}
2016-03-18 14:37:49 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "capabilities-accessor" )
2016-03-18 15:58:06 +00:00
// Accessor of root token
req . Data [ "accessor" ] = te . Accessor
req . Data [ "path" ] = "any_path"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-18 14:37:49 +00:00
if err != nil {
2016-03-18 15:58:06 +00:00
t . Fatalf ( "err: %v" , err )
}
if resp == nil {
t . Fatalf ( "bad: %v" , resp )
}
actual := resp . Data [ "capabilities" ]
expected := [ ] string { "root" }
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "bad: got\n%#v\nexpected\n%#v\n" , actual , expected )
}
2018-09-18 03:03:00 +00:00
policy , _ := ParseACLPolicy ( namespace . RootNamespace , capabilitiesPolicy )
2018-11-05 16:11:32 +00:00
err = core . policyStore . SetPolicy ( namespace . RootContext ( nil ) , policy )
2016-03-18 15:58:06 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , core . tokenStore , rootToken , "tokenid" , "" , [ ] string { "test" } )
2016-03-18 15:58:06 +00:00
2018-11-05 16:11:32 +00:00
te , err = core . tokenStore . Lookup ( namespace . RootContext ( nil ) , "tokenid" )
2016-03-18 15:58:06 +00:00
if err != nil {
t . Fatal ( err )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "capabilities-accessor" )
req . Data [ "accessor" ] = te . Accessor
req . Data [ "path" ] = "foo/bar"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-18 15:58:06 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil {
t . Fatalf ( "bad: %v" , resp )
}
actual = resp . Data [ "capabilities" ]
2016-03-18 16:40:17 +00:00
expected = [ ] string { "create" , "sudo" , "update" }
2016-03-18 15:58:06 +00:00
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "bad: got\n%#v\nexpected\n%#v\n" , actual , expected )
2016-03-18 14:37:49 +00:00
}
}
2015-03-15 21:42:05 +00:00
func TestSystemBackend_remount ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "remount" )
2015-03-15 21:42:05 +00:00
req . Data [ "from" ] = "secret"
req . Data [ "to" ] = "foo"
2015-09-01 22:29:30 +00:00
req . Data [ "config" ] = structs . Map ( MountConfig { } )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-15 21:42:05 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
}
func TestSystemBackend_remount_invalid ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "remount" )
2015-03-15 21:42:05 +00:00
req . Data [ "from" ] = "unknown"
req . Data [ "to" ] = "foo"
2015-09-01 22:29:30 +00:00
req . Data [ "config" ] = structs . Map ( MountConfig { } )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-15 21:53:41 +00:00
if err != logical . ErrInvalidRequest {
2015-03-15 21:42:05 +00:00
t . Fatalf ( "err: %v" , err )
}
2018-04-06 00:43:29 +00:00
if resp . Data [ "error" ] != ` no matching mount at "unknown/" ` {
2015-03-15 21:42:05 +00:00
t . Fatalf ( "bad: %v" , resp )
}
}
func TestSystemBackend_remount_system ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "remount" )
2015-03-15 21:42:05 +00:00
req . Data [ "from" ] = "sys"
req . Data [ "to" ] = "foo"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-15 21:53:41 +00:00
if err != logical . ErrInvalidRequest {
2015-03-15 21:42:05 +00:00
t . Fatalf ( "err: %v" , err )
}
2018-04-06 00:43:29 +00:00
if resp . Data [ "error" ] != ` cannot remount "sys/" ` {
2015-03-15 21:42:05 +00:00
t . Fatalf ( "bad: %v" , resp )
}
}
2017-05-04 02:03:42 +00:00
func TestSystemBackend_leases ( t * testing . T ) {
core , b , root := testCoreSystemBackend ( t )
// Create a key with a lease
req := logical . TestRequest ( t , logical . UpdateOperation , "secret/foo" )
req . Data [ "foo" ] = "bar"
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Read a key with a LeaseID
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
// Read lease
req = logical . TestRequest ( t , logical . UpdateOperation , "leases/lookup" )
req . Data [ "lease_id" ] = resp . Secret . LeaseID
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp . Data [ "renewable" ] == nil || resp . Data [ "renewable" ] . ( bool ) {
2017-09-15 13:02:29 +00:00
t . Fatal ( "kv leases are not renewable" )
2017-05-04 02:03:42 +00:00
}
// Invalid lease
req = logical . TestRequest ( t , logical . UpdateOperation , "leases/lookup" )
req . Data [ "lease_id" ] = "invalid"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "expected invalid request, got err: %v" , err )
}
}
func TestSystemBackend_leases_list ( t * testing . T ) {
core , b , root := testCoreSystemBackend ( t )
// Create a key with a lease
req := logical . TestRequest ( t , logical . UpdateOperation , "secret/foo" )
req . Data [ "foo" ] = "bar"
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Read a key with a LeaseID
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
// List top level
req = logical . TestRequest ( t , logical . ListOperation , "leases/lookup/" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Data == nil {
t . Fatalf ( "bad: %#v" , resp )
}
var keys [ ] string
if err := mapstructure . WeakDecode ( resp . Data [ "keys" ] , & keys ) ; err != nil {
t . Fatalf ( "err: %v" , err )
}
if len ( keys ) != 1 {
t . Fatalf ( "Expected 1 subkey lease, got %d: %#v" , len ( keys ) , keys )
}
if keys [ 0 ] != "secret/" {
t . Fatal ( "Expected only secret subkey" )
}
// List lease
req = logical . TestRequest ( t , logical . ListOperation , "leases/lookup/secret/foo" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Data == nil {
t . Fatalf ( "bad: %#v" , resp )
}
keys = [ ] string { }
if err := mapstructure . WeakDecode ( resp . Data [ "keys" ] , & keys ) ; err != nil {
t . Fatalf ( "err: %v" , err )
}
if len ( keys ) != 1 {
t . Fatalf ( "Expected 1 secret lease, got %d: %#v" , len ( keys ) , keys )
}
// Generate multiple leases
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req = logical . TestRequest ( t , logical . ListOperation , "leases/lookup/secret/foo" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Data == nil {
t . Fatalf ( "bad: %#v" , resp )
}
keys = [ ] string { }
if err := mapstructure . WeakDecode ( resp . Data [ "keys" ] , & keys ) ; err != nil {
t . Fatalf ( "err: %v" , err )
}
if len ( keys ) != 3 {
t . Fatalf ( "Expected 3 secret lease, got %d: %#v" , len ( keys ) , keys )
}
// Listing subkeys
req = logical . TestRequest ( t , logical . UpdateOperation , "secret/bar" )
req . Data [ "foo" ] = "bar"
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Read a key with a LeaseID
req = logical . TestRequest ( t , logical . ReadOperation , "secret/bar" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
req = logical . TestRequest ( t , logical . ListOperation , "leases/lookup/secret" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Data == nil {
t . Fatalf ( "bad: %#v" , resp )
}
keys = [ ] string { }
if err := mapstructure . WeakDecode ( resp . Data [ "keys" ] , & keys ) ; err != nil {
t . Fatalf ( "err: %v" , err )
}
if len ( keys ) != 2 {
t . Fatalf ( "Expected 2 secret lease, got %d: %#v" , len ( keys ) , keys )
}
expected := [ ] string { "bar/" , "foo/" }
if ! reflect . DeepEqual ( expected , keys ) {
t . Fatalf ( "exp: %#v, act: %#v" , expected , keys )
}
}
2015-03-16 23:11:55 +00:00
func TestSystemBackend_renew ( t * testing . T ) {
2015-03-24 18:37:07 +00:00
core , b , root := testCoreSystemBackend ( t )
2015-03-16 23:11:55 +00:00
// Create a key with a lease
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "secret/foo" )
2015-03-16 23:11:55 +00:00
req . Data [ "foo" ] = "bar"
2015-03-24 18:37:07 +00:00
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:11:55 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2015-04-08 20:35:32 +00:00
// Read a key with a LeaseID
2015-03-16 23:11:55 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
2015-03-24 18:37:07 +00:00
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:11:55 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-04-08 20:35:32 +00:00
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
2015-03-16 23:11:55 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
// Attempt renew
2017-05-04 02:03:42 +00:00
req2 := logical . TestRequest ( t , logical . UpdateOperation , "leases/renew/" + resp . Secret . LeaseID )
2018-11-05 16:11:32 +00:00
resp2 , err := b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2015-04-09 00:03:46 +00:00
if err != logical . ErrInvalidRequest {
2015-03-16 23:11:55 +00:00
t . Fatalf ( "err: %v" , err )
}
2015-04-09 00:03:46 +00:00
// Should get error about non-renewability
if resp2 . Data [ "error" ] != "lease is not renewable" {
2015-03-16 23:11:55 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2016-08-08 22:32:18 +00:00
// Add a TTL to the lease
req = logical . TestRequest ( t , logical . UpdateOperation , "secret/foo" )
req . Data [ "foo" ] = "bar"
req . Data [ "ttl" ] = "180s"
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-08 22:32:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Read a key with a LeaseID
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-08-08 22:32:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
// Attempt renew
2017-05-04 02:03:42 +00:00
req2 = logical . TestRequest ( t , logical . UpdateOperation , "leases/renew/" + resp . Secret . LeaseID )
2018-11-05 16:11:32 +00:00
resp2 , err = b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2016-08-08 22:32:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp2 . IsError ( ) {
t . Fatalf ( "got an error" )
}
if resp2 . Data == nil {
t . Fatal ( "nil data" )
}
if resp . Secret . TTL != 180 * time . Second {
2016-08-09 11:13:29 +00:00
t . Fatalf ( "bad lease duration: %v" , resp . Secret . TTL )
2016-08-08 22:32:18 +00:00
}
// Test the other route path
2017-05-04 02:03:42 +00:00
req2 = logical . TestRequest ( t , logical . UpdateOperation , "leases/renew" )
req2 . Data [ "lease_id" ] = resp . Secret . LeaseID
2018-11-05 16:11:32 +00:00
resp2 , err = b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp2 . IsError ( ) {
t . Fatalf ( "got an error" )
}
if resp2 . Data == nil {
t . Fatal ( "nil data" )
}
if resp . Secret . TTL != 180 * time . Second {
t . Fatalf ( "bad lease duration: %v" , resp . Secret . TTL )
}
// Test orig path
2016-08-08 22:32:18 +00:00
req2 = logical . TestRequest ( t , logical . UpdateOperation , "renew" )
req2 . Data [ "lease_id" ] = resp . Secret . LeaseID
2018-11-05 16:11:32 +00:00
resp2 , err = b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2016-08-08 22:32:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp2 . IsError ( ) {
t . Fatalf ( "got an error" )
}
if resp2 . Data == nil {
t . Fatal ( "nil data" )
}
2018-10-15 16:56:24 +00:00
if resp . Secret . TTL != time . Second * 180 {
2016-08-09 11:13:29 +00:00
t . Fatalf ( "bad lease duration: %v" , resp . Secret . TTL )
2016-08-08 22:32:18 +00:00
}
2015-03-16 23:11:55 +00:00
}
2015-03-16 23:14:53 +00:00
func TestSystemBackend_renew_invalidID ( t * testing . T ) {
b := testSystemBackend ( t )
2017-05-04 02:03:42 +00:00
// Attempt renew
req := logical . TestRequest ( t , logical . UpdateOperation , "leases/renew/foobarbaz" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp . Data [ "error" ] != "lease not found" {
2017-05-04 02:03:42 +00:00
t . Fatalf ( "bad: %v" , resp )
}
// Attempt renew with other method
req = logical . TestRequest ( t , logical . UpdateOperation , "leases/renew" )
req . Data [ "lease_id" ] = "foobarbaz"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp . Data [ "error" ] != "lease not found" {
2017-05-04 02:03:42 +00:00
t . Fatalf ( "bad: %v" , resp )
}
}
func TestSystemBackend_renew_invalidID_origUrl ( t * testing . T ) {
b := testSystemBackend ( t )
2015-03-16 23:14:53 +00:00
// Attempt renew
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "renew/foobarbaz" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:14:53 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp . Data [ "error" ] != "lease not found" {
2015-03-16 23:14:53 +00:00
t . Fatalf ( "bad: %v" , resp )
}
2017-04-27 14:47:43 +00:00
// Attempt renew with other method
req = logical . TestRequest ( t , logical . UpdateOperation , "renew" )
req . Data [ "lease_id" ] = "foobarbaz"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-27 14:47:43 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp . Data [ "error" ] != "lease not found" {
2017-04-27 14:47:43 +00:00
t . Fatalf ( "bad: %v" , resp )
}
2015-03-16 23:14:53 +00:00
}
2015-03-16 23:26:34 +00:00
func TestSystemBackend_revoke ( t * testing . T ) {
2015-03-24 18:37:07 +00:00
core , b , root := testCoreSystemBackend ( t )
2015-03-16 23:26:34 +00:00
// Create a key with a lease
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "secret/foo" )
2015-03-16 23:26:34 +00:00
req . Data [ "foo" ] = "bar"
req . Data [ "lease" ] = "1h"
2015-03-24 18:37:07 +00:00
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:26:34 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2015-04-08 20:35:32 +00:00
// Read a key with a LeaseID
2015-03-16 23:26:34 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
2015-03-24 18:37:07 +00:00
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:26:34 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-04-08 20:35:32 +00:00
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
2015-03-16 23:26:34 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2015-03-16 23:33:48 +00:00
// Attempt revoke
2016-01-07 15:30:47 +00:00
req2 := logical . TestRequest ( t , logical . UpdateOperation , "revoke/" + resp . Secret . LeaseID )
2018-11-05 16:11:32 +00:00
resp2 , err := b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2015-03-16 23:26:34 +00:00
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp2 )
}
if resp2 != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2015-03-16 23:33:48 +00:00
// Attempt renew
2016-01-07 15:30:47 +00:00
req3 := logical . TestRequest ( t , logical . UpdateOperation , "renew/" + resp . Secret . LeaseID )
2018-11-05 16:11:32 +00:00
resp3 , err := b . HandleRequest ( namespace . RootContext ( nil ) , req3 )
2015-03-16 23:33:48 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp3 . Data [ "error" ] != "lease not found" {
t . Fatalf ( "bad: %v" , * resp3 )
2015-03-16 23:33:48 +00:00
}
2017-04-27 14:47:43 +00:00
// Read a key with a LeaseID
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-27 14:47:43 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
// Test the other route path
req2 = logical . TestRequest ( t , logical . UpdateOperation , "revoke" )
req2 . Data [ "lease_id" ] = resp . Secret . LeaseID
2018-11-05 16:11:32 +00:00
resp2 , err = b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2017-04-27 14:47:43 +00:00
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp2 )
}
if resp2 != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2017-05-04 02:03:42 +00:00
// Read a key with a LeaseID
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
// Test the other route path
req2 = logical . TestRequest ( t , logical . UpdateOperation , "leases/revoke" )
req2 . Data [ "lease_id" ] = resp . Secret . LeaseID
2018-11-05 16:11:32 +00:00
resp2 , err = b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp2 )
}
if resp2 != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2015-03-16 23:26:34 +00:00
}
func TestSystemBackend_revoke_invalidID ( t * testing . T ) {
b := testSystemBackend ( t )
2017-05-04 02:03:42 +00:00
// Attempt revoke
req := logical . TestRequest ( t , logical . UpdateOperation , "leases/revoke/foobarbaz" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
// Attempt revoke with other method
req = logical . TestRequest ( t , logical . UpdateOperation , "leases/revoke" )
req . Data [ "lease_id" ] = "foobarbaz"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
}
func TestSystemBackend_revoke_invalidID_origUrl ( t * testing . T ) {
b := testSystemBackend ( t )
2017-04-27 14:47:43 +00:00
// Attempt revoke
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "revoke/foobarbaz" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:26:34 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
2017-04-27 14:47:43 +00:00
// Attempt revoke with other method
req = logical . TestRequest ( t , logical . UpdateOperation , "revoke" )
req . Data [ "lease_id" ] = "foobarbaz"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-27 14:47:43 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
2015-03-16 23:26:34 +00:00
}
2015-03-16 23:33:48 +00:00
func TestSystemBackend_revokePrefix ( t * testing . T ) {
2015-03-24 18:37:07 +00:00
core , b , root := testCoreSystemBackend ( t )
2015-03-16 23:33:48 +00:00
// Create a key with a lease
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "secret/foo" )
2015-03-16 23:33:48 +00:00
req . Data [ "foo" ] = "bar"
req . Data [ "lease" ] = "1h"
2015-03-24 18:37:07 +00:00
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:33:48 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2015-04-08 20:35:32 +00:00
// Read a key with a LeaseID
2015-03-16 23:33:48 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
2015-03-24 18:37:07 +00:00
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-16 23:33:48 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2015-04-08 20:35:32 +00:00
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
2015-03-16 23:33:48 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
2017-05-04 02:03:42 +00:00
// Attempt revoke
req2 := logical . TestRequest ( t , logical . UpdateOperation , "leases/revoke-prefix/secret/" )
2018-11-05 16:11:32 +00:00
resp2 , err := b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp2 )
}
if resp2 != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Attempt renew
req3 := logical . TestRequest ( t , logical . UpdateOperation , "leases/renew/" + resp . Secret . LeaseID )
2018-11-05 16:11:32 +00:00
resp3 , err := b . HandleRequest ( namespace . RootContext ( nil ) , req3 )
2017-05-04 02:03:42 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp3 . Data [ "error" ] != "lease not found" {
t . Fatalf ( "bad: %v" , * resp3 )
2017-05-04 02:03:42 +00:00
}
}
func TestSystemBackend_revokePrefix_origUrl ( t * testing . T ) {
core , b , root := testCoreSystemBackend ( t )
// Create a key with a lease
req := logical . TestRequest ( t , logical . UpdateOperation , "secret/foo" )
req . Data [ "foo" ] = "bar"
req . Data [ "lease" ] = "1h"
req . ClientToken = root
2018-11-05 16:11:32 +00:00
resp , err := core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Read a key with a LeaseID
req = logical . TestRequest ( t , logical . ReadOperation , "secret/foo" )
req . ClientToken = root
2018-10-15 16:56:24 +00:00
req . SetTokenEntry ( & logical . TokenEntry { ID : root , NamespaceID : "root" , Policies : [ ] string { "root" } } )
2018-11-05 16:11:32 +00:00
resp , err = core . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Secret == nil || resp . Secret . LeaseID == "" {
t . Fatalf ( "bad: %#v" , resp )
}
2015-03-16 23:33:48 +00:00
// Attempt revoke
2016-01-07 15:30:47 +00:00
req2 := logical . TestRequest ( t , logical . UpdateOperation , "revoke-prefix/secret/" )
2018-11-05 16:11:32 +00:00
resp2 , err := b . HandleRequest ( namespace . RootContext ( nil ) , req2 )
2015-03-16 23:33:48 +00:00
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp2 )
}
if resp2 != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Attempt renew
2016-01-07 15:30:47 +00:00
req3 := logical . TestRequest ( t , logical . UpdateOperation , "renew/" + resp . Secret . LeaseID )
2018-11-05 16:11:32 +00:00
resp3 , err := b . HandleRequest ( namespace . RootContext ( nil ) , req3 )
2015-03-16 23:33:48 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-10-15 16:56:24 +00:00
if resp3 . Data [ "error" ] != "lease not found" {
t . Fatalf ( "bad: %#v" , * resp3 )
2015-03-16 23:33:48 +00:00
}
}
2018-06-03 22:14:51 +00:00
func TestSystemBackend_revokePrefixAuth_newUrl ( t * testing . T ) {
core , _ , _ := TestCoreUnsealed ( t )
ts := core . tokenStore
2016-03-31 22:04:05 +00:00
bc := & logical . BackendConfig {
Logger : core . logger ,
System : logical . StaticSystemView {
DefaultLeaseTTLVal : time . Hour * 24 ,
2016-09-28 22:32:49 +00:00
MaxLeaseTTLVal : time . Hour * 24 * 32 ,
2016-03-31 22:04:05 +00:00
} ,
}
2018-04-03 00:46:59 +00:00
b := NewSystemBackend ( core , hclog . New ( & hclog . LoggerOptions { } ) )
2018-11-05 16:11:32 +00:00
err := b . Backend . Setup ( namespace . RootContext ( nil ) , bc )
2016-09-29 04:01:28 +00:00
if err != nil {
t . Fatal ( err )
}
2016-03-31 22:04:05 +00:00
exp := ts . expiration
2018-06-08 21:24:27 +00:00
te := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
ID : "foo" ,
Path : "auth/github/login/bar" ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2017-05-04 02:03:42 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , te )
2017-05-04 02:03:42 +00:00
2018-11-05 16:11:32 +00:00
te , err = ts . Lookup ( namespace . RootContext ( nil ) , "foo" )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "token entry was nil" )
}
// Create a new token
auth := & logical . Auth {
ClientToken : te . ID ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , te , auth )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
req := logical . TestRequest ( t , logical . UpdateOperation , "leases/revoke-prefix/auth/github/" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v %v" , err , resp )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
te , err = ts . Lookup ( namespace . RootContext ( nil ) , te . ID )
2017-05-04 02:03:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if te != nil {
t . Fatalf ( "bad: %v" , te )
}
}
func TestSystemBackend_revokePrefixAuth_origUrl ( t * testing . T ) {
2018-06-03 22:14:51 +00:00
core , _ , _ := TestCoreUnsealed ( t )
ts := core . tokenStore
2016-03-31 22:04:05 +00:00
bc := & logical . BackendConfig {
Logger : core . logger ,
System : logical . StaticSystemView {
DefaultLeaseTTLVal : time . Hour * 24 ,
2016-09-28 22:32:49 +00:00
MaxLeaseTTLVal : time . Hour * 24 * 32 ,
2016-03-31 22:04:05 +00:00
} ,
}
2018-04-03 00:46:59 +00:00
b := NewSystemBackend ( core , hclog . New ( & hclog . LoggerOptions { } ) )
2018-11-05 16:11:32 +00:00
err := b . Backend . Setup ( namespace . RootContext ( nil ) , bc )
2016-09-29 04:01:28 +00:00
if err != nil {
t . Fatal ( err )
}
2016-03-31 22:04:05 +00:00
exp := ts . expiration
2018-06-08 21:24:27 +00:00
te := & logical . TokenEntry {
2018-09-18 03:03:00 +00:00
ID : "foo" ,
Path : "auth/github/login/bar" ,
TTL : time . Hour ,
NamespaceID : namespace . RootNamespaceID ,
2016-03-31 22:04:05 +00:00
}
2018-06-03 22:14:51 +00:00
testMakeTokenDirectly ( t , ts , te )
2016-03-31 22:04:05 +00:00
2018-11-05 16:11:32 +00:00
te , err = ts . Lookup ( namespace . RootContext ( nil ) , "foo" )
2016-03-31 22:04:05 +00:00
if err != nil {
t . Fatal ( err )
}
if te == nil {
t . Fatal ( "token entry was nil" )
}
// Create a new token
auth := & logical . Auth {
ClientToken : te . ID ,
LeaseOptions : logical . LeaseOptions {
TTL : time . Hour ,
} ,
}
2018-11-05 16:11:32 +00:00
err = exp . RegisterAuth ( namespace . RootContext ( nil ) , te , auth )
2016-03-31 22:04:05 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
req := logical . TestRequest ( t , logical . UpdateOperation , "revoke-prefix/auth/github/" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-03-31 22:04:05 +00:00
if err != nil {
t . Fatalf ( "err: %v %v" , err , resp )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
2018-11-05 16:11:32 +00:00
te , err = ts . Lookup ( namespace . RootContext ( nil ) , te . ID )
2016-03-31 22:04:05 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if te != nil {
t . Fatalf ( "bad: %v" , te )
}
}
2015-03-20 19:48:19 +00:00
func TestSystemBackend_authTable ( t * testing . T ) {
b := testSystemBackend ( t )
req := logical . TestRequest ( t , logical . ReadOperation , "auth" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-20 19:48:19 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
2016-06-20 19:55:21 +00:00
"token/" : map [ string ] interface { } {
2015-03-20 19:48:19 +00:00
"type" : "token" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2015-03-20 19:48:19 +00:00
"description" : "token based credentials" ,
2017-06-26 17:14:36 +00:00
"accessor" : resp . Data [ "token/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "token/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2016-06-20 19:55:21 +00:00
"config" : map [ string ] interface { } {
2016-06-21 00:08:12 +00:00
"default_lease_ttl" : int64 ( 0 ) ,
"max_lease_ttl" : int64 ( 0 ) ,
2018-10-15 16:56:24 +00:00
"force_no_cache" : false ,
"token_type" : "default-service" ,
2016-06-20 19:55:21 +00:00
} ,
2017-11-13 16:22:22 +00:00
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2015-03-20 19:48:19 +00:00
} ,
}
2018-10-15 16:56:24 +00:00
if diff := deep . Equal ( resp . Data , exp ) ; diff != nil {
t . Fatal ( diff )
2015-03-20 19:48:19 +00:00
}
}
func TestSystemBackend_enableAuth ( t * testing . T ) {
2015-03-24 18:37:07 +00:00
c , b , _ := testCoreSystemBackend ( t )
2018-01-19 06:44:44 +00:00
c . credentialBackends [ "noop" ] = func ( context . Context , * logical . BackendConfig ) ( logical . Backend , error ) {
2018-11-07 01:21:24 +00:00
return & NoopBackend { BackendType : logical . TypeCredential } , nil
2015-03-20 19:48:19 +00:00
}
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/foo" )
2015-03-20 19:48:19 +00:00
req . Data [ "type" ] = "noop"
2018-02-22 15:26:29 +00:00
req . Data [ "config" ] = map [ string ] interface { } {
"default_lease_ttl" : "35m" ,
"max_lease_ttl" : "45m" ,
}
2017-11-13 16:22:22 +00:00
req . Data [ "local" ] = true
req . Data [ "seal_wrap" ] = true
2015-03-20 19:48:19 +00:00
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-20 19:48:19 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
2017-11-13 16:22:22 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "auth" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-11-13 16:22:22 +00:00
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" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-11-13 16:22:22 +00:00
"description" : "" ,
"accessor" : resp . Data [ "foo/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "foo/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-11-13 16:22:22 +00:00
"config" : map [ string ] interface { } {
2018-02-22 15:26:29 +00:00
"default_lease_ttl" : int64 ( 2100 ) ,
"max_lease_ttl" : int64 ( 2700 ) ,
2018-10-15 16:56:24 +00:00
"force_no_cache" : false ,
"token_type" : "default-service" ,
2017-11-13 16:22:22 +00:00
} ,
"local" : true ,
"seal_wrap" : true ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string { } ,
2017-11-13 16:22:22 +00:00
} ,
"token/" : map [ string ] interface { } {
"type" : "token" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2017-11-13 16:22:22 +00:00
"description" : "token based credentials" ,
"accessor" : resp . Data [ "token/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "token/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2017-11-13 16:22:22 +00:00
"config" : map [ string ] interface { } {
"default_lease_ttl" : int64 ( 0 ) ,
"max_lease_ttl" : int64 ( 0 ) ,
2018-10-15 16:56:24 +00:00
"force_no_cache" : false ,
"token_type" : "default-service" ,
2017-11-13 16:22:22 +00:00
} ,
"local" : false ,
"seal_wrap" : false ,
2018-03-21 19:04:27 +00:00
"options" : map [ string ] string ( nil ) ,
2017-11-13 16:22:22 +00:00
} ,
}
2018-10-15 16:56:24 +00:00
if diff := deep . Equal ( resp . Data , exp ) ; diff != nil {
t . Fatal ( diff )
2017-11-13 16:22:22 +00:00
}
2015-03-20 19:48:19 +00:00
}
func TestSystemBackend_enableAuth_invalid ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/foo" )
2015-03-20 19:48:19 +00:00
req . Data [ "type" ] = "nope"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-20 19:48:19 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-11-07 01:21:24 +00:00
if resp . Data [ "error" ] != ` plugin not found in the catalog: nope ` {
2015-03-20 19:48:19 +00:00
t . Fatalf ( "bad: %v" , resp )
}
}
func TestSystemBackend_disableAuth ( t * testing . T ) {
2015-03-24 18:37:07 +00:00
c , b , _ := testCoreSystemBackend ( t )
2018-01-19 06:44:44 +00:00
c . credentialBackends [ "noop" ] = func ( context . Context , * logical . BackendConfig ) ( logical . Backend , error ) {
2015-03-31 01:07:05 +00:00
return & NoopBackend { } , nil
2015-03-20 19:48:19 +00:00
}
// Register the backend
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "auth/foo" )
2015-03-20 19:48:19 +00:00
req . Data [ "type" ] = "noop"
2018-11-05 16:11:32 +00:00
b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-20 19:48:19 +00:00
// Deregister it
req = logical . TestRequest ( t , logical . DeleteOperation , "auth/foo" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-20 19:48:19 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
}
2015-03-23 21:43:31 +00:00
func TestSystemBackend_policyList ( t * testing . T ) {
b := testSystemBackend ( t )
req := logical . TestRequest ( t , logical . ReadOperation , "policy" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-23 21:43:31 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
2016-07-25 19:59:02 +00:00
"keys" : [ ] string { "default" , "root" } ,
"policies" : [ ] string { "default" , "root" } ,
2015-03-23 21:43:31 +00:00
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
}
func TestSystemBackend_policyCRUD ( t * testing . T ) {
b := testSystemBackend ( t )
// Create the policy
rules := ` path "foo/" { policy = "read" } `
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "policy/Foo" )
2015-03-23 21:43:31 +00:00
req . Data [ "rules" ] = rules
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-23 21:43:31 +00:00
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp )
}
2017-10-23 19:35:28 +00:00
if resp != nil && ( resp . IsError ( ) || len ( resp . Data ) > 0 ) {
2015-03-23 21:43:31 +00:00
t . Fatalf ( "bad: %#v" , resp )
}
// Read the policy
req = logical . TestRequest ( t , logical . ReadOperation , "policy/foo" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-23 21:43:31 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
"name" : "foo" ,
"rules" : rules ,
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
2015-10-07 17:52:21 +00:00
// Read, and make sure that case has been normalized
req = logical . TestRequest ( t , logical . ReadOperation , "policy/Foo" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-07-04 17:58:28 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2017-08-18 23:47:23 +00:00
exp = map [ string ] interface { } {
"name" : "foo" ,
"rules" : rules ,
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
2015-10-07 17:52:21 +00:00
}
2015-03-23 21:43:31 +00:00
// List the policies
req = logical . TestRequest ( t , logical . ReadOperation , "policy" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-23 21:43:31 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp = map [ string ] interface { } {
2016-07-25 19:59:02 +00:00
"keys" : [ ] string { "default" , "foo" , "root" } ,
"policies" : [ ] string { "default" , "foo" , "root" } ,
2015-03-23 21:43:31 +00:00
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
// Delete the policy
req = logical . TestRequest ( t , logical . DeleteOperation , "policy/foo" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-23 21:43:31 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// Read the policy (deleted)
req = logical . TestRequest ( t , logical . ReadOperation , "policy/foo" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-23 21:43:31 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %#v" , resp )
}
// List the policies (deleted)
req = logical . TestRequest ( t , logical . ReadOperation , "policy" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-23 21:43:31 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp = map [ string ] interface { } {
2016-07-25 19:59:02 +00:00
"keys" : [ ] string { "default" , "root" } ,
"policies" : [ ] string { "default" , "root" } ,
2015-03-23 21:43:31 +00:00
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
}
2015-03-31 23:45:00 +00:00
func TestSystemBackend_enableAudit ( t * testing . T ) {
c , b , _ := testCoreSystemBackend ( t )
2018-01-19 06:44:44 +00:00
c . auditBackends [ "noop" ] = func ( ctx context . Context , config * audit . BackendConfig ) ( audit . Backend , error ) {
2015-09-18 21:36:42 +00:00
return & NoopAudit {
Config : config ,
} , nil
2015-03-31 23:45:00 +00:00
}
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "audit/foo" )
2015-03-31 23:45:00 +00:00
req . Data [ "type" ] = "noop"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-31 23:45:00 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
}
2015-11-19 01:26:03 +00:00
func TestSystemBackend_auditHash ( t * testing . T ) {
c , b , _ := testCoreSystemBackend ( t )
2018-01-19 06:44:44 +00:00
c . auditBackends [ "noop" ] = func ( ctx context . Context , config * audit . BackendConfig ) ( audit . Backend , error ) {
2015-11-19 01:26:03 +00:00
view := & logical . InmemStorage { }
2018-11-05 16:11:32 +00:00
view . Put ( namespace . RootContext ( nil ) , & logical . StorageEntry {
2015-11-19 01:26:03 +00:00
Key : "salt" ,
Value : [ ] byte ( "foo" ) ,
} )
2017-05-24 00:36:20 +00:00
config . SaltView = view
config . SaltConfig = & salt . Config {
2015-11-19 01:26:03 +00:00
HMAC : sha256 . New ,
HMACType : "hmac-sha256" ,
2017-05-24 00:36:20 +00:00
Location : salt . DefaultLocation ,
2015-11-19 01:26:03 +00:00
}
return & NoopAudit {
Config : config ,
} , nil
}
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "audit/foo" )
2015-11-19 01:26:03 +00:00
req . Data [ "type" ] = "noop"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-11-19 01:26:03 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
2016-01-07 15:30:47 +00:00
req = logical . TestRequest ( t , logical . UpdateOperation , "audit-hash/foo" )
2015-11-19 01:26:03 +00:00
req . Data [ "input" ] = "bar"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-11-19 01:26:03 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp == nil || resp . Data == nil {
t . Fatalf ( "response or its data was nil" )
}
hash , ok := resp . Data [ "hash" ]
if ! ok {
t . Fatalf ( "did not get hash back in response, response was %#v" , resp . Data )
}
if hash . ( string ) != "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317" {
t . Fatalf ( "bad hash back: %s" , hash . ( string ) )
}
}
2015-03-31 23:45:00 +00:00
func TestSystemBackend_enableAudit_invalid ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "audit/foo" )
2015-03-31 23:45:00 +00:00
req . Data [ "type" ] = "nope"
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-31 23:45:00 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
2018-04-06 00:43:29 +00:00
if resp . Data [ "error" ] != ` unknown backend type: "nope" ` {
2015-03-31 23:45:00 +00:00
t . Fatalf ( "bad: %v" , resp )
}
}
func TestSystemBackend_auditTable ( t * testing . T ) {
c , b , _ := testCoreSystemBackend ( t )
2018-01-19 06:44:44 +00:00
c . auditBackends [ "noop" ] = func ( ctx context . Context , config * audit . BackendConfig ) ( audit . Backend , error ) {
2015-09-18 21:36:42 +00:00
return & NoopAudit {
Config : config ,
} , nil
2015-03-31 23:45:00 +00:00
}
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "audit/foo" )
2015-03-31 23:45:00 +00:00
req . Data [ "type" ] = "noop"
req . Data [ "description" ] = "testing"
req . Data [ "options" ] = map [ string ] interface { } {
"foo" : "bar" ,
}
2017-02-16 21:29:30 +00:00
req . Data [ "local" ] = true
2018-11-05 16:11:32 +00:00
b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-31 23:45:00 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "audit" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-31 23:45:00 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
2015-04-03 21:27:33 +00:00
"foo/" : map [ string ] interface { } {
2016-03-14 22:40:12 +00:00
"path" : "foo/" ,
2015-03-31 23:45:00 +00:00
"type" : "noop" ,
"description" : "testing" ,
"options" : map [ string ] string {
"foo" : "bar" ,
} ,
2017-02-16 21:29:30 +00:00
"local" : true ,
2015-03-31 23:45:00 +00:00
} ,
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
}
func TestSystemBackend_disableAudit ( t * testing . T ) {
c , b , _ := testCoreSystemBackend ( t )
2018-01-19 06:44:44 +00:00
c . auditBackends [ "noop" ] = func ( ctx context . Context , config * audit . BackendConfig ) ( audit . Backend , error ) {
2015-09-18 21:36:42 +00:00
return & NoopAudit {
Config : config ,
} , nil
2015-03-31 23:45:00 +00:00
}
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "audit/foo" )
2015-03-31 23:45:00 +00:00
req . Data [ "type" ] = "noop"
req . Data [ "description" ] = "testing"
req . Data [ "options" ] = map [ string ] interface { } {
"foo" : "bar" ,
}
2018-11-05 16:11:32 +00:00
b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-31 23:45:00 +00:00
// Deregister it
req = logical . TestRequest ( t , logical . DeleteOperation , "audit/foo" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-03-31 23:45:00 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
}
2018-02-09 23:43:48 +00:00
func TestSystemBackend_rawRead_Compressed ( t * testing . T ) {
b := testSystemBackendRaw ( t )
req := logical . TestRequest ( t , logical . ReadOperation , "raw/core/mounts" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-02-09 23:43:48 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! strings . HasPrefix ( resp . Data [ "value" ] . ( string ) , "{\"type\":\"mounts\"" ) {
t . Fatalf ( "bad: %v" , resp )
}
}
2015-05-28 17:24:41 +00:00
func TestSystemBackend_rawRead_Protected ( t * testing . T ) {
2017-09-15 04:21:35 +00:00
b := testSystemBackendRaw ( t )
2015-05-28 17:24:41 +00:00
req := logical . TestRequest ( t , logical . ReadOperation , "raw/" + keyringPath )
2018-11-05 16:11:32 +00:00
_ , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-05-28 17:24:41 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
}
func TestSystemBackend_rawWrite_Protected ( t * testing . T ) {
2017-09-15 04:21:35 +00:00
b := testSystemBackendRaw ( t )
2015-05-28 17:24:41 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "raw/" + keyringPath )
2018-11-05 16:11:32 +00:00
_ , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-05-28 17:24:41 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
}
2016-04-19 20:26:26 +00:00
func TestSystemBackend_rawReadWrite ( t * testing . T ) {
2017-10-23 19:35:28 +00:00
_ , b , _ := testCoreSystemBackendRaw ( t )
2015-04-02 00:44:43 +00:00
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "raw/sys/policy/test" )
2015-04-02 00:44:43 +00:00
req . Data [ "value" ] = ` path "secret/" { policy = "read" } `
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-04-02 00:44:43 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
2016-04-19 20:26:26 +00:00
// Read via raw API
req = logical . TestRequest ( t , logical . ReadOperation , "raw/sys/policy/test" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2016-04-19 20:26:26 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if ! strings . HasPrefix ( resp . Data [ "value" ] . ( string ) , "path" ) {
t . Fatalf ( "bad: %v" , resp )
}
2017-10-23 19:35:28 +00:00
// Note: since the upgrade code is gone that upgraded from 0.1, we can't
// simply parse this out directly via GetPolicy, so the test now ends here.
2015-04-02 00:44:43 +00:00
}
2015-05-28 17:24:41 +00:00
func TestSystemBackend_rawDelete_Protected ( t * testing . T ) {
2017-09-15 04:21:35 +00:00
b := testSystemBackendRaw ( t )
2015-05-28 17:24:41 +00:00
req := logical . TestRequest ( t , logical . DeleteOperation , "raw/" + keyringPath )
2018-11-05 16:11:32 +00:00
_ , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-05-28 17:24:41 +00:00
if err != logical . ErrInvalidRequest {
t . Fatalf ( "err: %v" , err )
}
}
2015-04-02 00:44:43 +00:00
func TestSystemBackend_rawDelete ( t * testing . T ) {
2017-09-15 04:21:35 +00:00
c , b , _ := testCoreSystemBackendRaw ( t )
2015-04-02 00:44:43 +00:00
// set the policy!
2017-10-23 19:35:28 +00:00
p := & Policy {
2018-09-18 03:03:00 +00:00
Name : "test" ,
Type : PolicyTypeACL ,
namespace : namespace . RootNamespace ,
2017-10-23 19:35:28 +00:00
}
2018-11-05 16:11:32 +00:00
err := c . policyStore . SetPolicy ( namespace . RootContext ( nil ) , p )
2015-04-02 00:44:43 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
// Delete the policy
req := logical . TestRequest ( t , logical . DeleteOperation , "raw/sys/policy/test" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-04-02 00:44:43 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
// Policy should be gone
2017-10-23 19:35:28 +00:00
c . policyStore . tokenPoliciesLRU . Purge ( )
2018-11-05 16:11:32 +00:00
out , err := c . policyStore . GetPolicy ( namespace . RootContext ( nil ) , "test" , PolicyTypeToken )
2015-04-02 00:44:43 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if out != nil {
t . Fatalf ( "policy should be gone" )
}
}
2015-05-28 00:53:42 +00:00
func TestSystemBackend_keyStatus ( t * testing . T ) {
b := testSystemBackend ( t )
req := logical . TestRequest ( t , logical . ReadOperation , "key-status" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-05-28 00:53:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
"term" : 1 ,
}
delete ( resp . Data , "install_time" )
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
}
func TestSystemBackend_rotate ( t * testing . T ) {
b := testSystemBackend ( t )
2016-01-07 15:30:47 +00:00
req := logical . TestRequest ( t , logical . UpdateOperation , "rotate" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-05-28 00:53:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
if resp != nil {
t . Fatalf ( "bad: %v" , resp )
}
req = logical . TestRequest ( t , logical . ReadOperation , "key-status" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2015-05-28 00:53:42 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
"term" : 2 ,
}
delete ( resp . Data , "install_time" )
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
}
2015-03-16 00:35:59 +00:00
func testSystemBackend ( t * testing . T ) logical . Backend {
2015-03-29 23:18:08 +00:00
c , _ , _ := TestCoreUnsealed ( t )
2018-03-01 16:14:56 +00:00
return c . systemBackend
2017-09-15 04:21:35 +00:00
}
2016-09-29 04:01:28 +00:00
2017-09-15 04:21:35 +00:00
func testSystemBackendRaw ( t * testing . T ) logical . Backend {
c , _ , _ := TestCoreUnsealedRaw ( t )
2018-03-01 16:14:56 +00:00
return c . systemBackend
2015-03-15 21:42:05 +00:00
}
2015-03-16 23:11:55 +00:00
2015-03-24 18:37:07 +00:00
func testCoreSystemBackend ( t * testing . T ) ( * Core , logical . Backend , string ) {
2015-03-29 23:18:08 +00:00
c , _ , root := TestCoreUnsealed ( t )
2018-03-01 16:14:56 +00:00
return c , c . systemBackend , root
2017-09-15 04:21:35 +00:00
}
func testCoreSystemBackendRaw ( t * testing . T ) ( * Core , logical . Backend , string ) {
c , _ , root := TestCoreUnsealedRaw ( t )
2018-03-01 16:14:56 +00:00
return c , c . systemBackend , root
2017-09-15 04:21:35 +00:00
}
2017-04-12 17:39:18 +00:00
func TestSystemBackend_PluginCatalog_CRUD ( t * testing . T ) {
c , b , _ := testCoreSystemBackend ( t )
// Bootstrap the pluginCatalog
sym , err := filepath . EvalSymlinks ( os . TempDir ( ) )
if err != nil {
t . Fatalf ( "error: %v" , err )
}
c . pluginCatalog . directory = sym
2018-11-07 01:21:24 +00:00
req := logical . TestRequest ( t , logical . ListOperation , "plugins/catalog/database" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-12 17:39:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-11-07 01:21:24 +00:00
if len ( resp . Data [ "keys" ] . ( [ ] string ) ) != len ( c . builtinRegistry . Keys ( consts . PluginTypeDatabase ) ) {
t . Fatalf ( "Wrong number of plugins, got %d, expected %d" , len ( resp . Data [ "keys" ] . ( [ ] string ) ) , len ( builtinplugins . Registry . Keys ( consts . PluginTypeDatabase ) ) )
2017-04-12 17:39:18 +00:00
}
2018-11-07 01:21:24 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "plugins/catalog/database/mysql-database-plugin" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-12 17:39:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-01-18 00:19:28 +00:00
actualRespData := resp . Data
expectedRespData := map [ string ] interface { } {
"name" : "mysql-database-plugin" ,
"command" : "" ,
"args" : [ ] string ( nil ) ,
"sha256" : "" ,
"builtin" : true ,
2017-04-12 17:39:18 +00:00
}
Backend plugin system (#2874)
* Add backend plugin changes
* Fix totp backend plugin tests
* Fix logical/plugin InvalidateKey test
* Fix plugin catalog CRUD test, fix NoopBackend
* Clean up commented code block
* Fix system backend mount test
* Set plugin_name to omitempty, fix handleMountTable config parsing
* Clean up comments, keep shim connections alive until cleanup
* Include pluginClient, disallow LookupPlugin call from within a plugin
* Add wrapper around backendPluginClient for proper cleanup
* Add logger shim tests
* Add logger, storage, and system shim tests
* Use pointer receivers for system view shim
* Use plugin name if no path is provided on mount
* Enable plugins for auth backends
* Add backend type attribute, move builtin/plugin/package
* Fix merge conflict
* Fix missing plugin name in mount config
* Add integration tests on enabling auth backend plugins
* Remove dependency cycle on mock-plugin
* Add passthrough backend plugin, use logical.BackendType to determine lease generation
* Remove vault package dependency on passthrough package
* Add basic impl test for passthrough plugin
* Incorporate feedback; set b.backend after shims creation on backendPluginServer
* Fix totp plugin test
* Add plugin backends docs
* Fix tests
* Fix builtin/plugin tests
* Remove flatten from PluginRunner fields
* Move mock plugin to logical/plugin, remove totp and passthrough plugins
* Move pluginMap into newPluginClient
* Do not create storage RPC connection on HandleRequest and HandleExistenceCheck
* Change shim logger's Fatal to no-op
* Change BackendType to uint32, match UX backend types
* Change framework.Backend Setup signature
* Add Setup func to logical.Backend interface
* Move OptionallyEnableMlock call into plugin.Serve, update docs and comments
* Remove commented var in plugin package
* RegisterLicense on logical.Backend interface (#3017)
* Add RegisterLicense to logical.Backend interface
* Update RegisterLicense to use callback func on framework.Backend
* Refactor framework.Backend.RegisterLicense
* plugin: Prevent plugin.SystemViewClient.ResponseWrapData from getting JWTs
* plugin: Revert BackendType to remove TypePassthrough and related references
* Fix typo in plugin backends docs
2017-07-20 17:28:40 +00:00
if ! reflect . DeepEqual ( actualRespData , expectedRespData ) {
t . Fatalf ( "expected did not match actual, got %#v\n expected %#v\n" , actualRespData , expectedRespData )
2017-04-12 17:39:18 +00:00
}
// Set a plugin
file , err := ioutil . TempFile ( os . TempDir ( ) , "temp" )
if err != nil {
t . Fatal ( err )
}
defer file . Close ( )
2018-01-18 00:19:28 +00:00
// Check we can only specify args in one of command or args.
2017-04-12 17:39:18 +00:00
command := fmt . Sprintf ( "%s --test" , filepath . Base ( file . Name ( ) ) )
2018-11-07 01:21:24 +00:00
req = logical . TestRequest ( t , logical . UpdateOperation , "plugins/catalog/database/test-plugin" )
2018-01-18 00:19:28 +00:00
req . Data [ "args" ] = [ ] string { "--foo" }
2017-04-12 17:39:18 +00:00
req . Data [ "sha_256" ] = hex . EncodeToString ( [ ] byte { '1' } )
req . Data [ "command" ] = command
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-12 17:39:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-03-20 18:54:10 +00:00
if resp . Error ( ) . Error ( ) != "must not specify args in command and args field" {
2018-01-18 00:19:28 +00:00
t . Fatalf ( "err: %v" , resp . Error ( ) )
}
delete ( req . Data , "args" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-01-18 00:19:28 +00:00
if err != nil || resp . Error ( ) != nil {
t . Fatalf ( "err: %v %v" , err , resp . Error ( ) )
}
2017-04-12 17:39:18 +00:00
2018-11-07 01:21:24 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "plugins/catalog/database/test-plugin" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-12 17:39:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-01-18 00:19:28 +00:00
actual := resp . Data
expected := map [ string ] interface { } {
"name" : "test-plugin" ,
"command" : filepath . Base ( file . Name ( ) ) ,
"args" : [ ] string { "--test" } ,
"sha256" : "31" ,
"builtin" : false ,
2017-04-12 17:39:18 +00:00
}
Backend plugin system (#2874)
* Add backend plugin changes
* Fix totp backend plugin tests
* Fix logical/plugin InvalidateKey test
* Fix plugin catalog CRUD test, fix NoopBackend
* Clean up commented code block
* Fix system backend mount test
* Set plugin_name to omitempty, fix handleMountTable config parsing
* Clean up comments, keep shim connections alive until cleanup
* Include pluginClient, disallow LookupPlugin call from within a plugin
* Add wrapper around backendPluginClient for proper cleanup
* Add logger shim tests
* Add logger, storage, and system shim tests
* Use pointer receivers for system view shim
* Use plugin name if no path is provided on mount
* Enable plugins for auth backends
* Add backend type attribute, move builtin/plugin/package
* Fix merge conflict
* Fix missing plugin name in mount config
* Add integration tests on enabling auth backend plugins
* Remove dependency cycle on mock-plugin
* Add passthrough backend plugin, use logical.BackendType to determine lease generation
* Remove vault package dependency on passthrough package
* Add basic impl test for passthrough plugin
* Incorporate feedback; set b.backend after shims creation on backendPluginServer
* Fix totp plugin test
* Add plugin backends docs
* Fix tests
* Fix builtin/plugin tests
* Remove flatten from PluginRunner fields
* Move mock plugin to logical/plugin, remove totp and passthrough plugins
* Move pluginMap into newPluginClient
* Do not create storage RPC connection on HandleRequest and HandleExistenceCheck
* Change shim logger's Fatal to no-op
* Change BackendType to uint32, match UX backend types
* Change framework.Backend Setup signature
* Add Setup func to logical.Backend interface
* Move OptionallyEnableMlock call into plugin.Serve, update docs and comments
* Remove commented var in plugin package
* RegisterLicense on logical.Backend interface (#3017)
* Add RegisterLicense to logical.Backend interface
* Update RegisterLicense to use callback func on framework.Backend
* Refactor framework.Backend.RegisterLicense
* plugin: Prevent plugin.SystemViewClient.ResponseWrapData from getting JWTs
* plugin: Revert BackendType to remove TypePassthrough and related references
* Fix typo in plugin backends docs
2017-07-20 17:28:40 +00:00
if ! reflect . DeepEqual ( actual , expected ) {
t . Fatalf ( "expected did not match actual, got %#v\n expected %#v\n" , actual , expected )
2017-04-12 17:39:18 +00:00
}
// Delete plugin
2018-11-07 01:21:24 +00:00
req = logical . TestRequest ( t , logical . DeleteOperation , "plugins/catalog/database/test-plugin" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-12 17:39:18 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
2018-11-07 01:21:24 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "plugins/catalog/database/test-plugin" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-04-25 04:24:19 +00:00
if resp != nil || err != nil {
t . Fatalf ( "expected nil response, plugin not deleted correctly got resp: %v, err: %v" , resp , err )
2017-04-12 17:39:18 +00:00
}
}
2017-10-20 14:59:17 +00:00
func TestSystemBackend_ToolsHash ( t * testing . T ) {
b := testSystemBackend ( t )
req := logical . TestRequest ( t , logical . UpdateOperation , "tools/hash" )
req . Data = map [ string ] interface { } {
"input" : "dGhlIHF1aWNrIGJyb3duIGZveA==" ,
}
2018-11-05 16:11:32 +00:00
_ , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-10-20 14:59:17 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
doRequest := func ( req * logical . Request , errExpected bool , expected string ) {
t . Helper ( )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-10-20 14:59:17 +00:00
if err != nil && ! errExpected {
t . Fatal ( err )
}
if resp == nil {
t . Fatal ( "expected non-nil response" )
}
if errExpected {
if ! resp . IsError ( ) {
t . Fatalf ( "bad: got error response: %#v" , * resp )
}
return
}
if resp . IsError ( ) {
t . Fatalf ( "bad: got error response: %#v" , * resp )
}
sum , ok := resp . Data [ "sum" ]
if ! ok {
t . Fatal ( "no sum key found in returned data" )
}
if sum . ( string ) != expected {
t . Fatal ( "mismatched hashes" )
}
}
// Test defaults -- sha2-256
doRequest ( req , false , "9ecb36561341d18eb65484e833efea61edc74b84cf5e6ae1b81c63533e25fc8f" )
// Test algorithm selection in the path
req . Path = "tools/hash/sha2-224"
doRequest ( req , false , "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865" )
// Reset and test algorithm selection in the data
req . Path = "tools/hash"
req . Data [ "algorithm" ] = "sha2-224"
doRequest ( req , false , "ea074a96cabc5a61f8298a2c470f019074642631a49e1c5e2f560865" )
req . Data [ "algorithm" ] = "sha2-384"
doRequest ( req , false , "15af9ec8be783f25c583626e9491dbf129dd6dd620466fdf05b3a1d0bb8381d30f4d3ec29f923ff1e09a0f6b337365a6" )
req . Data [ "algorithm" ] = "sha2-512"
doRequest ( req , false , "d9d380f29b97ad6a1d92e987d83fa5a02653301e1006dd2bcd51afa59a9147e9caedaf89521abc0f0b682adcd47fb512b8343c834a32f326fe9bef00542ce887" )
// Test returning as base64
req . Data [ "format" ] = "base64"
doRequest ( req , false , "2dOA8puXrWodkumH2D+loCZTMB4QBt0rzVGvpZqRR+nK7a+JUhq8DwtoKtzUf7USuDQ8g0oy8yb+m+8AVCzohw==" )
// Test bad input/format/algorithm
req . Data [ "format" ] = "base92"
doRequest ( req , true , "" )
req . Data [ "format" ] = "hex"
req . Data [ "algorithm" ] = "foobar"
doRequest ( req , true , "" )
req . Data [ "algorithm" ] = "sha2-256"
req . Data [ "input" ] = "foobar"
doRequest ( req , true , "" )
}
func TestSystemBackend_ToolsRandom ( t * testing . T ) {
b := testSystemBackend ( t )
req := logical . TestRequest ( t , logical . UpdateOperation , "tools/random" )
2018-11-05 16:11:32 +00:00
_ , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-10-20 14:59:17 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
doRequest := func ( req * logical . Request , errExpected bool , format string , numBytes int ) {
t . Helper ( )
getResponse := func ( ) [ ] byte {
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2017-10-20 14:59:17 +00:00
if err != nil && ! errExpected {
t . Fatal ( err )
}
if resp == nil {
t . Fatal ( "expected non-nil response" )
}
if errExpected {
if ! resp . IsError ( ) {
t . Fatalf ( "bad: got error response: %#v" , * resp )
}
return nil
}
if resp . IsError ( ) {
t . Fatalf ( "bad: got error response: %#v" , * resp )
}
if _ , ok := resp . Data [ "random_bytes" ] ; ! ok {
t . Fatal ( "no random_bytes found in response" )
}
outputStr := resp . Data [ "random_bytes" ] . ( string )
var outputBytes [ ] byte
switch format {
case "base64" :
outputBytes , err = base64 . StdEncoding . DecodeString ( outputStr )
case "hex" :
outputBytes , err = hex . DecodeString ( outputStr )
default :
t . Fatal ( "unknown format" )
}
if err != nil {
t . Fatal ( err )
}
return outputBytes
}
rand1 := getResponse ( )
// Expected error
if rand1 == nil {
return
}
rand2 := getResponse ( )
if len ( rand1 ) != numBytes || len ( rand2 ) != numBytes {
2018-03-20 18:54:10 +00:00
t . Fatal ( "length of output random bytes not what is expected" )
2017-10-20 14:59:17 +00:00
}
if reflect . DeepEqual ( rand1 , rand2 ) {
t . Fatal ( "found identical ouputs" )
}
}
// Test defaults
doRequest ( req , false , "base64" , 32 )
// Test size selection in the path
req . Path = "tools/random/24"
req . Data [ "format" ] = "hex"
doRequest ( req , false , "hex" , 24 )
// Test bad input/format
req . Path = "tools/random"
req . Data [ "format" ] = "base92"
doRequest ( req , true , "" , 0 )
req . Data [ "format" ] = "hex"
req . Data [ "bytes" ] = - 1
doRequest ( req , true , "" , 0 )
2019-07-25 01:22:23 +00:00
req . Data [ "format" ] = "hex"
req . Data [ "bytes" ] = maxBytes + 1
doRequest ( req , true , "" , 0 )
2017-10-20 14:59:17 +00:00
}
2018-03-20 03:16:33 +00:00
func TestSystemBackend_InternalUIMounts ( t * testing . T ) {
2018-04-23 22:00:02 +00:00
_ , b , rootToken := testCoreSystemBackend ( t )
2018-03-20 03:16:33 +00:00
// Ensure no entries are in the endpoint as a starting point
req := logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts" )
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-03-20 03:16:33 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
"secret" : map [ string ] interface { } { } ,
"auth" : map [ string ] interface { } { } ,
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
2018-04-23 22:00:02 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts" )
req . ClientToken = rootToken
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp = map [ string ] interface { } {
"secret" : map [ string ] interface { } {
"secret/" : map [ string ] interface { } {
"type" : "kv" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2018-04-23 22:00:02 +00:00
"description" : "key/value secret storage" ,
"accessor" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "secret/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "secret/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2018-04-23 22:00:02 +00:00
"config" : map [ string ] interface { } {
"default_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "secret/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "default_lease_ttl" ] . ( int64 ) ,
"max_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "secret/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "max_lease_ttl" ] . ( int64 ) ,
"force_no_cache" : false ,
} ,
"local" : false ,
"seal_wrap" : false ,
"options" : map [ string ] string {
"version" : "1" ,
} ,
} ,
"sys/" : map [ string ] interface { } {
"type" : "system" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2018-04-23 22:00:02 +00:00
"description" : "system endpoints used for control, policy and debugging" ,
"accessor" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "sys/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "sys/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2018-04-23 22:00:02 +00:00
"config" : map [ string ] interface { } {
2019-02-15 18:45:55 +00:00
"default_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "sys/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "default_lease_ttl" ] . ( int64 ) ,
"max_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "sys/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "max_lease_ttl" ] . ( int64 ) ,
"force_no_cache" : false ,
"passthrough_request_headers" : [ ] string { "Accept" } ,
2018-04-23 22:00:02 +00:00
} ,
"local" : false ,
"seal_wrap" : false ,
"options" : map [ string ] string ( nil ) ,
} ,
"cubbyhole/" : map [ string ] interface { } {
"description" : "per-token private secret storage" ,
"type" : "cubbyhole" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2018-04-23 22:00:02 +00:00
"accessor" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2018-04-23 22:00:02 +00:00
"config" : map [ string ] interface { } {
"default_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "default_lease_ttl" ] . ( int64 ) ,
"max_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "cubbyhole/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "max_lease_ttl" ] . ( int64 ) ,
"force_no_cache" : false ,
} ,
"local" : true ,
"seal_wrap" : false ,
"options" : map [ string ] string ( nil ) ,
} ,
"identity/" : map [ string ] interface { } {
"description" : "identity store" ,
"type" : "identity" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2018-04-23 22:00:02 +00:00
"accessor" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "identity/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "identity/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2018-04-23 22:00:02 +00:00
"config" : map [ string ] interface { } {
"default_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "identity/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "default_lease_ttl" ] . ( int64 ) ,
"max_lease_ttl" : resp . Data [ "secret" ] . ( map [ string ] interface { } ) [ "identity/" ] . ( map [ string ] interface { } ) [ "config" ] . ( map [ string ] interface { } ) [ "max_lease_ttl" ] . ( int64 ) ,
"force_no_cache" : false ,
} ,
"local" : false ,
"seal_wrap" : false ,
"options" : map [ string ] string ( nil ) ,
} ,
} ,
"auth" : map [ string ] interface { } {
"token/" : map [ string ] interface { } {
"options" : map [ string ] string ( nil ) ,
"config" : map [ string ] interface { } {
"default_lease_ttl" : int64 ( 0 ) ,
"max_lease_ttl" : int64 ( 0 ) ,
"force_no_cache" : false ,
2018-10-15 16:56:24 +00:00
"token_type" : "default-service" ,
2018-04-23 22:00:02 +00:00
} ,
"type" : "token" ,
2019-10-17 17:33:00 +00:00
"external_entropy_access" : false ,
2018-04-23 22:00:02 +00:00
"description" : "token based credentials" ,
"accessor" : resp . Data [ "auth" ] . ( map [ string ] interface { } ) [ "token/" ] . ( map [ string ] interface { } ) [ "accessor" ] ,
2019-04-24 19:27:43 +00:00
"uuid" : resp . Data [ "auth" ] . ( map [ string ] interface { } ) [ "token/" ] . ( map [ string ] interface { } ) [ "uuid" ] ,
2018-04-23 22:00:02 +00:00
"local" : false ,
"seal_wrap" : false ,
} ,
} ,
}
2018-10-15 16:56:24 +00:00
if diff := deep . Equal ( resp . Data , exp ) ; diff != nil {
t . Fatal ( diff )
2018-04-23 22:00:02 +00:00
}
2018-03-20 03:16:33 +00:00
// Mount-tune an auth mount
req = logical . TestRequest ( t , logical . UpdateOperation , "auth/token/tune" )
req . Data [ "listing_visibility" ] = "unauth"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-09-18 03:03:00 +00:00
if resp . IsError ( ) || err != nil {
t . Fatalf ( "resp.Error: %v, err:%v" , resp . Error ( ) , err )
}
2018-03-20 03:16:33 +00:00
// Mount-tune a secret mount
req = logical . TestRequest ( t , logical . UpdateOperation , "mounts/secret/tune" )
req . Data [ "listing_visibility" ] = "unauth"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-09-18 03:03:00 +00:00
if resp . IsError ( ) || err != nil {
t . Fatalf ( "resp.Error: %v, err:%v" , resp . Error ( ) , err )
}
2018-03-20 03:16:33 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts" )
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-03-20 03:16:33 +00:00
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp = map [ string ] interface { } {
"secret" : map [ string ] interface { } {
"secret/" : map [ string ] interface { } {
"type" : "kv" ,
"description" : "key/value secret storage" ,
2018-04-23 22:00:02 +00:00
"options" : map [ string ] string { "version" : "1" } ,
2018-03-20 03:16:33 +00:00
} ,
} ,
"auth" : map [ string ] interface { } {
"token/" : map [ string ] interface { } {
"type" : "token" ,
"description" : "token based credentials" ,
2018-04-23 22:00:02 +00:00
"options" : map [ string ] string ( nil ) ,
2018-03-20 03:16:33 +00:00
} ,
} ,
}
if ! reflect . DeepEqual ( resp . Data , exp ) {
t . Fatalf ( "got: %#v expect: %#v" , resp . Data , exp )
}
}
2018-04-23 22:00:02 +00:00
func TestSystemBackend_InternalUIMount ( t * testing . T ) {
core , b , rootToken := testCoreSystemBackend ( t )
req := logical . TestRequest ( t , logical . UpdateOperation , "policy/secret" )
req . ClientToken = rootToken
req . Data = map [ string ] interface { } {
"rules" : ` path "secret/foo/*" {
capabilities = [ "create" , "read" , "update" , "delete" , "list" ]
} ` ,
}
2018-11-05 16:11:32 +00:00
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "Bad %#v %#v" , err , resp )
}
req = logical . TestRequest ( t , logical . UpdateOperation , "mounts/kv" )
req . ClientToken = rootToken
req . Data = map [ string ] interface { } {
"type" : "kv" ,
}
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "Bad %#v %#v" , err , resp )
}
2018-04-23 22:16:10 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts/kv/bar" )
2018-04-23 22:00:02 +00:00
req . ClientToken = rootToken
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "Bad %#v %#v" , err , resp )
}
if resp . Data [ "type" ] != "kv" {
t . Fatalf ( "Bad Response: %#v" , resp )
}
2018-10-15 16:56:24 +00:00
testMakeServiceTokenViaBackend ( t , core . tokenStore , rootToken , "tokenid" , "" , [ ] string { "secret" } )
2018-04-23 22:00:02 +00:00
2018-04-23 22:16:10 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts/kv" )
2018-04-23 22:00:02 +00:00
req . ClientToken = "tokenid"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != logical . ErrPermissionDenied {
t . Fatal ( "expected permission denied error" )
}
2018-04-23 22:16:10 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts/secret" )
2018-04-23 22:00:02 +00:00
req . ClientToken = "tokenid"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "Bad %#v %#v" , err , resp )
}
if resp . Data [ "type" ] != "kv" {
t . Fatalf ( "Bad Response: %#v" , resp )
}
2018-04-23 22:16:10 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts/sys" )
2018-04-23 22:00:02 +00:00
req . ClientToken = "tokenid"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != nil || ( resp != nil && resp . IsError ( ) ) {
t . Fatalf ( "Bad %#v %#v" , err , resp )
}
if resp . Data [ "type" ] != "system" {
t . Fatalf ( "Bad Response: %#v" , resp )
}
2018-04-23 22:16:10 +00:00
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts/non-existent" )
2018-04-23 22:00:02 +00:00
req . ClientToken = "tokenid"
2018-11-05 16:11:32 +00:00
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
2018-04-23 22:00:02 +00:00
if err != logical . ErrPermissionDenied {
t . Fatal ( "expected permission denied error" )
}
}
2018-11-05 20:24:39 +00:00
func TestSystemBackend_OpenAPI ( t * testing . T ) {
_ , b , rootToken := testCoreSystemBackend ( t )
var oapi map [ string ] interface { }
// Ensure no paths are reported if there is no token
req := logical . TestRequest ( t , logical . ReadOperation , "internal/specs/openapi" )
resp , err := b . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
body := resp . Data [ "http_raw_body" ] . ( [ ] byte )
err = jsonutil . DecodeJSON ( body , & oapi )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
exp := map [ string ] interface { } {
"openapi" : framework . OASVersion ,
"info" : map [ string ] interface { } {
"title" : "HashiCorp Vault API" ,
"description" : "HTTP API that gives you full access to Vault. All API routes are prefixed with `/v1/`." ,
"version" : version . GetVersion ( ) . Version ,
"license" : map [ string ] interface { } {
"name" : "Mozilla Public License 2.0" ,
"url" : "https://www.mozilla.org/en-US/MPL/2.0" ,
} ,
} ,
"paths" : map [ string ] interface { } { } ,
}
if diff := deep . Equal ( oapi , exp ) ; diff != nil {
t . Fatal ( diff )
}
// Check that default paths are present with a root token
req = logical . TestRequest ( t , logical . ReadOperation , "internal/specs/openapi" )
req . ClientToken = rootToken
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
body = resp . Data [ "http_raw_body" ] . ( [ ] byte )
err = jsonutil . DecodeJSON ( body , & oapi )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
doc , err := framework . NewOASDocumentFromMap ( oapi )
if err != nil {
t . Fatal ( err )
}
pathSamples := [ ] struct {
path string
tag string
} {
{ "/auth/token/lookup" , "auth" } ,
2018-11-06 18:09:06 +00:00
{ "/cubbyhole/{path}" , "secrets" } ,
2018-11-05 20:24:39 +00:00
{ "/identity/group/id" , "identity" } ,
2018-11-06 18:09:06 +00:00
{ "/secret/.*" , "secrets" } , // TODO update after kv repo update
2018-11-05 20:24:39 +00:00
{ "/sys/policy" , "system" } ,
}
for _ , path := range pathSamples {
if doc . Paths [ path . path ] == nil {
t . Fatalf ( "didn't find expected path '%s'." , path )
}
tag := doc . Paths [ path . path ] . Get . Tags [ 0 ]
if tag != path . tag {
t . Fatalf ( "path: %s; expected tag: %s, actual: %s" , path . path , tag , path . tag )
}
}
// Simple sanity check of response size (which is much larger than most
// Vault responses), mainly to catch mass omission of expected path data.
minLen := 70000
if len ( body ) < minLen {
t . Fatalf ( "response size too small; expected: min %d, actual: %d" , minLen , len ( body ) )
}
// Test path-help response
req = logical . TestRequest ( t , logical . HelpOperation , "rotate" )
req . ClientToken = rootToken
resp , err = b . HandleRequest ( namespace . RootContext ( nil ) , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
doc = resp . Data [ "openapi" ] . ( * framework . OASDocument )
if len ( doc . Paths ) != 1 {
t . Fatalf ( "expected 1 path, actual: %d" , len ( doc . Paths ) )
}
if doc . Paths [ "/rotate" ] == nil {
t . Fatalf ( "expected to find path '/rotate'" )
}
}
2019-04-10 21:46:17 +00:00
func TestSystemBackend_PathWildcardPreflight ( t * testing . T ) {
core , b , _ := testCoreSystemBackend ( t )
ctx := namespace . RootContext ( nil )
// Add another mount
me := & MountEntry {
Table : mountTableType ,
Path : sanitizeMountPath ( "kv-v1" ) ,
Type : "kv" ,
Options : map [ string ] string { "version" : "1" } ,
}
if err := core . mount ( ctx , me ) ; err != nil {
t . Fatal ( err )
}
// Create the policy, designed to fail
rules := ` path "foo" { capabilities = ["read"] } `
req := logical . TestRequest ( t , logical . UpdateOperation , "policy/foo" )
req . Data [ "rules" ] = rules
resp , err := b . HandleRequest ( ctx , req )
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp )
}
if resp != nil && ( resp . IsError ( ) || len ( resp . Data ) > 0 ) {
t . Fatalf ( "bad: %#v" , resp )
}
if err := core . identityStore . upsertEntity ( ctx , & identity . Entity {
2019-05-07 19:29:51 +00:00
ID : "abcd" ,
Name : "abcd" ,
BucketKey : "abcd" ,
2019-04-10 21:46:17 +00:00
} , nil , false ) ; err != nil {
t . Fatal ( err )
}
te := & logical . TokenEntry {
TTL : 300 * time . Second ,
EntityID : "abcd" ,
Policies : [ ] string { "default" , "foo" } ,
NamespaceID : namespace . RootNamespaceID ,
}
if err := core . tokenStore . create ( ctx , te ) ; err != nil {
t . Fatal ( err )
}
t . Logf ( "token id: %s" , te . ID )
if err := core . expiration . RegisterAuth ( ctx , te , & logical . Auth {
LeaseOptions : logical . LeaseOptions {
TTL : te . TTL ,
} ,
ClientToken : te . ID ,
Accessor : te . Accessor ,
Orphan : true ,
} ) ; err != nil {
t . Fatal ( err )
}
// Check the mount access func
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts/kv-v1/baz" )
req . ClientToken = te . ID
resp , err = b . HandleRequest ( ctx , req )
if err == nil || ! strings . Contains ( err . Error ( ) , "permission denied" ) {
t . Fatalf ( "expected 403, got err: %v" , err )
}
// Modify policy to pass
rules = ` path "kv-v1/+" { capabilities = ["read"] } `
req = logical . TestRequest ( t , logical . UpdateOperation , "policy/foo" )
req . Data [ "rules" ] = rules
resp , err = b . HandleRequest ( ctx , req )
if err != nil {
t . Fatalf ( "err: %v %#v" , err , resp )
}
if resp != nil && ( resp . IsError ( ) || len ( resp . Data ) > 0 ) {
t . Fatalf ( "bad: %#v" , resp )
}
// Check the mount access func again
req = logical . TestRequest ( t , logical . ReadOperation , "internal/ui/mounts/kv-v1/baz" )
req . ClientToken = te . ID
resp , err = b . HandleRequest ( ctx , req )
if err != nil {
t . Fatalf ( "err: %v" , err )
}
}