mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 03:27:54 +00:00
backport of commit 2f677665b3 (#21527)
Co-authored-by: Max Bowsher <maxbowsher@gmail.com>
This commit is contained in:
committed by
GitHub
parent
50c8e7f5c2
commit
3bd61e99e7
@@ -40,7 +40,7 @@ const (
|
|||||||
// path matches that path or not (useful specifically for the paths that
|
// path matches that path or not (useful specifically for the paths that
|
||||||
// contain templated fields.)
|
// contain templated fields.)
|
||||||
var sudoPaths = map[string]*regexp.Regexp{
|
var sudoPaths = map[string]*regexp.Regexp{
|
||||||
"/auth/token/accessors/": regexp.MustCompile(`^/auth/token/accessors/?$`),
|
"/auth/token/accessors": regexp.MustCompile(`^/auth/token/accessors/?$`),
|
||||||
"/pki/root": regexp.MustCompile(`^/pki/root$`),
|
"/pki/root": regexp.MustCompile(`^/pki/root$`),
|
||||||
"/pki/root/sign-self-issued": regexp.MustCompile(`^/pki/root/sign-self-issued$`),
|
"/pki/root/sign-self-issued": regexp.MustCompile(`^/pki/root/sign-self-issued$`),
|
||||||
"/sys/audit": regexp.MustCompile(`^/sys/audit$`),
|
"/sys/audit": regexp.MustCompile(`^/sys/audit$`),
|
||||||
@@ -50,7 +50,7 @@ var sudoPaths = map[string]*regexp.Regexp{
|
|||||||
"/sys/config/auditing/request-headers": regexp.MustCompile(`^/sys/config/auditing/request-headers$`),
|
"/sys/config/auditing/request-headers": regexp.MustCompile(`^/sys/config/auditing/request-headers$`),
|
||||||
"/sys/config/auditing/request-headers/{header}": regexp.MustCompile(`^/sys/config/auditing/request-headers/.+$`),
|
"/sys/config/auditing/request-headers/{header}": regexp.MustCompile(`^/sys/config/auditing/request-headers/.+$`),
|
||||||
"/sys/config/cors": regexp.MustCompile(`^/sys/config/cors$`),
|
"/sys/config/cors": regexp.MustCompile(`^/sys/config/cors$`),
|
||||||
"/sys/config/ui/headers/": regexp.MustCompile(`^/sys/config/ui/headers/?$`),
|
"/sys/config/ui/headers": regexp.MustCompile(`^/sys/config/ui/headers/?$`),
|
||||||
"/sys/config/ui/headers/{header}": regexp.MustCompile(`^/sys/config/ui/headers/.+$`),
|
"/sys/config/ui/headers/{header}": regexp.MustCompile(`^/sys/config/ui/headers/.+$`),
|
||||||
"/sys/leases": regexp.MustCompile(`^/sys/leases$`),
|
"/sys/leases": regexp.MustCompile(`^/sys/leases$`),
|
||||||
"/sys/leases/lookup/": regexp.MustCompile(`^/sys/leases/lookup/?$`),
|
"/sys/leases/lookup/": regexp.MustCompile(`^/sys/leases/lookup/?$`),
|
||||||
@@ -249,7 +249,9 @@ func SudoPaths() map[string]*regexp.Regexp {
|
|||||||
return sudoPaths
|
return sudoPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine whether the given path requires the sudo capability
|
// Determine whether the given path requires the sudo capability.
|
||||||
|
// Note that this uses hardcoded static path information, so will return incorrect results for paths in namespaces,
|
||||||
|
// or for secret engines mounted at non-default paths.
|
||||||
func IsSudoPath(path string) bool {
|
func IsSudoPath(path string) bool {
|
||||||
// Return early if the path is any of the non-templated sudo paths.
|
// Return early if the path is any of the non-templated sudo paths.
|
||||||
if _, ok := sudoPaths[path]; ok {
|
if _, ok := sudoPaths[path]; ok {
|
||||||
|
|||||||
@@ -12,10 +12,12 @@ func TestIsSudoPath(t *testing.T) {
|
|||||||
path string
|
path string
|
||||||
expected bool
|
expected bool
|
||||||
}{
|
}{
|
||||||
|
// Testing: Not a real endpoint
|
||||||
{
|
{
|
||||||
"/not/in/sudo/paths/list",
|
"/not/in/sudo/paths/list",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
// Testing: sys/raw/{path}
|
||||||
{
|
{
|
||||||
"/sys/raw/single-node-path",
|
"/sys/raw/single-node-path",
|
||||||
true,
|
true,
|
||||||
@@ -28,26 +30,43 @@ func TestIsSudoPath(t *testing.T) {
|
|||||||
"/sys/raw/WEIRD(but_still_valid!)p4Th?🗿笑",
|
"/sys/raw/WEIRD(but_still_valid!)p4Th?🗿笑",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
// Testing: sys/auth/{path}/tune
|
||||||
{
|
{
|
||||||
"/sys/auth/path/in/middle/tune",
|
"/sys/auth/path/in/middle/tune",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
// Testing: sys/plugins/catalog/{type} and sys/plugins/catalog/{name} (regexes overlap)
|
||||||
{
|
{
|
||||||
"/sys/plugins/catalog/some-type",
|
"/sys/plugins/catalog/some-type",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
// Testing: Not a real endpoint
|
||||||
{
|
{
|
||||||
"/sys/plugins/catalog/some/type/or/name/with/slashes",
|
"/sys/plugins/catalog/some/type/or/name/with/slashes",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
// Testing: sys/plugins/catalog/{type}/{name}
|
||||||
{
|
{
|
||||||
"/sys/plugins/catalog/some-type/some-name",
|
"/sys/plugins/catalog/some-type/some-name",
|
||||||
true,
|
true,
|
||||||
},
|
},
|
||||||
|
// Testing: Not a real endpoint
|
||||||
{
|
{
|
||||||
"/sys/plugins/catalog/some-type/some/name/with/slashes",
|
"/sys/plugins/catalog/some-type/some/name/with/slashes",
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
// Testing: auth/token/accessors (an example of a sudo path that only accepts list operations)
|
||||||
|
// It is matched as sudo without the trailing slash...
|
||||||
|
{
|
||||||
|
"/auth/token/accessors",
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
// ...and also with it.
|
||||||
|
// (Although at the time of writing, the only caller of IsSudoPath always removes trailing slashes.)
|
||||||
|
{
|
||||||
|
"/auth/token/accessors/",
|
||||||
|
true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
|
|||||||
3
changelog/18571.txt
Normal file
3
changelog/18571.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:bug
|
||||||
|
auth/token, sys: Fix path-help being unavailable for some list-only endpoints
|
||||||
|
```
|
||||||
@@ -56,6 +56,17 @@ type Path struct {
|
|||||||
// This should be a valid regular expression. Named captures will be
|
// This should be a valid regular expression. Named captures will be
|
||||||
// exposed as fields that should map to a schema in Fields. If a named
|
// exposed as fields that should map to a schema in Fields. If a named
|
||||||
// capture is not a field in the Fields map, then it will be ignored.
|
// capture is not a field in the Fields map, then it will be ignored.
|
||||||
|
//
|
||||||
|
// The pattern will automatically have a ^ prepended and a $ appended before
|
||||||
|
// use, if these are not already present, so these may be omitted for clarity.
|
||||||
|
//
|
||||||
|
// If a ListOperation is being defined, the pattern must end with /? to match
|
||||||
|
// a trailing slash optionally, as ListOperations are always processed with a
|
||||||
|
// trailing slash added to the path if not already present. The match must not
|
||||||
|
// require the presence of a trailing slash, as HelpOperations, even for a
|
||||||
|
// path which only implements ListOperation, are processed without a trailing
|
||||||
|
// slash - so failure to make the trailing slash optional will break the
|
||||||
|
// `vault path-help` command for the path.
|
||||||
Pattern string
|
Pattern string
|
||||||
|
|
||||||
// Fields is the mapping of data fields to a schema describing that
|
// Fields is the mapping of data fields to a schema describing that
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ func (b *SystemBackend) configPaths() []*framework.Path {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
Pattern: "config/ui/headers/$",
|
Pattern: "config/ui/headers/?$",
|
||||||
|
|
||||||
Operations: map[logical.Operation]framework.OperationHandler{
|
Operations: map[logical.Operation]framework.OperationHandler{
|
||||||
logical.ListOperation: &framework.PathOperation{
|
logical.ListOperation: &framework.PathOperation{
|
||||||
@@ -1452,7 +1452,7 @@ func (b *SystemBackend) statusPaths() []*framework.Path {
|
|||||||
HelpDescription: strings.TrimSpace(sysHelp["ha-status"][1]),
|
HelpDescription: strings.TrimSpace(sysHelp["ha-status"][1]),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Pattern: "version-history/$",
|
Pattern: "version-history/?$",
|
||||||
|
|
||||||
DisplayAttrs: &framework.DisplayAttributes{
|
DisplayAttrs: &framework.DisplayAttributes{
|
||||||
OperationVerb: "version-history",
|
OperationVerb: "version-history",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
func (b *SystemBackend) pprofPaths() []*framework.Path {
|
func (b *SystemBackend) pprofPaths() []*framework.Path {
|
||||||
return []*framework.Path{
|
return []*framework.Path{
|
||||||
{
|
{
|
||||||
Pattern: "pprof/$",
|
Pattern: "pprof/?$",
|
||||||
|
|
||||||
DisplayAttrs: &framework.DisplayAttributes{
|
DisplayAttrs: &framework.DisplayAttributes{
|
||||||
OperationPrefix: "pprof",
|
OperationPrefix: "pprof",
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ func (ts *TokenStore) paths() []*framework.Path {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
Pattern: "accessors/$",
|
Pattern: "accessors/?$",
|
||||||
|
|
||||||
DisplayAttrs: &framework.DisplayAttributes{
|
DisplayAttrs: &framework.DisplayAttributes{
|
||||||
OperationPrefix: operationPrefixToken,
|
OperationPrefix: operationPrefixToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user