mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-05 12:26:34 +02:00
Add_Chroot_Namespace_In_Response (#24355)
This commit is contained in:
parent
aa9b02307d
commit
6e020e38e0
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -2642,6 +2642,10 @@ func (b *SystemBackend) internalPaths() []*framework.Path {
|
||||
Type: framework.TypeMap,
|
||||
Required: false,
|
||||
},
|
||||
"chroot_namespace": {
|
||||
Type: framework.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
}},
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user