diff --git a/audit/format.go b/audit/format.go
index c1d0126ed8..60833a2150 100644
--- a/audit/format.go
+++ b/audit/format.go
@@ -3,8 +3,10 @@ package audit
import (
"fmt"
"io"
+ "strings"
"time"
+ "github.com/SermoDigital/jose/jws"
"github.com/hashicorp/vault/logical"
"github.com/mitchellh/copystructure"
)
@@ -87,14 +89,6 @@ func (f *AuditFormatter) FormatRequest(
errString = err.Error()
}
- var reqWrapInfo *AuditRequestWrapInfo
- if req.WrapInfo != nil {
- reqWrapInfo = &AuditRequestWrapInfo{
- TTL: int(req.WrapInfo.TTL / time.Second),
- Format: req.WrapInfo.Format,
- }
- }
-
reqEntry := &AuditRequestEntry{
Type: "request",
Error: errString,
@@ -113,10 +107,13 @@ func (f *AuditFormatter) FormatRequest(
Path: req.Path,
Data: req.Data,
RemoteAddr: getRemoteAddr(req),
- WrapInfo: reqWrapInfo,
},
}
+ if req.WrapInfo != nil {
+ reqEntry.Request.WrapTTL = int(req.WrapInfo.TTL / time.Second)
+ }
+
if !config.OmitTime {
reqEntry.Time = time.Now().UTC().Format(time.RFC3339)
}
@@ -246,19 +243,15 @@ func (f *AuditFormatter) FormatResponse(
}
}
- var reqWrapInfo *AuditRequestWrapInfo
- if req.WrapInfo != nil {
- reqWrapInfo = &AuditRequestWrapInfo{
- TTL: int(req.WrapInfo.TTL / time.Second),
- Format: req.WrapInfo.Format,
- }
- }
-
var respWrapInfo *AuditResponseWrapInfo
if resp.WrapInfo != nil {
+ token := resp.WrapInfo.Token
+ if jwtToken := parseVaultTokenFromJWT(token); jwtToken != nil {
+ token = *jwtToken
+ }
respWrapInfo = &AuditResponseWrapInfo{
TTL: int(resp.WrapInfo.TTL / time.Second),
- Token: resp.WrapInfo.Token,
+ Token: token,
CreationTime: resp.WrapInfo.CreationTime.Format(time.RFC3339Nano),
WrappedAccessor: resp.WrapInfo.WrappedAccessor,
}
@@ -282,7 +275,6 @@ func (f *AuditFormatter) FormatResponse(
Path: req.Path,
Data: req.Data,
RemoteAddr: getRemoteAddr(req),
- WrapInfo: reqWrapInfo,
},
Response: AuditResponse{
@@ -294,6 +286,10 @@ func (f *AuditFormatter) FormatResponse(
},
}
+ if req.WrapInfo != nil {
+ respEntry.Request.WrapTTL = int(req.WrapInfo.TTL / time.Second)
+ }
+
if !config.OmitTime {
respEntry.Time = time.Now().UTC().Format(time.RFC3339)
}
@@ -328,7 +324,7 @@ type AuditRequest struct {
Path string `json:"path"`
Data map[string]interface{} `json:"data"`
RemoteAddr string `json:"remote_address"`
- WrapInfo *AuditRequestWrapInfo `json:"wrap_info,omitempty"`
+ WrapTTL int `json:"wrap_ttl"`
}
type AuditResponse struct {
@@ -351,11 +347,6 @@ type AuditSecret struct {
LeaseID string `json:"lease_id"`
}
-type AuditRequestWrapInfo struct {
- TTL int `json:"ttl"`
- Format string `json:"format"`
-}
-
type AuditResponseWrapInfo struct {
TTL int `json:"ttl"`
Token string `json:"token"`
@@ -370,3 +361,20 @@ func getRemoteAddr(req *logical.Request) string {
}
return ""
}
+
+// parseVaultTokenFromJWT returns a string iff the token was a JWT and we could
+// extract the original token ID from inside
+func parseVaultTokenFromJWT(token string) *string {
+ if strings.Count(token, ".") != 2 {
+ return nil
+ }
+
+ wt, err := jws.ParseJWT([]byte(token))
+ if err != nil || wt == nil {
+ return nil
+ }
+
+ result, _ := wt.Claims().JWTID()
+
+ return &result
+}
diff --git a/audit/format_json_test.go b/audit/format_json_test.go
index 5b2b098484..7fb7a8a15f 100644
--- a/audit/format_json_test.go
+++ b/audit/format_json_test.go
@@ -76,5 +76,5 @@ func TestFormatJSON_formatRequest(t *testing.T) {
}
}
-const testFormatJSONReqBasicStr = `{"time":"2015-08-05T13:45:46Z","type":"request","auth":{"display_name":"","policies":["root"],"metadata":null},"request":{"operation":"update","path":"/foo","data":null,"wrap_ttl":60,"remote_address":"127.0.0.1","wrap_info":{"ttl":60,"format":""}},"error":"this is an error"}
+const testFormatJSONReqBasicStr = `{"time":"2015-08-05T13:45:46Z","type":"request","auth":{"display_name":"","policies":["root"],"metadata":null},"request":{"operation":"update","path":"/foo","data":null,"wrap_ttl":60,"remote_address":"127.0.0.1"},"error":"this is an error"}
`
diff --git a/audit/format_jsonx_test.go b/audit/format_jsonx_test.go
index 1324b534a5..40d0bc572b 100644
--- a/audit/format_jsonx_test.go
+++ b/audit/format_jsonx_test.go
@@ -34,7 +34,7 @@ func TestFormatJSONx_formatRequest(t *testing.T) {
},
errors.New("this is an error"),
"",
- `rootthis is an errorupdate/foo127.0.0.160request`,
+ `rootthis is an errorupdate/foo127.0.0.160request`,
},
}
diff --git a/vault/cluster.go b/vault/cluster.go
index 69c171fbfc..d2dd63704a 100644
--- a/vault/cluster.go
+++ b/vault/cluster.go
@@ -42,11 +42,10 @@ var (
// This can be one of a few key types so the different params may or may not be filled
type clusterKeyParams struct {
- Type string `json:"type"`
- X *big.Int `json:"x,omitempty"`
- Y *big.Int `json:"y,omitempty"`
- D *big.Int `json:"d,omitempty"`
- ED25519Key []byte `json:"ed25519_key,omitempty"`
+ Type string `json:"type"`
+ X *big.Int `json:"x,omitempty"`
+ Y *big.Int `json:"y,omitempty"`
+ D *big.Int `json:"d,omitempty"`
}
type activeConnection struct {
diff --git a/vault/logical_system.go b/vault/logical_system.go
index f8519527ff..534651d52a 100644
--- a/vault/logical_system.go
+++ b/vault/logical_system.go
@@ -1528,10 +1528,6 @@ func (b *SystemBackend) handleWrappingUnwrap(
token = req.ClientToken
}
- if wt := b.Core.parseVaultTokenFromJWT(token); wt != nil {
- token = *wt
- }
-
if thirdParty {
// Use the token to decrement the use count to avoid a second operation on the token.
_, err := b.Core.tokenStore.UseTokenByID(token)
@@ -1592,10 +1588,6 @@ func (b *SystemBackend) handleWrappingLookup(
return logical.ErrorResponse("missing \"token\" value in input"), logical.ErrInvalidRequest
}
- if wt := b.Core.parseVaultTokenFromJWT(token); wt != nil {
- token = *wt
- }
-
cubbyReq := &logical.Request{
Operation: logical.ReadOperation,
Path: "cubbyhole/wrapinfo",
@@ -1652,10 +1644,6 @@ func (b *SystemBackend) handleWrappingRewrap(
token = req.ClientToken
}
- if wt := b.Core.parseVaultTokenFromJWT(token); wt != nil {
- token = *wt
- }
-
if thirdParty {
// Use the token to decrement the use count to avoid a second operation on the token.
_, err := b.Core.tokenStore.UseTokenByID(token)
diff --git a/vault/wrapping.go b/vault/wrapping.go
index 9e665cc837..0dc2e9b59a 100644
--- a/vault/wrapping.go
+++ b/vault/wrapping.go
@@ -240,7 +240,9 @@ func (c *Core) ValidateWrappingToken(req *logical.Request) (bool, error) {
var err error
var token string
+ var thirdParty bool
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")
} else if tokenStr == "" {
@@ -264,6 +266,14 @@ func (c *Core) ValidateWrappingToken(req *logical.Request) (bool, error) {
return false, errwrap.Wrapf("wrapping token signature could not be validated: {{err}}", err)
}
token, _ = wt.Claims().JWTID()
+ // We override the given request client token so that the rest of
+ // Vault sees the real value. This also ensures audit logs are
+ // consistent with the actual token that was issued.
+ if !thirdParty {
+ req.ClientToken = token
+ } else {
+ req.Data["token"] = token
+ }
}
}
@@ -298,21 +308,3 @@ func (c *Core) ValidateWrappingToken(req *logical.Request) (bool, error) {
return true, nil
}
-
-// parseVaultTokenFromJWT returns a string iff the token was a JWT and we could
-// extract the original token ID from inside
-func (c *Core) parseVaultTokenFromJWT(token string) *string {
- var result string
- if strings.Count(token, ".") != 2 {
- return nil
- }
-
- wt, err := jws.ParseJWT([]byte(token))
- if err != nil || wt == nil {
- return nil
- }
-
- result, _ = wt.Claims().JWTID()
-
- return &result
-}