2015-04-24 18:06:19 +00:00
|
|
|
package file
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2015-09-18 16:18:37 +00:00
|
|
|
"fmt"
|
2015-04-24 18:16:28 +00:00
|
|
|
"strconv"
|
2015-04-24 18:06:19 +00:00
|
|
|
|
|
|
|
"github.com/hashicorp/go-syslog"
|
|
|
|
"github.com/hashicorp/vault/audit"
|
2015-09-18 16:18:37 +00:00
|
|
|
"github.com/hashicorp/vault/helper/salt"
|
2015-04-24 18:06:19 +00:00
|
|
|
"github.com/hashicorp/vault/logical"
|
2015-04-24 18:39:43 +00:00
|
|
|
"github.com/mitchellh/copystructure"
|
2015-04-24 18:06:19 +00:00
|
|
|
)
|
|
|
|
|
2015-09-18 21:36:42 +00:00
|
|
|
func Factory(conf *audit.BackendConfig) (audit.Backend, error) {
|
2015-09-18 16:18:37 +00:00
|
|
|
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
|
2015-09-18 16:18:37 +00:00
|
|
|
facility, ok := conf.Config["facility"]
|
2015-04-24 18:06:19 +00:00
|
|
|
if !ok {
|
|
|
|
facility = "AUTH"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get tag or default to 'vault'
|
2015-09-18 16:18:37 +00:00
|
|
|
tag, ok := conf.Config["tag"]
|
2015-04-24 18:06:19 +00:00
|
|
|
if !ok {
|
|
|
|
tag = "vault"
|
|
|
|
}
|
|
|
|
|
2016-03-12 00:28:06 +00:00
|
|
|
// Check if hashing of accessor is disabled
|
2016-03-14 18:52:29 +00:00
|
|
|
hmacAccessor := true
|
|
|
|
if hmacAccessorRaw, ok := conf.Config["hmac_accessor"]; ok {
|
|
|
|
value, err := strconv.ParseBool(hmacAccessorRaw)
|
2016-03-12 00:28:06 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2016-03-14 18:52:29 +00:00
|
|
|
hmacAccessor = value
|
2016-03-12 00:28:06 +00:00
|
|
|
}
|
|
|
|
|
2015-04-24 18:16:28 +00:00
|
|
|
// Check if raw logging is enabled
|
2015-04-26 01:26:08 +00:00
|
|
|
logRaw := false
|
2015-09-18 16:18:37 +00:00
|
|
|
if raw, ok := conf.Config["log_raw"]; ok {
|
2015-04-24 18:16:28 +00:00
|
|
|
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{
|
2016-03-12 00:28:06 +00:00
|
|
|
logger: logger,
|
|
|
|
logRaw: logRaw,
|
2016-03-14 18:52:29 +00:00
|
|
|
hmacAccessor: hmacAccessor,
|
2016-03-12 00:28:06 +00:00
|
|
|
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 {
|
2016-03-12 00:28:06 +00:00
|
|
|
logger gsyslog.Syslogger
|
|
|
|
logRaw bool
|
2016-03-14 18:52:29 +00:00
|
|
|
hmacAccessor bool
|
2016-03-12 00:28:06 +00:00
|
|
|
salt *salt.Salt
|
2015-04-24 18:06:19 +00:00
|
|
|
}
|
|
|
|
|
2015-11-19 01:26:03 +00:00
|
|
|
func (b *Backend) GetHash(data string) string {
|
|
|
|
return audit.HashString(b.salt, data)
|
|
|
|
}
|
|
|
|
|
2015-06-19 01:30:18 +00:00
|
|
|
func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr error) error {
|
2015-04-24 18:16:28 +00:00
|
|
|
if !b.logRaw {
|
2015-06-30 00:16:17 +00:00
|
|
|
// 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
|
2015-06-30 00:16:17 +00:00
|
|
|
origState := req.Connection.ConnState
|
|
|
|
req.Connection.ConnState = nil
|
|
|
|
defer func() {
|
2015-07-08 22:45:15 +00:00
|
|
|
origReq.Connection.ConnState = origState
|
2015-06-30 00:16:17 +00:00
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2015-04-24 18:39:43 +00:00
|
|
|
// 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
|
2015-09-18 16:18:37 +00:00
|
|
|
if err := audit.Hash(b.salt, auth); err != nil {
|
2015-04-24 18:16:28 +00:00
|
|
|
return err
|
|
|
|
}
|
2015-09-18 16:18:37 +00:00
|
|
|
if err := audit.Hash(b.salt, req); err != nil {
|
2015-04-24 18:16:28 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2015-04-24 18:39:43 +00:00
|
|
|
|
|
|
|
// Encode the entry as JSON
|
2015-04-24 18:06:19 +00:00
|
|
|
var buf bytes.Buffer
|
|
|
|
var format audit.FormatJSON
|
2015-06-19 01:30:18 +00:00
|
|
|
if err := format.FormatRequest(&buf, auth, req, outerErr); err != nil {
|
2015-04-24 18:06:19 +00:00
|
|
|
return err
|
|
|
|
}
|
2015-04-24 18:39:43 +00:00
|
|
|
|
|
|
|
// 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 {
|
2015-04-24 18:16:28 +00:00
|
|
|
if !b.logRaw {
|
2015-06-30 00:16:17 +00:00
|
|
|
// 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
|
2015-06-30 00:16:17 +00:00
|
|
|
origState := req.Connection.ConnState
|
|
|
|
req.Connection.ConnState = nil
|
|
|
|
defer func() {
|
2015-07-08 22:45:15 +00:00
|
|
|
origReq.Connection.ConnState = origState
|
2015-06-30 00:16:17 +00:00
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
2015-04-24 18:39:43 +00:00
|
|
|
// 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
|
2016-03-12 00:28:06 +00:00
|
|
|
|
|
|
|
// Cache and restore accessor in the auth
|
2016-06-13 23:58:17 +00:00
|
|
|
var accessor, wrappedAccessor string
|
2016-03-14 18:52:29 +00:00
|
|
|
if !b.hmacAccessor && auth != nil && auth.Accessor != "" {
|
2016-03-12 00:28:06 +00:00
|
|
|
accessor = auth.Accessor
|
|
|
|
}
|
2015-09-18 16:18:37 +00:00
|
|
|
if err := audit.Hash(b.salt, auth); err != nil {
|
2015-04-24 18:16:28 +00:00
|
|
|
return err
|
|
|
|
}
|
2016-03-14 15:23:30 +00:00
|
|
|
if accessor != "" {
|
2016-03-12 00:28:06 +00:00
|
|
|
auth.Accessor = accessor
|
|
|
|
}
|
|
|
|
|
2015-09-18 16:18:37 +00:00
|
|
|
if err := audit.Hash(b.salt, req); err != nil {
|
2015-04-24 18:16:28 +00:00
|
|
|
return err
|
|
|
|
}
|
2016-03-12 00:28:06 +00:00
|
|
|
|
|
|
|
// Cache and restore accessor in the response
|
|
|
|
accessor = ""
|
2016-03-14 18:52:29 +00:00
|
|
|
if !b.hmacAccessor && resp != nil && resp.Auth != nil && resp.Auth.Accessor != "" {
|
2016-03-12 00:28:06 +00:00
|
|
|
accessor = resp.Auth.Accessor
|
|
|
|
}
|
2016-06-13 23:58:17 +00:00
|
|
|
if !b.hmacAccessor && resp != nil && resp.WrapInfo != nil && resp.WrapInfo.WrappedAccessor != "" {
|
|
|
|
wrappedAccessor = resp.WrapInfo.WrappedAccessor
|
|
|
|
}
|
2015-09-18 16:18:37 +00:00
|
|
|
if err := audit.Hash(b.salt, resp); err != nil {
|
2015-04-24 18:16:28 +00:00
|
|
|
return err
|
|
|
|
}
|
2016-03-14 15:23:30 +00:00
|
|
|
if accessor != "" {
|
2016-03-12 00:28:06 +00:00
|
|
|
resp.Auth.Accessor = accessor
|
|
|
|
}
|
2016-06-13 23:58:17 +00:00
|
|
|
if wrappedAccessor != "" {
|
|
|
|
resp.WrapInfo.WrappedAccessor = wrappedAccessor
|
|
|
|
}
|
2015-04-24 18:16:28 +00:00
|
|
|
}
|
2015-04-24 18:39:43 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
2015-04-24 18:39:43 +00:00
|
|
|
|
|
|
|
// Write otu to syslog
|
2015-04-24 18:06:19 +00:00
|
|
|
_, err = b.logger.Write(buf.Bytes())
|
|
|
|
return err
|
|
|
|
}
|