mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-03 20:17:59 +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 {
 | 
			
		||||
@@ -240,6 +269,8 @@ func (c *ServerCommand) Run(args []string) int {
 | 
			
		||||
		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
 | 
			
		||||
}
 | 
			
		||||
@@ -382,6 +388,8 @@ type CoreConfig struct {
 | 
			
		||||
	EnableUI bool `json:"ui" structs:"ui" mapstructure:"ui"`
 | 
			
		||||
 | 
			
		||||
	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
 | 
			
		||||
	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 {
 | 
			
		||||
		return nil, fmt.Errorf("no plugin found with name: %s", name)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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