2016-12-19 20:35:55 +00:00
|
|
|
package syslog
|
2015-04-24 18:06:19 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2018-01-19 06:44:44 +00:00
|
|
|
"context"
|
2015-09-18 16:18:37 +00:00
|
|
|
"fmt"
|
2015-04-24 18:16:28 +00:00
|
|
|
"strconv"
|
2017-05-24 00:36:20 +00:00
|
|
|
"sync"
|
2015-04-24 18:06:19 +00:00
|
|
|
|
2019-01-09 00:48:57 +00:00
|
|
|
gsyslog "github.com/hashicorp/go-syslog"
|
2015-04-24 18:06:19 +00:00
|
|
|
"github.com/hashicorp/vault/audit"
|
2019-04-12 21:54:35 +00:00
|
|
|
"github.com/hashicorp/vault/sdk/helper/salt"
|
|
|
|
"github.com/hashicorp/vault/sdk/logical"
|
2015-04-24 18:06:19 +00:00
|
|
|
)
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func Factory(ctx context.Context, conf *audit.BackendConfig) (audit.Backend, error) {
|
2017-05-24 00:36:20 +00:00
|
|
|
if conf.SaltConfig == nil {
|
|
|
|
return nil, fmt.Errorf("nil salt config")
|
|
|
|
}
|
|
|
|
if conf.SaltView == nil {
|
|
|
|
return nil, fmt.Errorf("nil salt view")
|
2015-09-18 16:18:37 +00:00
|
|
|
}
|
|
|
|
|
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-09-21 14:29:42 +00:00
|
|
|
format, ok := conf.Config["format"]
|
|
|
|
if !ok {
|
|
|
|
format = "json"
|
|
|
|
}
|
|
|
|
switch format {
|
|
|
|
case "json", "jsonx":
|
|
|
|
default:
|
2018-04-05 15:49:21 +00:00
|
|
|
return nil, fmt.Errorf("unknown format type %q", format)
|
2016-09-21 14:29:42 +00:00
|
|
|
}
|
|
|
|
|
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{
|
2017-05-24 00:36:20 +00:00
|
|
|
logger: logger,
|
|
|
|
saltConfig: conf.SaltConfig,
|
|
|
|
saltView: conf.SaltView,
|
2016-09-21 14:29:42 +00:00
|
|
|
formatConfig: audit.FormatterConfig{
|
|
|
|
Raw: logRaw,
|
|
|
|
HMACAccessor: hmacAccessor,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
switch format {
|
|
|
|
case "json":
|
2017-02-11 00:56:28 +00:00
|
|
|
b.formatter.AuditFormatWriter = &audit.JSONFormatWriter{
|
2017-05-24 00:36:20 +00:00
|
|
|
Prefix: conf.Config["prefix"],
|
|
|
|
SaltFunc: b.Salt,
|
2017-02-11 00:56:28 +00:00
|
|
|
}
|
2016-09-21 14:29:42 +00:00
|
|
|
case "jsonx":
|
2017-02-11 00:56:28 +00:00
|
|
|
b.formatter.AuditFormatWriter = &audit.JSONxFormatWriter{
|
2017-05-24 00:36:20 +00:00
|
|
|
Prefix: conf.Config["prefix"],
|
|
|
|
SaltFunc: b.Salt,
|
2017-02-11 00:56:28 +00:00
|
|
|
}
|
2015-04-24 18:06:19 +00:00
|
|
|
}
|
2016-09-21 14:29:42 +00:00
|
|
|
|
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-09-21 14:29:42 +00:00
|
|
|
logger gsyslog.Syslogger
|
|
|
|
|
|
|
|
formatter audit.AuditFormatter
|
|
|
|
formatConfig audit.FormatterConfig
|
2017-05-24 00:36:20 +00:00
|
|
|
|
|
|
|
saltMutex sync.RWMutex
|
|
|
|
salt *salt.Salt
|
|
|
|
saltConfig *salt.Config
|
|
|
|
saltView logical.Storage
|
2015-04-24 18:06:19 +00:00
|
|
|
}
|
|
|
|
|
2018-03-02 17:18:39 +00:00
|
|
|
var _ audit.Backend = (*Backend)(nil)
|
|
|
|
|
2018-03-08 19:21:11 +00:00
|
|
|
func (b *Backend) GetHash(ctx context.Context, data string) (string, error) {
|
|
|
|
salt, err := b.Salt(ctx)
|
2017-05-24 00:36:20 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return audit.HashString(salt, data), nil
|
2015-11-19 01:26:03 +00:00
|
|
|
}
|
|
|
|
|
2018-03-08 19:21:11 +00:00
|
|
|
func (b *Backend) LogRequest(ctx context.Context, in *audit.LogInput) error {
|
2015-04-24 18:06:19 +00:00
|
|
|
var buf bytes.Buffer
|
2018-03-08 19:21:11 +00:00
|
|
|
if err := b.formatter.FormatRequest(ctx, &buf, b.formatConfig, in); 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
|
|
|
|
}
|
|
|
|
|
2018-03-08 19:21:11 +00:00
|
|
|
func (b *Backend) LogResponse(ctx context.Context, in *audit.LogInput) error {
|
2015-04-24 18:06:19 +00:00
|
|
|
var buf bytes.Buffer
|
2018-03-08 19:21:11 +00:00
|
|
|
if err := b.formatter.FormatResponse(ctx, &buf, b.formatConfig, in); err != nil {
|
2015-04-24 18:06:19 +00:00
|
|
|
return err
|
|
|
|
}
|
2015-04-24 18:39:43 +00:00
|
|
|
|
2016-12-19 20:35:55 +00:00
|
|
|
// Write out to syslog
|
2018-03-02 17:18:39 +00:00
|
|
|
_, err := b.logger.Write(buf.Bytes())
|
2015-04-24 18:06:19 +00:00
|
|
|
return err
|
|
|
|
}
|
2016-09-30 19:04:50 +00:00
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (b *Backend) Reload(_ context.Context) error {
|
2016-09-30 19:04:50 +00:00
|
|
|
return nil
|
|
|
|
}
|
2017-05-24 00:36:20 +00:00
|
|
|
|
2018-03-08 19:21:11 +00:00
|
|
|
func (b *Backend) Salt(ctx context.Context) (*salt.Salt, error) {
|
2017-05-24 00:36:20 +00:00
|
|
|
b.saltMutex.RLock()
|
|
|
|
if b.salt != nil {
|
|
|
|
defer b.saltMutex.RUnlock()
|
|
|
|
return b.salt, nil
|
|
|
|
}
|
|
|
|
b.saltMutex.RUnlock()
|
|
|
|
b.saltMutex.Lock()
|
|
|
|
defer b.saltMutex.Unlock()
|
|
|
|
if b.salt != nil {
|
|
|
|
return b.salt, nil
|
|
|
|
}
|
2018-03-08 19:21:11 +00:00
|
|
|
salt, err := salt.NewSalt(ctx, b.saltView, b.saltConfig)
|
2017-05-24 00:36:20 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
b.salt = salt
|
|
|
|
return salt, nil
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
func (b *Backend) Invalidate(_ context.Context) {
|
2017-05-24 00:36:20 +00:00
|
|
|
b.saltMutex.Lock()
|
|
|
|
defer b.saltMutex.Unlock()
|
|
|
|
b.salt = nil
|
|
|
|
}
|