Skip to content

Commit

Permalink
Refactor PluginRunner run methods to use runCommon, fix TestSystemBac…
Browse files Browse the repository at this point in the history
…kend_Plugin_auth
  • Loading branch information
calvn committed Sep 1, 2017
1 parent c11d37b commit 8f4f047
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 53 deletions.
93 changes: 42 additions & 51 deletions helper/pluginutil/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pluginutil

import (
"crypto/sha256"
"crypto/tls"
"flag"
"fmt"
"os/exec"
Expand Down Expand Up @@ -49,90 +50,80 @@ type PluginRunner struct {
// returns a configured plugin.Client with TLS Configured and a wrapping token set
// on PluginUnwrapTokenEnv for plugin process consumption.
func (r *PluginRunner) Run(wrapper RunnerUtil, pluginMap map[string]plugin.Plugin, hs plugin.HandshakeConfig, env []string, logger log.Logger) (*plugin.Client, error) {
// Get a CA TLS Certificate
certBytes, key, err := generateCert()
if err != nil {
return nil, err
}
return r.runCommon(wrapper, pluginMap, hs, env, logger, false)
}

// Use CA to sign a client cert and return a configured TLS config
clientTLSConfig, err := createClientTLSConfig(certBytes, key)
if err != nil {
return nil, err
}
// RunMetadataMode returns a configured plugin.Client that will dispense a plugin
// in metadata mode. The PluginMetadaModeEnv is passed in as part of the Cmd to
// plugin.Client, and consumed by the plugin process on pluginutil.VaultPluginTLSProvider.
func (r *PluginRunner) RunMetadataMode(wrapper RunnerUtil, pluginMap map[string]plugin.Plugin, hs plugin.HandshakeConfig, env []string, logger log.Logger) (*plugin.Client, error) {
return r.runCommon(wrapper, pluginMap, hs, env, logger, true)

// Use CA to sign a server cert and wrap the values in a response wrapped
// token.
wrapToken, err := wrapServerConfig(wrapper, certBytes, key)
if err != nil {
return nil, err
}
}

func (r *PluginRunner) runCommon(wrapper RunnerUtil, pluginMap map[string]plugin.Plugin, hs plugin.HandshakeConfig, env []string, logger log.Logger, isMetadataMode bool) (*plugin.Client, error) {
cmd := exec.Command(r.Command, r.Args...)
cmd.Env = append(cmd.Env, env...)
// Add the response wrap token to the ENV of the plugin
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginUnwrapTokenEnv, wrapToken))
// Add the metadata mode ENV and set it to false
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginMetadaModeEnv, "false"))

// Add the mlock setting to the ENV of the plugin
if wrapper.MlockEnabled() {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginMlockEnabled, "true"))
}

secureConfig := &plugin.SecureConfig{
Checksum: r.Sha256,
Hash: sha256.New(),
}

// Create logger for the plugin client
clogger := &hclogFaker{
logger: logger,
}
namedLogger := clogger.ResetNamed("plugin")

client := plugin.NewClient(&plugin.ClientConfig{
HandshakeConfig: hs,
Plugins: pluginMap,
Cmd: cmd,
TLSConfig: clientTLSConfig,
SecureConfig: secureConfig,
Logger: namedLogger,
})
var clientTLSConfig *tls.Config
if !isMetadataMode {
// Add the metadata mode ENV and set it to false
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginMetadaModeEnv, "false"))

return client, nil
}
// Get a CA TLS Certificate
certBytes, key, err := generateCert()
if err != nil {
return nil, err
}

func (r *PluginRunner) RunMetadataMode(wrapper RunnerUtil, pluginMap map[string]plugin.Plugin, hs plugin.HandshakeConfig, env []string, logger log.Logger) (*plugin.Client, error) {
cmd := exec.Command(r.Command, r.Args...)
cmd.Env = append(cmd.Env, env...)
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginMetadaModeEnv, "true"))
// Use CA to sign a client cert and return a configured TLS config
clientTLSConfig, err = createClientTLSConfig(certBytes, key)
if err != nil {
return nil, err
}

// Add the mlock setting to the ENV of the plugin
if wrapper.MlockEnabled() {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginMlockEnabled, "true"))
// Use CA to sign a server cert and wrap the values in a response wrapped
// token.
wrapToken, err := wrapServerConfig(wrapper, certBytes, key)
if err != nil {
return nil, err
}

// Add the response wrap token to the ENV of the plugin
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginUnwrapTokenEnv, wrapToken))
} else {
namedLogger = clogger.ResetNamed("plugin.metadata")
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", PluginMetadaModeEnv, "true"))
}

secureConfig := &plugin.SecureConfig{
Checksum: r.Sha256,
Hash: sha256.New(),
}

// Create logger for the plugin client
clogger := &hclogFaker{
logger: logger,
}
namedLogger := clogger.ResetNamed("plugin.metadata")

client := plugin.NewClient(&plugin.ClientConfig{
clientConfig := &plugin.ClientConfig{
HandshakeConfig: hs,
Plugins: pluginMap,
Cmd: cmd,
SecureConfig: secureConfig,
TLSConfig: clientTLSConfig,
Logger: namedLogger,
})
}

return client, nil
client := plugin.NewClient(clientConfig)

return client, nil
}

type APIClientMeta struct {
Expand Down
2 changes: 1 addition & 1 deletion logical/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (b *BackendPluginClient) Cleanup() {
// NewBackend will return an instance of an RPC-based client implementation of the backend for
// external plugins, or a concrete implementation of the backend if it is a builtin backend.
// The backend is returned as a logical.Backend interface. The isMetadataMode param determines whether
// the plugin should run with the -metadata flag.
// the plugin should run in metadata mode.
func NewBackend(pluginName string, sys pluginutil.LookRunnerUtil, logger log.Logger, isMetadataMode bool) (logical.Backend, error) {
// Look for plugin in the plugin catalog
pluginRunner, err := sys.LookupPlugin(pluginName)
Expand Down
2 changes: 1 addition & 1 deletion vault/logical_system_integ_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func TestSystemBackend_Plugin_auth(t *testing.T) {
core := cluster.Cores[0]

// Make a request to lazy load the plugin
req := logical.TestRequest(t, logical.ReadOperation, "mock-0/internal")
req := logical.TestRequest(t, logical.ReadOperation, "auth/mock-0/internal")
req.ClientToken = core.Client.Token()
resp, err := core.HandleRequest(req)
if err != nil {
Expand Down

0 comments on commit 8f4f047

Please sign in to comment.