[#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 <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2020-10-02 14:39:32 +03:00 committed by Alex Vanin
parent 2ee24998ba
commit afeebd310c
2 changed files with 60 additions and 28 deletions

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neofs-api-go/pkg/container" "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/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/v2/object" "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" core "github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -75,7 +76,12 @@ func (b BasicChecker) Get(
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
@ -110,7 +116,12 @@ func (b BasicChecker) Head(
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
@ -133,7 +144,12 @@ func (b BasicChecker) Search(
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
@ -155,7 +171,12 @@ func (b BasicChecker) Delete(
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
@ -176,7 +197,12 @@ func (b BasicChecker) GetRange(
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
@ -198,7 +224,12 @@ func (b BasicChecker) GetRangeHash(
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
@ -217,23 +248,28 @@ func (p putStreamBasicChecker) Send(request *object.PutRequest) error {
} }
part := body.GetObjectPart() part := body.GetObjectPart()
if _, ok := part.(*object.PutObjectPartInit); ok { if part, ok := part.(*object.PutObjectPartInit); ok {
cid, err := getContainerIDFromRequest(request) cid, err := getContainerIDFromRequest(request)
if err != nil { if err != nil {
return err return err
} }
owner, err := getObjectOwnerFromMessage(request) ownerID, err := getObjectOwnerFromMessage(request)
if err != nil { if err != nil {
return err 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 { if err != nil {
return err return err
} }
if !basicACLCheck(reqInfo) || !stickyBitCheck(reqInfo, owner) { if !basicACLCheck(reqInfo) || !stickyBitCheck(reqInfo, ownerID) {
return ErrBasicAccessDenied return ErrBasicAccessDenied
} }
} }
@ -272,7 +308,7 @@ func (g getStreamBasicChecker) Recv() (*object.GetResponse, error) {
} }
func (b BasicChecker) findRequestInfo( func (b BasicChecker) findRequestInfo(
req RequestV2, req metaWithToken,
cid *container.ID, cid *container.ID,
op acl.Operation) (info requestInfo, err error) { op acl.Operation) (info requestInfo, err error) {

View file

@ -20,9 +20,9 @@ type (
InnerRingKeys() ([][]byte, error) InnerRingKeys() ([][]byte, error)
} }
RequestV2 interface { metaWithToken struct {
GetMetaHeader() *session.RequestMetaHeader vheader *session.RequestVerificationHeader
GetVerificationHeader() *session.RequestVerificationHeader token *session.SessionToken
} }
SenderClassifier struct { SenderClassifier struct {
@ -40,10 +40,11 @@ func NewSenderClassifier(ir InnerRingFetcher, nm core.Source) SenderClassifier {
} }
func (c SenderClassifier) Classify( func (c SenderClassifier) Classify(
req RequestV2, req metaWithToken,
cid *container.ID, cid *container.ID,
cnr *container.Container) acl.Role { cnr *container.Container) acl.Role {
if cid == nil || req == nil {
if cid == nil {
// log there // log there
return acl.RoleUnknown return acl.RoleUnknown
} }
@ -83,24 +84,19 @@ func (c SenderClassifier) Classify(
return acl.RoleOthers return acl.RoleOthers
} }
func requestOwner(req RequestV2) (*owner.ID, *ecdsa.PublicKey, error) { func requestOwner(req metaWithToken) (*owner.ID, *ecdsa.PublicKey, error) {
var ( if req.vheader == nil {
meta = req.GetMetaHeader() return nil, nil, errors.Wrap(ErrMalformedRequest, "nil verification header")
verify = req.GetVerificationHeader()
)
if meta == nil || verify == nil {
return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at meta or verify header")
} }
// if session token is presented, use it as truth source // if session token is presented, use it as truth source
if token := meta.GetSessionToken(); token != nil { if req.token != nil {
body := token.GetBody() body := req.token.GetBody()
if body == nil { if body == nil {
return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at session token body") return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at session token body")
} }
signature := token.GetSignature() signature := req.token.GetSignature()
if signature == nil { if signature == nil {
return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at signature") 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 // otherwise get original body signature
bodySignature := originalBodySignature(verify) bodySignature := originalBodySignature(req.vheader)
if bodySignature == nil { if bodySignature == nil {
return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at body signature") return nil, nil, errors.Wrap(ErrMalformedRequest, "nil at body signature")
} }