Changed handling the credential in S3fsCred more robust

This commit is contained in:
Takeshi Nakatani 2022-02-23 15:03:08 +00:00 committed by Andrew Gaul
parent afb0897553
commit 684ced5a41
5 changed files with 424 additions and 238 deletions

View File

@ -2552,13 +2552,13 @@ int S3fsCurl::RequestPerform(bool dontAddAuthHeaders /*=false*/)
// @param date e.g., get_date_rfc850()
// @param resource e.g., "/pub"
//
std::string S3fsCurl::CalcSignatureV2(const std::string& method, const std::string& strMD5, const std::string& content_type, const std::string& date, const std::string& resource)
std::string S3fsCurl::CalcSignatureV2(const std::string& method, const std::string& strMD5, const std::string& content_type, const std::string& date, const std::string& resource, const std::string& secret_access_key, const std::string& access_token)
{
std::string Signature;
std::string StringToSign;
if(!S3fsCurl::ps3fscred->GetIAMRole().empty() || S3fsCurl::ps3fscred->IsECS() || S3fsCurl::ps3fscred->IsUseSessionToken()){
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-security-token", S3fsCurl::ps3fscred->GetAccessToken().c_str());
if(!access_token.empty()){
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-security-token", access_token.c_str());
}
StringToSign += method + "\n";
@ -2568,8 +2568,8 @@ std::string S3fsCurl::CalcSignatureV2(const std::string& method, const std::stri
StringToSign += get_canonical_headers(requestHeaders, true);
StringToSign += resource;
const void* key = S3fsCurl::ps3fscred->GetSecretAccessKey().data();
size_t key_len = S3fsCurl::ps3fscred->GetSecretAccessKey().size();
const void* key = secret_access_key.data();
size_t key_len = secret_access_key.size();
const unsigned char* sdata = reinterpret_cast<const unsigned char*>(StringToSign.data());
size_t sdata_len = StringToSign.size();
unsigned char* md = NULL;
@ -2590,13 +2590,13 @@ std::string S3fsCurl::CalcSignatureV2(const std::string& method, const std::stri
return Signature;
}
std::string S3fsCurl::CalcSignature(const std::string& method, const std::string& canonical_uri, const std::string& query_string, const std::string& strdate, const std::string& payload_hash, const std::string& date8601)
std::string S3fsCurl::CalcSignature(const std::string& method, const std::string& canonical_uri, const std::string& query_string, const std::string& strdate, const std::string& payload_hash, const std::string& date8601, const std::string& secret_access_key, const std::string& access_token)
{
std::string Signature, StringCQ, StringToSign;
std::string uriencode;
if(!S3fsCurl::ps3fscred->GetIAMRole().empty() || S3fsCurl::ps3fscred->IsECS() || S3fsCurl::ps3fscred->IsUseSessionToken()){
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-security-token", S3fsCurl::ps3fscred->GetAccessToken().c_str());
if(!access_token.empty()){
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-security-token", access_token.c_str());
}
uriencode = urlEncode(canonical_uri);
@ -2617,7 +2617,7 @@ std::string S3fsCurl::CalcSignature(const std::string& method, const std::string
StringCQ += get_sorted_header_keys(requestHeaders) + "\n";
StringCQ += payload_hash;
std::string kSecret = "AWS4" + S3fsCurl::ps3fscred->GetSecretAccessKey();
std::string kSecret = "AWS4" + secret_access_key;
unsigned char *kDate, *kRegion, *kService, *kSigning, *sRequest = NULL;
unsigned int kDate_len,kRegion_len, kService_len, kSigning_len, sRequest_len = 0;
@ -2653,7 +2653,7 @@ std::string S3fsCurl::CalcSignature(const std::string& method, const std::string
return Signature;
}
void S3fsCurl::insertV4Headers()
void S3fsCurl::insertV4Headers(const std::string& access_key_id, const std::string& secret_access_key, const std::string& access_token)
{
std::string server_path = type == REQTYPE_LISTBUCKET ? "/" : path;
std::string payload_hash;
@ -2711,13 +2711,13 @@ void S3fsCurl::insertV4Headers()
}
if(!S3fsCurl::IsPublicBucket()){
std::string Signature = CalcSignature(op, realpath, query_string + (type == REQTYPE_PREMULTIPOST || type == REQTYPE_MULTILIST ? "=" : ""), strdate, contentSHA256, date8601);
std::string auth = "AWS4-HMAC-SHA256 Credential=" + S3fsCurl::ps3fscred->GetAccessKeyID() + "/" + strdate + "/" + endpoint + "/s3/aws4_request, SignedHeaders=" + get_sorted_header_keys(requestHeaders) + ", Signature=" + Signature;
std::string Signature = CalcSignature(op, realpath, query_string + (type == REQTYPE_PREMULTIPOST || type == REQTYPE_MULTILIST ? "=" : ""), strdate, contentSHA256, date8601, secret_access_key, access_token);
std::string auth = "AWS4-HMAC-SHA256 Credential=" + access_key_id + "/" + strdate + "/" + endpoint + "/s3/aws4_request, SignedHeaders=" + get_sorted_header_keys(requestHeaders) + ", Signature=" + Signature;
requestHeaders = curl_slist_sort_insert(requestHeaders, "Authorization", auth.c_str());
}
}
void S3fsCurl::insertV2Headers()
void S3fsCurl::insertV2Headers(const std::string& access_key_id, const std::string& secret_access_key, const std::string& access_token)
{
std::string resource;
std::string turl;
@ -2734,34 +2734,39 @@ void S3fsCurl::insertV2Headers()
}
if(!S3fsCurl::IsPublicBucket()){
std::string Signature = CalcSignatureV2(op, get_header_value(requestHeaders, "Content-MD5"), get_header_value(requestHeaders, "Content-Type"), date, resource);
requestHeaders = curl_slist_sort_insert(requestHeaders, "Authorization", std::string("AWS " + S3fsCurl::ps3fscred->GetAccessKeyID() + ":" + Signature).c_str());
std::string Signature = CalcSignatureV2(op, get_header_value(requestHeaders, "Content-MD5"), get_header_value(requestHeaders, "Content-Type"), date, resource, secret_access_key, access_token);
requestHeaders = curl_slist_sort_insert(requestHeaders, "Authorization", std::string("AWS " + access_key_id + ":" + Signature).c_str());
}
}
void S3fsCurl::insertIBMIAMHeaders()
void S3fsCurl::insertIBMIAMHeaders(const std::string& access_key_id, const std::string& access_token)
{
requestHeaders = curl_slist_sort_insert(requestHeaders, "Authorization", ("Bearer " + S3fsCurl::ps3fscred->GetAccessToken()).c_str());
requestHeaders = curl_slist_sort_insert(requestHeaders, "Authorization", ("Bearer " + access_token).c_str());
if(op == "PUT" && path == mount_prefix + "/"){
// ibm-service-instance-id header is required for bucket creation requests
requestHeaders = curl_slist_sort_insert(requestHeaders, "ibm-service-instance-id", S3fsCurl::ps3fscred->GetAccessKeyID().c_str());
requestHeaders = curl_slist_sort_insert(requestHeaders, "ibm-service-instance-id", access_key_id.c_str());
}
}
void S3fsCurl::insertAuthHeaders()
{
if(!S3fsCurl::ps3fscred->CheckIAMCredentialUpdate()){
std::string access_key_id;
std::string secret_access_key;
std::string access_token;
// check and get credential variables
if(!S3fsCurl::ps3fscred->CheckIAMCredentialUpdate(&access_key_id, &secret_access_key, &access_token)){
S3FS_PRN_ERR("An error occurred in checking IAM credential.");
return; // do not insert auth headers on error
}
if(S3fsCurl::ps3fscred->IsIBMIAMAuth()){
insertIBMIAMHeaders();
insertIBMIAMHeaders(access_key_id, access_token);
}else if(S3fsCurl::signature_type == V2_ONLY){
insertV2Headers();
insertV2Headers(access_key_id, secret_access_key, access_token);
}else{
insertV4Headers();
insertV4Headers(access_key_id, secret_access_key, access_token);
}
}
@ -2800,12 +2805,14 @@ int S3fsCurl::DeleteRequest(const char* tpath)
return RequestPerform();
}
//
// Get the token that we need to pass along with AWS IMDSv2 API requests
//
int S3fsCurl::GetIAMv2ApiToken()
int S3fsCurl::GetIAMv2ApiToken(const char* token_url, int token_ttl, const char* token_ttl_hdr, std::string& response)
{
url = std::string(S3fsCred::IAMv2_token_url);
if(!token_url || !token_ttl_hdr){
S3FS_PRN_ERR("IAMv2 token url(%s) or ttl_hdr(%s) parameter are wrong.", token_url ? token_url : "null", token_ttl_hdr ? token_ttl_hdr : "null");
return -EIO;
}
response.erase();
url = std::string(token_url);
if(!CreateCurlHandle()){
return -EIO;
}
@ -2813,8 +2820,8 @@ int S3fsCurl::GetIAMv2ApiToken()
responseHeaders.clear();
bodydata.Clear();
std::string ttlstr = str(S3fsCred::IAMv2_token_ttl);
requestHeaders = curl_slist_sort_insert(requestHeaders, S3fsCred::IAMv2_token_ttl_hdr, ttlstr.c_str());
std::string ttlstr = str(token_ttl);
requestHeaders = curl_slist_sort_insert(requestHeaders, token_ttl_hdr, ttlstr.c_str());
// Curl appends an "Expect: 100-continue" header to the token request,
// and aws responds with a 417 Expectation Failed. This ensures the
@ -2837,16 +2844,18 @@ int S3fsCurl::GetIAMv2ApiToken()
return -EIO;
}
// [NOTE]
// Be sure to give "dontAddAuthHeaders=true".
// If set to false(default), it will deadlock in S3fsCred.
//
int result = RequestPerform(true);
if(0 == result && !S3fsCurl::ps3fscred->SetIAMv2APIToken(bodydata.str())){
S3FS_PRN_ERR("Error storing IMDSv2 API token.");
result = -EIO;
if(0 == result){
response = bodydata.str();
}else{
S3FS_PRN_ERR("Error(%d) occurred, could not get IAMv2 api token.", result);
}
bodydata.Clear();
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_PUT, false)){
return -EIO;
}
return result;
}
@ -2855,64 +2864,31 @@ int S3fsCurl::GetIAMv2ApiToken()
// Get AccessKeyId/SecretAccessKey/AccessToken/Expiration by IAM role,
// and Set these value to class variable.
//
int S3fsCurl::GetIAMCredentials()
bool S3fsCurl::GetIAMCredentials(const char* cred_url, const char* iam_v2_token, const char* ibm_secret_access_key, std::string& response)
{
if (!S3fsCurl::ps3fscred->IsECS() && !S3fsCurl::ps3fscred->IsIBMIAMAuth()) {
S3FS_PRN_INFO3("[IAM role=%s]", S3fsCurl::ps3fscred->GetIAMRole().c_str());
if(S3fsCurl::ps3fscred->GetIAMRole().empty()) {
S3FS_PRN_ERR("IAM role name is empty.");
return -EIO;
}
if(!cred_url){
S3FS_PRN_ERR("url is null.");
return false;
}
url = cred_url;
response.erase();
// at first set type for handle
type = REQTYPE_IAMCRED;
if(!CreateCurlHandle()){
return -EIO;
return false;
}
// url
if(S3fsCurl::ps3fscred->IsECS()){
const char *env = std::getenv(S3fsCred::ECS_IAM_ENV_VAR);
if(env == NULL){
S3FS_PRN_ERR("%s is not set.", S3fsCred::ECS_IAM_ENV_VAR);
return -EIO;
}
url = S3fsCurl::ps3fscred->GetIAMCredentialsURL() + env;
}else{
if(S3fsCurl::ps3fscred->GetIMDSVersion() > 1){
int result = GetIAMv2ApiToken();
if(-ENOENT == result){
// If we get a 404 back when requesting the token service,
// then it's highly likely we're running in an environment
// that doesn't support the AWS IMDSv2 API, so we'll skip
// the token retrieval in the future.
S3fsCurl::ps3fscred->SetIMDSVersion(1);
}else if(result != 0){
// If we get an unexpected error when retrieving the API
// token, log it but continue. Requirement for including
// an API token with the metadata request may or may not
// be required, so we should not abort here.
S3FS_PRN_ERR("AWS IMDSv2 token retrieval failed: %d", result);
}
}
url = S3fsCurl::ps3fscred->GetIAMCredentialsURL() + S3fsCurl::ps3fscred->GetIAMRole();
}
requestHeaders = NULL;
responseHeaders.clear();
bodydata.Clear();
std::string postContent;
if(S3fsCurl::ps3fscred->IsIBMIAMAuth()){
url = S3fsCurl::ps3fscred->GetIAMCredentialsURL();
if(ibm_secret_access_key){
// make contents
postContent += "grant_type=urn:ibm:params:oauth:grant-type:apikey";
postContent += "&response_type=cloud_iam";
postContent += "&apikey=" + S3fsCurl::ps3fscred->GetSecretAccessKey();
postContent += "&apikey=" + std::string(ibm_secret_access_key);
// set postdata
postdata = reinterpret_cast<const unsigned char*>(postContent.c_str());
@ -2923,53 +2899,65 @@ int S3fsCurl::GetIAMCredentials()
requestHeaders = curl_slist_sort_insert(requestHeaders, "Authorization", "Basic Yng6Yng=");
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_POST, true)){ // POST
return -EIO;
return false;
}
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_POSTFIELDSIZE, static_cast<curl_off_t>(postdata_remaining))){
return -EIO;
return false;
}
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_READDATA, (void*)this)){
return -EIO;
return false;
}
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_READFUNCTION, S3fsCurl::ReadCallback)){
return -EIO;
return false;
}
}
if(S3fsCurl::ps3fscred->GetIMDSVersion() > 1){
requestHeaders = curl_slist_sort_insert(requestHeaders, S3fsCred::IAMv2_token_hdr, S3fsCurl::ps3fscred->GetIAMv2APIToken().c_str());
if(iam_v2_token){
requestHeaders = curl_slist_sort_insert(requestHeaders, S3fsCred::IAMv2_token_hdr, iam_v2_token);
}
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_URL, url.c_str())){
return -EIO;
return false;
}
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_WRITEDATA, (void*)&bodydata)){
return -EIO;
return false;
}
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback)){
return -EIO;
return false;
}
if(!S3fsCurl::AddUserAgent(hCurl)){ // put User-Agent
return -EIO;
return false;
}
// [NOTE]
// Be sure to give "dontAddAuthHeaders=true".
// If set to false(default), it will deadlock in S3fsCred.
//
int result = RequestPerform(true);
// analyzing response
if(0 == result && !S3fsCurl::ps3fscred->SetIAMCredentials(bodydata.str())){
S3FS_PRN_ERR("Something error occurred, could not get IAM credential.");
result = -EIO;
if(0 == result){
response = bodydata.str();
}else{
S3FS_PRN_ERR("Error(%d) occurred, could not get IAM role name.", result);
}
bodydata.Clear();
return result;
return (0 == result);
}
//
// Get IAM role name automatically.
//
bool S3fsCurl::LoadIAMRoleFromMetaData()
bool S3fsCurl::GetIAMRoleFromMetaData(const char* cred_url, const char* iam_v2_token, std::string& token)
{
if(!cred_url){
S3FS_PRN_ERR("url is null.");
return false;
}
url = cred_url;
token.erase();
S3FS_PRN_INFO3("Get IAM Role name");
// at first set type for handle
@ -2978,40 +2966,12 @@ bool S3fsCurl::LoadIAMRoleFromMetaData()
if(!CreateCurlHandle()){
return false;
}
// url
if(S3fsCurl::ps3fscred->IsECS()){
const char *env = std::getenv(S3fsCred::ECS_IAM_ENV_VAR);
if(env == NULL){
S3FS_PRN_ERR("%s is not set.", S3fsCred::ECS_IAM_ENV_VAR);
return -EIO;
}
url = S3fsCurl::ps3fscred->GetIAMCredentialsURL() + env;
}else{
if(S3fsCurl::ps3fscred->GetIMDSVersion() > 1){
int result = GetIAMv2ApiToken();
if(-ENOENT == result){
// If we get a 404 back when requesting the token service,
// then it's highly likely we're running in an environment
// that doesn't support the AWS IMDSv2 API, so we'll skip
// the token retrieval in the future.
S3fsCurl::ps3fscred->SetIMDSVersion(1);
}else if(result != 0){
// If we get an unexpected error when retrieving the API
// token, log it but continue. Requirement for including
// an API token with the metadata request may or may not
// be enforced, so we should not abort here.
S3FS_PRN_ERR("AWS IMDSv2 token retrieval failed: %d", result);
}
}
url = S3fsCurl::ps3fscred->GetIAMCredentialsURL();
}
requestHeaders = NULL;
responseHeaders.clear();
bodydata.Clear();
if(S3fsCurl::ps3fscred->GetIMDSVersion() > 1){
requestHeaders = curl_slist_sort_insert(requestHeaders, S3fsCred::IAMv2_token_hdr, S3fsCurl::ps3fscred->GetIAMv2APIToken().c_str());
if(iam_v2_token){
requestHeaders = curl_slist_sort_insert(requestHeaders, S3fsCred::IAMv2_token_hdr, iam_v2_token);
}
if(CURLE_OK != curl_easy_setopt(hCurl, CURLOPT_URL, url.c_str())){
@ -3027,12 +2987,17 @@ bool S3fsCurl::LoadIAMRoleFromMetaData()
return false;
}
// [NOTE]
// Be sure to give "dontAddAuthHeaders=true".
// If set to false(default), it will deadlock in S3fsCred.
//
int result = RequestPerform(true);
// analyzing response
if(0 == result && !S3fsCurl::ps3fscred->SetIAMRoleFromMetaData(bodydata.str())){
S3FS_PRN_ERR("Something error occurred, could not get IAM role name.");
result = -EIO;
if(0 == result){
token = bodydata.str();
}else{
S3FS_PRN_ERR("Error(%d) occurred, could not get IAM role name from meta data.", result);
}
bodydata.Clear();

View File

@ -249,13 +249,12 @@ class S3fsCurl
bool ResetHandle(bool lock_already_held = false);
bool RemakeHandle();
bool ClearInternalData();
void insertV4Headers();
void insertV2Headers();
void insertIBMIAMHeaders();
void insertV4Headers(const std::string& access_key_id, const std::string& secret_access_key, const std::string& access_token);
void insertV2Headers(const std::string& access_key_id, const std::string& secret_access_key, const std::string& access_token);
void insertIBMIAMHeaders(const std::string& access_key_id, const std::string& access_token);
void insertAuthHeaders();
std::string CalcSignatureV2(const std::string& method, const std::string& strMD5, const std::string& content_type, const std::string& date, const std::string& resource);
std::string CalcSignature(const std::string& method, const std::string& canonical_uri, const std::string& query_string, const std::string& strdate, const std::string& payload_hash, const std::string& date8601);
int GetIAMv2ApiToken();
std::string CalcSignatureV2(const std::string& method, const std::string& strMD5, const std::string& content_type, const std::string& date, const std::string& resource, const std::string& secret_access_key, const std::string& access_token);
std::string CalcSignature(const std::string& method, const std::string& canonical_uri, const std::string& query_string, const std::string& strdate, const std::string& payload_hash, const std::string& date8601, const std::string& secret_access_key, const std::string& access_token);
int UploadMultipartPostSetup(const char* tpath, int part_num, const std::string& upload_id);
int CopyMultipartPostSetup(const char* from, const char* to, int part_num, const std::string& upload_id, headers_t& meta);
bool UploadMultipartPostComplete();
@ -337,12 +336,13 @@ class S3fsCurl
bool CreateCurlHandle(bool only_pool = false, bool remake = false);
bool DestroyCurlHandle(bool restore_pool = true, bool clear_internal_data = true);
int GetIAMCredentials();
bool LoadIAMRoleFromMetaData();
bool GetIAMCredentials(const char* cred_url, const char* iam_v2_token, const char* ibm_secret_access_key, std::string& response);
bool GetIAMRoleFromMetaData(const char* cred_url, const char* iam_v2_token, std::string& token);
bool AddSseRequestHead(sse_type_t ssetype, const std::string& ssevalue, bool is_only_c, bool is_copy);
bool GetResponseCode(long& responseCode, bool from_curl_handle = true);
int RequestPerform(bool dontAddAuthHeaders=false);
int DeleteRequest(const char* tpath);
int GetIAMv2ApiToken(const char* token_url, int token_ttl, const char* token_ttl_hdr, std::string& response);
bool PreHeadRequest(const char* tpath, const char* bpath = NULL, const char* savedpath = NULL, size_t ssekey_pos = -1);
bool PreHeadRequest(const std::string& tpath, const std::string& bpath, const std::string& savedpath, size_t ssekey_pos = -1) {
return PreHeadRequest(tpath.c_str(), bpath.c_str(), savedpath.c_str(), ssekey_pos);

View File

@ -3380,16 +3380,10 @@ static void* s3fs_init(struct fuse_conn_info* conn)
}
// check loading IAM role name
if(ps3fscred->IsIAMRoleMetadataType()){
// load IAM role name from http://169.254.169.254/latest/meta-data/iam/security-credentials
//
S3fsCurl s3fscurl;
if(!s3fscurl.LoadIAMRoleFromMetaData()){
S3FS_PRN_CRIT("could not load IAM role name from meta data.");
s3fs_exit_fuseloop(EXIT_FAILURE);
return NULL;
}
S3FS_PRN_INFO("loaded IAM role name = %s", ps3fscred->GetIAMRole().c_str());
if(!ps3fscred->LoadIAMRoleFromMetaData()){
S3FS_PRN_CRIT("could not load IAM role name from meta data.");
s3fs_exit_fuseloop(EXIT_FAILURE);
return NULL;
}
// Check Bucket
@ -3502,7 +3496,7 @@ static int s3fs_check_service()
// At first time for access S3, we check IAM role if it sets.
if(!ps3fscred->CheckIAMCredentialUpdate()){
S3FS_PRN_CRIT("Failed to check IAM role name(%s).", ps3fscred->GetIAMRole().c_str());
S3FS_PRN_CRIT("Failed to initialize IAM credential.");
return EXIT_FAILURE;
}

View File

@ -97,6 +97,7 @@ bool S3fsCred::ParseIAMRoleFromMetaDataResponse(const char* response, std::strin
// Methods : Constructor / Destructor
//-------------------------------------------------------------------
S3fsCred::S3fsCred() :
is_lock_init(false),
passwd_file(""),
aws_profile(DEFAULT_AWS_PROFILE_NAME),
load_iamrole(false),
@ -115,10 +116,29 @@ S3fsCred::S3fsCred() :
IAM_expiry_field("Expiration"),
IAM_role("")
{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
#if S3FS_PTHREAD_ERRORCHECK
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
int result;
if(0 != (result = pthread_mutex_init(&token_lock, &attr))){
S3FS_PRN_CRIT("failed to init token_lock: %d", result);
abort();
}
is_lock_init = true;
}
S3fsCred::~S3fsCred()
{
if(is_lock_init){
int result;
if(0 != (result = pthread_mutex_destroy(&token_lock))){
S3FS_PRN_CRIT("failed to destroy token_lock: %d", result);
abort();
}
is_lock_init = false;
}
}
//-------------------------------------------------------------------
@ -156,8 +176,10 @@ bool S3fsCred::SetIAMRoleMetadataType(bool flag)
return old;
}
bool S3fsCred::SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey)
bool S3fsCred::SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey, AutoLock::Type type)
{
AutoLock auto_lock(&token_lock, type);
if((!is_ibm_iam_auth && (!AccessKeyId || '\0' == AccessKeyId[0])) || !SecretAccessKey || '\0' == SecretAccessKey[0]){
return false;
}
@ -167,8 +189,10 @@ bool S3fsCred::SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey
return true;
}
bool S3fsCred::SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken)
bool S3fsCred::SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken, AutoLock::Type type)
{
AutoLock auto_lock(&token_lock, type);
bool access_key_is_empty = !AccessKeyId || '\0' == AccessKeyId[0];
bool secret_access_key_is_empty = !SecretAccessKey || '\0' == SecretAccessKey[0];
bool session_token_is_empty = !SessionToken || '\0' == SessionToken[0];
@ -184,9 +208,11 @@ bool S3fsCred::SetAccessKeyWithSessionToken(const char* AccessKeyId, const char*
return true;
}
bool S3fsCred::IsSetAccessKeys() const
bool S3fsCred::IsSetAccessKeys(AutoLock::Type type)
{
return !IAM_role.empty() || ((!AWSAccessKeyId.empty() || is_ibm_iam_auth) && !AWSSecretAccessKey.empty());
AutoLock auto_lock(&token_lock, type);
return IsSetIAMRole(AutoLock::ALREADY_LOCKED) || ((!AWSAccessKeyId.empty() || is_ibm_iam_auth) && !AWSSecretAccessKey.empty());
}
bool S3fsCred::SetIsECS(bool flag)
@ -210,11 +236,26 @@ bool S3fsCred::SetIsIBMIAMAuth(bool flag)
return old;
}
std::string S3fsCred::SetIAMRole(const char* role)
bool S3fsCred::SetIAMRole(const char* role, AutoLock::Type type)
{
std::string old = IAM_role;
AutoLock auto_lock(&token_lock, type);
IAM_role = role ? role : "";
return old;
return true;
}
std::string S3fsCred::GetIAMRole(AutoLock::Type type)
{
AutoLock auto_lock(&token_lock, type);
return IAM_role;
}
bool S3fsCred::IsSetIAMRole(AutoLock::Type type)
{
AutoLock auto_lock(&token_lock, type);
return !IAM_role.empty();
}
size_t S3fsCred::SetIAMFieldCount(size_t field_count)
@ -245,24 +286,189 @@ std::string S3fsCred::SetIAMExpiryField(const char* expiry_field)
return old;
}
int S3fsCred::SetIMDSVersion(int version)
bool S3fsCred::GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoLock::Type type)
{
// check
if(check_iam_role && !is_ecs && !IsIBMIAMAuth()){
if(!IsSetIAMRole(type)) {
S3FS_PRN_ERR("IAM role name is empty.");
return false;
}
S3FS_PRN_INFO3("[IAM role=%s]", GetIAMRole(type).c_str());
}
if(is_ecs){
const char *env = std::getenv(S3fsCred::ECS_IAM_ENV_VAR);
if(env == NULL){
S3FS_PRN_ERR("%s is not set.", S3fsCred::ECS_IAM_ENV_VAR);
return false;
}
url = IAM_cred_url + env;
}else if(IsIBMIAMAuth()){
url = IAM_cred_url;
}else{
// [NOTE]
// To avoid deadlocking, do not manipulate the S3fsCred object
// in the S3fsCurl::GetIAMv2ApiToken method (when retrying).
//
AutoLock auto_lock(&token_lock, type); // Lock for IAM_api_version, IAMv2_api_token
if(GetIMDSVersion(AutoLock::ALREADY_LOCKED) > 1){
S3fsCurl s3fscurl;
std::string token;
int result = s3fscurl.GetIAMv2ApiToken(S3fsCred::IAMv2_token_url, S3fsCred::IAMv2_token_ttl, S3fsCred::IAMv2_token_ttl_hdr, token);
if(-ENOENT == result){
// If we get a 404 back when requesting the token service,
// then it's highly likely we're running in an environment
// that doesn't support the AWS IMDSv2 API, so we'll skip
// the token retrieval in the future.
SetIMDSVersion(1, AutoLock::ALREADY_LOCKED);
}else if(result != 0){
// If we get an unexpected error when retrieving the API
// token, log it but continue. Requirement for including
// an API token with the metadata request may or may not
// be required, so we should not abort here.
S3FS_PRN_ERR("AWS IMDSv2 token retrieval failed: %d", result);
}else{
// Set token
if(!SetIAMv2APIToken(token, AutoLock::ALREADY_LOCKED)){
S3FS_PRN_ERR("Error storing IMDSv2 API token(%s).", token.c_str());
}
}
}
if(check_iam_role){
url = IAM_cred_url + GetIAMRole(AutoLock::ALREADY_LOCKED);
}else{
url = IAM_cred_url;
}
}
return true;
}
int S3fsCred::SetIMDSVersion(int version, AutoLock::Type type)
{
AutoLock auto_lock(&token_lock, type);
int old = IAM_api_version;
IAM_api_version = version;
return old;
}
bool S3fsCred::SetIAMv2APIToken(const char* response)
int S3fsCred::GetIMDSVersion(AutoLock::Type type)
{
S3FS_PRN_INFO3("Setting AWS IMDSv2 API token to %s", response ? response : "(null)");
if(!response){
AutoLock auto_lock(&token_lock, type);
return IAM_api_version;
}
bool S3fsCred::SetIAMv2APIToken(const std::string& token, AutoLock::Type type)
{
S3FS_PRN_INFO3("Setting AWS IMDSv2 API token to %s", token.c_str());
AutoLock auto_lock(&token_lock, type);
if(token.empty()){
return false;
}
IAMv2_api_token = std::string(response);
IAMv2_api_token = token;
return true;
}
bool S3fsCred::SetIAMCredentials(const char* response)
std::string S3fsCred::GetIAMv2APIToken(AutoLock::Type type)
{
AutoLock auto_lock(&token_lock, type);
return IAMv2_api_token;
}
// [NOTE]
// Currently, token_lock is always locked before calling this method,
// and this method calls the S3fsCurl::GetIAMCredentials method.
// Currently, when the request fails and retries in the process of
// S3fsCurl::GetIAMCredentials, does not use the S3fsCred object in
// retry logic.
// Be careful not to deadlock whenever you change this logic.
//
bool S3fsCred::LoadIAMCredentials(AutoLock::Type type)
{
// url(check iam role)
std::string url;
AutoLock auto_lock(&token_lock, type);
if(!GetIAMCredentialsURL(url, true, AutoLock::ALREADY_LOCKED)){
return false;
}
const char* iam_v2_token = NULL;
std::string str_iam_v2_token;
if(GetIMDSVersion(AutoLock::ALREADY_LOCKED) > 1){
str_iam_v2_token = GetIAMv2APIToken(AutoLock::ALREADY_LOCKED);
iam_v2_token = str_iam_v2_token.c_str();
}
const char* ibm_secret_access_key = NULL;
std::string str_ibm_secret_access_key;
if(IsIBMIAMAuth()){
str_ibm_secret_access_key = AWSSecretAccessKey;
ibm_secret_access_key = str_ibm_secret_access_key.c_str();
}
S3fsCurl s3fscurl;
std::string response;
if(!s3fscurl.GetIAMCredentials(url.c_str(), iam_v2_token, ibm_secret_access_key, response)){
return false;
}
if(!SetIAMCredentials(response.c_str(), AutoLock::ALREADY_LOCKED)){
S3FS_PRN_ERR("Something error occurred, could not set IAM role name.");
return false;
}
return true;
}
//
// load IAM role name from http://169.254.169.254/latest/meta-data/iam/security-credentials
//
bool S3fsCred::LoadIAMRoleFromMetaData()
{
AutoLock auto_lock(&token_lock);
if(load_iamrole){
// url(not check iam role)
std::string url;
if(!GetIAMCredentialsURL(url, false, AutoLock::ALREADY_LOCKED)){
return false;
}
const char* iam_v2_token = NULL;
std::string str_iam_v2_token;
if(GetIMDSVersion(AutoLock::ALREADY_LOCKED) > 1){
str_iam_v2_token = GetIAMv2APIToken(AutoLock::ALREADY_LOCKED);
iam_v2_token = str_iam_v2_token.c_str();
}
S3fsCurl s3fscurl;
std::string token;
if(!s3fscurl.GetIAMRoleFromMetaData(url.c_str(), iam_v2_token, token)){
return false;
}
if(!SetIAMRoleFromMetaData(token.c_str(), AutoLock::ALREADY_LOCKED)){
S3FS_PRN_ERR("Something error occurred, could not set IAM role name.");
return false;
}
S3FS_PRN_INFO("loaded IAM role name = %s", GetIAMRole(AutoLock::ALREADY_LOCKED).c_str());
}
return true;
}
bool S3fsCred::SetIAMCredentials(const char* response, AutoLock::Type type)
{
S3FS_PRN_INFO3("IAM credential response = \"%s\"", response);
@ -276,6 +482,8 @@ bool S3fsCred::SetIAMCredentials(const char* response)
return false;
}
AutoLock auto_lock(&token_lock, type);
AWSAccessToken = keyval[IAM_token_field];
if(is_ibm_iam_auth){
@ -292,7 +500,7 @@ bool S3fsCred::SetIAMCredentials(const char* response)
return true;
}
bool S3fsCred::SetIAMRoleFromMetaData(const char* response)
bool S3fsCred::SetIAMRoleFromMetaData(const char* response, AutoLock::Type type)
{
S3FS_PRN_INFO3("IAM role name response = \"%s\"", response ? response : "(null)");
@ -301,11 +509,10 @@ bool S3fsCred::SetIAMRoleFromMetaData(const char* response)
return false;
}
SetIAMRole(rolename.c_str());
SetIAMRole(rolename.c_str(), type);
return true;
}
//-------------------------------------------------------------------
// Methods : for Credentials
//-------------------------------------------------------------------
@ -504,7 +711,7 @@ bool S3fsCred::ParseS3fsPasswdFile(bucketkvmap_t& resmap)
//
// only one default key pair is allowed, but not required
//
bool S3fsCred::ReadS3fsPasswdFile()
bool S3fsCred::ReadS3fsPasswdFile(AutoLock::Type type)
{
bucketkvmap_t bucketmap;
kvmap_t keyval;
@ -529,11 +736,17 @@ bool S3fsCred::ReadS3fsPasswdFile()
bucketkvmap_t::iterator it = bucketmap.find(S3fsCred::KEYVAL_FIELDS_TYPE);
if(bucketmap.end() != it){
// aws format
int result = CheckS3fsCredentialAwsFormat(it->second);
std::string access_key_id;
std::string secret_access_key;
int result = CheckS3fsCredentialAwsFormat(it->second, access_key_id, secret_access_key);
if(-1 == result){
return false;
}else if(1 == result){
// success to set
// found ascess(secret) keys
if(!SetAccessKey(access_key_id.c_str(), secret_access_key.c_str(), type)){
S3FS_PRN_EXIT("failed to set access key/secret key.");
return false;
}
return true;
}
}
@ -556,7 +769,7 @@ bool S3fsCred::ReadS3fsPasswdFile()
return false;
}
if(!SetAccessKey(aws_accesskeyid_it->second.c_str(), aws_secretkey_it->second.c_str())){
if(!SetAccessKey(aws_accesskeyid_it->second.c_str(), aws_secretkey_it->second.c_str(), type)){
S3FS_PRN_EXIT("failed to set internal data for access key/secret key from passwd file.");
return false;
}
@ -568,7 +781,7 @@ bool S3fsCred::ReadS3fsPasswdFile()
// 0 - NG(could not read)
// -1 - Should shutdown immediately
//
int S3fsCred::CheckS3fsCredentialAwsFormat(const kvmap_t& kvmap)
int S3fsCred::CheckS3fsCredentialAwsFormat(const kvmap_t& kvmap, std::string& access_key_id, std::string& secret_access_key)
{
std::string str1(S3fsCred::AWS_ACCESSKEYID);
std::string str2(S3fsCred::AWS_SECRETKEY);
@ -585,17 +798,16 @@ int S3fsCred::CheckS3fsCredentialAwsFormat(const kvmap_t& kvmap)
S3FS_PRN_EXIT("AWSAccesskey or AWSSecretkey is not specified.");
return -1;
}
if(!SetAccessKey(str1_it->second.c_str(), str2_it->second.c_str())){
S3FS_PRN_EXIT("failed to set access key/secret key.");
return -1;
}
access_key_id = str1_it->second;
secret_access_key = str2_it->second;
return 1;
}
//
// Read Aws Credential File
//
bool S3fsCred::ReadAwsCredentialFile(const std::string &filename)
bool S3fsCred::ReadAwsCredentialFile(const std::string &filename, AutoLock::Type type)
{
// open passwd file
std::ifstream PF(filename.c_str());
@ -652,12 +864,12 @@ bool S3fsCred::ReadAwsCredentialFile(const std::string &filename)
S3FS_PRN_EXIT("AWS session token was expected but wasn't provided in aws/credentials file for profile: %s.", aws_profile.c_str());
return false;
}
if(!SetAccessKey(accesskey.c_str(), secret.c_str())){
if(!SetAccessKey(accesskey.c_str(), secret.c_str(), type)){
S3FS_PRN_EXIT("failed to set internal data for access key/secret key from aws credential file.");
return false;
}
}else{
if(!SetAccessKeyWithSessionToken(accesskey.c_str(), secret.c_str(), session_token.c_str())){
if(!SetAccessKeyWithSessionToken(accesskey.c_str(), secret.c_str(), session_token.c_str(), type)){
S3FS_PRN_EXIT("session token is invalid.");
return false;
}
@ -695,13 +907,13 @@ bool S3fsCred::InitialS3fsCredentials()
}
// 1 - keys specified on the command line
if(IsSetAccessKeys()){
if(IsSetAccessKeys(AutoLock::NONE)){
return true;
}
// 2 - was specified on the command line
if(IsSetPasswdFile()){
if(!ReadS3fsPasswdFile()){
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
return false;
}
return true;
@ -721,7 +933,7 @@ bool S3fsCred::InitialS3fsCredentials()
S3FS_PRN_INFO2("access key from env variables");
if(AWSSESSIONTOKEN != NULL){
S3FS_PRN_INFO2("session token is available");
if(!SetAccessKeyWithSessionToken(AWSACCESSKEYID, AWSSECRETACCESSKEY, AWSSESSIONTOKEN)){
if(!SetAccessKeyWithSessionToken(AWSACCESSKEYID, AWSSECRETACCESSKEY, AWSSESSIONTOKEN, AutoLock::NONE)){
S3FS_PRN_EXIT("session token is invalid.");
return false;
}
@ -732,7 +944,7 @@ bool S3fsCred::InitialS3fsCredentials()
return false;
}
}
if(!SetAccessKey(AWSACCESSKEYID, AWSSECRETACCESSKEY)){
if(!SetAccessKey(AWSACCESSKEYID, AWSSECRETACCESSKEY, AutoLock::NONE)){
S3FS_PRN_EXIT("if one access key is specified, both keys need to be specified.");
return false;
}
@ -748,7 +960,7 @@ bool S3fsCred::InitialS3fsCredentials()
S3FS_PRN_EXIT("AWS_CREDENTIAL_FILE: \"%s\" is not readable.", passwd_file.c_str());
return false;
}
if(!ReadS3fsPasswdFile()){
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
return false;
}
return true;
@ -757,7 +969,7 @@ bool S3fsCred::InitialS3fsCredentials()
// 3b - check ${HOME}/.aws/credentials
std::string aws_credentials = std::string(getpwuid(getuid())->pw_dir) + "/.aws/credentials";
if(ReadAwsCredentialFile(aws_credentials)){
if(ReadAwsCredentialFile(aws_credentials, AutoLock::NONE)){
return true;
}else if(aws_profile != DEFAULT_AWS_PROFILE_NAME){
S3FS_PRN_EXIT("Could not find profile: %s in file: %s", aws_profile.c_str(), aws_credentials.c_str());
@ -770,14 +982,14 @@ bool S3fsCred::InitialS3fsCredentials()
passwd_file = HOME;
passwd_file += "/.passwd-s3fs";
if(IsReadableS3fsPasswdFile()){
if(!ReadS3fsPasswdFile()){
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
return false;
}
// It is possible that the user's file was there but
// contained no key pairs i.e. commented out
// in that case, go look in the final location
if(IsSetAccessKeys()){
if(IsSetAccessKeys(AutoLock::NONE)){
return true;
}
}
@ -786,7 +998,7 @@ bool S3fsCred::InitialS3fsCredentials()
// 5 - from the system default location
passwd_file = "/etc/passwd-s3fs";
if(IsReadableS3fsPasswdFile()){
if(!ReadS3fsPasswdFile()){
if(!ReadS3fsPasswdFile(AutoLock::NONE)){
return false;
}
return true;
@ -854,23 +1066,37 @@ bool S3fsCred::ParseIAMCredentialResponse(const char* response, iamcredmap_t& ke
return true;
}
bool S3fsCred::CheckIAMCredentialUpdate()
bool S3fsCred::CheckIAMCredentialUpdate(std::string* access_key_id, std::string* secret_access_key, std::string* access_token)
{
if(IAM_role.empty() && !is_ecs && !is_ibm_iam_auth){
return true;
}
if(time(NULL) + S3fsCred::IAM_EXPIRE_MERGIN <= AWSAccessTokenExpire){
return true;
}
S3FS_PRN_INFO("IAM Access Token refreshing...");
AutoLock auto_lock(&token_lock);
// update
S3fsCurl s3fscurl;
if(0 != s3fscurl.GetIAMCredentials()){
S3FS_PRN_ERR("IAM Access Token refresh failed");
return false;
if(IsSetIAMRole(AutoLock::ALREADY_LOCKED) || is_ecs || is_ibm_iam_auth){
if(AWSAccessTokenExpire < (time(NULL) + S3fsCred::IAM_EXPIRE_MERGIN)){
S3FS_PRN_INFO("IAM Access Token refreshing...");
// update
if(!LoadIAMCredentials(AutoLock::ALREADY_LOCKED)){
S3FS_PRN_ERR("IAM Access Token refresh failed");
return false;
}
S3FS_PRN_INFO("IAM Access Token refreshed");
}
}
// set
if(access_key_id){
*access_key_id = AWSAccessKeyId;
}
if(secret_access_key){
*secret_access_key = AWSSecretAccessKey;
}
if(access_token){
if(IsIBMIAMAuth() || IsSetIAMRole(AutoLock::ALREADY_LOCKED) || is_ecs || is_use_session_token){
*access_token = AWSAccessToken;
}else{
access_token->erase();
}
}
S3FS_PRN_INFO("IAM Access Token refreshed");
return true;
}
@ -900,7 +1126,7 @@ int S3fsCred::DetectParam(const char* arg)
SetIAMTokenField("\"access_token\"");
SetIAMExpiryField("\"expiration\"");
SetIAMFieldCount(2);
SetIMDSVersion(1);
SetIMDSVersion(1, AutoLock::NONE);
return 0;
}
@ -924,7 +1150,7 @@ int S3fsCred::DetectParam(const char* arg)
}
if(0 == strcmp(arg, "imdsv1only")){
SetIMDSVersion(1);
SetIMDSVersion(1, AutoLock::NONE);
return 0;
}
@ -934,14 +1160,14 @@ int S3fsCred::DetectParam(const char* arg)
return -1;
}
SetIsECS(true);
SetIMDSVersion(1);
SetIMDSVersion(1, AutoLock::NONE);
SetIAMCredentialsURL("http://169.254.170.2");
SetIAMFieldCount(5);
return 0;
}
if(is_prefix(arg, "iam_role")){
if(IsECS() || IsIBMIAMAuth()){
if(is_ecs || IsIBMIAMAuth()){
S3FS_PRN_EXIT("option iam_role cannot be used in conjunction with ecs or ibm");
return -1;
}
@ -953,7 +1179,7 @@ int S3fsCred::DetectParam(const char* arg)
}else if(is_prefix(arg, "iam_role=")){
const char* role = strchr(arg, '=') + sizeof(char);
SetIAMRole(role);
SetIAMRole(role, AutoLock::NONE);
SetIAMRoleMetadataType(false);
return 0;
}
@ -1014,21 +1240,21 @@ bool S3fsCred::CheckAllParams()
}
// error checking of command line arguments for compatibility
if(S3fsCurl::IsPublicBucket() && IsSetAccessKeys()){
if(S3fsCurl::IsPublicBucket() && IsSetAccessKeys(AutoLock::NONE)){
S3FS_PRN_EXIT("specifying both public_bucket and the access keys options is invalid.");
return false;
}
if(IsSetPasswdFile() && IsSetAccessKeys()){
if(IsSetPasswdFile() && IsSetAccessKeys(AutoLock::NONE)){
S3FS_PRN_EXIT("specifying both passwd_file and the access keys options is invalid.");
return false;
}
if(!S3fsCurl::IsPublicBucket() && !IsIAMRoleMetadataType() && !IsECS()){
if(!S3fsCurl::IsPublicBucket() && !load_iamrole && !is_ecs){
if(!InitialS3fsCredentials()){
return false;
}
if(!IsSetAccessKeys()){
if(!IsSetAccessKeys(AutoLock::NONE)){
S3FS_PRN_EXIT("could not establish security credentials, check documentation.");
return false;
}

View File

@ -21,6 +21,8 @@
#ifndef S3FS_CRED_H_
#define S3FS_CRED_H_
#include "autolock.h"
//----------------------------------------------
// Typedefs
//----------------------------------------------
@ -43,37 +45,39 @@ class S3fsCred
static const char* AWS_SECRETKEY;
static const int IAM_EXPIRE_MERGIN;
static const char* ECS_IAM_ENV_VAR;
static const char* IAMCRED_ACCESSKEYID;
static const char* IAMCRED_SECRETACCESSKEY;
static const char* IAMCRED_ROLEARN;
static std::string bucket_name;
pthread_mutex_t token_lock;
bool is_lock_init;
std::string passwd_file;
std::string aws_profile;
bool load_iamrole;
std::string AWSAccessKeyId;
std::string AWSSecretAccessKey;
std::string AWSAccessToken;
time_t AWSAccessTokenExpire;
std::string AWSAccessKeyId; // Protect exclusively
std::string AWSSecretAccessKey; // Protect exclusively
std::string AWSAccessToken; // Protect exclusively
time_t AWSAccessTokenExpire; // Protect exclusively
bool is_ecs;
bool is_use_session_token;
bool is_ibm_iam_auth;
std::string IAM_cred_url;
int IAM_api_version;
std::string IAMv2_api_token;
int IAM_api_version; // Protect exclusively
std::string IAMv2_api_token; // Protect exclusively
size_t IAM_field_count;
std::string IAM_token_field;
std::string IAM_expiry_field;
std::string IAM_role;
std::string IAM_role; // Protect exclusively
public:
static const char* ECS_IAM_ENV_VAR;
static const char* IAMv2_token_url;
static int IAMv2_token_ttl;
static const char* IAMv2_token_ttl_hdr;
@ -87,16 +91,24 @@ class S3fsCred
bool SetAwsProfileName(const char* profile_name);
bool SetIAMRoleMetadataType(bool flag);
bool SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey);
bool SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken);
bool IsSetAccessKeys() const;
bool SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey, AutoLock::Type type);
bool SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken, AutoLock::Type type);
bool IsSetAccessKeys(AutoLock::Type type);
bool SetIsECS(bool flag);
bool SetIsUseSessionToken(bool flag);
bool SetIsIBMIAMAuth(bool flag);
std::string SetIAMRole(const char* role);
int SetIMDSVersion(int version, AutoLock::Type type);
int GetIMDSVersion(AutoLock::Type type);
bool SetIAMv2APIToken(const std::string& token, AutoLock::Type type);
std::string GetIAMv2APIToken(AutoLock::Type type);
bool SetIAMRole(const char* role, AutoLock::Type type);
std::string GetIAMRole(AutoLock::Type type);
bool IsSetIAMRole(AutoLock::Type type);
size_t SetIAMFieldCount(size_t field_count);
std::string SetIAMCredentialsURL(const char* url);
std::string SetIAMTokenField(const char* token_field);
@ -105,14 +117,19 @@ class S3fsCred
bool IsReadableS3fsPasswdFile();
bool CheckS3fsPasswdFilePerms();
bool ParseS3fsPasswdFile(bucketkvmap_t& resmap);
bool ReadS3fsPasswdFile();
bool ReadS3fsPasswdFile(AutoLock::Type type);
int CheckS3fsCredentialAwsFormat(const kvmap_t& kvmap);
bool ReadAwsCredentialFile(const std::string &filename);
int CheckS3fsCredentialAwsFormat(const kvmap_t& kvmap, std::string& access_key_id, std::string& secret_access_key);
bool ReadAwsCredentialFile(const std::string &filename, AutoLock::Type type);
bool InitialS3fsCredentials();
bool ParseIAMCredentialResponse(const char* response, iamcredmap_t& keyval);
bool GetIAMCredentialsURL(std::string& url, bool check_iam_role, AutoLock::Type type);
bool LoadIAMCredentials(AutoLock::Type type);
bool SetIAMCredentials(const char* response, AutoLock::Type type);
bool SetIAMRoleFromMetaData(const char* response, AutoLock::Type type);
bool CheckForbiddenBucketParams();
public:
@ -122,27 +139,11 @@ class S3fsCred
S3fsCred();
~S3fsCred();
bool IsIAMRoleMetadataType() const { return load_iamrole; }
const std::string& GetAccessKeyID() const { return AWSAccessKeyId; }
const std::string& GetSecretAccessKey() const { return AWSSecretAccessKey; }
const std::string& GetAccessToken() const { return AWSAccessToken; }
bool IsECS() const { return is_ecs; }
bool IsUseSessionToken() const { return is_use_session_token; }
bool IsIBMIAMAuth() const { return is_ibm_iam_auth; }
const std::string& GetIAMRole() const { return IAM_role; }
const std::string& GetIAMCredentialsURL() const { return IAM_cred_url; }
int SetIMDSVersion(int version);
int GetIMDSVersion() const { return IAM_api_version; }
bool LoadIAMRoleFromMetaData();
bool SetIAMv2APIToken(const char* response);
const std::string& GetIAMv2APIToken() const { return IAMv2_api_token; }
bool SetIAMCredentials(const char* response);
bool SetIAMRoleFromMetaData(const char* response);
bool CheckIAMCredentialUpdate();
bool CheckIAMCredentialUpdate(std::string* access_key_id = NULL, std::string* secret_access_key = NULL, std::string* access_token = NULL);
int DetectParam(const char* arg);
bool CheckAllParams();