Move KmsLibrary code to the ent side of config parsing (#13463)
* Move KmsLibrary code to the ent side of config parsing * Normalize config.go * Nope, needs to be result
This commit is contained in:
parent
1966264bcd
commit
baec515677
|
@ -8,13 +8,10 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
wrapping "github.com/hashicorp/go-kms-wrapping"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
"github.com/hashicorp/hcl"
|
||||
|
@ -26,8 +23,6 @@ var entConfigValidate = func(_ *Config, _ string) []configutil.ConfigError {
|
|||
return nil
|
||||
}
|
||||
|
||||
var kmsLibraryValidator = defaultKmsLibraryValidator
|
||||
|
||||
// Config is the configuration for the vault server.
|
||||
type Config struct {
|
||||
UnusedKeys configutil.UnusedKeyMap `hcl:",unusedKeyPositions"`
|
||||
|
@ -90,8 +85,6 @@ type Config struct {
|
|||
|
||||
License string `hcl:"-"`
|
||||
LicensePath string `hcl:"license_path"`
|
||||
|
||||
KmsLibraries map[string]*KMSLibrary `hcl:"-"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -109,9 +102,6 @@ func (c *Config) Validate(sourceFilePath string) []configutil.ConfigError {
|
|||
for _, l := range c.Listeners {
|
||||
results = append(results, l.Validate(sourceFilePath)...)
|
||||
}
|
||||
for _, kmslibrary := range c.KmsLibraries {
|
||||
results = append(results, kmslibrary.Validate(sourceFilePath)...)
|
||||
}
|
||||
results = append(results, c.validateEnt(sourceFilePath)...)
|
||||
return results
|
||||
}
|
||||
|
@ -181,24 +171,6 @@ func (b *ServiceRegistration) GoString() string {
|
|||
return fmt.Sprintf("*%#v", *b)
|
||||
}
|
||||
|
||||
// KMSLibrary is a per-server configuration that will be further augmented with managed key configuration to
|
||||
// build up a KMS wrapper type to delegate encryption operations to HSMs
|
||||
type KMSLibrary struct {
|
||||
UnusedKeys configutil.UnusedKeyMap `hcl:",unusedKeyPositions"`
|
||||
FoundKeys []string `hcl:",decodedFields"`
|
||||
Type string `hcl:"-"`
|
||||
Name string `hcl:"name"`
|
||||
Library string `hcl:"library"`
|
||||
}
|
||||
|
||||
func (k *KMSLibrary) Validate(source string) []configutil.ConfigError {
|
||||
return configutil.ValidateUnusedFields(k.UnusedKeys, source)
|
||||
}
|
||||
|
||||
func (k *KMSLibrary) GoString() string {
|
||||
return fmt.Sprintf("*%#v", *k)
|
||||
}
|
||||
|
||||
func NewConfig() *Config {
|
||||
return &Config{
|
||||
SharedConfig: new(configutil.SharedConfig),
|
||||
|
@ -569,16 +541,7 @@ func ParseConfig(d, source string) (*Config, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Parse KMSLibraries sections if any
|
||||
if o := list.Filter("kms_library"); len(o.Items) > 0 {
|
||||
delete(result.UnusedKeys, "kms_library")
|
||||
if err := parseKmsLibraries(result, o); err != nil {
|
||||
return nil, fmt.Errorf("error parsing 'kms_library': %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
entConfig := &(result.entConfig)
|
||||
if err := entConfig.parseConfig(list); err != nil {
|
||||
if err := result.parseConfig(list); err != nil {
|
||||
return nil, fmt.Errorf("error parsing enterprise config: %w", err)
|
||||
}
|
||||
|
||||
|
@ -843,75 +806,6 @@ func parseServiceRegistration(result *Config, list *ast.ObjectList, name string)
|
|||
return nil
|
||||
}
|
||||
|
||||
func parseKmsLibraries(result *Config, list *ast.ObjectList) error {
|
||||
result.KmsLibraries = make(map[string]*KMSLibrary, len(list.Items))
|
||||
|
||||
for _, item := range list.Items {
|
||||
library, err := decodeKmsLibrary(item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateKmsLibrary(library); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, ok := result.KmsLibraries[library.Name]; ok {
|
||||
return fmt.Errorf("duplicated kms_library configuration sections with name %s", library.Name)
|
||||
}
|
||||
|
||||
result.KmsLibraries[library.Name] = library
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func decodeKmsLibrary(item *ast.ObjectItem) (*KMSLibrary, error) {
|
||||
library := &KMSLibrary{}
|
||||
if err := hcl.DecodeObject(&library, item.Val); err != nil {
|
||||
return nil, multierror.Prefix(err, "kms_library")
|
||||
}
|
||||
|
||||
if len(item.Keys) != 1 {
|
||||
return nil, errors.New("kms_library section was missing a type")
|
||||
}
|
||||
|
||||
library.Type = strings.ToLower(item.Keys[0].Token.Value().(string))
|
||||
library.Name = strings.ToLower(library.Name)
|
||||
|
||||
return library, nil
|
||||
}
|
||||
|
||||
func defaultKmsLibraryValidator(kms *KMSLibrary) error {
|
||||
switch kms.Type {
|
||||
case wrapping.PKCS11:
|
||||
return fmt.Errorf("KMS type 'pkcs11' requires the Vault Enterprise HSM binary")
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown KMS type %q", kms.Type)
|
||||
}
|
||||
}
|
||||
|
||||
func validateKmsLibrary(kmsConfig *KMSLibrary) error {
|
||||
if kmsConfig.Library == "" {
|
||||
return fmt.Errorf("library key can not be blank within kms_library type: %s", kmsConfig.Type)
|
||||
}
|
||||
|
||||
if kmsConfig.Name == "" {
|
||||
return fmt.Errorf("name key can not be blank within kms_library type: %s", kmsConfig.Type)
|
||||
}
|
||||
|
||||
nameRegex := regexp.MustCompile("^[\\w._-]+$")
|
||||
if !nameRegex.MatchString(kmsConfig.Name) {
|
||||
return fmt.Errorf("value ('%s') for name field contained invalid characters within kms_library type: %s", kmsConfig.Name, kmsConfig.Type)
|
||||
}
|
||||
|
||||
if err := kmsLibraryValidator(kmsConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Sanitized returns a copy of the config with all values that are considered
|
||||
// sensitive stripped. It also strips all `*Raw` values that are mainly
|
||||
// used for parsing.
|
||||
|
|
|
@ -17,7 +17,3 @@ func TestLoadConfigFile_json2(t *testing.T) {
|
|||
func TestParseEntropy(t *testing.T) {
|
||||
testParseEntropy(t, true)
|
||||
}
|
||||
|
||||
func TestKmsLibraryFailsForNonHSMBinary(t *testing.T) {
|
||||
testKmsLibraryFailsForNonHSMBinary(t)
|
||||
}
|
||||
|
|
|
@ -701,7 +701,7 @@ func testConfig_Sanitized(t *testing.T) {
|
|||
"enable_ui": true,
|
||||
"enable_response_header_hostname": false,
|
||||
"enable_response_header_raft_node_id": false,
|
||||
"log_requests_level": "basic",
|
||||
"log_requests_level": "basic",
|
||||
"ha_storage": map[string]interface{}{
|
||||
"cluster_addr": "top_level_cluster_addr",
|
||||
"disable_clustering": true,
|
||||
|
@ -1064,26 +1064,3 @@ func testConfigRaftAutopilot(t *testing.T) {
|
|||
t.Fatal(diff)
|
||||
}
|
||||
}
|
||||
|
||||
func testKmsLibraryFailsForNonHSMBinary(t *testing.T) {
|
||||
config := `
|
||||
ui = false
|
||||
storage "file" {
|
||||
path = "/tmp/test"
|
||||
}
|
||||
|
||||
listener "tcp" {
|
||||
address = "0.0.0.0:8200"
|
||||
tls_cert_file = "/opt/vault/tls/tls.crt"
|
||||
tls_key_file = "/opt/vault/tls/tls.key"
|
||||
}
|
||||
|
||||
kms_library "pkcs11" {
|
||||
name="Logical1"
|
||||
library="a library"
|
||||
}
|
||||
`
|
||||
_, err := ParseConfig(config, "")
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), "requires the Vault Enterprise HSM binary")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue