When tainting a route during setup, pre-calculate the namespace specific path (#15067)

This commit is contained in:
Josh Black 2022-04-26 09:13:45 -07:00 committed by GitHub
parent d6933e9ef4
commit a4593e8913
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 12 deletions

3
changelog/15067.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
core: pre-calculate namespace specific paths when tainting a route during postUnseal
```

View File

@ -3,6 +3,7 @@ package namespace
import (
"context"
"errors"
"fmt"
"strings"
"github.com/hashicorp/vault/sdk/helper/consts"
@ -15,6 +16,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"
)

View File

@ -7,7 +7,7 @@ import (
"strings"
"github.com/hashicorp/go-secure-stdlib/strutil"
uuid "github.com/hashicorp/go-uuid"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/vault/builtin/plugin"
"github.com/hashicorp/vault/helper/namespace"
"github.com/hashicorp/vault/sdk/helper/consts"
@ -825,16 +825,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)
}

View File

@ -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"
)

View File

@ -9,9 +9,9 @@ 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"
@ -47,6 +47,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
}
@ -530,7 +532,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{
@ -551,7 +553,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
@ -560,7 +562,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
}
}

View File

@ -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"
)