Fix parsing of seal stanzas that have an array for `purpose` (#9589)

Hexadecimal integers will be converted to decimal, which is unfortunate but shouldn't have any negative effects other than perhaps confusion in the `vault debug` output.
This commit is contained in:
ncabatoff 2020-07-27 16:28:52 -04:00 committed by GitHub
parent 003bccd16e
commit b491c6d72a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 37 deletions

View File

@ -757,8 +757,8 @@ func testParseSeals(t *testing.T) {
"slot": "0.0", "slot": "0.0",
"pin": "XXXXXXXX", "pin": "XXXXXXXX",
"key_label": "HASHICORP", "key_label": "HASHICORP",
"mechanism": "0x1082", "mechanism": "4226",
"hmac_mechanism": "0x0251", "hmac_mechanism": "593",
"hmac_key_label": "vault-hsm-hmac-key", "hmac_key_label": "vault-hsm-hmac-key",
"default_hmac_key_label": "vault-hsm-hmac-key", "default_hmac_key_label": "vault-hsm-hmac-key",
"generate_key": "true", "generate_key": "true",

View File

@ -68,49 +68,51 @@ 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 // We first decode into a map[string]interface{} because purpose isn't
var purpose []string // necessarily a string. Then we migrate everything else over to
var err error // map[string]string and error if it doesn't work.
{ var m map[string]interface{}
// We first decode into a map[string]interface{} because purpose isn't if err := hcl.DecodeObject(&m, item.Val); err != nil {
// necessarily a string. Then we migrate everything else over to
// map[string]string and error if it doesn't work.
var m map[string]interface{}
if err := hcl.DecodeObject(&m, item.Val); err != nil {
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
}
if v, ok := m["purpose"]; ok {
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))
}
for i, p := range purpose {
purpose[i] = strings.ToLower(p)
}
}
if v, ok := m["disabled"]; ok {
disabled, err = parseutil.ParseBool(v)
if err != nil {
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
}
}
}
var cfg map[string]string
if err := hcl.DecodeObject(&cfg, item.Val); err != nil {
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key)) return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
} }
delete(cfg, "purpose")
delete(cfg, "disabled") var purpose []string
var err error
if v, ok := m["purpose"]; ok {
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))
}
for i, p := range purpose {
purpose[i] = strings.ToLower(p)
}
delete(m, "purpose")
}
var disabled bool
if v, ok := m["disabled"]; ok {
disabled, err = parseutil.ParseBool(v)
if err != nil {
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
}
delete(m, "disabled")
}
strMap := make(map[string]string, len(m))
for k, v := range m {
s, err := parseutil.ParseString(v)
if err != nil {
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
}
strMap[k] = s
}
seal := &KMS{ seal := &KMS{
Type: strings.ToLower(key), Type: strings.ToLower(key),
Purpose: purpose, Purpose: purpose,
Disabled: disabled, Disabled: disabled,
} }
if len(cfg) > 0 { if len(strMap) > 0 {
seal.Config = cfg seal.Config = strMap
} }
seals = append(seals, seal) seals = append(seals, seal)
} }

View File

@ -112,6 +112,14 @@ func ParseBool(in interface{}) (bool, error) {
return result, nil return result, nil
} }
func ParseString(in interface{}) (string, error) {
var result string
if err := mapstructure.WeakDecode(in, &result); err != nil {
return "", err
}
return result, nil
}
func ParseCommaStringSlice(in interface{}) ([]string, error) { func ParseCommaStringSlice(in interface{}) ([]string, error) {
rawString, ok := in.(string) rawString, ok := in.(string)
if ok && rawString == "" { if ok && rawString == "" {

View File

@ -112,6 +112,14 @@ func ParseBool(in interface{}) (bool, error) {
return result, nil return result, nil
} }
func ParseString(in interface{}) (string, error) {
var result string
if err := mapstructure.WeakDecode(in, &result); err != nil {
return "", err
}
return result, nil
}
func ParseCommaStringSlice(in interface{}) ([]string, error) { func ParseCommaStringSlice(in interface{}) ([]string, error) {
rawString, ok := in.(string) rawString, ok := in.(string)
if ok && rawString == "" { if ok && rawString == "" {