2016-05-02 04:08:07 +00:00
package vault
import (
2016-05-19 15:25:15 +00:00
"encoding/json"
2016-09-29 04:01:28 +00:00
"fmt"
2016-05-02 04:08:07 +00:00
"strings"
"time"
"github.com/armon/go-metrics"
2016-05-16 20:11:33 +00:00
"github.com/hashicorp/go-multierror"
2016-09-29 19:03:47 +00:00
"github.com/hashicorp/vault/helper/jsonutil"
2016-08-08 21:42:25 +00:00
"github.com/hashicorp/vault/helper/policyutil"
2016-05-02 04:08:07 +00:00
"github.com/hashicorp/vault/helper/strutil"
"github.com/hashicorp/vault/logical"
)
// HandleRequest is used to handle a new incoming request
func ( c * Core ) HandleRequest ( req * logical . Request ) ( resp * logical . Response , err error ) {
c . stateLock . RLock ( )
defer c . stateLock . RUnlock ( )
if c . sealed {
return nil , ErrSealed
}
if c . standby {
return nil , ErrStandby
}
// Allowing writing to a path ending in / makes it extremely difficult to
// understand user intent for the filesystem-like backends (generic,
// cubbyhole) -- did they want a key named foo/ or did they want to write
// to a directory foo/ with no (or forgotten) key, or...? It also affects
// lookup, because paths ending in / are considered prefixes by some
// backends. Basically, it's all just terrible, so don't allow it.
if strings . HasSuffix ( req . Path , "/" ) &&
( req . Operation == logical . UpdateOperation ||
req . Operation == logical . CreateOperation ) {
return logical . ErrorResponse ( "cannot write to a path ending in '/'" ) , nil
}
var auth * logical . Auth
if c . router . LoginPath ( req . Path ) {
resp , auth , err = c . handleLoginRequest ( req )
} else {
resp , auth , err = c . handleRequest ( req )
}
// Ensure we don't leak internal data
if resp != nil {
if resp . Secret != nil {
resp . Secret . InternalData = nil
}
if resp . Auth != nil {
resp . Auth . InternalData = nil
}
}
// We are wrapping if there is anything to wrap (not a nil response) and a
2016-09-29 04:01:28 +00:00
// TTL was specified for the token. Errors on a call should be returned to
// the caller, so wrapping is turned off if an error is hit and the error
// is logged to the audit log.
wrapping := resp != nil &&
err == nil &&
! resp . IsError ( ) &&
resp . WrapInfo != nil &&
resp . WrapInfo . TTL != 0
2016-05-02 04:08:07 +00:00
2016-05-16 20:11:33 +00:00
if wrapping {
2016-09-29 04:01:28 +00:00
cubbyResp , cubbyErr := c . wrapInCubbyhole ( req , resp )
2016-05-16 20:11:33 +00:00
// If not successful, returns either an error response from the
2016-09-29 04:01:28 +00:00
// cubbyhole backend or an error; if either is set, set resp and err to
// those and continue so that that's what we audit log. Otherwise
// finish the wrapping and audit log that.
if cubbyResp != nil || cubbyErr != nil {
resp = cubbyResp
err = cubbyErr
} else {
wrappingResp := & logical . Response {
WrapInfo : resp . WrapInfo ,
}
wrappingResp . CloneWarnings ( resp )
resp = wrappingResp
2016-05-02 04:08:07 +00:00
}
}
2016-09-29 19:03:47 +00:00
auditResp := resp
// When unwrapping we want to log the actual response that will be written
// out. We still want to return the raw value to avoid automatic updating
// to any of it.
if req . Path == "sys/wrapping/unwrap" &&
resp != nil &&
resp . Data != nil &&
resp . Data [ logical . HTTPRawBody ] != nil {
// Decode the JSON
httpResp := & logical . HTTPResponse { }
err := jsonutil . DecodeJSON ( resp . Data [ logical . HTTPRawBody ] . ( [ ] byte ) , httpResp )
if err != nil {
c . logger . Error ( "core: failed to unmarshal wrapped HTTP response for audit logging" , "error" , err )
return nil , ErrInternalError
}
auditResp = logical . HTTPResponseToLogicalResponse ( httpResp )
}
2016-05-02 04:08:07 +00:00
// Create an audit trail of the response
2016-09-29 19:03:47 +00:00
if auditErr := c . auditBroker . LogResponse ( auth , req , auditResp , err ) ; auditErr != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to audit response" , "request_path" , req . Path , "error" , auditErr )
2016-05-02 04:08:07 +00:00
return nil , ErrInternalError
}
return
}
func ( c * Core ) handleRequest ( req * logical . Request ) ( retResp * logical . Response , retAuth * logical . Auth , retErr error ) {
defer metrics . MeasureSince ( [ ] string { "core" , "handle_request" } , time . Now ( ) )
// Validate the token
2016-05-02 07:11:14 +00:00
auth , te , ctErr := c . checkToken ( req )
// We run this logic first because we want to decrement the use count even in the case of an error
2016-05-02 04:08:07 +00:00
if te != nil {
2016-05-02 07:11:14 +00:00
// Attempt to use the token (decrement NumUses)
var err error
te , err = c . tokenStore . UseToken ( te )
if err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to use token" , "error" , err )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , nil , retErr
2016-05-02 07:11:14 +00:00
}
if te == nil {
// Token has been revoked by this point
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , logical . ErrPermissionDenied )
return nil , nil , retErr
2016-05-02 07:11:14 +00:00
}
if te . NumUses == - 1 {
// We defer a revocation until after logic has run, since this is a
// valid request (this is the token's final use). We pass the ID in
// directly just to be safe in case something else modifies te later.
defer func ( id string ) {
err = c . tokenStore . Revoke ( id )
if err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to revoke token" , "error" , err )
2016-05-02 07:11:14 +00:00
retResp = nil
retAuth = nil
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
2016-05-02 07:11:14 +00:00
}
if retResp != nil && retResp . Secret != nil &&
// Some backends return a TTL even without a Lease ID
retResp . Secret . LeaseID != "" {
retResp = logical . ErrorResponse ( "Secret cannot be returned; token had one use left, so leased credentials were immediately revoked." )
return
}
} ( te . ID )
}
2016-05-02 04:08:07 +00:00
}
2016-05-02 07:11:14 +00:00
if ctErr != nil {
2016-05-02 04:08:07 +00:00
// If it is an internal error we return that, otherwise we
// return invalid request so that the status codes can be correct
var errType error
2016-05-02 07:11:14 +00:00
switch ctErr {
2016-05-02 04:08:07 +00:00
case ErrInternalError , logical . ErrPermissionDenied :
2016-05-02 07:11:14 +00:00
errType = ctErr
2016-05-02 04:08:07 +00:00
default :
errType = logical . ErrInvalidRequest
}
2016-05-02 07:11:14 +00:00
if err := c . auditBroker . LogRequest ( auth , req , ctErr ) ; err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to audit request" , "path" , req . Path , "error" , err )
2016-05-02 04:08:07 +00:00
}
2016-05-16 20:11:33 +00:00
if errType != nil {
retErr = multierror . Append ( retErr , errType )
}
return logical . ErrorResponse ( ctErr . Error ( ) ) , nil , retErr
2016-05-02 04:08:07 +00:00
}
// Attach the display name
req . DisplayName = auth . DisplayName
// Create an audit trail of the request
if err := c . auditBroker . LogRequest ( auth , req , nil ) ; err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to audit request" , "path" , req . Path , "error" , err )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , auth , retErr
2016-05-02 04:08:07 +00:00
}
// Route the request
resp , err := c . router . Route ( req )
2016-05-16 20:11:33 +00:00
if resp != nil {
2016-11-11 20:12:11 +00:00
// If wrapping is used, use the shortest between the request and response
var wrapTTL time . Duration
2016-05-16 20:11:33 +00:00
2016-11-11 20:12:11 +00:00
// Ensure no wrap info information is set other than, possibly, the TTL
if resp . WrapInfo != nil {
if resp . WrapInfo . TTL > 0 {
wrapTTL = resp . WrapInfo . TTL
}
resp . WrapInfo = nil
}
if req . WrapTTL > 0 {
switch {
case wrapTTL == 0 :
wrapTTL = req . WrapTTL
case req . WrapTTL < wrapTTL :
wrapTTL = req . WrapTTL
}
}
if wrapTTL > 0 {
2016-05-16 20:11:33 +00:00
resp . WrapInfo = & logical . WrapInfo {
2016-11-11 20:12:11 +00:00
TTL : wrapTTL ,
2016-05-16 20:11:33 +00:00
}
}
}
2016-05-02 04:08:07 +00:00
// If there is a secret, we must register it with the expiration manager.
// We exclude renewal of a lease, since it does not need to be re-registered
2016-08-08 22:00:44 +00:00
if resp != nil && resp . Secret != nil && ! strings . HasPrefix ( req . Path , "sys/renew" ) {
2016-05-02 04:08:07 +00:00
// Get the SystemView for the mount
sysView := c . router . MatchingSystemView ( req . Path )
if sysView == nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: unable to retrieve system view from router" )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , auth , retErr
2016-05-02 04:08:07 +00:00
}
// Apply the default lease if none given
if resp . Secret . TTL == 0 {
resp . Secret . TTL = sysView . DefaultLeaseTTL ( )
}
// Limit the lease duration
maxTTL := sysView . MaxLeaseTTL ( )
if resp . Secret . TTL > maxTTL {
resp . Secret . TTL = maxTTL
}
// Generic mounts should return the TTL but not register
// for a lease as this provides a massive slowdown
registerLease := true
matchingBackend := c . router . MatchingBackend ( req . Path )
if matchingBackend == nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: unable to retrieve generic backend from router" )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , auth , retErr
2016-05-02 04:08:07 +00:00
}
if ptbe , ok := matchingBackend . ( * PassthroughBackend ) ; ok {
if ! ptbe . GeneratesLeases ( ) {
registerLease = false
resp . Secret . Renewable = false
}
}
if registerLease {
leaseID , err := c . expiration . Register ( req , resp )
if err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to register lease" , "request_path" , req . Path , "error" , err )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , auth , retErr
2016-05-02 04:08:07 +00:00
}
resp . Secret . LeaseID = leaseID
}
}
// Only the token store is allowed to return an auth block, for any
// other request this is an internal error. We exclude renewal of a token,
// since it does not need to be re-registered
if resp != nil && resp . Auth != nil && ! strings . HasPrefix ( req . Path , "auth/token/renew" ) {
if ! strings . HasPrefix ( req . Path , "auth/token/" ) {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: unexpected Auth response for non-token backend" , "request_path" , req . Path )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , auth , retErr
2016-05-02 04:08:07 +00:00
}
// Register with the expiration manager. We use the token's actual path
// here because roles allow suffixes.
te , err := c . tokenStore . Lookup ( resp . Auth . ClientToken )
if err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to look up token" , "error" , err )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , nil , retErr
2016-05-02 04:08:07 +00:00
}
if err := c . expiration . RegisterAuth ( te . Path , resp . Auth ) ; err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to register token lease" , "request_path" , req . Path , "error" , err )
2016-05-16 20:11:33 +00:00
retErr = multierror . Append ( retErr , ErrInternalError )
return nil , auth , retErr
2016-05-02 04:08:07 +00:00
}
}
2016-09-29 04:01:28 +00:00
if resp != nil &&
req . Path == "cubbyhole/response" &&
len ( te . Policies ) == 1 &&
te . Policies [ 0 ] == responseWrappingPolicyName {
2016-09-29 21:44:15 +00:00
resp . AddWarning ( "Reading from 'cubbyhole/response' is deprecated. Please use sys/wrapping/unwrap to unwrap responses, as it provides additional security checks and other benefits." )
2016-09-29 04:01:28 +00:00
}
2016-05-02 04:08:07 +00:00
// Return the response and error
2016-05-16 20:11:33 +00:00
if err != nil {
retErr = multierror . Append ( retErr , err )
}
return resp , auth , retErr
2016-05-02 04:08:07 +00:00
}
// handleLoginRequest is used to handle a login request, which is an
// unauthenticated request to the backend.
2016-08-08 21:56:14 +00:00
func ( c * Core ) handleLoginRequest ( req * logical . Request ) ( * logical . Response , * logical . Auth , error ) {
2016-05-02 04:08:07 +00:00
defer metrics . MeasureSince ( [ ] string { "core" , "handle_login_request" } , time . Now ( ) )
// Create an audit trail of the request, auth is not available on login requests
if err := c . auditBroker . LogRequest ( nil , req , nil ) ; err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to audit request" , "path" , req . Path , "error" , err )
2016-05-02 04:08:07 +00:00
return nil , nil , ErrInternalError
}
2016-08-08 21:32:37 +00:00
// The token store uses authentication even when creating a new token,
// so it's handled in handleRequest. It should not be reached here.
if strings . HasPrefix ( req . Path , "auth/token/" ) {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: unexpected login request for token backend" , "request_path" , req . Path )
2016-08-08 21:56:14 +00:00
return nil , nil , ErrInternalError
2016-08-08 21:32:37 +00:00
}
2016-05-02 04:08:07 +00:00
// Route the request
resp , err := c . router . Route ( req )
2016-07-05 15:46:21 +00:00
if resp != nil {
2016-11-11 20:12:11 +00:00
// If wrapping is used, use the shortest between the request and response
var wrapTTL time . Duration
2016-07-05 15:46:21 +00:00
2016-11-11 20:12:11 +00:00
// Ensure no wrap info information is set other than, possibly, the TTL
if resp . WrapInfo != nil {
if resp . WrapInfo . TTL > 0 {
wrapTTL = resp . WrapInfo . TTL
}
resp . WrapInfo = nil
}
if req . WrapTTL > 0 {
switch {
case wrapTTL == 0 :
wrapTTL = req . WrapTTL
case req . WrapTTL < wrapTTL :
wrapTTL = req . WrapTTL
}
}
if wrapTTL > 0 {
2016-07-05 15:46:21 +00:00
resp . WrapInfo = & logical . WrapInfo {
2016-11-11 20:12:11 +00:00
TTL : wrapTTL ,
2016-07-05 15:46:21 +00:00
}
}
2016-11-11 20:12:11 +00:00
2016-07-05 15:46:21 +00:00
}
2016-05-02 04:08:07 +00:00
// A login request should never return a secret!
if resp != nil && resp . Secret != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: unexpected Secret response for login path" , "request_path" , req . Path )
2016-05-02 04:08:07 +00:00
return nil , nil , ErrInternalError
}
// If the response generated an authentication, then generate the token
var auth * logical . Auth
if resp != nil && resp . Auth != nil {
auth = resp . Auth
2016-08-08 21:32:37 +00:00
if strutil . StrListSubset ( auth . Policies , [ ] string { "root" } ) {
return logical . ErrorResponse ( "authentication backends cannot create root tokens" ) , nil , logical . ErrInvalidRequest
}
2016-05-02 04:08:07 +00:00
// Determine the source of the login
source := c . router . MatchingMount ( req . Path )
source = strings . TrimPrefix ( source , credentialRoutePrefix )
source = strings . Replace ( source , "/" , "-" , - 1 )
// Prepend the source to the display name
auth . DisplayName = strings . TrimSuffix ( source + auth . DisplayName , "-" )
sysView := c . router . MatchingSystemView ( req . Path )
if sysView == nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: unable to look up sys view for login path" , "request_path" , req . Path )
2016-05-02 04:08:07 +00:00
return nil , nil , ErrInternalError
}
2016-08-08 21:32:37 +00:00
// Set the default lease if not provided
if auth . TTL == 0 {
2016-05-02 04:08:07 +00:00
auth . TTL = sysView . DefaultLeaseTTL ( )
}
// Limit the lease duration
if auth . TTL > sysView . MaxLeaseTTL ( ) {
auth . TTL = sysView . MaxLeaseTTL ( )
}
// Generate a token
te := TokenEntry {
Path : req . Path ,
Policies : auth . Policies ,
Meta : auth . Metadata ,
DisplayName : auth . DisplayName ,
CreationTime : time . Now ( ) . Unix ( ) ,
TTL : auth . TTL ,
}
2016-08-08 21:42:25 +00:00
te . Policies = policyutil . SanitizePolicies ( te . Policies , true )
2016-08-08 21:32:37 +00:00
2016-09-29 04:01:28 +00:00
// Prevent internal policies from being assigned to tokens
for _ , policy := range te . Policies {
if strutil . StrListContains ( nonAssignablePolicies , policy ) {
return logical . ErrorResponse ( fmt . Sprintf ( "cannot assign policy %q" , policy ) ) , nil , logical . ErrInvalidRequest
}
}
2016-05-02 04:08:07 +00:00
if err := c . tokenStore . create ( & te ) ; err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to create token" , "error" , err )
2016-05-02 04:08:07 +00:00
return nil , auth , ErrInternalError
}
// Populate the client token and accessor
auth . ClientToken = te . ID
auth . Accessor = te . Accessor
auth . Policies = te . Policies
// Register with the expiration manager
if err := c . expiration . RegisterAuth ( te . Path , auth ) ; err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to register token lease" , "request_path" , req . Path , "error" , err )
2016-05-02 04:08:07 +00:00
return nil , auth , ErrInternalError
}
// Attach the display name, might be used by audit backends
req . DisplayName = auth . DisplayName
}
return resp , auth , err
}
2016-05-16 20:11:33 +00:00
func ( c * Core ) wrapInCubbyhole ( req * logical . Request , resp * logical . Response ) ( * logical . Response , error ) {
2016-09-02 05:13:14 +00:00
// Before wrapping, obey special rules for listing: if no entries are
// found, 404. This prevents unwrapping only to find empty data.
if req . Operation == logical . ListOperation {
if resp == nil || len ( resp . Data ) == 0 {
return nil , logical . ErrUnsupportedPath
}
keysRaw , ok := resp . Data [ "keys" ]
if ! ok || keysRaw == nil {
return nil , logical . ErrUnsupportedPath
}
keys , ok := keysRaw . ( [ ] string )
if ! ok {
return nil , logical . ErrUnsupportedPath
}
if len ( keys ) == 0 {
return nil , logical . ErrUnsupportedPath
}
}
2016-05-16 20:11:33 +00:00
// If we are wrapping, the first part (performed in this functions) happens
// before auditing so that resp.WrapInfo.Token can contain the HMAC'd
// wrapping token ID in the audit logs, so that it can be determined from
// the audit logs whether the token was ever actually used.
2016-06-07 20:01:09 +00:00
creationTime := time . Now ( )
2016-05-16 20:11:33 +00:00
te := TokenEntry {
2016-06-07 19:00:35 +00:00
Path : req . Path ,
2016-06-10 17:48:46 +00:00
Policies : [ ] string { "response-wrapping" } ,
2016-06-07 20:01:09 +00:00
CreationTime : creationTime . Unix ( ) ,
2016-06-07 19:00:35 +00:00
TTL : resp . WrapInfo . TTL ,
NumUses : 1 ,
ExplicitMaxTTL : resp . WrapInfo . TTL ,
2016-05-16 20:11:33 +00:00
}
if err := c . tokenStore . create ( & te ) ; err != nil {
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to create wrapping token" , "error" , err )
2016-05-16 20:11:33 +00:00
return nil , ErrInternalError
}
resp . WrapInfo . Token = te . ID
2016-06-07 20:01:09 +00:00
resp . WrapInfo . CreationTime = creationTime
2016-05-16 20:11:33 +00:00
2016-06-14 05:54:09 +00:00
// This will only be non-nil if this response contains a token, so in that
// case put the accessor in the wrap info.
2016-06-13 23:58:17 +00:00
if resp . Auth != nil {
resp . WrapInfo . WrappedAccessor = resp . Auth . Accessor
}
2016-05-16 20:11:33 +00:00
cubbyReq := & logical . Request {
Operation : logical . CreateOperation ,
Path : "cubbyhole/response" ,
ClientToken : te . ID ,
2016-09-29 04:01:28 +00:00
}
// During a rewrap, store the original response, don't wrap it again.
if req . Path == "sys/wrapping/rewrap" {
cubbyReq . Data = map [ string ] interface { } {
"response" : resp . Data [ "response" ] ,
}
} else {
2016-09-29 19:03:47 +00:00
httpResponse := logical . LogicalResponseToHTTPResponse ( resp )
2016-09-29 04:01:28 +00:00
// Add the unique identifier of the original request to the response
httpResponse . RequestID = req . ID
// Because of the way that JSON encodes (likely just in Go) we actually get
// mixed-up values for ints if we simply put this object in the response
// and encode the whole thing; so instead we marshal it first, then store
// the string response. This actually ends up making it easier on the
// client side, too, as it becomes a straight read-string-pass-to-unmarshal
// operation.
marshaledResponse , err := json . Marshal ( httpResponse )
if err != nil {
c . logger . Error ( "core: failed to marshal wrapped response" , "error" , err )
return nil , ErrInternalError
}
cubbyReq . Data = map [ string ] interface { } {
2016-05-19 15:25:15 +00:00
"response" : string ( marshaledResponse ) ,
2016-09-29 04:01:28 +00:00
}
2016-05-16 20:11:33 +00:00
}
cubbyResp , err := c . router . Route ( cubbyReq )
if err != nil {
// Revoke since it's not yet being tracked for expiration
c . tokenStore . Revoke ( te . ID )
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to store wrapped response information" , "error" , err )
2016-05-16 20:11:33 +00:00
return nil , ErrInternalError
}
if cubbyResp != nil && cubbyResp . IsError ( ) {
c . tokenStore . Revoke ( te . ID )
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to store wrapped response information" , "error" , cubbyResp . Data [ "error" ] )
2016-05-16 20:11:33 +00:00
return cubbyResp , nil
}
2016-09-29 04:01:28 +00:00
// Store info for lookup
cubbyReq . Path = "cubbyhole/wrapinfo"
cubbyReq . Data = map [ string ] interface { } {
"creation_ttl" : resp . WrapInfo . TTL ,
"creation_time" : creationTime ,
}
cubbyResp , err = c . router . Route ( cubbyReq )
if err != nil {
// Revoke since it's not yet being tracked for expiration
c . tokenStore . Revoke ( te . ID )
c . logger . Error ( "core: failed to store wrapping information" , "error" , err )
return nil , ErrInternalError
}
if cubbyResp != nil && cubbyResp . IsError ( ) {
c . tokenStore . Revoke ( te . ID )
c . logger . Error ( "core: failed to store wrapping information" , "error" , cubbyResp . Data [ "error" ] )
return cubbyResp , nil
}
2016-05-16 20:11:33 +00:00
auth := & logical . Auth {
ClientToken : te . ID ,
2016-06-10 17:48:46 +00:00
Policies : [ ] string { "response-wrapping" } ,
2016-05-16 20:11:33 +00:00
LeaseOptions : logical . LeaseOptions {
TTL : te . TTL ,
Renewable : false ,
} ,
}
// Register the wrapped token with the expiration manager
if err := c . expiration . RegisterAuth ( te . Path , auth ) ; err != nil {
// Revoke since it's not yet being tracked for expiration
c . tokenStore . Revoke ( te . ID )
2016-08-19 20:45:17 +00:00
c . logger . Error ( "core: failed to register cubbyhole wrapping token lease" , "request_path" , req . Path , "error" , err )
2016-05-16 20:11:33 +00:00
return nil , ErrInternalError
}
return nil , nil
}