mirror of
https://github.com/minio/minio.git
synced 2025-11-20 01:50:24 -05:00
handler/PUT: Handle signature verification through a custom reader. (#2066)
Change brings in a new signVerifyReader which provides a io.Reader compatible reader, additionally implements Verify() function. Verify() function validates the signature present in the incoming request. This approach is choosen to avoid complexities involved in using io.Pipe(). Thanks to Krishna for his inputs on this. Fixes #2058 Fixes #2054 Fixes #2087
This commit is contained in:
committed by
Anand Babu (AB) Periasamy
parent
0540863663
commit
8a028a9efb
@@ -779,6 +779,66 @@ func (s *TestSuiteCommon) TestListBuckets(c *C) {
|
||||
c.Assert(err, IsNil)
|
||||
}
|
||||
|
||||
// This tests validate if PUT handler can successfully detect signature mismatch.
|
||||
func (s *TestSuiteCommon) TestValidateSignature(c *C) {
|
||||
// generate a random bucket name.
|
||||
bucketName := getRandomBucketName()
|
||||
// HTTP request to create the bucket.
|
||||
request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName),
|
||||
0, nil, s.accessKey, s.secretKey)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
client := http.Client{}
|
||||
// Execute the HTTP request to create bucket.
|
||||
response, err := client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
||||
|
||||
objName := "test-object"
|
||||
|
||||
// Body is on purpose set to nil so that we get payload generated for empty bytes.
|
||||
|
||||
// Create new HTTP request with incorrect secretKey to generate an incorrect signature.
|
||||
secretKey := s.secretKey + "a"
|
||||
request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objName), 0, nil, s.accessKey, secretKey)
|
||||
c.Assert(err, IsNil)
|
||||
response, err = client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
verifyError(c, response, "SignatureDoesNotMatch", "The request signature we calculated does not match the signature you provided. Check your key and signing method.", http.StatusForbidden)
|
||||
}
|
||||
|
||||
// This tests validate if PUT handler can successfully detect SHA256 mismatch.
|
||||
func (s *TestSuiteCommon) TestSHA256Mismatch(c *C) {
|
||||
// generate a random bucket name.
|
||||
bucketName := getRandomBucketName()
|
||||
// HTTP request to create the bucket.
|
||||
request, err := newTestRequest("PUT", getMakeBucketURL(s.endPoint, bucketName),
|
||||
0, nil, s.accessKey, s.secretKey)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
client := http.Client{}
|
||||
// Execute the HTTP request to create bucket.
|
||||
response, err := client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
||||
|
||||
objName := "test-object"
|
||||
|
||||
// Body is on purpose set to nil so that we get payload generated for empty bytes.
|
||||
|
||||
// Create new HTTP request with incorrect secretKey to generate an incorrect signature.
|
||||
secretKey := s.secretKey + "a"
|
||||
request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, objName), 0, nil, s.accessKey, secretKey)
|
||||
c.Assert(request.Header.Get("x-amz-content-sha256"), Equals, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855")
|
||||
// Set the body to generate signature mismatch.
|
||||
request.Body = ioutil.NopCloser(bytes.NewReader([]byte("Hello, World")))
|
||||
c.Assert(err, IsNil)
|
||||
// execute the HTTP request.
|
||||
response, err = client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
verifyError(c, response, "XAmzContentSHA256Mismatch", "The provided 'x-amz-content-sha256' header does not match what was computed.", http.StatusBadRequest)
|
||||
}
|
||||
|
||||
// TestNotBeAbleToCreateObjectInNonexistentBucket - Validates the error response
|
||||
// on an attempt to upload an object into a non-existent bucket.
|
||||
func (s *TestSuiteCommon) TestPutObjectLongName(c *C) {
|
||||
@@ -790,11 +850,11 @@ func (s *TestSuiteCommon) TestPutObjectLongName(c *C) {
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
client := http.Client{}
|
||||
// execute the HTTP request to create bucket.
|
||||
// Execute the HTTP request to create bucket.
|
||||
response, err := client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
||||
// content for the object to be uploaded.
|
||||
// Content for the object to be uploaded.
|
||||
buffer := bytes.NewReader([]byte("hello world"))
|
||||
// make long object name.
|
||||
longObjName := fmt.Sprintf("%0255d/%0255d/%0255d", 1, 1, 1)
|
||||
@@ -808,6 +868,7 @@ func (s *TestSuiteCommon) TestPutObjectLongName(c *C) {
|
||||
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
||||
// make long object name.
|
||||
longObjName = fmt.Sprintf("%0256d", 1)
|
||||
buffer = bytes.NewReader([]byte("hello world"))
|
||||
request, err = newTestRequest("PUT", getPutObjectURL(s.endPoint, bucketName, longObjName),
|
||||
int64(buffer.Len()), buffer, s.accessKey, s.secretKey)
|
||||
c.Assert(err, IsNil)
|
||||
@@ -1916,7 +1977,7 @@ func (s *TestSuiteCommon) TestObjectValidMD5(c *C) {
|
||||
client = http.Client{}
|
||||
response, err = client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
// exepcting a successful upload.
|
||||
// expecting a successful upload.
|
||||
c.Assert(response.StatusCode, Equals, http.StatusOK)
|
||||
objectName = "test-2-object"
|
||||
buffer1 = bytes.NewReader(data)
|
||||
@@ -1925,7 +1986,8 @@ func (s *TestSuiteCommon) TestObjectValidMD5(c *C) {
|
||||
int64(buffer1.Len()), buffer1, s.accessKey, s.secretKey)
|
||||
c.Assert(err, IsNil)
|
||||
// set Content-Md5 to invalid value.
|
||||
request.Header.Set("Content-Md5", "WvLTlMrX9NpYDQlEIFlnDw==")
|
||||
request.Header.Set("Content-Md5", "kvLTlMrX9NpYDQlEIFlnDA==")
|
||||
// expecting a failure during upload.
|
||||
client = http.Client{}
|
||||
response, err = client.Do(request)
|
||||
c.Assert(err, IsNil)
|
||||
|
||||
Reference in New Issue
Block a user