Skip to content

Commit

Permalink
Store original request path in WrapInfo (#3100)
Browse files Browse the repository at this point in the history
* Store original request path in WrapInfo as CreationPath

* Add wrapping_token_creation_path to CLI output

* Add CreationPath to AuditResponseWrapInfo

* Fix tests

* Add and fix tests, update API docs with new sample responses
  • Loading branch information
calvn authored Aug 2, 2017
1 parent ace37c9 commit 15634f3
Show file tree
Hide file tree
Showing 15 changed files with 70 additions and 11 deletions.
1 change: 1 addition & 0 deletions api/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type SecretWrapInfo struct {
Token string `json:"token"`
TTL int `json:"ttl"`
CreationTime time.Time `json:"creation_time"`
CreationPath string `json:"creation_path"`
WrappedAccessor string `json:"wrapped_accessor"`
}

Expand Down
2 changes: 2 additions & 0 deletions audit/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ func (f *AuditFormatter) FormatResponse(
TTL: int(resp.WrapInfo.TTL / time.Second),
Token: token,
CreationTime: resp.WrapInfo.CreationTime.Format(time.RFC3339Nano),
CreationPath: resp.WrapInfo.CreationPath,
WrappedAccessor: resp.WrapInfo.WrappedAccessor,
}
}
Expand Down Expand Up @@ -406,6 +407,7 @@ type AuditResponseWrapInfo struct {
TTL int `json:"ttl"`
Token string `json:"token"`
CreationTime string `json:"creation_time"`
CreationPath string `json:"creation_path"`
WrappedAccessor string `json:"wrapped_accessor,omitempty"`
}

