From afeebd310cf937796fb8b5648565f2d0c99a9bd6 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Fri, 2 Oct 2020 14:39:32 +0300 Subject: [PATCH] [#66] Use session token of object header at put ACL check Owner of the request is stored in session token most of the times. Put request contains session token in the object body, so we have to fetch it from there. Signed-off-by: Alex Vanin --- pkg/services/object/acl/basic.go | 58 ++++++++++++++++++++++----- pkg/services/object/acl/classifier.go | 30 ++++++-------- 2 files changed, 60 insertions(+), 28 deletions(-) diff --git a/pkg/services/object/acl/basic.go b/pkg/services/object/acl/basic.go index ba190614..0ccfff7f 100644 --- a/pkg/services/object/acl/basic.go +++ b/pkg/services/object/acl/basic.go @@ -8,6 +8,7 @@ import ( "github.com/nspcc-dev/neofs-api-go/pkg/container" "github.com/nspcc-dev/neofs-api-go/pkg/owner" "github.com/nspcc-dev/neofs-api-go/v2/object" + "github.com/nspcc-dev/neofs-api-go/v2/session" core "github.com/nspcc-dev/neofs-node/pkg/core/container" "github.com/pkg/errors" ) @@ -75,7 +76,12 @@ func (b BasicChecker) Get( return nil, err } - reqInfo, err := b.findRequestInfo(request, cid, acl.OperationGet) + req := metaWithToken{ + vheader: request.GetVerificationHeader(), + token: request.GetMetaHeader().GetSessionToken(), + } + + reqInfo, err := b.findRequestInfo(req, cid, acl.OperationGet) if err != nil { return nil, err } @@ -110,7 +116,12 @@ func (b BasicChecker) Head( return nil, err } - reqInfo, err := b.findRequestInfo(request, cid, acl.OperationHead) + req := metaWithToken{ + vheader: request.GetVerificationHeader(), + token: request.GetMetaHeader().GetSessionToken(), + } + + reqInfo, err := b.findRequestInfo(req, cid, acl.OperationHead) if err != nil { return nil, err } @@ -133,7 +144,12 @@ func (b BasicChecker) Search( return nil, err } - reqInfo, err := b.findRequestInfo(request, cid, acl.OperationSearch) + req := metaWithToken{ + vheader: request.GetVerificationHeader(), + token: request.GetMetaHeader().GetSessionToken(), + } + + reqInfo, err := b.findRequestInfo(req, cid, acl.OperationSearch) if err != nil { return nil, err } @@ -155,7 +171,12 @@ func (b BasicChecker) Delete( return nil, err } - reqInfo, err := b.findRequestInfo(request, cid, acl.OperationDelete) + req := metaWithToken{ + vheader: request.GetVerificationHeader(), + token: request.GetMetaHeader().GetSessionToken(), + } + + reqInfo, err := b.findRequestInfo(req, cid, acl.OperationDelete) if err != nil { return nil, err } @@ -176,7 +197,12 @@ func (b BasicChecker) GetRange( return nil, err } - reqInfo, err := b.findRequestInfo(request, cid, acl.OperationRange) + req := metaWithToken{ + vheader: request.GetVerificationHeader(), + token: request.GetMetaHeader().GetSessionToken(), + } + + reqInfo, err := b.findRequestInfo(req, cid, acl.OperationRange) if err != nil { return nil, err } @@ -198,7 +224,12 @@ func (b BasicChecker) GetRangeHash( return nil, err } - reqInfo, err := b.findRequestInfo(request, cid, acl.OperationRangeHash) + req := metaWithToken{ + vheader: request.GetVerificationHeader(), + token: request.GetMetaHeader().GetSessionToken(), + } + + reqInfo, err := b.findRequestInfo(req, cid, acl.OperationRangeHash) if err != nil { return nil, err } @@ -217,23 +248,28 @@ func (p putStreamBasicChecker) Send(request *object.PutRequest) error { } part := body.GetObjectPart() - if _, ok := part.(*object.PutObjectPartInit); ok { + if part, ok := part.(*object.PutObjectPartInit); ok { cid, err := getContainerIDFromRequest(request) if err != nil { return err } - owner, err := getObjectOwnerFromMessage(request) + ownerID, err := getObjectOwnerFromMessage(request) if err != nil { return err } - reqInfo, err := p.source.findRequestInfo(request, cid, acl.OperationPut) + req := metaWithToken{ + vheader: request.GetVerificationHeader(), + token: part.GetHeader().GetSessionToken(), + } + + reqInfo, err := p.source.findRequestInfo(req, cid, acl.OperationPut) if err != nil { return err } - if !basicACLCheck(reqInfo) || !stickyBitCheck(reqInfo, owner) { + if !basicACLCheck(reqInfo) || !stickyBitCheck(reqInfo, ownerID) { return ErrBasicAccessDenied } } @@ -272,7 +308,7 @@ func (g getStreamBasicChecker) Recv() (*object.GetResponse, error) { } func (b BasicChecker) findRequestInfo( - req RequestV2, + req metaWithToken, cid *container.ID, op acl.Operation) (info requestInfo, err error) { diff --git a/pkg/services/object/acl/classifier.go b/pkg/services/object/acl/classifier.go index 44e6e673..45f42f51 100644 --- a/pkg/services/object/acl/classifier.go +++ b/pkg/services/object/acl/classifier.go @@ -20,9 +20,9 @@ type ( InnerRingKeys() ([][]byte, error) } - RequestV2 interface { - GetMetaHeader() *session.RequestMetaHeader - GetVerificationHeader() *session.RequestVerificationHeader + metaWithToken struct { + vheader *session.RequestVerificationHeader + token *session.SessionToken } SenderClassifier struct { @@ -40,10 +40,11 @@ func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier { } func (c SenderClassifier) Classify( - req RequestV2, + req metaWithToken, cid *container.ID, cnr *container.Container) acl.Role { - if cid == nil || req == nil { + + if cid == nil { // log there return acl.RoleUnknown } @@ -83,24 +84,19 @@ func (c SenderClassifier) Classify( return acl.RoleOthers } -func requestOwner(req RequestV2) (*owner.ID, *ecdsa.PublicKey, error) { - var ( - meta = req.GetMetaHeader() - verify = req.GetVerificationHeader() - ) - - if meta == nil || verify == nil { - return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at meta or verify header") +func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) { + if req.vheader == nil { + return nil, nil, errors.Wrap(ErrMalformedRequest, "nil verification header") } // if session token is presented, use it as truth source - if token := meta.GetSessionToken(); token != nil { - body := token.GetBody() + if req.token != nil { + body := req.token.GetBody() if body == nil { return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at session token body") } - signature := token.GetSignature() + signature := req.token.GetSignature() if signature == nil { return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at signature") } @@ -109,7 +105,7 @@ func requestOwner(req RequestV2) (*owner.ID, *ecdsa.PublicKey, error) { } // otherwise get original body signature - bodySignature := originalBodySignature(verify) + bodySignature := originalBodySignature(req.vheader) if bodySignature == nil { return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at body signature") }