accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago accessPolicy: Implement Put, Get, Delete access policy.
This patch implements Get,Put,Delete bucket policies
Supporting - http://docs.aws.amazon.com/AmazonS3/latest/dev/access-policy-language-overview.html
Currently supports following actions.
"*": true,
"s3:*": true,
"s3:GetObject": true,
"s3:ListBucket": true,
"s3:PutObject": true,
"s3:CreateBucket": true,
"s3:GetBucketLocation": true,
"s3:DeleteBucket": true,
"s3:DeleteObject": true,
"s3:AbortMultipartUpload": true,
"s3:ListBucketMultipartUploads": true,
"s3:ListMultipartUploadParts": true,
following conditions for "StringEquals" and "StringNotEquals"
"s3:prefix", "s3:max-keys"
10 years ago |
|
/* * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0
* * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
package cmd
import ( "bytes" "crypto/md5" "crypto/sha256" "encoding/base64" "encoding/hex" "io/ioutil" "net/http" "strings" )
// Verify if the request http Header "x-amz-content-sha256" == "UNSIGNED-PAYLOAD"
func isRequestUnsignedPayload(r *http.Request) bool { return r.Header.Get("x-amz-content-sha256") == unsignedPayload }
// Verify if request has JWT.
func isRequestJWT(r *http.Request) bool { return strings.HasPrefix(r.Header.Get("Authorization"), jwtAlgorithm) }
// Verify if request has AWS Signature Version '4'.
func isRequestSignatureV4(r *http.Request) bool { return strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm) }
// Verify if request has AWS Signature Version '2'.
func isRequestSignatureV2(r *http.Request) bool { return (!strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm) && strings.HasPrefix(r.Header.Get("Authorization"), signV2Algorithm)) }
// Verify if request has AWS PreSign Version '4'.
func isRequestPresignedSignatureV4(r *http.Request) bool { _, ok := r.URL.Query()["X-Amz-Credential"] return ok }
// Verify request has AWS PreSign Version '2'.
func isRequestPresignedSignatureV2(r *http.Request) bool { _, ok := r.URL.Query()["AWSAccessKeyId"] return ok }
// Verify if request has AWS Post policy Signature Version '4'.
func isRequestPostPolicySignatureV4(r *http.Request) bool { return strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data") && r.Method == "POST" }
// Verify if the request has AWS Streaming Signature Version '4'. This is only valid for 'PUT' operation.
func isRequestSignStreamingV4(r *http.Request) bool { return r.Header.Get("x-amz-content-sha256") == streamingContentSHA256 && r.Method == "PUT" }
// Authorization type.
type authType int
// List of all supported auth types.
const ( authTypeUnknown authType = iota authTypeAnonymous authTypePresigned authTypePresignedV2 authTypePostPolicy authTypeStreamingSigned authTypeSigned authTypeSignedV2 authTypeJWT )
// Get request authentication type.
func getRequestAuthType(r *http.Request) authType { if isRequestSignatureV2(r) { return authTypeSignedV2 } else if isRequestPresignedSignatureV2(r) { return authTypePresignedV2 } else if isRequestSignStreamingV4(r) { return authTypeStreamingSigned } else if isRequestSignatureV4(r) { return authTypeSigned } else if isRequestPresignedSignatureV4(r) { return authTypePresigned } else if isRequestJWT(r) { return authTypeJWT } else if isRequestPostPolicySignatureV4(r) { return authTypePostPolicy } else if _, ok := r.Header["Authorization"]; !ok { return authTypeAnonymous } return authTypeUnknown }
// sum256 calculate sha256 sum for an input byte array
func sum256(data []byte) []byte { hash := sha256.New() hash.Write(data) return hash.Sum(nil) }
// sumMD5 calculate md5 sum for an input byte array
func sumMD5(data []byte) []byte { hash := md5.New() hash.Write(data) return hash.Sum(nil) }
// Verify if request has valid AWS Signature Version '2'.
func isReqAuthenticatedV2(r *http.Request) (s3Error APIErrorCode) { if isRequestSignatureV2(r) { return doesSignV2Match(r) } return doesPresignV2SignatureMatch(r) }
func reqSignatureV4Verify(r *http.Request) (s3Error APIErrorCode) { sha256sum := r.Header.Get("X-Amz-Content-Sha256") // Skips calculating sha256 on the payload on server,
// if client requested for it.
if skipContentSha256Cksum(r) { sha256sum = unsignedPayload } if isRequestSignatureV4(r) { return doesSignatureMatch(sha256sum, r, serverConfig.GetRegion()) } else if isRequestPresignedSignatureV4(r) { return doesPresignedSignatureMatch(sha256sum, r, serverConfig.GetRegion()) } return ErrAccessDenied }
// Verify if request has valid AWS Signature Version '4'.
func isReqAuthenticated(r *http.Request, region string) (s3Error APIErrorCode) { if r == nil { return ErrInternalError } payload, err := ioutil.ReadAll(r.Body) if err != nil { errorIf(err, "Unable to read request body for signature verification") return ErrInternalError } // Verify Content-Md5, if payload is set.
if r.Header.Get("Content-Md5") != "" { if r.Header.Get("Content-Md5") != base64.StdEncoding.EncodeToString(sumMD5(payload)) { return ErrBadDigest } } // Populate back the payload.
r.Body = ioutil.NopCloser(bytes.NewReader(payload)) var sha256sum string // Skips calculating sha256 on the payload on server,
// if client requested for it.
if skipContentSha256Cksum(r) { sha256sum = unsignedPayload } else { sha256sum = hex.EncodeToString(sum256(payload)) } if isRequestSignatureV4(r) { return doesSignatureMatch(sha256sum, r, region) } else if isRequestPresignedSignatureV4(r) { return doesPresignedSignatureMatch(sha256sum, r, region) } return ErrAccessDenied }
// checkAuth - checks for conditions satisfying the authorization of
// the incoming request. Request should be either Presigned or Signed
// in accordance with AWS S3 Signature V4 requirements. ErrAccessDenied
// is returned for unhandled auth type. Once the auth type is indentified
// request headers and body are used to calculate the signature validating
// the client signature present in request.
func checkAuth(r *http.Request) APIErrorCode { return checkAuthWithRegion(r, serverConfig.GetRegion()) }
// checkAuthWithRegion - similar to checkAuth but takes a custom region.
func checkAuthWithRegion(r *http.Request, region string) APIErrorCode { // Validates the request for both Presigned and Signed.
aType := getRequestAuthType(r) switch aType { case authTypeSignedV2, authTypePresignedV2: // Signature V2.
return isReqAuthenticatedV2(r) case authTypeSigned, authTypePresigned: // Signature V4.
return isReqAuthenticated(r, region) } // For all unhandled auth types return error AccessDenied.
return ErrAccessDenied }
// authHandler - handles all the incoming authorization headers and validates them if possible.
type authHandler struct { handler http.Handler }
// setAuthHandler to validate authorization header for the incoming request.
func setAuthHandler(h http.Handler) http.Handler { return authHandler{h} }
// List of all support S3 auth types.
var supportedS3AuthTypes = map[authType]struct{}{ authTypeAnonymous: {}, authTypePresigned: {}, authTypePresignedV2: {}, authTypeSigned: {}, authTypeSignedV2: {}, authTypePostPolicy: {}, authTypeStreamingSigned: {}, }
// Validate if the authType is valid and supported.
func isSupportedS3AuthType(aType authType) bool { _, ok := supportedS3AuthTypes[aType] return ok }
// handler for validating incoming authorization headers.
func (a authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { aType := getRequestAuthType(r) if isSupportedS3AuthType(aType) { // Let top level caller validate for anonymous and known signed requests.
a.handler.ServeHTTP(w, r) return } else if aType == authTypeJWT { // Validate Authorization header if its valid for JWT request.
if !isJWTReqAuthenticated(r) { w.WriteHeader(http.StatusUnauthorized) return } a.handler.ServeHTTP(w, r) return } writeErrorResponse(w, r, ErrSignatureVersionNotSupported, r.URL.Path) }
|