Expand Down
1 change: 1 addition & 0 deletions command/format.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ func (t TableFormatter) OutputSecret(ui cli.Ui, secret, s *api.Secret) error {
input = append(input, fmt.Sprintf("wrapping_token: %s %s", config.Delim, s.WrapInfo.Token))
input = append(input, fmt.Sprintf("wrapping_token_ttl: %s %s", config.Delim, (time.Second*time.Duration(s.WrapInfo.TTL)).String()))
input = append(input, fmt.Sprintf("wrapping_token_creation_time: %s %s", config.Delim, s.WrapInfo.CreationTime.String()))
input = append(input, fmt.Sprintf("wrapping_token_creation_path: %s %s", config.Delim, s.WrapInfo.CreationPath))
if s.WrapInfo.WrappedAccessor != "" {
input = append(input, fmt.Sprintf("wrapped_accessor: %s %s", config.Delim, s.WrapInfo.WrappedAccessor))
}
Expand Down
2 changes: 2 additions & 0 deletions command/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ func PrintRawField(ui cli.Ui, secret *api.Secret, field string) int {
val = secret.WrapInfo.TTL
case "wrapping_token_creation_time":
val = secret.WrapInfo.CreationTime.Format(time.RFC3339Nano)
case "wrapping_token_creation_path":
val = secret.WrapInfo.CreationPath
case "wrapped_accessor":
val = secret.WrapInfo.WrappedAccessor
default:
Expand Down
6 changes: 5 additions & 1 deletion helper/wrapping/wrapinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ type ResponseWrapInfo struct {

// The creation time. This can be used with the TTL to figure out an
// expected expiration.
CreationTime time.Time `json:"creation_time" structs:"creation_time" mapstructure:"cration_time"`
CreationTime time.Time `json:"creation_time" structs:"creation_time" mapstructure:"creation_time"`

// If the contained response is the output of a token creation call, the
// created token's accessor will be accessible here
WrappedAccessor string `json:"wrapped_accessor" structs:"wrapped_accessor" mapstructure:"wrapped_accessor"`

// The format to use. This doesn't get returned, it's only internal.
Format string `json:"format" structs:"format" mapstructure:"format"`

// CreationPath is the original request path that was used to create
// the wrapped response.
CreationPath string `json:"creation_path" structs:"creation_path" mapstructure:"creation_path"`
}
6 changes: 6 additions & 0 deletions http/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ func TestSysMounts_headerAuth_Wrapped(t *testing.T) {
}
expected["wrap_info"].(map[string]interface{})["creation_time"] = actualCreationTime

actualCreationPath, ok := actual["wrap_info"].(map[string]interface{})["creation_path"]
if !ok || actualCreationPath == "" {
t.Fatal("creation_path missing in wrap info")
}
expected["wrap_info"].(map[string]interface{})["creation_path"] = actualCreationPath

if !reflect.DeepEqual(actual, expected) {
t.Fatalf("bad:\nExpected: %#v\nActual: %#v\n%T %T", expected, actual, actual["warnings"], actual["data"])
}
Expand Down
1 change: 1 addition & 0 deletions http/logical.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func respondLogical(w http.ResponseWriter, r *http.Request, req *logical.Request
Token: resp.WrapInfo.Token,
TTL: int(resp.WrapInfo.TTL.Seconds()),
CreationTime: resp.WrapInfo.CreationTime.Format(time.RFC3339Nano),
CreationPath: resp.WrapInfo.CreationPath,
WrappedAccessor: resp.WrapInfo.WrappedAccessor,
},
}
Expand Down
11 changes: 11 additions & 0 deletions http/sys_wrapping_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,13 +308,24 @@ func TestHTTP_Wrapping(t *testing.T) {
}
wrapInfo = secret.WrapInfo

// Check for correct CreationPath before rewrap
if wrapInfo.CreationPath != "secret/foo" {
t.Fatal("error on wrapInfo.CreationPath: expected: secret/foo, got: %s", wrapInfo.CreationPath)
}

// Test rewrapping
secret, err = client.Logical().Write("sys/wrapping/rewrap", map[string]interface{}{
"token": wrapInfo.Token,
})
if err != nil {
t.Fatal(err)
}

// Check for correct Creation path after rewrap
if wrapInfo.CreationPath != "secret/foo" {
t.Fatal("error on wrapInfo.CreationPath: expected: secret/foo, got: %s", wrapInfo.CreationPath)
}

// Should be expired and fail
_, err = client.Logical().Write("sys/wrapping/unwrap", map[string]interface{}{
"token": wrapInfo.Token,
Expand Down
1 change: 1 addition & 0 deletions logical/translate_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ type HTTPWrapInfo struct {
Token string `json:"token"`
TTL int `json:"ttl"`
CreationTime string `json:"creation_time"`
CreationPath string `json:"creation_path"`
WrappedAccessor string `json:"wrapped_accessor,omitempty"`
}

Expand Down
14 changes: 13 additions & 1 deletion vault/logical_system.go
Original file line number Diff line number Diff line change
Expand Up @@ -2204,6 +2204,7 @@ func (b *SystemBackend) handleWrappingLookup(

creationTTLRaw := cubbyResp.Data["creation_ttl"]
creationTime := cubbyResp.Data["creation_time"]
creationPath := cubbyResp.Data["creation_path"]

resp := &logical.Response{
Data: map[string]interface{}{},
Expand All @@ -2219,6 +2220,9 @@ func (b *SystemBackend) handleWrappingLookup(
// This was JSON marshaled so it's already a string in RFC3339 format
resp.Data["creation_time"] = cubbyResp.Data["creation_time"]
}
if creationPath != nil {
resp.Data["creation_path"] = cubbyResp.Data["creation_path"]
}

return resp, nil
}
Expand Down Expand Up @@ -2278,6 +2282,13 @@ func (b *SystemBackend) handleWrappingRewrap(
return nil, fmt.Errorf("error reading creation_ttl value from wrapping information: %v", err)
}

// Get creation_path to return as the response later
creationPathRaw := cubbyResp.Data["creation_path"]
if creationPathRaw == nil {
return nil, fmt.Errorf("creation_path value in wrapping information was nil")
}
creationPath := creationPathRaw.(string)

// Fetch the original response and return it as the data for the new response
cubbyReq = &logical.Request{
Operation: logical.ReadOperation,
Expand Down Expand Up @@ -2310,7 +2321,8 @@ func (b *SystemBackend) handleWrappingRewrap(
"response": response,
},
WrapInfo: &wrapping.ResponseWrapInfo{
TTL: time.Duration(creationTTL),
TTL: time.Duration(creationTTL),
CreationPath: creationPath,
},
}, nil
}
Expand Down
16 changes: 10 additions & 6 deletions vault/request_handling.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,15 @@ func (c *Core) handleRequest(req *logical.Request) (retResp *logical.Response, r
if resp != nil {
// If wrapping is used, use the shortest between the request and response
var wrapTTL time.Duration
var wrapFormat string
var wrapFormat, creationPath string

// 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
}
wrapFormat = resp.WrapInfo.Format
creationPath = resp.WrapInfo.CreationPath
resp.WrapInfo = nil
}

Expand All @@ -218,8 +219,9 @@ func (c *Core) handleRequest(req *logical.Request) (retResp *logical.Response, r

if wrapTTL > 0 {
resp.WrapInfo = &wrapping.ResponseWrapInfo{
TTL: wrapTTL,
Format: wrapFormat,
TTL: wrapTTL,
Format: wrapFormat,
CreationPath: creationPath,
}
}
}
Expand Down Expand Up @@ -338,14 +340,15 @@ func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, *log
if resp != nil {
// If wrapping is used, use the shortest between the request and response
var wrapTTL time.Duration
var wrapFormat string
var wrapFormat, creationPath string

// 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
}
wrapFormat = resp.WrapInfo.Format
creationPath = resp.WrapInfo.CreationPath
resp.WrapInfo = nil
}

Expand All @@ -365,8 +368,9 @@ func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, *log

if wrapTTL > 0 {
resp.WrapInfo = &wrapping.ResponseWrapInfo{
TTL: wrapTTL,
Format: wrapFormat,
TTL: wrapTTL,
Format: wrapFormat,
CreationPath: creationPath,
}
}
}
Expand Down
11 changes: 11 additions & 0 deletions vault/wrapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l

resp.WrapInfo.Token = te.ID
resp.WrapInfo.CreationTime = creationTime
// If this is not a rewrap, store the request path as creation_path
if req.Path != "sys/wrapping/rewrap" {
resp.WrapInfo.CreationPath = req.Path
}

// This will only be non-nil if this response contains a token, so in that
// case put the accessor in the wrap info.
Expand Down Expand Up @@ -200,6 +204,12 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l
"creation_ttl": resp.WrapInfo.TTL,
"creation_time": creationTime,
}
// Store creation_path if not a rewrap
if req.Path != "sys/wrapping/rewrap" {
cubbyReq.Data["creation_path"] = req.Path
} else {
cubbyReq.Data["creation_path"] = resp.WrapInfo.CreationPath
}
cubbyResp, err = c.router.Route(cubbyReq)
if err != nil {
// Revoke since it's not yet being tracked for expiration
Expand Down Expand Up @@ -233,6 +243,7 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l
return nil, nil
}

