mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 11:38:02 +00:00
Add creation time to returned wrapped token info
This makes it easier to understand the expected lifetime without a lookup call that uses the single use left on the token. This also adds a couple of safety checks and for JSON uses int, rather than int64, for the TTL for the wrapped token.
This commit is contained in:
@@ -32,8 +32,9 @@ type Secret struct {
|
||||
|
||||
// SecretWrapInfo contains wrapping information if we have it.
|
||||
type SecretWrapInfo struct {
|
||||
Token string `json:"token"`
|
||||
TTL int `json:"ttl"`
|
||||
Token string `json:"token"`
|
||||
TTL int `json:"ttl"`
|
||||
CreationTime int64 `json:"creation_time"`
|
||||
}
|
||||
|
||||
// SecretAuth is the structure containing auth information if we have it.
|
||||
|
||||
@@ -20,7 +20,8 @@ func TestParseSecret(t *testing.T) {
|
||||
],
|
||||
"wrap_info": {
|
||||
"token": "token",
|
||||
"ttl": 60
|
||||
"ttl": 60,
|
||||
"creation_time": 100000
|
||||
}
|
||||
}`)
|
||||
|
||||
@@ -40,8 +41,9 @@ func TestParseSecret(t *testing.T) {
|
||||
"a warning!",
|
||||
},
|
||||
WrapInfo: &SecretWrapInfo{
|
||||
Token: "token",
|
||||
TTL: 60,
|
||||
Token: "token",
|
||||
TTL: 60,
|
||||
CreationTime: int64(100000),
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(secret, expected) {
|
||||
|
||||
@@ -46,7 +46,7 @@ func (f *FormatJSON) FormatRequest(
|
||||
Path: req.Path,
|
||||
Data: req.Data,
|
||||
RemoteAddr: getRemoteAddr(req),
|
||||
WrapTTL: int64(req.WrapTTL / time.Second),
|
||||
WrapTTL: int(req.WrapTTL / time.Second),
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -90,8 +90,9 @@ func (f *FormatJSON) FormatResponse(
|
||||
var respWrapInfo *JSONWrapInfo
|
||||
if resp.WrapInfo != nil {
|
||||
respWrapInfo = &JSONWrapInfo{
|
||||
TTL: int64(resp.WrapInfo.TTL / time.Second),
|
||||
Token: resp.WrapInfo.Token,
|
||||
TTL: int(resp.WrapInfo.TTL / time.Second),
|
||||
Token: resp.WrapInfo.Token,
|
||||
CreationTime: resp.WrapInfo.CreationTime,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ func (f *FormatJSON) FormatResponse(
|
||||
Path: req.Path,
|
||||
Data: req.Data,
|
||||
RemoteAddr: getRemoteAddr(req),
|
||||
WrapTTL: int64(req.WrapTTL / time.Second),
|
||||
WrapTTL: int(req.WrapTTL / time.Second),
|
||||
},
|
||||
|
||||
Response: JSONResponse{
|
||||
@@ -151,7 +152,7 @@ type JSONRequest struct {
|
||||
Path string `json:"path"`
|
||||
Data map[string]interface{} `json:"data"`
|
||||
RemoteAddr string `json:"remote_address"`
|
||||
WrapTTL int64 `json:"wrap_ttl"`
|
||||
WrapTTL int `json:"wrap_ttl"`
|
||||
}
|
||||
|
||||
type JSONResponse struct {
|
||||
@@ -175,8 +176,9 @@ type JSONSecret struct {
|
||||
}
|
||||
|
||||
type JSONWrapInfo struct {
|
||||
TTL int64 `json:"ttl"`
|
||||
Token string `json:"token"`
|
||||
TTL int `json:"ttl"`
|
||||
Token string `json:"token"`
|
||||
CreationTime int64 `json:"creation_time"`
|
||||
}
|
||||
|
||||
// getRemoteAddr safely gets the remote address avoiding a nil pointer
|
||||
|
||||
@@ -68,8 +68,9 @@ func TestCopy_response(t *testing.T) {
|
||||
"foo": "bar",
|
||||
},
|
||||
WrapInfo: &logical.WrapInfo{
|
||||
TTL: 60,
|
||||
Token: "foo",
|
||||
TTL: 60,
|
||||
Token: "foo",
|
||||
CreationTime: 100000,
|
||||
},
|
||||
}
|
||||
arg := expected
|
||||
@@ -137,8 +138,9 @@ func TestHash(t *testing.T) {
|
||||
"foo": "bar",
|
||||
},
|
||||
WrapInfo: &logical.WrapInfo{
|
||||
TTL: 60,
|
||||
Token: "bar",
|
||||
TTL: 60,
|
||||
Token: "bar",
|
||||
CreationTime: 100000,
|
||||
},
|
||||
},
|
||||
&logical.Response{
|
||||
@@ -146,8 +148,9 @@ func TestHash(t *testing.T) {
|
||||
"foo": "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317",
|
||||
},
|
||||
WrapInfo: &logical.WrapInfo{
|
||||
TTL: 60,
|
||||
Token: "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317",
|
||||
TTL: 60,
|
||||
Token: "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317",
|
||||
CreationTime: 100000,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -160,6 +160,7 @@ func (t TableFormatter) OutputSecret(ui cli.Ui, secret, s *api.Secret) error {
|
||||
if s.WrapInfo != nil {
|
||||
input = append(input, fmt.Sprintf("wrapping_token: %s %s", config.Delim, s.WrapInfo.Token))
|
||||
input = append(input, fmt.Sprintf("wrapping_token_ttl: %s %d", config.Delim, s.WrapInfo.TTL))
|
||||
input = append(input, fmt.Sprintf("wrapping_token_creation_time: %s %d", config.Delim, s.WrapInfo.CreationTime))
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(s.Data))
|
||||
|
||||
@@ -40,6 +40,10 @@ func PrintRawField(ui cli.Ui, secret *api.Secret, field string) int {
|
||||
if secret.WrapInfo != nil {
|
||||
val = secret.WrapInfo.TTL
|
||||
}
|
||||
case "wrapping_token_creation_time":
|
||||
if secret.WrapInfo != nil {
|
||||
val = secret.WrapInfo.CreationTime
|
||||
}
|
||||
case "refresh_interval":
|
||||
val = secret.LeaseDuration
|
||||
default:
|
||||
|
||||
@@ -185,6 +185,9 @@ func requestWrapTTL(r *http.Request, req *logical.Request) (*logical.Request, er
|
||||
}
|
||||
req.WrapTTL = time.Duration(seconds) * time.Second
|
||||
}
|
||||
if int64(req.WrapTTL) < 0 {
|
||||
return req, fmt.Errorf("requested wrap ttl cannot be negative")
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
@@ -163,8 +163,9 @@ func respondLogical(w http.ResponseWriter, r *http.Request, path string, dataOnl
|
||||
if resp.WrapInfo != nil && resp.WrapInfo.Token != "" {
|
||||
httpResp = logical.HTTPResponse{
|
||||
WrapInfo: &logical.HTTPWrapInfo{
|
||||
Token: resp.WrapInfo.Token,
|
||||
TTL: int(resp.WrapInfo.TTL.Seconds()),
|
||||
Token: resp.WrapInfo.Token,
|
||||
TTL: int(resp.WrapInfo.TTL.Seconds()),
|
||||
CreationTime: resp.WrapInfo.CreationTime,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -34,6 +34,10 @@ type WrapInfo struct {
|
||||
|
||||
// The token containing the wrapped response
|
||||
Token string
|
||||
|
||||
// The creation time in seconds since Unix epoch. This can be used with the
|
||||
// TTL to figure out an expected expiration.
|
||||
CreationTime int64
|
||||
}
|
||||
|
||||
// Response is a struct that stores the response of a request.
|
||||
|
||||
@@ -52,6 +52,7 @@ type HTTPAuth struct {
|
||||
}
|
||||
|
||||
type HTTPWrapInfo struct {
|
||||
Token string `json:"token"`
|
||||
TTL int `json:"ttl"`
|
||||
Token string `json:"token"`
|
||||
TTL int `json:"ttl"`
|
||||
CreationTime int64 `json:"creation_time"`
|
||||
}
|
||||
|
||||
@@ -376,11 +376,12 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l
|
||||
// wrapping token ID in the audit logs, so that it can be determined from
|
||||
// the audit logs whether the token was ever actually used.
|
||||
te := TokenEntry{
|
||||
Path: req.Path,
|
||||
Policies: []string{"cubbyhole-response-wrapping"},
|
||||
CreationTime: time.Now().Unix(),
|
||||
TTL: resp.WrapInfo.TTL,
|
||||
NumUses: 1,
|
||||
Path: req.Path,
|
||||
Policies: []string{"cubbyhole-response-wrapping"},
|
||||
CreationTime: time.Now().Unix(),
|
||||
TTL: resp.WrapInfo.TTL,
|
||||
NumUses: 1,
|
||||
ExplicitMaxTTL: resp.WrapInfo.TTL,
|
||||
}
|
||||
|
||||
if err := c.tokenStore.create(&te); err != nil {
|
||||
@@ -389,6 +390,7 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l
|
||||
}
|
||||
|
||||
resp.WrapInfo.Token = te.ID
|
||||
resp.WrapInfo.CreationTime = te.CreationTime
|
||||
|
||||
httpResponse := logical.SanitizeResponse(resp)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user