mirror of
https://github.com/hashicorp/vault.git
synced 2026-06-08 16:24:51 -04:00
Add some repcluster handling to audit and add some tests (#2384)
* Add some repcluster handling to audit and add some tests * Fix incorrect assumption about nil auth
This commit is contained in:
parent
513f8b918d
commit
64d63ba55a
4 changed files with 141 additions and 54 deletions
121
audit/format.go
121
audit/format.go
|
|
@ -27,7 +27,11 @@ func (f *AuditFormatter) FormatRequest(
|
|||
config FormatterConfig,
|
||||
auth *logical.Auth,
|
||||
req *logical.Request,
|
||||
err error) error {
|
||||
inErr error) error {
|
||||
|
||||
if req == nil {
|
||||
return fmt.Errorf("request to request-audit a nil request")
|
||||
}
|
||||
|
||||
if w == nil {
|
||||
return fmt.Errorf("writer for audit request is nil")
|
||||
|
|
@ -49,22 +53,26 @@ func (f *AuditFormatter) FormatRequest(
|
|||
}()
|
||||
}
|
||||
|
||||
// Copy the structures
|
||||
cp, err := copystructure.Copy(auth)
|
||||
if err != nil {
|
||||
return err
|
||||
// Copy the auth structure
|
||||
if auth != nil {
|
||||
cp, err := copystructure.Copy(auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
auth = cp.(*logical.Auth)
|
||||
}
|
||||
auth = cp.(*logical.Auth)
|
||||
|
||||
cp, err = copystructure.Copy(req)
|
||||
cp, err := copystructure.Copy(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req = cp.(*logical.Request)
|
||||
|
||||
// Hash any sensitive information
|
||||
if err := Hash(config.Salt, auth); err != nil {
|
||||
return err
|
||||
if auth != nil {
|
||||
if err := Hash(config.Salt, auth); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Cache and restore accessor in the request
|
||||
|
|
@ -85,8 +93,8 @@ func (f *AuditFormatter) FormatRequest(
|
|||
auth = new(logical.Auth)
|
||||
}
|
||||
var errString string
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
if inErr != nil {
|
||||
errString = inErr.Error()
|
||||
}
|
||||
|
||||
reqEntry := &AuditRequestEntry{
|
||||
|
|
@ -107,6 +115,7 @@ func (f *AuditFormatter) FormatRequest(
|
|||
Path: req.Path,
|
||||
Data: req.Data,
|
||||
RemoteAddr: getRemoteAddr(req),
|
||||
ReplicationCluster: req.ReplicationCluster,
|
||||
Headers: req.Headers,
|
||||
},
|
||||
}
|
||||
|
|
@ -128,7 +137,11 @@ func (f *AuditFormatter) FormatResponse(
|
|||
auth *logical.Auth,
|
||||
req *logical.Request,
|
||||
resp *logical.Response,
|
||||
err error) error {
|
||||
inErr error) error {
|
||||
|
||||
if req == nil {
|
||||
return fmt.Errorf("request to response-audit a nil request")
|
||||
}
|
||||
|
||||
if w == nil {
|
||||
return fmt.Errorf("writer for audit request is nil")
|
||||
|
|
@ -150,37 +163,43 @@ func (f *AuditFormatter) FormatResponse(
|
|||
}()
|
||||
}
|
||||
|
||||
// Copy the structure
|
||||
cp, err := copystructure.Copy(auth)
|
||||
if err != nil {
|
||||
return err
|
||||
// Copy the auth structure
|
||||
if auth != nil {
|
||||
cp, err := copystructure.Copy(auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
auth = cp.(*logical.Auth)
|
||||
}
|
||||
auth = cp.(*logical.Auth)
|
||||
|
||||
cp, err = copystructure.Copy(req)
|
||||
cp, err := copystructure.Copy(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req = cp.(*logical.Request)
|
||||
|
||||
cp, err = copystructure.Copy(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
if resp != nil {
|
||||
cp, err := copystructure.Copy(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp = cp.(*logical.Response)
|
||||
}
|
||||
resp = cp.(*logical.Response)
|
||||
|
||||
// Hash any sensitive information
|
||||
|
||||
// Cache and restore accessor in the auth
|
||||
var accessor, wrappedAccessor string
|
||||
if !config.HMACAccessor && auth != nil && auth.Accessor != "" {
|
||||
accessor = auth.Accessor
|
||||
}
|
||||
if err := Hash(config.Salt, auth); err != nil {
|
||||
return err
|
||||
}
|
||||
if accessor != "" {
|
||||
auth.Accessor = accessor
|
||||
if auth != nil {
|
||||
var accessor string
|
||||
if !config.HMACAccessor && auth.Accessor != "" {
|
||||
accessor = auth.Accessor
|
||||
}
|
||||
if err := Hash(config.Salt, auth); err != nil {
|
||||
return err
|
||||
}
|
||||
if accessor != "" {
|
||||
auth.Accessor = accessor
|
||||
}
|
||||
}
|
||||
|
||||
// Cache and restore accessor in the request
|
||||
|
|
@ -196,21 +215,23 @@ func (f *AuditFormatter) FormatResponse(
|
|||
}
|
||||
|
||||
// Cache and restore accessor in the response
|
||||
accessor = ""
|
||||
if !config.HMACAccessor && resp != nil && resp.Auth != nil && resp.Auth.Accessor != "" {
|
||||
accessor = resp.Auth.Accessor
|
||||
}
|
||||
if !config.HMACAccessor && resp != nil && resp.WrapInfo != nil && resp.WrapInfo.WrappedAccessor != "" {
|
||||
wrappedAccessor = resp.WrapInfo.WrappedAccessor
|
||||
}
|
||||
if err := Hash(config.Salt, resp); err != nil {
|
||||
return err
|
||||
}
|
||||
if accessor != "" {
|
||||
resp.Auth.Accessor = accessor
|
||||
}
|
||||
if wrappedAccessor != "" {
|
||||
resp.WrapInfo.WrappedAccessor = wrappedAccessor
|
||||
if resp != nil {
|
||||
var accessor, wrappedAccessor string
|
||||
if !config.HMACAccessor && resp != nil && resp.Auth != nil && resp.Auth.Accessor != "" {
|
||||
accessor = resp.Auth.Accessor
|
||||
}
|
||||
if !config.HMACAccessor && resp != nil && resp.WrapInfo != nil && resp.WrapInfo.WrappedAccessor != "" {
|
||||
wrappedAccessor = resp.WrapInfo.WrappedAccessor
|
||||
}
|
||||
if err := Hash(config.Salt, resp); err != nil {
|
||||
return err
|
||||
}
|
||||
if accessor != "" {
|
||||
resp.Auth.Accessor = accessor
|
||||
}
|
||||
if wrappedAccessor != "" {
|
||||
resp.WrapInfo.WrappedAccessor = wrappedAccessor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,8 +243,8 @@ func (f *AuditFormatter) FormatResponse(
|
|||
resp = new(logical.Response)
|
||||
}
|
||||
var errString string
|
||||
if err != nil {
|
||||
errString = err.Error()
|
||||
if inErr != nil {
|
||||
errString = inErr.Error()
|
||||
}
|
||||
|
||||
var respAuth *AuditAuth
|
||||
|
|
@ -276,6 +297,7 @@ func (f *AuditFormatter) FormatResponse(
|
|||
Path: req.Path,
|
||||
Data: req.Data,
|
||||
RemoteAddr: getRemoteAddr(req),
|
||||
ReplicationCluster: req.ReplicationCluster,
|
||||
Headers: req.Headers,
|
||||
},
|
||||
|
||||
|
|
@ -312,14 +334,15 @@ type AuditRequestEntry struct {
|
|||
type AuditResponseEntry struct {
|
||||
Time string `json:"time,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Error string `json:"error"`
|
||||
Auth AuditAuth `json:"auth"`
|
||||
Request AuditRequest `json:"request"`
|
||||
Response AuditResponse `json:"response"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
type AuditRequest struct {
|
||||
ID string `json:"id"`
|
||||
ReplicationCluster string `json:"replication_cluster,omitempty"`
|
||||
Operation logical.Operation `json:"operation"`
|
||||
ClientToken string `json:"client_token"`
|
||||
ClientTokenAccessor string `json:"client_token_accessor"`
|
||||
|
|
|
|||
55
audit/format_test.go
Normal file
55
audit/format_test.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package audit
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/vault/helper/salt"
|
||||
"github.com/hashicorp/vault/logical"
|
||||
)
|
||||
|
||||
type noopFormatWriter struct {
|
||||
}
|
||||
|
||||
func (n *noopFormatWriter) WriteRequest(_ io.Writer, _ *AuditRequestEntry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *noopFormatWriter) WriteResponse(_ io.Writer, _ *AuditResponseEntry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFormatRequestErrors(t *testing.T) {
|
||||
salter, _ := salt.NewSalt(nil, nil)
|
||||
config := FormatterConfig{
|
||||
Salt: salter,
|
||||
}
|
||||
formatter := AuditFormatter{
|
||||
AuditFormatWriter: &noopFormatWriter{},
|
||||
}
|
||||
|
||||
if err := formatter.FormatRequest(ioutil.Discard, config, nil, nil, nil); err == nil {
|
||||
t.Fatal("expected error due to nil request")
|
||||
}
|
||||
if err := formatter.FormatRequest(nil, config, nil, &logical.Request{}, nil); err == nil {
|
||||
t.Fatal("expected error due to nil writer")
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatResponseErrors(t *testing.T) {
|
||||
salter, _ := salt.NewSalt(nil, nil)
|
||||
config := FormatterConfig{
|
||||
Salt: salter,
|
||||
}
|
||||
formatter := AuditFormatter{
|
||||
AuditFormatWriter: &noopFormatWriter{},
|
||||
}
|
||||
|
||||
if err := formatter.FormatResponse(ioutil.Discard, config, nil, nil, nil, nil); err == nil {
|
||||
t.Fatal("expected error due to nil request")
|
||||
}
|
||||
if err := formatter.FormatResponse(nil, config, nil, &logical.Request{}, nil, nil); err == nil {
|
||||
t.Fatal("expected error due to nil writer")
|
||||
}
|
||||
}
|
||||
|
|
@ -157,10 +157,15 @@ func (b *Backend) open() error {
|
|||
return err
|
||||
}
|
||||
|
||||
// Change the file mode in case the log file already existed
|
||||
err = os.Chmod(b.path, b.mode)
|
||||
if err != nil {
|
||||
return err
|
||||
// Change the file mode in case the log file already existed. We special
|
||||
// case /dev/null since we can't chmod it
|
||||
switch b.path {
|
||||
case "/dev/null":
|
||||
default:
|
||||
err = os.Chmod(b.path, b.mode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ type Request struct {
|
|||
// Id is the uuid associated with each request
|
||||
ID string `json:"id" structs:"id" mapstructure:"id"`
|
||||
|
||||
// If set, the name given to the replication secondary where this request
|
||||
// originated
|
||||
ReplicationCluster string `json:"replication_cluster" structs:"replication_cluster", mapstructure:"replication_cluster"`
|
||||
|
||||
// Operation is the requested operation type
|
||||
Operation Operation `json:"operation" structs:"operation" mapstructure:"operation"`
|
||||
|
||||
|
|
@ -38,7 +42,7 @@ type Request struct {
|
|||
Data map[string]interface{} `json:"map" structs:"data" mapstructure:"data"`
|
||||
|
||||
// Storage can be used to durably store and retrieve state.
|
||||
Storage Storage `json:"storage" structs:"storage" mapstructure:"storage"`
|
||||
Storage Storage `json:"-"`
|
||||
|
||||
// Secret will be non-nil only for Revoke and Renew operations
|
||||
// to represent the secret that was returned prior.
|
||||
|
|
|
|||
Loading…
Reference in a new issue