open-vault/builtin/audit/syslog/backend.go

201 lines
4.4 KiB
Go
Raw Normal View History

2015-04-24 18:06:19 +00:00
package file
import (
"bytes"
"fmt"
"strconv"
2015-04-24 18:06:19 +00:00
"github.com/hashicorp/go-syslog"
"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/helper/salt"
2015-04-24 18:06:19 +00:00
"github.com/hashicorp/vault/logical"
"github.com/mitchellh/copystructure"
2015-04-24 18:06:19 +00:00
)
func Factory(conf *audit.BackendConfig) (audit.Backend, error) {
if conf.Salt == nil {
return nil, fmt.Errorf("Nil salt passed in")
}
2015-04-24 18:06:19 +00:00
// Get facility or default to AUTH
facility, ok := conf.Config["facility"]
2015-04-24 18:06:19 +00:00
if !ok {
facility = "AUTH"
}
// Get tag or default to 'vault'
tag, ok := conf.Config["tag"]
2015-04-24 18:06:19 +00:00
if !ok {
tag = "vault"
}
// Check if hashing of accessor is disabled
hashAccessor := true
if hashAccessorRaw, ok := conf.Config["hash_accessor"]; ok {
value, err := strconv.ParseBool(hashAccessorRaw)
if err != nil {
return nil, err
}
hashAccessor = value
}
// Check if raw logging is enabled
2015-04-26 01:26:08 +00:00
logRaw := false
if raw, ok := conf.Config["log_raw"]; ok {
b, err := strconv.ParseBool(raw)
if err != nil {
return nil, err
}
logRaw = b
}
2015-04-24 18:06:19 +00:00
// Get the logger
logger, err := gsyslog.NewLogger(gsyslog.LOG_INFO, facility, tag)
if err != nil {
return nil, err
}
b := &Backend{
logger: logger,
logRaw: logRaw,
hashAccessor: hashAccessor,
salt: conf.Salt,
2015-04-24 18:06:19 +00:00
}
return b, nil
}
// Backend is the audit backend for the syslog-based audit store.
type Backend struct {
logger gsyslog.Syslogger
logRaw bool
hashAccessor bool
salt *salt.Salt
2015-04-24 18:06:19 +00:00
}
func (b *Backend) GetHash(data string) string {
return audit.HashString(b.salt, data)
}
func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr error) error {
if !b.logRaw {
// Before we copy the structure we must nil out some data
// otherwise we will cause reflection to panic and die
if req.Connection != nil && req.Connection.ConnState != nil {
2015-07-08 22:45:15 +00:00
origReq := req
origState := req.Connection.ConnState
req.Connection.ConnState = nil
defer func() {
2015-07-08 22:45:15 +00:00
origReq.Connection.ConnState = origState
}()
}
// Copy the structures
cp, err := copystructure.Copy(auth)
if err != nil {
return err
}
auth = cp.(*logical.Auth)
cp, err = copystructure.Copy(req)
if err != nil {
return err
}
req = cp.(*logical.Request)
// Hash any sensitive information
if err := audit.Hash(b.salt, auth); err != nil {
return err
}
if err := audit.Hash(b.salt, req); err != nil {
return err
}
}
// Encode the entry as JSON
2015-04-24 18:06:19 +00:00
var buf bytes.Buffer
var format audit.FormatJSON
if err := format.FormatRequest(&buf, auth, req, outerErr); err != nil {
2015-04-24 18:06:19 +00:00
return err
}
// Write out to syslog
2015-04-24 18:06:19 +00:00
_, err := b.logger.Write(buf.Bytes())
return err
}
func (b *Backend) LogResponse(auth *logical.Auth, req *logical.Request,
resp *logical.Response, err error) error {
if !b.logRaw {
// Before we copy the structure we must nil out some data
// otherwise we will cause reflection to panic and die
if req.Connection != nil && req.Connection.ConnState != nil {
2015-07-08 22:45:15 +00:00
origReq := req
origState := req.Connection.ConnState
req.Connection.ConnState = nil
defer func() {
2015-07-08 22:45:15 +00:00
origReq.Connection.ConnState = origState
}()
}
// Copy the structure
cp, err := copystructure.Copy(auth)
if err != nil {
return err
}
auth = cp.(*logical.Auth)
cp, err = copystructure.Copy(req)
if err != nil {
return err
}
req = cp.(*logical.Request)
cp, err = copystructure.Copy(resp)
if err != nil {
return err
}
resp = cp.(*logical.Response)
// Hash any sensitive information
// Cache and restore accessor in the auth
var accessor string
if !b.hashAccessor && auth != nil && auth.Accessor != "" {
accessor = auth.Accessor
}
if err := audit.Hash(b.salt, auth); err != nil {
return err
}
if accessor != "" {
auth.Accessor = accessor
}
if err := audit.Hash(b.salt, req); err != nil {
return err
}
// Cache and restore accessor in the response
accessor = ""
if !b.hashAccessor && resp != nil && resp.Auth != nil && resp.Auth.Accessor != "" {
accessor = resp.Auth.Accessor
}
if err := audit.Hash(b.salt, resp); err != nil {
return err
}
if accessor != "" {
resp.Auth.Accessor = accessor
}
}
// Encode the entry as JSON
2015-04-24 18:06:19 +00:00
var buf bytes.Buffer
var format audit.FormatJSON
if err := format.FormatResponse(&buf, auth, req, resp, err); err != nil {
return err
}
// Write otu to syslog
2015-04-24 18:06:19 +00:00
_, err = b.logger.Write(buf.Bytes())
return err
}