From f9248c21d4fb78948f3bb4b17e88ef99ff8d424a Mon Sep 17 00:00:00 2001 From: Michal Niewrzal Date: Wed, 17 Oct 2018 13:40:11 +0200 Subject: [PATCH] Satellite verification on storage node (#469) * Satellite verification on storage node * fix formatting * fix formatting * rename SignatureAuth to SignedMessage * fixes after review * fix linter errors * improve errors handling * remove SignedMessageProvider * fix liter errors * params changed to authorization, signed message in audit, minor fixes * fix formatting --- examples/piecestore-client/main.go | 6 +- pkg/audit/service.go | 9 +- pkg/audit/verifier.go | 14 +- pkg/audit/verifier_test.go | 6 +- pkg/auth/auth.go | 11 + pkg/auth/signature.go | 41 +++- pkg/auth/signature_test.go | 40 ++++ pkg/pb/piecestore.pb.go | 208 ++++++++++-------- pkg/pb/piecestore.proto | 5 +- pkg/piecestore/rpc/client/client.go | 23 +- pkg/piecestore/rpc/client/pieceranger.go | 21 +- pkg/piecestore/rpc/client/pieceranger_test.go | 4 +- pkg/piecestore/rpc/server/retrieve.go | 5 + pkg/piecestore/rpc/server/server.go | 10 +- pkg/piecestore/rpc/server/server_test.go | 5 +- pkg/piecestore/rpc/server/store.go | 5 + pkg/pointerdb/pdbclient/client.go | 8 +- pkg/pointerdb/pdbclient/client_test.go | 12 +- pkg/pointerdb/pdbclient/mocks/mock_client.go | 21 +- pkg/storage/ec/client.go | 45 ++-- pkg/storage/ec/client_test.go | 14 +- pkg/storage/ec/mocks/mock_client.go | 30 ++- pkg/storage/ec/psclient_mock_test.go | 24 +- pkg/storage/segments/store.go | 18 +- pkg/storage/segments/store_test.go | 9 +- 25 files changed, 382 insertions(+), 212 deletions(-) create mode 100644 pkg/auth/auth.go diff --git a/examples/piecestore-client/main.go b/examples/piecestore-client/main.go index 4175e1dab..2d68be86f 100644 --- a/examples/piecestore-client/main.go +++ b/examples/piecestore-client/main.go @@ -91,7 +91,7 @@ func main() { id := client.NewPieceID() - if err := psClient.Put(context.Background(), id, dataSection, ttl, &pb.PayerBandwidthAllocation{}); err != nil { + if err := psClient.Put(context.Background(), id, dataSection, ttl, &pb.PayerBandwidthAllocation{}, nil); err != nil { fmt.Printf("Failed to Store data of id: %s\n", id) return err } @@ -140,7 +140,7 @@ func main() { return err } - rr, err := psClient.Get(ctx, client.PieceID(id), pieceInfo.Size, &pb.PayerBandwidthAllocation{}) + rr, err := psClient.Get(ctx, client.PieceID(id), pieceInfo.Size, &pb.PayerBandwidthAllocation{}, nil) if err != nil { fmt.Printf("Failed to retrieve file of id: %s\n", id) errRemove := os.Remove(outputDir) @@ -182,7 +182,7 @@ func main() { Aliases: []string{"x"}, RunE: func(cmd *cobra.Command, args []string) error { id := args[0] - return psClient.Delete(context.Background(), client.PieceID(id)) + return psClient.Delete(context.Background(), client.PieceID(id), nil) }, }) diff --git a/pkg/audit/service.go b/pkg/audit/service.go index 240c0ab77..a6eec6751 100644 --- a/pkg/audit/service.go +++ b/pkg/audit/service.go @@ -82,7 +82,14 @@ func (service *Service) Run(ctx context.Context, interval time.Duration) (err er service.errs = append(service.errs, err) cancel() } - verifiedNodes, err := service.Verifier.verify(ctx, stripe.Index, stripe.Segment) + + authorization, err := service.Cursor.pointers.SignedMessage() + if err != nil { + service.errs = append(service.errs, err) + cancel() + } + + verifiedNodes, err := service.Verifier.verify(ctx, stripe.Index, stripe.Segment, authorization) if err != nil { service.errs = append(service.errs, err) cancel() diff --git a/pkg/audit/verifier.go b/pkg/audit/verifier.go index db6493550..c474e4bdb 100644 --- a/pkg/audit/verifier.go +++ b/pkg/audit/verifier.go @@ -35,7 +35,7 @@ type Verifier struct { } type downloader interface { - DownloadShares(ctx context.Context, pointer *pb.Pointer, stripeIndex int) (shares []share, nodes []*pb.Node, err error) + DownloadShares(ctx context.Context, pointer *pb.Pointer, stripeIndex int, authorization *pb.SignedMessage) (shares []share, nodes []*pb.Node, err error) } // defaultDownloader downloads shares from networked storage nodes @@ -67,7 +67,7 @@ func (d *defaultDownloader) dial(ctx context.Context, node *pb.Node) (ps client. // getShare use piece store clients to download shares from a given node func (d *defaultDownloader) getShare(ctx context.Context, stripeIndex, shareSize, pieceNumber int, - id client.PieceID, pieceSize int64, node *pb.Node) (s share, err error) { + id client.PieceID, pieceSize int64, node *pb.Node, authorization *pb.SignedMessage) (s share, err error) { defer mon.Task()(&ctx)(&err) ps, err := d.dial(ctx, node) @@ -80,7 +80,7 @@ func (d *defaultDownloader) getShare(ctx context.Context, stripeIndex, shareSize return s, err } - rr, err := ps.Get(ctx, derivedPieceID, pieceSize, &pb.PayerBandwidthAllocation{}) + rr, err := ps.Get(ctx, derivedPieceID, pieceSize, &pb.PayerBandwidthAllocation{}, authorization) if err != nil { return s, err } @@ -108,7 +108,7 @@ func (d *defaultDownloader) getShare(ctx context.Context, stripeIndex, shareSize // Download Shares downloads shares from the nodes where remote pieces are located func (d *defaultDownloader) DownloadShares(ctx context.Context, pointer *pb.Pointer, - stripeIndex int) (shares []share, nodes []*pb.Node, err error) { + stripeIndex int, authorization *pb.SignedMessage) (shares []share, nodes []*pb.Node, err error) { defer mon.Task()(&ctx)(&err) var nodeIds []dht.NodeID pieces := pointer.Remote.GetRemotePieces() @@ -129,7 +129,7 @@ func (d *defaultDownloader) DownloadShares(ctx context.Context, pointer *pb.Poin paddedSize := calcPadded(pointer.GetSize(), shareSize) pieceSize := paddedSize / int64(pointer.Remote.Redundancy.GetMinReq()) - s, err := d.getShare(ctx, stripeIndex, shareSize, i, pieceID, pieceSize, node) + s, err := d.getShare(ctx, stripeIndex, shareSize, i, pieceID, pieceSize, node, authorization) if err != nil { s = share{ Error: err, @@ -197,10 +197,10 @@ func calcPadded(size int64, blockSize int) int64 { } // verify downloads shares then verifies the data correctness at the given stripe -func (verifier *Verifier) verify(ctx context.Context, stripeIndex int, pointer *pb.Pointer) (verifiedNodes []*proto.Node, err error) { +func (verifier *Verifier) verify(ctx context.Context, stripeIndex int, pointer *pb.Pointer, authorization *pb.SignedMessage) (verifiedNodes []*proto.Node, err error) { defer mon.Task()(&ctx)(&err) - shares, nodes, err := verifier.downloader.DownloadShares(ctx, pointer, stripeIndex) + shares, nodes, err := verifier.downloader.DownloadShares(ctx, pointer, stripeIndex, authorization) if err != nil { return nil, err } diff --git a/pkg/audit/verifier_test.go b/pkg/audit/verifier_test.go index 024d880a5..4e6e1ba69 100644 --- a/pkg/audit/verifier_test.go +++ b/pkg/audit/verifier_test.go @@ -43,7 +43,7 @@ func TestPassingAudit(t *testing.T) { md := mockDownloader{shares: mockShares} verifier := &Verifier{downloader: &md} pointer := makePointer(tt.nodeAmt) - verifiedNodes, err := verifier.verify(ctx, 6, pointer) + verifiedNodes, err := verifier.verify(ctx, 6, pointer, nil) if err != nil { t.Fatal(err) } @@ -86,7 +86,7 @@ func TestSomeNodesPassAudit(t *testing.T) { md := mockDownloader{shares: mockShares} verifier := &Verifier{downloader: &md} pointer := makePointer(tt.nodeAmt) - verifiedNodes, err := verifier.verify(ctx, 6, pointer) + verifiedNodes, err := verifier.verify(ctx, 6, pointer, nil) if err != nil { t.Fatal(err) } @@ -202,7 +202,7 @@ func TestCalcPadded(t *testing.T) { } func (m *mockDownloader) DownloadShares(ctx context.Context, pointer *pb.Pointer, - stripeIndex int) (shares []share, nodes []*pb.Node, err error) { + stripeIndex int, authorization *pb.SignedMessage) (shares []share, nodes []*pb.Node, err error) { for _, share := range m.shares { shares = append(shares, share) } diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go new file mode 100644 index 000000000..4581e94cb --- /dev/null +++ b/pkg/auth/auth.go @@ -0,0 +1,11 @@ +// Copyright (C) 2018 Storj Labs, Inc. +// See LICENSE for copying information. + +package auth + +import ( + "github.com/zeebo/errs" +) + +// Error is the default auth error class +var Error = errs.Class("auth error") diff --git a/pkg/auth/signature.go b/pkg/auth/signature.go index 1a35e44cd..e7e4fdbde 100644 --- a/pkg/auth/signature.go +++ b/pkg/auth/signature.go @@ -13,11 +13,6 @@ import ( "storj.io/storj/pkg/provider" ) -// SignatureAuthProvider interface provides access to last signature auth data -type SignatureAuthProvider interface { - Auth() (*pb.SignatureAuth, error) -} - // GenerateSignature creates signature from identity id func GenerateSignature(identity *provider.FullIdentity) ([]byte, error) { if identity == nil { @@ -35,8 +30,8 @@ func GenerateSignature(identity *provider.FullIdentity) ([]byte, error) { return signature, nil } -// NewSignatureAuth creates instance of signature auth data -func NewSignatureAuth(signature []byte, identity *provider.PeerIdentity) (*pb.SignatureAuth, error) { +// NewSignedMessage creates instance of signed message +func NewSignedMessage(signature []byte, identity *provider.PeerIdentity) (*pb.SignedMessage, error) { k, ok := identity.Leaf.PublicKey.(*ecdsa.PublicKey) if !ok { return nil, peertls.ErrUnsupportedKey.New("%T", identity.Leaf.PublicKey) @@ -46,9 +41,39 @@ func NewSignatureAuth(signature []byte, identity *provider.PeerIdentity) (*pb.Si if err != nil { return nil, err } - return &pb.SignatureAuth{ + return &pb.SignedMessage{ Data: identity.ID.Bytes(), Signature: signature, PublicKey: encodedKey, }, nil } + +// SignedMessageVerifier checks if provided signed message can be verified +type SignedMessageVerifier func(signature *pb.SignedMessage) error + +// NewSignedMessageVerifier creates default implementation of SignedMessageVerifier +func NewSignedMessageVerifier() SignedMessageVerifier { + return func(signedMessage *pb.SignedMessage) error { + if signedMessage == nil { + return Error.New("no message to verify") + } + if signedMessage.Signature == nil { + return Error.New("missing signature for verification") + } + if signedMessage.Data == nil { + return Error.New("missing data for verification") + } + if signedMessage.PublicKey == nil { + return Error.New("missing public key for verification") + } + + k, err := cryptopasta.DecodePublicKey(signedMessage.GetPublicKey()) + if err != nil { + return Error.Wrap(err) + } + if ok := cryptopasta.Verify(signedMessage.GetData(), signedMessage.GetSignature(), k); !ok { + return Error.New("failed to verify message") + } + return nil + } +} diff --git a/pkg/auth/signature_test.go b/pkg/auth/signature_test.go index 9a86dc7dd..5789199a9 100644 --- a/pkg/auth/signature_test.go +++ b/pkg/auth/signature_test.go @@ -38,3 +38,43 @@ func TestGenerateSignature(t *testing.T) { assert.Equal(t, tt.verified, verified) } } + +func TestSignedMessageVerifier(t *testing.T) { + ctx := context.Background() + ca, err := provider.NewCA(ctx, 12, 4) + assert.NoError(t, err) + identity, err := ca.NewIdentity() + assert.NoError(t, err) + + signature, err := GenerateSignature(identity) + assert.NoError(t, err) + + peerIdentity := &provider.PeerIdentity{ID: identity.ID, Leaf: identity.Leaf} + signedMessage, err := NewSignedMessage(signature, peerIdentity) + assert.NoError(t, err) + + for _, tt := range []struct { + signature []byte + data []byte + publicKey []byte + errString string + }{ + {signedMessage.Signature, signedMessage.Data, signedMessage.PublicKey, ""}, + {nil, signedMessage.Data, signedMessage.PublicKey, "auth error: missing signature for verification"}, + {signedMessage.Signature, nil, signedMessage.PublicKey, "auth error: missing data for verification"}, + {signedMessage.Signature, signedMessage.Data, nil, "auth error: missing public key for verification"}, + + {signedMessage.Signature, []byte("malformed data"), signedMessage.PublicKey, "auth error: failed to verify message"}, + } { + signedMessage.Signature = tt.signature + signedMessage.Data = tt.data + signedMessage.PublicKey = tt.publicKey + + err := NewSignedMessageVerifier()(signedMessage) + if tt.errString != "" { + assert.EqualError(t, err, tt.errString) + } else { + assert.NoError(t, err) + } + } +} diff --git a/pkg/pb/piecestore.pb.go b/pkg/pb/piecestore.pb.go index fbdacbd83..ea4d1da63 100644 --- a/pkg/pb/piecestore.pb.go +++ b/pkg/pb/piecestore.pb.go @@ -35,7 +35,7 @@ func (m *PayerBandwidthAllocation) Reset() { *m = PayerBandwidthAllocati func (m *PayerBandwidthAllocation) String() string { return proto.CompactTextString(m) } func (*PayerBandwidthAllocation) ProtoMessage() {} func (*PayerBandwidthAllocation) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{0} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{0} } func (m *PayerBandwidthAllocation) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PayerBandwidthAllocation.Unmarshal(m, b) @@ -84,7 +84,7 @@ func (m *PayerBandwidthAllocation_Data) Reset() { *m = PayerBandwidthAll func (m *PayerBandwidthAllocation_Data) String() string { return proto.CompactTextString(m) } func (*PayerBandwidthAllocation_Data) ProtoMessage() {} func (*PayerBandwidthAllocation_Data) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{0, 0} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{0, 0} } func (m *PayerBandwidthAllocation_Data) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PayerBandwidthAllocation_Data.Unmarshal(m, b) @@ -151,7 +151,7 @@ func (m *RenterBandwidthAllocation) Reset() { *m = RenterBandwidthAlloca func (m *RenterBandwidthAllocation) String() string { return proto.CompactTextString(m) } func (*RenterBandwidthAllocation) ProtoMessage() {} func (*RenterBandwidthAllocation) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{1} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{1} } func (m *RenterBandwidthAllocation) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RenterBandwidthAllocation.Unmarshal(m, b) @@ -197,7 +197,7 @@ func (m *RenterBandwidthAllocation_Data) Reset() { *m = RenterBandwidthA func (m *RenterBandwidthAllocation_Data) String() string { return proto.CompactTextString(m) } func (*RenterBandwidthAllocation_Data) ProtoMessage() {} func (*RenterBandwidthAllocation_Data) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{1, 0} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{1, 0} } func (m *RenterBandwidthAllocation_Data) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_RenterBandwidthAllocation_Data.Unmarshal(m, b) @@ -234,6 +234,7 @@ func (m *RenterBandwidthAllocation_Data) GetTotal() int64 { type PieceStore struct { Bandwidthallocation *RenterBandwidthAllocation `protobuf:"bytes,1,opt,name=bandwidthallocation,proto3" json:"bandwidthallocation,omitempty"` Piecedata *PieceStore_PieceData `protobuf:"bytes,2,opt,name=piecedata,proto3" json:"piecedata,omitempty"` + Authorization *SignedMessage `protobuf:"bytes,3,opt,name=authorization,proto3" json:"authorization,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -243,7 +244,7 @@ func (m *PieceStore) Reset() { *m = PieceStore{} } func (m *PieceStore) String() string { return proto.CompactTextString(m) } func (*PieceStore) ProtoMessage() {} func (*PieceStore) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{2} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{2} } func (m *PieceStore) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceStore.Unmarshal(m, b) @@ -277,6 +278,13 @@ func (m *PieceStore) GetPiecedata() *PieceStore_PieceData { return nil } +func (m *PieceStore) GetAuthorization() *SignedMessage { + if m != nil { + return m.Authorization + } + return nil +} + type PieceStore_PieceData struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` ExpirationUnixSec int64 `protobuf:"varint,2,opt,name=expiration_unix_sec,json=expirationUnixSec,proto3" json:"expiration_unix_sec,omitempty"` @@ -290,7 +298,7 @@ func (m *PieceStore_PieceData) Reset() { *m = PieceStore_PieceData{} } func (m *PieceStore_PieceData) String() string { return proto.CompactTextString(m) } func (*PieceStore_PieceData) ProtoMessage() {} func (*PieceStore_PieceData) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{2, 0} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{2, 0} } func (m *PieceStore_PieceData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceStore_PieceData.Unmarshal(m, b) @@ -342,7 +350,7 @@ func (m *PieceId) Reset() { *m = PieceId{} } func (m *PieceId) String() string { return proto.CompactTextString(m) } func (*PieceId) ProtoMessage() {} func (*PieceId) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{3} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{3} } func (m *PieceId) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceId.Unmarshal(m, b) @@ -382,7 +390,7 @@ func (m *PieceSummary) Reset() { *m = PieceSummary{} } func (m *PieceSummary) String() string { return proto.CompactTextString(m) } func (*PieceSummary) ProtoMessage() {} func (*PieceSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{4} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{4} } func (m *PieceSummary) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceSummary.Unmarshal(m, b) @@ -426,6 +434,7 @@ func (m *PieceSummary) GetExpirationUnixSec() int64 { type PieceRetrieval struct { Bandwidthallocation *RenterBandwidthAllocation `protobuf:"bytes,1,opt,name=bandwidthallocation,proto3" json:"bandwidthallocation,omitempty"` PieceData *PieceRetrieval_PieceData `protobuf:"bytes,2,opt,name=pieceData,proto3" json:"pieceData,omitempty"` + Authorization *SignedMessage `protobuf:"bytes,3,opt,name=authorization,proto3" json:"authorization,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -435,7 +444,7 @@ func (m *PieceRetrieval) Reset() { *m = PieceRetrieval{} } func (m *PieceRetrieval) String() string { return proto.CompactTextString(m) } func (*PieceRetrieval) ProtoMessage() {} func (*PieceRetrieval) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{5} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{5} } func (m *PieceRetrieval) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceRetrieval.Unmarshal(m, b) @@ -469,6 +478,13 @@ func (m *PieceRetrieval) GetPieceData() *PieceRetrieval_PieceData { return nil } +func (m *PieceRetrieval) GetAuthorization() *SignedMessage { + if m != nil { + return m.Authorization + } + return nil +} + type PieceRetrieval_PieceData struct { Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` @@ -482,7 +498,7 @@ func (m *PieceRetrieval_PieceData) Reset() { *m = PieceRetrieval_PieceDa func (m *PieceRetrieval_PieceData) String() string { return proto.CompactTextString(m) } func (*PieceRetrieval_PieceData) ProtoMessage() {} func (*PieceRetrieval_PieceData) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{5, 0} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{5, 0} } func (m *PieceRetrieval_PieceData) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceRetrieval_PieceData.Unmarshal(m, b) @@ -535,7 +551,7 @@ func (m *PieceRetrievalStream) Reset() { *m = PieceRetrievalStream{} } func (m *PieceRetrievalStream) String() string { return proto.CompactTextString(m) } func (*PieceRetrievalStream) ProtoMessage() {} func (*PieceRetrievalStream) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{6} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{6} } func (m *PieceRetrievalStream) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceRetrievalStream.Unmarshal(m, b) @@ -570,17 +586,18 @@ func (m *PieceRetrievalStream) GetContent() []byte { } type PieceDelete struct { - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Authorization *SignedMessage `protobuf:"bytes,3,opt,name=authorization,proto3" json:"authorization,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *PieceDelete) Reset() { *m = PieceDelete{} } func (m *PieceDelete) String() string { return proto.CompactTextString(m) } func (*PieceDelete) ProtoMessage() {} func (*PieceDelete) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{7} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{7} } func (m *PieceDelete) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceDelete.Unmarshal(m, b) @@ -607,6 +624,13 @@ func (m *PieceDelete) GetId() string { return "" } +func (m *PieceDelete) GetAuthorization() *SignedMessage { + if m != nil { + return m.Authorization + } + return nil +} + type PieceDeleteSummary struct { Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` @@ -618,7 +642,7 @@ func (m *PieceDeleteSummary) Reset() { *m = PieceDeleteSummary{} } func (m *PieceDeleteSummary) String() string { return proto.CompactTextString(m) } func (*PieceDeleteSummary) ProtoMessage() {} func (*PieceDeleteSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{8} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{8} } func (m *PieceDeleteSummary) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceDeleteSummary.Unmarshal(m, b) @@ -657,7 +681,7 @@ func (m *PieceStoreSummary) Reset() { *m = PieceStoreSummary{} } func (m *PieceStoreSummary) String() string { return proto.CompactTextString(m) } func (*PieceStoreSummary) ProtoMessage() {} func (*PieceStoreSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{9} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{9} } func (m *PieceStoreSummary) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_PieceStoreSummary.Unmarshal(m, b) @@ -701,7 +725,7 @@ func (m *StatsReq) Reset() { *m = StatsReq{} } func (m *StatsReq) String() string { return proto.CompactTextString(m) } func (*StatsReq) ProtoMessage() {} func (*StatsReq) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{10} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{10} } func (m *StatsReq) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatsReq.Unmarshal(m, b) @@ -735,7 +759,7 @@ func (m *StatSummary) Reset() { *m = StatSummary{} } func (m *StatSummary) String() string { return proto.CompactTextString(m) } func (*StatSummary) ProtoMessage() {} func (*StatSummary) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{11} + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{11} } func (m *StatSummary) XXX_Unmarshal(b []byte) error { return xxx_messageInfo_StatSummary.Unmarshal(m, b) @@ -783,7 +807,7 @@ func (m *StatSummary) GetAvailableBandwidth() int64 { return 0 } -type SignatureAuth struct { +type SignedMessage struct { Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` Signature []byte `protobuf:"bytes,2,opt,name=signature,proto3" json:"signature,omitempty"` PublicKey []byte `protobuf:"bytes,3,opt,name=publicKey,proto3" json:"publicKey,omitempty"` @@ -792,45 +816,45 @@ type SignatureAuth struct { XXX_sizecache int32 `json:"-"` } -func (m *SignatureAuth) Reset() { *m = SignatureAuth{} } -func (m *SignatureAuth) String() string { return proto.CompactTextString(m) } -func (*SignatureAuth) ProtoMessage() {} -func (*SignatureAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_piecestore_b29c3a3a1a7e53a5, []int{12} +func (m *SignedMessage) Reset() { *m = SignedMessage{} } +func (m *SignedMessage) String() string { return proto.CompactTextString(m) } +func (*SignedMessage) ProtoMessage() {} +func (*SignedMessage) Descriptor() ([]byte, []int) { + return fileDescriptor_piecestore_83d494dbeb442cfc, []int{12} } -func (m *SignatureAuth) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_SignatureAuth.Unmarshal(m, b) +func (m *SignedMessage) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_SignedMessage.Unmarshal(m, b) } -func (m *SignatureAuth) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_SignatureAuth.Marshal(b, m, deterministic) +func (m *SignedMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_SignedMessage.Marshal(b, m, deterministic) } -func (dst *SignatureAuth) XXX_Merge(src proto.Message) { - xxx_messageInfo_SignatureAuth.Merge(dst, src) +func (dst *SignedMessage) XXX_Merge(src proto.Message) { + xxx_messageInfo_SignedMessage.Merge(dst, src) } -func (m *SignatureAuth) XXX_Size() int { - return xxx_messageInfo_SignatureAuth.Size(m) +func (m *SignedMessage) XXX_Size() int { + return xxx_messageInfo_SignedMessage.Size(m) } -func (m *SignatureAuth) XXX_DiscardUnknown() { - xxx_messageInfo_SignatureAuth.DiscardUnknown(m) +func (m *SignedMessage) XXX_DiscardUnknown() { + xxx_messageInfo_SignedMessage.DiscardUnknown(m) } -var xxx_messageInfo_SignatureAuth proto.InternalMessageInfo +var xxx_messageInfo_SignedMessage proto.InternalMessageInfo -func (m *SignatureAuth) GetData() []byte { +func (m *SignedMessage) GetData() []byte { if m != nil { return m.Data } return nil } -func (m *SignatureAuth) GetSignature() []byte { +func (m *SignedMessage) GetSignature() []byte { if m != nil { return m.Signature } return nil } -func (m *SignatureAuth) GetPublicKey() []byte { +func (m *SignedMessage) GetPublicKey() []byte { if m != nil { return m.PublicKey } @@ -854,7 +878,7 @@ func init() { proto.RegisterType((*PieceStoreSummary)(nil), "piecestoreroutes.PieceStoreSummary") proto.RegisterType((*StatsReq)(nil), "piecestoreroutes.StatsReq") proto.RegisterType((*StatSummary)(nil), "piecestoreroutes.StatSummary") - proto.RegisterType((*SignatureAuth)(nil), "piecestoreroutes.SignatureAuth") + proto.RegisterType((*SignedMessage)(nil), "piecestoreroutes.SignedMessage") } // Reference imports to suppress errors if they are not otherwise used. @@ -1128,55 +1152,57 @@ var _PieceStoreRoutes_serviceDesc = grpc.ServiceDesc{ Metadata: "piecestore.proto", } -func init() { proto.RegisterFile("piecestore.proto", fileDescriptor_piecestore_b29c3a3a1a7e53a5) } +func init() { proto.RegisterFile("piecestore.proto", fileDescriptor_piecestore_83d494dbeb442cfc) } -var fileDescriptor_piecestore_b29c3a3a1a7e53a5 = []byte{ - // 737 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x4a, 0xdc, 0x40, - 0x14, 0x36, 0xd9, 0x3f, 0xf7, 0xec, 0x6a, 0x75, 0x14, 0xc9, 0x86, 0xb5, 0x2c, 0x51, 0x64, 0xb1, - 0xb0, 0x14, 0xfb, 0x04, 0xca, 0x42, 0x2b, 0x05, 0x2b, 0x09, 0xde, 0x08, 0x65, 0x99, 0x4d, 0x8e, - 0x3a, 0x90, 0x4d, 0xd2, 0x64, 0x62, 0x57, 0x2f, 0xfb, 0x14, 0x85, 0xde, 0xf6, 0xa6, 0xaf, 0xd1, - 0x57, 0xea, 0x0b, 0x94, 0xcc, 0xe4, 0x67, 0xff, 0xb2, 0xde, 0xb4, 0x77, 0x73, 0xfe, 0xbe, 0xf3, - 0x9d, 0x9f, 0x1c, 0x02, 0x3b, 0x01, 0x43, 0x1b, 0x23, 0xee, 0x87, 0x38, 0x08, 0x42, 0x9f, 0xfb, - 0x64, 0x46, 0x13, 0xfa, 0x31, 0xc7, 0xc8, 0xf8, 0xa3, 0x80, 0x76, 0x4d, 0x9f, 0x30, 0xbc, 0xa0, - 0x9e, 0xf3, 0x95, 0x39, 0xfc, 0xe1, 0xdc, 0x75, 0x7d, 0x9b, 0x72, 0xe6, 0x7b, 0xa4, 0x0b, 0xcd, - 0x88, 0xdd, 0x7b, 0x94, 0xc7, 0x21, 0x6a, 0x4a, 0x4f, 0xe9, 0xb7, 0xcd, 0x42, 0x41, 0x08, 0x54, - 0x1d, 0xca, 0xa9, 0xa6, 0x0a, 0x83, 0x78, 0xeb, 0x3f, 0x15, 0xa8, 0x0e, 0x29, 0xa7, 0x64, 0x1f, - 0x6a, 0x41, 0x02, 0x9b, 0x86, 0x49, 0x81, 0x1c, 0x40, 0x3d, 0x44, 0x8f, 0x63, 0x98, 0x06, 0xa5, - 0x12, 0xe9, 0xc0, 0xe6, 0x84, 0x4e, 0x47, 0x11, 0x7b, 0x46, 0xad, 0xd2, 0x53, 0xfa, 0x15, 0xb3, - 0x31, 0xa1, 0x53, 0x8b, 0x3d, 0x23, 0x19, 0xc0, 0x1e, 0x4e, 0x03, 0x16, 0x0a, 0x46, 0xa3, 0xd8, - 0x63, 0xd3, 0x51, 0x84, 0xb6, 0x56, 0x15, 0x5e, 0xbb, 0x85, 0xe9, 0xc6, 0x63, 0x53, 0x0b, 0x6d, - 0x72, 0x04, 0x5b, 0x11, 0x86, 0x8c, 0xba, 0x23, 0x2f, 0x9e, 0x8c, 0x31, 0xd4, 0x6a, 0x3d, 0xa5, - 0xdf, 0x34, 0xdb, 0x52, 0x79, 0x25, 0x74, 0xc6, 0x6f, 0x05, 0x3a, 0xa6, 0x48, 0xfd, 0x6f, 0xca, - 0x8e, 0xd2, 0xaa, 0x6f, 0x60, 0x47, 0x14, 0x3a, 0xa2, 0x39, 0x9a, 0x00, 0x68, 0x9d, 0x9d, 0x0e, - 0x16, 0x5b, 0x3f, 0x28, 0x6b, 0xbb, 0xf9, 0x4a, 0x60, 0xcc, 0x10, 0xda, 0x87, 0x1a, 0xf7, 0x39, - 0x75, 0x45, 0xce, 0x8a, 0x29, 0x05, 0xe3, 0xbb, 0x0a, 0x70, 0x9d, 0x80, 0x5a, 0x09, 0x28, 0xf9, - 0x0c, 0x7b, 0xe3, 0x0c, 0x6c, 0x29, 0xfd, 0x9b, 0xe5, 0xf4, 0xa5, 0xf5, 0x9b, 0xab, 0x70, 0xc8, - 0x10, 0x9a, 0x02, 0x22, 0xaf, 0xbd, 0x75, 0x76, 0xb2, 0xa2, 0xa6, 0x9c, 0x8f, 0x7c, 0x26, 0x5d, - 0x31, 0x8b, 0x40, 0x1d, 0xa1, 0x99, 0xeb, 0xc9, 0x36, 0xa8, 0xcc, 0x11, 0x04, 0x9b, 0xa6, 0xca, - 0x9c, 0xb2, 0x51, 0xab, 0x65, 0xa3, 0xd6, 0xa0, 0x61, 0xfb, 0x1e, 0x47, 0x8f, 0x8b, 0xa5, 0x69, - 0x9b, 0x99, 0x68, 0x74, 0xa0, 0x21, 0xd2, 0x5c, 0x3a, 0x8b, 0x49, 0x8c, 0x31, 0xb4, 0x25, 0xc9, - 0x78, 0x32, 0xa1, 0xe1, 0xd3, 0x12, 0x09, 0x02, 0x55, 0xb1, 0x86, 0x32, 0xab, 0x78, 0x97, 0x11, - 0xab, 0x94, 0x10, 0x33, 0xbe, 0xa9, 0xb0, 0x2d, 0x92, 0x98, 0xc8, 0x43, 0x86, 0x8f, 0xd4, 0xfd, - 0xdf, 0xd3, 0xf9, 0x90, 0x4e, 0x67, 0x58, 0x4c, 0xe7, 0xb4, 0x64, 0x3a, 0x39, 0xa7, 0xa5, 0x09, - 0x25, 0x4f, 0xfd, 0xfd, 0xba, 0x09, 0xad, 0x6a, 0xce, 0x01, 0xd4, 0xfd, 0xbb, 0xbb, 0x08, 0x79, - 0xda, 0x8f, 0x54, 0x32, 0x86, 0xb0, 0x3f, 0x9f, 0xcf, 0xe2, 0x21, 0xd2, 0x49, 0x8e, 0xa1, 0xcc, - 0x60, 0xcc, 0x4c, 0x52, 0x9d, 0x9f, 0xe4, 0x21, 0xb4, 0x24, 0x1d, 0x74, 0x91, 0xe3, 0xd2, 0x34, - 0x07, 0x40, 0x66, 0xcc, 0xd9, 0x4c, 0x35, 0x68, 0x4c, 0x30, 0x8a, 0xe8, 0x3d, 0xa6, 0xae, 0x99, - 0x68, 0x58, 0xb0, 0x5b, 0xac, 0xe8, 0x8b, 0xee, 0xe4, 0x18, 0xb6, 0xc4, 0xb7, 0x66, 0xa2, 0x8d, - 0xec, 0x11, 0x9d, 0xb4, 0xf0, 0x79, 0xa5, 0x01, 0xb0, 0x69, 0x71, 0xca, 0x23, 0x13, 0xbf, 0x18, - 0xbf, 0x14, 0x68, 0x25, 0x42, 0x86, 0xdd, 0x85, 0x66, 0x1c, 0xa1, 0x63, 0x05, 0xd4, 0xce, 0x4a, - 0x2e, 0x14, 0xe4, 0x04, 0xb6, 0xe9, 0x23, 0x65, 0x2e, 0x1d, 0xbb, 0x28, 0x5d, 0x64, 0x82, 0x05, - 0x6d, 0xc2, 0x23, 0x09, 0xca, 0xd7, 0x21, 0x6d, 0xf5, 0xbc, 0x92, 0x0c, 0x80, 0xe4, 0x71, 0x85, - 0xab, 0xbc, 0x94, 0x2b, 0x2c, 0xc6, 0x08, 0xb6, 0xac, 0xec, 0xac, 0x9d, 0xc7, 0xfc, 0x21, 0x3f, - 0x6d, 0x4a, 0x71, 0xda, 0xe6, 0x8f, 0xa1, 0xba, 0x78, 0x0c, 0xbb, 0xd0, 0x0c, 0xe2, 0xb1, 0xcb, - 0xec, 0x8f, 0xf8, 0x94, 0x7e, 0x84, 0x85, 0xe2, 0xec, 0x47, 0x05, 0x76, 0x8a, 0x76, 0x9b, 0x62, - 0x09, 0xc9, 0x10, 0x6a, 0x42, 0x47, 0x3a, 0x25, 0x0b, 0x7a, 0xe9, 0xe8, 0xaf, 0xcb, 0x2e, 0x8b, - 0xec, 0xaa, 0xb1, 0x41, 0x6e, 0x61, 0x33, 0x5d, 0x2c, 0x24, 0xbd, 0x97, 0x36, 0x5d, 0x3f, 0x79, - 0xc9, 0x43, 0xee, 0xa6, 0xb1, 0xd1, 0x57, 0xde, 0x2a, 0xe4, 0x0a, 0x6a, 0xf2, 0xa4, 0x76, 0xd7, - 0x1d, 0x38, 0xfd, 0x68, 0x9d, 0x35, 0x67, 0xda, 0x57, 0xc8, 0x27, 0xa8, 0xa7, 0xeb, 0x7b, 0x58, - 0x12, 0x22, 0xcd, 0xfa, 0xf1, 0x5a, 0x73, 0x51, 0xfc, 0x30, 0x21, 0x48, 0x79, 0x44, 0xf4, 0xe5, - 0x80, 0x6c, 0x13, 0xf5, 0xc3, 0xd5, 0xb6, 0x1c, 0xe5, 0xa2, 0x7a, 0xab, 0x06, 0xe3, 0x71, 0x5d, - 0xfc, 0x19, 0xbc, 0xfb, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x52, 0x6c, 0xb8, 0x84, 0x2d, 0x08, 0x00, - 0x00, +var fileDescriptor_piecestore_83d494dbeb442cfc = []byte{ + // 772 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x56, 0xdd, 0x4e, 0xdb, 0x48, + 0x14, 0xc6, 0xce, 0x1f, 0x39, 0x49, 0x58, 0x18, 0x10, 0x72, 0xac, 0xb0, 0x1b, 0x19, 0x84, 0x22, + 0x56, 0x8a, 0x56, 0xec, 0x13, 0x2c, 0xca, 0x6a, 0x17, 0x55, 0xa5, 0x68, 0x2c, 0x6e, 0x90, 0xaa, + 0x68, 0x62, 0x1f, 0x60, 0x24, 0xc7, 0x4e, 0xed, 0x31, 0x0d, 0xbc, 0x4a, 0x6f, 0x7b, 0xd3, 0xd7, + 0xe8, 0x5d, 0x9f, 0xa2, 0x0f, 0xd1, 0x17, 0xa8, 0x3c, 0xe3, 0xd8, 0xf9, 0x73, 0xb8, 0xa1, 0x77, + 0x3e, 0x7f, 0xdf, 0xf9, 0xce, 0xcf, 0x9c, 0x04, 0x76, 0x27, 0x1c, 0x1d, 0x8c, 0x44, 0x10, 0x62, + 0x7f, 0x12, 0x06, 0x22, 0x20, 0x73, 0x9a, 0x30, 0x88, 0x05, 0x46, 0xd6, 0x0f, 0x0d, 0x8c, 0x6b, + 0xf6, 0x84, 0xe1, 0x05, 0xf3, 0xdd, 0x8f, 0xdc, 0x15, 0x0f, 0xff, 0x78, 0x5e, 0xe0, 0x30, 0xc1, + 0x03, 0x9f, 0x74, 0xa0, 0x1e, 0xf1, 0x7b, 0x9f, 0x89, 0x38, 0x44, 0x43, 0xeb, 0x6a, 0xbd, 0x26, + 0xcd, 0x15, 0x84, 0x40, 0xd9, 0x65, 0x82, 0x19, 0xba, 0x34, 0xc8, 0x6f, 0xf3, 0xb3, 0x06, 0xe5, + 0x01, 0x13, 0x8c, 0x1c, 0x40, 0x65, 0x92, 0xc0, 0xa6, 0x61, 0x4a, 0x20, 0x87, 0x50, 0x0d, 0xd1, + 0x17, 0x18, 0xa6, 0x41, 0xa9, 0x44, 0xda, 0xb0, 0x3d, 0x66, 0xd3, 0x61, 0xc4, 0x9f, 0xd1, 0x28, + 0x75, 0xb5, 0x5e, 0x89, 0xd6, 0xc6, 0x6c, 0x6a, 0xf3, 0x67, 0x24, 0x7d, 0xd8, 0xc7, 0xe9, 0x84, + 0x87, 0x92, 0xd1, 0x30, 0xf6, 0xf9, 0x74, 0x18, 0xa1, 0x63, 0x94, 0xa5, 0xd7, 0x5e, 0x6e, 0xba, + 0xf1, 0xf9, 0xd4, 0x46, 0x87, 0x1c, 0x43, 0x2b, 0xc2, 0x90, 0x33, 0x6f, 0xe8, 0xc7, 0xe3, 0x11, + 0x86, 0x46, 0xa5, 0xab, 0xf5, 0xea, 0xb4, 0xa9, 0x94, 0x57, 0x52, 0x67, 0x7d, 0xd5, 0xa0, 0x4d, + 0x65, 0xea, 0xd7, 0x29, 0x3b, 0x4a, 0xab, 0xbe, 0x81, 0x5d, 0x59, 0xe8, 0x90, 0x65, 0x68, 0x12, + 0xa0, 0x71, 0x7e, 0xd6, 0x5f, 0x6e, 0x7d, 0xbf, 0xa8, 0xed, 0xf4, 0x37, 0x89, 0x31, 0x47, 0xe8, + 0x00, 0x2a, 0x22, 0x10, 0xcc, 0x93, 0x39, 0x4b, 0x54, 0x09, 0xd6, 0x77, 0x1d, 0xe0, 0x3a, 0x01, + 0xb5, 0x13, 0x50, 0xf2, 0x1e, 0xf6, 0x47, 0x33, 0xb0, 0x95, 0xf4, 0x7f, 0xae, 0xa6, 0x2f, 0xac, + 0x9f, 0xae, 0xc3, 0x21, 0x03, 0xa8, 0x4b, 0x88, 0xac, 0xf6, 0xc6, 0xf9, 0xe9, 0x9a, 0x9a, 0x32, + 0x3e, 0xea, 0x33, 0xe9, 0x0a, 0xcd, 0x03, 0xc9, 0xbf, 0xd0, 0x62, 0xb1, 0x78, 0x08, 0x42, 0xfe, + 0xac, 0xe8, 0x95, 0x24, 0xd2, 0x1f, 0xab, 0x48, 0x36, 0xbf, 0xf7, 0xd1, 0x7d, 0x8b, 0x51, 0xc4, + 0xee, 0x91, 0x2e, 0x46, 0x99, 0x08, 0xf5, 0x0c, 0x9e, 0xec, 0x80, 0xce, 0x5d, 0x59, 0x67, 0x9d, + 0xea, 0xdc, 0x2d, 0xda, 0x18, 0xbd, 0x68, 0x63, 0x0c, 0xa8, 0x39, 0x81, 0x2f, 0xd0, 0x17, 0x92, + 0x4d, 0x93, 0xce, 0x44, 0xab, 0x0d, 0x35, 0x99, 0xe6, 0xd2, 0x5d, 0x4e, 0x62, 0x8d, 0xa0, 0xa9, + 0x6a, 0x8d, 0xc7, 0x63, 0x16, 0x3e, 0xad, 0x90, 0x20, 0x50, 0x96, 0xdb, 0xac, 0xb2, 0xca, 0xef, + 0x22, 0x62, 0xa5, 0x02, 0x62, 0xd6, 0x37, 0x1d, 0x76, 0x64, 0x12, 0x8a, 0x22, 0xe4, 0xf8, 0xc8, + 0xbc, 0x5f, 0x3d, 0xe4, 0xff, 0xd3, 0x21, 0x0f, 0xf2, 0x21, 0x9f, 0x15, 0x0c, 0x39, 0xe3, 0xb4, + 0x32, 0xe8, 0xc1, 0x2b, 0x0e, 0xfa, 0xbf, 0x4d, 0x83, 0x5e, 0xd7, 0xe3, 0x43, 0xa8, 0x06, 0x77, + 0x77, 0x11, 0x8a, 0xb4, 0xad, 0xa9, 0x64, 0x0d, 0xe0, 0x60, 0x91, 0xb6, 0x2d, 0x42, 0x64, 0xe3, + 0x0c, 0x43, 0x9b, 0xc3, 0x98, 0x5b, 0x08, 0x7d, 0x71, 0x21, 0x5c, 0x68, 0x28, 0x3a, 0xe8, 0xa1, + 0xc0, 0x15, 0x42, 0xaf, 0x53, 0xb4, 0xd5, 0x07, 0x32, 0x97, 0x65, 0xb6, 0x61, 0x06, 0xd4, 0xc6, + 0xca, 0x3f, 0xcd, 0x38, 0x13, 0x2d, 0x1b, 0xf6, 0xf2, 0x77, 0xf7, 0xa2, 0x3b, 0x39, 0x81, 0x96, + 0x3c, 0x20, 0x14, 0x1d, 0xe4, 0x8f, 0xe8, 0xa6, 0xfd, 0x5b, 0x54, 0x5a, 0x00, 0xdb, 0xb6, 0x60, + 0x22, 0xa2, 0xf8, 0xc1, 0xfa, 0xa2, 0x41, 0x23, 0x11, 0x66, 0xd8, 0x1d, 0xa8, 0xc7, 0x11, 0xba, + 0xf6, 0x84, 0x39, 0xb3, 0xce, 0xe5, 0x0a, 0x72, 0x0a, 0x3b, 0xec, 0x91, 0x71, 0x8f, 0x8d, 0x3c, + 0x54, 0x2e, 0x2a, 0xc1, 0x92, 0x36, 0xe1, 0x91, 0x04, 0x65, 0xcb, 0x99, 0x4e, 0x6c, 0x51, 0x49, + 0xfa, 0x40, 0xb2, 0xb8, 0xdc, 0x55, 0x9d, 0xff, 0x35, 0x16, 0x6b, 0x08, 0xad, 0x85, 0xe6, 0x66, + 0xf7, 0x5a, 0xcb, 0xef, 0xf5, 0xe2, 0x85, 0xd7, 0x97, 0x2f, 0x7c, 0x07, 0xea, 0x93, 0x78, 0xe4, + 0x71, 0xe7, 0x0d, 0x3e, 0xa5, 0x27, 0x21, 0x57, 0x9c, 0x7f, 0x2a, 0xc1, 0x6e, 0xde, 0x6e, 0x2a, + 0xe7, 0x49, 0x06, 0x50, 0x91, 0x3a, 0xd2, 0x2e, 0x78, 0x2e, 0x97, 0xae, 0xf9, 0x7b, 0xd1, 0xb9, + 0x54, 0x5d, 0xb5, 0xb6, 0xc8, 0x2d, 0x6c, 0xa7, 0xfb, 0x89, 0xa4, 0xfb, 0xd2, 0xbb, 0x33, 0x4f, + 0x5f, 0xf2, 0x50, 0x2b, 0x6e, 0x6d, 0xf5, 0xb4, 0xbf, 0x34, 0x72, 0x05, 0x15, 0xf5, 0x3b, 0xd1, + 0xd9, 0x74, 0xb5, 0xcd, 0xe3, 0x4d, 0xd6, 0x8c, 0x69, 0x4f, 0x23, 0xef, 0xa0, 0x9a, 0xbe, 0x82, + 0xa3, 0x82, 0x10, 0x65, 0x36, 0x4f, 0x36, 0x9a, 0xf3, 0xe2, 0x07, 0x09, 0x41, 0x26, 0x22, 0x62, + 0xae, 0x79, 0x2e, 0xe9, 0x26, 0x9a, 0x47, 0xeb, 0x6d, 0x19, 0xca, 0x45, 0xf9, 0x56, 0x9f, 0x8c, + 0x46, 0x55, 0xf9, 0x77, 0xe7, 0xef, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xd5, 0x30, 0x0c, 0x12, + 0x02, 0x09, 0x00, 0x00, } diff --git a/pkg/pb/piecestore.proto b/pkg/pb/piecestore.proto index 3f6da7a5e..43fc7c5c2 100644 --- a/pkg/pb/piecestore.proto +++ b/pkg/pb/piecestore.proto @@ -49,6 +49,7 @@ message PieceStore { RenterBandwidthAllocation bandwidthallocation = 1; PieceData piecedata = 2; + SignedMessage authorization = 3; } message PieceId { @@ -70,6 +71,7 @@ message PieceRetrieval { RenterBandwidthAllocation bandwidthallocation = 1; PieceData pieceData = 2; + SignedMessage authorization = 3; } message PieceRetrievalStream { @@ -79,6 +81,7 @@ message PieceRetrievalStream { message PieceDelete { string id = 1; + SignedMessage authorization = 3; } message PieceDeleteSummary { @@ -99,7 +102,7 @@ message StatSummary { int64 availableBandwidth = 4; } -message SignatureAuth { +message SignedMessage { bytes data = 1; bytes signature = 2; bytes publicKey = 3; diff --git a/pkg/piecestore/rpc/client/client.go b/pkg/piecestore/rpc/client/client.go index 0692e3ecd..1519a3c05 100644 --- a/pkg/piecestore/rpc/client/client.go +++ b/pkg/piecestore/rpc/client/client.go @@ -38,9 +38,9 @@ var ( // PSClient is an interface describing the functions for interacting with piecestore nodes type PSClient interface { Meta(ctx context.Context, id PieceID) (*pb.PieceSummary, error) - Put(ctx context.Context, id PieceID, data io.Reader, ttl time.Time, ba *pb.PayerBandwidthAllocation) error - Get(ctx context.Context, id PieceID, size int64, ba *pb.PayerBandwidthAllocation) (ranger.Ranger, error) - Delete(ctx context.Context, pieceID PieceID) error + Put(ctx context.Context, id PieceID, data io.Reader, ttl time.Time, ba *pb.PayerBandwidthAllocation, authorization *pb.SignedMessage) error + Get(ctx context.Context, id PieceID, size int64, ba *pb.PayerBandwidthAllocation, authorization *pb.SignedMessage) (ranger.Ranger, error) + Delete(ctx context.Context, pieceID PieceID, authorization *pb.SignedMessage) error Stats(ctx context.Context) (*pb.StatSummary, error) io.Closer } @@ -99,13 +99,16 @@ func (client *Client) Meta(ctx context.Context, id PieceID) (*pb.PieceSummary, e } // Put uploads a Piece to a piece store Server -func (client *Client) Put(ctx context.Context, id PieceID, data io.Reader, ttl time.Time, ba *pb.PayerBandwidthAllocation) error { +func (client *Client) Put(ctx context.Context, id PieceID, data io.Reader, ttl time.Time, ba *pb.PayerBandwidthAllocation, authorization *pb.SignedMessage) error { stream, err := client.route.Store(ctx) if err != nil { return err } - msg := &pb.PieceStore{Piecedata: &pb.PieceStore_PieceData{Id: id.String(), ExpirationUnixSec: ttl.Unix()}} + msg := &pb.PieceStore{ + Piecedata: &pb.PieceStore_PieceData{Id: id.String(), ExpirationUnixSec: ttl.Unix()}, + Authorization: authorization, + } if err = stream.Send(msg); err != nil { if _, closeErr := stream.CloseAndRecv(); closeErr != nil { zap.S().Errorf("error closing stream %s :: %v.Send() = %v", closeErr, stream, closeErr) @@ -128,7 +131,7 @@ func (client *Client) Put(ctx context.Context, id PieceID, data io.Reader, ttl t if err == io.ErrUnexpectedEOF { _ = writer.Close() zap.S().Infof("Node cut from upload due to slow connection. Deleting piece %s...", id) - deleteErr := client.Delete(ctx, id) + deleteErr := client.Delete(ctx, id, authorization) if deleteErr != nil { return deleteErr } @@ -141,18 +144,18 @@ func (client *Client) Put(ctx context.Context, id PieceID, data io.Reader, ttl t } // Get begins downloading a Piece from a piece store Server -func (client *Client) Get(ctx context.Context, id PieceID, size int64, ba *pb.PayerBandwidthAllocation) (ranger.Ranger, error) { +func (client *Client) Get(ctx context.Context, id PieceID, size int64, ba *pb.PayerBandwidthAllocation, authorization *pb.SignedMessage) (ranger.Ranger, error) { stream, err := client.route.Retrieve(ctx) if err != nil { return nil, err } - return PieceRangerSize(client, stream, id, size, ba), nil + return PieceRangerSize(client, stream, id, size, ba, authorization), nil } // Delete a Piece from a piece store Server -func (client *Client) Delete(ctx context.Context, id PieceID) error { - reply, err := client.route.Delete(ctx, &pb.PieceDelete{Id: id.String()}) +func (client *Client) Delete(ctx context.Context, id PieceID, authorization *pb.SignedMessage) error { + reply, err := client.route.Delete(ctx, &pb.PieceDelete{Id: id.String(), Authorization: authorization}) if err != nil { return err } diff --git a/pkg/piecestore/rpc/client/pieceranger.go b/pkg/piecestore/rpc/client/pieceranger.go index 634011f2d..c09a5d9e3 100644 --- a/pkg/piecestore/rpc/client/pieceranger.go +++ b/pkg/piecestore/rpc/client/pieceranger.go @@ -19,27 +19,28 @@ import ( var Error = errs.Class("pieceRanger error") type pieceRanger struct { - c *Client - id PieceID - size int64 - stream pb.PieceStoreRoutes_RetrieveClient - pba *pb.PayerBandwidthAllocation + c *Client + id PieceID + size int64 + stream pb.PieceStoreRoutes_RetrieveClient + pba *pb.PayerBandwidthAllocation + authorization *pb.SignedMessage } // PieceRanger PieceRanger returns a Ranger from a PieceID. -func PieceRanger(ctx context.Context, c *Client, stream pb.PieceStoreRoutes_RetrieveClient, id PieceID, pba *pb.PayerBandwidthAllocation) (ranger.Ranger, error) { +func PieceRanger(ctx context.Context, c *Client, stream pb.PieceStoreRoutes_RetrieveClient, id PieceID, pba *pb.PayerBandwidthAllocation, authorization *pb.SignedMessage) (ranger.Ranger, error) { piece, err := c.Meta(ctx, id) if err != nil { return nil, err } - return &pieceRanger{c: c, id: id, size: piece.Size, stream: stream, pba: pba}, nil + return &pieceRanger{c: c, id: id, size: piece.Size, stream: stream, pba: pba, authorization: authorization}, nil } // PieceRangerSize creates a PieceRanger with known size. // Use it if you know the piece size. This will safe the extra request for // retrieving the piece size from the piece storage. -func PieceRangerSize(c *Client, stream pb.PieceStoreRoutes_RetrieveClient, id PieceID, size int64, pba *pb.PayerBandwidthAllocation) ranger.Ranger { - return &pieceRanger{c: c, id: id, size: size, stream: stream, pba: pba} +func PieceRangerSize(c *Client, stream pb.PieceStoreRoutes_RetrieveClient, id PieceID, size int64, pba *pb.PayerBandwidthAllocation, authorization *pb.SignedMessage) ranger.Ranger { + return &pieceRanger{c: c, id: id, size: size, stream: stream, pba: pba, authorization: authorization} } // Size implements Ranger.Size @@ -63,7 +64,7 @@ func (r *pieceRanger) Range(ctx context.Context, offset, length int64) (io.ReadC } // send piece data - if err := r.stream.Send(&pb.PieceRetrieval{PieceData: &pb.PieceRetrieval_PieceData{Id: r.id.String(), Size: length, Offset: offset}}); err != nil { + if err := r.stream.Send(&pb.PieceRetrieval{PieceData: &pb.PieceRetrieval_PieceData{Id: r.id.String(), Size: length, Offset: offset}, Authorization: r.authorization}); err != nil { return nil, err } diff --git a/pkg/piecestore/rpc/client/pieceranger_test.go b/pkg/piecestore/rpc/client/pieceranger_test.go index de03ec7af..eb2e83d63 100644 --- a/pkg/piecestore/rpc/client/pieceranger_test.go +++ b/pkg/piecestore/rpc/client/pieceranger_test.go @@ -77,7 +77,7 @@ func TestPieceRanger(t *testing.T) { c, err := NewCustomRoute(route, 32*1024, priv) assert.NoError(t, err) - rr, err := PieceRanger(ctx, c, stream, pid, &pb.PayerBandwidthAllocation{}) + rr, err := PieceRanger(ctx, c, stream, pid, &pb.PayerBandwidthAllocation{}, nil) if assert.NoError(t, err, errTag) { assert.Equal(t, tt.size, rr.Size(), errTag) } @@ -148,7 +148,7 @@ func TestPieceRangerSize(t *testing.T) { c, err := NewCustomRoute(route, 32*1024, priv) assert.NoError(t, err) - rr := PieceRangerSize(c, stream, pid, tt.size, &pb.PayerBandwidthAllocation{}) + rr := PieceRangerSize(c, stream, pid, tt.size, &pb.PayerBandwidthAllocation{}, nil) assert.Equal(t, tt.size, rr.Size(), errTag) r, err := rr.Range(ctx, tt.offset, tt.length) if tt.errString != "" { diff --git a/pkg/piecestore/rpc/server/retrieve.go b/pkg/piecestore/rpc/server/retrieve.go index 8314566c7..e5e009d7f 100644 --- a/pkg/piecestore/rpc/server/retrieve.go +++ b/pkg/piecestore/rpc/server/retrieve.go @@ -37,6 +37,11 @@ func (s *Server) Retrieve(stream pb.PieceStoreRoutes_RetrieveServer) (err error) return RetrieveError.New("error receiving piece data") } + authorization := recv.GetAuthorization() + if err := s.verifier(authorization); err != nil { + return err + } + pd := recv.GetPieceData() if pd == nil { return RetrieveError.New("PieceStore message is nil") diff --git a/pkg/piecestore/rpc/server/server.go b/pkg/piecestore/rpc/server/server.go index 9842da4ea..a1c79d84d 100644 --- a/pkg/piecestore/rpc/server/server.go +++ b/pkg/piecestore/rpc/server/server.go @@ -20,6 +20,7 @@ import ( "golang.org/x/net/context" monkit "gopkg.in/spacemonkeygo/monkit.v2" + "storj.io/storj/pkg/auth" "storj.io/storj/pkg/pb" "storj.io/storj/pkg/peertls" pstore "storj.io/storj/pkg/piecestore" @@ -84,6 +85,7 @@ type Server struct { pkey crypto.PrivateKey totalAllocated int64 totalBwAllocated int64 + verifier auth.SignedMessageVerifier } // Initialize -- initializes a server struct @@ -151,7 +153,8 @@ func Initialize(ctx context.Context, config Config, pkey crypto.PrivateKey) (*Se return &Server{DataDir: dataDir, DB: db, pkey: pkey, totalAllocated: allocatedDiskSpace, totalBwAllocated: allocatedBandwidth}, nil } - return &Server{DataDir: dataDir, DB: db, pkey: pkey, totalAllocated: allocatedDiskSpace, totalBwAllocated: allocatedBandwidth}, nil + signatureVerifier := auth.NewSignedMessageVerifier() + return &Server{DataDir: dataDir, DB: db, pkey: pkey, totalAllocated: allocatedDiskSpace, totalBwAllocated: allocatedBandwidth, verifier: signatureVerifier}, nil } // Stop the piececstore node @@ -213,6 +216,11 @@ func (s *Server) Stats(ctx context.Context, in *pb.StatsReq) (*pb.StatSummary, e func (s *Server) Delete(ctx context.Context, in *pb.PieceDelete) (*pb.PieceDeleteSummary, error) { log.Printf("Deleting %s...", in.GetId()) + authorization := in.GetAuthorization() + if err := s.verifier(authorization); err != nil { + return nil, err + } + if err := s.deleteByID(in.GetId()); err != nil { return nil, err } diff --git a/pkg/piecestore/rpc/server/server_test.go b/pkg/piecestore/rpc/server/server_test.go index 1584e1ef2..47f3654d6 100644 --- a/pkg/piecestore/rpc/server/server_test.go +++ b/pkg/piecestore/rpc/server/server_test.go @@ -492,7 +492,10 @@ func newTestServerStruct(t *testing.T) (*Server, func()) { t.Fatalf("failed open psdb: %v", err) } - server := &Server{DataDir: tempDir, DB: psDB} + verifier := func(authorization *pb.SignedMessage) error { + return nil + } + server := &Server{DataDir: tempDir, DB: psDB, verifier: verifier} return server, func() { if serr := server.Stop(ctx); serr != nil { t.Fatal(serr) diff --git a/pkg/piecestore/rpc/server/store.go b/pkg/piecestore/rpc/server/store.go index fb06dd3d5..1bcaa8450 100644 --- a/pkg/piecestore/rpc/server/store.go +++ b/pkg/piecestore/rpc/server/store.go @@ -34,6 +34,11 @@ func (s *Server) Store(reqStream pb.PieceStoreRoutes_StoreServer) (err error) { return StoreError.New("Error receiving Piece metadata") } + authorization := recv.GetAuthorization() + if err := s.verifier(authorization); err != nil { + return err + } + pd := recv.GetPiecedata() if pd == nil { return StoreError.New("PieceStore message is nil") diff --git a/pkg/pointerdb/pdbclient/client.go b/pkg/pointerdb/pdbclient/client.go index a47d3e815..4b242f67f 100644 --- a/pkg/pointerdb/pdbclient/client.go +++ b/pkg/pointerdb/pdbclient/client.go @@ -57,6 +57,8 @@ type Client interface { recursive bool, limit int, metaFlags uint32) ( items []ListItem, more bool, err error) Delete(ctx context.Context, path p.Path) error + + SignedMessage() (*pb.SignedMessage, error) } // NewClient initializes a new pointerdb client @@ -154,8 +156,8 @@ func (pdb *PointerDB) Delete(ctx context.Context, path p.Path) (err error) { return err } -// Auth gets signature auth data from last request -func (pdb *PointerDB) Auth() (*pb.SignatureAuth, error) { +// SignedMessage gets signed message from last request +func (pdb *PointerDB) SignedMessage() (*pb.SignedMessage, error) { signature := pdb.signatureHeader.Get("signature") if signature == nil { return nil, nil @@ -171,5 +173,5 @@ func (pdb *PointerDB) Auth() (*pb.SignatureAuth, error) { return nil, err } - return auth.NewSignatureAuth(decodedSignature, identity) + return auth.NewSignedMessage(decodedSignature, identity) } diff --git a/pkg/pointerdb/pdbclient/client_test.go b/pkg/pointerdb/pdbclient/client_test.go index b65318712..372b1ae88 100644 --- a/pkg/pointerdb/pdbclient/client_test.go +++ b/pkg/pointerdb/pdbclient/client_test.go @@ -302,7 +302,7 @@ func TestDelete(t *testing.T) { } } -func TestAuth(t *testing.T) { +func TestSignedMessage(t *testing.T) { ctx := context.Background() ca, err := provider.NewCA(ctx, 12, 4) assert.NoError(t, err) @@ -324,10 +324,14 @@ func TestAuth(t *testing.T) { peer: peer, } - auth, _ := pointerdb.Auth() + auth, err := pointerdb.SignedMessage() + assert.NoError(t, err) - pk, _ := identity.Leaf.PublicKey.(*ecdsa.PublicKey) - expectedKey, _ := cryptopasta.EncodePublicKey(pk) + pk, ok := identity.Leaf.PublicKey.(*ecdsa.PublicKey) + assert.Equal(t, true, ok) + + expectedKey, err := cryptopasta.EncodePublicKey(pk) + assert.NoError(t, err) assert.Equal(t, expectedKey, auth.GetPublicKey()) assert.Equal(t, identity.ID.Bytes(), auth.GetData()) diff --git a/pkg/pointerdb/pdbclient/mocks/mock_client.go b/pkg/pointerdb/pdbclient/mocks/mock_client.go index 0d1156fc0..8cd9b1327 100644 --- a/pkg/pointerdb/pdbclient/mocks/mock_client.go +++ b/pkg/pointerdb/pdbclient/mocks/mock_client.go @@ -1,18 +1,18 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: storj.io/storj/pkg/pb/pdbclient (interfaces: Client) +// Source: storj.io/storj/pkg/pointerdb/pdbclient (interfaces: Client) // Package mock_pointerdb is a generated GoMock package. package mock_pointerdb import ( context "context" - reflect "reflect" + "reflect" gomock "github.com/golang/mock/gomock" paths "storj.io/storj/pkg/paths" - "storj.io/storj/pkg/pb" - "storj.io/storj/pkg/pointerdb/pdbclient" + pb "storj.io/storj/pkg/pb" + pdbclient "storj.io/storj/pkg/pointerdb/pdbclient" ) // MockClient is a mock of Client interface @@ -88,3 +88,16 @@ func (m *MockClient) Put(arg0 context.Context, arg1 paths.Path, arg2 *pb.Pointer func (mr *MockClientMockRecorder) Put(arg0, arg1, arg2 interface{}) *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockClient)(nil).Put), arg0, arg1, arg2) } + +// SignedMessage mocks base method +func (m *MockClient) SignedMessage() (*pb.SignedMessage, error) { + ret := m.ctrl.Call(m, "SignedMessage") + ret0, _ := ret[0].(*pb.SignedMessage) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// SignedMessage indicates an expected call of SignedMessage +func (mr *MockClientMockRecorder) SignedMessage() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignedMessage", reflect.TypeOf((*MockClient)(nil).SignedMessage)) +} diff --git a/pkg/storage/ec/client.go b/pkg/storage/ec/client.go index fb61a0234..e8fe688c9 100644 --- a/pkg/storage/ec/client.go +++ b/pkg/storage/ec/client.go @@ -27,10 +27,10 @@ var mon = monkit.Package() // Client defines an interface for storing erasure coded data to piece store nodes type Client interface { Put(ctx context.Context, nodes []*pb.Node, rs eestream.RedundancyStrategy, - pieceID client.PieceID, data io.Reader, expiration time.Time) (successfulNodes []*pb.Node, err error) + pieceID client.PieceID, data io.Reader, expiration time.Time, authorization *pb.SignedMessage) (successfulNodes []*pb.Node, err error) Get(ctx context.Context, nodes []*pb.Node, es eestream.ErasureScheme, - pieceID client.PieceID, size int64) (ranger.Ranger, error) - Delete(ctx context.Context, nodes []*pb.Node, pieceID client.PieceID) error + pieceID client.PieceID, size int64, authorization *pb.SignedMessage) (ranger.Ranger, error) + Delete(ctx context.Context, nodes []*pb.Node, pieceID client.PieceID, authorization *pb.SignedMessage) error } type dialer interface { @@ -65,7 +65,7 @@ func NewClient(identity *provider.FullIdentity, transport transport.Client, mbm } func (ec *ecClient) Put(ctx context.Context, nodes []*pb.Node, rs eestream.RedundancyStrategy, - pieceID client.PieceID, data io.Reader, expiration time.Time) (successfulNodes []*pb.Node, err error) { + pieceID client.PieceID, data io.Reader, expiration time.Time, authorization *pb.SignedMessage) (successfulNodes []*pb.Node, err error) { defer mon.Task()(&ctx)(&err) if len(nodes) != rs.TotalCount() { @@ -109,8 +109,7 @@ func (ec *ecClient) Put(ctx context.Context, nodes []*pb.Node, rs eestream.Redun infos <- info{i: i, err: err} return } - - err = ps.Put(ctx, derivedPieceID, readers[i], expiration, &pb.PayerBandwidthAllocation{}) + err = ps.Put(ctx, derivedPieceID, readers[i], expiration, &pb.PayerBandwidthAllocation{}, authorization) // normally the bellow call should be deferred, but doing so fails // randomly the unit tests utils.LogClose(ps) @@ -140,7 +139,7 @@ func (ec *ecClient) Put(ctx context.Context, nodes []*pb.Node, rs eestream.Redun case <-ctx.Done(): err = utils.CombineErrors( Error.New("upload cancelled by user"), - ec.Delete(context.Background(), nodes, pieceID), + ec.Delete(context.Background(), nodes, pieceID, authorization), ) default: } @@ -154,7 +153,7 @@ func (ec *ecClient) Put(ctx context.Context, nodes []*pb.Node, rs eestream.Redun } func (ec *ecClient) Get(ctx context.Context, nodes []*pb.Node, es eestream.ErasureScheme, - pieceID client.PieceID, size int64) (rr ranger.Ranger, err error) { + pieceID client.PieceID, size int64, authorization *pb.SignedMessage) (rr ranger.Ranger, err error) { defer mon.Task()(&ctx)(&err) if len(nodes) != es.TotalCount() { @@ -187,11 +186,12 @@ func (ec *ecClient) Get(ctx context.Context, nodes []*pb.Node, es eestream.Erasu } rr := &lazyPieceRanger{ - dialer: ec.d, - node: n, - id: derivedPieceID, - size: pieceSize, - pba: &pb.PayerBandwidthAllocation{}, + dialer: ec.d, + node: n, + id: derivedPieceID, + size: pieceSize, + pba: &pb.PayerBandwidthAllocation{}, + authorization: authorization, } ch <- rangerInfo{i: i, rr: rr, err: nil} @@ -213,7 +213,7 @@ func (ec *ecClient) Get(ctx context.Context, nodes []*pb.Node, es eestream.Erasu return eestream.Unpad(rr, int(paddedSize-size)) } -func (ec *ecClient) Delete(ctx context.Context, nodes []*pb.Node, pieceID client.PieceID) (err error) { +func (ec *ecClient) Delete(ctx context.Context, nodes []*pb.Node, pieceID client.PieceID, authorization *pb.SignedMessage) (err error) { defer mon.Task()(&ctx)(&err) errs := make(chan error, len(nodes)) @@ -238,7 +238,7 @@ func (ec *ecClient) Delete(ctx context.Context, nodes []*pb.Node, pieceID client errs <- err return } - err = ps.Delete(ctx, derivedPieceID) + err = ps.Delete(ctx, derivedPieceID, authorization) // normally the bellow call should be deferred, but doing so fails // randomly the unit tests utils.LogClose(ps) @@ -300,12 +300,13 @@ func calcPadded(size int64, blockSize int) int64 { } type lazyPieceRanger struct { - ranger ranger.Ranger - dialer dialer - node *pb.Node - id client.PieceID - size int64 - pba *pb.PayerBandwidthAllocation + ranger ranger.Ranger + dialer dialer + node *pb.Node + id client.PieceID + size int64 + pba *pb.PayerBandwidthAllocation + authorization *pb.SignedMessage } // Size implements Ranger.Size @@ -320,7 +321,7 @@ func (lr *lazyPieceRanger) Range(ctx context.Context, offset, length int64) (io. if err != nil { return nil, err } - ranger, err := ps.Get(ctx, lr.id, lr.size, lr.pba) + ranger, err := ps.Get(ctx, lr.id, lr.size, lr.pba, lr.authorization) if err != nil { return nil, err } diff --git a/pkg/storage/ec/client_test.go b/pkg/storage/ec/client_test.go index 01d490450..97c4c31ef 100644 --- a/pkg/storage/ec/client_test.go +++ b/pkg/storage/ec/client_test.go @@ -178,8 +178,8 @@ TestLoop: } ps := NewMockPSClient(ctrl) gomock.InOrder( - ps.EXPECT().Put(gomock.Any(), derivedID, gomock.Any(), ttl, gomock.Any()).Return(errs[n]). - Do(func(ctx context.Context, id client.PieceID, data io.Reader, ttl time.Time, ba *pb.PayerBandwidthAllocation) { + ps.EXPECT().Put(gomock.Any(), derivedID, gomock.Any(), ttl, gomock.Any(), gomock.Any()).Return(errs[n]). + Do(func(ctx context.Context, id client.PieceID, data io.Reader, ttl time.Time, ba *pb.PayerBandwidthAllocation, authorization *pb.SignedMessage) { // simulate that the mocked piece store client is reading the data _, err := io.Copy(ioutil.Discard, data) assert.NoError(t, err, errTag) @@ -195,7 +195,7 @@ TestLoop: r := io.LimitReader(rand.Reader, int64(size)) ec := ecClient{d: &mockDialer{m: m}, mbm: tt.mbm} - successfulNodes, err := ec.Put(ctx, tt.nodes, rs, id, r, ttl) + successfulNodes, err := ec.Put(ctx, tt.nodes, rs, id, r, ttl, nil) if tt.errString != "" { assert.EqualError(t, err, tt.errString, errTag) @@ -269,12 +269,12 @@ TestLoop: continue TestLoop } ps := NewMockPSClient(ctrl) - ps.EXPECT().Get(gomock.Any(), derivedID, int64(size/k), gomock.Any()).Return(ranger.ByteRanger(nil), errs[n]) + ps.EXPECT().Get(gomock.Any(), derivedID, int64(size/k), gomock.Any(), gomock.Any()).Return(ranger.ByteRanger(nil), errs[n]) m[n] = ps } } ec := ecClient{d: &mockDialer{m: m}, mbm: tt.mbm} - rr, err := ec.Get(ctx, tt.nodes, es, id, int64(size)) + rr, err := ec.Get(ctx, tt.nodes, es, id, int64(size), nil) if err == nil { _, err := rr.Range(ctx, 0, 0) assert.NoError(t, err, errTag) @@ -329,7 +329,7 @@ TestLoop: } ps := NewMockPSClient(ctrl) gomock.InOrder( - ps.EXPECT().Delete(gomock.Any(), derivedID).Return(errs[n]), + ps.EXPECT().Delete(gomock.Any(), derivedID, gomock.Any()).Return(errs[n]), ps.EXPECT().Close().Return(nil), ) m[n] = ps @@ -337,7 +337,7 @@ TestLoop: } ec := ecClient{d: &mockDialer{m: m}} - err := ec.Delete(ctx, tt.nodes, id) + err := ec.Delete(ctx, tt.nodes, id, nil) if tt.errString != "" { assert.EqualError(t, err, tt.errString, errTag) diff --git a/pkg/storage/ec/mocks/mock_client.go b/pkg/storage/ec/mocks/mock_client.go index ad261be48..45c428484 100644 --- a/pkg/storage/ec/mocks/mock_client.go +++ b/pkg/storage/ec/mocks/mock_client.go @@ -6,16 +6,14 @@ package mock_ecclient import ( context "context" + gomock "github.com/golang/mock/gomock" io "io" reflect "reflect" - time "time" - - gomock "github.com/golang/mock/gomock" - eestream "storj.io/storj/pkg/eestream" pb "storj.io/storj/pkg/pb" client "storj.io/storj/pkg/piecestore/rpc/client" ranger "storj.io/storj/pkg/ranger" + time "time" ) // MockClient is a mock of Client interface @@ -42,39 +40,39 @@ func (m *MockClient) EXPECT() *MockClientMockRecorder { } // Delete mocks base method -func (m *MockClient) Delete(arg0 context.Context, arg1 []*pb.Node, arg2 client.PieceID) error { - ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2) +func (m *MockClient) Delete(arg0 context.Context, arg1 []*pb.Node, arg2 client.PieceID, arg3 *pb.SignedMessage) error { + ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2, arg3) ret0, _ := ret[0].(error) return ret0 } // Delete indicates an expected call of Delete -func (mr *MockClientMockRecorder) Delete(arg0, arg1, arg2 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClient)(nil).Delete), arg0, arg1, arg2) +func (mr *MockClientMockRecorder) Delete(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockClient)(nil).Delete), arg0, arg1, arg2, arg3) } // Get mocks base method -func (m *MockClient) Get(arg0 context.Context, arg1 []*pb.Node, arg2 eestream.ErasureScheme, arg3 client.PieceID, arg4 int64) (ranger.Ranger, error) { - ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3, arg4) +func (m *MockClient) Get(arg0 context.Context, arg1 []*pb.Node, arg2 eestream.ErasureScheme, arg3 client.PieceID, arg4 int64, arg5 *pb.SignedMessage) (ranger.Ranger, error) { + ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(ranger.Ranger) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get -func (mr *MockClientMockRecorder) Get(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClient)(nil).Get), arg0, arg1, arg2, arg3, arg4) +func (mr *MockClientMockRecorder) Get(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockClient)(nil).Get), arg0, arg1, arg2, arg3, arg4, arg5) } // Put mocks base method -func (m *MockClient) Put(arg0 context.Context, arg1 []*pb.Node, arg2 eestream.RedundancyStrategy, arg3 client.PieceID, arg4 io.Reader, arg5 time.Time) ([]*pb.Node, error) { - ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2, arg3, arg4, arg5) +func (m *MockClient) Put(arg0 context.Context, arg1 []*pb.Node, arg2 eestream.RedundancyStrategy, arg3 client.PieceID, arg4 io.Reader, arg5 time.Time, arg6 *pb.SignedMessage) ([]*pb.Node, error) { + ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2, arg3, arg4, arg5, arg6) ret0, _ := ret[0].([]*pb.Node) ret1, _ := ret[1].(error) return ret0, ret1 } // Put indicates an expected call of Put -func (mr *MockClientMockRecorder) Put(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockClient)(nil).Put), arg0, arg1, arg2, arg3, arg4, arg5) +func (mr *MockClientMockRecorder) Put(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockClient)(nil).Put), arg0, arg1, arg2, arg3, arg4, arg5, arg6) } diff --git a/pkg/storage/ec/psclient_mock_test.go b/pkg/storage/ec/psclient_mock_test.go index cba11b7c9..e66000656 100644 --- a/pkg/storage/ec/psclient_mock_test.go +++ b/pkg/storage/ec/psclient_mock_test.go @@ -58,28 +58,28 @@ func (mr *MockPSClientMockRecorder) Close() *gomock.Call { } // Delete mocks base method -func (m *MockPSClient) Delete(arg0 context.Context, arg1 client.PieceID) error { - ret := m.ctrl.Call(m, "Delete", arg0, arg1) +func (m *MockPSClient) Delete(arg0 context.Context, arg1 client.PieceID, arg2 *pb.SignedMessage) error { + ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2) ret0, _ := ret[0].(error) return ret0 } // Delete indicates an expected call of Delete -func (mr *MockPSClientMockRecorder) Delete(arg0, arg1 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockPSClient)(nil).Delete), arg0, arg1) +func (mr *MockPSClientMockRecorder) Delete(arg0, arg1, arg2 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockPSClient)(nil).Delete), arg0, arg1, arg2) } // Get mocks base method -func (m *MockPSClient) Get(arg0 context.Context, arg1 client.PieceID, arg2 int64, arg3 *pb.PayerBandwidthAllocation) (ranger.Ranger, error) { - ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3) +func (m *MockPSClient) Get(arg0 context.Context, arg1 client.PieceID, arg2 int64, arg3 *pb.PayerBandwidthAllocation, arg4 *pb.SignedMessage) (ranger.Ranger, error) { + ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3, arg4) ret0, _ := ret[0].(ranger.Ranger) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get -func (mr *MockPSClientMockRecorder) Get(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPSClient)(nil).Get), arg0, arg1, arg2, arg3) +func (mr *MockPSClientMockRecorder) Get(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockPSClient)(nil).Get), arg0, arg1, arg2, arg3, arg4) } // Meta mocks base method @@ -96,15 +96,15 @@ func (mr *MockPSClientMockRecorder) Meta(arg0, arg1 interface{}) *gomock.Call { } // Put mocks base method -func (m *MockPSClient) Put(arg0 context.Context, arg1 client.PieceID, arg2 io.Reader, arg3 time.Time, arg4 *pb.PayerBandwidthAllocation) error { - ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2, arg3, arg4) +func (m *MockPSClient) Put(arg0 context.Context, arg1 client.PieceID, arg2 io.Reader, arg3 time.Time, arg4 *pb.PayerBandwidthAllocation, arg5 *pb.SignedMessage) error { + ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2, arg3, arg4, arg5) ret0, _ := ret[0].(error) return ret0 } // Put indicates an expected call of Put -func (mr *MockPSClientMockRecorder) Put(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockPSClient)(nil).Put), arg0, arg1, arg2, arg3, arg4) +func (mr *MockPSClientMockRecorder) Put(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Put", reflect.TypeOf((*MockPSClient)(nil).Put), arg0, arg1, arg2, arg3, arg4, arg5) } // Stats mocks base method diff --git a/pkg/storage/segments/store.go b/pkg/storage/segments/store.go index 6f41b7e51..840d86489 100644 --- a/pkg/storage/segments/store.go +++ b/pkg/storage/segments/store.go @@ -121,8 +121,12 @@ func (s *segmentStore) Put(ctx context.Context, data io.Reader, expiration time. pieceID := client.NewPieceID() sizedReader := SizeReader(peekReader) + signedMessage, err := s.pdb.SignedMessage() + if err != nil { + return Meta{}, Error.Wrap(err) + } // puts file to ecclient - successfulNodes, err := s.ec.Put(ctx, nodes, s.rs, pieceID, sizedReader, expiration) + successfulNodes, err := s.ec.Put(ctx, nodes, s.rs, pieceID, sizedReader, expiration, signedMessage) if err != nil { return Meta{}, Error.Wrap(err) } @@ -211,7 +215,11 @@ func (s *segmentStore) Get(ctx context.Context, path paths.Path) ( return nil, Meta{}, err } - rr, err = s.ec.Get(ctx, nodes, es, pid, pr.GetSize()) + signedMessage, err := s.pdb.SignedMessage() + if err != nil { + return nil, Meta{}, Error.Wrap(err) + } + rr, err = s.ec.Get(ctx, nodes, es, pid, pr.GetSize(), signedMessage) if err != nil { return nil, Meta{}, Error.Wrap(err) } @@ -248,8 +256,12 @@ func (s *segmentStore) Delete(ctx context.Context, path paths.Path) (err error) return Error.Wrap(err) } + signedMessage, err := s.pdb.SignedMessage() + if err != nil { + return Error.Wrap(err) + } // ecclient sends delete request - err = s.ec.Delete(ctx, nodes, pid) + err = s.ec.Delete(ctx, nodes, pid, signedMessage) if err != nil { return Error.Wrap(err) } diff --git a/pkg/storage/segments/store_test.go b/pkg/storage/segments/store_test.go index d8685a5e3..0f37f5396 100644 --- a/pkg/storage/segments/store_test.go +++ b/pkg/storage/segments/store_test.go @@ -117,8 +117,9 @@ func TestSegmentStorePutRemote(t *testing.T) { ).Return([]*pb.Node{ {Id: "im-a-node"}, }, nil), + mockPDB.EXPECT().SignedMessage(), mockEC.EXPECT().Put( - gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ), mockES.EXPECT().RequiredCount().Return(1), mockES.EXPECT().TotalCount().Return(1), @@ -286,8 +287,9 @@ func TestSegmentStoreGetRemote(t *testing.T) { Metadata: tt.metadata, }, nil), mockOC.EXPECT().BulkLookup(gomock.Any(), gomock.Any()), + mockPDB.EXPECT().SignedMessage(), mockEC.EXPECT().Get( - gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ), } gomock.InOrder(calls...) @@ -402,8 +404,9 @@ func TestSegmentStoreDeleteRemote(t *testing.T) { Metadata: tt.metadata, }, nil), mockOC.EXPECT().BulkLookup(gomock.Any(), gomock.Any()), + mockPDB.EXPECT().SignedMessage(), mockEC.EXPECT().Delete( - gomock.Any(), gomock.Any(), gomock.Any(), + gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), ), mockPDB.EXPECT().Delete( gomock.Any(), gomock.Any(),