Use role name instead of profile name when iam_role=auto

When using an instance with an IAM Role, transient credentials can be
found in http://169.254.169.254/latest/meta-data/ at
iam/security-credentials/role-name and s3fs tries to do this. However,
it is using the profile-name where role-name is needed. In many cases
the role and profile name are the same, but they are not always.

The simplest way to find the role name appears to be to GET
http://169.254.169.254/latest/meta-data/iam/security-credentials/
itself, which returns a listing of the role names for which temporary
credentials exist. (I think there will probably only be one, but we
probably want to split on newlines and take the first one here in case
that assumption is not valid). This is the approach the AWS SDK appears
to use (based on WireShark analysis).

Bug: https://github.com/s3fs-fuse/s3fs-fuse/issues/421
Signed-off-by: Nathaniel W. Turner <nate@houseofnate.net>
This commit is contained in:
Nathaniel W. Turner 2016-05-23 18:09:16 -07:00
parent 594c9ca7d2
commit 584ea488bf
2 changed files with 6 additions and 36 deletions

View File

@ -315,9 +315,6 @@ void CurlHandlerPool::ReturnHandler(CURL* h)
#define IAMCRED_ACCESSTOKEN "Token" #define IAMCRED_ACCESSTOKEN "Token"
#define IAMCRED_EXPIRATION "Expiration" #define IAMCRED_EXPIRATION "Expiration"
#define IAMCRED_KEYCOUNT 4 #define IAMCRED_KEYCOUNT 4
#define IAM_DEFAULT_ROLE_URL "http://169.254.169.254/latest/meta-data/iam/info"
#define IAMDEFROLE_PROFARN "InstanceProfileArn"
#define IAMDEFROLE_PROFARN_PART ":instance-profile/"
// [NOTICE] // [NOTICE]
// This symbol is for libcurl under 7.23.0 // This symbol is for libcurl under 7.23.0
@ -1447,40 +1444,13 @@ bool S3fsCurl::ParseIAMRoleFromMetaDataResponse(const char* response, string& ro
// [NOTE] // [NOTE]
// expected following strings. // expected following strings.
// //
// { // myrolename
// "Code" : "Success",
// "LastUpdated" : "2016-01-01T00:00:00Z",
// "InstanceProfileArn" : "arn:aws:iam::111111111111:instance-profile/myrolename",
// "InstanceProfileId" : "AAAAAAAAAAAAAAAAAAAAA"
// }
// //
istringstream ssrole(response); istringstream ssrole(response);
string oneline; string oneline;
while(getline(ssrole, oneline, '\n')){ if (getline(ssrole, oneline, '\n')){
string::size_type pos; rolename = oneline;
if(string::npos != (pos = oneline.find(IAMDEFROLE_PROFARN))){ return !rolename.empty();
if(string::npos == (pos = oneline.find(':', pos + strlen(IAMDEFROLE_PROFARN)))){
continue;
}
if(string::npos == (pos = oneline.find('\"', pos))){
continue;
}
// value
oneline = oneline.substr(pos + sizeof(char));
if(string::npos == (pos = oneline.find('\"'))){
continue;
}
oneline = oneline.substr(0, pos);
// role name
if(string::npos == (pos = oneline.find(IAMDEFROLE_PROFARN_PART))){
continue;
}
rolename = oneline.substr(pos + strlen(IAMDEFROLE_PROFARN_PART));
return !rolename.empty();
}
} }
return false; return false;
} }
@ -2384,7 +2354,7 @@ bool S3fsCurl::LoadIAMRoleFromMetaData(void)
} }
// url // url
url = IAM_DEFAULT_ROLE_URL; url = IAM_CRED_URL;
requestHeaders = NULL; requestHeaders = NULL;
responseHeaders.clear(); responseHeaders.clear();
bodydata = new BodyData(); bodydata = new BodyData();

View File

@ -3354,7 +3354,7 @@ static void* s3fs_init(struct fuse_conn_info* conn)
// check loading IAM role name // check loading IAM role name
if(load_iamrole){ if(load_iamrole){
// load IAM role name from http://169.254.169.254/latest/meta-data/iam/info // load IAM role name from http://169.254.169.254/latest/meta-data/iam/security-credentials
// //
S3fsCurl s3fscurl; S3fsCurl s3fscurl;
if(!s3fscurl.LoadIAMRoleFromMetaData()){ if(!s3fscurl.LoadIAMRoleFromMetaData()){