[#449] tree: Allow reading requests signed by keys from allow list

Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
This commit is contained in:
Anton Nikiforov 2023-06-23 11:25:08 +03:00
parent 40eae22109
commit 71889234b7
4 changed files with 49 additions and 0 deletions

View file

@ -1,9 +1,11 @@
package treeconfig package treeconfig
import ( import (
"fmt"
"time" "time"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-node/config"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
) )
const ( const (
@ -71,3 +73,22 @@ func (c TreeConfig) ReplicationWorkerCount() int {
func (c TreeConfig) SyncInterval() time.Duration { func (c TreeConfig) SyncInterval() time.Duration {
return config.DurationSafe(c.cfg, "sync_interval") return config.DurationSafe(c.cfg, "sync_interval")
} }
// AuthorizedKeys parses and returns an array of "authorized_keys" config
// parameter from "tree" section.
//
// Returns an empty list if not set.
func (c TreeConfig) AuthorizedKeys() keys.PublicKeys {
authorizedKeysStr := config.StringSliceSafe(c.cfg, "authorized_keys")
authorizedKeys := make(keys.PublicKeys, 0, len(authorizedKeysStr))
for i := range authorizedKeysStr {
pub, err := keys.NewPublicKeyFromString(authorizedKeysStr[i])
if err != nil {
panic(fmt.Errorf("could not parse Tree authorized key %s: %w", authorizedKeysStr[i], err))
}
authorizedKeys = append(authorizedKeys, pub)
}
return authorizedKeys
}

View file

@ -56,6 +56,7 @@ func initTreeService(c *cfg) {
tree.WithReplicationTimeout(treeConfig.ReplicationTimeout()), tree.WithReplicationTimeout(treeConfig.ReplicationTimeout()),
tree.WithReplicationChannelCapacity(treeConfig.ReplicationChannelCapacity()), tree.WithReplicationChannelCapacity(treeConfig.ReplicationChannelCapacity()),
tree.WithReplicationWorkerCount(treeConfig.ReplicationWorkerCount()), tree.WithReplicationWorkerCount(treeConfig.ReplicationWorkerCount()),
tree.WithAuthorizedKeys(treeConfig.AuthorizedKeys()),
tree.WithMetrics(c.metricsCollector.TreeService())) tree.WithMetrics(c.metricsCollector.TreeService()))
for _, srv := range c.cfgGRPC.servers { for _, srv := range c.cfgGRPC.servers {

View file

@ -33,6 +33,7 @@ type cfg struct {
replicatorWorkerCount int replicatorWorkerCount int
replicatorTimeout time.Duration replicatorTimeout time.Duration
containerCacheSize int containerCacheSize int
authorizedKeys [][]byte
metrics MetricsRegister metrics MetricsRegister
} }
@ -124,3 +125,14 @@ func WithMetrics(v MetricsRegister) Option {
c.metrics = v c.metrics = v
} }
} }
// WithAuthorizedKeys returns option to add list of public
// keys that have rights to use Tree service.
func WithAuthorizedKeys(keys keys.PublicKeys) Option {
return func(c *cfg) {
c.authorizedKeys = nil
for _, key := range keys {
c.authorizedKeys = append(c.authorizedKeys, key.Bytes())
}
}
}

View file

@ -51,6 +51,21 @@ func (s *Service) verifyClient(req message, cid cidSDK.ID, rawBearer []byte, op
if err != nil { if err != nil {
return err return err
} }
if op == acl.OpObjectGet {
// verify if the request for a client operation
// was signed by a key from authorized list.
// Operation must be one of READ.
sign := req.GetSignature()
if sign == nil {
return errors.New("missing signature")
}
var key = sign.GetKey()
for i := range s.authorizedKeys {
if bytes.Equal(s.authorizedKeys[i], key) {
return nil
}
}
}
cnr, err := s.cnrSource.Get(cid) cnr, err := s.cnrSource.Get(cid)
if err != nil { if err != nil {