Add to auth/audit too
This commit is contained in:
parent
475b0e2d33
commit
a57996ac08
|
@ -26,6 +26,10 @@ const (
|
|||
// auditBarrierPrefix is the prefix to the UUID used in the
|
||||
// barrier view for the audit backends.
|
||||
auditBarrierPrefix = "audit/"
|
||||
|
||||
// auditTableType is the value we expect to find for the audit table and
|
||||
// corresponding entries
|
||||
auditTableType = "audit"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -146,6 +150,26 @@ func (c *Core) loadAudits() error {
|
|||
|
||||
// Done if we have restored the audit table
|
||||
if c.audit != nil {
|
||||
needPersist := false
|
||||
|
||||
// Upgrade to typed auth table
|
||||
if c.audit.Type == "" {
|
||||
c.audit.Type = auditTableType
|
||||
needPersist = true
|
||||
}
|
||||
|
||||
// Upgrade to table-scoped entries
|
||||
for _, entry := range c.audit.Entries {
|
||||
if entry.Table == "" {
|
||||
entry.Table = c.audit.Type
|
||||
needPersist = true
|
||||
}
|
||||
}
|
||||
|
||||
if needPersist {
|
||||
return c.persistAudit(c.audit)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -159,6 +183,25 @@ func (c *Core) loadAudits() error {
|
|||
|
||||
// persistAudit is used to persist the audit table after modification
|
||||
func (c *Core) persistAudit(table *MountTable) error {
|
||||
if table.Type != auditTableType {
|
||||
c.logger.Printf(
|
||||
"[ERR] core: given table to persist has type %s but need type %s",
|
||||
table.Type,
|
||||
auditTableType)
|
||||
return fmt.Errorf("invalid table type given, not persisting")
|
||||
}
|
||||
|
||||
for _, entry := range table.Entries {
|
||||
if entry.Table != table.Type {
|
||||
c.logger.Printf(
|
||||
"[ERR] core: entry in audit table with path %s has table value %s but is in table %s, refusing to persist",
|
||||
entry.Path,
|
||||
entry.Table,
|
||||
table.Type)
|
||||
return fmt.Errorf("invalid audit entry found, not persisting")
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal the table
|
||||
raw, err := json.Marshal(table)
|
||||
if err != nil {
|
||||
|
@ -240,7 +283,9 @@ func (c *Core) newAuditBackend(t string, view logical.Storage, conf map[string]s
|
|||
|
||||
// defaultAuditTable creates a default audit table
|
||||
func defaultAuditTable() *MountTable {
|
||||
table := &MountTable{}
|
||||
table := &MountTable{
|
||||
Type: auditTableType,
|
||||
}
|
||||
return table
|
||||
}
|
||||
|
||||
|
|
|
@ -56,8 +56,9 @@ func TestCore_EnableAudit(t *testing.T) {
|
|||
}
|
||||
|
||||
me := &MountEntry{
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
Table: auditTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err := c.enableAudit(me)
|
||||
if err != nil {
|
||||
|
@ -115,8 +116,9 @@ func TestCore_DisableAudit(t *testing.T) {
|
|||
}
|
||||
|
||||
me := &MountEntry{
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
Table: auditTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err = c.enableAudit(me)
|
||||
if err != nil {
|
||||
|
@ -196,6 +198,9 @@ func verifyDefaultAuditTable(t *testing.T, table *MountTable) {
|
|||
if len(table.Entries) != 0 {
|
||||
t.Fatalf("bad: %v", table.Entries)
|
||||
}
|
||||
if table.Type != auditTableType {
|
||||
t.Fatalf("bad: %v", *table)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuditBroker_LogRequest(t *testing.T) {
|
||||
|
|
|
@ -22,6 +22,10 @@ const (
|
|||
|
||||
// credentialRoutePrefix is the mount prefix used for the router
|
||||
credentialRoutePrefix = "auth/"
|
||||
|
||||
// credentialTableType is the value we expect to find for the credential
|
||||
// table and corresponding entries
|
||||
credentialTableType = "auth"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -210,6 +214,26 @@ func (c *Core) loadCredentials() error {
|
|||
|
||||
// Done if we have restored the auth table
|
||||
if c.auth != nil {
|
||||
needPersist := false
|
||||
|
||||
// Upgrade to typed auth table
|
||||
if c.auth.Type == "" {
|
||||
c.auth.Type = credentialTableType
|
||||
needPersist = true
|
||||
}
|
||||
|
||||
// Upgrade to table-scoped entries
|
||||
for _, entry := range c.auth.Entries {
|
||||
if entry.Table == "" {
|
||||
entry.Table = c.auth.Type
|
||||
needPersist = true
|
||||
}
|
||||
}
|
||||
|
||||
if needPersist {
|
||||
return c.persistAuth(c.auth)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -224,6 +248,25 @@ func (c *Core) loadCredentials() error {
|
|||
|
||||
// persistAuth is used to persist the auth table after modification
|
||||
func (c *Core) persistAuth(table *MountTable) error {
|
||||
if table.Type != credentialTableType {
|
||||
c.logger.Printf(
|
||||
"[ERR] core: given table to persist has type %s but need type %s",
|
||||
table.Type,
|
||||
credentialTableType)
|
||||
return fmt.Errorf("invalid table type given, not persisting")
|
||||
}
|
||||
|
||||
for _, entry := range table.Entries {
|
||||
if entry.Table != table.Type {
|
||||
c.logger.Printf(
|
||||
"[ERR] core: entry in auth table with path %s has table value %s but is in table %s, refusing to persist",
|
||||
entry.Path,
|
||||
entry.Table,
|
||||
table.Type)
|
||||
return fmt.Errorf("invalid auth entry found, not persisting")
|
||||
}
|
||||
}
|
||||
|
||||
// Marshal the table
|
||||
raw, err := json.Marshal(table)
|
||||
if err != nil {
|
||||
|
@ -341,12 +384,15 @@ func (c *Core) newCredentialBackend(
|
|||
|
||||
// defaultAuthTable creates a default auth table
|
||||
func defaultAuthTable() *MountTable {
|
||||
table := &MountTable{}
|
||||
table := &MountTable{
|
||||
Type: credentialTableType,
|
||||
}
|
||||
tokenUUID, err := uuid.GenerateUUID()
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("could not generate UUID for default auth table token entry: %v", err))
|
||||
}
|
||||
tokenAuth := &MountEntry{
|
||||
Table: credentialTableType,
|
||||
Path: "token/",
|
||||
Type: "token",
|
||||
Description: "token based credentials",
|
||||
|
|
|
@ -41,8 +41,9 @@ func TestCore_EnableCredential(t *testing.T) {
|
|||
}
|
||||
|
||||
me := &MountEntry{
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
Table: credentialTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err := c.enableCredential(me)
|
||||
if err != nil {
|
||||
|
@ -86,8 +87,9 @@ func TestCore_EnableCredential_twice_409(t *testing.T) {
|
|||
}
|
||||
|
||||
me := &MountEntry{
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
Table: credentialTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err := c.enableCredential(me)
|
||||
if err != nil {
|
||||
|
@ -109,8 +111,9 @@ func TestCore_EnableCredential_twice_409(t *testing.T) {
|
|||
func TestCore_EnableCredential_Token(t *testing.T) {
|
||||
c, _, _ := TestCoreUnsealed(t)
|
||||
me := &MountEntry{
|
||||
Path: "foo",
|
||||
Type: "token",
|
||||
Table: credentialTableType,
|
||||
Path: "foo",
|
||||
Type: "token",
|
||||
}
|
||||
err := c.enableCredential(me)
|
||||
if err.Error() != "token credential backend cannot be instantiated" {
|
||||
|
@ -130,8 +133,9 @@ func TestCore_DisableCredential(t *testing.T) {
|
|||
}
|
||||
|
||||
me := &MountEntry{
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
Table: credentialTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err = c.enableCredential(me)
|
||||
if err != nil {
|
||||
|
@ -188,8 +192,9 @@ func TestCore_DisableCredential_Cleanup(t *testing.T) {
|
|||
}
|
||||
|
||||
me := &MountEntry{
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
Table: credentialTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err := c.enableCredential(me)
|
||||
if err != nil {
|
||||
|
@ -260,6 +265,9 @@ func verifyDefaultAuthTable(t *testing.T, table *MountTable) {
|
|||
if len(table.Entries) != 1 {
|
||||
t.Fatalf("bad: %v", table.Entries)
|
||||
}
|
||||
if table.Type != credentialTableType {
|
||||
t.Fatalf("bad: %v", *table)
|
||||
}
|
||||
for idx, entry := range table.Entries {
|
||||
switch idx {
|
||||
case 0:
|
||||
|
|
|
@ -1002,6 +1002,7 @@ func (b *SystemBackend) handleEnableAuth(
|
|||
|
||||
// Create the mount entry
|
||||
me := &MountEntry{
|
||||
Table: credentialTableType,
|
||||
Path: path,
|
||||
Type: logicalType,
|
||||
Description: description,
|
||||
|
@ -1170,6 +1171,7 @@ func (b *SystemBackend) handleEnableAudit(
|
|||
|
||||
// Create the mount entry
|
||||
me := &MountEntry{
|
||||
Table: auditTableType,
|
||||
Path: path,
|
||||
Type: backendType,
|
||||
Description: description,
|
||||
|
|
|
@ -26,7 +26,8 @@ const (
|
|||
// system logical backend.
|
||||
systemBarrierPrefix = "sys/"
|
||||
|
||||
// mountTableType is the value we expect to find for the mount table and corresponding entries
|
||||
// mountTableType is the value we expect to find for the mount table and
|
||||
// corresponding entries
|
||||
mountTableType = "mounts"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/audit"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
|
@ -327,19 +328,73 @@ func TestDefaultMountTable(t *testing.T) {
|
|||
func TestCore_MountTable_UpgradeToTyped(t *testing.T) {
|
||||
c, _, _ := TestCoreUnsealed(t)
|
||||
|
||||
c.auditBackends["noop"] = func(config *audit.BackendConfig) (audit.Backend, error) {
|
||||
return &NoopAudit{
|
||||
Config: config,
|
||||
}, nil
|
||||
}
|
||||
|
||||
me := &MountEntry{
|
||||
Table: auditTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err := c.enableAudit(me)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
c.credentialBackends["noop"] = func(*logical.BackendConfig) (logical.Backend, error) {
|
||||
return &NoopBackend{}, nil
|
||||
}
|
||||
|
||||
me = &MountEntry{
|
||||
Table: credentialTableType,
|
||||
Path: "foo",
|
||||
Type: "noop",
|
||||
}
|
||||
err = c.enableCredential(me)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
testCore_MountTable_UpgradeToTyped_Common(t, c, "mounts")
|
||||
testCore_MountTable_UpgradeToTyped_Common(t, c, "audits")
|
||||
testCore_MountTable_UpgradeToTyped_Common(t, c, "credentials")
|
||||
}
|
||||
|
||||
func testCore_MountTable_UpgradeToTyped_Common(
|
||||
t *testing.T,
|
||||
c *Core,
|
||||
testType string) {
|
||||
|
||||
var path string
|
||||
var mt *MountTable
|
||||
switch testType {
|
||||
case "mounts":
|
||||
path = coreMountConfigPath
|
||||
mt = c.mounts
|
||||
case "audits":
|
||||
path = coreAuditConfigPath
|
||||
mt = c.audit
|
||||
case "credentials":
|
||||
path = coreAuthConfigPath
|
||||
mt = c.auth
|
||||
}
|
||||
|
||||
// Save the expected table
|
||||
goodJson, err := json.Marshal(c.mounts)
|
||||
goodJson, err := json.Marshal(mt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Create a pre-typed version
|
||||
c.mounts.Type = ""
|
||||
for _, entry := range c.mounts.Entries {
|
||||
mt.Type = ""
|
||||
for _, entry := range mt.Entries {
|
||||
entry.Table = ""
|
||||
}
|
||||
|
||||
raw, err := json.Marshal(c.mounts)
|
||||
raw, err := json.Marshal(mt)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -349,20 +404,35 @@ func TestCore_MountTable_UpgradeToTyped(t *testing.T) {
|
|||
}
|
||||
|
||||
entry := &Entry{
|
||||
Key: coreMountConfigPath,
|
||||
Key: path,
|
||||
Value: raw,
|
||||
}
|
||||
if err := c.barrier.Put(entry); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var persistFunc func(*MountTable) error
|
||||
|
||||
// It should load successfully and be upgraded and persisted
|
||||
err = c.loadMounts()
|
||||
switch testType {
|
||||
case "mounts":
|
||||
err = c.loadMounts()
|
||||
persistFunc = c.persistMounts
|
||||
mt = c.mounts
|
||||
case "credentials":
|
||||
err = c.loadCredentials()
|
||||
persistFunc = c.persistAuth
|
||||
mt = c.auth
|
||||
case "audits":
|
||||
err = c.loadAudits()
|
||||
persistFunc = c.persistAudit
|
||||
mt = c.audit
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
entry, err = c.barrier.Get(coreMountConfigPath)
|
||||
entry, err = c.barrier.Get(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -372,20 +442,23 @@ func TestCore_MountTable_UpgradeToTyped(t *testing.T) {
|
|||
}
|
||||
|
||||
// Now try saving invalid versions
|
||||
c.mounts.Type = "auth"
|
||||
if err := c.persistMounts(c.mounts); err == nil {
|
||||
origTableType := mt.Type
|
||||
mt.Type = "foo"
|
||||
if err := persistFunc(mt); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
|
||||
c.mounts.Type = mountTableType
|
||||
c.mounts.Entries[0].Table = "foobar"
|
||||
if err := c.persistMounts(c.mounts); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
if len(mt.Entries) > 0 {
|
||||
mt.Type = origTableType
|
||||
mt.Entries[0].Table = "bar"
|
||||
if err := persistFunc(mt); err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
|
||||
c.mounts.Entries[0].Table = c.mounts.Type
|
||||
if err := c.persistMounts(c.mounts); err != nil {
|
||||
t.Fatal(err)
|
||||
mt.Entries[0].Table = mt.Type
|
||||
if err := persistFunc(mt); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,7 @@ func TestCoreWithTokenStore(t *testing.T) (*Core, *TokenStore, []byte, string) {
|
|||
c, key, root := TestCoreUnsealed(t)
|
||||
|
||||
me := &MountEntry{
|
||||
Table: credentialTableType,
|
||||
Path: "token/",
|
||||
Type: "token",
|
||||
Description: "token based credentials",
|
||||
|
@ -184,7 +185,7 @@ func TestCoreWithTokenStore(t *testing.T) (*Core, *TokenStore, []byte, string) {
|
|||
ts := tokenstore.(*TokenStore)
|
||||
|
||||
router := NewRouter()
|
||||
router.Mount(ts, "auth/token/", &MountEntry{UUID: ""}, ts.view)
|
||||
router.Mount(ts, "auth/token/", &MountEntry{Table: credentialTableType, UUID: ""}, ts.view)
|
||||
|
||||
subview := c.systemBarrierView.SubView(expirationSubPath)
|
||||
logger := log.New(os.Stderr, "", log.LstdFlags)
|
||||
|
|
Loading…
Reference in New Issue