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

Add token accessor to wrap information if one exists #1520

Merged
merged 2 commits into from Jun 14, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 7 additions & 4 deletions api/secret.go
Expand Up @@ -31,11 +31,14 @@ type Secret struct {
WrapInfo *SecretWrapInfo `json:"wrap_info,omitempty"`
}

// SecretWrapInfo contains wrapping information if we have it.
// SecretWrapInfo contains wrapping information if we have it. If what is
// contained is an authentication token, the accessor for the token will be
// available in WrappedAccessor.
type SecretWrapInfo struct {
Token string `json:"token"`
TTL int `json:"ttl"`
CreationTime time.Time `json:"creation_time"`
Token string `json:"token"`
TTL int `json:"ttl"`
CreationTime time.Time `json:"creation_time"`
WrappedAccessor string `json:"wrapped_accessor"`
}

// SecretAuth is the structure containing auth information if we have it.
Expand Down
10 changes: 6 additions & 4 deletions api/secret_test.go
Expand Up @@ -22,7 +22,8 @@ func TestParseSecret(t *testing.T) {
"wrap_info": {
"token": "token",
"ttl": 60,
"creation_time": "2016-06-07T15:52:10-04:00"
"creation_time": "2016-06-07T15:52:10-04:00",
"wrapped_accessor": "abcd1234"
}
}`)

Expand All @@ -44,9 +45,10 @@ func TestParseSecret(t *testing.T) {
"a warning!",
},
WrapInfo: &SecretWrapInfo{
Token: "token",
TTL: 60,
CreationTime: rawTime,
Token: "token",
TTL: 60,
CreationTime: rawTime,
WrappedAccessor: "abcd1234",
},
}
if !reflect.DeepEqual(secret, expected) {
Expand Down
25 changes: 14 additions & 11 deletions audit/format_json.go
Expand Up @@ -90,9 +90,10 @@ func (f *FormatJSON) FormatResponse(
var respWrapInfo *JSONWrapInfo
if resp.WrapInfo != nil {
respWrapInfo = &JSONWrapInfo{
TTL: int(resp.WrapInfo.TTL / time.Second),
Token: resp.WrapInfo.Token,
CreationTime: resp.WrapInfo.CreationTime,
TTL: int(resp.WrapInfo.TTL / time.Second),
Token: resp.WrapInfo.Token,
CreationTime: resp.WrapInfo.CreationTime,
WrappedAccessor: resp.WrapInfo.WrappedAccessor,
}
}

Expand All @@ -110,11 +111,12 @@ func (f *FormatJSON) FormatResponse(
},

Request: JSONRequest{
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
RemoteAddr: getRemoteAddr(req),
WrapTTL: int(req.WrapTTL / time.Second),
ClientToken: req.ClientToken,
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
RemoteAddr: getRemoteAddr(req),
WrapTTL: int(req.WrapTTL / time.Second),
},

Response: JSONResponse{
Expand Down Expand Up @@ -176,9 +178,10 @@ type JSONSecret struct {
}

type JSONWrapInfo struct {
TTL int `json:"ttl"`
Token string `json:"token"`
CreationTime time.Time `json:"creation_time"`
TTL int `json:"ttl"`
Token string `json:"token"`
CreationTime time.Time `json:"creation_time"`
WrappedAccessor string `json:"wrapped_accessor,omitempty"`
}

// getRemoteAddr safely gets the remote address avoiding a nil pointer
Expand Down
4 changes: 4 additions & 0 deletions audit/hashstructure.go
Expand Up @@ -86,6 +86,10 @@ func Hash(salter *salt.Salt, raw interface{}) error {
}

s.Token = fn(s.Token)

if s.WrappedAccessor != "" {
s.WrappedAccessor = fn(s.WrappedAccessor)
}
}

return nil
Expand Down
21 changes: 12 additions & 9 deletions audit/hashstructure_test.go
Expand Up @@ -68,9 +68,10 @@ func TestCopy_response(t *testing.T) {
"foo": "bar",
},
WrapInfo: &logical.WrapInfo{
TTL: 60,
Token: "foo",
CreationTime: time.Now(),
TTL: 60,
Token: "foo",
CreationTime: time.Now(),
WrappedAccessor: "abcd1234",
},
}
arg := expected
Expand Down Expand Up @@ -138,19 +139,21 @@ func TestHash(t *testing.T) {
"foo": "bar",
},
WrapInfo: &logical.WrapInfo{
TTL: 60,
Token: "bar",
CreationTime: now,
TTL: 60,
Token: "bar",
CreationTime: now,
WrappedAccessor: "bar",
},
},
&logical.Response{
Data: map[string]interface{}{
"foo": "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317",
},
WrapInfo: &logical.WrapInfo{
TTL: 60,
Token: "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317",
CreationTime: now,
TTL: 60,
Token: "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317",
CreationTime: now,
WrappedAccessor: "hmac-sha256:f9320baf0249169e73850cd6156ded0106e2bb6ad8cab01b7bbbebe6d1065317",
},
},
},
Expand Down
8 changes: 7 additions & 1 deletion builtin/audit/file/backend.go
Expand Up @@ -167,7 +167,7 @@ func (b *Backend) LogResponse(
// Hash any sensitive information

// Cache and restore accessor in the auth
var accessor string
var accessor, wrappedAccessor string
if !b.hmacAccessor && auth != nil && auth.Accessor != "" {
accessor = auth.Accessor
}
Expand All @@ -187,12 +187,18 @@ func (b *Backend) LogResponse(
if !b.hmacAccessor && resp != nil && resp.Auth != nil && resp.Auth.Accessor != "" {
accessor = resp.Auth.Accessor
}
if !b.hmacAccessor && resp != nil && resp.WrapInfo != nil && resp.WrapInfo.WrappedAccessor != "" {
wrappedAccessor = resp.WrapInfo.WrappedAccessor
}
if err := audit.Hash(b.salt, resp); err != nil {
return err
}
if accessor != "" {
resp.Auth.Accessor = accessor
}
if wrappedAccessor != "" {
resp.WrapInfo.WrappedAccessor = wrappedAccessor
}
}

var format audit.FormatJSON
Expand Down
8 changes: 7 additions & 1 deletion builtin/audit/syslog/backend.go
Expand Up @@ -159,7 +159,7 @@ func (b *Backend) LogResponse(auth *logical.Auth, req *logical.Request,
// Hash any sensitive information

// Cache and restore accessor in the auth
var accessor string
var accessor, wrappedAccessor string
if !b.hmacAccessor && auth != nil && auth.Accessor != "" {
accessor = auth.Accessor
}
Expand All @@ -179,12 +179,18 @@ func (b *Backend) LogResponse(auth *logical.Auth, req *logical.Request,
if !b.hmacAccessor && resp != nil && resp.Auth != nil && resp.Auth.Accessor != "" {
accessor = resp.Auth.Accessor
}
if !b.hmacAccessor && resp != nil && resp.WrapInfo != nil && resp.WrapInfo.WrappedAccessor != "" {
wrappedAccessor = resp.WrapInfo.WrappedAccessor
}
if err := audit.Hash(b.salt, resp); err != nil {
return err
}
if accessor != "" {
resp.Auth.Accessor = accessor
}
if wrappedAccessor != "" {
resp.WrapInfo.WrappedAccessor = wrappedAccessor
}
}

// Encode the entry as JSON
Expand Down
3 changes: 3 additions & 0 deletions command/format.go
Expand Up @@ -161,6 +161,9 @@ 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 %d", config.Delim, s.WrapInfo.TTL))
input = append(input, fmt.Sprintf("wrapping_token_creation_time: %s %s", config.Delim, s.WrapInfo.CreationTime.String()))
if s.WrapInfo.WrappedAccessor != "" {
input = append(input, fmt.Sprintf("wrapped_accessor: %s %s", config.Delim, s.WrapInfo.WrappedAccessor))
}
}

keys := make([]string, 0, len(s.Data))
Expand Down
4 changes: 4 additions & 0 deletions command/util.go
Expand Up @@ -44,6 +44,10 @@ func PrintRawField(ui cli.Ui, secret *api.Secret, field string) int {
if secret.WrapInfo != nil {
val = secret.WrapInfo.CreationTime.String()
}
case "wrapped_accessor":
if secret.WrapInfo != nil {
val = secret.WrapInfo.WrappedAccessor
}
case "refresh_interval":
val = secret.LeaseDuration
default:
Expand Down
7 changes: 4 additions & 3 deletions http/logical.go
Expand Up @@ -163,9 +163,10 @@ 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()),
CreationTime: resp.WrapInfo.CreationTime,
Token: resp.WrapInfo.Token,
TTL: int(resp.WrapInfo.TTL.Seconds()),
CreationTime: resp.WrapInfo.CreationTime,
WrappedAccessor: resp.WrapInfo.WrappedAccessor,
},
}
} else {
Expand Down
4 changes: 4 additions & 0 deletions logical/response.go
Expand Up @@ -38,6 +38,10 @@ type WrapInfo struct {
// The creation time. This can be used with the TTL to figure out an
// expected expiration.
CreationTime time.Time

// If the contained response is the output of a token creation call, the
// created token's accessor will be accessible here
WrappedAccessor string
}

// Response is a struct that stores the response of a request.
Expand Down
7 changes: 4 additions & 3 deletions logical/sanitize.go
Expand Up @@ -54,7 +54,8 @@ type HTTPAuth struct {
}

type HTTPWrapInfo struct {
Token string `json:"token"`
TTL int `json:"ttl"`
CreationTime time.Time `json:"creation_time"`
Token string `json:"token"`
TTL int `json:"ttl"`
CreationTime time.Time `json:"creation_time"`
WrappedAccessor string `json:"wrapped_accessor,omitempty"`
}
4 changes: 4 additions & 0 deletions vault/request_handling.go
Expand Up @@ -393,6 +393,10 @@ func (c *Core) wrapInCubbyhole(req *logical.Request, resp *logical.Response) (*l
resp.WrapInfo.Token = te.ID
resp.WrapInfo.CreationTime = creationTime

if resp.Auth != nil {
Copy link
Member

Choose a reason for hiding this comment

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

A comment here would help understand that Auth will be non-nil only when a token is created and hence that is the only case when this will be set.

resp.WrapInfo.WrappedAccessor = resp.Auth.Accessor
}

httpResponse := logical.SanitizeResponse(resp)

// Because of the way that JSON encodes (likely just in Go) we actually get
Expand Down