Update config encrypt/decrypt CLI command (#309)

This updates the command to our emergent standards. It also enables
using a separate config file for a config kms, which allows non-string
values to be encrypted.

This allowed some nice cleanup as well.
pull/311/head
Jeff Mitchell 6 years ago committed by GitHub
parent 274afa6b02
commit 28df6eb7b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

2
.gitignore vendored

@ -122,6 +122,6 @@ internal/ui/assets.go
update-ui-assets*
# Test config file
test.hcl
test*.hcl
# vim: set filetype=conf :

@ -18,6 +18,7 @@ import (
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authtokens"
"github.com/hashicorp/boundary/internal/wrapper"
"github.com/hashicorp/boundary/recovery"
"github.com/mitchellh/cli"
"github.com/pkg/errors"
@ -183,10 +184,13 @@ func (c *Command) Client(opt ...Option) (*api.Client, error) {
tokenName := "default"
switch {
case c.FlagRecoveryConfig != "":
wrapper, err := recovery.GetWrapper(c.Context, c.FlagRecoveryConfig)
wrapper, err := wrapper.GetWrapper(c.FlagRecoveryConfig, "recovery")
if err != nil {
return nil, err
}
if wrapper == nil {
return nil, errors.New(`No "kms" block with purpose "recovery" found`)
}
if err := wrapper.Init(c.Context); err != nil {
return nil, fmt.Errorf("Error initializing kms: %w", err)
}
@ -284,11 +288,6 @@ func (c *Command) FlagSet(bit FlagSetBit) *FlagSets {
c.flagsOnce.Do(func() {
set := NewFlagSets(c.UI)
// These flag sets will apply to all leaf subcommands.
// TODO: Optional, but FlagSetHTTP can be safely removed from the individual
// Flags() subcommands.
bit = bit | FlagSetHTTP
if bit&FlagSetHTTP != 0 {
f := set.NewFlagSet("Connection Options")

@ -213,7 +213,13 @@ func (b *Server) PrintInfo(ui cli.Ui, mode string) {
}
// Server configuration output
padding := 36
padding := 0
for _, k := range b.InfoKeys {
currPadding := padding - len(k)
if currPadding < 2 {
padding = len(k) + 2
}
}
sort.Strings(b.InfoKeys)
ui.Output(fmt.Sprintf("==> Boundary %s configuration:\n", mode))
for _, k := range b.InfoKeys {

@ -144,12 +144,13 @@ func initCommands(ui, serverCmdUi cli.Ui, runOpts *RunOptions) {
"config encrypt": func() (cli.Command, error) {
return &config.EncryptDecryptCommand{
Command: base.NewCommand(ui),
Encrypt: true,
Func: "encrypt",
}, nil
},
"config decrypt": func() (cli.Command, error) {
return &config.EncryptDecryptCommand{
Command: base.NewCommand(ui),
Func: "decrypt",
}, nil
},

@ -1,8 +1,6 @@
package config
import (
"strings"
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/mitchellh/cli"
)
@ -18,23 +16,21 @@ func (c *Command) Synopsis() string {
}
func (c *Command) Help() string {
helpText := `
Usage: boundary config <subcommand> [options] [args]
This command groups subcommands for operators interacting with Boundary's
config files. Here are a few examples of config commands:
Encrypt sensitive values in a config file:
$ boundary config encrypt config.hcl
Decrypt sensitive values in a config file:
$ boundary config decrypt config.hcl
Please see the individual subcommand help for detailed usage information.`
return strings.TrimSpace(helpText)
return base.WrapForHelpText([]string{
"Usage: boundary config <subcommand> [options] [args]",
"",
" This command groups subcommands for operators interacting with Boundary's config files. Here are a few examples of config commands:",
"",
" Encrypt sensitive values in a config file:",
"",
" $ boundary config encrypt config.hcl",
"",
" Decrypt sensitive values in a config file:",
"",
" $ boundary config decrypt config.hcl",
"",
" Please see the individual subcommand help for detailed usage information.",
})
}
func (c *Command) Run(args []string) int {

@ -3,12 +3,13 @@ package config
import (
"fmt"
"io/ioutil"
"net/textproto"
"os"
"strings"
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/wrapper"
"github.com/hashicorp/shared-secure-libs/configutil"
"github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/mitchellh/cli"
"github.com/posener/complete"
)
@ -18,49 +19,82 @@ var _ cli.CommandAutocomplete = (*EncryptDecryptCommand)(nil)
type EncryptDecryptCommand struct {
*base.Command
Encrypt bool
Func string
flagConfig string
flagConfigKms string
flagOverwrite bool
flagStrip bool
}
func (c *EncryptDecryptCommand) Synopsis() string {
dir := "Decrypts"
if c.Encrypt {
dir = "Encrypts"
}
return fmt.Sprintf("%s sensitive values in Vault's configuration file", dir)
return fmt.Sprintf("%s sensitive values in Boundary's configuration file", textproto.CanonicalMIMEHeaderKey(c.Func))
}
func (c *EncryptDecryptCommand) Help() string {
subCmd := "Decrypt"
if c.Encrypt {
subCmd = "Encrypt"
}
helpText := `
Usage: boundary config %s [options] [args]
%s sensitive values in a Boundary's configuration file. These values must be marked
with {{%s()}} as appropriate. This can only be used with string parameters, and
the markers must be inside the quote marks delimiting the string; as an example:
foo = "{{encrypt(bar)}}"
By default this will print the new configuration out. To overwrite into the same
file use the -overwrite flag.
$ boundary config %s -overwrite config.hcl
`
helpText = fmt.Sprintf(helpText, strings.ToLower(subCmd), subCmd, strings.ToLower(subCmd), strings.ToLower(subCmd))
return strings.TrimSpace(helpText)
var args []string
args = append(args,
"Usage: boundary config {{func}} [options] [args]",
"",
" {{upperfunc}} sensitive values in a Boundary's configuration file. These values must be marked with {{{{func}}()}} as appropriate. Example:",
"",
` foo = "{{encrypt(bar)}}"`,
"",
" By default this will print out the new configuration. To overwrite into the same file use the -overwrite flag.",
"",
" $ boundary config {{func}} -overwrite config.hcl",
"",
` In order for this command to perform its task, a "kms" block must be defined within a configuration file. Example:`,
"",
` kms "aead" {`,
` purpose = "config"`,
` aead_type = "aes-gcm"`,
` key = "7xtkEoS5EXPbgynwd+dDLHopaCqK8cq0Rpep4eooaTs="`,
` }`,
"",
` The "kms" block can be defined in the configuration file or via the -config flag. If defined in the configuration file, only string parameters are supported, and the markers must be inside the quote marks delimiting the string. Additionally, if the block is defined inline, do NOT use an an "aead" block with the key defined in the configuration file as it provides no protection.`,
"",
"",
)
for i, line := range args {
args[i] =
strings.Replace(
strings.Replace(
line, "{{func}}", c.Func, -1,
),
"{{upperfunc}}", textproto.CanonicalMIMEHeaderKey(c.Func), -1,
)
}
return base.WrapForHelpText(args) + c.Flags().Help()
}
func (c *EncryptDecryptCommand) Flags() *base.FlagSets {
set := c.FlagSet(0)
set := c.FlagSet(base.FlagSetNone)
f := set.NewFlagSet("Command Options")
f.StringVar(&base.StringVar{
Name: "config-kms",
Target: &c.flagConfigKms,
Completion: complete.PredictOr(
complete.PredictFiles("*.hcl"),
complete.PredictFiles("*.json"),
),
Usage: `If specified, the given file will be parsed for a "kms" block with purpose "config" and will use it to perform the command. If not set, the command will expect a block inline with the configuration file, and will only be able to support quoted string parameters.`,
})
f.StringVar(&base.StringVar{
Name: "config",
Target: &c.flagConfig,
Completion: complete.PredictOr(
complete.PredictFiles("*.hcl"),
complete.PredictFiles("*.json"),
),
Usage: `The configuration file upon which to perform encryption or decryption`,
})
f.BoolVar(&base.BoolVar{
Name: "overwrite",
Target: &c.flagOverwrite,
@ -85,73 +119,61 @@ func (c *EncryptDecryptCommand) AutocompleteFlags() complete.Flags {
}
func (c *EncryptDecryptCommand) Run(args []string) (ret int) {
op := "decrypt"
if c.Encrypt {
op = "encrypt"
}
f := c.Flags()
if err := f.Parse(args); err != nil {
c.UI.Error(err.Error())
return 1
}
path := ""
args = f.Args()
switch len(args) {
case 1:
path = strings.TrimSpace(args[0])
default:
c.UI.Error(fmt.Sprintf("Incorrect arguments (expected 1, got %d)", len(args)))
switch c.flagConfig {
case "":
c.UI.Error(`Missing required parameter -config`)
return 1
default:
c.flagConfig = strings.TrimSpace(c.flagConfig)
}
if path == "" {
c.UI.Error("A configuration file must be specified")
return 1
kmsDefFile := c.flagConfig
switch c.flagConfigKms {
case "":
default:
kmsDefFile = strings.TrimSpace(c.flagConfigKms)
}
kmses, err := configutil.LoadConfigKMSes(path)
wrapper, err := wrapper.GetWrapper(kmsDefFile, "config")
if err != nil {
c.UI.Error(fmt.Errorf("Error loading configuration from %s: %w", path, err).Error())
c.UI.Error(err.Error())
return 1
}
var kms *configutil.KMS
for _, v := range kmses {
if strutil.StrListContains(v.Purpose, "config") {
if kms != nil {
c.UI.Error("Only one kms block marked for \"config\" purpose is allowed")
return 1
}
kms = v
}
}
if kms == nil {
c.UI.Error("No kms block with \"config\" purpose defined in the configuration file")
if wrapper == nil {
c.UI.Error(`No wrapper with "config" purpose found"`)
return 1
}
d, err := ioutil.ReadFile(path)
if err != nil {
c.UI.Error(fmt.Errorf("Error reading config file: %w", err).Error())
if err := wrapper.Init(c.Context); err != nil {
c.UI.Error(fmt.Errorf("Error initializing KMS: %w", err).Error())
return 1
}
defer func() {
if err := wrapper.Finalize(c.Context); err != nil {
c.UI.Warn(fmt.Errorf("Error encountered when finalizing KMS: %w", err).Error())
}
}()
raw := string(d)
wrapper, err := configutil.ConfigureWrapper(kms, nil, nil, nil)
d, err := ioutil.ReadFile(c.flagConfig)
if err != nil {
c.UI.Error(fmt.Errorf("Error creating kms: %w", err).Error())
c.UI.Error(fmt.Errorf("Error reading config file: %w", err).Error())
return 1
}
wrapper.Init(c.Context)
defer wrapper.Finalize(c.Context)
raw := string(d)
raw, err = configutil.EncryptDecrypt(raw, !c.Encrypt, c.flagStrip, wrapper)
raw, err = configutil.EncryptDecrypt(raw, c.Func == "decrypt", c.flagStrip, wrapper)
if err != nil {
c.UI.Error(fmt.Errorf("Error %sing via kms: %w", op, err).Error())
c.UI.Error(fmt.Errorf("Error %sing via kms: %w", c.Func, err).Error())
return 1
}
@ -160,7 +182,7 @@ func (c *EncryptDecryptCommand) Run(args []string) (ret int) {
return 0
}
file, err := os.Create(path)
file, err := os.Create(c.flagConfig)
if err != nil {
c.UI.Error(fmt.Errorf("Error opening file for writing: %w", err).Error())
return 1
@ -182,5 +204,5 @@ func (c *EncryptDecryptCommand) Run(args []string) (ret int) {
c.UI.Error(fmt.Sprintf("Wrong number of bytes written to file, expected %d, wrote %d", len(raw), n))
}
return 0
return
}

@ -15,31 +15,52 @@ import (
)
const (
configEncryptPath = "./fixtures/configEncrypt.hcl"
configDecryptPath = "./fixtures/configDecrypt.hcl"
configEncryptPath = "./fixtures/config_encrypt.hcl"
configDecryptPath = "./fixtures/config_decrypt.hcl"
configKmsPath = "./fixtures/config_kms.hcl"
configExtEncryptPath = "./fixtures/config_ext_encrypt.hcl"
configExtEncryptStrippedPath = "./fixtures/config_ext_encrypt_stripped.hcl"
configExtDecryptPath = "./fixtures/config_ext_decrypt.hcl"
)
func TestEncryptDecrypt(t *testing.T) {
cases := []struct {
encrypt bool
config string
exp string
f string
config string
configKms string
exp string
strip bool
}{
{
encrypt: true,
config: configEncryptPath,
exp: "",
f: "encrypt",
config: configEncryptPath,
},
{
f: "decrypt",
config: configDecryptPath,
exp: configEncryptPath,
},
{
f: "encrypt-ext",
config: configExtEncryptPath,
configKms: configKmsPath,
},
{
encrypt: false,
config: configDecryptPath,
exp: configEncryptPath,
f: "decrypt-ext",
config: configExtDecryptPath,
configKms: configKmsPath,
exp: configExtEncryptPath,
},
{
f: "decrypt-ext-strip",
config: configExtDecryptPath,
configKms: configKmsPath,
exp: configExtEncryptStrippedPath,
},
}
for _, c := range cases {
t.Run(fmt.Sprintf("Test encrypt %v", c.encrypt), func(t *testing.T) {
t.Run(fmt.Sprintf("Test encrypt %v", c.f), func(t *testing.T) {
var b bytes.Buffer
@ -51,9 +72,17 @@ func TestEncryptDecrypt(t *testing.T) {
cmd := &EncryptDecryptCommand{
Command: base.NewCommand(ui),
Encrypt: c.encrypt}
Func: c.f,
}
if err := cmd.Run([]string{c.config}); err != 0 {
args := []string{"-config", c.config}
if c.configKms != "" {
args = append(args, "-config-kms", c.configKms)
}
if c.strip {
args = append(args, "-strip")
}
if err := cmd.Run(args); err != 0 {
assert.Equal(t, err, 0)
}
@ -64,7 +93,7 @@ func TestEncryptDecrypt(t *testing.T) {
// If it's encrypting, then we can assume that it did the right thing since
// there are many tests on the underlying codebase for that. If it's not
// encrypting, compare it to the cleartext to verify because we can.
if !c.encrypt {
if c.f == "decrypt" {
expected, err := ioutil.ReadFile(c.exp)
assert.NoError(t, err)

@ -0,0 +1,7 @@
int_val = {{decrypt(Ch7a69AX8R5w_cCZJUqLTQkWesuSHMrHxrRMMZnq53QqAA)}}
bool_val = {{decrypt(CiDURLrWUXLhEfkOemqqiQlcD_gsGsIx-kxVTIlVncN6-yoA)}}
kms "aead" {
purpose = "root"
aead_type = "aes-gcm"
key ="{{decrypt(CkiRTINwX19TnC3AB-zx5E133TXI9KzBWb8TxfVDrPb9m3Yfm9K99OkuJgRTj1rjmeMF-Kpl-0oouEc8_mNk6oPIqD8nUNvH3FYqAA)}}"
}

@ -0,0 +1,7 @@
int_val = {{encrypt(20)}}
bool_val = {{encrypt(true)}}
kms "aead" {
purpose = "root"
aead_type = "aes-gcm"
key ="{{encrypt(aA1hxJo0JUAqcIATx/r0QTjAGD/btCPechEsukI2bt0=)}}"
}

@ -0,0 +1,7 @@
int_val = 20
bool_val = true
kms "aead" {
purpose = "root"
aead_type = "aes-gcm"
key ="aA1hxJo0JUAqcIATx/r0QTjAGD/btCPechEsukI2bt0=)"
}

@ -0,0 +1,5 @@
kms "aead" {
purpose = "config"
aead_type = "aes-gcm"
key = "c964AJj8VW8w4hKz/Jd8MvuLt0kkcjVuFqMiMvTvvN8="
}

@ -10,9 +10,10 @@ import (
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/cmd/config"
"github.com/hashicorp/boundary/internal/servers/controller"
"github.com/hashicorp/boundary/internal/wrapper"
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/shared-secure-libs/configutil"
"github.com/hashicorp/vault/sdk/helper/mlock"
"github.com/hashicorp/vault/sdk/helper/strutil"
"github.com/mitchellh/cli"
@ -33,9 +34,10 @@ type Command struct {
Config *config.Config
controller *controller.Controller
configKMS *configutil.KMS
configWrapper wrapping.Wrapper
flagConfig string
flagConfigKms string
flagLogLevel string
flagLogFormat string
flagCombineLogs bool
@ -78,7 +80,17 @@ func (c *Command) Flags() *base.FlagSets {
complete.PredictFiles("*.hcl"),
complete.PredictFiles("*.json"),
),
Usage: "Path to a configuration file.",
Usage: "Path to the configuration file.",
})
f.StringVar(&base.StringVar{
Name: "config-kms",
Target: &c.flagConfigKms,
Completion: complete.PredictOr(
complete.PredictFiles("*.hcl"),
complete.PredictFiles("*.json"),
),
Usage: `Path to a configuration file containing a "kms" block marked for "config" purpose, to perform decryption of the main configuration file. If not set, will look for such a block in the main configuration file, which has some drawbacks; see the help output for "boundary config encrypt -h" for details.`,
})
f.StringVar(&base.StringVar{
@ -178,6 +190,14 @@ func (c *Command) Run(args []string) int {
return result
}
if c.configWrapper != nil {
defer func() {
if err := c.configWrapper.Finalize(c.Context); err != nil {
c.UI.Warn(fmt.Errorf("Error finalizing config kms: %w", err).Error())
}
}()
}
if err := c.SetupLogging(c.flagLogLevel, c.flagLogFormat, c.Config.LogLevel, c.Config.LogFormat); err != nil {
c.UI.Error(err.Error())
return 1
@ -317,19 +337,20 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
return 1
}
// preload the KMS for encrypting/decrypting the config parameters
kmss, err := configutil.LoadConfigKMSes(c.flagConfig)
wrapperPath := c.flagConfig
if c.flagConfigKms != "" {
wrapperPath = c.flagConfigKms
}
wrapper, err := wrapper.GetWrapper(wrapperPath, "config")
if err != nil {
c.UI.Error("error loading KMS config: " + err.Error())
c.UI.Error(err.Error())
return 1
}
for _, kms := range kmss {
for _, purpose := range kms.Purpose {
if purpose == "config" {
c.configKMS = kms
break
}
if wrapper != nil {
c.configWrapper = wrapper
if err := wrapper.Init(c.Context); err != nil {
c.UI.Error(fmt.Errorf("Could not initialize kms: %w", err).Error())
return 1
}
}
@ -351,7 +372,7 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
c.flagDevLoginName = ""
}
c.Config, err = config.LoadFile(c.flagConfig, c.configKMS)
c.Config, err = config.LoadFile(c.flagConfig, wrapper)
if err != nil {
c.UI.Error("Error parsing config: " + err.Error())
return 1
@ -361,7 +382,7 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
if len(c.flagConfig) == 0 {
c.Config, err = config.DevController()
} else {
c.Config, err = config.LoadFile(c.flagConfig, c.configKMS)
c.Config, err = config.LoadFile(c.flagConfig, wrapper)
}
if err != nil {
c.UI.Error(fmt.Errorf("Error creating dev config: %w", err).Error())
@ -468,7 +489,7 @@ func (c *Command) WaitForInterrupt() int {
goto RUNRELOADFUNCS
}
newConf, err = config.LoadFile(c.flagConfig, c.configKMS)
newConf, err = config.LoadFile(c.flagConfig, c.configWrapper)
if err != nil {
c.Logger.Error("could not reload config", "path", c.flagConfig, "error", err)
goto RUNRELOADFUNCS
@ -480,9 +501,6 @@ func (c *Command) WaitForInterrupt() int {
goto RUNRELOADFUNCS
}
// Commented out until we need this
//controller.SetConfig(config)
if newConf.LogLevel != "" {
configLogLevel := strings.ToLower(strings.TrimSpace(newConf.LogLevel))
switch configLogLevel {

@ -9,9 +9,10 @@ import (
"github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/cmd/config"
"github.com/hashicorp/boundary/internal/servers/worker"
"github.com/hashicorp/boundary/internal/wrapper"
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-multierror"
"github.com/hashicorp/shared-secure-libs/configutil"
"github.com/hashicorp/vault/sdk/helper/mlock"
"github.com/mitchellh/cli"
"github.com/posener/complete"
@ -33,9 +34,10 @@ type Command struct {
Config *config.Config
worker *worker.Worker
configKMS *configutil.KMS
configWrapper wrapping.Wrapper
flagConfig string
flagConfigKms string
flagLogLevel string
flagLogFormat string
flagDev bool
@ -76,6 +78,16 @@ func (c *Command) Flags() *base.FlagSets {
Usage: "Path to a configuration file.",
})
f.StringVar(&base.StringVar{
Name: "config-kms",
Target: &c.flagConfigKms,
Completion: complete.PredictOr(
complete.PredictFiles("*.hcl"),
complete.PredictFiles("*.json"),
),
Usage: `Path to a configuration file containing a "kms" block marked for "config" purpose, to perform decryption of the main configuration file. If not set, will look for such a block in the main configuration file, which has some drawbacks; see the help output for "boundary config encrypt -h" for details.`,
})
f.StringVar(&base.StringVar{
Name: "log-level",
Target: &c.flagLogLevel,
@ -135,6 +147,14 @@ func (c *Command) Run(args []string) int {
return result
}
if c.configWrapper != nil {
defer func() {
if err := c.configWrapper.Finalize(c.Context); err != nil {
c.UI.Warn(fmt.Errorf("Error finalizing config kms: %w", err).Error())
}
}()
}
if err := c.SetupLogging(c.flagLogLevel, c.flagLogFormat, c.Config.LogLevel, c.Config.LogFormat); err != nil {
c.UI.Error(err.Error())
return 1
@ -206,19 +226,20 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
return 1
}
// preload the KMS for encrypting/decrypting the config parameters
kmss, err := configutil.LoadConfigKMSes(c.flagConfig)
wrapperPath := c.flagConfig
if c.flagConfigKms != "" {
wrapperPath = c.flagConfigKms
}
wrapper, err := wrapper.GetWrapper(wrapperPath, "config")
if err != nil {
c.UI.Error("error loading KMS config: " + err.Error())
c.UI.Error(err.Error())
return 1
}
for _, kms := range kmss {
for _, purpose := range kms.Purpose {
if purpose == "config" {
c.configKMS = kms
break
}
if wrapper != nil {
c.configWrapper = wrapper
if err := wrapper.Init(c.Context); err != nil {
c.UI.Error(fmt.Errorf("Could not initialize kms: %w", err).Error())
return 1
}
}
@ -228,7 +249,7 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
c.UI.Error("Must supply a config file with -config")
return 1
}
c.Config, err = config.LoadFile(c.flagConfig, c.configKMS)
c.Config, err = config.LoadFile(c.flagConfig, wrapper)
if err != nil {
c.UI.Error("Error parsing config: " + err.Error())
return 1
@ -238,7 +259,7 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
if len(c.flagConfig) == 0 {
c.Config, err = config.DevWorker()
} else {
c.Config, err = config.LoadFile(c.flagConfig, c.configKMS)
c.Config, err = config.LoadFile(c.flagConfig, wrapper)
}
if err != nil {
c.UI.Error(fmt.Errorf("Error creating dev config: %s", err).Error())
@ -311,7 +332,7 @@ func (c *Command) WaitForInterrupt() int {
goto RUNRELOADFUNCS
}
newConf, err = config.LoadFile(c.flagConfig, c.configKMS)
newConf, err = config.LoadFile(c.flagConfig, c.configWrapper)
if err != nil {
c.Logger.Error("could not reload config", "path", c.flagConfig, "error", err)
goto RUNRELOADFUNCS
@ -323,9 +344,6 @@ func (c *Command) WaitForInterrupt() int {
goto RUNRELOADFUNCS
}
// Commented out until we need this
//c.worker.SetConfig(config)
if newConf.LogLevel != "" {
configLogLevel := strings.ToLower(strings.TrimSpace(newConf.LogLevel))
switch configLogLevel {

@ -2,13 +2,13 @@ package config
import (
"bytes"
"context"
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/hcl"
"github.com/hashicorp/shared-secure-libs/configutil"
)
@ -175,7 +175,7 @@ func New() *Config {
}
// LoadFile loads the configuration from the given file.
func LoadFile(path string, kms *configutil.KMS) (*Config, error) {
func LoadFile(path string, wrapper wrapping.Wrapper) (*Config, error) {
d, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
@ -183,8 +183,8 @@ func LoadFile(path string, kms *configutil.KMS) (*Config, error) {
raw := string(d)
if kms != nil {
raw, err = configDecrypt(raw, kms)
if wrapper != nil {
raw, err = configutil.EncryptDecrypt(raw, true, true, wrapper)
if err != nil {
return nil, err
}
@ -235,15 +235,3 @@ func (c *Config) Sanitized() map[string]interface{} {
return result
}
func configDecrypt(raw string, kms *configutil.KMS) (string, error) {
wrapper, err := configutil.ConfigureWrapper(kms, nil, nil, nil)
if err != nil {
return raw, err
}
wrapper.Init(context.Background())
defer wrapper.Finalize(context.Background())
return configutil.EncryptDecrypt(raw, true, true, wrapper)
}

@ -0,0 +1,36 @@
package wrapper
import (
"fmt"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/shared-secure-libs/configutil"
"github.com/hashicorp/vault/sdk/helper/strutil"
)
func GetWrapper(path, purpose string) (wrapping.Wrapper, error) {
kmses, err := configutil.LoadConfigKMSes(path)
if err != nil {
return nil, fmt.Errorf("Error parsing config file: %w", err)
}
var kms *configutil.KMS
for _, v := range kmses {
if strutil.StrListContains(v.Purpose, purpose) {
if kms != nil {
return nil, fmt.Errorf("Only one %q block marked for %q purpose is allowed", "kms", purpose)
}
kms = v
}
}
if kms == nil {
return nil, nil
}
wrapper, err := configutil.ConfigureWrapper(kms, nil, nil, nil)
if err != nil {
return nil, fmt.Errorf("Error configuring kms: %w", err)
}
return wrapper, nil
}

@ -11,8 +11,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/shared-secure-libs/configutil"
"github.com/hashicorp/vault/sdk/helper/strutil"
"google.golang.org/protobuf/proto"
)
@ -30,33 +28,6 @@ type Info struct {
CreationTime time.Time `json:"creation_time"`
}
func GetWrapper(ctx context.Context, path string) (wrapping.Wrapper, error) {
kmses, err := configutil.LoadConfigKMSes(path)
if err != nil {
return nil, fmt.Errorf("Error parsing config file: %w", err)
}
var kms *configutil.KMS
for _, v := range kmses {
if strutil.StrListContains(v.Purpose, "recovery") {
if kms != nil {
return nil, fmt.Errorf("Only one %q block marked for %q purpose is allowed", "kms", "recovery")
}
kms = v
}
}
if kms == nil {
return nil, fmt.Errorf("No %q block marked for %q purpose is allowed", "kms", "recovery")
}
wrapper, err := configutil.ConfigureWrapper(kms, nil, nil, nil)
if err != nil {
return nil, fmt.Errorf("Error configuring kms: %w", err)
}
return wrapper, nil
}
func GenerateRecoveryToken(ctx context.Context, wrapper wrapping.Wrapper) (string, error) {
b, err := uuid.GenerateRandomBytes(nonceLength)
if err != nil {

Loading…
Cancel
Save