[#1451] writer: Sign EC parts with node's private key
As EC put request may be processed only by container node, so sign requests with current node private to not to perform APE checks. Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
17ec84151b
commit
0befda5f4f
3 changed files with 36 additions and 11 deletions
|
@ -37,10 +37,12 @@ type ECWriter struct {
|
|||
|
||||
ObjectMeta object.ContentMeta
|
||||
ObjectMetaValid bool
|
||||
|
||||
remoteRequestSignKey *ecdsa.PrivateKey
|
||||
}
|
||||
|
||||
func (e *ECWriter) WriteObject(ctx context.Context, obj *objectSDK.Object) error {
|
||||
relayed, err := e.relayIfNotContainerNode(ctx, obj)
|
||||
relayed, isContainerNode, err := e.relayIfNotContainerNode(ctx, obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -60,23 +62,35 @@ func (e *ECWriter) WriteObject(ctx context.Context, obj *objectSDK.Object) error
|
|||
e.ObjectMetaValid = true
|
||||
}
|
||||
|
||||
if isContainerNode {
|
||||
restoreTokens := e.CommonPrm.ForgetTokens()
|
||||
defer restoreTokens()
|
||||
// As request executed on container node, so sign request with container key.
|
||||
e.remoteRequestSignKey, err = e.Config.KeyStorage.GetKey(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
e.remoteRequestSignKey = e.Key
|
||||
}
|
||||
|
||||
if obj.ECHeader() != nil {
|
||||
return e.writeECPart(ctx, obj)
|
||||
}
|
||||
return e.writeRawObject(ctx, obj)
|
||||
}
|
||||
|
||||
func (e *ECWriter) relayIfNotContainerNode(ctx context.Context, obj *objectSDK.Object) (bool, error) {
|
||||
if e.Relay == nil {
|
||||
return false, nil
|
||||
}
|
||||
func (e *ECWriter) relayIfNotContainerNode(ctx context.Context, obj *objectSDK.Object) (bool, bool, error) {
|
||||
currentNodeIsContainerNode, err := e.currentNodeIsContainerNode()
|
||||
if err != nil {
|
||||
return false, err
|
||||
return false, false, err
|
||||
}
|
||||
if currentNodeIsContainerNode {
|
||||
// object can be splitted or saved local
|
||||
return false, nil
|
||||
return false, true, nil
|
||||
}
|
||||
if e.Relay == nil {
|
||||
return false, currentNodeIsContainerNode, nil
|
||||
}
|
||||
objID := object.AddressOf(obj).Object()
|
||||
var index uint32
|
||||
|
@ -85,9 +99,9 @@ func (e *ECWriter) relayIfNotContainerNode(ctx context.Context, obj *objectSDK.O
|
|||
index = obj.ECHeader().Index()
|
||||
}
|
||||
if err := e.relayToContainerNode(ctx, objID, index); err != nil {
|
||||
return false, err
|
||||
return false, false, err
|
||||
}
|
||||
return true, nil
|
||||
return true, currentNodeIsContainerNode, nil
|
||||
}
|
||||
|
||||
func (e *ECWriter) currentNodeIsContainerNode() (bool, error) {
|
||||
|
@ -338,7 +352,7 @@ func (e *ECWriter) writePartRemote(ctx context.Context, obj *objectSDK.Object, n
|
|||
client.NodeInfoFromNetmapElement(&clientNodeInfo, node)
|
||||
|
||||
remoteTaget := remoteWriter{
|
||||
privateKey: e.Key,
|
||||
privateKey: e.remoteRequestSignKey,
|
||||
clientConstructor: e.Config.ClientConstructor,
|
||||
commonPrm: e.CommonPrm,
|
||||
nodeInfo: clientNodeInfo,
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/client"
|
||||
netmapcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/network"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object/util"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/object_manager/placement"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||
|
@ -127,6 +128,8 @@ func TestECWriter(t *testing.T) {
|
|||
|
||||
ownerKey, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
nodeKey, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
pool, err := ants.NewPool(4, ants.WithNonblocking(true))
|
||||
require.NoError(t, err)
|
||||
|
@ -141,6 +144,7 @@ func TestECWriter(t *testing.T) {
|
|||
RemotePool: pool,
|
||||
Logger: log,
|
||||
ClientConstructor: clientConstructor{vectors: ns},
|
||||
KeyStorage: util.NewKeyStorage(&nodeKey.PrivateKey, nil, nil),
|
||||
},
|
||||
PlacementOpts: append(
|
||||
[]placement.Option{placement.UseBuilder(builder), placement.ForContainer(cnr)},
|
||||
|
|
|
@ -100,12 +100,19 @@ func (p *CommonPrm) SetNetmapLookupDepth(v uint64) {
|
|||
|
||||
// ForgetTokens forgets all the tokens read from the request's
|
||||
// meta information before.
|
||||
func (p *CommonPrm) ForgetTokens() {
|
||||
func (p *CommonPrm) ForgetTokens() func() {
|
||||
if p != nil {
|
||||
tk := p.token
|
||||
br := p.bearer
|
||||
p.token = nil
|
||||
p.bearer = nil
|
||||
return func() {
|
||||
p.token = tk
|
||||
p.bearer = br
|
||||
}
|
||||
}
|
||||
return func() {}
|
||||
}
|
||||
|
||||
func CommonPrmFromV2(req interface {
|
||||
GetMetaHeader() *session.RequestMetaHeader
|
||||
|
|
Loading…
Reference in a new issue