Skip to content

Commit

Permalink
node: Support wildcard for container sessions (#2741)
Browse files Browse the repository at this point in the history
  • Loading branch information
roman-khimov authored Feb 19, 2024
2 parents d54311b + 21e78b1 commit 996b1ea
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 11 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ Changelog for NeoFS Node
### Added

### Fixed
- Inability to deploy contract with non-standard zone via neofs-adm
- Inability to deploy contract with non-standard zone via neofs-adm (#2740)
- Container session token's `wildcard` field support (#2741)

### Changed

Expand Down
32 changes: 24 additions & 8 deletions pkg/services/container/morph/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package container
import (
"bytes"
"context"
"crypto/ecdsa"
"errors"
"fmt"

Expand All @@ -14,6 +15,7 @@ import (
containercore "github.com/nspcc-dev/neofs-node/pkg/core/container"
containerSvc "github.com/nspcc-dev/neofs-node/pkg/services/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
eaclSDK "github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/user"
Expand Down Expand Up @@ -335,22 +337,18 @@ func (s *morphExecutor) validateToken(t *sessionV2.Token, cIDV2 *refs.ContainerI
return fmt.Errorf("incorrect token signature: %w", err)
}

if cIDV2 == nil { // can be nil for PUT or wildcard may be true
if cIDV2 == nil { // can be nil for PUT
return nil
}

if sessionCID := cc.ContainerID().GetValue(); !bytes.Equal(sessionCID, cIDV2.GetValue()) {
return fmt.Errorf("wrong container: %s", base58.Encode(sessionCID))
}

var cID cid.ID
var cIDRequested cid.ID

err = cID.ReadFromV2(*cIDV2)
err = cIDRequested.ReadFromV2(*cIDV2)
if err != nil {
return fmt.Errorf("invalid container ID: %w", err)
}

cnr, err := s.rdr.Get(cID)
cnr, err := s.rdr.Get(cIDRequested)
if err != nil {
return fmt.Errorf("reading container from the network: %w", err)
}
Expand All @@ -359,5 +357,23 @@ func (s *morphExecutor) validateToken(t *sessionV2.Token, cIDV2 *refs.ContainerI
return fmt.Errorf("session was not issued by the container owner, issuer: %q", issuer)
}

var keyFromToken neofsecdsa.PublicKey

err = keyFromToken.Decode(t.GetSignature().GetKey())
if err != nil {
return errors.New("error while decoding public key from the token's signer")
}

userFromToken := user.ResolveFromECDSAPublicKey(ecdsa.PublicKey(keyFromToken))
if !cnr.Value.Owner().Equals(userFromToken) {
return fmt.Errorf("session token signer differs container owner: signer: %s, owner: %s", userFromToken, cnr.Value.Owner())
}

if !cc.Wildcard() {
if sessionCID := cc.ContainerID().GetValue(); !bytes.Equal(sessionCID, cIDV2.GetValue()) {
return fmt.Errorf("wrong container: %s", base58.Encode(sessionCID))
}
}

return nil
}
47 changes: 45 additions & 2 deletions pkg/services/container/morph/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ package container_test

import (
"context"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha256"
"testing"

"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neofs-api-go/v2/container"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
Expand All @@ -17,6 +21,7 @@ import (
cidtest "github.com/nspcc-dev/neofs-sdk-go/container/id/test"
containertest "github.com/nspcc-dev/neofs-sdk-go/container/test"
neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
sessionsdk "github.com/nspcc-dev/neofs-sdk-go/session"
sessiontest "github.com/nspcc-dev/neofs-sdk-go/session/test"
"github.com/nspcc-dev/neofs-sdk-go/user"
Expand All @@ -32,11 +37,11 @@ func (m mock) Get(_ cid.ID) (*containerCore.Container, error) {
return &containerCore.Container{Value: m.cnr}, nil
}

func (m mock) GetEACL(id cid.ID) (*containerCore.EACL, error) {
func (m mock) GetEACL(_ cid.ID) (*containerCore.EACL, error) {
return nil, nil
}

func (m mock) List(id *user.ID) ([]cid.ID, error) {
func (m mock) List(_ *user.ID) ([]cid.ID, error) {
return nil, nil
}

Expand Down Expand Up @@ -279,6 +284,44 @@ func TestValidateToken(t *testing.T) {
_, err = e.Delete(context.TODO(), &tokV2, &reqBody)
require.Error(t, err)
})

t.Run("wildcard support", func(t *testing.T) {
var reqBody container.DeleteRequestBody
reqBody.SetContainerID(&cIDV2)

var tok sessionsdk.Container

priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
require.NoError(t, err)

tok.SetExp(11)
tok.SetNbf(22)
tok.SetIat(33)
tok.ForVerb(sessionsdk.VerbContainerDelete)
tok.SetID(uuid.New())
tok.SetAuthKey((*neofsecdsa.PublicKey)(&priv.PublicKey))
require.NoError(t, tok.Sign(signer))

var tokV2 session.Token
tok.WriteToV2(&tokV2)

m := &mock{cnr: cnr}
e := containerSvcMorph.NewExecutor(m, m)

t.Run("wrong owner", func(t *testing.T) {
m.cnr = containertest.Container(t)

_, err := e.Delete(context.TODO(), &tokV2, &reqBody)
require.Error(t, err)
})

t.Run("correct owner", func(t *testing.T) {
m.cnr = cnr

_, err := e.Delete(context.TODO(), &tokV2, &reqBody)
require.NoError(t, err)
})
})
}

func generateToken(t *testing.T, ctx session.TokenContext, signer user.Signer) *session.Token {
Expand Down

0 comments on commit 996b1ea

Please sign in to comment.