Skip to content

Commit

Permalink
add session token support
Browse files Browse the repository at this point in the history
  • Loading branch information
Michal Lula committed Apr 14, 2019
1 parent d7bb834 commit a8e88df
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 6 deletions.
2 changes: 1 addition & 1 deletion doc/man/s3fs.1
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ For unprivileged user.
s3fs is a FUSE filesystem that allows you to mount an Amazon S3 bucket as a local filesystem. It stores files natively and transparently in S3 (i.e., you can use other programs to access the same files).
.SH AUTHENTICATION
s3fs supports the standard AWS credentials (filehttps://docs.aws.amazon.com/cli/latest/userguide/cli-config-files.html) stored in `${HOME}/.aws/credentials`.
Alternatively, s3fs supports a custom passwd file.
Alternatively, s3fs supports a custom passwd file. Only AWS credentials file format can be used when AWS session token is required.
The s3fs password file has this format (use this format if you have only one set of credentials):
.RS 4
\fBaccessKeyId\fP:\fBsecretAccessKey\fP
Expand Down
26 changes: 24 additions & 2 deletions src/curl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ int S3fsCurl::max_multireq = 20; // default
off_t S3fsCurl::multipart_size = MULTIPART_SIZE; // default
bool S3fsCurl::is_sigv4 = true; // default
bool S3fsCurl::is_ua = true; // default
bool S3fsCurl::is_use_session_token = false; // default

//-------------------------------------------------------------------
// Class methods for S3fsCurl
Expand Down Expand Up @@ -1194,6 +1195,20 @@ bool S3fsCurl::SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey
return true;
}

bool S3fsCurl::SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char* SessionToken)
{
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];
if((!S3fsCurl::is_ibm_iam_auth && access_key_is_empty) || secret_access_key_is_empty || session_token_is_empty){
return false;
}
AWSAccessKeyId = AccessKeyId;
AWSSecretAccessKey = SecretAccessKey;
AWSAccessToken = SessionToken;
return true;
}

