diff --git a/pkg/innerring/processors/container/common.go b/pkg/innerring/processors/container/common.go index 73112a3b..be4da01c 100644 --- a/pkg/innerring/processors/container/common.go +++ b/pkg/innerring/processors/container/common.go @@ -8,12 +8,19 @@ import ( "fmt" "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/session" "github.com/nspcc-dev/neofs-api-go/util/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 { OwnerID() *owner.ID } @@ -125,3 +132,37 @@ func (cp *Processor) checkSessionToken(token *session.Token) error { 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 +} diff --git a/pkg/innerring/processors/container/process_container.go b/pkg/innerring/processors/container/process_container.go index 41c98fa3..c5f82ac4 100644 --- a/pkg/innerring/processors/container/process_container.go +++ b/pkg/innerring/processors/container/process_container.go @@ -8,6 +8,9 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" 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" containerEvent "github.com/nspcc-dev/neofs-node/pkg/morph/event/container" "go.uber.org/zap" @@ -67,7 +70,15 @@ func (cp *Processor) checkPutContainer(e *containerEvent.Put) error { 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) @@ -104,10 +115,10 @@ func (cp *Processor) processContainerDelete(delete *containerEvent.Delete) { } func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error { - cid := e.ContainerID() + binCID := e.ContainerID() // receive owner of the related container - cnr, err := cp.cnrClient.Get(cid) + cnr, err := cp.cnrClient.Get(binCID) if err != nil { 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 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()) if err != nil { return fmt.Errorf("invalid session key: %w", err) } - // TODO: check verb and container ID - // check token ownership err = cp.checkKeyOwnershipWithToken(cnr, key, token) if err != nil { @@ -143,7 +166,7 @@ func (cp *Processor) checkDeleteContainer(e *containerEvent.Delete) error { } // verify signature - cidHash := sha256.Sum256(cid) + cidHash := sha256.Sum256(binCID) sig := e.Signature() for _, key := range checkKeys { diff --git a/pkg/innerring/processors/container/process_eacl.go b/pkg/innerring/processors/container/process_eacl.go index 8b4ef157..920ffbd4 100644 --- a/pkg/innerring/processors/container/process_eacl.go +++ b/pkg/innerring/processors/container/process_eacl.go @@ -8,6 +8,7 @@ import ( "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/session" "github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper" "github.com/nspcc-dev/neofs-node/pkg/morph/event/container" "go.uber.org/zap" @@ -67,9 +68,15 @@ func (cp *Processor) checkSetEACL(e container.SetEACL) error { return err } - cnr.SetSessionToken(tok) - - // TODO: check verb and container ID + if tok != nil { + // check token context + err = checkTokenContextWithCID(tok, table.CID(), func(c *session.ContainerContext) bool { + return c.IsForSetEACL() + }) + if err != nil { + return err + } + } // check key ownership return cp.checkKeyOwnership(cnr, key)