vault: Adding ACL enforcement

This commit is contained in:
Armon Dadgar 2015-03-24 11:37:07 -07:00
parent 43a99aec93
commit 20c2375352
4 changed files with 64 additions and 17 deletions

View File

@ -208,7 +208,39 @@ func (c *Core) HandleRequest(req *logical.Request) (*logical.Response, error) {
return nil, ErrSealed
}
// TODO: Enforce ACLs
// Ensure there is a client token
if req.ClientToken == "" {
return logical.ErrorResponse("missing client token"), logical.ErrInvalidRequest
}
// Resolve the token policy
te, err := c.tokenStore.Lookup(req.ClientToken)
if err != nil {
c.logger.Printf("[ERR] core: failed to lookup token: %v", err)
return nil, ErrInternalError
}
// Ensure the token is valid
if te == nil {
return logical.ErrorResponse("invalid client token"), logical.ErrInvalidRequest
}
// Construct the corresponding ACL object
acl, err := c.policy.ACL(te.Policies...)
if err != nil {
c.logger.Printf("[ERR] core: failed to construct ACL: %v", err)
return nil, ErrInternalError
}
// Check if this is a root protected path
if c.router.RootPath(req.Path) && !acl.RootPrivilege(req.Path) {
return nil, logical.ErrPermissionDenied
}
// Check the standard non-root ACLs
if !acl.AllowOperation(req.Operation, req.Path) {
return nil, logical.ErrPermissionDenied
}
// Route the request
resp, err := c.router.Route(req)

View File

