Skip to content

Commit

Permalink
Handle permission issue on pki health-check tune checkers (hashicorp#…
Browse files Browse the repository at this point in the history
…19276)

* Handle permission issue on pki health-check tune checkers

 - Prior to this fix, if the end-user's Vault token did not have permission to the
   mount's tune api, we would return as if the tunable params had not been set.
 - Now check to see if we encountered a permission issue and report that back to
   the end-user like the other checks do.
  • Loading branch information
stevendpclark authored Feb 22, 2023
1 parent 4df7c64 commit fe7eeda
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 19 deletions.
3 changes: 3 additions & 0 deletions changelog/19276.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
cli/pki: Properly report permission issues within health-check mount tune checks
```
35 changes: 27 additions & 8 deletions command/healthcheck/pki_allow_if_modified_since.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type AllowIfModifiedSince struct {
UnsupportedVersion bool

TuneData map[string]interface{}
Fetcher *PathFetch
}

func NewAllowIfModifiedSinceCheck() Check {
Expand Down Expand Up @@ -42,15 +43,16 @@ func (h *AllowIfModifiedSince) LoadConfig(config map[string]interface{}) error {
}

func (h *AllowIfModifiedSince) FetchResources(e *Executor) error {
exit, _, data, err := fetchMountTune(e, func() {
var exit bool
var err error

exit, h.Fetcher, h.TuneData, err = fetchMountTune(e, func() {
h.UnsupportedVersion = true
})
if exit {

if exit || err != nil {
return err
}

h.TuneData = data

return nil
}

Expand All @@ -59,11 +61,28 @@ func (h *AllowIfModifiedSince) Evaluate(e *Executor) (results []*Result, err err
ret := Result{
Status: ResultInvalidVersion,
Endpoint: "/sys/mounts/{{mount}}/tune",
Message: "This health check requires Vault 1.9+ but an earlier version of Vault Server was contacted, preventing this health check from running.",
Message: "This health check requires Vault 1.12+ but an earlier version of Vault Server was contacted, preventing this health check from running.",
}
return []*Result{&ret}, nil
}

if h.Fetcher.IsSecretPermissionsError() {
ret := Result{
Status: ResultInsufficientPermissions,
Endpoint: "/sys/mounts/{{mount}}/tune",
Message: "Without this information, this health check is unable to function.",
}

if e.Client.Token() == "" {
ret.Message = "No token available so unable read the tune endpoint for this mount. " + ret.Message
} else {
ret.Message = "This token lacks permission to read the tune endpoint for this mount. " + ret.Message
}

results = append(results, &ret)
return
}

req, err := StringList(h.TuneData["passthrough_request_headers"])
if err != nil {
return nil, fmt.Errorf("unable to parse value from server for passthrough_request_headers: %w", err)
Expand All @@ -74,15 +93,15 @@ func (h *AllowIfModifiedSince) Evaluate(e *Executor) (results []*Result, err err
return nil, fmt.Errorf("unable to parse value from server for allowed_response_headers: %w", err)
}

var foundIMS bool = false
foundIMS := false
for _, param := range req {
if strings.EqualFold(param, "If-Modified-Since") {
foundIMS = true
break
}
}

var foundLM bool = false
foundLM := false
for _, param := range resp {
if strings.EqualFold(param, "Last-Modified") {
foundLM = true
Expand Down
34 changes: 26 additions & 8 deletions command/healthcheck/pki_audit_visibility.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type AuditVisibility struct {

IgnoredParameters map[string]bool
TuneData map[string]interface{}
Fetcher *PathFetch
}

func NewAuditVisibilityCheck() Check {
Expand Down Expand Up @@ -100,29 +101,46 @@ func (h *AuditVisibility) LoadConfig(config map[string]interface{}) error {
}

func (h *AuditVisibility) FetchResources(e *Executor) error {
exit, _, data, err := fetchMountTune(e, func() {
var exit bool
var err error

exit, h.Fetcher, h.TuneData, err = fetchMountTune(e, func() {
h.UnsupportedVersion = true
})
if exit {

if exit || err != nil {
return err
}

h.TuneData = data

return nil
}

func (h *AuditVisibility) Evaluate(e *Executor) (results []*Result, err error) {
if h.UnsupportedVersion {
// Shouldn't happen; /certs has been around forever.
ret := Result{
Status: ResultInvalidVersion,
Endpoint: "/{{mount}}/certs",
Message: "This health check requires Vault 1.11+ but an earlier version of Vault Server was contacted, preventing this health check from running.",
Endpoint: "/sys/mounts/{{mount}}/tune",
Message: "This health check requires Vault 1.9+ but an earlier version of Vault Server was contacted, preventing this health check from running.",
}
return []*Result{&ret}, nil
}

if h.Fetcher.IsSecretPermissionsError() {
ret := Result{
Status: ResultInsufficientPermissions,
Endpoint: "/sys/mounts/{{mount}}/tune",
Message: "Without this information, this health check is unable to function.",
}

if e.Client.Token() == "" {
ret.Message = "No token available so unable read the tune endpoint for this mount. " + ret.Message
} else {
ret.Message = "This token lacks permission to read the tune endpoint for this mount. " + ret.Message
}

results = append(results, &ret)
return
}

sourceMap := map[string][]string{
"audit_non_hmac_request_keys": VisibleReqParams,
"audit_non_hmac_response_keys": VisibleRespParams,
Expand Down
2 changes: 1 addition & 1 deletion command/healthcheck/pki_tidy_last_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func (h *TidyLastRun) Evaluate(e *Executor) (results []*Result, err error) {
ret := Result{
Status: ResultInsufficientPermissions,
Endpoint: "/{{mount}}/tidy-status",
Message: "Without this information, this health check is unable tof unction.",
Message: "Without this information, this health check is unable to function.",
}

if e.Client.Token() == "" {
Expand Down
4 changes: 2 additions & 2 deletions command/healthcheck/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ func StringList(source interface{}) ([]string, error) {
func fetchMountTune(e *Executor, versionError func()) (bool, *PathFetch, map[string]interface{}, error) {
tuneRet, err := e.FetchIfNotFetched(logical.ReadOperation, "/sys/mounts/{{mount}}/tune")
if err != nil {
return true, nil, nil, err
return true, nil, nil, fmt.Errorf("failed to fetch mount tune information: %w", err)
}

if !tuneRet.IsSecretOK() {
if tuneRet.IsUnsupportedPathError() {
versionError()
}

return true, nil, nil, nil
return true, tuneRet, nil, nil
}

var data map[string]interface{} = nil
Expand Down

0 comments on commit fe7eeda

Please sign in to comment.