forked from TrueCloudLab/frostfs-node
[#525] ir/container: Check session verb and container ID
Token of the container session should be written out with container context. The context should have the verb corresponding to the operation. If an operation is performed on a fixed container, the session should be propagated to it or to all user containers Implement all described checks in validation of `Put` / `Delete` / `SetEACL` events. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
25d87809c8
commit
23c5277014
3 changed files with 80 additions and 9 deletions
|
@ -8,12 +8,19 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/session"
|
"github.com/nspcc-dev/neofs-api-go/pkg/session"
|
||||||
"github.com/nspcc-dev/neofs-api-go/util/signature"
|
"github.com/nspcc-dev/neofs-api-go/util/signature"
|
||||||
signature2 "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
signature2 "github.com/nspcc-dev/neofs-api-go/v2/signature"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errWrongSessionContext = errors.New("wrong session context")
|
||||||
|
errWrongSessionVerb = errors.New("wrong token verb")
|
||||||
|
errWrongCID = errors.New("wrong container ID")
|
||||||
|
)
|
||||||
|
|
||||||
type ownerIDSource interface {
|
type ownerIDSource interface {
|
||||||
OwnerID() *owner.ID
|
OwnerID() *owner.ID
|
||||||
}
|
}
|
||||||
|
@ -125,3 +132,37 @@ func (cp *Processor) checkSessionToken(token *session.Token) error {
|
||||||
|
|
||||||
return cp.checkKeyOwnership(token, key)
|
return cp.checkKeyOwnership(token, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type verbAssert func(*session.ContainerContext) bool
|
||||||
|
|
||||||
|
func contextWithVerifiedVerb(tok *session.Token, verbAssert verbAssert) (*session.ContainerContext, error) {
|
||||||
|
c := session.GetContainerContext(tok)
|
||||||
|
if c == nil {
|
||||||
|
return nil, errWrongSessionContext
|
||||||
|
}
|
||||||
|
|
||||||
|
if !verbAssert(c) {
|
||||||
|
return nil, errWrongSessionVerb
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkTokenContext(tok *session.Token, verbAssert verbAssert) error {
|
||||||
|
_, err := contextWithVerifiedVerb(tok, verbAssert)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkTokenContextWithCID(tok *session.Token, id *cid.ID, verbAssert verbAssert) error {
|
||||||
|
c, err := contextWithVerifiedVerb(tok, verbAssert)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tokCID := c.Container()
|
||||||
|
if tokCID != nil && !tokCID.Equal(id) {
|
||||||
|
return errWrongCID
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container"
|
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container"
|
||||||
|
cid "github.com/nspcc-dev/neofs-api-go/pkg/container/id"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/session"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/container"
|
"github.com/nspcc-dev/neofs-node/pkg/core/container"
|
||||||
containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
|
containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -67,7 +70,15 @@ func (cp *Processor) checkPutContainer(e *containerEvent.Put) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check verb and CID
|
if tok != nil {
|
||||||
|
// check token context
|
||||||
|
err = checkTokenContext(tok, func(c *session.ContainerContext) bool {
|
||||||
|
return c.IsForPut()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cnr.SetSessionToken(tok)
|
cnr.SetSessionToken(tok)
|
||||||
|
|
||||||
|
@ -104,10 +115,10 @@ func (cp *Processor) processContainerDelete(delete *containerEvent.Delete) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
||||||
cid := e.ContainerID()
|
binCID := e.ContainerID()
|
||||||
|
|
||||||
// receive owner of the related container
|
// receive owner of the related container
|
||||||
cnr, err := cp.cnrClient.Get(cid)
|
cnr, err := cp.cnrClient.Get(binCID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not receive the container: %w", err)
|
return fmt.Errorf("could not receive the container: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -120,13 +131,25 @@ func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
||||||
var checkKeys keys.PublicKeys
|
var checkKeys keys.PublicKeys
|
||||||
|
|
||||||
if token != nil {
|
if token != nil {
|
||||||
|
// check token context
|
||||||
|
// TODO: think how to avoid version casts
|
||||||
|
idV2 := new(refs.ContainerID)
|
||||||
|
idV2.SetValue(binCID)
|
||||||
|
|
||||||
|
id := cid.NewFromV2(idV2)
|
||||||
|
|
||||||
|
err = checkTokenContextWithCID(token, id, func(c *session.ContainerContext) bool {
|
||||||
|
return c.IsForDelete()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
key, err := keys.NewPublicKeyFromBytes(token.SessionKey(), elliptic.P256())
|
key, err := keys.NewPublicKeyFromBytes(token.SessionKey(), elliptic.P256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid session key: %w", err)
|
return fmt.Errorf("invalid session key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check verb and container ID
|
|
||||||
|
|
||||||
// check token ownership
|
// check token ownership
|
||||||
err = cp.checkKeyOwnershipWithToken(cnr, key, token)
|
err = cp.checkKeyOwnershipWithToken(cnr, key, token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -143,7 +166,7 @@ func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// verify signature
|
// verify signature
|
||||||
cidHash := sha256.Sum256(cid)
|
cidHash := sha256.Sum256(binCID)
|
||||||
sig := e.Signature()
|
sig := e.Signature()
|
||||||
|
|
||||||
for _, key := range checkKeys {
|
for _, key := range checkKeys {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/session"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/event/container"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -67,9 +68,15 @@ func (cp *Processor) checkSetEACL(e container.SetEACL) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cnr.SetSessionToken(tok)
|
if tok != nil {
|
||||||
|
// check token context
|
||||||
// TODO: check verb and container ID
|
err = checkTokenContextWithCID(tok, table.CID(), func(c *session.ContainerContext) bool {
|
||||||
|
return c.IsForSetEACL()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check key ownership
|
// check key ownership
|
||||||
return cp.checkKeyOwnership(cnr, key)
|
return cp.checkKeyOwnership(cnr, key)
|
||||||
|
|
Loading…
Reference in a new issue