Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VAULT-2285 adding capability to accept comma separated entries for au… #12126

Merged
merged 17 commits into from Aug 9, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions changelog/12126.txt
@@ -0,0 +1,4 @@
```release-note:bug
auth/secret: Adding capability to use comma separated parameters for auth enable/tune
ncabatoff marked this conversation as resolved.
Show resolved Hide resolved
auth/secret: Adding missing CLI parameters and updating website information accordingly
ncabatoff marked this conversation as resolved.
Show resolved Hide resolved
```
6 changes: 6 additions & 0 deletions command/auth_enable_test.go
Expand Up @@ -86,6 +86,12 @@ func TestAuthEnableCommand_Run(t *testing.T) {
code := cmd.Run([]string{
"-path", "auth_integration/",
"-description", "The best kind of test",
"-audit-non-hmac-request-keys", "foo,bar",
"-audit-non-hmac-response-keys", "foo,bar",
"-passthrough-request-headers", "authorization,authentication",
"-passthrough-request-headers", "www-authentication",
"-allowed-response-headers", "authorization",
"-listing-visibility", "unauth",
"userpass",
})
if exp := 0; code != exp {
Expand Down
42 changes: 33 additions & 9 deletions command/auth_tune.go
Expand Up @@ -20,15 +20,17 @@ var (
type AuthTuneCommand struct {
*BaseCommand

flagAuditNonHMACRequestKeys []string
flagAuditNonHMACResponseKeys []string
flagDefaultLeaseTTL time.Duration
flagDescription string
flagListingVisibility string
flagMaxLeaseTTL time.Duration
flagOptions map[string]string
flagTokenType string
flagVersion int
flagAuditNonHMACRequestKeys []string
flagAuditNonHMACResponseKeys []string
flagDefaultLeaseTTL time.Duration
flagDescription string
flagListingVisibility string
flagMaxLeaseTTL time.Duration
flagPassthroughRequestHeaders []string
flagAllowedResponseHeaders []string
flagOptions map[string]string
flagTokenType string
flagVersion int
}

func (c *AuthTuneCommand) Synopsis() string {
Expand Down Expand Up @@ -107,6 +109,20 @@ func (c *AuthTuneCommand) Flags() *FlagSets {
"or a previously configured value for the auth method.",
})

f.StringSliceVar(&StringSliceVar{
Name: flagNamePassthroughRequestHeaders,
Target: &c.flagPassthroughRequestHeaders,
Usage: "Comma-separated string or list of request header values that " +
"will be sent to the plugin",
})

f.StringSliceVar(&StringSliceVar{
Name: flagNameAllowedResponseHeaders,
Target: &c.flagAllowedResponseHeaders,
Usage: "Comma-separated string or list of response header values that " +
"plugins will be allowed to set",
})

f.StringMapVar(&StringMapVar{
Name: "options",
Target: &c.flagOptions,
Expand Down Expand Up @@ -194,6 +210,14 @@ func (c *AuthTuneCommand) Run(args []string) int {
mountConfigInput.ListingVisibility = c.flagListingVisibility
}

if fl.Name == flagNamePassthroughRequestHeaders {
mountConfigInput.PassthroughRequestHeaders = c.flagPassthroughRequestHeaders
}

if fl.Name == flagNameAllowedResponseHeaders {
mountConfigInput.AllowedResponseHeaders = c.flagAllowedResponseHeaders
}

if fl.Name == flagNameTokenType {
mountConfigInput.TokenType = c.flagTokenType
}
Expand Down
3 changes: 3 additions & 0 deletions command/auth_tune_test.go
Expand Up @@ -92,6 +92,9 @@ func TestAuthTuneCommand_Run(t *testing.T) {
"-max-lease-ttl", "1h",
"-audit-non-hmac-request-keys", "foo,bar",
"-audit-non-hmac-response-keys", "foo,bar",
"-passthrough-request-headers", "authorization",
"-passthrough-request-headers", "www-authentication",
"-allowed-response-headers", "authorization,www-authentication",
"-listing-visibility", "unauth",
"my-auth/",
})
Expand Down
5 changes: 5 additions & 0 deletions command/secrets_enable_test.go
Expand Up @@ -107,6 +107,11 @@ func TestSecretsEnableCommand_Run(t *testing.T) {
"-description", "The best kind of test",
"-default-lease-ttl", "30m",
"-max-lease-ttl", "1h",
"-audit-non-hmac-request-keys", "foo,bar",
"-audit-non-hmac-response-keys", "foo,bar",
"-passthrough-request-headers", "authorization,authentication",
"-passthrough-request-headers", "www-authentication",
"-allowed-response-headers", "authorization",
"-force-no-cache",
"pki",
})
Expand Down
40 changes: 32 additions & 8 deletions command/secrets_tune.go
Expand Up @@ -20,14 +20,16 @@ var (
type SecretsTuneCommand struct {
*BaseCommand

flagAuditNonHMACRequestKeys []string
flagAuditNonHMACResponseKeys []string
flagDefaultLeaseTTL time.Duration
flagDescription string
flagListingVisibility string
flagMaxLeaseTTL time.Duration
flagOptions map[string]string
flagVersion int
flagAuditNonHMACRequestKeys []string
flagAuditNonHMACResponseKeys []string
flagDefaultLeaseTTL time.Duration
flagDescription string
flagListingVisibility string
flagMaxLeaseTTL time.Duration
flagPassthroughRequestHeaders []string
flagAllowedResponseHeaders []string
flagOptions map[string]string
flagVersion int
}

func (c *SecretsTuneCommand) Synopsis() string {
Expand Down Expand Up @@ -106,6 +108,20 @@ func (c *SecretsTuneCommand) Flags() *FlagSets {
"TTL, or a previously configured value for the secrets engine.",
})

f.StringSliceVar(&StringSliceVar{
Name: flagNamePassthroughRequestHeaders,
Target: &c.flagPassthroughRequestHeaders,
Usage: "Comma-separated string or list of request header values that " +
"will be sent to the plugin",
})

f.StringSliceVar(&StringSliceVar{
Name: flagNameAllowedResponseHeaders,
Target: &c.flagAllowedResponseHeaders,
Usage: "Comma-separated string or list of response header values that " +
"plugins will be allowed to set",
})

f.StringMapVar(&StringMapVar{
Name: "options",
Target: &c.flagOptions,
Expand Down Expand Up @@ -189,6 +205,14 @@ func (c *SecretsTuneCommand) Run(args []string) int {
if fl.Name == flagNameListingVisibility {
mountConfigInput.ListingVisibility = c.flagListingVisibility
}

if fl.Name == flagNamePassthroughRequestHeaders {
mountConfigInput.PassthroughRequestHeaders = c.flagPassthroughRequestHeaders
}

if fl.Name == flagNameAllowedResponseHeaders {
mountConfigInput.AllowedResponseHeaders = c.flagAllowedResponseHeaders
}
})

if err := client.Sys().TuneMount(mountPath, mountConfigInput); err != nil {
Expand Down
3 changes: 3 additions & 0 deletions command/secrets_tune_test.go
Expand Up @@ -166,6 +166,9 @@ func TestSecretsTuneCommand_Run(t *testing.T) {
"-max-lease-ttl", "1h",
"-audit-non-hmac-request-keys", "foo,bar",
"-audit-non-hmac-response-keys", "foo,bar",
"-passthrough-request-headers", "authorization",
ncabatoff marked this conversation as resolved.
Show resolved Hide resolved
"-passthrough-request-headers", "www-authentication",
"-allowed-response-headers", "authorization,www-authentication",
"-listing-visibility", "unauth",
"mount_tune_integration/",
})
Expand Down
92 changes: 83 additions & 9 deletions vault/logical_system.go
Expand Up @@ -13,6 +13,7 @@ import (
"net/http"
"path"
"path/filepath"
"reflect"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -898,6 +899,13 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d
var apiConfig APIMountConfig

configMap := data.Get("config").(map[string]interface{})
// Augmenting configMap for some config options to treat them as comma separated entries
err := augmentEnableAuthConfigMap(configMap)
if err != nil {
return logical.ErrorResponse(
"unable to parse given auth config information"),
logical.ErrInvalidRequest
}
if configMap != nil && len(configMap) != 0 {
err := mapstructure.Decode(configMap, &apiConfig)
if err != nil {
Expand Down Expand Up @@ -1309,6 +1317,19 @@ func (b *SystemBackend) handleMountTuneWrite(ctx context.Context, req *logical.R
return b.handleTuneWriteCommon(ctx, path, data)
}

func augmentTuneWriteParams(paramIn interface{}) ([]string, error) {
newVal := paramIn.([]string)
ncabatoff marked this conversation as resolved.
Show resolved Hide resolved
var outputSlice []string
for _, v := range newVal {
ncabatoff marked this conversation as resolved.
Show resolved Hide resolved
res, err := parseutil.ParseCommaStringSlice(v)
if err != nil {
return nil, err
}
outputSlice = append(outputSlice, res...)
}
return outputSlice, nil
}

// handleTuneWriteCommon is used to set config settings on a path
func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string, data *framework.FieldData) (*logical.Response, error) {
repState := b.Core.ReplicationState()
Expand Down Expand Up @@ -1418,13 +1439,15 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
}

if rawVal, ok := data.GetOk("audit_non_hmac_request_keys"); ok {
auditNonHMACRequestKeys := rawVal.([]string)
auditNonHMACRequestKeys, err := augmentTuneWriteParams(rawVal)
if err != nil {
return handleError(err)
}

oldVal := mountEntry.Config.AuditNonHMACRequestKeys
mountEntry.Config.AuditNonHMACRequestKeys = auditNonHMACRequestKeys

// Update the mount table
var err error
switch {
case strings.HasPrefix(path, "auth/"):
err = b.Core.persistAuth(ctx, b.Core.auth, &mountEntry.Local)
Expand All @@ -1444,13 +1467,15 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
}

if rawVal, ok := data.GetOk("audit_non_hmac_response_keys"); ok {
auditNonHMACResponseKeys := rawVal.([]string)
auditNonHMACResponseKeys, err := augmentTuneWriteParams(rawVal)
if err != nil {
return handleError(err)
}

oldVal := mountEntry.Config.AuditNonHMACResponseKeys
mountEntry.Config.AuditNonHMACResponseKeys = auditNonHMACResponseKeys

// Update the mount table
var err error
switch {
case strings.HasPrefix(path, "auth/"):
err = b.Core.persistAuth(ctx, b.Core.auth, &mountEntry.Local)
Expand Down Expand Up @@ -1537,13 +1562,15 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
}

if rawVal, ok := data.GetOk("passthrough_request_headers"); ok {
headers := rawVal.([]string)
headers, err := augmentTuneWriteParams(rawVal)
if err != nil {
return handleError(err)
}

oldVal := mountEntry.Config.PassthroughRequestHeaders
mountEntry.Config.PassthroughRequestHeaders = headers

// Update the mount table
var err error
switch {
case strings.HasPrefix(path, "auth/"):
err = b.Core.persistAuth(ctx, b.Core.auth, &mountEntry.Local)
Expand All @@ -1563,13 +1590,14 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
}

if rawVal, ok := data.GetOk("allowed_response_headers"); ok {
headers := rawVal.([]string)

headers, err := augmentTuneWriteParams(rawVal)
if err != nil {
return handleError(err)
}
oldVal := mountEntry.Config.AllowedResponseHeaders
mountEntry.Config.AllowedResponseHeaders = headers

// Update the mount table
var err error
switch {
case strings.HasPrefix(path, "auth/"):
err = b.Core.persistAuth(ctx, b.Core.auth, &mountEntry.Local)
Expand Down Expand Up @@ -1869,6 +1897,45 @@ func (b *SystemBackend) handleAuthTable(ctx context.Context, req *logical.Reques
return resp, nil
}

func augmentEnableAuthConfigMap(configMap map[string]interface{}) error {
hghaf099 marked this conversation as resolved.
Show resolved Hide resolved
configParamNameSlice := []string{
"audit_non_hmac_request_keys",
"audit_non_hmac_response_keys",
"passthrough_request_headers",
"allowed_response_headers",
}
for _, paramName := range configParamNameSlice {
if raw, ok := configMap[paramName]; ok {
outputSlice := []string{}

rt := reflect.TypeOf(raw)
ncabatoff marked this conversation as resolved.
Show resolved Hide resolved
switch rt.Kind() {
case reflect.Slice:
rawNew := raw.([]interface{})
for _, rawVal := range rawNew {
rawValSt := rawVal.(string)
hghaf099 marked this conversation as resolved.
Show resolved Hide resolved
res, err := parseutil.ParseCommaStringSlice(rawValSt)
if err != nil {
return err
}
outputSlice = append(outputSlice, res...)
}
case reflect.String:
rawNew := raw.(string)
res, err := parseutil.ParseCommaStringSlice(rawNew)
if err != nil {
return err
}
outputSlice = append(outputSlice, res...)
default:
return fmt.Errorf("Invalid input parameter type for %v", paramName)
}
configMap[paramName] = outputSlice
}
}
return nil
}

// handleEnableAuth is used to enable a new credential backend
func (b *SystemBackend) handleEnableAuth(ctx context.Context, req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
repState := b.Core.ReplicationState()
Expand All @@ -1895,6 +1962,13 @@ func (b *SystemBackend) handleEnableAuth(ctx context.Context, req *logical.Reque
var apiConfig APIMountConfig

configMap := data.Get("config").(map[string]interface{})
// Augmenting configMap for some config options to treat them as comma separated entries
err := augmentEnableAuthConfigMap(configMap)
if err != nil {
return logical.ErrorResponse(
ncabatoff marked this conversation as resolved.
Show resolved Hide resolved
"unable to parse given auth config information"),
logical.ErrInvalidRequest
}
if configMap != nil && len(configMap) != 0 {
err := mapstructure.Decode(configMap, &apiConfig)
if err != nil {
Expand Down
15 changes: 15 additions & 0 deletions website/content/docs/commands/auth/enable.mdx
Expand Up @@ -57,12 +57,27 @@ flags](/docs/commands) included on all commands.
configured default lease TTL, or a previously configured value for the auth
method.

- `-passthrough-request-headers` `(string: "")` - request header values that will
be sent to the plugin.
hghaf099 marked this conversation as resolved.
Show resolved Hide resolved
hghaf099 marked this conversation as resolved.
Show resolved Hide resolved

- `-allowed-response-headers` `(string: "")` - response header values that plugins
hghaf099 marked this conversation as resolved.
Show resolved Hide resolved
will be allowed to set.

- `-description` `(string: "")` - Human-friendly description for the purpose of
this auth method.

- `-listing-visibility` `(string: "")` - The flag to toggle whether to show the
mount in the UI-specific listing endpoint.

- `-local` `(bool: false)` - Mark the auth method as local-only. Local auth
methods are not replicated nor removed by replication.

- `-max-lease-ttl` `(string: "")` - The maximum lease duration, specified as
a string duration like "5s" or "30m".

- `-path` `(string: "")` - Place where the auth method will be accessible. This
must be unique across all auth methods. This defaults to the "type" of the
auth method. The auth method will be accessible at `/auth/<path>`.

- `-seal-wrap` `(bool: false)` - Enable seal wrapping for the mount, causing
values stored by the mount to be wrapped by the seal's encryption capability.