2015-04-11 21:46:09 +00:00
|
|
|
package framework
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/logical"
|
|
|
|
)
|
|
|
|
|
2016-01-29 20:27:01 +00:00
|
|
|
// LeaseExtend returns an OperationFunc that can be used to simply extend the
|
|
|
|
// lease of the auth/secret for the duration that was requested.
|
2015-04-11 23:41:08 +00:00
|
|
|
//
|
2016-01-29 20:27:01 +00:00
|
|
|
// backendIncrement is the backend's requested increment -- perhaps from a user
|
|
|
|
// request, perhaps from a role/config value. If not set, uses the mount/system
|
|
|
|
// value.
|
2015-06-17 21:24:12 +00:00
|
|
|
//
|
2016-01-29 20:27:01 +00:00
|
|
|
// backendMax is the backend's requested increment -- this can be more
|
|
|
|
// restrictive than the mount/system value but not less.
|
|
|
|
//
|
|
|
|
// systemView is the system view from the calling backend, used to determine
|
|
|
|
// and/or correct default/max times.
|
2016-01-29 19:59:07 +00:00
|
|
|
func LeaseExtend(backendIncrement, backendMax time.Duration, systemView logical.SystemView) OperationFunc {
|
2015-04-11 21:46:09 +00:00
|
|
|
return func(req *logical.Request, data *FieldData) (*logical.Response, error) {
|
2016-01-29 19:59:07 +00:00
|
|
|
var leaseOpts *logical.LeaseOptions
|
|
|
|
switch {
|
|
|
|
case req.Auth != nil:
|
|
|
|
leaseOpts = &req.Auth.LeaseOptions
|
|
|
|
case req.Secret != nil:
|
|
|
|
leaseOpts = &req.Secret.LeaseOptions
|
|
|
|
default:
|
2015-04-11 21:46:09 +00:00
|
|
|
return nil, fmt.Errorf("no lease options for request")
|
|
|
|
}
|
|
|
|
|
2016-01-29 19:59:07 +00:00
|
|
|
// Use the mount's configured max unless the backend specifies
|
|
|
|
// something more restrictive (perhaps from a role configuration
|
|
|
|
// parameter)
|
|
|
|
max := systemView.MaxLeaseTTL()
|
|
|
|
if backendMax > 0 && backendMax < max {
|
|
|
|
max = backendMax
|
2015-06-17 21:24:12 +00:00
|
|
|
}
|
|
|
|
|
2016-01-29 19:59:07 +00:00
|
|
|
// Should never happen, but guard anyways
|
|
|
|
if max < 0 {
|
|
|
|
return nil, fmt.Errorf("max TTL is negative")
|
2015-06-17 21:16:44 +00:00
|
|
|
}
|
|
|
|
|
2016-01-29 19:59:07 +00:00
|
|
|
// We cannot go past this time
|
|
|
|
maxValidTime := leaseOpts.IssueTime.UTC().Add(max)
|
|
|
|
|
2015-06-17 21:16:44 +00:00
|
|
|
// Get the current time
|
2015-04-11 23:41:08 +00:00
|
|
|
now := time.Now().UTC()
|
|
|
|
|
2016-01-29 19:59:07 +00:00
|
|
|
// If we are past the max TTL, we shouldn't be in this function...but
|
|
|
|
// fast path out if we are
|
|
|
|
if maxValidTime.Before(now) {
|
|
|
|
return nil, fmt.Errorf("past the max TTL, cannot renew")
|
2015-04-11 23:41:08 +00:00
|
|
|
}
|
|
|
|
|
2016-01-29 19:59:07 +00:00
|
|
|
// Basic max safety checks have passed, now let's figure out our
|
2016-01-30 01:02:15 +00:00
|
|
|
// increment. We'll use the user-supplied value first, then backend-provided default if possible, or the
|
|
|
|
// mount/system default if not.
|
2016-01-29 19:59:07 +00:00
|
|
|
increment := leaseOpts.Increment
|
|
|
|
if increment <= 0 {
|
2016-01-30 01:02:15 +00:00
|
|
|
if backendIncrement > 0 {
|
|
|
|
increment = backendIncrement
|
|
|
|
} else {
|
|
|
|
increment = systemView.DefaultLeaseTTL()
|
|
|
|
}
|
2015-04-11 23:41:08 +00:00
|
|
|
}
|
|
|
|
|
2016-01-29 22:20:20 +00:00
|
|
|
// We are proposing a time of the current time plus the increment
|
|
|
|
proposedExpiration := now.Add(increment)
|
2016-01-29 19:59:07 +00:00
|
|
|
|
|
|
|
// If the proposed expiration is after the maximum TTL of the lease,
|
|
|
|
// cap the increment to whatever is left
|
|
|
|
if maxValidTime.Before(proposedExpiration) {
|
|
|
|
increment = maxValidTime.Sub(now)
|
|
|
|
}
|
2015-04-11 21:46:09 +00:00
|
|
|
|
|
|
|
// Set the lease
|
2016-01-29 19:59:07 +00:00
|
|
|
leaseOpts.TTL = increment
|
2015-08-21 00:47:17 +00:00
|
|
|
|
2015-04-11 21:46:09 +00:00
|
|
|
return &logical.Response{Auth: req.Auth, Secret: req.Secret}, nil
|
|
|
|
}
|
|
|
|
}
|