diff options
Diffstat (limited to 'pkg/s3signer')
-rw-r--r-- | pkg/s3signer/request-signature-streaming.go | 7 | ||||
-rw-r--r-- | pkg/s3signer/request-signature-streaming_test.go | 7 | ||||
-rw-r--r-- | pkg/s3signer/request-signature-v2.go | 50 | ||||
-rw-r--r-- | pkg/s3signer/request-signature-v2_test.go | 3 | ||||
-rw-r--r-- | pkg/s3signer/request-signature-v4.go | 3 | ||||
-rw-r--r-- | pkg/s3signer/request-signature_test.go | 3 | ||||
-rw-r--r-- | pkg/s3signer/test-utils_test.go | 3 | ||||
-rw-r--r-- | pkg/s3signer/utils.go | 3 | ||||
-rw-r--r-- | pkg/s3signer/utils_test.go | 10 |
9 files changed, 49 insertions, 40 deletions
diff --git a/pkg/s3signer/request-signature-streaming.go b/pkg/s3signer/request-signature-streaming.go index 22059bb..156a6d6 100644 --- a/pkg/s3signer/request-signature-streaming.go +++ b/pkg/s3signer/request-signature-streaming.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2017 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,7 +33,6 @@ import ( // http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-streaming.html#example-signature-calculations-streaming const ( streamingSignAlgorithm = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD" - streamingEncoding = "aws-chunked" streamingPayloadHdr = "AWS4-HMAC-SHA256-PAYLOAD" emptySHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" payloadChunkSize = 64 * 1024 @@ -99,9 +99,8 @@ func prepareStreamingRequest(req *http.Request, sessionToken string, dataLen int if sessionToken != "" { req.Header.Set("X-Amz-Security-Token", sessionToken) } - req.Header.Set("Content-Encoding", streamingEncoding) - req.Header.Set("X-Amz-Date", timestamp.Format(iso8601DateFormat)) + req.Header.Set("X-Amz-Date", timestamp.Format(iso8601DateFormat)) // Set content length with streaming signature for each chunk included. req.ContentLength = getStreamLength(dataLen, int64(payloadChunkSize)) req.Header.Set("x-amz-decoded-content-length", strconv.FormatInt(dataLen, 10)) diff --git a/pkg/s3signer/request-signature-streaming_test.go b/pkg/s3signer/request-signature-streaming_test.go index 1f49f22..535adb3 100644 --- a/pkg/s3signer/request-signature-streaming_test.go +++ b/pkg/s3signer/request-signature-streaming_test.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2017 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +43,7 @@ func TestGetSeedSignature(t *testing.T) { req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", "us-east-1", int64(dataLen), reqTime) actualSeedSignature := req.Body.(*StreamingReader).seedSignature - expectedSeedSignature := "007480502de61457e955731b0f5d191f7e6f54a8a0f6cc7974a5ebd887965686" + expectedSeedSignature := "38cab3af09aa15ddf29e26e36236f60fb6bfb6243a20797ae9a8183674526079" if actualSeedSignature != expectedSeedSignature { t.Errorf("Expected %s but received %s", expectedSeedSignature, actualSeedSignature) } @@ -74,7 +75,7 @@ func TestSetStreamingAuthorization(t *testing.T) { reqTime, _ := time.Parse(iso8601DateFormat, "20130524T000000Z") req = StreamingSignV4(req, accessKeyID, secretAccessKeyID, "", location, dataLen, reqTime) - expectedAuthorization := "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=content-encoding;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=007480502de61457e955731b0f5d191f7e6f54a8a0f6cc7974a5ebd887965686" + expectedAuthorization := "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,Signature=38cab3af09aa15ddf29e26e36236f60fb6bfb6243a20797ae9a8183674526079" actualAuthorization := req.Header.Get("Authorization") if actualAuthorization != expectedAuthorization { diff --git a/pkg/s3signer/request-signature-v2.go b/pkg/s3signer/request-signature-v2.go index af0e915..620af1c 100644 --- a/pkg/s3signer/request-signature-v2.go +++ b/pkg/s3signer/request-signature-v2.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2015 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,9 +43,7 @@ const ( func encodeURL2Path(u *url.URL) (path string) { // Encode URL path. if isS3, _ := filepath.Match("*.s3*.amazonaws.com", u.Host); isS3 { - hostSplits := strings.SplitN(u.Host, ".", 4) - // First element is the bucket name. - bucketName := hostSplits[0] + bucketName := u.Host[:strings.LastIndex(u.Host, ".s3")] path = "/" + bucketName path += u.Path path = s3utils.EncodePath(path) @@ -78,7 +77,7 @@ func PreSignV2(req http.Request, accessKeyID, secretAccessKey string, expires in } // Get presigned string to sign. - stringToSign := preStringifyHTTPReq(req) + stringToSign := preStringToSignV2(req) hm := hmac.New(sha1.New, []byte(secretAccessKey)) hm.Write([]byte(stringToSign)) @@ -147,7 +146,7 @@ func SignV2(req http.Request, accessKeyID, secretAccessKey string) *http.Request } // Calculate HMAC for secretAccessKey. - stringToSign := stringifyHTTPReq(req) + stringToSign := stringToSignV2(req) hm := hmac.New(sha1.New, []byte(secretAccessKey)) hm.Write([]byte(stringToSign)) @@ -172,15 +171,14 @@ func SignV2(req http.Request, accessKeyID, secretAccessKey string) *http.Request // Expires + "\n" + // CanonicalizedProtocolHeaders + // CanonicalizedResource; -func preStringifyHTTPReq(req http.Request) string { +func preStringToSignV2(req http.Request) string { buf := new(bytes.Buffer) // Write standard headers. writePreSignV2Headers(buf, req) // Write canonicalized protocol headers if any. writeCanonicalizedHeaders(buf, req) // Write canonicalized Query resources if any. - isPreSign := true - writeCanonicalizedResource(buf, req, isPreSign) + writeCanonicalizedResource(buf, req) return buf.String() } @@ -200,15 +198,14 @@ func writePreSignV2Headers(buf *bytes.Buffer, req http.Request) { // Date + "\n" + // CanonicalizedProtocolHeaders + // CanonicalizedResource; -func stringifyHTTPReq(req http.Request) string { +func stringToSignV2(req http.Request) string { buf := new(bytes.Buffer) // Write standard headers. writeSignV2Headers(buf, req) // Write canonicalized protocol headers if any. writeCanonicalizedHeaders(buf, req) // Write canonicalized Query resources if any. - isPreSign := false - writeCanonicalizedResource(buf, req, isPreSign) + writeCanonicalizedResource(buf, req) return buf.String() } @@ -255,17 +252,27 @@ func writeCanonicalizedHeaders(buf *bytes.Buffer, req http.Request) { } } -// The following list is already sorted and should always be, otherwise we could -// have signature-related issues +// AWS S3 Signature V2 calculation rule is give here: +// http://docs.aws.amazon.com/AmazonS3/latest/dev/RESTAuthentication.html#RESTAuthenticationStringToSign + +// Whitelist resource list that will be used in query string for signature-V2 calculation. +// The list should be alphabetically sorted var resourceList = []string{ "acl", "delete", + "lifecycle", "location", "logging", "notification", "partNumber", "policy", "requestPayment", + "response-cache-control", + "response-content-disposition", + "response-content-encoding", + "response-content-language", + "response-content-type", + "response-expires", "torrent", "uploadId", "uploads", @@ -280,22 +287,11 @@ var resourceList = []string{ // CanonicalizedResource = [ "/" + Bucket ] + // <HTTP-Request-URI, from the protocol name up to the query string> + // [ sub-resource, if present. For example "?acl", "?location", "?logging", or "?torrent"]; -func writeCanonicalizedResource(buf *bytes.Buffer, req http.Request, isPreSign bool) { +func writeCanonicalizedResource(buf *bytes.Buffer, req http.Request) { // Save request URL. requestURL := req.URL // Get encoded URL path. - path := encodeURL2Path(requestURL) - if isPreSign { - // Get encoded URL path. - if len(requestURL.Query()) > 0 { - // Keep the usual queries unescaped for string to sign. - query, _ := url.QueryUnescape(s3utils.QueryEncode(requestURL.Query())) - path = path + "?" + query - } - buf.WriteString(path) - return - } - buf.WriteString(path) + buf.WriteString(encodeURL2Path(requestURL)) if requestURL.RawQuery != "" { var n int vals, _ := url.ParseQuery(requestURL.RawQuery) diff --git a/pkg/s3signer/request-signature-v2_test.go b/pkg/s3signer/request-signature-v2_test.go index 3c0e0ec..042b6e6 100644 --- a/pkg/s3signer/request-signature-v2_test.go +++ b/pkg/s3signer/request-signature-v2_test.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2015, 2016 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkg/s3signer/request-signature-v4.go b/pkg/s3signer/request-signature-v4.go index 0d75dc1..d5721ac 100644 --- a/pkg/s3signer/request-signature-v4.go +++ b/pkg/s3signer/request-signature-v4.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2015 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkg/s3signer/request-signature_test.go b/pkg/s3signer/request-signature_test.go index 85ff063..d53483e 100644 --- a/pkg/s3signer/request-signature_test.go +++ b/pkg/s3signer/request-signature_test.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2015, 2016 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkg/s3signer/test-utils_test.go b/pkg/s3signer/test-utils_test.go index 049e581..cf96d66 100644 --- a/pkg/s3signer/test-utils_test.go +++ b/pkg/s3signer/test-utils_test.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2015 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkg/s3signer/utils.go b/pkg/s3signer/utils.go index 0619b30..2924363 100644 --- a/pkg/s3signer/utils.go +++ b/pkg/s3signer/utils.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2015 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/pkg/s3signer/utils_test.go b/pkg/s3signer/utils_test.go index b266e42..22a2d65 100644 --- a/pkg/s3signer/utils_test.go +++ b/pkg/s3signer/utils_test.go @@ -1,5 +1,6 @@ /* - * Minio Go Library for Amazon S3 Compatible Cloud Storage (C) 2015 Minio, Inc. + * Minio Go Library for Amazon S3 Compatible Cloud Storage + * Copyright 2015-2017 Minio, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +26,7 @@ import ( // Tests url encoding. func TestEncodeURL2Path(t *testing.T) { type urlStrings struct { + bucketName string objName string encodedObjName string } @@ -32,22 +34,27 @@ func TestEncodeURL2Path(t *testing.T) { bucketName := "bucketName" want := []urlStrings{ { + bucketName: "bucketName", objName: "本語", encodedObjName: "%E6%9C%AC%E8%AA%9E", }, { + bucketName: "bucketName", objName: "本語.1", encodedObjName: "%E6%9C%AC%E8%AA%9E.1", }, { objName: ">123>3123123", + bucketName: "bucketName", encodedObjName: "%3E123%3E3123123", }, { + bucketName: "bucketName", objName: "test 1 2.txt", encodedObjName: "test%201%202.txt", }, { + bucketName: "test.bucketName", objName: "test++ 1.txt", encodedObjName: "test%2B%2B%201.txt", }, @@ -63,4 +70,5 @@ func TestEncodeURL2Path(t *testing.T) { t.Fatal("Error") } } + } |