vault: require root token for seal
This commit is contained in:
parent
04c80a81bc
commit
0666bda865
|
@ -47,10 +47,10 @@ func TestSysSealStatus_uninit(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSysSeal(t *testing.T) {
|
||||
core := vault.TestCore(t)
|
||||
vault.TestCoreInit(t, core)
|
||||
core, _, token := vault.TestCoreUnsealed(t)
|
||||
ln, addr := TestServer(t, core)
|
||||
defer ln.Close()
|
||||
TestServerAuth(t, addr, token)
|
||||
|
||||
resp := testHttpPut(t, addr+"/v1/sys/seal", nil)
|
||||
testResponseStatus(t, resp, 204)
|
||||
|
|
|
@ -225,38 +225,21 @@ func (c *Core) HandleRequest(req *logical.Request) (*logical.Response, error) {
|
|||
}
|
||||
|
||||
func (c *Core) handleRequest(req *logical.Request) (*logical.Response, error) {
|
||||
// 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)
|
||||
// Validate the token
|
||||
err := c.checkToken(
|
||||
req.Operation, req.Path, req.ClientToken, c.router.RootPath(req.Path))
|
||||
if err != nil {
|
||||
c.logger.Printf("[ERR] core: failed to lookup token: %v", err)
|
||||
return nil, ErrInternalError
|
||||
}
|
||||
// If it is an internal error we return that, otherwise we
|
||||
// return invalid request so that the status codes can be correct
|
||||
errType := logical.ErrInvalidRequest
|
||||
switch err {
|
||||
case ErrInternalError:
|
||||
fallthrough
|
||||
case logical.ErrPermissionDenied:
|
||||
errType = err
|
||||
}
|
||||
|
||||
// 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
|
||||
return logical.ErrorResponse(err.Error()), errType
|
||||
}
|
||||
|
||||
// Route the request
|
||||
|
@ -321,6 +304,45 @@ func (c *Core) handleLoginRequest(req *logical.Request) (*logical.Response, erro
|
|||
return resp, err
|
||||
}
|
||||
|
||||
func (c *Core) checkToken(
|
||||
op logical.Operation, path string, token string, root bool) error {
|
||||
// Ensure there is a client token
|
||||
if token == "" {
|
||||
return fmt.Errorf("missing client token")
|
||||
}
|
||||
|
||||
// Resolve the token policy
|
||||
te, err := c.tokenStore.Lookup(token)
|
||||
if err != nil {
|
||||
c.logger.Printf("[ERR] core: failed to lookup token: %v", err)
|
||||
return ErrInternalError
|
||||
}
|
||||
|
||||
// Ensure the token is valid
|
||||
if te == nil {
|
||||
return fmt.Errorf("invalid client token")
|
||||
}
|
||||
|
||||
// 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 ErrInternalError
|
||||
}
|
||||
|
||||
// Check if this is a root protected path
|
||||
if root && !acl.RootPrivilege(path) {
|
||||
return logical.ErrPermissionDenied
|
||||
}
|
||||
|
||||
// Check the standard non-root ACLs
|
||||
if !acl.AllowOperation(op, path) {
|
||||
return logical.ErrPermissionDenied
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Initialized checks if the Vault is already initialized
|
||||
func (c *Core) Initialized() (bool, error) {
|
||||
// Check the barrier first
|
||||
|
@ -586,12 +608,23 @@ func (c *Core) Unseal(key []byte) (bool, error) {
|
|||
|
||||
// Seal is used to re-seal the Vault. This requires the Vault to
|
||||
// be unsealed again to perform any further operations.
|
||||
func (c *Core) Seal() error {
|
||||
func (c *Core) Seal(token string) error {
|
||||
c.stateLock.Lock()
|
||||
defer c.stateLock.Unlock()
|
||||
if c.sealed {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate the token is a root token
|
||||
err := c.checkToken(
|
||||
logical.WriteOperation,
|
||||
"sys/seal",
|
||||
token,
|
||||
true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.sealed = true
|
||||
|
||||
// Do pre-seal teardown
|
||||
|
|
|
@ -202,13 +202,13 @@ func TestCore_Unseal_MultiShare(t *testing.T) {
|
|||
t.Fatalf("should not be sealed")
|
||||
}
|
||||
|
||||
err = c.Seal()
|
||||
err = c.Seal(res.RootToken)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Ignore redundant
|
||||
err = c.Seal()
|
||||
err = c.Seal(res.RootToken)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
@ -312,8 +312,8 @@ func TestCore_Route_Sealed(t *testing.T) {
|
|||
|
||||
// Attempt to unseal after doing a first seal
|
||||
func TestCore_SealUnseal(t *testing.T) {
|
||||
c, key, _ := TestCoreUnsealed(t)
|
||||
if err := c.Seal(); err != nil {
|
||||
c, key, root := TestCoreUnsealed(t)
|
||||
if err := c.Seal(root); err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if unseal, err := c.Unseal(key); err != nil || !unseal {
|
||||
|
@ -416,10 +416,7 @@ func TestCore_HandleRequest_RootPath(t *testing.T) {
|
|||
}
|
||||
resp, err := c.HandleRequest(req)
|
||||
if err != logical.ErrPermissionDenied {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if resp != nil {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
t.Fatalf("err: %v, resp: %v", err, resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -476,10 +473,7 @@ func TestCore_HandleRequest_PermissionDenied(t *testing.T) {
|
|||
}
|
||||
resp, err := c.HandleRequest(req)
|
||||
if err != logical.ErrPermissionDenied {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if resp != nil {
|
||||
t.Fatalf("bad: %#v", resp)
|
||||
t.Fatalf("err: %v, resp: %v", err, resp)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ func NewSystemBackend(core *Core) logical.Backend {
|
|||
"revoke-prefix/*",
|
||||
"policy",
|
||||
"policy/*",
|
||||
"seal",
|
||||
},
|
||||
},
|
||||
|
||||
|
@ -216,17 +215,6 @@ func NewSystemBackend(core *Core) logical.Backend {
|
|||
HelpSynopsis: strings.TrimSpace(sysHelp["policy"][0]),
|
||||
HelpDescription: strings.TrimSpace(sysHelp["policy"][1]),
|
||||
},
|
||||
|
||||
&framework.Path{
|
||||
Pattern: "seal$",
|
||||
|
||||
Callbacks: map[logical.Operation]framework.OperationFunc{
|
||||
logical.WriteOperation: b.handleSeal,
|
||||
},
|
||||
|
||||
HelpSynopsis: strings.TrimSpace(sysHelp["seal"][0]),
|
||||
HelpDescription: strings.TrimSpace(sysHelp["seal"][1]),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -238,17 +226,6 @@ type SystemBackend struct {
|
|||
Core *Core
|
||||
}
|
||||
|
||||
// handleSeal is used to mount a new path
|
||||
func (b *SystemBackend) handleSeal(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
// Attempt seal
|
||||
if err := b.Core.Seal(); err != nil {
|
||||
return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// handleMountTable handles the "mounts" endpoint to provide the mount table
|
||||
func (b *SystemBackend) handleMountTable(
|
||||
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
|
||||
|
|
|
@ -15,7 +15,6 @@ func TestSystemBackend_RootPaths(t *testing.T) {
|
|||
"revoke-prefix/*",
|
||||
"policy",
|
||||
"policy/*",
|
||||
"seal",
|
||||
}
|
||||
|
||||
b := testSystemBackend(t)
|
||||
|
@ -25,22 +24,6 @@ func TestSystemBackend_RootPaths(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestSystemBackend_seal(t *testing.T) {
|
||||
core, b, _ := testCoreSystemBackend(t)
|
||||
req := logical.TestRequest(t, logical.WriteOperation, "seal")
|
||||
_, err := b.HandleRequest(req)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
sealed, err := core.Sealed()
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if !sealed {
|
||||
t.Fatal("should be sealed")
|
||||
}
|
||||
}
|
||||
func TestSystemBackend_mounts(t *testing.T) {
|
||||
b := testSystemBackend(t)
|
||||
req := logical.TestRequest(t, logical.ReadOperation, "mounts")
|
||||
|
|
Loading…
Reference in New Issue