mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 19:17:58 +00:00
Execute builtin plugins
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
@@ -131,6 +133,33 @@ func (c *ServerCommand) Run(args []string) int {
|
||||
dev = true
|
||||
}
|
||||
|
||||
// Record the vault binary's location and SHA-256 checksum for use in
|
||||
// builtin plugins.
|
||||
ex, err := os.Executable()
|
||||
if err != nil {
|
||||
c.Ui.Output(fmt.Sprintf(
|
||||
"Error looking up vault binary: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
file, err := os.Open(ex)
|
||||
if err != nil {
|
||||
c.Ui.Output(fmt.Sprintf(
|
||||
"Error loading vault binary: %s", err))
|
||||
return 1
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
hash := sha256.New()
|
||||
_, err = io.Copy(hash, file)
|
||||
if err != nil {
|
||||
c.Ui.Output(fmt.Sprintf(
|
||||
"Error checksumming vault binary: %s", err))
|
||||
return 1
|
||||
}
|
||||
|
||||
sha256Value := hash.Sum(nil)
|
||||
|
||||
// Validation
|
||||
if !dev {
|
||||
switch {
|
||||
@@ -225,21 +254,23 @@ func (c *ServerCommand) Run(args []string) int {
|
||||
}
|
||||
|
||||
coreConfig := &vault.CoreConfig{
|
||||
Physical: backend,
|
||||
RedirectAddr: config.Backend.RedirectAddr,
|
||||
HAPhysical: nil,
|
||||
Seal: seal,
|
||||
AuditBackends: c.AuditBackends,
|
||||
CredentialBackends: c.CredentialBackends,
|
||||
LogicalBackends: c.LogicalBackends,
|
||||
Logger: c.logger,
|
||||
DisableCache: config.DisableCache,
|
||||
DisableMlock: config.DisableMlock,
|
||||
MaxLeaseTTL: config.MaxLeaseTTL,
|
||||
DefaultLeaseTTL: config.DefaultLeaseTTL,
|
||||
ClusterName: config.ClusterName,
|
||||
CacheSize: config.CacheSize,
|
||||
PluginDirectory: config.PluginDirectory,
|
||||
Physical: backend,
|
||||
RedirectAddr: config.Backend.RedirectAddr,
|
||||
HAPhysical: nil,
|
||||
Seal: seal,
|
||||
AuditBackends: c.AuditBackends,
|
||||
CredentialBackends: c.CredentialBackends,
|
||||
LogicalBackends: c.LogicalBackends,
|
||||
Logger: c.logger,
|
||||
DisableCache: config.DisableCache,
|
||||
DisableMlock: config.DisableMlock,
|
||||
MaxLeaseTTL: config.MaxLeaseTTL,
|
||||
DefaultLeaseTTL: config.DefaultLeaseTTL,
|
||||
ClusterName: config.ClusterName,
|
||||
CacheSize: config.CacheSize,
|
||||
PluginDirectory: config.PluginDirectory,
|
||||
VaultBinaryLocation: ex,
|
||||
VaultBinarySHA256: sha256Value,
|
||||
}
|
||||
if dev {
|
||||
coreConfig.DevToken = devRootTokenID
|
||||
@@ -252,7 +283,7 @@ func (c *ServerCommand) Run(args []string) int {
|
||||
"Error getting user's home directory: %v", err))
|
||||
return 1
|
||||
}
|
||||
coreConfig.PluginDirectory = filepath.Join(homePath, "/vault-plugins/")
|
||||
coreConfig.PluginDirectory = filepath.Join(homePath, "/.vault-plugins/")
|
||||
}
|
||||
|
||||
var disableClustering bool
|
||||
|
||||
@@ -335,6 +335,12 @@ type Core struct {
|
||||
// pluginDirectory is the location vault will look for plugins
|
||||
pluginDirectory string
|
||||
|
||||
// vaultBinaryLocation is used to run builtin plugins in secure mode
|
||||
vaultBinaryLocation string
|
||||
|
||||
// vaultBinarySHA256 is used to run builtin plugins in secure mode
|
||||
vaultBinarySHA256 []byte
|
||||
|
||||
// pluginCatalog is used to manage plugin configurations
|
||||
pluginCatalog *PluginCatalog
|
||||
}
|
||||
@@ -381,7 +387,9 @@ type CoreConfig struct {
|
||||
|
||||
EnableUI bool `json:"ui" structs:"ui" mapstructure:"ui"`
|
||||
|
||||
PluginDirectory string `json:"plugin_directory" structs:"plugin_directory" mapstructure:"plugin_directory"`
|
||||
PluginDirectory string `json:"plugin_directory" structs:"plugin_directory" mapstructure:"plugin_directory"`
|
||||
VaultBinaryLocation string `json:"vault_binary_location" structs:"vault_binary_location" mapstructure:"vault_binary_location"`
|
||||
VaultBinarySHA256 []byte `json:"vault_binary_sha256" structs:"vault_binary_sha256" mapstructure:"vault_binary_sha256"`
|
||||
|
||||
ReloadFuncs *map[string][]ReloadFunc
|
||||
ReloadFuncsLock *sync.RWMutex
|
||||
@@ -439,6 +447,8 @@ func NewCore(conf *CoreConfig) (*Core, error) {
|
||||
clusterName: conf.ClusterName,
|
||||
clusterListenerShutdownCh: make(chan struct{}),
|
||||
clusterListenerShutdownSuccessCh: make(chan struct{}),
|
||||
vaultBinaryLocation: conf.VaultBinaryLocation,
|
||||
vaultBinarySHA256: conf.VaultBinarySHA256,
|
||||
}
|
||||
|
||||
// Wrap the physical backend in a cache layer if enabled and not already wrapped
|
||||
|
||||
@@ -10,50 +10,62 @@ import (
|
||||
|
||||
"github.com/hashicorp/vault/helper/jsonutil"
|
||||
"github.com/hashicorp/vault/helper/pluginutil"
|
||||
"github.com/hashicorp/vault/helper/strutil"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
var (
|
||||
pluginCatalogPrefix = "plugin-catalog/"
|
||||
builtinPlugins = []string{"mysql-database-plugin", "postgres-database-plugin"}
|
||||
)
|
||||
|
||||
type PluginCatalog struct {
|
||||
catalogView *BarrierView
|
||||
directory string
|
||||
catalogView *BarrierView
|
||||
directory string
|
||||
vaultCommand string
|
||||
vaultSHA256 []byte
|
||||
|
||||
lock sync.RWMutex
|
||||
builtin map[string]*pluginutil.PluginRunner
|
||||
}
|
||||
|
||||
func NewPluginCatalog(view *BarrierView, directory string) *PluginCatalog {
|
||||
return &PluginCatalog{
|
||||
catalogView: view.SubView(pluginCatalogPrefix),
|
||||
directory: directory,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Core) setupPluginCatalog() error {
|
||||
catalog := NewPluginCatalog(c.systemBarrierView, c.pluginDirectory)
|
||||
c.pluginCatalog = catalog
|
||||
c.pluginCatalog = &PluginCatalog{
|
||||
catalogView: c.systemBarrierView.SubView(pluginCatalogPrefix),
|
||||
directory: c.pluginDirectory,
|
||||
vaultCommand: c.vaultBinaryLocation,
|
||||
vaultSHA256: c.vaultBinarySHA256,
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *PluginCatalog) Get(name string) (*pluginutil.PluginRunner, error) {
|
||||
// Look for external plugins in the barrier
|
||||
out, err := c.catalogView.Get(name)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to retrieve plugin \"%s\": %v", name, err)
|
||||
}
|
||||
if out == nil {
|
||||
if out != nil {
|
||||
entry := new(pluginutil.PluginRunner)
|
||||
if err := jsonutil.DecodeJSON(out.Value, entry); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode plugin entry: %v", err)
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
// Look for builtin plugins
|
||||
if !strutil.StrListContains(builtinPlugins, name) {
|
||||
return nil, fmt.Errorf("no plugin found with name: %s", name)
|
||||
}
|
||||
|
||||
entry := new(pluginutil.PluginRunner)
|
||||
if err := jsonutil.DecodeJSON(out.Value, entry); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode plugin entry: %v", err)
|
||||
}
|
||||
|
||||
return entry, nil
|
||||
return &pluginutil.PluginRunner{
|
||||
Name: name,
|
||||
Command: c.vaultCommand,
|
||||
Args: []string{"plugin-exec", name},
|
||||
Sha256: c.vaultSHA256,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *PluginCatalog) Set(name, command string, sha256 []byte) error {
|
||||
|
||||
Reference in New Issue
Block a user