Merge pull request #2682 from hashicorp/skip-init
Add logic to skip initialization in some cases and some invalidation logic
This commit is contained in:
commit
051f670b19
|
@ -72,6 +72,8 @@ func Backend(conf *logical.BackendConfig) (*framework.Backend, error) {
|
|||
AuthRenew: b.pathLoginRenew,
|
||||
|
||||
Init: b.initialize,
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
|
||||
b.view = conf.StorageView
|
||||
|
@ -91,6 +93,7 @@ type backend struct {
|
|||
func (b *backend) initialize() error {
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA1Hash,
|
||||
Location: salt.DefaultLocation,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -174,6 +177,14 @@ func (b *backend) upgradeToSalted(view logical.Storage) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case salt.DefaultLocation:
|
||||
// reread the salt
|
||||
b.initialize()
|
||||
}
|
||||
}
|
||||
|
||||
const backendHelp = `
|
||||
The App ID credential provider is used to perform authentication from
|
||||
within applications or machine by pairing together two hard-to-guess
|
||||
|
|
|
@ -15,6 +15,7 @@ type backend struct {
|
|||
// The salt value to be used by the information to be accessed only
|
||||
// by this backend.
|
||||
salt *salt.Salt
|
||||
saltMutex sync.RWMutex
|
||||
|
||||
// The view to use when creating the salt
|
||||
view logical.Storage
|
||||
|
@ -93,13 +94,17 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
},
|
||||
),
|
||||
Init: b.initialize,
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *backend) initialize() error {
|
||||
b.saltMutex.Lock()
|
||||
defer b.saltMutex.Unlock()
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
Location: salt.DefaultLocation,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -108,6 +113,14 @@ func (b *backend) initialize() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case salt.DefaultLocation:
|
||||
// reread the salt
|
||||
b.initialize()
|
||||
}
|
||||
}
|
||||
|
||||
// periodicFunc of the backend will be invoked once a minute by the RollbackManager.
|
||||
// RoleRole backend utilizes this function to delete expired SecretID entries.
|
||||
// This could mean that the SecretID may live in the backend upto 1 min after its
|
||||
|
|
|
@ -1939,7 +1939,9 @@ func (b *backend) setRoleIDEntry(s logical.Storage, roleID string, roleIDEntry *
|
|||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
b.saltMutex.RLock()
|
||||
entryIndex := "role_id/" + b.salt.SaltID(roleID)
|
||||
b.saltMutex.RUnlock()
|
||||
|
||||
entry, err := logical.StorageEntryJSON(entryIndex, roleIDEntry)
|
||||
if err != nil {
|
||||
|
@ -1963,7 +1965,9 @@ func (b *backend) roleIDEntry(s logical.Storage, roleID string) (*roleIDStorageE
|
|||
|
||||
var result roleIDStorageEntry
|
||||
|
||||
b.saltMutex.RLock()
|
||||
entryIndex := "role_id/" + b.salt.SaltID(roleID)
|
||||
b.saltMutex.RUnlock()
|
||||
|
||||
if entry, err := s.Get(entryIndex); err != nil {
|
||||
return nil, err
|
||||
|
@ -1987,7 +1991,9 @@ func (b *backend) roleIDEntryDelete(s logical.Storage, roleID string) error {
|
|||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
b.saltMutex.RLock()
|
||||
entryIndex := "role_id/" + b.salt.SaltID(roleID)
|
||||
b.saltMutex.RUnlock()
|
||||
|
||||
return s.Delete(entryIndex)
|
||||
}
|
||||
|
|
|
@ -469,7 +469,9 @@ func (b *backend) secretIDAccessorEntry(s logical.Storage, secretIDAccessor stri
|
|||
var result secretIDAccessorStorageEntry
|
||||
|
||||
// Create index entry, mapping the accessor to the token ID
|
||||
b.saltMutex.RLock()
|
||||
entryIndex := "accessor/" + b.salt.SaltID(secretIDAccessor)
|
||||
b.saltMutex.RUnlock()
|
||||
|
||||
accessorLock := b.secretIDAccessorLock(secretIDAccessor)
|
||||
accessorLock.RLock()
|
||||
|
@ -498,7 +500,9 @@ func (b *backend) createSecretIDAccessorEntry(s logical.Storage, entry *secretID
|
|||
entry.SecretIDAccessor = accessorUUID
|
||||
|
||||
// Create index entry, mapping the accessor to the token ID
|
||||
b.saltMutex.RLock()
|
||||
entryIndex := "accessor/" + b.salt.SaltID(entry.SecretIDAccessor)
|
||||
b.saltMutex.RUnlock()
|
||||
|
||||
accessorLock := b.secretIDAccessorLock(accessorUUID)
|
||||
accessorLock.Lock()
|
||||
|
@ -517,7 +521,9 @@ func (b *backend) createSecretIDAccessorEntry(s logical.Storage, entry *secretID
|
|||
|
||||
// deleteSecretIDAccessorEntry deletes the storage index mapping the accessor to a SecretID.
|
||||
func (b *backend) deleteSecretIDAccessorEntry(s logical.Storage, secretIDAccessor string) error {
|
||||
b.saltMutex.RLock()
|
||||
accessorEntryIndex := "accessor/" + b.salt.SaltID(secretIDAccessor)
|
||||
b.saltMutex.RUnlock()
|
||||
|
||||
accessorLock := b.secretIDAccessorLock(secretIDAccessor)
|
||||
accessorLock.Lock()
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/hashicorp/vault/helper/salt"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
)
|
||||
|
@ -21,7 +20,6 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
|
|||
|
||||
type backend struct {
|
||||
*framework.Backend
|
||||
Salt *salt.Salt
|
||||
|
||||
// Used during initialization to set the salt
|
||||
view logical.Storage
|
||||
|
@ -105,24 +103,11 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
},
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
|
||||
Init: b.initialize,
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func (b *backend) initialize() error {
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Salt = salt
|
||||
return nil
|
||||
}
|
||||
|
||||
// periodicFunc performs the tasks that the backend wishes to do periodically.
|
||||
// Currently this will be triggered once in a minute by the RollbackManager.
|
||||
//
|
||||
|
|
|
@ -2,6 +2,7 @@ package ssh
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/vault/helper/salt"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
|
@ -12,6 +13,7 @@ type backend struct {
|
|||
*framework.Backend
|
||||
view logical.Storage
|
||||
salt *salt.Salt
|
||||
saltMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
|
||||
|
@ -57,14 +59,19 @@ func Backend(conf *logical.BackendConfig) (*backend, error) {
|
|||
secretOTP(&b),
|
||||
},
|
||||
|
||||
Init: b.Initialize,
|
||||
Init: b.initialize,
|
||||
|
||||
Invalidate: b.invalidate,
|
||||
}
|
||||
return &b, nil
|
||||
}
|
||||
|
||||
func (b *backend) Initialize() error {
|
||||
func (b *backend) initialize() error {
|
||||
b.saltMutex.Lock()
|
||||
defer b.saltMutex.Unlock()
|
||||
salt, err := salt.NewSalt(b.view, &salt.Config{
|
||||
HashFunc: salt.SHA256Hash,
|
||||
Location: salt.DefaultLocation,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -73,6 +80,14 @@ func (b *backend) Initialize() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *backend) invalidate(key string) {
|
||||
switch key {
|
||||
case salt.DefaultLocation:
|
||||
// reread the salt
|
||||
b.initialize()
|
||||
}
|
||||
}
|
||||
|
||||
const backendHelp = `
|
||||
The SSH backend generates credentials allowing clients to establish SSH
|
||||
connections to remote hosts.
|
||||
|
|
|
@ -207,6 +207,8 @@ func (b *backend) GenerateSaltedOTP() (string, string, error) {
|
|||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
b.saltMutex.RLock()
|
||||
defer b.saltMutex.RUnlock()
|
||||
return str, b.salt.SaltID(str), nil
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,9 @@ func (b *backend) pathVerifyWrite(req *logical.Request, d *framework.FieldData)
|
|||
// Create the salt of OTP because entry would have been create with the
|
||||
// salt and not directly of the OTP. Salt will yield the same value which
|
||||
// because the seed is the same, the backend salt.
|
||||
b.saltMutex.RLock()
|
||||
otpSalted := b.salt.SaltID(otp)
|
||||
b.saltMutex.RUnlock()
|
||||
|
||||
// Return nil if there is no entry found for the OTP
|
||||
otpEntry, err := b.getOTP(req.Storage, otpSalted)
|
||||
|
|
|
@ -33,6 +33,8 @@ func (b *backend) secretOTPRevoke(req *logical.Request, d *framework.FieldData)
|
|||
return nil, fmt.Errorf("secret is missing internal data")
|
||||
}
|
||||
|
||||
b.saltMutex.RLock()
|
||||
defer b.saltMutex.RUnlock()
|
||||
err := req.Storage.Delete("otp/" + b.salt.SaltID(otp))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -42,7 +42,7 @@ var (
|
|||
)
|
||||
|
||||
// enableCredential is used to enable a new credential backend
|
||||
func (c *Core) enableCredential(entry *MountEntry) error {
|
||||
func (c *Core) enableCredential(entry *MountEntry, skipInitialization bool) error {
|
||||
// Ensure we end the path in a slash
|
||||
if !strings.HasSuffix(entry.Path, "/") {
|
||||
entry.Path += "/"
|
||||
|
@ -99,9 +99,11 @@ func (c *Core) enableCredential(entry *MountEntry) error {
|
|||
return fmt.Errorf("nil backend returned from %q factory", entry.Type)
|
||||
}
|
||||
|
||||
if !skipInitialization {
|
||||
if err := backend.Initialize(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Update the auth table
|
||||
newTable := c.auth.shallowClone()
|
||||
|
|
|
@ -1210,7 +1210,7 @@ func (b *SystemBackend) handleMount(
|
|||
}
|
||||
|
||||
// Attempt mount
|
||||
if err := b.Core.mount(me); err != nil {
|
||||
if err := b.Core.mount(me, false); err != nil {
|
||||
b.Backend.Logger().Error("sys: mount failed", "path", me.Path, "error", err)
|
||||
return handleError(err)
|
||||
}
|
||||
|
@ -1642,7 +1642,7 @@ func (b *SystemBackend) handleEnableAuth(
|
|||
}
|
||||
|
||||
// Attempt enabling
|
||||
if err := b.Core.enableCredential(me); err != nil {
|
||||
if err := b.Core.enableCredential(me, false); err != nil {
|
||||
b.Backend.Logger().Error("sys: enable auth mount failed", "path", me.Path, "error", err)
|
||||
return handleError(err)
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ func (e *MountEntry) Clone() *MountEntry {
|
|||
}
|
||||
|
||||
// Mount is used to mount a new backend to the mount table.
|
||||
func (c *Core) mount(entry *MountEntry) error {
|
||||
func (c *Core) mount(entry *MountEntry, skipInitialization bool) error {
|
||||
// Ensure we end the path in a slash
|
||||
if !strings.HasSuffix(entry.Path, "/") {
|
||||
entry.Path += "/"
|
||||
|
@ -219,9 +219,11 @@ func (c *Core) mount(entry *MountEntry) error {
|
|||
|
||||
// Call initialize; this takes care of init tasks that must be run after
|
||||
// the ignore paths are collected
|
||||
if !skipInitialization {
|
||||
if err := backend.Initialize(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
newTable := c.mounts.shallowClone()
|
||||
newTable.Entries = append(newTable.Entries, entry)
|
||||
|
|
Loading…
Reference in a new issue