@ -304,6 +304,7 @@ func TestCore_Route_Sealed(t *testing.T) {
}
// Should not error after unseal
req.ClientToken = res.RootToken
_, err = c.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
@ -323,7 +324,7 @@ func TestCore_SealUnseal(t *testing.T) {
// Ensure we get a VaultID
func TestCore_HandleRequest_Lease(t *testing.T) {
c, _ := TestCoreUnsealed(t)
c, _, root := TestCoreUnsealedToken(t)
req := &logical.Request{
Operation: logical.WriteOperation,
@ -332,6 +333,7 @@ func TestCore_HandleRequest_Lease(t *testing.T) {
"foo": "bar",
"lease": "1h",
},
ClientToken: root,
}
resp, err := c.HandleRequest(req)
if err != nil {
@ -377,7 +379,7 @@ func TestCore_HandleLogin_Token(t *testing.T) {
},
},
}
c, _ := TestCoreUnsealed(t)
c, _, root := TestCoreUnsealedToken(t)
c.credentialBackends["noop"] = func(map[string]string) (credential.Backend, error) {
return noop, nil
}
@ -385,6 +387,7 @@ func TestCore_HandleLogin_Token(t *testing.T) {
// Enable the credential backend
req := logical.TestRequest(t, logical.WriteOperation, "sys/auth/foo")
req.Data["type"] = "noop"
req.ClientToken = root
_, err := c.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)

View File

@ -149,12 +149,13 @@ func TestSystemBackend_remount_system(t *testing.T) {
}
func TestSystemBackend_renew(t *testing.T) {
core, b := testCoreSystemBackend(t)
core, b, root := testCoreSystemBackend(t)
// Create a key with a lease
req := logical.TestRequest(t, logical.WriteOperation, "secret/foo")
req.Data["foo"] = "bar"
req.Data["lease"] = "1h"
req.ClientToken = root
resp, err := core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
@ -165,6 +166,7 @@ func TestSystemBackend_renew(t *testing.T) {
// Read a key with a VaultID
req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
req.ClientToken = root
resp, err = core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
@ -204,12 +206,13 @@ func TestSystemBackend_renew_invalidID(t *testing.T) {
}
func TestSystemBackend_revoke(t *testing.T) {
core, b := testCoreSystemBackend(t)
core, b, root := testCoreSystemBackend(t)
// Create a key with a lease
req := logical.TestRequest(t, logical.WriteOperation, "secret/foo")
req.Data["foo"] = "bar"
req.Data["lease"] = "1h"
req.ClientToken = root
resp, err := core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
@ -220,6 +223,7 @@ func TestSystemBackend_revoke(t *testing.T) {
// Read a key with a VaultID
req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
req.ClientToken = root
resp, err = core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
@ -264,12 +268,13 @@ func TestSystemBackend_revoke_invalidID(t *testing.T) {
}
func TestSystemBackend_revokePrefix(t *testing.T) {
core, b := testCoreSystemBackend(t)
core, b, root := testCoreSystemBackend(t)
// Create a key with a lease
req := logical.TestRequest(t, logical.WriteOperation, "secret/foo")
req.Data["foo"] = "bar"
req.Data["lease"] = "1h"
req.ClientToken = root
resp, err := core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
@ -280,6 +285,7 @@ func TestSystemBackend_revokePrefix(t *testing.T) {
// Read a key with a VaultID
req = logical.TestRequest(t, logical.ReadOperation, "secret/foo")
req.ClientToken = root
resp, err = core.HandleRequest(req)
if err != nil {
t.Fatalf("err: %v", err)
@ -329,7 +335,7 @@ func TestSystemBackend_authTable(t *testing.T) {
}
func TestSystemBackend_enableAuth(t *testing.T) {
c, b := testCoreSystemBackend(t)
c, b, _ := testCoreSystemBackend(t)
c.credentialBackends["noop"] = func(map[string]string) (credential.Backend, error) {
return &NoopCred{}, nil
}
@ -360,7 +366,7 @@ func TestSystemBackend_enableAuth_invalid(t *testing.T) {
}
func TestSystemBackend_disableAuth(t *testing.T) {
c, b := testCoreSystemBackend(t)
c, b, _ := testCoreSystemBackend(t)
c.credentialBackends["noop"] = func(map[string]string) (credential.Backend, error) {
return &NoopCred{}, nil
}
@ -494,7 +500,7 @@ func testSystemBackend(t *testing.T) logical.Backend {
return NewSystemBackend(c)
}
func testCoreSystemBackend(t *testing.T) (*Core, logical.Backend) {
c, _ := TestCoreUnsealed(t)
return c, NewSystemBackend(c)
func testCoreSystemBackend(t *testing.T) (*Core, logical.Backend, string) {
c, _, root := TestCoreUnsealedToken(t)
return c, NewSystemBackend(c), root
}

View File

@ -23,8 +23,8 @@ func TestCore(t *testing.T) *Core {
}
// TestCoreInit initializes the core with a single key, and returns
// the list of keys that must be used to unseal the core.
func TestCoreInit(t *testing.T, core *Core) []byte {
// the key that must be used to unseal the core and a root token.
func TestCoreInit(t *testing.T, core *Core) ([]byte, string) {
result, err := core.Initialize(&SealConfig{
SecretShares: 1,
SecretThreshold: 1,
@ -32,15 +32,21 @@ func TestCoreInit(t *testing.T, core *Core) []byte {
if err != nil {
t.Fatalf("err: %s", err)
}
return result.SecretShares[0]
return result.SecretShares[0], result.RootToken
}
// TestCoreUnsealed returns a pure in-memory core that is already
// initialized and unsealed.
func TestCoreUnsealed(t *testing.T) (*Core, []byte) {
core, key, _ := TestCoreUnsealedToken(t)
return core, key
}
// TestCoreUnsealedToken returns a pure in-memory core that is already
// initialized and unsealed along with the root token.
func TestCoreUnsealedToken(t *testing.T) (*Core, []byte, string) {
core := TestCore(t)
key := TestCoreInit(t, core)
key, token := TestCoreInit(t, core)
if _, err := core.Unseal(TestKeyCopy(key)); err != nil {
t.Fatalf("unseal err: %s", err)
}
@ -53,7 +59,7 @@ func TestCoreUnsealed(t *testing.T) (*Core, []byte) {
t.Fatal("should not be sealed")
}
return core, key
return core, key, token
}
// TestKeyCopy is a silly little function to just copy the key so that