Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store original request path in WrapInfo #3100

Merged
merged 5 commits into from
Aug 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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": ""
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrapped_accessor is not returned if it's empty.

"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",
}
}
```