mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 02:28:09 +00:00 
			
		
		
		
	 b7dff9777d
			
		
	
	b7dff9777d
	
	
	
		
			
			* wip * Work on the tuneable allowance and some bugs * Call handleCancellableRequest instead, which gets the audit order more correct and includes the preauth response * Get rid of no longer needed operation * Phew, this wasn't necessary * Add auth error handling by the backend, and fix a bug with handleInvalidCredentials * Cleanup req/resp naming * Use the new form, and data * Discovered that tokens werent really being checked because isLoginRequest returns true for the re-request into the backend, when it shouldnt * Add a few more checks in the delegated request handler for bad inputs - Protect the delegated handler from bad inputs from the backend such as an empty accessor, a path that isn't registered as a login request - Add similar protections for bad auth results as we do in the normal login request paths. Technically not 100% needed but if somehow the handleCancelableRequest doesn't use the handleLoginRequest code path we could get into trouble in the future - Add delegated-auth-accessors flag to the secrets tune command and api-docs * Unit tests and some small fixes * Remove transit preauth test, rely on unit tests * Cleanup and add a little more commentary in tests * Fix typos, add another failure use-case which we reference a disabled auth mount * PR Feedback - Use router to lookup mount instead of defining a new lookup method - Enforce auth table types and namespace when mount is found - Define a type alias for the handleInvalidCreds - Fix typos/grammar - Clean up globals in test * Additional PR feedback - Add test for delegated auth handler - Force batch token usage - Add a test to validate failures if a non-batch token is used - Check for Data member being nil in test cases * Update failure error message around requiring batch tokens * Trap MFA requests * Reword some error messages * Add test and fixes for delegated response wrapping * Move MFA test to dedicated mount - If the delegated auth tests were running in parallel, the MFA test case might influence the other tests, so move the MFA to a dedicated mount * PR feedback: use textproto.CanonicalMIMEHeaderKey - Change the X-Vault-Wrap-Ttl constant to X-Vault-Wrap-TTL and use textproto.CanonicalMIMEHeaderKey to format it within the delete call. - This protects the code around changes of the constant typing * PR feedback - Append Error to RequestDelegatedAuth - Force error interface impl through explicit nil var assignment on RequestDelegatedAuthError - Clean up test factory and leverage NewTestSoloCluster - Leverage newer maps.Clone as this is 1.16 only --------- Co-authored-by: Scott G. Miller <smiller@hashicorp.com>
		
			
				
	
	
		
			170 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) HashiCorp, Inc.
 | |
| // SPDX-License-Identifier: MPL-2.0
 | |
| 
 | |
| package logical
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"errors"
 | |
| )
 | |
| 
 | |
| var (
 | |
| 	// ErrUnsupportedOperation is returned if the operation is not supported
 | |
| 	// by the logical backend.
 | |
| 	ErrUnsupportedOperation = errors.New("unsupported operation")
 | |
| 
 | |
| 	// ErrUnsupportedPath is returned if the path is not supported
 | |
| 	// by the logical backend.
 | |
| 	ErrUnsupportedPath = errors.New("unsupported path")
 | |
| 
 | |
| 	// ErrInvalidRequest is returned if the request is invalid
 | |
| 	ErrInvalidRequest = errors.New("invalid request")
 | |
| 
 | |
| 	// ErrPermissionDenied is returned if the client is not authorized
 | |
| 	ErrPermissionDenied = errors.New("permission denied")
 | |
| 
 | |
| 	// ErrInvalidCredentials is returned when the provided credentials are incorrect
 | |
| 	// This is used internally for user lockout purposes. This is not seen externally.
 | |
| 	// The status code returned does not change because of this error
 | |
| 	ErrInvalidCredentials = errors.New("invalid credentials")
 | |
| 
 | |
| 	// ErrMultiAuthzPending is returned if the the request needs more
 | |
| 	// authorizations
 | |
| 	ErrMultiAuthzPending = errors.New("request needs further approval")
 | |
| 
 | |
| 	// ErrUpstreamRateLimited is returned when Vault receives a rate limited
 | |
| 	// response from an upstream
 | |
| 	ErrUpstreamRateLimited = errors.New("upstream rate limited")
 | |
| 
 | |
| 	// ErrPerfStandbyForward is returned when Vault is in a state such that a
 | |
| 	// perf standby cannot satisfy a request
 | |
| 	ErrPerfStandbyPleaseForward = errors.New("please forward to the active node")
 | |
| 
 | |
| 	// ErrLeaseCountQuotaExceeded is returned when a request is rejected due to a lease
 | |
| 	// count quota being exceeded.
 | |
| 	ErrLeaseCountQuotaExceeded = errors.New("lease count quota exceeded")
 | |
| 
 | |
| 	// ErrRateLimitQuotaExceeded is returned when a request is rejected due to a
 | |
| 	// rate limit quota being exceeded.
 | |
| 	ErrRateLimitQuotaExceeded = errors.New("rate limit quota exceeded")
 | |
| 
 | |
| 	// ErrUnrecoverable is returned when a request fails due to something that
 | |
| 	// is likely to require manual intervention. This is a generic form of an
 | |
| 	// unrecoverable error.
 | |
| 	// e.g.: misconfigured or disconnected storage backend.
 | |
| 	ErrUnrecoverable = errors.New("unrecoverable error")
 | |
| 
 | |
| 	// ErrMissingRequiredState is returned when a request can't be satisfied
 | |
| 	// with the data in the local node's storage, based on the provided
 | |
| 	// X-Vault-Index request header.
 | |
| 	ErrMissingRequiredState = errors.New("required index state not present")
 | |
| 
 | |
| 	// Error indicating that the requested path used to serve a purpose in older
 | |
| 	// versions, but the functionality has now been removed
 | |
| 	ErrPathFunctionalityRemoved = errors.New("functionality on this path has been removed")
 | |
| )
 | |
