mirror of
				https://github.com/minio/minio.git
				synced 2025-10-29 15:55:00 -04:00 
			
		
		
		
	signV4: Move pkg/signature to pkg/s3/signature4
Cleanup and move this to relevant path.
This commit is contained in:
		
							parent
							
								
									d3966d1dde
								
							
						
					
					
						commit
						653ceee9ee
					
				| @ -16,13 +16,88 @@ | ||||
| 
 | ||||
| package main | ||||
| 
 | ||||
| import "net/http" | ||||
| import ( | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/hex" | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| ) | ||||
| 
 | ||||
| const ( | ||||
| 	signV4Algorithm = "AWS4-HMAC-SHA256" | ||||
| 	jwtAlgorithm    = "Bearer" | ||||
| ) | ||||
| 
 | ||||
| // Verify if request has JWT. | ||||
| func isRequestJWT(r *http.Request) bool { | ||||
| 	if _, ok := r.Header["Authorization"]; ok { | ||||
| 		if strings.HasPrefix(r.Header.Get("Authorization"), jwtAlgorithm) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request has AWS Signature Version '4'. | ||||
| func isRequestSignatureV4(r *http.Request) bool { | ||||
| 	if _, ok := r.Header["Authorization"]; ok { | ||||
| 		if strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request has AWS Presignature Version '4'. | ||||
| func isRequestPresignedSignatureV4(r *http.Request) bool { | ||||
| 	if _, ok := r.URL.Query()["X-Amz-Credential"]; ok { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request has AWS Post policy Signature Version '4'. | ||||
| func isRequestPostPolicySignatureV4(r *http.Request) bool { | ||||
| 	if _, ok := r.Header["Content-Type"]; ok { | ||||
| 		if strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data") { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request requires ACL check. | ||||
| func isRequestRequiresACLCheck(r *http.Request) bool { | ||||
| 	if isRequestSignatureV4(r) || isRequestPresignedSignatureV4(r) || isRequestPostPolicySignatureV4(r) { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // Verify if request has valid AWS Signature Version '4'. | ||||
| func isSignV4ReqAuthenticated(sign *signature4.Sign, r *http.Request) bool { | ||||
| 	auth := sign.SetHTTPRequestToVerify(r) | ||||
| 	if isRequestSignatureV4(r) { | ||||
| 		dummyPayload := sha256.Sum256([]byte("")) | ||||
| 		ok, err := auth.DoesSignatureMatch(hex.EncodeToString(dummyPayload[:])) | ||||
| 		if err != nil { | ||||
| 			errorIf(err.Trace(), "Signature verification failed.", nil) | ||||
| 			return false | ||||
| 		} | ||||
| 		return ok | ||||
| 	} else if isRequestPresignedSignatureV4(r) { | ||||
| 		ok, err := auth.DoesPresignedSignatureMatch() | ||||
| 		if err != nil { | ||||
| 			errorIf(err.Trace(), "Presigned signature verification failed.", nil) | ||||
| 			return false | ||||
| 		} | ||||
| 		return ok | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // authHandler - handles all the incoming authorization headers and | ||||
| // validates them if possible. | ||||
| type authHandler struct { | ||||
|  | ||||
| @ -24,11 +24,11 @@ import ( | ||||
| 	"mime/multipart" | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"github.com/gorilla/mux" | ||||
| 	mux "github.com/gorilla/mux" | ||||
| 	"github.com/minio/minio/pkg/crypto/sha256" | ||||
| 	"github.com/minio/minio/pkg/fs" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| ) | ||||
| 
 | ||||
| // GetBucketLocationHandler - GET Bucket location. | ||||
| @ -368,7 +368,7 @@ func (api storageAPI) PostPolicyBucketHandler(w http.ResponseWriter, r *http.Req | ||||
| 		writeErrorResponse(w, r, SignatureDoesNotMatch, r.URL.Path) | ||||
| 		return | ||||
| 	} | ||||
| 	if err = signV4.ApplyPolicyCond(formValues); err != nil { | ||||
| 	if err = signature4.ApplyPolicyCond(formValues); err != nil { | ||||
| 		errorIf(err.Trace(), "Invalid request, policy doesn't match with the endpoint.", nil) | ||||
| 		writeErrorResponse(w, r, MalformedPOSTRequest, r.URL.Path) | ||||
| 		return | ||||
|  | ||||
| @ -39,7 +39,7 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/disk" | ||||
| 	"github.com/minio/minio/pkg/mimedb" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| ) | ||||
| 
 | ||||
| // isValidUploadID - is upload id. | ||||
| @ -297,7 +297,7 @@ 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 } | ||||
| 
 | ||||
| // CreateObjectPart - create a part in a multipart session | ||||
| func (fs Filesystem) CreateObjectPart(bucket, object, uploadID, expectedMD5Sum string, partID int, size int64, data io.Reader, signature *signV4.Signature) (string, *probe.Error) { | ||||
| func (fs Filesystem) CreateObjectPart(bucket, object, uploadID, expectedMD5Sum string, partID int, size int64, data io.Reader, signature *signature4.Sign) (string, *probe.Error) { | ||||
| 	di, err := disk.GetInfo(fs.path) | ||||
| 	if err != nil { | ||||
| 		return "", probe.NewError(err) | ||||
| @ -431,7 +431,7 @@ func (fs Filesystem) CreateObjectPart(bucket, object, uploadID, expectedMD5Sum s | ||||
| } | ||||
| 
 | ||||
| // CompleteMultipartUpload - complete a multipart upload and persist the data | ||||
| func (fs Filesystem) CompleteMultipartUpload(bucket, object, uploadID string, data io.Reader, signature *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (fs Filesystem) CompleteMultipartUpload(bucket, object, uploadID string, data io.Reader, signature *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	// Check bucket name is valid. | ||||
| 	if !IsValidBucketName(bucket) { | ||||
| 		return ObjectMetadata{}, probe.NewError(BucketNameInvalid{Bucket: bucket}) | ||||
|  | ||||
| @ -34,7 +34,7 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/ioutils" | ||||
| 	"github.com/minio/minio/pkg/mimedb" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| ) | ||||
| 
 | ||||
| /// Object Operations | ||||
| @ -199,7 +199,7 @@ func isMD5SumEqual(expectedMD5Sum, actualMD5Sum string) bool { | ||||
| } | ||||
| 
 | ||||
| // CreateObject - create an object. | ||||
| func (fs Filesystem) CreateObject(bucket, object, expectedMD5Sum string, size int64, data io.Reader, sig *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (fs Filesystem) CreateObject(bucket, object, expectedMD5Sum string, size int64, data io.Reader, sig *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	di, e := disk.GetInfo(fs.path) | ||||
| 	if e != nil { | ||||
| 		return ObjectMetadata{}, probe.NewError(e) | ||||
| @ -294,7 +294,7 @@ func (fs Filesystem) CreateObject(bucket, object, expectedMD5Sum string, size in | ||||
| 		} | ||||
| 		if !ok { | ||||
| 			file.CloseAndPurge() | ||||
| 			return ObjectMetadata{}, signV4.ErrSignDoesNotMath("Signature does not match") | ||||
| 			return ObjectMetadata{}, probe.NewError(SignDoesNotMatch{}) | ||||
| 		} | ||||
| 	} | ||||
| 	file.Close() | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Minio Cloud Storage, (C) 2015 Minio, Inc. | ||||
|  * 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. | ||||
| @ -14,7 +14,7 @@ | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package signature | ||||
| package signature4 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| @ -24,13 +24,14 @@ import ( | ||||
| 
 | ||||
| type errFunc func(msg string, a ...string) *probe.Error | ||||
| 
 | ||||
| // generic error factory which wraps around probe.NewError() | ||||
| func errFactory() errFunc { | ||||
| 	return func(msg string, a ...string) *probe.Error { | ||||
| 		return probe.NewError(fmt.Errorf("%s, Args: %s", msg, a)).Untrace() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Various errors. | ||||
| // Various signature v4 errors. | ||||
| var ( | ||||
| 	ErrPolicyAlreadyExpired  = errFactory() | ||||
| 	ErrInvalidRegion         = errFactory() | ||||
| @ -1,4 +1,20 @@ | ||||
| package signature | ||||
| /* | ||||
|  * Minio Cloud Storage, (C) 2015 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 signature4 | ||||
| 
 | ||||
| import ( | ||||
| 	"net/url" | ||||
| @ -8,7 +24,9 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| ) | ||||
| 
 | ||||
| type credScope struct { | ||||
| // credential data type represents structured form of Credential | ||||
| // string from authorization header. | ||||
| type credential struct { | ||||
| 	accessKeyID string | ||||
| 	scope       struct { | ||||
| 		date    time.Time | ||||
| @ -18,45 +36,46 @@ type credScope struct { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func parseCredential(credElement string) (credScope, *probe.Error) { | ||||
| // parse credential string into its structured form. | ||||
| func parseCredential(credElement string) (credential, *probe.Error) { | ||||
| 	creds := strings.Split(strings.TrimSpace(credElement), "=") | ||||
| 	if len(creds) != 2 { | ||||
| 		return credScope{}, ErrMissingFields("Credential tag has missing fields.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrMissingFields("Credential tag has missing fields.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	if creds[0] != "Credential" { | ||||
| 		return credScope{}, ErrMissingCredTag("Missing credentials tag.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrMissingCredTag("Missing credentials tag.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	credElements := strings.Split(strings.TrimSpace(creds[1]), "/") | ||||
| 	if len(credElements) != 5 { | ||||
| 		return credScope{}, ErrCredMalformed("Credential values malformed.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrCredMalformed("Credential values malformed.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	if !isValidAccessKey.MatchString(credElements[0]) { | ||||
| 		return credScope{}, ErrInvalidAccessKeyID("Invalid access key id.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrInvalidAccessKeyID("Invalid access key id.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	cred := credScope{ | ||||
| 	cred := credential{ | ||||
| 		accessKeyID: credElements[0], | ||||
| 	} | ||||
| 	var e error | ||||
| 	cred.scope.date, e = time.Parse(yyyymmdd, credElements[1]) | ||||
| 	if e != nil { | ||||
| 		return credScope{}, ErrInvalidDateFormat("Invalid date format.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrInvalidDateFormat("Invalid date format.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	if credElements[2] == "" { | ||||
| 		return credScope{}, ErrRegionISEmpty("Region is empty.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrRegionISEmpty("Region is empty.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	cred.scope.region = credElements[2] | ||||
| 	if credElements[3] != "s3" { | ||||
| 		return credScope{}, ErrInvalidService("Invalid service detected.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrInvalidService("Invalid service detected.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	cred.scope.service = credElements[3] | ||||
| 	if credElements[4] != "aws4_request" { | ||||
| 		return credScope{}, ErrInvalidRequestVersion("Invalid request version detected.", credElement).Trace(credElement) | ||||
| 		return credential{}, ErrInvalidRequestVersion("Invalid request version detected.", credElement).Trace(credElement) | ||||
| 	} | ||||
| 	cred.scope.request = credElements[4] | ||||
| 	return cred, nil | ||||
| } | ||||
| 
 | ||||
| // parse signature. | ||||
| // Parse signature string. | ||||
| func parseSignature(signElement string) (string, *probe.Error) { | ||||
| 	signFields := strings.Split(strings.TrimSpace(signElement), "=") | ||||
| 	if len(signFields) != 2 { | ||||
| @ -69,7 +88,7 @@ func parseSignature(signElement string) (string, *probe.Error) { | ||||
| 	return signature, nil | ||||
| } | ||||
| 
 | ||||
| // parse signed headers. | ||||
| // Parse signed headers string. | ||||
| func parseSignedHeaders(signedHdrElement string) ([]string, *probe.Error) { | ||||
| 	signedHdrFields := strings.Split(strings.TrimSpace(signedHdrElement), "=") | ||||
| 	if len(signedHdrFields) != 2 { | ||||
| @ -82,14 +101,14 @@ func parseSignedHeaders(signedHdrElement string) ([]string, *probe.Error) { | ||||
| 	return signedHeaders, nil | ||||
| } | ||||
| 
 | ||||
| // structured version of AWS Signature V4 header. | ||||
| // signValues data type represents structured form of AWS Signature V4 header. | ||||
| type signValues struct { | ||||
| 	Creds         credScope | ||||
| 	Credential    credential | ||||
| 	SignedHeaders []string | ||||
| 	Signature     string | ||||
| } | ||||
| 
 | ||||
| // structued version of AWS Signature V4 query string. | ||||
| // preSignValues data type represents structued form of AWS Signature V4 query string. | ||||
| type preSignValues struct { | ||||
| 	signValues | ||||
| 	Date    time.Time | ||||
| @ -115,8 +134,8 @@ func parsePreSignV4(query url.Values) (preSignValues, *probe.Error) { | ||||
| 	preSignV4Values := preSignValues{} | ||||
| 
 | ||||
| 	var err *probe.Error | ||||
| 	// Save credentail values. | ||||
| 	preSignV4Values.Creds, err = parseCredential("Credential=" + query.Get("X-Amz-Credential")) | ||||
| 	// Save credential. | ||||
| 	preSignV4Values.Credential, err = parseCredential("Credential=" + query.Get("X-Amz-Credential")) | ||||
| 	if err != nil { | ||||
| 		return preSignValues{}, err.Trace(query.Get("X-Amz-Credential")) | ||||
| 	} | ||||
| @ -181,7 +200,7 @@ func parseSignV4(v4Auth string) (signValues, *probe.Error) { | ||||
| 
 | ||||
| 	var err *probe.Error | ||||
| 	// Save credentail values. | ||||
| 	signV4Values.Creds, err = parseCredential(authFields[0]) | ||||
| 	signV4Values.Credential, err = parseCredential(authFields[0]) | ||||
| 	if err != nil { | ||||
| 		return signValues{}, err.Trace(v4Auth) | ||||
| 	} | ||||
| @ -14,7 +14,7 @@ | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package signature | ||||
| package signature4 | ||||
| 
 | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| @ -14,7 +14,15 @@ | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| package signature | ||||
| // Package signature4 implements helper functions to validate AWS | ||||
| // Signature Version '4' authorization header. | ||||
| // | ||||
| // This package provides comprehensive helpers for following signature | ||||
| // types. | ||||
| // - Based on Authorization header. | ||||
| // - Based on Query parameters. | ||||
| // - Based on Form POST policy. | ||||
| package signature4 | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| @ -30,8 +38,8 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| ) | ||||
| 
 | ||||
| // Signature - local variables | ||||
| type Signature struct { | ||||
| // Sign - local variables | ||||
| type Sign struct { | ||||
| 	accessKeyID            string | ||||
| 	secretAccessKey        string | ||||
| 	region                 string | ||||
| @ -39,6 +47,7 @@ type Signature struct { | ||||
| 	extractedSignedHeaders http.Header | ||||
| } | ||||
| 
 | ||||
| // AWS Signature Version '4' constants. | ||||
| const ( | ||||
| 	signV4Algorithm = "AWS4-HMAC-SHA256" | ||||
| 	iso8601Format   = "20060102T150405Z" | ||||
| @ -46,7 +55,7 @@ const ( | ||||
| ) | ||||
| 
 | ||||
| // New - initialize a new authorization checkes. | ||||
| func New(accessKeyID, secretAccessKey, region string) (*Signature, *probe.Error) { | ||||
| func New(accessKeyID, secretAccessKey, region string) (*Sign, *probe.Error) { | ||||
| 	if !isValidAccessKey.MatchString(accessKeyID) { | ||||
| 		return nil, ErrInvalidAccessKeyID("Invalid access key id.", accessKeyID).Trace(accessKeyID) | ||||
| 	} | ||||
| @ -56,7 +65,7 @@ func New(accessKeyID, secretAccessKey, region string) (*Signature, *probe.Error) | ||||
| 	if region == "" { | ||||
| 		return nil, ErrRegionISEmpty("Region is empty.").Trace() | ||||
| 	} | ||||
| 	signature := &Signature{ | ||||
| 	signature := &Sign{ | ||||
| 		accessKeyID:     accessKeyID, | ||||
| 		secretAccessKey: secretAccessKey, | ||||
| 		region:          region, | ||||
| @ -65,7 +74,7 @@ func New(accessKeyID, secretAccessKey, region string) (*Signature, *probe.Error) | ||||
| } | ||||
| 
 | ||||
| // SetHTTPRequestToVerify - sets the http request which needs to be verified. | ||||
| func (s *Signature) SetHTTPRequestToVerify(r *http.Request) *Signature { | ||||
| func (s *Sign) SetHTTPRequestToVerify(r *http.Request) *Sign { | ||||
| 	// Do not set http request if its 'nil'. | ||||
| 	if r == nil { | ||||
| 		return s | ||||
| @ -75,7 +84,7 @@ func (s *Signature) SetHTTPRequestToVerify(r *http.Request) *Signature { | ||||
| } | ||||
| 
 | ||||
| // getCanonicalHeaders generate a list of request headers with their values | ||||
| func (s Signature) getCanonicalHeaders(signedHeaders http.Header) string { | ||||
| func (s Sign) getCanonicalHeaders(signedHeaders http.Header) string { | ||||
| 	var headers []string | ||||
| 	vals := make(http.Header) | ||||
| 	for k, vv := range signedHeaders { | ||||
| @ -107,7 +116,7 @@ func (s Signature) getCanonicalHeaders(signedHeaders http.Header) string { | ||||
| } | ||||
| 
 | ||||
| // getSignedHeaders generate a string i.e alphabetically sorted, semicolon-separated list of lowercase request header names | ||||
| func (s Signature) getSignedHeaders(signedHeaders http.Header) string { | ||||
| func (s Sign) getSignedHeaders(signedHeaders http.Header) string { | ||||
| 	var headers []string | ||||
| 	for k := range signedHeaders { | ||||
| 		headers = append(headers, strings.ToLower(k)) | ||||
| @ -127,7 +136,7 @@ func (s Signature) getSignedHeaders(signedHeaders http.Header) string { | ||||
| //  <SignedHeaders>\n | ||||
| //  <HashedPayload> | ||||
| // | ||||
| func (s *Signature) getCanonicalRequest() string { | ||||
| func (s *Sign) getCanonicalRequest() string { | ||||
| 	payload := s.httpRequest.Header.Get(http.CanonicalHeaderKey("x-amz-content-sha256")) | ||||
| 	s.httpRequest.URL.RawQuery = strings.Replace(s.httpRequest.URL.Query().Encode(), "+", "%20", -1) | ||||
| 	encodedPath := getURLEncodedName(s.httpRequest.URL.Path) | ||||
| @ -154,7 +163,7 @@ func (s *Signature) getCanonicalRequest() string { | ||||
| //  <SignedHeaders>\n | ||||
| //  <HashedPayload> | ||||
| // | ||||
| func (s Signature) getPresignedCanonicalRequest(presignedQuery string) string { | ||||
| func (s Sign) getPresignedCanonicalRequest(presignedQuery string) string { | ||||
| 	rawQuery := strings.Replace(presignedQuery, "+", "%20", -1) | ||||
| 	encodedPath := getURLEncodedName(s.httpRequest.URL.Path) | ||||
| 	// Convert any space strings back to "+". | ||||
| @ -171,7 +180,7 @@ func (s Signature) getPresignedCanonicalRequest(presignedQuery string) string { | ||||
| } | ||||
| 
 | ||||
| // getScope generate a string of a specific date, an AWS region, and a service. | ||||
| func (s Signature) getScope(t time.Time) string { | ||||
| func (s Sign) getScope(t time.Time) string { | ||||
| 	scope := strings.Join([]string{ | ||||
| 		t.Format(yyyymmdd), | ||||
| 		s.region, | ||||
| @ -182,7 +191,7 @@ func (s Signature) getScope(t time.Time) string { | ||||
| } | ||||
| 
 | ||||
| // getStringToSign a string based on selected query values. | ||||
| func (s Signature) getStringToSign(canonicalRequest string, t time.Time) string { | ||||
| func (s Sign) getStringToSign(canonicalRequest string, t time.Time) string { | ||||
| 	stringToSign := signV4Algorithm + "\n" + t.Format(iso8601Format) + "\n" | ||||
| 	stringToSign = stringToSign + s.getScope(t) + "\n" | ||||
| 	canonicalRequestBytes := sha256.Sum256([]byte(canonicalRequest)) | ||||
| @ -191,7 +200,7 @@ func (s Signature) getStringToSign(canonicalRequest string, t time.Time) string | ||||
| } | ||||
| 
 | ||||
| // getSigningKey hmac seed to calculate final signature. | ||||
| func (s Signature) getSigningKey(t time.Time) []byte { | ||||
| func (s Sign) getSigningKey(t time.Time) []byte { | ||||
| 	secret := s.secretAccessKey | ||||
| 	date := sumHMAC([]byte("AWS4"+secret), []byte(t.Format(yyyymmdd))) | ||||
| 	region := sumHMAC(date, []byte(s.region)) | ||||
| @ -201,27 +210,27 @@ func (s Signature) getSigningKey(t time.Time) []byte { | ||||
| } | ||||
| 
 | ||||
| // getSignature final signature in hexadecimal form. | ||||
| func (s Signature) getSignature(signingKey []byte, stringToSign string) string { | ||||
| func (s Sign) getSignature(signingKey []byte, stringToSign string) string { | ||||
| 	return hex.EncodeToString(sumHMAC(signingKey, []byte(stringToSign))) | ||||
| } | ||||
| 
 | ||||
| // DoesPolicySignatureMatch - Verify query headers with post policy | ||||
| //     - http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html | ||||
| // returns true if matches, false otherwise. if error is not nil then it is always false | ||||
| func (s *Signature) DoesPolicySignatureMatch(formValues map[string]string) (bool, *probe.Error) { | ||||
| func (s *Sign) DoesPolicySignatureMatch(formValues map[string]string) (bool, *probe.Error) { | ||||
| 	// Parse credential tag. | ||||
| 	creds, err := parseCredential("Credential=" + formValues["X-Amz-Credential"]) | ||||
| 	credential, err := parseCredential("Credential=" + formValues["X-Amz-Credential"]) | ||||
| 	if err != nil { | ||||
| 		return false, err.Trace(formValues["X-Amz-Credential"]) | ||||
| 	} | ||||
| 
 | ||||
| 	// Verify if the access key id matches. | ||||
| 	if creds.accessKeyID != s.accessKeyID { | ||||
| 		return false, ErrInvalidAccessKeyID("Access key id does not match with our records.", creds.accessKeyID).Trace(creds.accessKeyID) | ||||
| 	if credential.accessKeyID != s.accessKeyID { | ||||
| 		return false, ErrInvalidAccessKeyID("Access key id does not match with our records.", credential.accessKeyID).Trace(credential.accessKeyID) | ||||
| 	} | ||||
| 
 | ||||
| 	// Verify if the region is valid. | ||||
| 	reqRegion := creds.scope.region | ||||
| 	reqRegion := credential.scope.region | ||||
| 	if !isValidRegion(reqRegion, s.region) { | ||||
| 		return false, ErrInvalidRegion("Requested region is not recognized.", reqRegion).Trace(reqRegion) | ||||
| 	} | ||||
| @ -245,20 +254,20 @@ func (s *Signature) DoesPolicySignatureMatch(formValues map[string]string) (bool | ||||
| // DoesPresignedSignatureMatch - Verify query headers with presigned signature | ||||
| //     - 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 | ||||
| func (s *Signature) DoesPresignedSignatureMatch() (bool, *probe.Error) { | ||||
| func (s *Sign) DoesPresignedSignatureMatch() (bool, *probe.Error) { | ||||
| 	// Parse request query string. | ||||
| 	preSignV4Values, err := parsePreSignV4(s.httpRequest.URL.Query()) | ||||
| 	preSignValues, err := parsePreSignV4(s.httpRequest.URL.Query()) | ||||
| 	if err != nil { | ||||
| 		return false, err.Trace(s.httpRequest.URL.String()) | ||||
| 	} | ||||
| 
 | ||||
| 	// Verify if the access key id matches. | ||||
| 	if preSignV4Values.Creds.accessKeyID != s.accessKeyID { | ||||
| 		return false, ErrInvalidAccessKeyID("Access key id does not match with our records.", preSignV4Values.Creds.accessKeyID).Trace(preSignV4Values.Creds.accessKeyID) | ||||
| 	if preSignValues.Credential.accessKeyID != s.accessKeyID { | ||||
| 		return false, ErrInvalidAccessKeyID("Access key id does not match with our records.", preSignValues.Credential.accessKeyID).Trace(preSignValues.Credential.accessKeyID) | ||||
| 	} | ||||
| 
 | ||||
| 	// Verify if region is valid. | ||||
| 	reqRegion := preSignV4Values.Creds.scope.region | ||||
| 	reqRegion := preSignValues.Credential.scope.region | ||||
| 	if !isValidRegion(reqRegion, s.region) { | ||||
| 		return false, ErrInvalidRegion("Requested region is not recognized.", reqRegion).Trace(reqRegion) | ||||
| 	} | ||||
| @ -267,19 +276,19 @@ func (s *Signature) DoesPresignedSignatureMatch() (bool, *probe.Error) { | ||||
| 	s.region = reqRegion | ||||
| 
 | ||||
| 	// Extract all the signed headers along with its values. | ||||
| 	s.extractedSignedHeaders = extractSignedHeaders(preSignV4Values.SignedHeaders, s.httpRequest.Header) | ||||
| 	s.extractedSignedHeaders = extractSignedHeaders(preSignValues.SignedHeaders, s.httpRequest.Header) | ||||
| 
 | ||||
| 	// Construct new query. | ||||
| 	query := make(url.Values) | ||||
| 	query.Set("X-Amz-Algorithm", signV4Algorithm) | ||||
| 
 | ||||
| 	if time.Now().UTC().Sub(preSignV4Values.Date) > time.Duration(preSignV4Values.Expires) { | ||||
| 	if time.Now().UTC().Sub(preSignValues.Date) > time.Duration(preSignValues.Expires) { | ||||
| 		return false, ErrExpiredPresignRequest("Presigned request already expired, please initiate a new request.") | ||||
| 	} | ||||
| 
 | ||||
| 	// Save the date and expires. | ||||
| 	t := preSignV4Values.Date | ||||
| 	expireSeconds := int(time.Duration(preSignV4Values.Expires) / time.Second) | ||||
| 	t := preSignValues.Date | ||||
| 	expireSeconds := int(time.Duration(preSignValues.Expires) / time.Second) | ||||
| 
 | ||||
| 	// Construct the query. | ||||
| 	query.Set("X-Amz-Date", t.Format(iso8601Format)) | ||||
| @ -325,7 +334,7 @@ func (s *Signature) DoesPresignedSignatureMatch() (bool, *probe.Error) { | ||||
| // DoesSignatureMatch - Verify authorization header with calculated header in accordance with | ||||
| //     - 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 | ||||
| func (s *Signature) DoesSignatureMatch(hashedPayload string) (bool, *probe.Error) { | ||||
| func (s *Sign) DoesSignatureMatch(hashedPayload string) (bool, *probe.Error) { | ||||
| 	// Save authorization header. | ||||
| 	v4Auth := s.httpRequest.Header.Get("Authorization") | ||||
| 
 | ||||
| @ -339,12 +348,12 @@ func (s *Signature) DoesSignatureMatch(hashedPayload string) (bool, *probe.Error | ||||
| 	s.extractedSignedHeaders = extractSignedHeaders(signV4Values.SignedHeaders, s.httpRequest.Header) | ||||
| 
 | ||||
| 	// Verify if the access key id matches. | ||||
| 	if signV4Values.Creds.accessKeyID != s.accessKeyID { | ||||
| 		return false, ErrInvalidAccessKeyID("Access key id does not match with our records.", signV4Values.Creds.accessKeyID).Trace(signV4Values.Creds.accessKeyID) | ||||
| 	if signV4Values.Credential.accessKeyID != s.accessKeyID { | ||||
| 		return false, ErrInvalidAccessKeyID("Access key id does not match with our records.", signV4Values.Credential.accessKeyID).Trace(signV4Values.Credential.accessKeyID) | ||||
| 	} | ||||
| 
 | ||||
| 	// Verify if region is valid. | ||||
| 	reqRegion := signV4Values.Creds.scope.region | ||||
| 	reqRegion := signV4Values.Credential.scope.region | ||||
| 	if !isValidRegion(reqRegion, s.region) { | ||||
| 		return false, ErrInvalidRegion("Requested region is not recognized.", reqRegion).Trace(reqRegion) | ||||
| 	} | ||||
| @ -1,4 +1,20 @@ | ||||
| package signature | ||||
| /* | ||||
|  * 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 signature4 | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/hmac" | ||||
| @ -11,12 +27,6 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/crypto/sha256" | ||||
| ) | ||||
| 
 | ||||
| // AccessID and SecretID length in bytes | ||||
| const ( | ||||
| 	MinioAccessID = 20 | ||||
| 	MinioSecretID = 40 | ||||
| ) | ||||
| 
 | ||||
| /// helpers | ||||
| 
 | ||||
| // isValidSecretKey - validate secret key. | ||||
| @ -34,7 +34,7 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/crypto/sha256" | ||||
| 	"github.com/minio/minio/pkg/crypto/sha512" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| 	"github.com/minio/minio/pkg/xl/block" | ||||
| ) | ||||
| 
 | ||||
| @ -236,7 +236,7 @@ func (b bucket) ReadObject(objectName string) (reader io.ReadCloser, size int64, | ||||
| } | ||||
| 
 | ||||
| // WriteObject - write a new object into bucket | ||||
| func (b bucket) WriteObject(objectName string, objectData io.Reader, size int64, expectedMD5Sum string, metadata map[string]string, signature *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (b bucket) WriteObject(objectName string, objectData io.Reader, size int64, expectedMD5Sum string, metadata map[string]string, signature *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	b.lock.Lock() | ||||
| 	defer b.lock.Unlock() | ||||
| 	if objectName == "" || objectData == nil { | ||||
|  | ||||
| @ -20,7 +20,7 @@ import ( | ||||
| 	"io" | ||||
| 
 | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| ) | ||||
| 
 | ||||
| // Collection of XL specification interfaces | ||||
| @ -37,7 +37,7 @@ type CloudStorage interface { | ||||
| 	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 | ||||
| 	MakeBucket(bucket string, ACL string, location io.Reader, signature *signature4.Sign) *probe.Error | ||||
| 
 | ||||
| 	// Bucket operations | ||||
| 	ListObjects(string, BucketResourcesMetadata) ([]ObjectMetadata, BucketResourcesMetadata, *probe.Error) | ||||
| @ -46,7 +46,7 @@ type CloudStorage interface { | ||||
| 	GetObject(w io.Writer, bucket, object string, start, length int64) (int64, *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) | ||||
| 	CreateObject(string, string, string, int64, io.Reader, map[string]string, *signature4.Sign) (ObjectMetadata, *probe.Error) | ||||
| 
 | ||||
| 	Multipart | ||||
| } | ||||
| @ -55,8 +55,8 @@ type CloudStorage interface { | ||||
| type Multipart interface { | ||||
| 	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) | ||||
| 	CreateObjectPart(string, string, string, int, string, string, int64, io.Reader, *signature4.Sign) (string, *probe.Error) | ||||
| 	CompleteMultipartUpload(bucket, key, uploadID string, data io.Reader, signature *signature4.Sign) (ObjectMetadata, *probe.Error) | ||||
| 	ListMultipartUploads(string, BucketMultipartResourcesMetadata) (BucketMultipartResourcesMetadata, *probe.Error) | ||||
| 	ListObjectParts(string, string, ObjectResourcesMetadata) (ObjectResourcesMetadata, *probe.Error) | ||||
| } | ||||
|  | ||||
| @ -35,7 +35,7 @@ import ( | ||||
| 
 | ||||
| 	"github.com/minio/minio/pkg/crypto/sha256" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| 	"github.com/minio/minio/pkg/xl/cache/data" | ||||
| ) | ||||
| 
 | ||||
| @ -109,7 +109,7 @@ func (xl API) AbortMultipartUpload(bucket, key, uploadID string) *probe.Error { | ||||
| } | ||||
| 
 | ||||
| // CreateObjectPart - create a part in a multipart session | ||||
| func (xl API) CreateObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *signV4.Signature) (string, *probe.Error) { | ||||
| func (xl API) CreateObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *signature4.Sign) (string, *probe.Error) { | ||||
| 	xl.lock.Lock() | ||||
| 	etag, err := xl.createObjectPart(bucket, key, uploadID, partID, "", expectedMD5Sum, size, data, signature) | ||||
| 	xl.lock.Unlock() | ||||
| @ -120,7 +120,7 @@ func (xl API) CreateObjectPart(bucket, key, uploadID string, partID int, content | ||||
| } | ||||
| 
 | ||||
| // createObject - internal wrapper function called by CreateObjectPart | ||||
| func (xl API) createObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *signV4.Signature) (string, *probe.Error) { | ||||
| func (xl API) createObjectPart(bucket, key, uploadID string, partID int, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *signature4.Sign) (string, *probe.Error) { | ||||
| 	if !IsValidBucket(bucket) { | ||||
| 		return "", probe.NewError(BucketNameInvalid{Bucket: bucket}) | ||||
| 	} | ||||
| @ -289,7 +289,7 @@ func (xl API) mergeMultipart(parts *CompleteMultipartUpload, uploadID string, fu | ||||
| } | ||||
| 
 | ||||
| // CompleteMultipartUpload - complete a multipart upload and persist the data | ||||
| func (xl API) CompleteMultipartUpload(bucket, key, uploadID string, data io.Reader, signature *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (xl API) CompleteMultipartUpload(bucket, key, uploadID string, data io.Reader, signature *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	xl.lock.Lock() | ||||
| 	defer xl.lock.Unlock() | ||||
| 	size := int64(xl.multiPartObjects[uploadID].Stats().Bytes) | ||||
| @ -307,7 +307,7 @@ func (xl API) CompleteMultipartUpload(bucket, key, uploadID string, data io.Read | ||||
| 	return objectMetadata, nil | ||||
| } | ||||
| 
 | ||||
| func (xl API) completeMultipartUploadV2(bucket, key, uploadID string, data io.Reader, signature *signV4.Signature) (io.Reader, *probe.Error) { | ||||
| func (xl API) completeMultipartUploadV2(bucket, key, uploadID string, data io.Reader, signature *signature4.Sign) (io.Reader, *probe.Error) { | ||||
| 	if !IsValidBucket(bucket) { | ||||
| 		return nil, probe.NewError(BucketNameInvalid{Bucket: bucket}) | ||||
| 	} | ||||
|  | ||||
| @ -35,7 +35,7 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/crypto/sha256" | ||||
| 	"github.com/minio/minio/pkg/crypto/sha512" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| 	"github.com/minio/minio/pkg/xl/block" | ||||
| ) | ||||
| 
 | ||||
| @ -128,7 +128,7 @@ func (xl API) listObjects(bucket, prefix, marker, delimiter string, maxkeys int) | ||||
| } | ||||
| 
 | ||||
| // putObject - put object | ||||
| func (xl API) putObject(bucket, object, expectedMD5Sum string, reader io.Reader, size int64, metadata map[string]string, signature *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (xl API) putObject(bucket, object, expectedMD5Sum string, reader io.Reader, size int64, metadata map[string]string, signature *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	if bucket == "" || strings.TrimSpace(bucket) == "" { | ||||
| 		return ObjectMetadata{}, probe.NewError(InvalidArgument{}) | ||||
| 	} | ||||
| @ -160,7 +160,7 @@ func (xl API) putObject(bucket, object, expectedMD5Sum string, reader io.Reader, | ||||
| } | ||||
| 
 | ||||
| // putObject - put object | ||||
| func (xl API) putObjectPart(bucket, object, expectedMD5Sum, uploadID string, partID int, reader io.Reader, size int64, metadata map[string]string, signature *signV4.Signature) (PartMetadata, *probe.Error) { | ||||
| func (xl API) putObjectPart(bucket, object, expectedMD5Sum, uploadID string, partID int, reader io.Reader, size int64, metadata map[string]string, signature *signature4.Sign) (PartMetadata, *probe.Error) { | ||||
| 	if bucket == "" || strings.TrimSpace(bucket) == "" { | ||||
| 		return PartMetadata{}, probe.NewError(InvalidArgument{}) | ||||
| 	} | ||||
| @ -337,7 +337,7 @@ func (xl API) listObjectParts(bucket, object string, resources ObjectResourcesMe | ||||
| } | ||||
| 
 | ||||
| // completeMultipartUpload complete an incomplete multipart upload | ||||
| func (xl API) completeMultipartUpload(bucket, object, uploadID string, data io.Reader, signature *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (xl API) completeMultipartUpload(bucket, object, uploadID string, data io.Reader, signature *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	if bucket == "" || strings.TrimSpace(bucket) == "" { | ||||
| 		return ObjectMetadata{}, probe.NewError(InvalidArgument{}) | ||||
| 	} | ||||
|  | ||||
| @ -34,7 +34,7 @@ import ( | ||||
| 	"github.com/minio/minio/pkg/crypto/sha256" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	"github.com/minio/minio/pkg/quick" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| 	"github.com/minio/minio/pkg/xl/cache/data" | ||||
| 	"github.com/minio/minio/pkg/xl/cache/metadata" | ||||
| ) | ||||
| @ -267,7 +267,7 @@ func isMD5SumEqual(expectedMD5Sum, actualMD5Sum string) *probe.Error { | ||||
| } | ||||
| 
 | ||||
| // CreateObject - create an object | ||||
| func (xl API) CreateObject(bucket, key, expectedMD5Sum string, size int64, data io.Reader, metadata map[string]string, signature *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (xl API) CreateObject(bucket, key, expectedMD5Sum string, size int64, data io.Reader, metadata map[string]string, signature *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	xl.lock.Lock() | ||||
| 	defer xl.lock.Unlock() | ||||
| 
 | ||||
| @ -280,7 +280,7 @@ func (xl API) CreateObject(bucket, key, expectedMD5Sum string, size int64, data | ||||
| } | ||||
| 
 | ||||
| // createObject - PUT object to cache buffer | ||||
| func (xl API) createObject(bucket, key, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *signV4.Signature) (ObjectMetadata, *probe.Error) { | ||||
| func (xl API) createObject(bucket, key, contentType, expectedMD5Sum string, size int64, data io.Reader, signature *signature4.Sign) (ObjectMetadata, *probe.Error) { | ||||
| 	if len(xl.config.NodeDiskMap) == 0 { | ||||
| 		if size > int64(xl.config.MaxSize) { | ||||
| 			generic := GenericObjectError{Bucket: bucket, Object: key} | ||||
| @ -414,7 +414,7 @@ func (xl API) createObject(bucket, key, contentType, expectedMD5Sum string, size | ||||
| } | ||||
| 
 | ||||
| // MakeBucket - create bucket in cache | ||||
| func (xl API) MakeBucket(bucketName, acl string, location io.Reader, signature *signV4.Signature) *probe.Error { | ||||
| func (xl API) MakeBucket(bucketName, acl string, location io.Reader, signature *signature4.Sign) *probe.Error { | ||||
| 	xl.lock.Lock() | ||||
| 	defer xl.lock.Unlock() | ||||
| 
 | ||||
|  | ||||
| @ -27,7 +27,7 @@ import ( | ||||
| 	"github.com/minio/minio-go" | ||||
| 	"github.com/minio/minio/pkg/fs" | ||||
| 	"github.com/minio/minio/pkg/probe" | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| 	"github.com/minio/minio/pkg/s3/signature4" | ||||
| ) | ||||
| 
 | ||||
| // storageAPI container for S3 compatible API. | ||||
| @ -37,7 +37,7 @@ type storageAPI struct { | ||||
| 	// Filesystem instance. | ||||
| 	Filesystem fs.Filesystem | ||||
| 	// Signature instance. | ||||
| 	Signature *signV4.Signature | ||||
| 	Signature *signature4.Sign | ||||
| 	// Region instance. | ||||
| 	Region string | ||||
| } | ||||
| @ -141,7 +141,7 @@ func initAPI(conf cloudServerConfig) storageAPI { | ||||
| 	fs, err := fs.New(conf.Path, conf.MinFreeDisk) | ||||
| 	fatalIf(err.Trace(), "Initializing filesystem failed.", nil) | ||||
| 
 | ||||
| 	sign, err := signV4.New(conf.AccessKeyID, conf.SecretAccessKey, conf.Region) | ||||
| 	sign, err := signature4.New(conf.AccessKeyID, conf.SecretAccessKey, conf.Region) | ||||
| 	fatalIf(err.Trace(conf.AccessKeyID, conf.SecretAccessKey, conf.Region), "Initializing signature version '4' failed.", nil) | ||||
| 
 | ||||
| 	return storageAPI{ | ||||
|  | ||||
							
								
								
									
										94
									
								
								signature.go
									
									
									
									
									
								
							
							
						
						
									
										94
									
								
								signature.go
									
									
									
									
									
								
							| @ -1,94 +0,0 @@ | ||||
| /* | ||||
|  * 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 main | ||||
| 
 | ||||
| import ( | ||||
| 	"crypto/sha256" | ||||
| 	"encoding/hex" | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	signV4 "github.com/minio/minio/pkg/signature" | ||||
| ) | ||||
| 
 | ||||
| // Verify if request has JWT. | ||||
| func isRequestJWT(r *http.Request) bool { | ||||
| 	if _, ok := r.Header["Authorization"]; ok { | ||||
| 		if strings.HasPrefix(r.Header.Get("Authorization"), jwtAlgorithm) { | ||||
| 			return ok | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request has AWS Signature Version '4'. | ||||
| func isRequestSignatureV4(r *http.Request) bool { | ||||
| 	if _, ok := r.Header["Authorization"]; ok { | ||||
| 		if strings.HasPrefix(r.Header.Get("Authorization"), signV4Algorithm) { | ||||
| 			return ok | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request has AWS Presignature Version '4'. | ||||
| func isRequestPresignedSignatureV4(r *http.Request) bool { | ||||
| 	if _, ok := r.URL.Query()["X-Amz-Credential"]; ok { | ||||
| 		return ok | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request has AWS Post policy Signature Version '4'. | ||||
| func isRequestPostPolicySignatureV4(r *http.Request) bool { | ||||
| 	if _, ok := r.Header["Content-Type"]; ok { | ||||
| 		if strings.Contains(r.Header.Get("Content-Type"), "multipart/form-data") { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // Verify if request requires ACL check. | ||||
| func isRequestRequiresACLCheck(r *http.Request) bool { | ||||
| 	if isRequestSignatureV4(r) || isRequestPresignedSignatureV4(r) || isRequestPostPolicySignatureV4(r) { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // Verify if request has valid AWS Signature Version '4'. | ||||
| func isSignV4ReqAuthenticated(sign *signV4.Signature, r *http.Request) bool { | ||||
| 	auth := sign.SetHTTPRequestToVerify(r) | ||||
| 	if isRequestSignatureV4(r) { | ||||
| 		dummyPayload := sha256.Sum256([]byte("")) | ||||
| 		ok, err := auth.DoesSignatureMatch(hex.EncodeToString(dummyPayload[:])) | ||||
| 		if err != nil { | ||||
| 			errorIf(err.Trace(), "Signature verification failed.", nil) | ||||
| 			return false | ||||
| 		} | ||||
| 		return ok | ||||
| 	} else if isRequestPresignedSignatureV4(r) { | ||||
| 		ok, err := auth.DoesPresignedSignatureMatch() | ||||
| 		if err != nil { | ||||
| 			errorIf(err.Trace(), "Presigned signature verification failed.", nil) | ||||
| 			return false | ||||
| 		} | ||||
| 		return ok | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user