long S3fsCurl::SetSslVerifyHostname(long value)
{
if(0 != value && 1 != value){
Expand All @@ -1211,6 +1226,13 @@ bool S3fsCurl::SetIsIBMIAMAuth(bool flag)
return old;
}

bool S3fsCurl::SetIsUseSessionToken(bool flag)
{
bool old = S3fsCurl::is_use_session_token;
S3fsCurl::is_use_session_token = flag;
return old;
}

bool S3fsCurl::SetIsECS(bool flag)
{
bool old = S3fsCurl::is_ecs;
Expand Down Expand Up @@ -2408,7 +2430,7 @@ string S3fsCurl::CalcSignatureV2(const string& method, const string& strMD5, con
string Signature;
string StringToSign;

if(!S3fsCurl::IAM_role.empty() || S3fsCurl::is_ecs){
if(!S3fsCurl::IAM_role.empty() || S3fsCurl::is_ecs || S3fsCurl::is_use_session_token){
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-security-token", S3fsCurl::AWSAccessToken.c_str());
}

Expand Down Expand Up @@ -2446,7 +2468,7 @@ string S3fsCurl::CalcSignature(const string& method, const string& canonical_uri
string Signature, StringCQ, StringToSign;
string uriencode;

if(!S3fsCurl::IAM_role.empty() || S3fsCurl::is_ecs){
if(!S3fsCurl::IAM_role.empty() || S3fsCurl::is_ecs || S3fsCurl::is_use_session_token){
requestHeaders = curl_slist_sort_insert(requestHeaders, "x-amz-security-token", S3fsCurl::AWSAccessToken.c_str());
}

Expand Down
3 changes: 3 additions & 0 deletions src/curl.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ class S3fsCurl
static std::string AWSAccessToken;
static time_t AWSAccessTokenExpire;
static bool is_ecs;
static bool is_use_session_token;
static bool is_ibm_iam_auth;
static std::string IAM_cred_url;
static size_t IAM_field_count;
Expand Down Expand Up @@ -428,6 +429,7 @@ class S3fsCurl
static bool SetVerbose(bool flag);
static bool GetVerbose(void) { return S3fsCurl::is_verbose; }
static bool SetAccessKey(const char* AccessKeyId, const char* SecretAccessKey);
static bool SetAccessKeyWithSessionToken(const char* AccessKeyId, const char* SecretAccessKey, const char * SessionToken);
static bool IsSetAccessKeyID(void){
return (0 < S3fsCurl::AWSAccessKeyId.size());
}
Expand All @@ -443,6 +445,7 @@ class S3fsCurl
static int SetMaxMultiRequest(int max);
static int GetMaxMultiRequest(void) { return S3fsCurl::max_multireq; }
static bool SetIsECS(bool flag);
static bool SetIsUseSessionToken(bool flag);
static bool SetIsIBMIAMAuth(bool flag);
static size_t SetIAMFieldCount(size_t field_count);
static std::string SetIAMCredentialsURL(const char* url);
Expand Down
40 changes: 37 additions & 3 deletions src/s3fs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ static bool is_remove_cache = false;
static bool is_ecs = false;
static bool is_ibm_iam_auth = false;
static bool is_use_xattr = false;
static bool is_use_session_token = false;
static bool create_bucket = false;
static int64_t singlepart_copy_limit = 512 * 1024 * 1024;
static bool is_specified_endpoint = false;
Expand Down Expand Up @@ -4085,6 +4086,7 @@ static int read_aws_credentials_file(const std::string &filename)
string profile;
string accesskey;
string secret;
string session_token;

// read each line
string line;
Expand All @@ -4104,6 +4106,7 @@ static int read_aws_credentials_file(const std::string &filename)
profile = line.substr(1, line.size() - 2);
accesskey.clear();
secret.clear();
session_token.clear();
}

size_t pos = line.find_first_of('=');
Expand All @@ -4116,16 +4119,26 @@ static int read_aws_credentials_file(const std::string &filename)
accesskey = value;
}else if(key == "aws_secret_access_key"){
secret = value;
}else if(key == "aws_session_token"){
session_token = value;
}
}

if(profile != aws_profile){
return EXIT_FAILURE;
}
if(!S3fsCurl::SetAccessKey(accesskey.c_str(), secret.c_str())){
S3FS_PRN_EXIT("failed to set internal data for access key/secret key from aws credential file.");
return EXIT_FAILURE;
if (session_token.empty()) {
if(!S3fsCurl::SetAccessKey(accesskey.c_str(), secret.c_str())){
S3FS_PRN_EXIT("failed to set internal data for access key/secret key from aws credential file.");
return EXIT_FAILURE;
}
} else {
if (!S3fsCurl::SetAccessKeyWithSessionToken(accesskey.c_str(), secret.c_str(), session_token.c_str())) {
S3FS_PRN_EXIT("session token is invalid.");
return EXIT_FAILURE;
}
}

return EXIT_SUCCESS;
}

Expand Down Expand Up @@ -4249,12 +4262,29 @@ static int get_access_keys()
// 3 - environment variables
char* AWSACCESSKEYID = getenv("AWSACCESSKEYID");
char* AWSSECRETACCESSKEY = getenv("AWSSECRETACCESSKEY");
char* AWSSESSIONTOKEN = getenv("AWSSESSIONTOKEN");
if(AWSACCESSKEYID != NULL || AWSSECRETACCESSKEY != NULL){
if( (AWSACCESSKEYID == NULL && AWSSECRETACCESSKEY != NULL) ||
(AWSACCESSKEYID != NULL && AWSSECRETACCESSKEY == NULL) ){
S3FS_PRN_EXIT("if environment variable AWSACCESSKEYID is set then AWSSECRETACCESSKEY must be set too.");
return EXIT_FAILURE;
}
S3FS_PRN_INFO2("access key from env variables");
if (AWSSESSIONTOKEN != NULL) {
S3FS_PRN_INFO2("session token is available");
is_use_session_token = true;
S3fsCurl::SetIsUseSessionToken(true);
if (!S3fsCurl::SetAccessKeyWithSessionToken(AWSACCESSKEYID, AWSSECRETACCESSKEY, AWSSESSIONTOKEN)) {
S3FS_PRN_EXIT("session token is invalid.");
return EXIT_FAILURE;
}
} else {
S3FS_PRN_INFO2("session token is not available");
if (is_use_session_token) {
S3FS_PRN_EXIT("environment variable AWSSESSIONTOKEN is expected to be set.");
return EXIT_FAILURE;
}
}
if(!S3fsCurl::SetAccessKey(AWSACCESSKEYID, AWSSECRETACCESSKEY)){
S3FS_PRN_EXIT("if one access key is specified, both keys need to be specified.");
return EXIT_FAILURE;
Expand Down Expand Up @@ -4680,6 +4710,10 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
is_ibm_iam_auth = true;
return 0;
}
if (0 == STR2NCMP(arg, "use_session_token")) {
S3fsCurl::SetIsUseSessionToken(true);
is_use_session_token = true;
}
if(0 == STR2NCMP(arg, "ibm_iam_endpoint=")){
std::string endpoint_url;
std::string iam_endpoint = strchr(arg, '=') + sizeof(char);
Expand Down
5 changes: 5 additions & 0 deletions src/s3fs_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1329,6 +1329,11 @@ void show_help ()
" Unicode set.\n"
" Useful on clients not using utf-8 as their file system encoding.\n"
"\n"
" use_session_token - indicate that session token should be provided.\n"
" If credentials are provided by environment variables this switch\n"
" forces presence check of AWSSESSIONTOKEN variable.\n"
" Otherwise an error is returned."
"\n"
"FUSE/mount Options:\n"
"\n"
" Most of the generic mount options described in 'man mount' are\n"
Expand Down

0 comments on commit a8e88df

Please sign in to comment.