From 15dd0df18793fe3e3b008f5f2793a88623aa7f3b Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Fri, 10 Jul 2015 11:47:04 -0700 Subject: [PATCH] Support signature v4 at rest --- pkg/donut/bucket.go | 26 +++++++++++++++++++++----- pkg/donut/donut-v1.go | 4 ++-- pkg/donut/donut-v2.go | 1 + 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/pkg/donut/bucket.go b/pkg/donut/bucket.go index 36d897d3b..0cf0d0f49 100644 --- a/pkg/donut/bucket.go +++ b/pkg/donut/bucket.go @@ -31,9 +31,11 @@ import ( "encoding/hex" "encoding/json" + "github.com/minio/minio/pkg/crypto/sha256" "github.com/minio/minio/pkg/crypto/sha512" "github.com/minio/minio/pkg/donut/split" "github.com/minio/minio/pkg/iodine" + "github.com/minio/minio/pkg/utils/atomic" ) const ( @@ -220,7 +222,7 @@ func (b bucket) ReadObject(objectName string) (reader io.ReadCloser, size int64, } // WriteObject - write a new object into bucket -func (b bucket) WriteObject(objectName string, objectData io.Reader, expectedMD5Sum string, metadata map[string]string) (ObjectMetadata, error) { +func (b bucket) WriteObject(objectName string, objectData io.Reader, expectedMD5Sum string, metadata map[string]string, signature *Signature) (ObjectMetadata, error) { b.lock.Lock() defer b.lock.Unlock() if objectName == "" || objectData == nil { @@ -231,6 +233,7 @@ func (b bucket) WriteObject(objectName string, objectData io.Reader, expectedMD5 return ObjectMetadata{}, iodine.New(err, nil) } sumMD5 := md5.New() + sum256 := sha256.New() sum512 := sha512.New() objMetadata := ObjectMetadata{} objMetadata.Version = objectMetadataVersion @@ -238,7 +241,7 @@ func (b bucket) WriteObject(objectName string, objectData io.Reader, expectedMD5 // if total writers are only '1' do not compute erasure switch len(writers) == 1 { case true: - mw := io.MultiWriter(writers[0], sumMD5, sum512) + mw := io.MultiWriter(writers[0], sumMD5, sum256, sum512) totalLength, err := io.Copy(mw, objectData) if err != nil { return ObjectMetadata{}, iodine.New(err, nil) @@ -251,7 +254,7 @@ func (b bucket) WriteObject(objectName string, objectData io.Reader, expectedMD5 return ObjectMetadata{}, iodine.New(err, nil) } // write encoded data with k, m and writers - chunkCount, totalLength, err := b.writeObjectData(k, m, writers, objectData, sumMD5, sum512) + chunkCount, totalLength, err := b.writeObjectData(k, m, writers, objectData, sumMD5, sum256, sum512) if err != nil { return ObjectMetadata{}, iodine.New(err, nil) } @@ -267,7 +270,19 @@ func (b bucket) WriteObject(objectName string, objectData io.Reader, expectedMD5 objMetadata.Object = objectName dataMD5sum := sumMD5.Sum(nil) dataSHA512sum := sum512.Sum(nil) - + if signature != nil { + ok, err := signature.DoesSignatureMatch(hex.EncodeToString(sum256.Sum(nil))) + if err != nil { + return ObjectMetadata{}, iodine.New(err, nil) + } + if !ok { + // purge all writers, when control flow reaches here + for _, writer := range writers { + writer.(*atomic.File).CloseAndPurge() + } + return ObjectMetadata{}, iodine.New(SignatureDoesNotMatch{}, nil) + } + } objMetadata.MD5Sum = hex.EncodeToString(dataMD5sum) objMetadata.SHA512Sum = hex.EncodeToString(dataSHA512sum) @@ -382,7 +397,7 @@ func (b bucket) getDataAndParity(totalWriters int) (k uint8, m uint8, err error) } // writeObjectData - -func (b bucket) writeObjectData(k, m uint8, writers []io.WriteCloser, objectData io.Reader, sumMD5, sum512 hash.Hash) (int, int, error) { +func (b bucket) writeObjectData(k, m uint8, writers []io.WriteCloser, objectData io.Reader, sumMD5, sum256, sum512 hash.Hash) (int, int, error) { encoder, err := newEncoder(k, m, "Cauchy") if err != nil { return 0, 0, iodine.New(err, nil) @@ -396,6 +411,7 @@ func (b bucket) writeObjectData(k, m uint8, writers []io.WriteCloser, objectData totalLength = totalLength + len(chunk.Data) encodedBlocks, _ := encoder.Encode(chunk.Data) sumMD5.Write(chunk.Data) + sum256.Write(chunk.Data) sum512.Write(chunk.Data) for blockIndex, block := range encodedBlocks { _, err := io.Copy(writers[blockIndex], bytes.NewBuffer(block)) diff --git a/pkg/donut/donut-v1.go b/pkg/donut/donut-v1.go index ada4300f6..10b622dd7 100644 --- a/pkg/donut/donut-v1.go +++ b/pkg/donut/donut-v1.go @@ -122,7 +122,7 @@ func (donut API) listObjects(bucket, prefix, marker, delimiter string, maxkeys i } // putObject - put object -func (donut API) putObject(bucket, object, expectedMD5Sum string, reader io.Reader, metadata map[string]string) (ObjectMetadata, error) { +func (donut API) putObject(bucket, object, expectedMD5Sum string, reader io.Reader, metadata map[string]string, signature *Signature) (ObjectMetadata, error) { errParams := map[string]string{ "bucket": bucket, "object": object, @@ -146,7 +146,7 @@ func (donut API) putObject(bucket, object, expectedMD5Sum string, reader io.Read if _, ok := bucketMeta.Buckets[bucket].BucketObjects[object]; ok { return ObjectMetadata{}, iodine.New(ObjectExists{Object: object}, errParams) } - objMetadata, err := donut.buckets[bucket].WriteObject(object, reader, expectedMD5Sum, metadata) + objMetadata, err := donut.buckets[bucket].WriteObject(object, reader, expectedMD5Sum, metadata, signature) if err != nil { return ObjectMetadata{}, iodine.New(err, errParams) } diff --git a/pkg/donut/donut-v2.go b/pkg/donut/donut-v2.go index c43d781a5..d976c1177 100644 --- a/pkg/donut/donut-v2.go +++ b/pkg/donut/donut-v2.go @@ -374,6 +374,7 @@ func (donut API) createObject(bucket, key, contentType, expectedMD5Sum string, s "contentType": contentType, "contentLength": strconv.FormatInt(size, 10), }, + signature, ) if err != nil { return ObjectMetadata{}, iodine.New(err, nil)