Skip to content

Commit

Permalink
refactor validateWrappingToken to perform audit logging
Browse files Browse the repository at this point in the history
  • Loading branch information
calvn committed Jul 3, 2019
1 parent 00c3d11 commit 37556fb
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 72 deletions.
66 changes: 12 additions & 54 deletions vault/request_handling.go
Original file line number Diff line number Diff line change
Expand Up @@ -590,33 +590,12 @@ func (c *Core) handleRequest(ctx context.Context, req *logical.Request) (retResp
// logical.Request's token-related fields.
switch req.Path {
case "sys/wrapping/rewrap", "sys/wrapping/unwrap":
valid, err := c.validateWrappingToken(ctx, req)

// Perform audit logging before returning if there's an issue with checking
// the wrapping token
if err != nil || !valid {
// We log the Auth object like so here since the wrapping token can
// come from the header, which gets set as the ClientToken
auth := &logical.Auth{
ClientToken: req.ClientToken,
Accessor: req.ClientTokenAccessor,
}

logInput := &audit.LogInput{
Auth: auth,
Request: req,
NonHMACReqDataKeys: nonHMACReqDataKeys,
}
if err := c.auditBroker.LogRequest(ctx, logInput, c.auditedHeaders); err != nil {
c.logger.Error("failed to audit request", "path", req.Path, "error", err)
}

switch {
case err != nil:
return nil, auth, errwrap.Wrapf("error validating wrapping token: {{err}}", err)
case !valid:
return logical.ErrorResponse(consts.ErrInvalidWrappingToken.Error()), auth, logical.ErrInvalidRequest
}
valid, wtAuth, err := c.validateWrappingToken(ctx, req, nonHMACReqDataKeys)
if err != nil {
return nil, wtAuth, errwrap.Wrapf("error validating wrapping token: {{err}}", err)
}
if !valid {
return logical.ErrorResponse(consts.ErrInvalidWrappingToken.Error()), wtAuth, logical.ErrInvalidRequest
}
}

Expand Down Expand Up @@ -958,33 +937,12 @@ func (c *Core) handleLoginRequest(ctx context.Context, req *logical.Request) (re
// logical.Request's token-related fields.
switch req.Path {
case "sys/wrapping/lookup":
valid, err := c.validateWrappingToken(ctx, req)
// Perform audit logging before returning if there's an issue with checking
// the wrapping token
if err != nil || !valid {
// We log the Auth object like so here since the wrapping token can
// come from the header, which gets set as the ClientToken
auth := &logical.Auth{
ClientToken: req.ClientToken,
Accessor: req.ClientTokenAccessor,
}

logInput := &audit.LogInput{
Auth: auth,
Request: req,
NonHMACReqDataKeys: nonHMACReqDataKeys,
}
if err := c.auditBroker.LogRequest(ctx, logInput, c.auditedHeaders); err != nil {
c.logger.Error("failed to audit request", "path", req.Path, "error", err)
}

switch {
case err != nil:
return nil, auth, errwrap.Wrapf("error validating wrapping token: {{err}}", err)
case !valid:
return logical.ErrorResponse(consts.ErrInvalidWrappingToken.Error()), auth, logical.ErrInvalidRequest

}
valid, wtAuth, err := c.validateWrappingToken(ctx, req, nonHMACReqDataKeys)
if err != nil {
return nil, wtAuth, errwrap.Wrapf("error validating wrapping token: {{err}}", err)
}
if !valid {
return logical.ErrorResponse(consts.ErrInvalidWrappingToken.Error()), wtAuth, logical.ErrInvalidRequest
}
}

Expand Down
57 changes: 39 additions & 18 deletions vault/wrapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,12 +312,33 @@ DONELISTHANDLING:
// validateWrappingToken checks whether a token is a wrapping token. The passed
// in logical request will be updated if the wrapping token was provided within
// a JWT token.
func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request) (bool, error) {
func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request, nonHMACReqDataKeys []string) (valid bool, auth *logical.Auth, err error) {
defer func() {
// Perform audit logging before returning if there's an issue with checking
// the wrapping token
if err != nil || !valid {
// We log the Auth object like so here since the wrapping token can
// come from the header, which gets set as the ClientToken
auth = &logical.Auth{
ClientToken: req.ClientToken,
Accessor: req.ClientTokenAccessor,
}

logInput := &logical.LogInput{
Auth: auth,
Request: req,
NonHMACReqDataKeys: nonHMACReqDataKeys,
}
if err := c.auditBroker.LogRequest(ctx, logInput, c.auditedHeaders); err != nil {
c.logger.Error("failed to audit request", "path", req.Path, "error", err)
}
}
}()

if req == nil {
return false, fmt.Errorf("invalid request")
return false, nil, fmt.Errorf("invalid request")
}

var err error
var token string
var thirdParty bool

Expand All @@ -326,9 +347,9 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request)
if req.Data != nil && req.Data["token"] != nil {
thirdParty = true
if tokenStr, ok := req.Data["token"].(string); !ok {
return false, fmt.Errorf("could not decode token in request body")
return false, nil, fmt.Errorf("could not decode token in request body")
} else if tokenStr == "" {
return false, fmt.Errorf("empty token in request body")
return false, nil, fmt.Errorf("empty token in request body")
} else {
token = tokenStr
}
Expand All @@ -346,23 +367,23 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request)
// Implement the jose library way
parsedJWT, err := squarejwt.ParseSigned(token)
if err != nil {
return false, errwrap.Wrapf("wrapping token could not be parsed: {{err}}", err)
return false, nil, errwrap.Wrapf("wrapping token could not be parsed: {{err}}", err)
}
var claims squarejwt.Claims
var allClaims = make(map[string]interface{})
if err = parsedJWT.Claims(&c.wrappingJWTKey.PublicKey, &claims, &allClaims); err != nil {
return false, errwrap.Wrapf("wrapping token signature could not be validated: {{err}}", err)
return false, nil, errwrap.Wrapf("wrapping token signature could not be validated: {{err}}", err)
}
typeClaimRaw, ok := allClaims["type"]
if !ok {
return false, errors.New("could not validate type claim")
return false, nil, errors.New("could not validate type claim")
}
typeClaim, ok := typeClaimRaw.(string)
if !ok {
return false, errors.New("could not parse type claim")
return false, nil, errors.New("could not parse type claim")
}
if typeClaim != "wrapping" {
return false, errors.New("unexpected type claim")
return false, nil, errors.New("unexpected type claim")
}
if !thirdParty {
req.ClientToken = claims.ID
Expand All @@ -374,33 +395,33 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request)
}

if token == "" {
return false, fmt.Errorf("token is empty")
return false, nil, fmt.Errorf("token is empty")
}

if c.Sealed() {
return false, consts.ErrSealed
return false, nil, consts.ErrSealed
}

c.stateLock.RLock()
defer c.stateLock.RUnlock()
if c.standby && !c.perfStandby {
return false, consts.ErrStandby
return false, nil, consts.ErrStandby
}

te, err := c.tokenStore.Lookup(ctx, token)
if err != nil {
return false, err
return false, nil, err
}
if te == nil {
return false, nil
return false, nil, nil
}

if len(te.Policies) != 1 {
return false, nil
return false, nil, nil
}

if te.Policies[0] != responseWrappingPolicyName && te.Policies[0] != controlGroupPolicyName {
return false, nil
return false, nil, nil
}

if !thirdParty {
Expand All @@ -409,5 +430,5 @@ func (c *Core) validateWrappingToken(ctx context.Context, req *logical.Request)
req.SetTokenEntry(te)
}

return true, nil
return true, nil, nil
}

0 comments on commit 37556fb

Please sign in to comment.