diff --git a/doc/man/s3fs.1 b/doc/man/s3fs.1 index 6f87c21..5ca8449 100644 --- a/doc/man/s3fs.1 +++ b/doc/man/s3fs.1 @@ -221,8 +221,11 @@ If the s3fs could not connect to the region specified by this option, s3fs could But if you do not specify this option, and if you can not connect with the default region, s3fs will retry to automatically connect to the other region. So s3fs can know the correct region name, because s3fs can find it in an error from the S3 server. .TP -\fB\-o\fR sigv2 (default is signature version 4) -sets signing AWS requests by using Signature Version 2. +\fB\-o\fR sigv2 (default is signature version 4 falling back to version 2) +sets signing AWS requests by using only signature version 2. +.TP +\fB\-o\fR sigv4 (default is signature version 4 falling back to version 2) +sets signing AWS requests by using only signature version 4. .TP \fB\-o\fR mp_umask (default is "0000") sets umask for the mount point directory. diff --git a/src/curl.cpp b/src/curl.cpp index f1bd996..d4bcb6d 100644 --- a/src/curl.cpp +++ b/src/curl.cpp @@ -127,7 +127,7 @@ std::string S3fsCurl::userAgent; int S3fsCurl::max_parallel_cnt = 5; // default int S3fsCurl::max_multireq = 20; // default off_t S3fsCurl::multipart_size = MULTIPART_SIZE; // default -bool S3fsCurl::is_sigv4 = true; // default +signature_type_t S3fsCurl::signature_type = V2_OR_V4; // default bool S3fsCurl::is_ua = true; // default bool S3fsCurl::is_use_session_token= false; // default bool S3fsCurl::requester_pays = false; // default @@ -889,7 +889,7 @@ bool S3fsCurl::FinalCheckSse() S3FS_PRN_ERR("sse type is SSE-KMS, but there is no specified kms id."); return false; } - if(!S3fsCurl::IsSignatureV4()){ + if(S3fsCurl::GetSignatureType() == V2_ONLY){ S3FS_PRN_ERR("sse type is SSE-KMS, but signature type is not v4. SSE-KMS require signature v4."); return false; } @@ -2621,7 +2621,7 @@ void S3fsCurl::insertAuthHeaders() if(S3fsCurl::is_ibm_iam_auth){ insertIBMIAMHeaders(); - }else if(!S3fsCurl::is_sigv4){ + }else if(S3fsCurl::signature_type == V2_ONLY){ insertV2Headers(); }else{ insertV4Headers(); diff --git a/src/curl.h b/src/curl.h index 1f9c2fd..3d1c93e 100644 --- a/src/curl.h +++ b/src/curl.h @@ -153,7 +153,7 @@ class S3fsCurl static int max_parallel_cnt; static int max_multireq; static off_t multipart_size; - static bool is_sigv4; + static signature_type_t signature_type; static bool is_ua; // User-Agent static bool requester_pays; @@ -339,8 +339,8 @@ class S3fsCurl static const char* GetIAMRole() { return S3fsCurl::IAM_role.c_str(); } static bool SetMultipartSize(off_t size); static off_t GetMultipartSize() { return S3fsCurl::multipart_size; } - static bool SetSignatureV4(bool isset) { bool bresult = S3fsCurl::is_sigv4; S3fsCurl::is_sigv4 = isset; return bresult; } - static bool IsSignatureV4() { return S3fsCurl::is_sigv4; } + static signature_type_t SetSignatureType(signature_type_t signature_type) { signature_type_t bresult = S3fsCurl::signature_type; S3fsCurl::signature_type = signature_type; return bresult; } + static signature_type_t GetSignatureType() { return S3fsCurl::signature_type; } static bool SetUserAgentFlag(bool isset) { bool bresult = S3fsCurl::is_ua; S3fsCurl::is_ua = isset; return bresult; } static bool IsUserAgentFlag() { return S3fsCurl::is_ua; } static void InitUserAgent(); diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 9002abb..7c50936 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -881,9 +881,9 @@ static int do_create_bucket() int res = s3fscurl.PutRequest("/", meta, tmpfd); if(res < 0){ long responseCode = s3fscurl.GetLastResponseCode(); - if((responseCode == 400 || responseCode == 403) && S3fsCurl::IsSignatureV4()){ + if((responseCode == 400 || responseCode == 403) && S3fsCurl::GetSignatureType() == V2_OR_V4){ S3FS_PRN_ERR("Could not connect, so retry to connect by signature version 2."); - S3fsCurl::SetSignatureV4(false); + S3fsCurl::SetSignatureType(V2_ONLY); // retry to check s3fscurl.DestroyCurlHandle(); @@ -3390,7 +3390,8 @@ static int s3fs_check_service() // current endpoint is wrong, so try to connect to expected region. S3FS_PRN_CRIT("Failed to connect region '%s'(default), so retry to connect region '%s'.", endpoint.c_str(), expectregion.c_str()); endpoint = expectregion; - if(S3fsCurl::IsSignatureV4()){ + if(S3fsCurl::GetSignatureType() == V4_ONLY || + S3fsCurl::GetSignatureType() == V2_OR_V4){ if(s3host == "http://s3.amazonaws.com"){ s3host = "http://s3-" + endpoint + ".amazonaws.com"; }else if(s3host == "https://s3.amazonaws.com"){ @@ -3407,10 +3408,10 @@ static int s3fs_check_service() } // try signature v2 - if(0 > res && (responseCode == 400 || responseCode == 403) && S3fsCurl::IsSignatureV4()){ + if(0 > res && (responseCode == 400 || responseCode == 403) && S3fsCurl::GetSignatureType() == V2_OR_V4){ // switch sigv2 S3FS_PRN_CRIT("Failed to connect by sigv4, so retry to connect by signature version 2."); - S3fsCurl::SetSignatureV4(false); + S3fsCurl::SetSignatureType(V2_ONLY); // retry to check with sigv2 s3fscurl.DestroyCurlHandle(); @@ -4502,7 +4503,11 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar return 0; } if(0 == strcmp(arg, "sigv2")){ - S3fsCurl::SetSignatureV4(false); + S3fsCurl::SetSignatureType(V2_ONLY); + return 0; + } + if(0 == strcmp(arg, "sigv4")){ + S3fsCurl::SetSignatureType(V4_ONLY); return 0; } if(0 == strcmp(arg, "createbucket")){ diff --git a/src/s3fs_help.cpp b/src/s3fs_help.cpp index 1c0836e..b253c5f 100644 --- a/src/s3fs_help.cpp +++ b/src/s3fs_help.cpp @@ -274,8 +274,11 @@ static const char help_string[] = " can know the correct region name, because s3fs can find it in an\n" " error from the S3 server.\n" "\n" - " sigv2 (default is signature version 4)\n" - " - sets signing AWS requests by using Signature Version 2\n" + " sigv2 (default is signature version 4 falling back to version 2)\n" + " - sets signing AWS requests by using only signature version 2\n" + "\n" + " sigv4 (default is signature version 4 falling back to version 2)\n" + " - sets signing AWS requests by using only signature version 4\n" "\n" " mp_umask (default is \"0000\")\n" " - sets umask for the mount point directory.\n" diff --git a/src/types.h b/src/types.h index 3f56acd..9aa96f2 100644 --- a/src/types.h +++ b/src/types.h @@ -234,6 +234,12 @@ class sse_type_t{ Value value_; }; +enum signature_type_t { + V2_ONLY, + V4_ONLY, + V2_OR_V4 +}; + //---------------------------------------------- // etaglist_t / filepart //---------------------------------------------- diff --git a/test/small-integration-test.sh b/test/small-integration-test.sh index 69201f4..ab26986 100755 --- a/test/small-integration-test.sh +++ b/test/small-integration-test.sh @@ -63,6 +63,7 @@ FLAGS=( nomultipart notsup_compat_dir sigv2 + sigv4 singlepart_copy_limit=$((10 * 1024)) # limit size to exercise multipart code paths #use_sse # TODO: S3Proxy does not support SSE )