forked from TrueCloudLab/frostfs-node
[#2144] node: Try node's private key if dynamic token fetching failed
`GETRANGEHASH` request spawns `GETRANGE` requests if an object could not be found locally. If the original request contains session, it can be static and, therefore, fetching session key can not be performed successfully. As the best effort a node could request object's range with its own key. Signed-off-by: Pavel Karpy <p.karpy@yadro.com>
This commit is contained in:
parent
86a4fba571
commit
6a4e5e6f0a
4 changed files with 35 additions and 0 deletions
|
@ -29,6 +29,7 @@ Changelog for NeoFS Node
|
|||
- Use `sync.Pool` in Object.PUT service (#2139)
|
||||
- Shard uses metabase for `HEAD` requests by default, not write-cache (#2167)
|
||||
- Clarify help for `--expire-at` parameter for commands `object lock/put` and `bearer create` (#2097)
|
||||
- Node spawns `GETRANGE` requests signed with the node's key if session key was not found for `RANGEHASH` (#2144)
|
||||
|
||||
### Fixed
|
||||
- Open FSTree in sync mode by default (#1992)
|
||||
|
|
|
@ -109,6 +109,12 @@ func (exec execCtx) isChild(obj *objectSDK.Object) bool {
|
|||
}
|
||||
|
||||
func (exec execCtx) key() (*ecdsa.PrivateKey, error) {
|
||||
if exec.prm.signerKey != nil {
|
||||
// the key has already been requested and
|
||||
// cached in the previous operations
|
||||
return exec.prm.signerKey, nil
|
||||
}
|
||||
|
||||
var sessionInfo *util.SessionInfo
|
||||
|
||||
if tok := exec.prm.common.SessionToken(); tok != nil {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package getsvc
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"hash"
|
||||
|
||||
|
@ -74,6 +75,11 @@ type commonPrm struct {
|
|||
raw bool
|
||||
|
||||
forwarder RequestForwarder
|
||||
|
||||
// signerKey is a cached key that should be used for spawned
|
||||
// requests (if any), could be nil if incoming request handling
|
||||
// routine does not include any key fetching operations
|
||||
signerKey *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
// ChunkWriter is an interface of target component
|
||||
|
@ -145,6 +151,11 @@ func (p *commonPrm) WithRawFlag(raw bool) {
|
|||
p.raw = raw
|
||||
}
|
||||
|
||||
// WithCachedSignerKey sets optional key for all further requests.
|
||||
func (p *commonPrm) WithCachedSignerKey(signerKey *ecdsa.PrivateKey) {
|
||||
p.signerKey = signerKey
|
||||
}
|
||||
|
||||
// SetHeaderWriter sets target component to write the object header.
|
||||
func (p *HeadPrm) SetHeaderWriter(w HeaderWriter) {
|
||||
p.objWriter = &partWriter{
|
||||
|
|
|
@ -362,6 +362,23 @@ func (s *Service) toHashRangePrm(req *objectV2.GetRangeHashRequest) (*getsvc.Ran
|
|||
|
||||
p.WithAddress(addr)
|
||||
|
||||
if tok := commonPrm.SessionToken(); tok != nil {
|
||||
signerKey, err := s.keyStorage.GetKey(&util.SessionInfo{
|
||||
ID: tok.ID(),
|
||||
Owner: tok.Issuer(),
|
||||
})
|
||||
if err != nil && errors.As(err, new(apistatus.SessionTokenNotFound)) {
|
||||
commonPrm.ForgetTokens()
|
||||
signerKey, err = s.keyStorage.GetKey(nil)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetching session key: %w", err)
|
||||
}
|
||||
|
||||
p.WithCachedSignerKey(signerKey)
|
||||
}
|
||||
|
||||
rngsV2 := body.GetRanges()
|
||||
rngs := make([]object.Range, len(rngsV2))
|
||||
|
||||
|
|
Loading…
Reference in a new issue