From d403d5ac8c6f2d832eeb3eb89bb4ef26bdb6cdc7 Mon Sep 17 00:00:00 2001 From: Josh Black <raskchanky@users.noreply.github.com> Date: Tue, 26 Apr 2022 09:13:45 -0700 Subject: [PATCH 1/2] When tainting a route during setup, pre-calculate the namespace specific path (#15067) --- changelog/15067.txt | 3 +++ helper/namespace/namespace.go | 5 +++++ vault/auth.go | 10 +++++++--- vault/rollback_test.go | 3 +-- vault/router.go | 15 +++++++++------ vault/router_test.go | 2 +- 6 files changed, 26 insertions(+), 12 deletions(-) create mode 100644 changelog/15067.txt diff --git a/changelog/15067.txt b/changelog/15067.txt new file mode 100644 index 000000000000..4adee8fb6a49 --- /dev/null +++ b/changelog/15067.txt @@ -0,0 +1,3 @@ +```release-note:bug +core: pre-calculate namespace specific paths when tainting a route during postUnseal +``` diff --git a/helper/namespace/namespace.go b/helper/namespace/namespace.go index 1b59495cab84..6e042f84689c 100644 --- a/helper/namespace/namespace.go +++ b/helper/namespace/namespace.go @@ -3,6 +3,7 @@ package namespace import ( "context" "errors" + "fmt" "strings" ) @@ -13,6 +14,10 @@ type Namespace struct { Path string `json:"path"` } +func (n *Namespace) String() string { + return fmt.Sprintf("ID: %s. Path: %s", n.ID, n.Path) +} + const ( RootNamespaceID = "root" ) diff --git a/vault/auth.go b/vault/auth.go index 74b6a3391052..c7ffe57a27ad 100644 --- a/vault/auth.go +++ b/vault/auth.go @@ -6,7 +6,8 @@ import ( "fmt" "strings" - uuid "github.com/hashicorp/go-uuid" + "github.com/hashicorp/go-secure-stdlib/strutil" + "github.com/hashicorp/go-uuid" "github.com/hashicorp/vault/builtin/plugin" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/consts" @@ -723,16 +724,19 @@ func (c *Core) setupCredentials(ctx context.Context) error { path := credentialRoutePrefix + entry.Path err = c.router.Mount(backend, path, entry, view) if err != nil { - c.logger.Error("failed to mount auth entry", "path", entry.Path, "error", err) + c.logger.Error("failed to mount auth entry", "path", entry.Path, "namespace", entry.Namespace(), "error", err) return errLoadAuthFailed } if c.logger.IsInfo() { - c.logger.Info("successfully enabled credential backend", "type", entry.Type, "path", entry.Path) + c.logger.Info("successfully enabled credential backend", "type", entry.Type, "path", entry.Path, "namespace", entry.Namespace()) } // Ensure the path is tainted if set in the mount table if entry.Tainted { + // Calculate any namespace prefixes here, because when Taint() is called, there won't be + // a namespace to pull from the context. This is similar to what we do above in c.router.Mount(). + path = entry.Namespace().Path + path c.router.Taint(ctx, path) } diff --git a/vault/rollback_test.go b/vault/rollback_test.go index 4308d70e1c2e..681101217a30 100644 --- a/vault/rollback_test.go +++ b/vault/rollback_test.go @@ -7,8 +7,7 @@ import ( "time" log "github.com/hashicorp/go-hclog" - uuid "github.com/hashicorp/go-uuid" - + "github.com/hashicorp/go-uuid" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/logging" ) diff --git a/vault/router.go b/vault/router.go index be067f78a28e..85e3d9b9bc74 100644 --- a/vault/router.go +++ b/vault/router.go @@ -8,9 +8,10 @@ import ( "sync/atomic" "time" - metrics "github.com/armon/go-metrics" - radix "github.com/armon/go-radix" - hclog "github.com/hashicorp/go-hclog" + "github.com/armon/go-metrics" + "github.com/armon/go-radix" + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/salt" @@ -43,6 +44,8 @@ func NewRouter() *Router { storagePrefix: radix.New(), mountUUIDCache: radix.New(), mountAccessorCache: radix.New(), + // this will get replaced in production with a real logger but it's useful to have a default in place for tests + logger: hclog.NewNullLogger(), } return r } @@ -509,7 +512,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc } r.l.RUnlock() if !ok { - return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath + return logical.ErrorResponse(fmt.Sprintf("no handler for route %q. route entry not found.", req.Path)), false, false, logical.ErrUnsupportedPath } req.Path = adjustedPath defer metrics.MeasureSince([]string{ @@ -530,7 +533,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc // Filtered mounts will have a nil backend if re.backend == nil { - return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath + return logical.ErrorResponse(fmt.Sprintf("no handler for route %q. route entry found, but backend is nil.", req.Path)), false, false, logical.ErrUnsupportedPath } // If the path is tainted, we reject any operation except for @@ -539,7 +542,7 @@ func (r *Router) routeCommon(ctx context.Context, req *logical.Request, existenc switch req.Operation { case logical.RevokeOperation, logical.RollbackOperation: default: - return logical.ErrorResponse(fmt.Sprintf("no handler for route '%s'", req.Path)), false, false, logical.ErrUnsupportedPath + return logical.ErrorResponse(fmt.Sprintf("no handler for route %q. route entry is tainted.", req.Path)), false, false, logical.ErrUnsupportedPath } } diff --git a/vault/router_test.go b/vault/router_test.go index b20b69894fe4..2663cd203f61 100644 --- a/vault/router_test.go +++ b/vault/router_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - uuid "github.com/hashicorp/go-uuid" + "github.com/hashicorp/go-uuid" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/logical" ) From 06f5a329a425b5095491d1cac1d2b34b57124956 Mon Sep 17 00:00:00 2001 From: Josh Black <raskchanky@gmail.com> Date: Wed, 27 Apr 2022 11:40:54 -0700 Subject: [PATCH 2/2] remove the stdlib dep --- vault/auth.go | 1 - vault/router.go | 1 - 2 files changed, 2 deletions(-) diff --git a/vault/auth.go b/vault/auth.go index c7ffe57a27ad..def7bf3648a6 100644 --- a/vault/auth.go +++ b/vault/auth.go @@ -6,7 +6,6 @@ import ( "fmt" "strings" - "github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/go-uuid" "github.com/hashicorp/vault/builtin/plugin" "github.com/hashicorp/vault/helper/namespace" diff --git a/vault/router.go b/vault/router.go index 85e3d9b9bc74..367d8be162bf 100644 --- a/vault/router.go +++ b/vault/router.go @@ -11,7 +11,6 @@ import ( "github.com/armon/go-metrics" "github.com/armon/go-radix" "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/vault/helper/namespace" "github.com/hashicorp/vault/sdk/helper/consts" "github.com/hashicorp/vault/sdk/helper/salt"