Fix 1.5 regression that meant non-string values in the seal stanza would fail config parsing, preventing startup. (#9555)

This commit is contained in:
ncabatoff
2020-07-23 13:53:00 -04:00
committed by GitHub
parent 5269a5151d
commit 34144e38ee
4 changed files with 126 additions and 32 deletions

View File

@@ -49,3 +49,7 @@ func TestParseEntropy(t *testing.T) {
func TestConfigRaftRetryJoin(t *testing.T) { func TestConfigRaftRetryJoin(t *testing.T) {
testConfigRaftRetryJoin(t) testConfigRaftRetryJoin(t)
} }
func TestParseSeals(t *testing.T) {
testParseSeals(t)
}

View File

@@ -2,6 +2,7 @@ package server
import ( import (
"fmt" "fmt"
"github.com/stretchr/testify/require"
"strings" "strings"
"testing" "testing"
"time" "time"
@@ -711,3 +712,60 @@ listener "tcp" {
t.Fatal(diff) t.Fatal(diff)
} }
} }
func testParseSeals(t *testing.T) {
config, err := LoadConfigFile("./test-fixtures/config_seals.hcl")
if err != nil {
t.Fatalf("err: %s", err)
}
config.Listeners[0].RawConfig = nil
expected := &Config{
Storage: &Storage{
Type: "consul",
Config: map[string]string{},
},
SharedConfig: &configutil.SharedConfig{
Listeners: []*configutil.Listener{
{
Type: "tcp",
Address: "127.0.0.1:443",
},
},
Seals: []*configutil.KMS{
&configutil.KMS{
Type: "pkcs11",
Purpose: []string{"many", "purposes"},
Config: map[string]string{
"lib": "/usr/lib/libcklog2.so",
"slot": "0.0",
"pin": "XXXXXXXX",
"key_label": "HASHICORP",
"mechanism": "0x1082",
"hmac_mechanism": "0x0251",
"hmac_key_label": "vault-hsm-hmac-key",
"default_hmac_key_label": "vault-hsm-hmac-key",
"generate_key": "true",
},
},
&configutil.KMS{
Type: "pkcs11",
Purpose: []string{"single"},
Disabled: true,
Config: map[string]string{
"lib": "/usr/lib/libcklog2.so",
"slot": "0.0",
"pin": "XXXXXXXX",
"key_label": "HASHICORP",
"mechanism": "0x1082",
"hmac_mechanism": "0x0251",
"hmac_key_label": "vault-hsm-hmac-key",
"default_hmac_key_label": "vault-hsm-hmac-key",
"generate_key": "true",
},
},
},
},
}
require.Equal(t, config, expected)
}

View File

@@ -0,0 +1,34 @@
listener "tcp" {
address = "127.0.0.1:443"
}
backend "consul" {
}
seal "pkcs11" {
purpose = "many,purposes"
lib = "/usr/lib/libcklog2.so"
slot = "0.0"
pin = "XXXXXXXX"
key_label = "HASHICORP"
mechanism = "0x1082"
hmac_mechanism = "0x0251"
hmac_key_label = "vault-hsm-hmac-key"
default_hmac_key_label = "vault-hsm-hmac-key"
generate_key = "true"
}
seal "pkcs11" {
purpose = "single"
disabled = "true"
lib = "/usr/lib/libcklog2.so"
slot = "0.0"
pin = "XXXXXXXX"
key_label = "HASHICORP"
mechanism = 0x1082
hmac_mechanism = 0x0251
hmac_key_label = "vault-hsm-hmac-key"
default_hmac_key_label = "vault-hsm-hmac-key"
generate_key = "true"
}

View File

@@ -68,6 +68,10 @@ func parseKMS(result *[]*KMS, list *ast.ObjectList, blockName string, maxKMS int
key = item.Keys[0].Token.Value().(string) key = item.Keys[0].Token.Value().(string)
} }
var disabled bool
var purpose []string
var err error
{
// We first decode into a map[string]interface{} because purpose isn't // We first decode into a map[string]interface{} because purpose isn't
// necessarily a string. Then we migrate everything else over to // necessarily a string. Then we migrate everything else over to
// map[string]string and error if it doesn't work. // map[string]string and error if it doesn't work.
@@ -76,8 +80,6 @@ func parseKMS(result *[]*KMS, list *ast.ObjectList, blockName string, maxKMS int
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key)) return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
} }
var purpose []string
var err error
if v, ok := m["purpose"]; ok { if v, ok := m["purpose"]; ok {
if purpose, err = parseutil.ParseCommaStringSlice(v); err != nil { if purpose, err = parseutil.ParseCommaStringSlice(v); err != nil {
return multierror.Prefix(fmt.Errorf("unable to parse 'purpose' in kms type %q: %w", key, err), fmt.Sprintf("%s.%s:", blockName, key)) return multierror.Prefix(fmt.Errorf("unable to parse 'purpose' in kms type %q: %w", key, err), fmt.Sprintf("%s.%s:", blockName, key))
@@ -85,34 +87,30 @@ func parseKMS(result *[]*KMS, list *ast.ObjectList, blockName string, maxKMS int
for i, p := range purpose { for i, p := range purpose {
purpose[i] = strings.ToLower(p) purpose[i] = strings.ToLower(p)
} }
delete(m, "purpose")
} }
var disabled bool
if v, ok := m["disabled"]; ok { if v, ok := m["disabled"]; ok {
disabled, err = parseutil.ParseBool(v) disabled, err = parseutil.ParseBool(v)
if err != nil { if err != nil {
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key)) return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
} }
delete(m, "disabled") }
} }
strMap := make(map[string]string, len(m)) var cfg map[string]string
for k, v := range m { if err := hcl.DecodeObject(&cfg, item.Val); err != nil {
if vs, ok := v.(string); ok { return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
strMap[k] = vs
} else {
return multierror.Prefix(fmt.Errorf("unable to parse 'purpose' in kms type %q: value could not be parsed as string", key), fmt.Sprintf("%s.%s:", blockName, key))
}
} }
delete(cfg, "purpose")
delete(cfg, "disabled")
seal := &KMS{ seal := &KMS{
Type: strings.ToLower(key), Type: strings.ToLower(key),
Purpose: purpose, Purpose: purpose,
Disabled: disabled, Disabled: disabled,
} }
if len(strMap) > 0 { if len(cfg) > 0 {
seal.Config = strMap seal.Config = cfg
} }
seals = append(seals, seal) seals = append(seals, seal)
} }