Skip to content

Commit

Permalink
Add HMAC capability to salt. Pass a salt into audit backends. Require…
Browse files Browse the repository at this point in the history
… it for audit.Hash.
  • Loading branch information
jefferai committed Sep 18, 2015
1 parent d62f533 commit a4ca14c
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 71 deletions.
15 changes: 13 additions & 2 deletions audit/audit.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package audit

import "github.com/hashicorp/vault/logical"
import (
"github.com/hashicorp/vault/helper/salt"
"github.com/hashicorp/vault/logical"
)

// Backend interface must be implemented for an audit
// mechanism to be made available. Audit backends can be enabled to
Expand All @@ -20,5 +23,13 @@ type Backend interface {
LogResponse(*logical.Auth, *logical.Request, *logical.Response, error) error
}

type BackendConfig struct {
// The salt that should be used for any secret obfuscation
Salt *salt.Salt

// Config is the opaque user configuration provided when mounting
Config map[string]string
}

// Factory is the factory function to create an audit backend.
type Factory func(map[string]string) (Backend, error)
type Factory func(BackendConfig) (Backend, error)
27 changes: 10 additions & 17 deletions audit/hashstructure.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package audit

import (
"crypto/sha1"
"encoding/hex"
"fmt"
"reflect"
"strings"

"github.com/hashicorp/vault/helper/salt"
"github.com/hashicorp/vault/logical"
"github.com/mitchellh/copystructure"
"github.com/mitchellh/reflectwalk"
Expand All @@ -17,28 +15,24 @@ import (
// it will be passed through.
//
// The structure is modified in-place.
func Hash(raw interface{}) error {
fn := HashSHA1("")
func Hash(salter *salt.Salt, raw interface{}) error {
fn := salter.GetHMAC

switch s := raw.(type) {
case *logical.Auth:
if s == nil {
return nil
}
if s.ClientToken != "" {
token, err := fn(s.ClientToken)
if err != nil {
return err
}

token := fn(s.ClientToken)
s.ClientToken = token
}
case *logical.Request:
if s == nil {
return nil
}
if s.Auth != nil {
if err := Hash(s.Auth); err != nil {
if err := Hash(salter, s.Auth); err != nil {
return err
}
}
Expand All @@ -54,7 +48,7 @@ func Hash(raw interface{}) error {
return nil
}
if s.Auth != nil {
if err := Hash(s.Auth); err != nil {
if err := Hash(salter, s.Auth); err != nil {
return err
}
}
Expand Down Expand Up @@ -90,16 +84,18 @@ func HashStructure(s interface{}, cb HashCallback) (interface{}, error) {

// HashCallback is the callback called for HashStructure to hash
// a value.
type HashCallback func(string) (string, error)
type HashCallback func(string) string

// HashSHA1 returns a HashCallback that hashes data with SHA1 and
// with an optional salt. If salt is a blank string, no salt is used.
/*
func HashSHA1(salt string) HashCallback {
return func(v string) (string, error) {
hashed := sha1.Sum([]byte(v + salt))
return "sha1:" + hex.EncodeToString(hashed[:]), nil
}
}
*/

// hashWalker implements interfaces for the reflectwalk package
// (github.com/mitchellh/reflectwalk) that can be used to automatically
Expand Down Expand Up @@ -188,10 +184,7 @@ func (w *hashWalker) Primitive(v reflect.Value) error {
return nil
}

replaceVal, err := w.Callback(v.Interface().(string))
if err != nil {
return fmt.Errorf("Error hashing value: %s", err)
}
replaceVal := w.Callback(v.Interface().(string))

resultVal := reflect.ValueOf(replaceVal)
switch w.loc {
Expand Down
39 changes: 23 additions & 16 deletions builtin/audit/file/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,24 @@ import (
"sync"

"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/helper/salt"
"github.com/hashicorp/vault/logical"
"github.com/mitchellh/copystructure"
)

func Factory(conf map[string]string) (audit.Backend, error) {
path, ok := conf["path"]
func Factory(conf audit.BackendConfig) (audit.Backend, error) {
if conf.Salt == nil {
return nil, fmt.Errorf("Nil salt passed in")
}

path, ok := conf.Config["path"]
if !ok {
return nil, fmt.Errorf("path is required")
}

// Check if raw logging is enabled
logRaw := false
if raw, ok := conf["log_raw"]; ok {
if raw, ok := conf.Config["log_raw"]; ok {
b, err := strconv.ParseBool(raw)
if err != nil {
return nil, err
Expand All @@ -29,8 +34,9 @@ func Factory(conf map[string]string) (audit.Backend, error) {
}

b := &Backend{
Path: path,
LogRaw: logRaw,
path: path,
logRaw: logRaw,
salt: conf.Salt,
}

// Ensure that the file can be successfully opened for writing;
Expand All @@ -49,8 +55,9 @@ func Factory(conf map[string]string) (audit.Backend, error) {
// It doesn't do anything more at the moment to assist with rotation
// or reset the write cursor, this should be done in the future.
type Backend struct {
Path string
LogRaw bool
path string
logRaw bool
salt *salt.Salt

once sync.Once
f *os.File
Expand All @@ -60,7 +67,7 @@ func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr
if err := b.open(); err != nil {
return err
}
if !b.LogRaw {
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 {
Expand All @@ -86,10 +93,10 @@ func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr
req = cp.(*logical.Request)

// Hash any sensitive information
if err := audit.Hash(auth); err != nil {
if err := audit.Hash(b.salt, auth); err != nil {
return err
}
if err := audit.Hash(req); err != nil {
if err := audit.Hash(b.salt, req); err != nil {
return err
}
}
Expand All @@ -106,7 +113,7 @@ func (b *Backend) LogResponse(
if err := b.open(); err != nil {
return err
}
if !b.LogRaw {
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 {
Expand Down Expand Up @@ -138,13 +145,13 @@ func (b *Backend) LogResponse(
resp = cp.(*logical.Response)

// Hash any sensitive information
if err := audit.Hash(auth); err != nil {
if err := audit.Hash(b.salt, auth); err != nil {
return err
}
if err := audit.Hash(req); err != nil {
if err := audit.Hash(b.salt, req); err != nil {
return err
}
if err := audit.Hash(resp); err != nil {
if err := audit.Hash(b.salt, resp); err != nil {
return err
}
}
Expand All @@ -157,12 +164,12 @@ func (b *Backend) open() error {
if b.f != nil {
return nil
}
if err := os.MkdirAll(filepath.Dir(b.Path), 0600); err != nil {
if err := os.MkdirAll(filepath.Dir(b.path), 0600); err != nil {
return err
}

var err error
b.f, err = os.OpenFile(b.Path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
b.f, err = os.OpenFile(b.path, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
}
Expand Down
26 changes: 17 additions & 9 deletions builtin/audit/syslog/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,36 @@ package file

import (
"bytes"
"fmt"
"strconv"

"github.com/hashicorp/go-syslog"
"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/helper/salt"
"github.com/hashicorp/vault/logical"
"github.com/mitchellh/copystructure"
)

func Factory(conf map[string]string) (audit.Backend, error) {
func Factory(conf audit.BackendConfig) (audit.Backend, error) {
if conf.Salt == nil {
return nil, fmt.Errorf("Nil salt passed in")
}

// Get facility or default to AUTH
facility, ok := conf["facility"]
facility, ok := conf.Config["facility"]
if !ok {
facility = "AUTH"
}

// Get tag or default to 'vault'
tag, ok := conf["tag"]
tag, ok := conf.Config["tag"]
if !ok {
tag = "vault"
}

// Check if raw logging is enabled
logRaw := false
if raw, ok := conf["log_raw"]; ok {
if raw, ok := conf.Config["log_raw"]; ok {
b, err := strconv.ParseBool(raw)
if err != nil {
return nil, err
Expand All @@ -42,6 +48,7 @@ func Factory(conf map[string]string) (audit.Backend, error) {
b := &Backend{
logger: logger,
logRaw: logRaw,
salt: conf.Salt,
}
return b, nil
}
Expand All @@ -50,6 +57,7 @@ func Factory(conf map[string]string) (audit.Backend, error) {
type Backend struct {
logger gsyslog.Syslogger
logRaw bool
salt *salt.Salt
}

func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr error) error {
Expand Down Expand Up @@ -79,10 +87,10 @@ func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr
req = cp.(*logical.Request)

// Hash any sensitive information
if err := audit.Hash(auth); err != nil {
if err := audit.Hash(b.salt, auth); err != nil {
return err
}
if err := audit.Hash(req); err != nil {
if err := audit.Hash(b.salt, req); err != nil {
return err
}
}
Expand Down Expand Up @@ -133,13 +141,13 @@ func (b *Backend) LogResponse(auth *logical.Auth, req *logical.Request,
resp = cp.(*logical.Response)

// Hash any sensitive information
if err := audit.Hash(auth); err != nil {
if err := audit.Hash(b.salt, auth); err != nil {
return err
}
if err := audit.Hash(req); err != nil {
if err := audit.Hash(b.salt, req); err != nil {
return err
}
if err := audit.Hash(resp); err != nil {
if err := audit.Hash(b.salt, resp); err != nil {
return err
}
}
Expand Down
4 changes: 3 additions & 1 deletion builtin/credential/app-id/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) {

func Backend(conf *logical.BackendConfig) (*framework.Backend, error) {
// Initialize the salt
salt, err := salt.NewSalt(conf.StorageView, nil)
salt, err := salt.NewSalt(conf.StorageView, &salt.Config{
HashFunc: salt.SHA1Hash,
})
if err != nil {
return nil, err
}
Expand Down
4 changes: 3 additions & 1 deletion builtin/logical/ssh/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ func Factory(conf *logical.BackendConfig) (logical.Backend, error) {
}

func Backend(conf *logical.BackendConfig) (*framework.Backend, error) {
salt, err := salt.NewSalt(conf.StorageView, nil)
salt, err := salt.NewSalt(conf.StorageView, &salt.Config{
HashFunc: salt.SHA1Hash,
})
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit a4ca14c

Please sign in to comment.