diff --git a/pkg/donut/disk/disk_linux.go b/pkg/donut/disk/disk_linux.go index 1e132f45e..362f9c142 100644 --- a/pkg/donut/disk/disk_linux.go +++ b/pkg/donut/disk/disk_linux.go @@ -31,6 +31,7 @@ var fsType2StringMap = map[string]string{ "6969": "NFS", "ef51": "EXT2OLD", "ef53": "EXT4", + "f15f": "ecryptfs", } // getFSType - get filesystem type diff --git a/pkg/donut/donut-v1.go b/pkg/donut/donut-v1.go index ff461f83e..5875b8403 100644 --- a/pkg/donut/donut-v1.go +++ b/pkg/donut/donut-v1.go @@ -619,10 +619,11 @@ func (donut API) makeDonutBucket(bucketName, acl string) *probe.Error { } nodeNumber = nodeNumber + 1 } - metadata, err := donut.getDonutBucketMetadata() + var metadata *AllBuckets + metadata, err = donut.getDonutBucketMetadata() if err != nil { if os.IsNotExist(err.ToGoError()) { - metadata := new(AllBuckets) + metadata = new(AllBuckets) metadata.Buckets = make(map[string]BucketMetadata) metadata.Buckets[bucketName] = bucketMetadata err = donut.setDonutBucketMetadata(metadata) diff --git a/pkg/donut/donut-v1_test.go b/pkg/donut/donut-v1_test.go index ea9957a3a..b845fdea0 100644 --- a/pkg/donut/donut-v1_test.go +++ b/pkg/donut/donut-v1_test.go @@ -74,7 +74,7 @@ func (s *MyDonutSuite) SetUpSuite(c *C) { c.Assert(perr, IsNil) // testing empty donut - buckets, perr := dd.ListBuckets(nil) + buckets, perr := dd.ListBuckets() c.Assert(perr, IsNil) c.Assert(len(buckets), Equals, 0) } @@ -99,7 +99,7 @@ func (s *MyDonutSuite) TestEmptyBucket(c *C) { // check if bucket is empty var resources BucketResourcesMetadata resources.Maxkeys = 1 - objectsMetadata, resources, err := dd.ListObjects("foo1", resources, nil) + objectsMetadata, resources, err := dd.ListObjects("foo1", resources) c.Assert(err, IsNil) c.Assert(len(objectsMetadata), Equals, 0) c.Assert(resources.CommonPrefixes, DeepEquals, []string{}) @@ -113,7 +113,7 @@ func (s *MyDonutSuite) TestMakeBucketAndList(c *C) { c.Assert(err, IsNil) // check bucket exists - buckets, err := dd.ListBuckets(nil) + buckets, err := dd.ListBuckets() c.Assert(err, IsNil) c.Assert(len(buckets), Equals, 5) c.Assert(buckets[0].ACL, Equals, BucketACL("private")) @@ -137,7 +137,7 @@ func (s *MyDonutSuite) TestCreateMultipleBucketsAndList(c *C) { err = dd.MakeBucket("bar1", "private", nil, nil) c.Assert(err, IsNil) - buckets, err := dd.ListBuckets(nil) + buckets, err := dd.ListBuckets() c.Assert(err, IsNil) c.Assert(len(buckets), Equals, 2) @@ -147,7 +147,7 @@ func (s *MyDonutSuite) TestCreateMultipleBucketsAndList(c *C) { err = dd.MakeBucket("foobar1", "private", nil, nil) c.Assert(err, IsNil) - buckets, err = dd.ListBuckets(nil) + buckets, err = dd.ListBuckets() c.Assert(err, IsNil) c.Assert(len(buckets), Equals, 3) @@ -205,7 +205,7 @@ func (s *MyDonutSuite) TestNewObjectCanBeWritten(c *C) { c.Assert(size, Equals, int64(len(data))) c.Assert(buffer.Bytes(), DeepEquals, []byte(data)) - actualMetadata, err = dd.GetObjectMetadata("foo", "obj", nil) + actualMetadata, err = dd.GetObjectMetadata("foo", "obj") c.Assert(err, IsNil) c.Assert(hex.EncodeToString(hasher.Sum(nil)), Equals, actualMetadata.MD5Sum) c.Assert(int64(len(data)), Equals, actualMetadata.Size) @@ -244,7 +244,7 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "o" resources.Delimiter = "1" resources.Maxkeys = 10 - objectsMetadata, resources, err := dd.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err := dd.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.CommonPrefixes[0], Equals, "obj1") @@ -253,7 +253,7 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "" resources.Delimiter = "1" resources.Maxkeys = 10 - objectsMetadata, resources, err = dd.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err = dd.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(objectsMetadata[0].Object, Equals, "obj2") c.Assert(resources.IsTruncated, Equals, false) @@ -263,7 +263,7 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "o" resources.Delimiter = "" resources.Maxkeys = 10 - objectsMetadata, resources, err = dd.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err = dd.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(resources.IsTruncated, Equals, false) c.Assert(objectsMetadata[0].Object, Equals, "obj1") @@ -283,7 +283,7 @@ func (s *MyDonutSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "o" resources.Delimiter = "" resources.Maxkeys = 2 - objectsMetadata, resources, err = dd.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err = dd.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(resources.IsTruncated, Equals, true) c.Assert(len(objectsMetadata), Equals, 2) diff --git a/pkg/donut/donut-v2.go b/pkg/donut/donut-v2.go index 11a0b4803..77d0e2ffc 100644 --- a/pkg/donut/donut-v2.go +++ b/pkg/donut/donut-v2.go @@ -205,20 +205,10 @@ func (donut API) GetObject(w io.Writer, bucket string, object string, start, len } // GetBucketMetadata - -func (donut API) GetBucketMetadata(bucket string, signature *signv4.Signature) (BucketMetadata, *probe.Error) { +func (donut API) GetBucketMetadata(bucket string) (BucketMetadata, *probe.Error) { donut.lock.Lock() defer donut.lock.Unlock() - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return BucketMetadata{}, err.Trace() - } - if !ok { - return BucketMetadata{}, probe.NewError(signv4.DoesNotMatch{}) - } - } - if !IsValidBucket(bucket) { return BucketMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket}) } @@ -238,20 +228,10 @@ func (donut API) GetBucketMetadata(bucket string, signature *signv4.Signature) ( } // SetBucketMetadata - -func (donut API) SetBucketMetadata(bucket string, metadata map[string]string, signature *signv4.Signature) *probe.Error { +func (donut API) SetBucketMetadata(bucket string, metadata map[string]string) *probe.Error { donut.lock.Lock() defer donut.lock.Unlock() - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return err.Trace() - } - if !ok { - return probe.NewError(signv4.DoesNotMatch{}) - } - } - if !IsValidBucket(bucket) { return probe.NewError(BucketNameInvalid{Bucket: bucket}) } @@ -487,20 +467,10 @@ func (donut API) MakeBucket(bucketName, acl string, location io.Reader, signatur } // ListObjects - list objects from cache -func (donut API) ListObjects(bucket string, resources BucketResourcesMetadata, signature *signv4.Signature) ([]ObjectMetadata, BucketResourcesMetadata, *probe.Error) { +func (donut API) ListObjects(bucket string, resources BucketResourcesMetadata) ([]ObjectMetadata, BucketResourcesMetadata, *probe.Error) { donut.lock.Lock() defer donut.lock.Unlock() - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return nil, BucketResourcesMetadata{}, err.Trace() - } - if !ok { - return nil, BucketResourcesMetadata{}, probe.NewError(signv4.DoesNotMatch{}) - } - } - if !IsValidBucket(bucket) { return nil, BucketResourcesMetadata{IsTruncated: false}, probe.NewError(BucketNameInvalid{Bucket: bucket}) } @@ -590,20 +560,10 @@ func (b byBucketName) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b byBucketName) Less(i, j int) bool { return b[i].Name < b[j].Name } // ListBuckets - List buckets from cache -func (donut API) ListBuckets(signature *signv4.Signature) ([]BucketMetadata, *probe.Error) { +func (donut API) ListBuckets() ([]BucketMetadata, *probe.Error) { donut.lock.Lock() defer donut.lock.Unlock() - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return nil, err.Trace() - } - if !ok { - return nil, probe.NewError(signv4.DoesNotMatch{}) - } - } - var results []BucketMetadata if len(donut.config.NodeDiskMap) > 0 { buckets, err := donut.listBuckets() @@ -624,30 +584,10 @@ func (donut API) ListBuckets(signature *signv4.Signature) ([]BucketMetadata, *pr } // GetObjectMetadata - get object metadata from cache -func (donut API) GetObjectMetadata(bucket, key string, signature *signv4.Signature) (ObjectMetadata, *probe.Error) { +func (donut API) GetObjectMetadata(bucket, key string) (ObjectMetadata, *probe.Error) { donut.lock.Lock() defer donut.lock.Unlock() - if signature != nil { - if signature.Presigned { - ok, err := signature.DoesPresignedSignatureMatch() - if err != nil { - return ObjectMetadata{}, err.Trace() - } - if !ok { - return ObjectMetadata{}, probe.NewError(signv4.DoesNotMatch{}) - } - } else { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return ObjectMetadata{}, err.Trace() - } - if !ok { - return ObjectMetadata{}, probe.NewError(signv4.DoesNotMatch{}) - } - } - } - // check if bucket exists if !IsValidBucket(bucket) { return ObjectMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket}) diff --git a/pkg/donut/donut-v2_test.go b/pkg/donut/donut-v2_test.go index 94b42c465..7474cc25c 100644 --- a/pkg/donut/donut-v2_test.go +++ b/pkg/donut/donut-v2_test.go @@ -49,7 +49,7 @@ func (s *MyCacheSuite) SetUpSuite(c *C) { // testing empty cache var buckets []BucketMetadata - buckets, perr := dc.ListBuckets(nil) + buckets, perr := dc.ListBuckets() c.Assert(perr, IsNil) c.Assert(len(buckets), Equals, 0) } @@ -74,7 +74,7 @@ func (s *MyCacheSuite) TestEmptyBucket(c *C) { // check if bucket is empty var resources BucketResourcesMetadata resources.Maxkeys = 1 - objectsMetadata, resources, err := dc.ListObjects("foo1", resources, nil) + objectsMetadata, resources, err := dc.ListObjects("foo1", resources) c.Assert(err, IsNil) c.Assert(len(objectsMetadata), Equals, 0) c.Assert(resources.CommonPrefixes, DeepEquals, []string{}) @@ -88,7 +88,7 @@ func (s *MyCacheSuite) TestMakeBucketAndList(c *C) { c.Assert(err, IsNil) // check bucket exists - buckets, err := dc.ListBuckets(nil) + buckets, err := dc.ListBuckets() c.Assert(err, IsNil) c.Assert(len(buckets), Equals, 5) c.Assert(buckets[0].ACL, Equals, BucketACL("private")) @@ -112,7 +112,7 @@ func (s *MyCacheSuite) TestCreateMultipleBucketsAndList(c *C) { err = dc.MakeBucket("bar1", "private", nil, nil) c.Assert(err, IsNil) - buckets, err := dc.ListBuckets(nil) + buckets, err := dc.ListBuckets() c.Assert(err, IsNil) c.Assert(len(buckets), Equals, 2) @@ -122,7 +122,7 @@ func (s *MyCacheSuite) TestCreateMultipleBucketsAndList(c *C) { err = dc.MakeBucket("foobar1", "private", nil, nil) c.Assert(err, IsNil) - buckets, err = dc.ListBuckets(nil) + buckets, err = dc.ListBuckets() c.Assert(err, IsNil) c.Assert(len(buckets), Equals, 3) @@ -180,7 +180,7 @@ func (s *MyCacheSuite) TestNewObjectCanBeWritten(c *C) { c.Assert(size, Equals, int64(len(data))) c.Assert(buffer.Bytes(), DeepEquals, []byte(data)) - actualMetadata, err = dc.GetObjectMetadata("foo", "obj", nil) + actualMetadata, err = dc.GetObjectMetadata("foo", "obj") c.Assert(err, IsNil) c.Assert(hex.EncodeToString(hasher.Sum(nil)), Equals, actualMetadata.MD5Sum) c.Assert(int64(len(data)), Equals, actualMetadata.Size) @@ -219,7 +219,7 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "o" resources.Delimiter = "1" resources.Maxkeys = 10 - objectsMetadata, resources, err := dc.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err := dc.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(resources.IsTruncated, Equals, false) c.Assert(resources.CommonPrefixes[0], Equals, "obj1") @@ -228,7 +228,7 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "" resources.Delimiter = "1" resources.Maxkeys = 10 - objectsMetadata, resources, err = dc.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err = dc.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(objectsMetadata[0].Object, Equals, "obj2") c.Assert(resources.IsTruncated, Equals, false) @@ -238,7 +238,7 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "o" resources.Delimiter = "" resources.Maxkeys = 10 - objectsMetadata, resources, err = dc.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err = dc.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(resources.IsTruncated, Equals, false) c.Assert(objectsMetadata[0].Object, Equals, "obj1") @@ -258,7 +258,7 @@ func (s *MyCacheSuite) TestMultipleNewObjects(c *C) { resources.Prefix = "o" resources.Delimiter = "" resources.Maxkeys = 2 - objectsMetadata, resources, err = dc.ListObjects("foo5", resources, nil) + objectsMetadata, resources, err = dc.ListObjects("foo5", resources) c.Assert(err, IsNil) c.Assert(resources.IsTruncated, Equals, true) c.Assert(len(objectsMetadata), Equals, 2) diff --git a/pkg/donut/interfaces.go b/pkg/donut/interfaces.go index b04790e12..bbf17ca8e 100644 --- a/pkg/donut/interfaces.go +++ b/pkg/donut/interfaces.go @@ -34,17 +34,17 @@ type Interface interface { // CloudStorage is a donut cloud storage interface type CloudStorage interface { // Storage service operations - GetBucketMetadata(bucket string, signature *signv4.Signature) (BucketMetadata, *probe.Error) - SetBucketMetadata(bucket string, metadata map[string]string, signature *signv4.Signature) *probe.Error - ListBuckets(signature *signv4.Signature) ([]BucketMetadata, *probe.Error) + GetBucketMetadata(bucket string) (BucketMetadata, *probe.Error) + SetBucketMetadata(bucket string, metadata map[string]string) *probe.Error + ListBuckets() ([]BucketMetadata, *probe.Error) MakeBucket(bucket string, ACL string, location io.Reader, signature *signv4.Signature) *probe.Error // Bucket operations - ListObjects(string, BucketResourcesMetadata, *signv4.Signature) ([]ObjectMetadata, BucketResourcesMetadata, *probe.Error) + ListObjects(string, BucketResourcesMetadata) ([]ObjectMetadata, BucketResourcesMetadata, *probe.Error) // Object operations GetObject(w io.Writer, bucket, object string, start, length int64) (int64, *probe.Error) - GetObjectMetadata(bucket, object string, signature *signv4.Signature) (ObjectMetadata, *probe.Error) + GetObjectMetadata(bucket, object string) (ObjectMetadata, *probe.Error) // bucket, object, expectedMD5Sum, size, reader, metadata, signature CreateObject(string, string, string, int64, io.Reader, map[string]string, *signv4.Signature) (ObjectMetadata, *probe.Error) @@ -53,12 +53,12 @@ type CloudStorage interface { // Multipart API type Multipart interface { - NewMultipartUpload(bucket, key, contentType string, signature *signv4.Signature) (string, *probe.Error) - AbortMultipartUpload(bucket, key, uploadID string, signature *signv4.Signature) *probe.Error + NewMultipartUpload(bucket, key, contentType string) (string, *probe.Error) + AbortMultipartUpload(bucket, key, uploadID string) *probe.Error CreateObjectPart(string, string, string, int, string, string, int64, io.Reader, *signv4.Signature) (string, *probe.Error) CompleteMultipartUpload(bucket, key, uploadID string, data io.Reader, signature *signv4.Signature) (ObjectMetadata, *probe.Error) - ListMultipartUploads(string, BucketMultipartResourcesMetadata, *signv4.Signature) (BucketMultipartResourcesMetadata, *probe.Error) - ListObjectParts(string, string, ObjectResourcesMetadata, *signv4.Signature) (ObjectResourcesMetadata, *probe.Error) + ListMultipartUploads(string, BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, *probe.Error) + ListObjectParts(string, string, ObjectResourcesMetadata) (ObjectResourcesMetadata, *probe.Error) } // Management is a donut management system interface diff --git a/pkg/donut/multipart.go b/pkg/donut/multipart.go index 4d8c80339..0dc2826da 100644 --- a/pkg/donut/multipart.go +++ b/pkg/donut/multipart.go @@ -41,7 +41,7 @@ import ( /// V2 API functions // NewMultipartUpload - initiate a new multipart session -func (donut API) NewMultipartUpload(bucket, key, contentType string, signature *signv4.Signature) (string, *probe.Error) { +func (donut API) NewMultipartUpload(bucket, key, contentType string) (string, *probe.Error) { donut.lock.Lock() defer donut.lock.Unlock() @@ -51,15 +51,6 @@ func (donut API) NewMultipartUpload(bucket, key, contentType string, signature * if !IsValidObjectName(key) { return "", probe.NewError(ObjectNameInvalid{Object: key}) } - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return "", err.Trace() - } - if !ok { - return "", probe.NewError(signv4.DoesNotMatch{}) - } - } // if len(donut.config.NodeDiskMap) > 0 { // return donut.newMultipartUpload(bucket, key, contentType) // } @@ -89,7 +80,7 @@ func (donut API) NewMultipartUpload(bucket, key, contentType string, signature * } // AbortMultipartUpload - abort an incomplete multipart session -func (donut API) AbortMultipartUpload(bucket, key, uploadID string, signature *signv4.Signature) *probe.Error { +func (donut API) AbortMultipartUpload(bucket, key, uploadID string) *probe.Error { donut.lock.Lock() defer donut.lock.Unlock() @@ -99,15 +90,6 @@ func (donut API) AbortMultipartUpload(bucket, key, uploadID string, signature *s if !IsValidObjectName(key) { return probe.NewError(ObjectNameInvalid{Object: key}) } - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return err.Trace() - } - if !ok { - return probe.NewError(signv4.DoesNotMatch{}) - } - } // TODO: multipart support for donut is broken, since we haven't finalized the format in which // it can be stored, disabling this for now until we get the underlying layout stable. // @@ -381,21 +363,11 @@ func (a byKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a byKey) Less(i, j int) bool { return a[i].Key < a[j].Key } // ListMultipartUploads - list incomplete multipart sessions for a given bucket -func (donut API) ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata, signature *signv4.Signature) (BucketMultipartResourcesMetadata, *probe.Error) { +func (donut API) ListMultipartUploads(bucket string, resources BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, *probe.Error) { // TODO handle delimiter, low priority donut.lock.Lock() defer donut.lock.Unlock() - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return BucketMultipartResourcesMetadata{}, err.Trace() - } - if !ok { - return BucketMultipartResourcesMetadata{}, probe.NewError(signv4.DoesNotMatch{}) - } - } - if !IsValidBucket(bucket) { return BucketMultipartResourcesMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket}) } @@ -466,21 +438,11 @@ func (a partNumber) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a partNumber) Less(i, j int) bool { return a[i].PartNumber < a[j].PartNumber } // ListObjectParts - list parts from incomplete multipart session for a given object -func (donut API) ListObjectParts(bucket, key string, resources ObjectResourcesMetadata, signature *signv4.Signature) (ObjectResourcesMetadata, *probe.Error) { +func (donut API) ListObjectParts(bucket, key string, resources ObjectResourcesMetadata) (ObjectResourcesMetadata, *probe.Error) { // Verify upload id donut.lock.Lock() defer donut.lock.Unlock() - if signature != nil { - ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") - if err != nil { - return ObjectResourcesMetadata{}, err.Trace() - } - if !ok { - return ObjectResourcesMetadata{}, probe.NewError(signv4.DoesNotMatch{}) - } - } - if !IsValidBucket(bucket) { return ObjectResourcesMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket}) } diff --git a/server-api-bucket-handlers.go b/server-api-bucket-handlers.go index 735f35bc5..52e9ecae8 100644 --- a/server-api-bucket-handlers.go +++ b/server-api-bucket-handlers.go @@ -29,7 +29,7 @@ func (api API) isValidOp(w http.ResponseWriter, req *http.Request) bool { vars := mux.Vars(req) bucket := vars["bucket"] - bucketMetadata, err := api.Donut.GetBucketMetadata(bucket, nil) + bucketMetadata, err := api.Donut.GetBucketMetadata(bucket) if err != nil { errorIf(err.Trace(), "GetBucketMetadata failed.", nil) switch err.ToGoError().(type) { @@ -94,24 +94,10 @@ func (api API) ListMultipartUploadsHandler(w http.ResponseWriter, req *http.Requ vars := mux.Vars(req) bucket := vars["bucket"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - resources, err := api.Donut.ListMultipartUploads(bucket, resources, signature) + resources, err := api.Donut.ListMultipartUploads(bucket, resources) if err != nil { errorIf(err.Trace(), "ListMultipartUploads failed.", nil) switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNotFound: writeErrorResponse(w, req, NoSuchBucket, req.URL.Path) default: @@ -165,19 +151,7 @@ func (api API) ListObjectsHandler(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) bucket := vars["bucket"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - objects, resources, err := api.Donut.ListObjects(bucket, resources, signature) + objects, resources, err := api.Donut.ListObjects(bucket, resources) if err == nil { // generate response response := generateListObjectsResponse(bucket, objects, resources) @@ -189,8 +163,6 @@ func (api API) ListObjectsHandler(w http.ResponseWriter, req *http.Request) { return } switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNameInvalid: writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketNotFound: @@ -226,19 +198,7 @@ func (api API) ListBucketsHandler(w http.ResponseWriter, req *http.Request) { // return // } - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - buckets, err := api.Donut.ListBuckets(signature) + buckets, err := api.Donut.ListBuckets() if err == nil { // generate response response := generateListBucketsResponse(buckets) @@ -249,13 +209,8 @@ func (api API) ListBucketsHandler(w http.ResponseWriter, req *http.Request) { w.Write(encodedSuccessResponse) return } - switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) - default: - errorIf(err.Trace(), "ListBuckets failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - } + errorIf(err.Trace(), "ListBuckets failed.", nil) + writeErrorResponse(w, req, InternalError, req.URL.Path) } // PutBucketHandler - PUT Bucket @@ -402,8 +357,6 @@ func (api API) PostPolicyBucketHandler(w http.ResponseWriter, req *http.Request) writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) case donut.BadDigest: writeErrorResponse(w, req, BadDigest, req.URL.Path) - case signv4.MissingDateHeader: - writeErrorResponse(w, req, RequestTimeTooSkewed, req.URL.Path) case signv4.DoesNotMatch: writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.IncompleteBody: @@ -444,19 +397,7 @@ func (api API) PutBucketACLHandler(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) bucket := vars["bucket"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - err := api.Donut.SetBucketMetadata(bucket, map[string]string{"acl": getACLTypeString(aclType)}, signature) + err := api.Donut.SetBucketMetadata(bucket, map[string]string{"acl": getACLTypeString(aclType)}) if err != nil { errorIf(err.Trace(), "PutBucketACL failed.", nil) switch err.ToGoError().(type) { @@ -493,19 +434,7 @@ func (api API) HeadBucketHandler(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) bucket := vars["bucket"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - _, err := api.Donut.GetBucketMetadata(bucket, signature) + _, err := api.Donut.GetBucketMetadata(bucket) if err != nil { errorIf(err.Trace(), "GetBucketMetadata failed.", nil) switch err.ToGoError().(type) { diff --git a/server-api-generic-handlers.go b/server-api-generic-handlers.go index 74b2b3641..933ddc05c 100644 --- a/server-api-generic-handlers.go +++ b/server-api-generic-handlers.go @@ -21,7 +21,6 @@ import ( "net/http" "time" - "github.com/minio/minio/pkg/auth" "github.com/rs/cors" ) @@ -99,47 +98,6 @@ func (h timeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.handler.ServeHTTP(w, r) } -// ValidateAuthHeaderHandler - validate auth header handler is wrapper handler used -// for request validation with authorization header. Current authorization layer -// supports S3's standard HMAC based signature request. -func ValidateAuthHeaderHandler(h http.Handler) http.Handler { - return validateAuthHandler{h} -} - -// validate auth header handler ServeHTTP() wrapper -func (h validateAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - accessKeyID, err := stripAccessKeyID(r.Header.Get("Authorization")) - switch err.ToGoError() { - case errInvalidRegion: - writeErrorResponse(w, r, AuthorizationHeaderMalformed, r.URL.Path) - return - case errAccessKeyIDInvalid: - writeErrorResponse(w, r, InvalidAccessKeyID, r.URL.Path) - return - case nil: - // load auth config - authConfig, err := auth.LoadConfig() - if err != nil { - writeErrorResponse(w, r, InternalError, r.URL.Path) - return - } - // Access key not found - for _, user := range authConfig.Users { - if user.AccessKeyID == accessKeyID { - h.handler.ServeHTTP(w, r) - return - } - } - writeErrorResponse(w, r, InvalidAccessKeyID, r.URL.Path) - return - // All other errors for now, serve them - default: - // control reaches here, we should just send the request up the stack - internally - // individual calls will validate themselves against un-authenticated requests - h.handler.ServeHTTP(w, r) - } -} - // CorsHandler handler for CORS (Cross Origin Resource Sharing) func CorsHandler(h http.Handler) http.Handler { return cors.Default().Handler(h) diff --git a/server-api-object-handlers.go b/server-api-object-handlers.go index 2e9f385b4..6b89c5f68 100644 --- a/server-api-object-handlers.go +++ b/server-api-object-handlers.go @@ -53,40 +53,10 @@ func (api API) GetObjectHandler(w http.ResponseWriter, req *http.Request) { bucket = vars["bucket"] object = vars["object"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } else { - if _, ok := req.URL.Query()["X-Amz-Credential"]; ok { - var err *probe.Error - signature, err = initPresignedSignatureV4(req) - if err != nil { - switch err.ToGoError() { - case errAccessKeyIDInvalid: - errorIf(err.Trace(), "Invalid access key id requested.", nil) - writeErrorResponse(w, req, InvalidAccessKeyID, req.URL.Path) - return - default: - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - } - } - metadata, err := api.Donut.GetObjectMetadata(bucket, object, signature) + metadata, err := api.Donut.GetObjectMetadata(bucket, object) if err != nil { errorIf(err.Trace(), "GetObject failed.", nil) switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNameInvalid: writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketNotFound: @@ -135,24 +105,10 @@ func (api API) HeadObjectHandler(w http.ResponseWriter, req *http.Request) { bucket = vars["bucket"] object = vars["object"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - metadata, err := api.Donut.GetObjectMetadata(bucket, object, signature) + metadata, err := api.Donut.GetObjectMetadata(bucket, object) if err != nil { errorIf(err.Trace(), "GetObjectMetadata failed.", nil) switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.BucketNameInvalid: writeErrorResponse(w, req, InvalidBucketName, req.URL.Path) case donut.BucketNotFound: @@ -299,24 +255,10 @@ func (api API) NewMultipartUploadHandler(w http.ResponseWriter, req *http.Reques bucket = vars["bucket"] object = vars["object"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - uploadID, err := api.Donut.NewMultipartUpload(bucket, object, req.Header.Get("Content-Type"), signature) + uploadID, err := api.Donut.NewMultipartUpload(bucket, object, req.Header.Get("Content-Type")) if err != nil { errorIf(err.Trace(), "NewMultipartUpload failed.", nil) switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.ObjectExists: writeErrorResponse(w, req, MethodNotAllowed, req.URL.Path) default: @@ -455,24 +397,10 @@ func (api API) AbortMultipartUploadHandler(w http.ResponseWriter, req *http.Requ objectResourcesMetadata := getObjectResources(req.URL.Query()) - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - err := api.Donut.AbortMultipartUpload(bucket, object, objectResourcesMetadata.UploadID, signature) + err := api.Donut.AbortMultipartUpload(bucket, object, objectResourcesMetadata.UploadID) if err != nil { errorIf(err.Trace(), "AbortMutlipartUpload failed.", nil) switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.InvalidUploadID: writeErrorResponse(w, req, NoSuchUpload, req.URL.Path) default: @@ -516,24 +444,10 @@ func (api API) ListObjectPartsHandler(w http.ResponseWriter, req *http.Request) bucket := vars["bucket"] object := vars["object"] - var signature *signv4.Signature - if _, ok := req.Header["Authorization"]; ok { - // Init signature V4 verification - var err *probe.Error - signature, err = initSignatureV4(req) - if err != nil { - errorIf(err.Trace(), "Initializing signature v4 failed.", nil) - writeErrorResponse(w, req, InternalError, req.URL.Path) - return - } - } - - objectResourcesMetadata, err := api.Donut.ListObjectParts(bucket, object, objectResourcesMetadata, signature) + objectResourcesMetadata, err := api.Donut.ListObjectParts(bucket, object, objectResourcesMetadata) if err != nil { errorIf(err.Trace(), "ListObjectParts failed.", nil) switch err.ToGoError().(type) { - case signv4.DoesNotMatch: - writeErrorResponse(w, req, SignatureDoesNotMatch, req.URL.Path) case donut.InvalidUploadID: writeErrorResponse(w, req, NoSuchUpload, req.URL.Path) default: diff --git a/server-api-signature-handler.go b/server-api-signature-handler.go new file mode 100644 index 000000000..b90943203 --- /dev/null +++ b/server-api-signature-handler.go @@ -0,0 +1,99 @@ +package main + +import ( + "net/http" + + "github.com/minio/minio/pkg/probe" + signv4 "github.com/minio/minio/pkg/signature" +) + +type signatureHandler struct { + handler http.Handler +} + +// SignatureHandler to validate authorization header for the incoming request. +func SignatureHandler(h http.Handler) http.Handler { + return signatureHandler{h} +} + +func isRequestSignatureV4(req *http.Request) bool { + if _, ok := req.Header["Authorization"]; ok { + return ok + } + return false +} + +func isRequestPresignedSignatureV4(req *http.Request) bool { + if _, ok := req.URL.Query()["X-Amz-Credential"]; ok { + return ok + } + return false +} + +func (s signatureHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + var signature *signv4.Signature + if isRequestSignatureV4(r) { + // If the request is not a PUT method handle the verification here. + // For PUT and POST requests with payload, send the call upwards for verification + if r.Method != "PUT" && r.Method != "POST" { + // Init signature V4 verification + var err *probe.Error + signature, err = initSignatureV4(r) + if err != nil { + switch err.ToGoError() { + case errInvalidRegion: + errorIf(err.Trace(), "Unknown region in authorization header.", nil) + writeErrorResponse(w, r, AuthorizationHeaderMalformed, r.URL.Path) + return + case errAccessKeyIDInvalid: + errorIf(err.Trace(), "Invalid access key id.", nil) + writeErrorResponse(w, r, InvalidAccessKeyID, r.URL.Path) + return + default: + errorIf(err.Trace(), "Initializing signature v4 failed.", nil) + writeErrorResponse(w, r, InternalError, r.URL.Path) + return + } + } + ok, err := signature.DoesSignatureMatch("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855") + if err != nil { + errorIf(err.Trace(), "Unable to verify signature.", nil) + writeErrorResponse(w, r, InternalError, r.URL.Path) + return + } + if !ok { + writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + return + } + } + s.handler.ServeHTTP(w, r) + return + } + if isRequestPresignedSignatureV4(r) { + var err *probe.Error + signature, err = initPresignedSignatureV4(r) + if err != nil { + switch err.ToGoError() { + case errAccessKeyIDInvalid: + errorIf(err.Trace(), "Invalid access key id requested.", nil) + writeErrorResponse(w, r, InvalidAccessKeyID, r.URL.Path) + return + default: + errorIf(err.Trace(), "Initializing signature v4 failed.", nil) + writeErrorResponse(w, r, InternalError, r.URL.Path) + return + } + } + ok, err := signature.DoesPresignedSignatureMatch() + if err != nil { + errorIf(err.Trace(), "Unable to verify signature.", nil) + writeErrorResponse(w, r, InternalError, r.URL.Path) + return + } + if !ok { + writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) + return + } + } + s.handler.ServeHTTP(w, r) +} diff --git a/server-api-signature.go b/server-api-signature.go index b0f9182e4..743ca89e5 100644 --- a/server-api-signature.go +++ b/server-api-signature.go @@ -19,7 +19,6 @@ package main import ( "bytes" "encoding/base64" - "errors" "io" "io/ioutil" "mime/multipart" @@ -127,7 +126,7 @@ func initSignatureV4(req *http.Request) (*signv4.Signature, *probe.Error) { return signature, nil } } - return nil, probe.NewError(errors.New("AccessKeyID not found")) + return nil, probe.NewError(errAccessKeyIDInvalid) } func extractHTTPFormValues(reader *multipart.Reader) (io.Reader, map[string]string, *probe.Error) { diff --git a/server-router.go b/server-router.go index ee54e31bf..e3b33a463 100644 --- a/server-router.go +++ b/server-router.go @@ -85,7 +85,7 @@ func getAPIHandler(api API) http.Handler { var mwHandlers = []MiddlewareHandler{ TimeValidityHandler, IgnoreResourcesHandler, - ValidateAuthHeaderHandler, + SignatureHandler, // api.LoggingHandler, // Disabled logging until we bring in external logging support CorsHandler, }