Add_Chroot_Namespace_In_Response (#24355)

This commit is contained in:
divyaac 2023-12-04 14:51:44 -08:00 committed by GitHub
parent aa9b02307d
commit 6e020e38e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 40 additions and 25 deletions

View File

@ -151,6 +151,10 @@ func handler(props *vault.HandlerProperties) http.Handler {
// Create the muxer to handle the actual endpoints
mux := http.NewServeMux()
var chrootNamespace string
if props.ListenerConfig != nil {
chrootNamespace = props.ListenerConfig.ChrootNamespace
}
switch {
case props.RecoveryMode:
@ -161,8 +165,8 @@ func handler(props *vault.HandlerProperties) http.Handler {
mux.Handle("/v1/sys/generate-recovery-token/update", handleSysGenerateRootUpdate(core, strategy))
default:
// Handle non-forwarded paths
mux.Handle("/v1/sys/config/state/", handleLogicalNoForward(core))
mux.Handle("/v1/sys/host-info", handleLogicalNoForward(core))
mux.Handle("/v1/sys/config/state/", handleLogicalNoForward(core, chrootNamespace))
mux.Handle("/v1/sys/host-info", handleLogicalNoForward(core, chrootNamespace))
mux.Handle("/v1/sys/init", handleSysInit(core))
mux.Handle("/v1/sys/seal-status", handleSysSealStatus(core,
@ -177,7 +181,7 @@ func handler(props *vault.HandlerProperties) http.Handler {
mux.Handle("/v1/sys/health", handleSysHealth(core,
WithRedactClusterName(props.ListenerConfig.RedactClusterName),
WithRedactVersion(props.ListenerConfig.RedactVersion)))
mux.Handle("/v1/sys/monitor", handleLogicalNoForward(core))
mux.Handle("/v1/sys/monitor", handleLogicalNoForward(core, chrootNamespace))
mux.Handle("/v1/sys/generate-root/attempt", handleRequestForwarding(core,
handleAuditNonLogical(core, handleSysGenerateRootAttempt(core, vault.GenerateStandardRootTokenStrategy))))
mux.Handle("/v1/sys/generate-root/update", handleRequestForwarding(core,
@ -193,10 +197,10 @@ func handler(props *vault.HandlerProperties) http.Handler {
mux.Handle("/v1/sys/internal/ui/feature-flags", handleSysInternalFeatureFlags(core))
for _, path := range injectDataIntoTopRoutes {
mux.Handle(path, handleRequestForwarding(core, handleLogicalWithInjector(core)))
mux.Handle(path, handleRequestForwarding(core, handleLogicalWithInjector(core, chrootNamespace)))
}
mux.Handle("/v1/sys/", handleRequestForwarding(core, handleLogical(core)))
mux.Handle("/v1/", handleRequestForwarding(core, handleLogical(core)))
mux.Handle("/v1/sys/", handleRequestForwarding(core, handleLogical(core, chrootNamespace)))
mux.Handle("/v1/", handleRequestForwarding(core, handleLogical(core, chrootNamespace)))
if core.UIEnabled() {
if uiBuiltIn {
mux.Handle("/ui/", http.StripPrefix("/ui/", gziphandler.GzipHandler(handleUIHeaders(core, handleUI(http.FileServer(&UIAssetWrapper{FileSystem: assetFS()}))))))
@ -213,7 +217,7 @@ func handler(props *vault.HandlerProperties) http.Handler {
if props.ListenerConfig != nil && props.ListenerConfig.Telemetry.UnauthenticatedMetricsAccess {
mux.Handle("/v1/sys/metrics", handleMetricsUnauthenticated(core))
} else {
mux.Handle("/v1/sys/metrics", handleLogicalNoForward(core))
mux.Handle("/v1/sys/metrics", handleLogicalNoForward(core, chrootNamespace))
}
if props.ListenerConfig != nil && props.ListenerConfig.Profiling.UnauthenticatedPProfAccess {
@ -226,13 +230,13 @@ func handler(props *vault.HandlerProperties) http.Handler {
mux.Handle("/v1/sys/pprof/symbol", http.HandlerFunc(pprof.Symbol))
mux.Handle("/v1/sys/pprof/trace", http.HandlerFunc(pprof.Trace))
} else {
mux.Handle("/v1/sys/pprof/", handleLogicalNoForward(core))
mux.Handle("/v1/sys/pprof/", handleLogicalNoForward(core, chrootNamespace))
}
if props.ListenerConfig != nil && props.ListenerConfig.InFlightRequestLogging.UnauthenticatedInFlightAccess {
mux.Handle("/v1/sys/in-flight-req", handleUnAuthenticatedInFlightRequest(core))
} else {
mux.Handle("/v1/sys/in-flight-req", handleLogicalNoForward(core))
mux.Handle("/v1/sys/in-flight-req", handleLogicalNoForward(core, chrootNamespace))
}
entAdditionalRoutes(mux, core)
}

View File

@ -257,11 +257,12 @@ func buildLogicalPath(r *http.Request) (string, int, error) {
return path, 0, nil
}
func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Request) (*logical.Request, io.ReadCloser, int, error) {
func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Request, chrootNamespace string) (*logical.Request, io.ReadCloser, int, error) {
req, origBody, status, err := buildLogicalRequestNoAuth(core.PerfStandby(), core.RouterAccess(), w, r)
if err != nil || status != 0 {
return nil, nil, status, err
}
req.ChrootNamespace = chrootNamespace
req.SetRequiredState(r.Header.Values(VaultIndexHeaderName))
requestAuth(r, req)
@ -290,22 +291,22 @@ func buildLogicalRequest(core *vault.Core, w http.ResponseWriter, r *http.Reques
// - Perf standby and token with limited use count.
// - Perf standby and token re-validation needed (e.g. due to invalid token).
// - Perf standby and control group error.
func handleLogical(core *vault.Core) http.Handler {
return handleLogicalInternal(core, false, false)
func handleLogical(core *vault.Core, chrootNamespace string) http.Handler {
return handleLogicalInternal(core, false, false, chrootNamespace)
}
// handleLogicalWithInjector returns a handler for processing logical requests
// that also have their logical response data injected at the top-level payload.
// All forwarding behavior remains the same as `handleLogical`.
func handleLogicalWithInjector(core *vault.Core) http.Handler {
return handleLogicalInternal(core, true, false)
func handleLogicalWithInjector(core *vault.Core, chrootNamespace string) http.Handler {
return handleLogicalInternal(core, true, false, chrootNamespace)
}
// handleLogicalNoForward returns a handler for processing logical local-only
// requests. These types of requests never forwarded, and return an
// `vault.ErrCannotForwardLocalOnly` error if attempted to do so.
func handleLogicalNoForward(core *vault.Core) http.Handler {
return handleLogicalInternal(core, false, true)
func handleLogicalNoForward(core *vault.Core, chrootNamespace string) http.Handler {
return handleLogicalInternal(core, false, true, chrootNamespace)
}
func handleLogicalRecovery(raw *vault.RawBackend, token *atomic.String) http.Handler {
@ -338,9 +339,9 @@ func handleLogicalRecovery(raw *vault.RawBackend, token *atomic.String) http.Han
// handleLogicalInternal is a common helper that returns a handler for
// processing logical requests. The behavior depends on the various boolean
// toggles. Refer to usage on functions for possible behaviors.
func handleLogicalInternal(core *vault.Core, injectDataIntoTopLevel bool, noForward bool) http.Handler {
func handleLogicalInternal(core *vault.Core, injectDataIntoTopLevel bool, noForward bool, chrootNamespace string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
req, origBody, statusCode, err := buildLogicalRequest(core, w, r)
req, origBody, statusCode, err := buildLogicalRequest(core, w, r, chrootNamespace)
if err != nil || statusCode != 0 {
respondError(w, statusCode, err)
return

View File

@ -323,7 +323,7 @@ func TestLogical_ListSuffix(t *testing.T) {
req = req.WithContext(namespace.RootContext(nil))
req.Header.Add(consts.AuthHeaderName, rootToken)
lreq, _, status, err := buildLogicalRequest(core, nil, req)
lreq, _, status, err := buildLogicalRequest(core, nil, req, "")
if err != nil {
t.Fatal(err)
}
@ -338,7 +338,7 @@ func TestLogical_ListSuffix(t *testing.T) {
req = req.WithContext(namespace.RootContext(nil))
req.Header.Add(consts.AuthHeaderName, rootToken)
lreq, _, status, err = buildLogicalRequest(core, nil, req)
lreq, _, status, err = buildLogicalRequest(core, nil, req, "")
if err != nil {
t.Fatal(err)
}
@ -358,7 +358,7 @@ func TestLogical_ListSuffix(t *testing.T) {
t.Fatal(err)
}
lreq, _, status, err = buildLogicalRequest(core, nil, req)
lreq, _, status, err = buildLogicalRequest(core, nil, req, "")
if err != nil {
t.Fatal(err)
}
@ -517,7 +517,7 @@ func TestLogical_ListWithQueryParameters(t *testing.T) {
req = req.WithContext(namespace.RootContext(nil))
req.Header.Add(consts.AuthHeaderName, rootToken)
lreq, _, status, err := buildLogicalRequest(core, nil, req)
lreq, _, status, err := buildLogicalRequest(core, nil, req, "")
if err != nil {
t.Fatal(err)
}

View File

@ -18,7 +18,7 @@ import (
func handleSysSeal(core *vault.Core) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
req, _, statusCode, err := buildLogicalRequest(core, w, r)
req, _, statusCode, err := buildLogicalRequest(core, w, r, "")
if err != nil || statusCode != 0 {
respondError(w, statusCode, err)
return
@ -48,7 +48,7 @@ func handleSysSeal(core *vault.Core) http.Handler {
func handleSysStepDown(core *vault.Core) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
req, _, statusCode, err := buildLogicalRequest(core, w, r)
req, _, statusCode, err := buildLogicalRequest(core, w, r, "")
if err != nil || statusCode != 0 {
respondError(w, statusCode, err)
return

View File

@ -248,6 +248,9 @@ type Request struct {
// When a request has been forwarded, contains information of the host the request was forwarded 'from'
ForwardedFrom string `json:"forwarded_from,omitempty"`
// Name of the chroot namespace for the listener that the request was made against
ChrootNamespace string `json:"chroot_namespace,omitempty"`
}
// Clone returns a deep copy of the request by using copystructure

View File

@ -4708,6 +4708,8 @@ func (b *SystemBackend) pathInternalUIResultantACL(ctx context.Context, req *log
},
}
resp.Data["chroot_namespace"] = req.ChrootNamespace
if acl.root {
resp.Data["root"] = true
return resp, nil

View File

@ -144,7 +144,8 @@ func TestSystemBackend_InternalUIResultantACL(t *testing.T) {
},
},
},
"root": false,
"root": false,
"chroot_namespace": "",
}
if diff := deep.Equal(resp.Data, exp); diff != nil {

View File

@ -2642,6 +2642,10 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
Type: framework.TypeMap,
Required: false,
},
"chroot_namespace": {
Type: framework.TypeString,
Required: true,
},
},
}},
},