From cd34145969ddee74b0a7f5b4d79e555dd13e6daf Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Mon, 5 Oct 2020 17:13:23 +0300 Subject: [PATCH] [#73] Use request owner public key in eACL check Classifier fetches public key of the request owner and owner itself. Extended ACL check should rely on this public key, because it might be extracted from session token. Signed-off-by: Alex Vanin --- pkg/services/object/acl/{basic.go => acl.go} | 7 +++---- pkg/services/object/acl/classifier.go | 22 ++++++++++---------- 2 files changed, 14 insertions(+), 15 deletions(-) rename pkg/services/object/acl/{basic.go => acl.go} (99%) diff --git a/pkg/services/object/acl/basic.go b/pkg/services/object/acl/acl.go similarity index 99% rename from pkg/services/object/acl/basic.go rename to pkg/services/object/acl/acl.go index 68767071..b5d5a679 100644 --- a/pkg/services/object/acl/basic.go +++ b/pkg/services/object/acl/acl.go @@ -386,8 +386,8 @@ func (b Service) findRequestInfo( return info, ErrUnknownContainer } - // find request role - role := b.sender.Classify(req, cid, cnr) + // find request role and key + role, key := b.sender.Classify(req, cid, cnr) if role == acl.RoleUnknown { return info, ErrUnknownRole } @@ -400,12 +400,11 @@ func (b Service) findRequestInfo( info.requestRole = role info.operation = verb info.owner = owner.NewIDFromV2(cnr.GetOwnerID()) - info.cid = cid // it is assumed that at the moment the key will be valid, // otherwise the request would not pass validation - info.senderKey = req.vheader.GetBodySignature().GetKey() + info.senderKey = key return info, nil } diff --git a/pkg/services/object/acl/classifier.go b/pkg/services/object/acl/classifier.go index 45f42f51..b0dc590c 100644 --- a/pkg/services/object/acl/classifier.go +++ b/pkg/services/object/acl/classifier.go @@ -42,46 +42,46 @@ func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier { func (c SenderClassifier) Classify( req metaWithToken, cid *container.ID, - cnr *container.Container) acl.Role { + cnr *container.Container) (acl.Role, []byte) { if cid == nil { // log there - return acl.RoleUnknown + return acl.RoleUnknown, nil } ownerID, ownerKey, err := requestOwner(req) if err != nil || ownerID == nil || ownerKey == nil { // log there - return acl.RoleUnknown + return acl.RoleUnknown, nil } + ownerKeyInBytes := crypto.MarshalPublicKey(ownerKey) + // todo: get owner from neofs.id if present // if request owner is the same as container owner, return RoleUser if bytes.Equal(cnr.GetOwnerID().GetValue(), ownerID.ToV2().GetValue()) { - return acl.RoleUser + return acl.RoleUser, ownerKeyInBytes } - ownerKeyInBytes := crypto.MarshalPublicKey(ownerKey) - isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes) if err != nil { // log there - return acl.RoleUnknown + return acl.RoleUnknown, nil } else if isInnerRingNode { - return acl.RoleSystem + return acl.RoleSystem, ownerKeyInBytes } isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr) if err != nil { // log there - return acl.RoleUnknown + return acl.RoleUnknown, nil } else if isContainerNode { - return acl.RoleSystem + return acl.RoleSystem, ownerKeyInBytes } // if none of above, return RoleOthers - return acl.RoleOthers + return acl.RoleOthers, ownerKeyInBytes } func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) {