[#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 <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2020-10-05 17:13:23 +03:00 committed by Alex Vanin
parent a9e801cb22
commit cd34145969
2 changed files with 14 additions and 15 deletions

View file

@ -386,8 +386,8 @@ func (b Service) findRequestInfo(
return info, ErrUnknownContainer return info, ErrUnknownContainer
} }
// find request role // find request role and key
role := b.sender.Classify(req, cid, cnr) role, key := b.sender.Classify(req, cid, cnr)
if role == acl.RoleUnknown { if role == acl.RoleUnknown {
return info, ErrUnknownRole return info, ErrUnknownRole
} }
@ -400,12 +400,11 @@ func (b Service) findRequestInfo(
info.requestRole = role info.requestRole = role
info.operation = verb info.operation = verb
info.owner = owner.NewIDFromV2(cnr.GetOwnerID()) info.owner = owner.NewIDFromV2(cnr.GetOwnerID())
info.cid = cid info.cid = cid
// it is assumed that at the moment the key will be valid, // it is assumed that at the moment the key will be valid,
// otherwise the request would not pass validation // otherwise the request would not pass validation
info.senderKey = req.vheader.GetBodySignature().GetKey() info.senderKey = key
return info, nil return info, nil
} }

View file

@ -42,46 +42,46 @@ func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier {
func (c SenderClassifier) Classify( func (c SenderClassifier) Classify(
req metaWithToken, req metaWithToken,
cid *container.ID, cid *container.ID,
cnr *container.Container) acl.Role { cnr *container.Container) (acl.Role, []byte) {
if cid == nil { if cid == nil {
// log there // log there
return acl.RoleUnknown return acl.RoleUnknown, nil
} }
ownerID, ownerKey, err := requestOwner(req) ownerID, ownerKey, err := requestOwner(req)
if err != nil || ownerID == nil || ownerKey == nil { if err != nil || ownerID == nil || ownerKey == nil {
// log there // log there
return acl.RoleUnknown return acl.RoleUnknown, nil
} }
ownerKeyInBytes := crypto.MarshalPublicKey(ownerKey)
// todo: get owner from neofs.id if present // todo: get owner from neofs.id if present
// if request owner is the same as container owner, return RoleUser // if request owner is the same as container owner, return RoleUser
if bytes.Equal(cnr.GetOwnerID().GetValue(), ownerID.ToV2().GetValue()) { 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) isInnerRingNode, err := c.isInnerRingKey(ownerKeyInBytes)
if err != nil { if err != nil {
// log there // log there
return acl.RoleUnknown return acl.RoleUnknown, nil
} else if isInnerRingNode { } else if isInnerRingNode {
return acl.RoleSystem return acl.RoleSystem, ownerKeyInBytes
} }
isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr) isContainerNode, err := c.isContainerKey(ownerKeyInBytes, cid.ToV2().GetValue(), cnr)
if err != nil { if err != nil {
// log there // log there
return acl.RoleUnknown return acl.RoleUnknown, nil
} else if isContainerNode { } else if isContainerNode {
return acl.RoleSystem return acl.RoleSystem, ownerKeyInBytes
} }
// if none of above, return RoleOthers // if none of above, return RoleOthers
return acl.RoleOthers return acl.RoleOthers, ownerKeyInBytes
} }
func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) { func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) {