aboutsummaryrefslogtreecommitdiff
path: root/weed/s3api/auto_signature_v4_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'weed/s3api/auto_signature_v4_test.go')
-rw-r--r--weed/s3api/auto_signature_v4_test.go112
1 files changed, 54 insertions, 58 deletions
diff --git a/weed/s3api/auto_signature_v4_test.go b/weed/s3api/auto_signature_v4_test.go
index 86fbbd19e..b8b817ab8 100644
--- a/weed/s3api/auto_signature_v4_test.go
+++ b/weed/s3api/auto_signature_v4_test.go
@@ -6,13 +6,10 @@ import (
"crypto/sha256"
"encoding/base64"
"encoding/hex"
- "errors"
"fmt"
"io"
"net/http"
- "net/url"
"sort"
- "strconv"
"strings"
"sync"
"testing"
@@ -76,7 +73,7 @@ func TestIsReqAuthenticated(t *testing.T) {
SecretKey: "secret_key_1",
},
},
- Actions: []string{},
+ Actions: []string{"Read", "Write"},
},
},
})
@@ -149,7 +146,7 @@ func TestCheckAdminRequestAuthType(t *testing.T) {
SecretKey: "secret_key_1",
},
},
- Actions: []string{},
+ Actions: []string{"Admin", "Read", "Write"},
},
},
})
@@ -170,15 +167,12 @@ func TestCheckAdminRequestAuthType(t *testing.T) {
func BenchmarkGetSignature(b *testing.B) {
t := time.Now()
- iam := IdentityAccessManagement{
- hashes: make(map[string]*sync.Pool),
- hashCounters: make(map[string]*int32),
- }
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
- iam.getSignature("secret-key", t, "us-east-1", "s3", "random data")
+ signingKey := getSigningKey("secret-key", t.Format(yyyymmdd), "us-east-1", "s3")
+ getSignature(signingKey, "random data")
}
}
@@ -213,6 +207,53 @@ func mustNewPresignedRequest(iam *IdentityAccessManagement, method string, urlSt
return req
}
+// preSignV4 adds presigned URL parameters to the request
+func preSignV4(iam *IdentityAccessManagement, req *http.Request, accessKey, secretKey string, expires int64) error {
+ // Create credential scope
+ now := time.Now().UTC()
+ dateStr := now.Format(iso8601Format)
+
+ // Create credential header
+ scope := fmt.Sprintf("%s/%s/%s/%s", now.Format(yyyymmdd), "us-east-1", "s3", "aws4_request")
+ credential := fmt.Sprintf("%s/%s", accessKey, scope)
+
+ // Get the query parameters
+ query := req.URL.Query()
+ query.Set("X-Amz-Algorithm", signV4Algorithm)
+ query.Set("X-Amz-Credential", credential)
+ query.Set("X-Amz-Date", dateStr)
+ query.Set("X-Amz-Expires", fmt.Sprintf("%d", expires))
+ query.Set("X-Amz-SignedHeaders", "host")
+
+ // Set the query on the URL (without signature yet)
+ req.URL.RawQuery = query.Encode()
+
+ // Get the payload hash
+ hashedPayload := getContentSha256Cksum(req)
+
+ // Extract signed headers
+ extractedSignedHeaders := make(http.Header)
+ extractedSignedHeaders["host"] = []string{req.Host}
+
+ // Get canonical request
+ canonicalRequest := getCanonicalRequest(extractedSignedHeaders, hashedPayload, req.URL.RawQuery, req.URL.Path, req.Method)
+
+ // Get string to sign
+ stringToSign := getStringToSign(canonicalRequest, now, scope)
+
+ // Get signing key
+ signingKey := getSigningKey(secretKey, now.Format(yyyymmdd), "us-east-1", "s3")
+
+ // Calculate signature
+ signature := getSignature(signingKey, stringToSign)
+
+ // Add signature to query
+ query.Set("X-Amz-Signature", signature)
+ req.URL.RawQuery = query.Encode()
+
+ return nil
+}
+
// Returns new HTTP request object.
func newTestRequest(method, urlStr string, contentLength int64, body io.ReadSeeker) (*http.Request, error) {
if method == "" {
@@ -254,11 +295,6 @@ func newTestRequest(method, urlStr string, contentLength int64, body io.ReadSeek
return req, nil
}
-// getSHA256Hash returns SHA-256 hash in hex encoding of given data.
-func getSHA256Hash(data []byte) string {
- return hex.EncodeToString(getSHA256Sum(data))
-}
-
// getMD5HashBase64 returns MD5 hash in base64 encoding of given data.
func getMD5HashBase64(data []byte) string {
return base64.StdEncoding.EncodeToString(getMD5Sum(data))
@@ -467,46 +503,6 @@ func signRequestV4(req *http.Request, accessKey, secretKey string) error {
return nil
}
-// preSignV4 presign the request, in accordance with
-// http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html.
-func preSignV4(iam *IdentityAccessManagement, req *http.Request, accessKeyID, secretAccessKey string, expires int64) error {
- // Presign is not needed for anonymous credentials.
- if accessKeyID == "" || secretAccessKey == "" {
- return errors.New("Presign cannot be generated without access and secret keys")
- }
-
- region := "us-east-1"
- date := time.Now().UTC()
- scope := getScope(date, region)
- credential := fmt.Sprintf("%s/%s", accessKeyID, scope)
-
- // Set URL query.
- query := req.URL.Query()
- query.Set("X-Amz-Algorithm", signV4Algorithm)
- query.Set("X-Amz-Date", date.Format(iso8601Format))
- query.Set("X-Amz-Expires", strconv.FormatInt(expires, 10))
- query.Set("X-Amz-SignedHeaders", "host")
- query.Set("X-Amz-Credential", credential)
- query.Set("X-Amz-Content-Sha256", unsignedPayload)
-
- // "host" is the only header required to be signed for Presigned URLs.
- extractedSignedHeaders := make(http.Header)
- extractedSignedHeaders.Set("host", req.Host)
-
- queryStr := strings.Replace(query.Encode(), "+", "%20", -1)
- canonicalRequest := getCanonicalRequest(extractedSignedHeaders, unsignedPayload, queryStr, req.URL.Path, req.Method)
- stringToSign := getStringToSign(canonicalRequest, date, scope)
- signature := iam.getSignature(secretAccessKey, date, region, "s3", stringToSign)
-
- req.URL.RawQuery = query.Encode()
-
- // Add signature header to RawQuery.
- req.URL.RawQuery += "&X-Amz-Signature=" + url.QueryEscape(signature)
-
- // Construct the final presigned URL.
- return nil
-}
-
// EncodePath encode the strings from UTF-8 byte representations to HTML hex escape sequences
//
// This is necessary since regular url.Parse() and url.Encode() functions do not support UTF-8
@@ -529,12 +525,12 @@ func EncodePath(pathName string) string {
encodedPathname = encodedPathname + string(s)
continue
default:
- len := utf8.RuneLen(s)
- if len < 0 {
+ runeLen := utf8.RuneLen(s)
+ if runeLen < 0 {
// if utf8 cannot convert return the same string as is
return pathName
}
- u := make([]byte, len)
+ u := make([]byte, runeLen)
utf8.EncodeRune(u, s)
for _, r := range u {
hex := hex.EncodeToString([]byte{r})