2015-03-19 02:36:17 +00:00
|
|
|
package vault
|
|
|
|
|
|
|
|
import (
|
2016-05-30 22:58:58 +00:00
|
|
|
"encoding/json"
|
2015-03-19 02:36:17 +00:00
|
|
|
"reflect"
|
|
|
|
"testing"
|
2015-03-19 17:39:47 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/vault/logical"
|
2015-03-19 02:36:17 +00:00
|
|
|
)
|
|
|
|
|
2016-05-30 22:58:58 +00:00
|
|
|
func TestAuth_UpgradeAWSEC2Auth(t *testing.T) {
|
|
|
|
c, _, _ := TestCoreUnsealed(t)
|
|
|
|
|
|
|
|
// create a no-op backend in the name of "aws"
|
|
|
|
c.credentialBackends["aws"] = func(*logical.BackendConfig) (logical.Backend, error) {
|
|
|
|
return &NoopBackend{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// create a mount entry and create an entry in the mount table
|
|
|
|
me := &MountEntry{
|
|
|
|
Table: credentialTableType,
|
|
|
|
Path: "aws",
|
|
|
|
Type: "aws",
|
|
|
|
}
|
|
|
|
err := c.enableCredential(me)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// save the mount table with an auth entry for "aws"
|
|
|
|
mt := c.auth
|
|
|
|
before, err := json.Marshal(mt)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
entry := &Entry{
|
|
|
|
Key: coreAuthConfigPath,
|
|
|
|
Value: before,
|
|
|
|
}
|
|
|
|
if err := c.barrier.Put(entry); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// create an expected value
|
|
|
|
var expectedMt MountTable
|
|
|
|
expectedMt = *c.auth
|
2016-05-31 23:52:08 +00:00
|
|
|
|
|
|
|
for _, entry := range expectedMt.Entries {
|
|
|
|
if entry.Type == "aws" {
|
|
|
|
entry.Type = "aws-ec2"
|
|
|
|
}
|
|
|
|
}
|
2016-05-30 22:58:58 +00:00
|
|
|
expected, err := json.Marshal(&expectedMt)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// loadCredentials should upgrade the mount table and the entry should now be "aws-ec2"
|
|
|
|
err = c.loadCredentials()
|
|
|
|
|
|
|
|
// read the entry back again and compare it with the expected value
|
|
|
|
actual, err := c.barrier.Get(coreAuthConfigPath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
if !reflect.DeepEqual(expected, actual.Value) {
|
|
|
|
t.Fatalf("bad: expected\n%s\ngot\n%s\n", string(expected), string(entry.Value))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-19 02:36:17 +00:00
|
|
|
func TestCore_DefaultAuthTable(t *testing.T) {
|
2015-03-29 23:18:08 +00:00
|
|
|
c, key, _ := TestCoreUnsealed(t)
|
2015-03-19 02:36:17 +00:00
|
|
|
verifyDefaultAuthTable(t, c.auth)
|
|
|
|
|
|
|
|
// Start a second core with same physical
|
2015-04-29 01:12:57 +00:00
|
|
|
conf := &CoreConfig{
|
|
|
|
Physical: c.physical,
|
|
|
|
DisableMlock: true,
|
|
|
|
}
|
2015-03-19 02:36:17 +00:00
|
|
|
c2, err := NewCore(conf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
unseal, err := c2.Unseal(key)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !unseal {
|
|
|
|
t.Fatalf("should be unsealed")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify matching mount tables
|
|
|
|
if !reflect.DeepEqual(c.auth, c2.auth) {
|
|
|
|
t.Fatalf("mismatch: %v %v", c.auth, c2.auth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-19 17:39:47 +00:00
|
|
|
func TestCore_EnableCredential(t *testing.T) {
|
2015-03-29 23:18:08 +00:00
|
|
|
c, key, _ := TestCoreUnsealed(t)
|
2015-07-01 00:30:43 +00:00
|
|
|
c.credentialBackends["noop"] = func(*logical.BackendConfig) (logical.Backend, error) {
|
2015-03-31 01:07:05 +00:00
|
|
|
return &NoopBackend{}, nil
|
2015-03-19 17:39:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
me := &MountEntry{
|
2016-05-26 17:38:51 +00:00
|
|
|
Table: credentialTableType,
|
|
|
|
Path: "foo",
|
|
|
|
Type: "noop",
|
2015-03-19 17:39:47 +00:00
|
|
|
}
|
|
|
|
err := c.enableCredential(me)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
match := c.router.MatchingMount("auth/foo/bar")
|
|
|
|
if match != "auth/foo/" {
|
|
|
|
t.Fatalf("missing mount")
|
|
|
|
}
|
|
|
|
|
2015-04-29 01:12:57 +00:00
|
|
|
conf := &CoreConfig{
|
|
|
|
Physical: c.physical,
|
|
|
|
DisableMlock: true,
|
|
|
|
}
|
2015-03-19 17:39:47 +00:00
|
|
|
c2, err := NewCore(conf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
2015-11-02 16:01:00 +00:00
|
|
|
c2.credentialBackends["noop"] = func(*logical.BackendConfig) (logical.Backend, error) {
|
|
|
|
return &NoopBackend{}, nil
|
|
|
|
}
|
2015-03-19 17:39:47 +00:00
|
|
|
unseal, err := c2.Unseal(key)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !unseal {
|
|
|
|
t.Fatalf("should be unsealed")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify matching auth tables
|
|
|
|
if !reflect.DeepEqual(c.auth, c2.auth) {
|
|
|
|
t.Fatalf("mismatch: %v %v", c.auth, c2.auth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-12 00:18:52 +00:00
|
|
|
func TestCore_EnableCredential_twice_409(t *testing.T) {
|
|
|
|
c, _, _ := TestCoreUnsealed(t)
|
|
|
|
c.credentialBackends["noop"] = func(*logical.BackendConfig) (logical.Backend, error) {
|
|
|
|
return &NoopBackend{}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
me := &MountEntry{
|
2016-05-26 17:38:51 +00:00
|
|
|
Table: credentialTableType,
|
|
|
|
Path: "foo",
|
|
|
|
Type: "noop",
|
2015-08-12 00:18:52 +00:00
|
|
|
}
|
|
|
|
err := c.enableCredential(me)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
2015-09-15 16:27:22 +00:00
|
|
|
// 2nd should be a 409 error
|
|
|
|
err2 := c.enableCredential(me)
|
|
|
|
switch err2.(type) {
|
|
|
|
case logical.HTTPCodedError:
|
|
|
|
if err2.(logical.HTTPCodedError).Code() != 409 {
|
|
|
|
t.Fatalf("invalid code given")
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
t.Fatalf("expected a different error type")
|
|
|
|
}
|
2015-08-12 00:18:52 +00:00
|
|
|
}
|
|
|
|
|
2015-03-19 17:39:47 +00:00
|
|
|
func TestCore_EnableCredential_Token(t *testing.T) {
|
2015-03-29 23:18:08 +00:00
|
|
|
c, _, _ := TestCoreUnsealed(t)
|
2015-03-19 17:39:47 +00:00
|
|
|
me := &MountEntry{
|
2016-05-26 17:38:51 +00:00
|
|
|
Table: credentialTableType,
|
|
|
|
Path: "foo",
|
|
|
|
Type: "token",
|
2015-03-19 17:39:47 +00:00
|
|
|
}
|
|
|
|
err := c.enableCredential(me)
|
|
|
|
if err.Error() != "token credential backend cannot be instantiated" {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCore_DisableCredential(t *testing.T) {
|
2015-03-29 23:18:08 +00:00
|
|
|
c, key, _ := TestCoreUnsealed(t)
|
2015-07-01 00:30:43 +00:00
|
|
|
c.credentialBackends["noop"] = func(*logical.BackendConfig) (logical.Backend, error) {
|
2015-03-31 01:07:05 +00:00
|
|
|
return &NoopBackend{}, nil
|
2015-03-19 17:39:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
err := c.disableCredential("foo")
|
|
|
|
if err.Error() != "no matching backend" {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
me := &MountEntry{
|
2016-05-26 17:38:51 +00:00
|
|
|
Table: credentialTableType,
|
|
|
|
Path: "foo",
|
|
|
|
Type: "noop",
|
2015-03-19 17:39:47 +00:00
|
|
|
}
|
|
|
|
err = c.enableCredential(me)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = c.disableCredential("foo")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
match := c.router.MatchingMount("auth/foo/bar")
|
|
|
|
if match != "" {
|
|
|
|
t.Fatalf("backend present")
|
|
|
|
}
|
|
|
|
|
2015-04-29 01:12:57 +00:00
|
|
|
conf := &CoreConfig{
|
|
|
|
Physical: c.physical,
|
|
|
|
DisableMlock: true,
|
|
|
|
}
|
2015-03-19 17:39:47 +00:00
|
|
|
c2, err := NewCore(conf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
unseal, err := c2.Unseal(key)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if !unseal {
|
|
|
|
t.Fatalf("should be unsealed")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Verify matching mount tables
|
|
|
|
if !reflect.DeepEqual(c.auth, c2.auth) {
|
|
|
|
t.Fatalf("mismatch: %v %v", c.auth, c2.auth)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCore_DisableCredential_Protected(t *testing.T) {
|
2015-03-29 23:18:08 +00:00
|
|
|
c, _, _ := TestCoreUnsealed(t)
|
2015-03-19 17:39:47 +00:00
|
|
|
err := c.disableCredential("token")
|
|
|
|
if err.Error() != "token credential backend cannot be disabled" {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-03 23:15:34 +00:00
|
|
|
func TestCore_DisableCredential_Cleanup(t *testing.T) {
|
|
|
|
noop := &NoopBackend{
|
|
|
|
Login: []string{"login"},
|
|
|
|
}
|
|
|
|
c, _, _ := TestCoreUnsealed(t)
|
2015-07-01 00:30:43 +00:00
|
|
|
c.credentialBackends["noop"] = func(*logical.BackendConfig) (logical.Backend, error) {
|
2015-04-03 23:15:34 +00:00
|
|
|
return noop, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
me := &MountEntry{
|
2016-05-26 17:38:51 +00:00
|
|
|
Table: credentialTableType,
|
|
|
|
Path: "foo",
|
|
|
|
Type: "noop",
|
2015-04-03 23:15:34 +00:00
|
|
|
}
|
|
|
|
err := c.enableCredential(me)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Store the view
|
2015-09-15 16:27:22 +00:00
|
|
|
view := c.router.MatchingStorageView("auth/foo/")
|
2015-04-03 23:15:34 +00:00
|
|
|
|
|
|
|
// Inject data
|
|
|
|
se := &logical.StorageEntry{
|
|
|
|
Key: "plstodelete",
|
|
|
|
Value: []byte("test"),
|
|
|
|
}
|
|
|
|
if err := view.Put(se); err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate a new token auth
|
|
|
|
noop.Response = &logical.Response{
|
|
|
|
Auth: &logical.Auth{
|
|
|
|
Policies: []string{"foo"},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
r := &logical.Request{
|
|
|
|
Operation: logical.ReadOperation,
|
|
|
|
Path: "auth/foo/login",
|
|
|
|
}
|
|
|
|
resp, err := c.HandleRequest(r)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if resp.Auth.ClientToken == "" {
|
|
|
|
t.Fatalf("bad: %#v", resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Disable should cleanup
|
|
|
|
err = c.disableCredential("foo")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Token should be revoked
|
|
|
|
te, err := c.tokenStore.Lookup(resp.Auth.ClientToken)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if te != nil {
|
|
|
|
t.Fatalf("bad: %#v", te)
|
|
|
|
}
|
|
|
|
|
|
|
|
// View should be empty
|
|
|
|
out, err := CollectKeys(view)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("err: %v", err)
|
|
|
|
}
|
|
|
|
if len(out) != 0 {
|
|
|
|
t.Fatalf("bad: %#v", out)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-19 02:36:17 +00:00
|
|
|
func TestDefaultAuthTable(t *testing.T) {
|
|
|
|
table := defaultAuthTable()
|
|
|
|
verifyDefaultAuthTable(t, table)
|
|
|
|
}
|
|
|
|
|
2015-03-19 16:54:57 +00:00
|
|
|
func verifyDefaultAuthTable(t *testing.T, table *MountTable) {
|
2015-03-19 02:36:17 +00:00
|
|
|
if len(table.Entries) != 1 {
|
|
|
|
t.Fatalf("bad: %v", table.Entries)
|
|
|
|
}
|
2016-05-26 17:38:51 +00:00
|
|
|
if table.Type != credentialTableType {
|
|
|
|
t.Fatalf("bad: %v", *table)
|
|
|
|
}
|
2015-03-19 02:36:17 +00:00
|
|
|
for idx, entry := range table.Entries {
|
|
|
|
switch idx {
|
|
|
|
case 0:
|
2015-04-03 21:24:00 +00:00
|
|
|
if entry.Path != "token/" {
|
2015-03-19 02:36:17 +00:00
|
|
|
t.Fatalf("bad: %v", entry)
|
|
|
|
}
|
|
|
|
if entry.Type != "token" {
|
|
|
|
t.Fatalf("bad: %v", entry)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if entry.Description == "" {
|
|
|
|
t.Fatalf("bad: %v", entry)
|
|
|
|
}
|
|
|
|
if entry.UUID == "" {
|
|
|
|
t.Fatalf("bad: %v", entry)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|