mirror of
https://github.com/minio/minio.git
synced 2025-01-12 07:23:23 -05:00
Merge pull request #1280 from harshavardhana/region
signature: No need to validate region for getBucketLocation and listBuckets
This commit is contained in:
commit
12515eabe2
@ -129,10 +129,11 @@ func isReqAuthenticated(r *http.Request) (s3Error APIErrorCode) {
|
|||||||
}
|
}
|
||||||
// Populate back the payload.
|
// Populate back the payload.
|
||||||
r.Body = ioutil.NopCloser(bytes.NewReader(payload))
|
r.Body = ioutil.NopCloser(bytes.NewReader(payload))
|
||||||
|
validateRegion := true // Validate region.
|
||||||
if isRequestSignatureV4(r) {
|
if isRequestSignatureV4(r) {
|
||||||
return doesSignatureMatch(hex.EncodeToString(sum256(payload)), r)
|
return doesSignatureMatch(hex.EncodeToString(sum256(payload)), r, validateRegion)
|
||||||
} else if isRequestPresignedSignatureV4(r) {
|
} else if isRequestPresignedSignatureV4(r) {
|
||||||
return doesPresignedSignatureMatch(r)
|
return doesPresignedSignatureMatch(r, validateRegion)
|
||||||
}
|
}
|
||||||
return ErrAccessDenied
|
return ErrAccessDenied
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -88,7 +90,28 @@ func (api objectStorageAPI) GetBucketLocationHandler(w http.ResponseWriter, r *h
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
case authTypeSigned, authTypePresigned:
|
case authTypeSigned, authTypePresigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
payload, e := ioutil.ReadAll(r.Body)
|
||||||
|
if e != nil {
|
||||||
|
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Verify Content-Md5, if payload is set.
|
||||||
|
if r.Header.Get("Content-Md5") != "" {
|
||||||
|
if r.Header.Get("Content-Md5") != base64.StdEncoding.EncodeToString(sumMD5(payload)) {
|
||||||
|
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Populate back the payload.
|
||||||
|
r.Body = ioutil.NopCloser(bytes.NewReader(payload))
|
||||||
|
var s3Error APIErrorCode // API error code.
|
||||||
|
validateRegion := false // Validate region.
|
||||||
|
if isRequestSignatureV4(r) {
|
||||||
|
s3Error = doesSignatureMatch(hex.EncodeToString(sum256(payload)), r, validateRegion)
|
||||||
|
} else if isRequestPresignedSignatureV4(r) {
|
||||||
|
s3Error = doesPresignedSignatureMatch(r, validateRegion)
|
||||||
|
}
|
||||||
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -117,7 +140,7 @@ func (api objectStorageAPI) GetBucketLocationHandler(w http.ResponseWriter, r *h
|
|||||||
Location: region,
|
Location: region,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
setCommonHeaders(w) // write headers.
|
setCommonHeaders(w) // Write headers.
|
||||||
writeSuccessResponse(w, encodedSuccessResponse)
|
writeSuccessResponse(w, encodedSuccessResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +279,28 @@ func (api objectStorageAPI) ListBucketsHandler(w http.ResponseWriter, r *http.Re
|
|||||||
writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path)
|
writeErrorResponse(w, r, ErrAccessDenied, r.URL.Path)
|
||||||
return
|
return
|
||||||
case authTypeSigned, authTypePresigned:
|
case authTypeSigned, authTypePresigned:
|
||||||
if s3Error := isReqAuthenticated(r); s3Error != ErrNone {
|
payload, e := ioutil.ReadAll(r.Body)
|
||||||
|
if e != nil {
|
||||||
|
writeErrorResponse(w, r, ErrInternalError, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Verify Content-Md5, if payload is set.
|
||||||
|
if r.Header.Get("Content-Md5") != "" {
|
||||||
|
if r.Header.Get("Content-Md5") != base64.StdEncoding.EncodeToString(sumMD5(payload)) {
|
||||||
|
writeErrorResponse(w, r, ErrBadDigest, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Populate back the payload.
|
||||||
|
r.Body = ioutil.NopCloser(bytes.NewReader(payload))
|
||||||
|
var s3Error APIErrorCode // API error code.
|
||||||
|
validateRegion := false // Validate region.
|
||||||
|
if isRequestSignatureV4(r) {
|
||||||
|
s3Error = doesSignatureMatch(hex.EncodeToString(sum256(payload)), r, validateRegion)
|
||||||
|
} else if isRequestPresignedSignatureV4(r) {
|
||||||
|
s3Error = doesPresignedSignatureMatch(r, validateRegion)
|
||||||
|
}
|
||||||
|
if s3Error != ErrNone {
|
||||||
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
writeErrorResponse(w, r, s3Error, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -601,8 +601,9 @@ func (api objectStorageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
// Create anonymous object.
|
// Create anonymous object.
|
||||||
objectInfo, err = api.ObjectAPI.PutObject(bucket, object, size, r.Body, nil)
|
objectInfo, err = api.ObjectAPI.PutObject(bucket, object, size, r.Body, nil)
|
||||||
case authTypePresigned:
|
case authTypePresigned:
|
||||||
|
validateRegion := true // Validate region.
|
||||||
// For presigned requests verify them right here.
|
// For presigned requests verify them right here.
|
||||||
if apiErr := doesPresignedSignatureMatch(r); apiErr != ErrNone {
|
if apiErr := doesPresignedSignatureMatch(r, validateRegion); apiErr != ErrNone {
|
||||||
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -622,7 +623,8 @@ func (api objectStorageAPI) PutObjectHandler(w http.ResponseWriter, r *http.Requ
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
shaPayload := shaWriter.Sum(nil)
|
shaPayload := shaWriter.Sum(nil)
|
||||||
if apiErr := doesSignatureMatch(hex.EncodeToString(shaPayload), r); apiErr != ErrNone {
|
validateRegion := true // Validate region.
|
||||||
|
if apiErr := doesSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion); apiErr != ErrNone {
|
||||||
if apiErr == ErrSignatureDoesNotMatch {
|
if apiErr == ErrSignatureDoesNotMatch {
|
||||||
writer.CloseWithError(errSignatureMismatch)
|
writer.CloseWithError(errSignatureMismatch)
|
||||||
return
|
return
|
||||||
@ -779,8 +781,9 @@ func (api objectStorageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http.
|
|||||||
// already allowed.
|
// already allowed.
|
||||||
partMD5, err = api.ObjectAPI.PutObjectPart(bucket, object, uploadID, partID, size, r.Body, hex.EncodeToString(md5Bytes))
|
partMD5, err = api.ObjectAPI.PutObjectPart(bucket, object, uploadID, partID, size, r.Body, hex.EncodeToString(md5Bytes))
|
||||||
case authTypePresigned:
|
case authTypePresigned:
|
||||||
|
validateRegion := true // Validate region.
|
||||||
// For presigned requests verify right here.
|
// For presigned requests verify right here.
|
||||||
apiErr := doesPresignedSignatureMatch(r)
|
apiErr := doesPresignedSignatureMatch(r, validateRegion)
|
||||||
if apiErr != ErrNone {
|
if apiErr != ErrNone {
|
||||||
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
writeErrorResponse(w, r, apiErr, r.URL.Path)
|
||||||
return
|
return
|
||||||
@ -800,7 +803,8 @@ func (api objectStorageAPI) PutObjectPartHandler(w http.ResponseWriter, r *http.
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
shaPayload := shaWriter.Sum(nil)
|
shaPayload := shaWriter.Sum(nil)
|
||||||
if apiErr := doesSignatureMatch(hex.EncodeToString(shaPayload), r); apiErr != ErrNone {
|
validateRegion := true // Validate region.
|
||||||
|
if apiErr := doesSignatureMatch(hex.EncodeToString(shaPayload), r, validateRegion); apiErr != ErrNone {
|
||||||
if apiErr == ErrSignatureDoesNotMatch {
|
if apiErr == ErrSignatureDoesNotMatch {
|
||||||
writer.CloseWithError(errSignatureMismatch)
|
writer.CloseWithError(errSignatureMismatch)
|
||||||
return
|
return
|
||||||
|
@ -195,7 +195,8 @@ func doesPolicySignatureMatch(formValues map[string]string) APIErrorCode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify if the region is valid.
|
// Verify if the region is valid.
|
||||||
if !isValidRegion(credHeader.scope.region, region) {
|
sRegion := credHeader.scope.region
|
||||||
|
if !isValidRegion(sRegion, region) {
|
||||||
return ErrInvalidRegion
|
return ErrInvalidRegion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +222,7 @@ func doesPolicySignatureMatch(formValues map[string]string) APIErrorCode {
|
|||||||
// doesPresignedSignatureMatch - Verify query headers with presigned signature
|
// doesPresignedSignatureMatch - Verify query headers with presigned signature
|
||||||
// - http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
|
// - http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
|
||||||
// returns true if matches, false otherwise. if error is not nil then it is always false
|
// returns true if matches, false otherwise. if error is not nil then it is always false
|
||||||
func doesPresignedSignatureMatch(r *http.Request) APIErrorCode {
|
func doesPresignedSignatureMatch(r *http.Request, validateRegion bool) APIErrorCode {
|
||||||
// Access credentials.
|
// Access credentials.
|
||||||
cred := serverConfig.GetCredential()
|
cred := serverConfig.GetCredential()
|
||||||
|
|
||||||
@ -244,9 +245,15 @@ func doesPresignedSignatureMatch(r *http.Request) APIErrorCode {
|
|||||||
|
|
||||||
// Verify if region is valid.
|
// Verify if region is valid.
|
||||||
sRegion := preSignValues.Credential.scope.region
|
sRegion := preSignValues.Credential.scope.region
|
||||||
|
// Should validate region, only if region is set. Some operations
|
||||||
|
// do not need region validated for example GetBucketLocation.
|
||||||
|
if validateRegion {
|
||||||
if !isValidRegion(sRegion, region) {
|
if !isValidRegion(sRegion, region) {
|
||||||
return ErrInvalidRegion
|
return ErrInvalidRegion
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
region = sRegion
|
||||||
|
}
|
||||||
|
|
||||||
// Extract all the signed headers along with its values.
|
// Extract all the signed headers along with its values.
|
||||||
extractedSignedHeaders := extractSignedHeaders(preSignValues.SignedHeaders, req.Header)
|
extractedSignedHeaders := extractSignedHeaders(preSignValues.SignedHeaders, req.Header)
|
||||||
@ -267,7 +274,7 @@ func doesPresignedSignatureMatch(r *http.Request) APIErrorCode {
|
|||||||
query.Set("X-Amz-Date", t.Format(iso8601Format))
|
query.Set("X-Amz-Date", t.Format(iso8601Format))
|
||||||
query.Set("X-Amz-Expires", strconv.Itoa(expireSeconds))
|
query.Set("X-Amz-Expires", strconv.Itoa(expireSeconds))
|
||||||
query.Set("X-Amz-SignedHeaders", getSignedHeaders(extractedSignedHeaders))
|
query.Set("X-Amz-SignedHeaders", getSignedHeaders(extractedSignedHeaders))
|
||||||
query.Set("X-Amz-Credential", cred.AccessKeyID+"/"+getScope(t, region))
|
query.Set("X-Amz-Credential", cred.AccessKeyID+"/"+getScope(t, sRegion))
|
||||||
|
|
||||||
// Save other headers available in the request parameters.
|
// Save other headers available in the request parameters.
|
||||||
for k, v := range req.URL.Query() {
|
for k, v := range req.URL.Query() {
|
||||||
@ -321,7 +328,7 @@ func doesPresignedSignatureMatch(r *http.Request) APIErrorCode {
|
|||||||
// doesSignatureMatch - Verify authorization header with calculated header in accordance with
|
// doesSignatureMatch - Verify authorization header with calculated header in accordance with
|
||||||
// - http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
|
// - http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
|
||||||
// returns true if matches, false otherwise. if error is not nil then it is always false
|
// returns true if matches, false otherwise. if error is not nil then it is always false
|
||||||
func doesSignatureMatch(hashedPayload string, r *http.Request) APIErrorCode {
|
func doesSignatureMatch(hashedPayload string, r *http.Request, validateRegion bool) APIErrorCode {
|
||||||
// Access credentials.
|
// Access credentials.
|
||||||
cred := serverConfig.GetCredential()
|
cred := serverConfig.GetCredential()
|
||||||
|
|
||||||
@ -350,9 +357,15 @@ func doesSignatureMatch(hashedPayload string, r *http.Request) APIErrorCode {
|
|||||||
|
|
||||||
// Verify if region is valid.
|
// Verify if region is valid.
|
||||||
sRegion := signV4Values.Credential.scope.region
|
sRegion := signV4Values.Credential.scope.region
|
||||||
|
// Should validate region, only if region is set. Some operations
|
||||||
|
// do not need region validated for example GetBucketLocation.
|
||||||
|
if validateRegion {
|
||||||
if !isValidRegion(sRegion, region) {
|
if !isValidRegion(sRegion, region) {
|
||||||
return ErrInvalidRegion
|
return ErrInvalidRegion
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
region = sRegion
|
||||||
|
}
|
||||||
|
|
||||||
// Extract date, if not present throw error.
|
// Extract date, if not present throw error.
|
||||||
var date string
|
var date string
|
||||||
|
Loading…
Reference in New Issue
Block a user