// ValidateWrappingToken checks whether a token is a wrapping token.
func (c *Core) ValidateWrappingToken(req *logical.Request) (bool, error) {
if req == nil {
return false, fmt.Errorf("invalid request")
Expand Down
5 changes: 4 additions & 1 deletion website/source/api/system/wrapping-lookup.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,12 @@ $ curl \
"lease_duration": 0,
"renewable": false,
"data": {
"creation_path": "sys/wrapping/wrap",
"creation_time": "2016-09-28T14:16:13.07103516-04:00",
"creation_ttl": 300
},
"warnings": null
"wrap_info": null,
"warnings": null,
"auth": null
}
```
2 changes: 1 addition & 1 deletion website/source/api/system/wrapping-rewrap.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ $ curl \
"token": "3b6f1193-0707-ac17-284d-e41032e74d1f",
"ttl": 300,
"creation_time": "2016-09-28T14:22:26.486186607-04:00",
"wrapped_accessor": ""
"creation_path": "sys/wrapping/wrap"
}
}
```
2 changes: 1 addition & 1 deletion website/source/api/system/wrapping-wrap.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ $ curl \
"token": "fb79b9d3-d94e-9eb6-4919-c559311133d6",
"ttl": 300,
"creation_time": "2016-09-28T14:41:00.56961496-04:00",
"wrapped_accessor": ""
"creation_path": "sys/wrapping/wrap",
}
}
```

0 comments on commit 15634f3

Please sign in to comment.