a581e96b78
* Lazy load plugins to avoid setup-unwrap cycle * Remove commented blocks * Refactor NewTestCluster, use single core cluster on basic plugin tests * Set c.pluginDirectory in TestAddTestPlugin for setupPluginCatalog to work properly * Add special path to mock plugin * Move ensureCoresSealed to vault/testing.go * Use same method for EnsureCoresSealed and Cleanup * Bump ensureCoresSealed timeout to 60s * Correctly handle nil opts on NewTestCluster * Add metadata flag to APIClientMeta, use meta-enabled plugin when mounting to bootstrap * Check metadata flag directly on the plugin process * Plumb isMetadataMode down to PluginRunner * Add NOOP shims when running in metadata mode * Remove unused flag from the APIMetadata object * Remove setupSecretPlugins and setupCredentialPlugins functions * Move when we setup rollback manager to after the plugins are initialized * Fix tests * Fix merge issue * start rollback manager after the credential setup * Add guards against running certain client and server functions while in metadata mode * Call initialize once a plugin is loaded on the fly * Add more tests, update basic secret/auth plugin tests to trigger lazy loading * Skip mount if plugin removed from catalog * Fixup * Remove commented line on LookupPlugin * Fail on mount operation if plugin is re-added to catalog and mount is on existing path * Check type and special paths on startBackend * Fix merge conflicts * Refactor PluginRunner run methods to use runCommon, fix TestSystemBackend_Plugin_auth
147 lines
3.8 KiB
Go
147 lines
3.8 KiB
Go
package vault
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/hashicorp/errwrap"
|
|
|
|
"github.com/hashicorp/vault/helper/consts"
|
|
"github.com/hashicorp/vault/helper/pluginutil"
|
|
"github.com/hashicorp/vault/helper/wrapping"
|
|
"github.com/hashicorp/vault/logical"
|
|
)
|
|
|
|
type dynamicSystemView struct {
|
|
core *Core
|
|
mountEntry *MountEntry
|
|
}
|
|
|
|
func (d dynamicSystemView) DefaultLeaseTTL() time.Duration {
|
|
def, _ := d.fetchTTLs()
|
|
return def
|
|
}
|
|
|
|
func (d dynamicSystemView) MaxLeaseTTL() time.Duration {
|
|
_, max := d.fetchTTLs()
|
|
return max
|
|
}
|
|
|
|
func (d dynamicSystemView) SudoPrivilege(path string, token string) bool {
|
|
// Resolve the token policy
|
|
te, err := d.core.tokenStore.Lookup(token)
|
|
if err != nil {
|
|
d.core.logger.Error("core: failed to lookup token", "error", err)
|
|
return false
|
|
}
|
|
|
|
// Ensure the token is valid
|
|
if te == nil {
|
|
d.core.logger.Error("entry not found for given token")
|
|
return false
|
|
}
|
|
|
|
// Construct the corresponding ACL object
|
|
acl, err := d.core.policyStore.ACL(te.Policies...)
|
|
if err != nil {
|
|
d.core.logger.Error("failed to retrieve ACL for token's policies", "token_policies", te.Policies, "error", err)
|
|
return false
|
|
}
|
|
|
|
// The operation type isn't important here as this is run from a path the
|
|
// user has already been given access to; we only care about whether they
|
|
// have sudo
|
|
req := new(logical.Request)
|
|
req.Operation = logical.ReadOperation
|
|
req.Path = path
|
|
_, rootPrivs := acl.AllowOperation(req)
|
|
return rootPrivs
|
|
}
|
|
|
|
// TTLsByPath returns the default and max TTLs corresponding to a particular
|
|
// mount point, or the system default
|
|
func (d dynamicSystemView) fetchTTLs() (def, max time.Duration) {
|
|
def = d.core.defaultLeaseTTL
|
|
max = d.core.maxLeaseTTL
|
|
|
|
if d.mountEntry.Config.DefaultLeaseTTL != 0 {
|
|
def = d.mountEntry.Config.DefaultLeaseTTL
|
|
}
|
|
if d.mountEntry.Config.MaxLeaseTTL != 0 {
|
|
max = d.mountEntry.Config.MaxLeaseTTL
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// Tainted indicates that the mount is in the process of being removed
|
|
func (d dynamicSystemView) Tainted() bool {
|
|
return d.mountEntry.Tainted
|
|
}
|
|
|
|
// CachingDisabled indicates whether to use caching behavior
|
|
func (d dynamicSystemView) CachingDisabled() bool {
|
|
return d.core.cachingDisabled || (d.mountEntry != nil && d.mountEntry.Config.ForceNoCache)
|
|
}
|
|
|
|
// Checks if this is a primary Vault instance.
|
|
func (d dynamicSystemView) ReplicationState() consts.ReplicationState {
|
|
var state consts.ReplicationState
|
|
d.core.clusterParamsLock.RLock()
|
|
state = d.core.replicationState
|
|
d.core.clusterParamsLock.RUnlock()
|
|
return state
|
|
}
|
|
|
|
// ResponseWrapData wraps the given data in a cubbyhole and returns the
|
|
// token used to unwrap.
|
|
func (d dynamicSystemView) ResponseWrapData(data map[string]interface{}, ttl time.Duration, jwt bool) (*wrapping.ResponseWrapInfo, error) {
|
|
req := &logical.Request{
|
|
Operation: logical.CreateOperation,
|
|
Path: "sys/wrapping/wrap",
|
|
}
|
|
|
|
resp := &logical.Response{
|
|
WrapInfo: &wrapping.ResponseWrapInfo{
|
|
TTL: ttl,
|
|
},
|
|
Data: data,
|
|
}
|
|
|
|
if jwt {
|
|
resp.WrapInfo.Format = "jwt"
|
|
}
|
|
|
|
_, err := d.core.wrapInCubbyhole(req, resp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return resp.WrapInfo, nil
|
|
}
|
|
|
|
// LookupPlugin looks for a plugin with the given name in the plugin catalog. It
|
|
// returns a PluginRunner or an error if no plugin was found.
|
|
func (d dynamicSystemView) LookupPlugin(name string) (*pluginutil.PluginRunner, error) {
|
|
if d.core == nil {
|
|
return nil, fmt.Errorf("system view core is nil")
|
|
}
|
|
if d.core.pluginCatalog == nil {
|
|
return nil, fmt.Errorf("system view core plugin catalog is nil")
|
|
}
|
|
r, err := d.core.pluginCatalog.Get(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if r == nil {
|
|
return nil, errwrap.Wrapf(fmt.Sprintf("{{err}}: %s", name), ErrPluginNotFound)
|
|
}
|
|
|
|
return r, nil
|
|
}
|
|
|
|
// MlockEnabled returns the configuration setting for enabling mlock on plugins.
|
|
func (d dynamicSystemView) MlockEnabled() bool {
|
|
return d.core.enableMlock
|
|
}
|