| 
 | |
| type DelegatedAuthErrorHandler func(ctx context.Context, initiatingRequest, authRequest *Request, authResponse *Response, err error) (*Response, error)
 | |
| 
 | |
| var _ error = &RequestDelegatedAuthError{}
 | |
| 
 | |
| // RequestDelegatedAuthError Special error indicating the backend wants to delegate authentication elsewhere
 | |
| type RequestDelegatedAuthError struct {
 | |
| 	mountAccessor string
 | |
| 	path          string
 | |
| 	data          map[string]interface{}
 | |
| 	errHandler    DelegatedAuthErrorHandler
 | |
| }
 | |
| 
 | |
| func NewDelegatedAuthenticationRequest(mountAccessor, path string, data map[string]interface{}, errHandler DelegatedAuthErrorHandler) *RequestDelegatedAuthError {
 | |
| 	return &RequestDelegatedAuthError{
 | |
| 		mountAccessor: mountAccessor,
 | |
| 		path:          path,
 | |
| 		data:          data,
 | |
| 		errHandler:    errHandler,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (d *RequestDelegatedAuthError) Error() string {
 | |
| 	return "authentication delegation requested"
 | |
| }
 | |
| 
 | |
| func (d *RequestDelegatedAuthError) MountAccessor() string {
 | |
| 	return d.mountAccessor
 | |
| }
 | |
| 
 | |
| func (d *RequestDelegatedAuthError) Path() string {
 | |
| 	return d.path
 | |
| }
 | |
| 
 | |
| func (d *RequestDelegatedAuthError) Data() map[string]interface{} {
 | |
| 	return d.data
 | |
| }
 | |
| 
 | |
| func (d *RequestDelegatedAuthError) AuthErrorHandler() DelegatedAuthErrorHandler {
 | |
| 	return d.errHandler
 | |
| }
 | |
| 
 | |
| type HTTPCodedError interface {
 | |
| 	Error() string
 | |
| 	Code() int
 | |
| }
 | |
| 
 | |
| func CodedError(status int, msg string) HTTPCodedError {
 | |
| 	return &codedError{
 | |
| 		Status:  status,
 | |
| 		Message: msg,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| var _ HTTPCodedError = (*codedError)(nil)
 | |
| 
 | |
| type codedError struct {
 | |
| 	Status  int
 | |
| 	Message string
 | |
| }
 | |
| 
 | |
| func (e *codedError) Error() string {
 | |
| 	return e.Message
 | |
| }
 | |
| 
 | |
| func (e *codedError) Code() int {
 | |
| 	return e.Status
 | |
| }
 | |
| 
 | |
| // Struct to identify user input errors.  This is helpful in responding the
 | |
| // appropriate status codes to clients from the HTTP endpoints.
 | |
| type StatusBadRequest struct {
 | |
| 	Err string
 | |
| }
 | |
| 
 | |
| // Implementing error interface
 | |
| func (s *StatusBadRequest) Error() string {
 | |
| 	return s.Err
 | |
| }
 | |
| 
 | |
| // This is a new type declared to not cause potential compatibility problems if
 | |
| // the logic around the CodedError changes; in particular for logical request
 | |
| // paths it is basically ignored, and changing that behavior might cause
 | |
| // unforeseen issues.
 | |
| type ReplicationCodedError struct {
 | |
| 	Msg  string
 | |
| 	Code int
 | |
| }
 | |
| 
 | |
| func (r *ReplicationCodedError) Error() string {
 | |
| 	return r.Msg
 | |
| }
 | |
| 
 | |
| type KeyNotFoundError struct {
 | |
| 	Err error
 | |
| }
 | |
| 
 | |
| func (e *KeyNotFoundError) WrappedErrors() []error {
 | |
| 	return []error{e.Err}
 | |
| }
 | |
| 
 | |
| func (e *KeyNotFoundError) Error() string {
 | |
| 	return e.Err.Error()
 | |
| }
 |