VAULT-29784: Skip connection verification on DB config read (#28139)

* skip connection verification on config read

* ensure appropriate default on config update call that results in a creation

* changelog

* leave verify_connection in config read response

* update test to handle output of verify_connection parameter

* fix remaining tests
This commit is contained in:
davidadeleon
2024-08-21 16:43:37 -04:00
committed by GitHub
parent dbc542efd7
commit fe44e55943
4 changed files with 34 additions and 7 deletions

View File

@@ -291,6 +291,18 @@ func (b *databaseBackend) GetConnection(ctx context.Context, s logical.Storage,
return b.GetConnectionWithConfig(ctx, name, config)
}
func (b *databaseBackend) GetConnectionSkipVerify(ctx context.Context, s logical.Storage, name string) (*dbPluginInstance, error) {
config, err := b.DatabaseConfig(ctx, s, name)
if err != nil {
return nil, err
}
// Force the skip verifying the connection
config.VerifyConnection = false
return b.GetConnectionWithConfig(ctx, name, config)
}
func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name string, config *DatabaseConfig) (*dbPluginInstance, error) {
// fast path, reuse the existing connection
dbi := b.connections.Get(name)
@@ -331,7 +343,7 @@ func (b *databaseBackend) GetConnectionWithConfig(ctx context.Context, name stri
initReq := v5.InitializeRequest{
Config: config.ConnectionDetails,
VerifyConnection: true,
VerifyConnection: config.VerifyConnection,
}
_, err = dbw.Initialize(ctx, initReq)
if err != nil {

View File

@@ -210,6 +210,7 @@ func TestBackend_config_connection(t *testing.T) {
"root_credentials_rotate_statements": []string{},
"password_policy": "",
"plugin_version": "",
"verify_connection": false,
}
configReq.Operation = logical.ReadOperation
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
@@ -264,6 +265,7 @@ func TestBackend_config_connection(t *testing.T) {
"root_credentials_rotate_statements": []string{},
"password_policy": "",
"plugin_version": "",
"verify_connection": false,
}
configReq.Operation = logical.ReadOperation
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
@@ -307,6 +309,7 @@ func TestBackend_config_connection(t *testing.T) {
"root_credentials_rotate_statements": []string{},
"password_policy": "",
"plugin_version": "",
"verify_connection": false,
}
configReq.Operation = logical.ReadOperation
resp, err = b.HandleRequest(namespace.RootContext(nil), configReq)
@@ -764,6 +767,7 @@ func TestBackend_connectionCrud(t *testing.T) {
"root_credentials_rotate_statements": []any{},
"password_policy": "",
"plugin_version": "",
"verify_connection": false,
}
resp, err = client.Read("database/config/plugin-test")
if err != nil {

View File

@@ -41,6 +41,7 @@ type DatabaseConfig struct {
RootCredentialsRotateStatements []string `json:"root_credentials_rotate_statements" structs:"root_credentials_rotate_statements" mapstructure:"root_credentials_rotate_statements"`
PasswordPolicy string `json:"password_policy" structs:"password_policy" mapstructure:"password_policy"`
VerifyConnection bool `json:"verify_connection" structs:"verify_connection" mapstructure:"verify_connection"`
}
func (c *DatabaseConfig) SupportsCredentialType(credentialType v5.CredentialType) bool {
@@ -378,7 +379,7 @@ func (b *databaseBackend) connectionReadHandler() framework.OperationFunc {
delete(config.ConnectionDetails, "service_account_json")
resp := &logical.Response{}
if dbi, err := b.GetConnection(ctx, req.Storage, name); err == nil {
if dbi, err := b.GetConnectionSkipVerify(ctx, req.Storage, name); err == nil {
config.RunningPluginVersion = dbi.runningPluginVersion
if config.PluginVersion != "" && config.PluginVersion != config.RunningPluginVersion {
warning := fmt.Sprintf("Plugin version is configured as %q, but running %q", config.PluginVersion, config.RunningPluginVersion)
@@ -422,15 +423,15 @@ func (b *databaseBackend) connectionDeleteHandler() framework.OperationFunc {
// both builtin and plugin database types.
func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
return func(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
verifyConnection := data.Get("verify_connection").(bool)
name := data.Get("name").(string)
if name == "" {
return logical.ErrorResponse(respErrEmptyName), nil
}
// Baseline
config := &DatabaseConfig{}
config := &DatabaseConfig{
VerifyConnection: true,
}
entry, err := req.Storage.Get(ctx, fmt.Sprintf("config/%s", name))
if err != nil {
@@ -442,6 +443,13 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
}
}
// If this value was provided as part of the request we want to set it to this value
if verifyConnectionRaw, ok := data.GetOk("verify_connection"); ok {
config.VerifyConnection = verifyConnectionRaw.(bool)
} else if req.Operation == logical.CreateOperation {
config.VerifyConnection = data.Get("verify_connection").(bool)
}
if pluginNameRaw, ok := data.GetOk("plugin_name"); ok {
config.PluginName = pluginNameRaw.(string)
} else if req.Operation == logical.CreateOperation {
@@ -509,7 +517,7 @@ func (b *databaseBackend) connectionWriteHandler() framework.OperationFunc {
initReq := v5.InitializeRequest{
Config: config.ConnectionDetails,
VerifyConnection: verifyConnection,
VerifyConnection: config.VerifyConnection,
}
initResp, err := dbw.Initialize(ctx, initReq)
if err != nil {

3
changelog/28139.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
secrets/database: Skip connection verification on reading existing DB connection configuration
```