| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | /* | 
					
						
							| 
									
										
										
										
											2016-07-19 14:56:27 +08:00
										 |  |  |  * Minio Cloud Storage, (C) 2015, 2016 Minio, Inc. | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | import ( | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"io/ioutil" | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | 	"net/http" | 
					
						
							|  |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-02 05:34:40 +08:00
										 |  |  | // 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 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | // Verify if request has JWT.
 | 
					
						
							|  |  |  | func isRequestJWT(r *http.Request) bool { | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | 	return strings.HasPrefix(r.Header.Get("Authorization"), jwtAlgorithm) | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Verify if request has AWS Signature Version '4'.
 | 
					
						
							|  |  |  | func isRequestSignatureV4(r *http.Request) bool { | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | 	return strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm) | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | // 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)) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | // Verify if request has AWS PreSign Version '4'.
 | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | func isRequestPresignedSignatureV4(r *http.Request) bool { | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | 	_, ok := r.URL.Query()["X-Amz-Credential"] | 
					
						
							|  |  |  | 	return ok | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | // Verify request has AWS PreSign Version '2'.
 | 
					
						
							|  |  |  | func isRequestPresignedSignatureV2(r *http.Request) bool { | 
					
						
							|  |  |  | 	_, ok := r.URL.Query()["AWSAccessKeyId"] | 
					
						
							|  |  |  | 	return ok | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | // Verify if request has AWS Post policy Signature Version '4'.
 | 
					
						
							|  |  |  | func isRequestPostPolicySignatureV4(r *http.Request) bool { | 
					
						
							| 
									
										
										
										
											2017-01-19 04:24:34 +08:00
										 |  |  | 	return strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data") && r.Method == httpPOST | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Verify if the request has AWS Streaming Signature Version '4'. This is only valid for 'PUT' operation.
 | 
					
						
							|  |  |  | func isRequestSignStreamingV4(r *http.Request) bool { | 
					
						
							| 
									
										
										
										
											2017-02-21 04:07:03 +08:00
										 |  |  | 	return r.Header.Get("x-amz-content-sha256") == streamingContentSHA256 && | 
					
						
							|  |  |  | 		r.Method == httpPUT | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | // Authorization type.
 | 
					
						
							|  |  |  | type authType int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // List of all supported auth types.
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	authTypeUnknown authType = iota | 
					
						
							|  |  |  | 	authTypeAnonymous | 
					
						
							|  |  |  | 	authTypePresigned | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 	authTypePresignedV2 | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | 	authTypePostPolicy | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | 	authTypeStreamingSigned | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | 	authTypeSigned | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 	authTypeSignedV2 | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | 	authTypeJWT | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Get request authentication type.
 | 
					
						
							|  |  |  | func getRequestAuthType(r *http.Request) authType { | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 	if isRequestSignatureV2(r) { | 
					
						
							|  |  |  | 		return authTypeSignedV2 | 
					
						
							|  |  |  | 	} else if isRequestPresignedSignatureV2(r) { | 
					
						
							|  |  |  | 		return authTypePresignedV2 | 
					
						
							|  |  |  | 	} else if isRequestSignStreamingV4(r) { | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | 		return authTypeStreamingSigned | 
					
						
							|  |  |  | 	} else if isRequestSignatureV4(r) { | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | 		return authTypeSigned | 
					
						
							|  |  |  | 	} else if isRequestPresignedSignatureV4(r) { | 
					
						
							|  |  |  | 		return authTypePresigned | 
					
						
							|  |  |  | 	} else if isRequestJWT(r) { | 
					
						
							|  |  |  | 		return authTypeJWT | 
					
						
							|  |  |  | 	} else if isRequestPostPolicySignatureV4(r) { | 
					
						
							|  |  |  | 		return authTypePostPolicy | 
					
						
							| 
									
										
										
										
											2016-03-11 09:36:48 +08:00
										 |  |  | 	} else if _, ok := r.Header["Authorization"]; !ok { | 
					
						
							|  |  |  | 		return authTypeAnonymous | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return authTypeUnknown | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 05:51:05 +08:00
										 |  |  | func checkRequestAuthType(r *http.Request, bucket, policyAction, region string) APIErrorCode { | 
					
						
							|  |  |  | 	reqAuthType := getRequestAuthType(r) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch reqAuthType { | 
					
						
							|  |  |  | 	case authTypePresignedV2, authTypeSignedV2: | 
					
						
							|  |  |  | 		// Signature V2 validation.
 | 
					
						
							|  |  |  | 		s3Error := isReqAuthenticatedV2(r) | 
					
						
							|  |  |  | 		if s3Error != ErrNone { | 
					
						
							| 
									
										
										
										
											2017-05-31 15:11:06 +08:00
										 |  |  | 			errorIf(errSignatureMismatch, "%s", dumpRequest(r)) | 
					
						
							| 
									
										
										
										
											2016-11-22 05:51:05 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return s3Error | 
					
						
							|  |  |  | 	case authTypeSigned, authTypePresigned: | 
					
						
							|  |  |  | 		s3Error := isReqAuthenticated(r, region) | 
					
						
							|  |  |  | 		if s3Error != ErrNone { | 
					
						
							| 
									
										
										
										
											2017-05-31 15:11:06 +08:00
										 |  |  | 			errorIf(errSignatureMismatch, "%s", dumpRequest(r)) | 
					
						
							| 
									
										
										
										
											2016-11-22 05:51:05 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		return s3Error | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if reqAuthType == authTypeAnonymous && policyAction != "" { | 
					
						
							|  |  |  | 		// http://docs.aws.amazon.com/AmazonS3/latest/dev/using-with-s3-actions.html
 | 
					
						
							| 
									
										
										
										
											2017-08-05 16:00:05 +08:00
										 |  |  | 		sourceIP := getSourceIPAddress(r) | 
					
						
							| 
									
										
										
										
											2017-01-30 11:45:11 +08:00
										 |  |  | 		return enforceBucketPolicy(bucket, policyAction, r.URL.Path, | 
					
						
							| 
									
										
										
										
											2017-08-05 16:00:05 +08:00
										 |  |  | 			r.Referer(), sourceIP, r.URL.Query()) | 
					
						
							| 
									
										
										
										
											2016-11-22 05:51:05 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 05:51:05 +08:00
										 |  |  | 	// By default return ErrAccessDenied
 | 
					
						
							|  |  |  | 	return ErrAccessDenied | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | // 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) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-04-11 00:58:08 +08:00
										 |  |  | func reqSignatureV4Verify(r *http.Request, region string) (s3Error APIErrorCode) { | 
					
						
							|  |  |  | 	sha256sum := getContentSha256Cksum(r) | 
					
						
							|  |  |  | 	switch { | 
					
						
							|  |  |  | 	case isRequestSignatureV4(r): | 
					
						
							|  |  |  | 		return doesSignatureMatch(sha256sum, r, region) | 
					
						
							|  |  |  | 	case isRequestPresignedSignatureV4(r): | 
					
						
							|  |  |  | 		return doesPresignedSignatureMatch(sha256sum, r, region) | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return ErrAccessDenied | 
					
						
							| 
									
										
										
										
											2016-10-03 06:51:49 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | // Verify if request has valid AWS Signature Version '4'.
 | 
					
						
							| 
									
										
										
										
											2016-09-30 06:51:00 +08:00
										 |  |  | func isReqAuthenticated(r *http.Request, region string) (s3Error APIErrorCode) { | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | 	if r == nil { | 
					
						
							|  |  |  | 		return ErrInternalError | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-11 00:58:08 +08:00
										 |  |  | 	if errCode := reqSignatureV4Verify(r, region); errCode != ErrNone { | 
					
						
							|  |  |  | 		return errCode | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-04-30 05:24:10 +08:00
										 |  |  | 	payload, err := ioutil.ReadAll(r.Body) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 		errorIf(err, "Unable to read request body for signature verification") | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | 		return ErrInternalError | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-11 00:58:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Populate back the payload.
 | 
					
						
							|  |  |  | 	r.Body = ioutil.NopCloser(bytes.NewReader(payload)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | 	// Verify Content-Md5, if payload is set.
 | 
					
						
							|  |  |  | 	if r.Header.Get("Content-Md5") != "" { | 
					
						
							| 
									
										
										
										
											2016-11-22 05:51:05 +08:00
										 |  |  | 		if r.Header.Get("Content-Md5") != getMD5HashBase64(payload) { | 
					
						
							| 
									
										
										
										
											2016-03-13 08:08:15 +08:00
										 |  |  | 			return ErrBadDigest | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-11 00:58:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-05 16:04:50 +08:00
										 |  |  | 	if skipContentSha256Cksum(r) { | 
					
						
							| 
									
										
										
										
											2017-04-11 00:58:08 +08:00
										 |  |  | 		return ErrNone | 
					
						
							| 
									
										
										
										
											2016-07-02 05:34:40 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-11 00:58:08 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Verify that X-Amz-Content-Sha256 Header == sha256(payload)
 | 
					
						
							|  |  |  | 	// If X-Amz-Content-Sha256 header is not sent then we don't calculate/verify sha256(payload)
 | 
					
						
							|  |  |  | 	sum := r.Header.Get("X-Amz-Content-Sha256") | 
					
						
							|  |  |  | 	if isRequestPresignedSignatureV4(r) { | 
					
						
							|  |  |  | 		sum = r.URL.Query().Get("X-Amz-Content-Sha256") | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-04-11 00:58:08 +08:00
										 |  |  | 	if sum != "" && sum != getSHA256Hash(payload) { | 
					
						
							|  |  |  | 		return ErrContentSHA256Mismatch | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return ErrNone | 
					
						
							| 
									
										
										
										
											2016-02-22 09:57:05 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-18 04:23:15 +08:00
										 |  |  | // authHandler - handles all the incoming authorization headers and validates them if possible.
 | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | 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} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | // List of all support S3 auth types.
 | 
					
						
							| 
									
										
										
										
											2016-08-16 22:57:14 +08:00
										 |  |  | var supportedS3AuthTypes = map[authType]struct{}{ | 
					
						
							|  |  |  | 	authTypeAnonymous:       {}, | 
					
						
							|  |  |  | 	authTypePresigned:       {}, | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 	authTypePresignedV2:     {}, | 
					
						
							| 
									
										
										
										
											2016-08-16 22:57:14 +08:00
										 |  |  | 	authTypeSigned:          {}, | 
					
						
							| 
									
										
										
										
											2016-10-01 05:32:13 +08:00
										 |  |  | 	authTypeSignedV2:        {}, | 
					
						
							| 
									
										
										
										
											2016-08-16 22:57:14 +08:00
										 |  |  | 	authTypePostPolicy:      {}, | 
					
						
							|  |  |  | 	authTypeStreamingSigned: {}, | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Validate if the authType is valid and supported.
 | 
					
						
							|  |  |  | func isSupportedS3AuthType(aType authType) bool { | 
					
						
							| 
									
										
										
										
											2016-08-16 22:57:14 +08:00
										 |  |  | 	_, ok := supportedS3AuthTypes[aType] | 
					
						
							|  |  |  | 	return ok | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-17 10:50:36 +08:00
										 |  |  | // handler for validating incoming authorization headers.
 | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | func (a authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | 	aType := getRequestAuthType(r) | 
					
						
							|  |  |  | 	if isSupportedS3AuthType(aType) { | 
					
						
							|  |  |  | 		// Let top level caller validate for anonymous and known signed requests.
 | 
					
						
							| 
									
										
										
										
											2016-02-17 10:50:36 +08:00
										 |  |  | 		a.handler.ServeHTTP(w, r) | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2016-08-09 11:56:29 +08:00
										 |  |  | 	} else if aType == authTypeJWT { | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | 		// Validate Authorization header if its valid for JWT request.
 | 
					
						
							| 
									
										
										
										
											2016-12-28 00:28:10 +08:00
										 |  |  | 		if !isHTTPRequestValid(r) { | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | 			w.WriteHeader(http.StatusUnauthorized) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
											
												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"
											
										 
											2016-02-04 08:46:56 +08:00
										 |  |  | 		a.handler.ServeHTTP(w, r) | 
					
						
							|  |  |  | 		return | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-01-06 16:37:00 +08:00
										 |  |  | 	writeErrorResponse(w, ErrSignatureVersionNotSupported, r.URL) | 
					
						
							| 
									
										
										
										
											2016-02-16 09:42:39 +08:00
										 |  |  | } |