Sync over

This commit is contained in:
Jeff Mitchell
2017-10-23 16:42:56 -04:00
parent d79e0d2ad5
commit 98168dc791
36 changed files with 521 additions and 167 deletions

View File

@@ -3,6 +3,7 @@ package logical
import (
"errors"
"fmt"
"strings"
"time"
)
@@ -11,23 +12,41 @@ import (
type RequestWrapInfo struct {
// Setting to non-zero specifies that the response should be wrapped.
// Specifies the desired TTL of the wrapping token.
TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"`
TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl" sentinel:""`
// The format to use for the wrapped response; if not specified it's a bare
// token
Format string `json:"format" structs:"format" mapstructure:"format"`
Format string `json:"format" structs:"format" mapstructure:"format" sentinel:""`
}
// Request is a struct that stores the parameters and context
// of a request being made to Vault. It is used to abstract
// the details of the higher level request protocol from the handlers.
func (r *RequestWrapInfo) SentinelGet(key string) (interface{}, error) {
if r == nil {
return nil, nil
}
switch key {
case "ttl":
return r.TTL, nil
case "ttl_seconds":
return int64(r.TTL.Seconds()), nil
}
return nil, nil
}
// Request is a struct that stores the parameters and context of a request
// being made to Vault. It is used to abstract the details of the higher level
// request protocol from the handlers.
//
// Note: Many of these have Sentinel disabled because they are values populated
// by the router after policy checks; the token namespace would be the right
// place to access them via Sentinel
type Request struct {
// Id is the uuid associated with each request
ID string `json:"id" structs:"id" mapstructure:"id"`
ID string `json:"id" structs:"id" mapstructure:"id" sentinel:""`
// If set, the name given to the replication secondary where this request
// originated
ReplicationCluster string `json:"replication_cluster" structs:"replication_cluster" mapstructure:"replication_cluster"`
ReplicationCluster string `json:"replication_cluster" structs:"replication_cluster" mapstructure:"replication_cluster" sentinel:""`
// Operation is the requested operation type
Operation Operation `json:"operation" structs:"operation" mapstructure:"operation"`
@@ -36,26 +55,26 @@ type Request struct {
// routing. As an example, if the original request path is "prod/aws/foo"
// and the AWS logical backend is mounted at "prod/aws/", then the
// final path is "foo" since the mount prefix is trimmed.
Path string `json:"path" structs:"path" mapstructure:"path"`
Path string `json:"path" structs:"path" mapstructure:"path" sentinel:""`
// Request data is an opaque map that must have string keys.
Data map[string]interface{} `json:"map" structs:"data" mapstructure:"data"`
// Storage can be used to durably store and retrieve state.
Storage Storage `json:"-"`
Storage Storage `json:"-" sentinel:""`
// Secret will be non-nil only for Revoke and Renew operations
// to represent the secret that was returned prior.
Secret *Secret `json:"secret" structs:"secret" mapstructure:"secret"`
Secret *Secret `json:"secret" structs:"secret" mapstructure:"secret" sentinel:""`
// Auth will be non-nil only for Renew operations
// to represent the auth that was returned prior.
Auth *Auth `json:"auth" structs:"auth" mapstructure:"auth"`
Auth *Auth `json:"auth" structs:"auth" mapstructure:"auth" sentinel:""`
// Headers will contain the http headers from the request. This value will
// be used in the audit broker to ensure we are auditing only the allowed
// headers.
Headers map[string][]string `json:"headers" structs:"headers" mapstructure:"headers"`
Headers map[string][]string `json:"headers" structs:"headers" mapstructure:"headers" sentinel:""`
// Connection will be non-nil only for credential providers to
// inspect the connection information and potentially use it for
@@ -66,45 +85,58 @@ type Request struct {
// can be verified and ACLs applied. This value is passed
// through to the logical backends but after being salted and
// hashed.
ClientToken string `json:"client_token" structs:"client_token" mapstructure:"client_token"`
ClientToken string `json:"client_token" structs:"client_token" mapstructure:"client_token" sentinel:""`
// ClientTokenAccessor is provided to the core so that the it can get
// logged as part of request audit logging.
ClientTokenAccessor string `json:"client_token_accessor" structs:"client_token_accessor" mapstructure:"client_token_accessor"`
ClientTokenAccessor string `json:"client_token_accessor" structs:"client_token_accessor" mapstructure:"client_token_accessor" sentinel:""`
// DisplayName is provided to the logical backend to help associate
// dynamic secrets with the source entity. This is not a sensitive
// name, but is useful for operators.
DisplayName string `json:"display_name" structs:"display_name" mapstructure:"display_name"`
DisplayName string `json:"display_name" structs:"display_name" mapstructure:"display_name" sentinel:""`
// MountPoint is provided so that a logical backend can generate
// paths relative to itself. The `Path` is effectively the client
// request path with the MountPoint trimmed off.
MountPoint string `json:"mount_point" structs:"mount_point" mapstructure:"mount_point"`
MountPoint string `json:"mount_point" structs:"mount_point" mapstructure:"mount_point" sentinel:""`
// MountType is provided so that a logical backend can make decisions
// based on the specific mount type (e.g., if a mount type has different
// aliases, generating different defaults depending on the alias)
MountType string `json:"mount_type" structs:"mount_type" mapstructure:"mount_type"`
MountType string `json:"mount_type" structs:"mount_type" mapstructure:"mount_type" sentinel:""`
// MountAccessor is provided so that identities returned by the authentication
// backends can be tied to the mount it belongs to.
MountAccessor string `json:"mount_accessor" structs:"mount_accessor" mapstructure:"mount_accessor"`
MountAccessor string `json:"mount_accessor" structs:"mount_accessor" mapstructure:"mount_accessor" sentinel:""`
// WrapInfo contains requested response wrapping parameters
WrapInfo *RequestWrapInfo `json:"wrap_info" structs:"wrap_info" mapstructure:"wrap_info"`
WrapInfo *RequestWrapInfo `json:"wrap_info" structs:"wrap_info" mapstructure:"wrap_info" sentinel:""`
// ClientTokenRemainingUses represents the allowed number of uses left on the
// token supplied
ClientTokenRemainingUses int `json:"client_token_remaining_uses" structs:"client_token_remaining_uses" mapstructure:"client_token_remaining_uses"`
// MFACreds holds the parsed MFA information supplied over the API as part of
// X-Vault-MFA header
MFACreds MFACreds `json:"mfa_creds" structs:"mfa_creds" mapstructure:"mfa_creds" sentinel:""`
// EntityID is the identity of the caller extracted out of the token used
// to make this request
EntityID string `json:"entity_id" structs:"entity_id" mapstructure:"entity_id"`
EntityID string `json:"entity_id" structs:"entity_id" mapstructure:"entity_id" sentinel:""`
// PolicyOverride indicates that the requestor wishes to override
// soft-mandatory Sentinel policies
PolicyOverride bool `json:"policy_override" structs:"policy_override" mapstructure:"policy_override"`
// Whether the request is unauthenticated, as in, had no client token
// attached. Useful in some situations where the client token is not made
// accessible.
Unauthenticated bool `json:"unauthenticated" structs:"unauthenticated" mapstructure:"unauthenticated"`
// For replication, contains the last WAL on the remote side after handling
// the request, used for best-effort avoidance of stale read-after-write
lastRemoteWAL uint64
lastRemoteWAL uint64 `sentinel:""`
}
// Get returns a data field and guards for nil Data
@@ -126,6 +158,24 @@ func (r *Request) GoString() string {
return fmt.Sprintf("*%#v", *r)
}
func (r *Request) SentinelGet(key string) (interface{}, error) {
switch key {
case "path":
// Sanitize it here so that it's consistent in policies
return strings.TrimPrefix(r.Path, "/"), nil
case "wrapping", "wrap_info":
// If the pointer is nil accessing the wrap info is considered
// "undefined" so this allows us to instead discover a TTL of zero
if r.WrapInfo == nil {
return &RequestWrapInfo{}, nil
}
return r.WrapInfo, nil
}
return nil, nil
}
func (r *Request) LastRemoteWAL() uint64 {
return r.lastRemoteWAL
}