Merge branch 'nbrownus-audit-logging'

This commit is contained in:
Armon Dadgar 2015-06-29 15:19:12 -07:00
commit c1ff26d186
20 changed files with 175 additions and 116 deletions

View File

@ -11,7 +11,7 @@ type Backend interface {
// request is authorized but before the request is executed. The arguments
// MUST not be modified in anyway. They should be deep copied if this is
// a possibility.
LogRequest(*logical.Auth, *logical.Request) error
LogRequest(*logical.Auth, *logical.Request, error) error
// LogResponse is used to syncronously log a response. This is done after
// the request is processed but before the response is sent. The arguments

View File

@ -5,24 +5,32 @@ import (
"io"
"github.com/hashicorp/vault/logical"
"errors"
)
// FormatJSON is a Formatter implementation that structuteres data into
// FormatJSON is a Formatter implementation that structures data into
// a JSON format.
type FormatJSON struct{}
func (f *FormatJSON) FormatRequest(
w io.Writer,
auth *logical.Auth, req *logical.Request) error {
auth *logical.Auth,
req *logical.Request,
err error) error {
// If auth is nil, make an empty one
if auth == nil {
auth = new(logical.Auth)
}
if err == nil {
err = errors.New("")
}
// Encode!
enc := json.NewEncoder(w)
return enc.Encode(&JSONRequestEntry{
Type: "request",
Error: err.Error(),
Auth: JSONAuth{
DisplayName: auth.DisplayName,
@ -31,9 +39,10 @@ func (f *FormatJSON) FormatRequest(
},
Request: JSONRequest{
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
RemoteAddr: req.Connection.RemoteAddr,
},
})
}
@ -51,10 +60,13 @@ func (f *FormatJSON) FormatResponse(
if resp == nil {
resp = new(logical.Response)
}
if err == nil {
err = errors.New("")
}
var respAuth JSONAuth
var respAuth *JSONAuth
if resp.Auth != nil {
respAuth = JSONAuth{
respAuth = &JSONAuth{
ClientToken: resp.Auth.ClientToken,
DisplayName: resp.Auth.DisplayName,
Policies: resp.Auth.Policies,
@ -62,9 +74,9 @@ func (f *FormatJSON) FormatResponse(
}
}
var respSecret JSONSecret
var respSecret *JSONSecret
if resp.Secret != nil {
respSecret = JSONSecret{
respSecret = &JSONSecret{
LeaseID: resp.Secret.LeaseID,
}
}
@ -73,6 +85,7 @@ func (f *FormatJSON) FormatResponse(
enc := json.NewEncoder(w)
return enc.Encode(&JSONResponseEntry{
Type: "response",
Error: err.Error(),
Auth: JSONAuth{
Policies: auth.Policies,
@ -80,9 +93,10 @@ func (f *FormatJSON) FormatResponse(
},
Request: JSONRequest{
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
Operation: req.Operation,
Path: req.Path,
Data: req.Data,
RemoteAddr: req.Connection.RemoteAddr,
},
Response: JSONResponse{
@ -99,6 +113,7 @@ type JSONRequestEntry struct {
Type string `json:"type"`
Auth JSONAuth `json:"auth"`
Request JSONRequest `json:"request"`
Error string `json:"error"`
}
// JSONResponseEntry is the structure of a response audit log entry in JSON.
@ -111,14 +126,15 @@ type JSONResponseEntry struct {
}
type JSONRequest struct {
Operation logical.Operation `json:"operation"`
Path string `json:"path"`
Data map[string]interface{} `json:"data"`
Operation logical.Operation `json:"operation"`
Path string `json:"path"`
Data map[string]interface{} `json:"data"`
RemoteAddr string `json:"remote_address"`
}
type JSONResponse struct {
Auth JSONAuth `json:"auth,omitempty"`
Secret JSONSecret `json:"secret,emitempty"`
Auth *JSONAuth `json:"auth,omitempty"`
Secret *JSONSecret `json:"secret,emitempty"`
Data map[string]interface{} `json:"data"`
Redirect string `json:"redirect"`
}

View File

@ -5,12 +5,14 @@ import (
"testing"
"github.com/hashicorp/vault/logical"
"errors"
)
func TestFormatJSON_formatRequest(t *testing.T) {
cases := map[string]struct {
Auth *logical.Auth
Req *logical.Request
Err error
Result string
}{
"auth, request": {
@ -18,7 +20,11 @@ func TestFormatJSON_formatRequest(t *testing.T) {
&logical.Request{
Operation: logical.WriteOperation,
Path: "/foo",
Connection: &logical.Connection{
RemoteAddr: "127.0.0.1",
},
},
errors.New("this is an error"),
testFormatJSONReqBasicStr,
},
}
@ -26,7 +32,7 @@ func TestFormatJSON_formatRequest(t *testing.T) {
for name, tc := range cases {
var buf bytes.Buffer
var format FormatJSON
if err := format.FormatRequest(&buf, tc.Auth, tc.Req); err != nil {
if err := format.FormatRequest(&buf, tc.Auth, tc.Req, tc.Err); err != nil {
t.Fatalf("bad: %s\nerr: %s", name, err)
}
@ -38,5 +44,5 @@ func TestFormatJSON_formatRequest(t *testing.T) {
}
}
const testFormatJSONReqBasicStr = `{"type":"request","auth":{"display_name":"","policies":["root"],"metadata":null},"request":{"operation":"write","path":"/foo","data":null}}
const testFormatJSONReqBasicStr = `{"type":"request","auth":{"display_name":"","policies":["root"],"metadata":null},"request":{"operation":"write","path":"/foo","data":null,"remote_address":"127.0.0.1"},"error":"this is an error"}
`

View File

@ -12,6 +12,6 @@ import (
//
// It is recommended that you pass data through Hash prior to formatting it.
type Formatter interface {
FormatRequest(io.Writer, *logical.Auth, *logical.Request) error
FormatRequest(io.Writer, *logical.Auth, *logical.Request, error) error
FormatResponse(io.Writer, *logical.Auth, *logical.Request, *logical.Response, error) error
}

View File

@ -48,7 +48,7 @@ type Backend struct {
f *os.File
}
func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request) error {
func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr error) error {
if err := b.open(); err != nil {
return err
}
@ -76,7 +76,7 @@ func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request) error {
}
var format audit.FormatJSON
return format.FormatRequest(b.f, auth, req)
return format.FormatRequest(b.f, auth, req, outerErr)
}
func (b *Backend) LogResponse(

View File

@ -52,7 +52,7 @@ type Backend struct {
logRaw bool
}
func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request) error {
func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request, outerErr error) error {
if !b.logRaw {
// Copy the structures
cp, err := copystructure.Copy(auth)
@ -79,7 +79,7 @@ func (b *Backend) LogRequest(auth *logical.Auth, req *logical.Request) error {
// Encode the entry as JSON
var buf bytes.Buffer
var format audit.FormatJSON
if err := format.FormatRequest(&buf, auth, req); err != nil {
if err := format.FormatRequest(&buf, auth, req, outerErr); err != nil {
return err
}

View File

@ -28,8 +28,9 @@ func handleHelp(core *vault.Core, w http.ResponseWriter, req *http.Request) {
}
resp, err := core.HandleRequest(requestAuth(req, &logical.Request{
Operation: logical.HelpOperation,
Path: path,
Operation: logical.HelpOperation,
Path: path,
Connection: getConnection(req),
}))
if err != nil {
respondError(w, http.StatusInternalServerError, err)

View File

@ -54,13 +54,6 @@ func handleLogical(core *vault.Core) http.Handler {
}
}
// http.Server will set RemoteAddr to an "IP:port" string
var remoteAddr string
remoteAddr, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
remoteAddr = ""
}
// Make the internal request. We attach the connection info
// as well in case this is an authentication request that requires
// it. Vault core handles stripping this if we need to.
@ -68,10 +61,7 @@ func handleLogical(core *vault.Core) http.Handler {
Operation: op,
Path: path,
Data: req,
Connection: &logical.Connection{
RemoteAddr: remoteAddr,
ConnState: r.TLS,
},
Connection: getConnection(r),
}))
if !ok {
return
@ -198,6 +188,22 @@ func respondRaw(w http.ResponseWriter, r *http.Request, path string, resp *logic
w.Write(body)
}
func getConnection(r *http.Request) (connection *logical.Connection) {
var remoteAddr string
remoteAddr, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
remoteAddr = ""
}
connection = &logical.Connection{
RemoteAddr: remoteAddr,
ConnState: r.TLS,
}
return
}
type LogicalResponse struct {
LeaseID string `json:"lease_id"`
Renewable bool `json:"renewable"`

View File

@ -16,8 +16,9 @@ func handleSysListAudit(core *vault.Core) http.Handler {
}
resp, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.ReadOperation,
Path: "sys/audit",
Operation: logical.ReadOperation,
Path: "sys/audit",
Connection: getConnection(r),
}))
if !ok {
return
@ -57,8 +58,9 @@ func handleSysDisableAudit(core *vault.Core, w http.ResponseWriter, r *http.Requ
}
_, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.DeleteOperation,
Path: "sys/audit/" + path,
Operation: logical.DeleteOperation,
Path: "sys/audit/" + path,
Connection: getConnection(r),
}))
if !ok {
return
@ -74,6 +76,7 @@ func handleSysEnableAudit(core *vault.Core, w http.ResponseWriter, r *http.Reque
respondError(w, http.StatusNotFound, nil)
return
}
path := r.URL.Path[len(prefix):]
if path == "" {
respondError(w, http.StatusNotFound, nil)
@ -88,8 +91,9 @@ func handleSysEnableAudit(core *vault.Core, w http.ResponseWriter, r *http.Reque
}
_, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/audit/" + path,
Operation: logical.WriteOperation,
Path: "sys/audit/" + path,
Connection: getConnection(r),
Data: map[string]interface{}{
"type": req.Type,
"description": req.Description,

View File

@ -30,8 +30,9 @@ func handleSysListAuth(core *vault.Core) http.Handler {
}
resp, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.ReadOperation,
Path: "sys/auth",
Operation: logical.ReadOperation,
Path: "sys/auth",
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusInternalServerError, err)
@ -78,8 +79,9 @@ func handleSysEnableAuth(
}
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/auth/" + path,
Operation: logical.WriteOperation,
Path: "sys/auth/" + path,
Connection: getConnection(r),
Data: map[string]interface{}{
"type": req.Type,
"description": req.Description,
@ -99,8 +101,9 @@ func handleSysDisableAuth(
r *http.Request,
path string) {
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.DeleteOperation,
Path: "sys/auth/" + path,
Operation: logical.DeleteOperation,
Path: "sys/auth/" + path,
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusInternalServerError, err)

View File

@ -38,8 +38,9 @@ func handleSysRenew(core *vault.Core) http.Handler {
}
resp, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/renew/" + path,
Operation: logical.WriteOperation,
Path: "sys/renew/" + path,
Connection: getConnection(r),
Data: map[string]interface{}{
"increment": req.Increment,
},
@ -72,8 +73,9 @@ func handleSysRevoke(core *vault.Core) http.Handler {
}
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/revoke/" + path,
Operation: logical.WriteOperation,
Path: "sys/revoke/" + path,
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusBadRequest, err)
@ -104,8 +106,9 @@ func handleSysRevokePrefix(core *vault.Core) http.Handler {
}
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/revoke-prefix/" + path,
Operation: logical.WriteOperation,
Path: "sys/revoke-prefix/" + path,
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusBadRequest, err)

View File

@ -41,8 +41,9 @@ func handleSysRemount(core *vault.Core) http.Handler {
}
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/remount",
Operation: logical.WriteOperation,
Path: "sys/remount",
Connection: getConnection(r),
Data: map[string]interface{}{
"from": req.From,
"to": req.To,
@ -65,8 +66,9 @@ func handleSysListMounts(core *vault.Core) http.Handler {
}
resp, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.ReadOperation,
Path: "sys/mounts",
Operation: logical.ReadOperation,
Path: "sys/mounts",
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusInternalServerError, err)
@ -121,8 +123,9 @@ func handleSysMount(
}
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/mounts/" + path,
Operation: logical.WriteOperation,
Path: "sys/mounts/" + path,
Connection: getConnection(r),
Data: map[string]interface{}{
"type": req.Type,
"description": req.Description,
@ -142,8 +145,9 @@ func handleSysUnmount(
r *http.Request,
path string) {
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.DeleteOperation,
Path: "sys/mounts/" + path,
Operation: logical.DeleteOperation,
Path: "sys/mounts/" + path,
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusInternalServerError, err)

View File

@ -16,8 +16,9 @@ func handleSysListPolicies(core *vault.Core) http.Handler {
}
resp, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.ReadOperation,
Path: "sys/policy",
Operation: logical.ReadOperation,
Path: "sys/policy",
Connection: getConnection(r),
}))
if !ok {
return
@ -65,8 +66,9 @@ func handleSysDeletePolicy(core *vault.Core, w http.ResponseWriter, r *http.Requ
}
_, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.DeleteOperation,
Path: "sys/policy/" + path,
Operation: logical.DeleteOperation,
Path: "sys/policy/" + path,
Connection: getConnection(r),
}))
if !ok {
return
@ -89,8 +91,9 @@ func handleSysReadPolicy(core *vault.Core, w http.ResponseWriter, r *http.Reques
}
resp, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.ReadOperation,
Path: "sys/policy/" + path,
Operation: logical.ReadOperation,
Path: "sys/policy/" + path,
Connection: getConnection(r),
}))
if !ok {
return
@ -124,8 +127,9 @@ func handleSysWritePolicy(core *vault.Core, w http.ResponseWriter, r *http.Reque
}
_, ok := request(core, w, r, requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/policy/" + path,
Operation: logical.WriteOperation,
Path: "sys/policy/" + path,
Connection: getConnection(r),
Data: map[string]interface{}{
"rules": req.Rules,
},

View File

@ -15,8 +15,9 @@ func handleSysKeyStatus(core *vault.Core) http.Handler {
}
resp, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.ReadOperation,
Path: "sys/key-status",
Operation: logical.ReadOperation,
Path: "sys/key-status",
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusInternalServerError, err)
@ -37,8 +38,9 @@ func handleSysRotate(core *vault.Core) http.Handler {
}
_, err := core.HandleRequest(requestAuth(r, &logical.Request{
Operation: logical.WriteOperation,
Path: "sys/rotate",
Operation: logical.WriteOperation,
Path: "sys/rotate",
Connection: getConnection(r),
}))
if err != nil {
respondError(w, http.StatusInternalServerError, err)

View File

@ -261,7 +261,7 @@ func (a *AuditBroker) IsRegistered(name string) bool {
// LogRequest is used to ensure all the audit backends have an opportunity to
// log the given request and that *at least one* succeeds.
func (a *AuditBroker) LogRequest(auth *logical.Auth, req *logical.Request) (reterr error) {
func (a *AuditBroker) LogRequest(auth *logical.Auth, req *logical.Request, outerErr error) (reterr error) {
defer metrics.MeasureSince([]string{"audit", "log_request"}, time.Now())
a.l.RLock()
defer a.l.RUnlock()
@ -276,7 +276,7 @@ func (a *AuditBroker) LogRequest(auth *logical.Auth, req *logical.Request) (rete
anyLogged := false
for name, be := range a.backends {
start := time.Now()
err := be.backend.LogRequest(auth, req)
err := be.backend.LogRequest(auth, req, outerErr)
metrics.MeasureSince([]string{"audit", name, "log_request"}, start)
if err != nil {
a.logger.Printf("[ERR] audit: backend '%s' failed to log request: %v", name, err)

View File

@ -10,12 +10,14 @@ import (
"github.com/hashicorp/vault/audit"
"github.com/hashicorp/vault/logical"
"errors"
)
type NoopAudit struct {
ReqErr error
ReqAuth []*logical.Auth
Req []*logical.Request
ReqErrs []error
RespErr error
RespAuth []*logical.Auth
@ -24,9 +26,10 @@ type NoopAudit struct {
RespErrs []error
}
func (n *NoopAudit) LogRequest(a *logical.Auth, r *logical.Request) error {
func (n *NoopAudit) LogRequest(a *logical.Auth, r *logical.Request, err error) error {
n.ReqAuth = append(n.ReqAuth, a)
n.Req = append(n.Req, r)
n.ReqErrs = append(n.ReqErrs, err)
return n.ReqErr
}
@ -203,8 +206,9 @@ func TestAuditBroker_LogRequest(t *testing.T) {
Operation: logical.ReadOperation,
Path: "sys/mounts",
}
reqErrs := errors.New("errs")
err := b.LogRequest(auth, req)
err := b.LogRequest(auth, req, reqErrs)
if err != nil {
t.Fatalf("err: %v", err)
}
@ -216,17 +220,20 @@ func TestAuditBroker_LogRequest(t *testing.T) {
if !reflect.DeepEqual(a.Req[0], req) {
t.Fatalf("Bad: %#v", a.Req[0])
}
if !reflect.DeepEqual(a.ReqErrs[0], reqErrs) {
t.Fatalf("Bad: %#v", a.ReqErrs[0])
}
}
// Should still work with one failing backend
a1.ReqErr = fmt.Errorf("failed")
if err := b.LogRequest(auth, req); err != nil {
if err := b.LogRequest(auth, req, nil); err != nil {
t.Fatalf("err: %v", err)
}
// Should FAIL work with both failing backends
a2.ReqErr = fmt.Errorf("failed")
if err := b.LogRequest(auth, req); err.Error() != "no audit backend succeeded in logging the request" {
if err := b.LogRequest(auth, req, nil); err.Error() != "no audit backend succeeded in logging the request" {
t.Fatalf("err: %v", err)
}
}

View File

@ -354,10 +354,12 @@ func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err
return nil, ErrStandby
}
var auth *logical.Auth
if c.router.LoginPath(req.Path) {
resp, err = c.handleLoginRequest(req)
resp, auth, err = c.handleLoginRequest(req)
} else {
resp, err = c.handleRequest(req)
resp, auth, err = c.handleRequest(req)
}
// Ensure we don't leak internal data
@ -369,11 +371,20 @@ func (c *Core) HandleRequest(req *logical.Request) (resp *logical.Response, err
resp.Auth.InternalData = nil
}
}
// Create an audit trail of the response
if err := c.auditBroker.LogResponse(auth, req, resp, err); err != nil {
c.logger.Printf("[ERR] core: failed to audit response (request: %#v, response: %#v): %v",
req, resp, err)
return nil, ErrInternalError
}
return
}
func (c *Core) handleRequest(req *logical.Request) (*logical.Response, error) {
func (c *Core) handleRequest(req *logical.Request) (*logical.Response, *logical.Auth, error) {
defer metrics.MeasureSince([]string{"core", "handle_request"}, time.Now())
// Validate the token
auth, err := c.checkToken(req.Operation, req.Path, req.ClientToken)
if err != nil {
@ -387,17 +398,22 @@ func (c *Core) handleRequest(req *logical.Request) (*logical.Response, error) {
errType = logical.ErrInvalidRequest
}
return logical.ErrorResponse(err.Error()), errType
if err := c.auditBroker.LogRequest(auth, req, err); err != nil {
c.logger.Printf("[ERR] core: failed to audit request (%#v): %v",
req, err)
}
return logical.ErrorResponse(err.Error()), nil, errType
}
// Attach the display name
req.DisplayName = auth.DisplayName
// Create an audit trail of the request
if err := c.auditBroker.LogRequest(auth, req); err != nil {
if err := c.auditBroker.LogRequest(auth, req, errors.New("")); err != nil {
c.logger.Printf("[ERR] core: failed to audit request (%#v): %v",
req, err)
return nil, ErrInternalError
return nil, auth, ErrInternalError
}
// Route the request
@ -422,7 +438,7 @@ func (c *Core) handleRequest(req *logical.Request) (*logical.Response, error) {
c.logger.Printf(
"[ERR] core: failed to register lease "+
"(request: %#v, response: %#v): %v", req, resp, err)
return nil, ErrInternalError
return nil, auth, ErrInternalError
}
resp.Secret.LeaseID = leaseID
}
@ -435,7 +451,7 @@ func (c *Core) handleRequest(req *logical.Request) (*logical.Response, error) {
c.logger.Printf(
"[ERR] core: unexpected Auth response for non-token backend "+
"(request: %#v, response: %#v)", req, resp)
return nil, ErrInternalError
return nil, auth, ErrInternalError
}
// Set the default lease if non-provided, root tokens are exempt
@ -452,31 +468,24 @@ func (c *Core) handleRequest(req *logical.Request) (*logical.Response, error) {
if err := c.expiration.RegisterAuth(req.Path, resp.Auth); err != nil {
c.logger.Printf("[ERR] core: failed to register token lease "+
"(request: %#v, response: %#v): %v", req, resp, err)
return nil, ErrInternalError
return nil, auth, ErrInternalError
}
}
// Create an audit trail of the response
if err := c.auditBroker.LogResponse(auth, req, resp, err); err != nil {
c.logger.Printf("[ERR] core: failed to audit response (request: %#v, response: %#v): %v",
req, resp, err)
return nil, ErrInternalError
}
// Return the response and error
return resp, err
return resp, auth, err
}
// handleLoginRequest is used to handle a login request, which is an
// unauthenticated request to the backend.
func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, error) {
func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, *logical.Auth, error) {
defer metrics.MeasureSince([]string{"core", "handle_login_request"}, time.Now())
// Create an audit trail of the request, auth is not available on login requests
if err := c.auditBroker.LogRequest(nil, req); err != nil {
if err := c.auditBroker.LogRequest(nil, req, errors.New("")); err != nil {
c.logger.Printf("[ERR] core: failed to audit request (%#v): %v",
req, err)
return nil, ErrInternalError
return nil, nil, ErrInternalError
}
// Route the request
@ -486,7 +495,7 @@ func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, erro
if resp != nil && resp.Secret != nil {
c.logger.Printf("[ERR] core: unexpected Secret response for login path"+
"(request: %#v, response: %#v)", req, resp)
return nil, ErrInternalError
return nil, nil, ErrInternalError
}
// If the response generated an authentication, then generate the token
@ -511,7 +520,7 @@ func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, erro
}
if err := c.tokenStore.Create(&te); err != nil {
c.logger.Printf("[ERR] core: failed to create token: %v", err)
return nil, ErrInternalError
return nil, auth, ErrInternalError
}
// Populate the client token
@ -531,21 +540,14 @@ func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, erro
if err := c.expiration.RegisterAuth(req.Path, auth); err != nil {
c.logger.Printf("[ERR] core: failed to register token lease "+
"(request: %#v, response: %#v): %v", req, resp, err)
return nil, ErrInternalError
return nil, auth, ErrInternalError
}
// Attach the display name, might be used by audit backends
req.DisplayName = auth.DisplayName
}
// Create an audit trail of the response
if err := c.auditBroker.LogResponse(auth, req, resp, err); err != nil {
c.logger.Printf("[ERR] core: failed to audit response (request: %#v, response: %#v): %v",
req, resp, err)
return nil, ErrInternalError
}
return resp, err
return resp, auth, err
}
func (c *Core) checkToken(

View File

@ -140,6 +140,7 @@ func (m *RollbackManager) attemptRollback(path string, rs *rollbackState) (err e
req := &logical.Request{
Operation: logical.RollbackOperation,
Path: path,
Connection: &logical.Connection{},
}
_, err = m.router.Route(req)

View File

@ -86,7 +86,7 @@ func TestKeyCopy(key []byte) []byte {
type noopAudit struct{}
func (n *noopAudit) LogRequest(a *logical.Auth, r *logical.Request) error {
func (n *noopAudit) LogRequest(a *logical.Auth, r *logical.Request, e error) error {
return nil
}

View File

@ -656,13 +656,13 @@ func (ts *TokenStore) handleLookup(
// Lookup the token
out, err := ts.Lookup(id)
if err != nil {
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
}
// Fast-path the not found case
if out == nil {
return nil, nil
return logical.ErrorResponse("bad token"), logical.ErrPermissionDenied
}
// Generate a response. We purposely omit the parent reference otherwise