[#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
33ad753302
commit
9902965ff4
3 changed files with 36 additions and 11 deletions
|
@ -37,10 +37,12 @@ type ECWriter struct {
|
||||||
|
|
||||||
ObjectMeta object.ContentMeta
|
ObjectMeta object.ContentMeta
|
||||||
ObjectMetaValid bool
|
ObjectMetaValid bool
|
||||||
|
|
||||||
|
remoteRequestSignKey *ecdsa.PrivateKey
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ECWriter) WriteObject(ctx context.Context, obj *objectSDK.Object) error {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -60,23 +62,35 @@ func (e *ECWriter) WriteObject(ctx context.Context, obj *objectSDK.Object) error
|
||||||
e.ObjectMetaValid = true
|
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 {
|
if obj.ECHeader() != nil {
|
||||||
return e.writeECPart(ctx, obj)
|
return e.writeECPart(ctx, obj)
|
||||||
}
|
}
|
||||||
return e.writeRawObject(ctx, obj)
|
return e.writeRawObject(ctx, obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *ECWriter) relayIfNotContainerNode(ctx context.Context, obj *objectSDK.Object) (bool, error) {
|
func (e *ECWriter) relayIfNotContainerNode(ctx context.Context, obj *objectSDK.Object) (bool, bool, error) {
|
||||||
if e.Relay == nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
currentNodeIsContainerNode, err := e.currentNodeIsContainerNode()
|
currentNodeIsContainerNode, err := e.currentNodeIsContainerNode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, false, err
|
||||||
}
|
}
|
||||||
if currentNodeIsContainerNode {
|
if currentNodeIsContainerNode {
|
||||||
// object can be splitted or saved local
|
// 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()
|
objID := object.AddressOf(obj).Object()
|
||||||
var index uint32
|
var index uint32
|
||||||
|
@ -85,9 +99,9 @@ func (e *ECWriter) relayIfNotContainerNode(ctx context.Context, obj *objectSDK.O
|
||||||
index = obj.ECHeader().Index()
|
index = obj.ECHeader().Index()
|
||||||
}
|
}
|
||||||
if err := e.relayToContainerNode(ctx, objID, index); err != nil {
|
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) {
|
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)
|
client.NodeInfoFromNetmapElement(&clientNodeInfo, node)
|
||||||
|
|
||||||
remoteTaget := remoteWriter{
|
remoteTaget := remoteWriter{
|
||||||
privateKey: e.Key,
|
privateKey: e.remoteRequestSignKey,
|
||||||
clientConstructor: e.Config.ClientConstructor,
|
clientConstructor: e.Config.ClientConstructor,
|
||||||
commonPrm: e.CommonPrm,
|
commonPrm: e.CommonPrm,
|
||||||
nodeInfo: clientNodeInfo,
|
nodeInfo: clientNodeInfo,
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/client"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/client"
|
||||||
netmapcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/netmap"
|
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/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/services/object_manager/placement"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/checksum"
|
||||||
|
@ -127,6 +128,8 @@ func TestECWriter(t *testing.T) {
|
||||||
|
|
||||||
ownerKey, err := keys.NewPrivateKey()
|
ownerKey, err := keys.NewPrivateKey()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
nodeKey, err := keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
pool, err := ants.NewPool(4, ants.WithNonblocking(true))
|
pool, err := ants.NewPool(4, ants.WithNonblocking(true))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -141,6 +144,7 @@ func TestECWriter(t *testing.T) {
|
||||||
RemotePool: pool,
|
RemotePool: pool,
|
||||||
Logger: log,
|
Logger: log,
|
||||||
ClientConstructor: clientConstructor{vectors: ns},
|
ClientConstructor: clientConstructor{vectors: ns},
|
||||||
|
KeyStorage: util.NewKeyStorage(&nodeKey.PrivateKey, nil, nil),
|
||||||
},
|
},
|
||||||
PlacementOpts: append(
|
PlacementOpts: append(
|
||||||
[]placement.Option{placement.UseBuilder(builder), placement.ForContainer(cnr)},
|
[]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
|
// ForgetTokens forgets all the tokens read from the request's
|
||||||
// meta information before.
|
// meta information before.
|
||||||
func (p *CommonPrm) ForgetTokens() {
|
func (p *CommonPrm) ForgetTokens() func() {
|
||||||
if p != nil {
|
if p != nil {
|
||||||
|
tk := p.token
|
||||||
|
br := p.bearer
|
||||||
p.token = nil
|
p.token = nil
|
||||||
p.bearer = nil
|
p.bearer = nil
|
||||||
|
return func() {
|
||||||
|
p.token = tk
|
||||||
|
p.bearer = br
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return func() {}
|
||||||
|
}
|
||||||
|
|
||||||
func CommonPrmFromV2(req interface {
|
func CommonPrmFromV2(req interface {
|
||||||
GetMetaHeader() *session.RequestMetaHeader
|
GetMetaHeader() *session.RequestMetaHeader
|
||||||
|
|
Loading…
Reference in a new issue