From: Pritha Srivastava Date: Wed, 16 May 2018 06:11:33 +0000 (+0530) Subject: rgw: Renamed STS related files. X-Git-Tag: v14.0.1~113^2~19 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=c9b2c885d1502fc99f95e30fec8457ab4088e154;p=ceph.git rgw: Renamed STS related files. Signed-off-by: Pritha Srivastava --- diff --git a/src/rgw/CMakeLists.txt b/src/rgw/CMakeLists.txt index b4056ede33f..8efd43bd63d 100644 --- a/src/rgw/CMakeLists.txt +++ b/src/rgw/CMakeLists.txt @@ -140,7 +140,7 @@ set(rgw_a_srcs rgw_swift_auth.cc rgw_usage.cc rgw_opa.cc - sts-assume-role.cc + rgw_sts.cc rgw_rest_sts.cc) gperf_generate(${CMAKE_SOURCE_DIR}/src/rgw/rgw_iam_policy_keywords.gperf diff --git a/src/rgw/rgw_rest_sts.cc b/src/rgw/rgw_rest_sts.cc index a737a633718..f402bd2f30e 100644 --- a/src/rgw/rgw_rest_sts.cc +++ b/src/rgw/rgw_rest_sts.cc @@ -22,7 +22,7 @@ #include "rgw_iam_policy.h" #include "rgw_iam_policy_keywords.h" -#include "sts-assume-role.h" +#include "rgw_sts.h" #include #include diff --git a/src/rgw/rgw_rest_sts.h b/src/rgw/rgw_rest_sts.h index d2f9e9b2923..b12e61a518f 100644 --- a/src/rgw/rgw_rest_sts.h +++ b/src/rgw/rgw_rest_sts.h @@ -1,7 +1,7 @@ #ifndef CEPH_RGW_REST_STS_H #define CEPH_RGW_REST_STS_H -#include "sts-assume-role.h" +#include "rgw_sts.h" class RGWREST_STS : public RGWRESTOp { protected: diff --git a/src/rgw/rgw_sts.cc b/src/rgw/rgw_sts.cc new file mode 100644 index 00000000000..6bdccff7544 --- /dev/null +++ b/src/rgw/rgw_sts.cc @@ -0,0 +1,317 @@ +#include +#include +#include +#include +#include + +#include "common/errno.h" +#include "common/Formatter.h" +#include "common/ceph_json.h" +#include "common/ceph_time.h" +#include "rgw_rados.h" +#include "auth/Crypto.h" +#include "include/ceph_fs.h" + +#include "include/types.h" +#include "rgw_string.h" + +#include "rgw_common.h" +#include "rgw_tools.h" +#include "rgw_role.h" +#include "rgw_user.h" +#include "rgw_iam_policy.h" +#include "rgw_sts.h" + +#define dout_subsys ceph_subsys_rgw + +namespace STS { + +void Credentials::dump(Formatter *f) const +{ + encode_json("AccessKeyId", accessKeyId , f); + encode_json("Expiration", expiration , f); + encode_json("SecretAccessKey", secretAccessKey , f); + encode_json("SessionToken", sessionToken , f); +} + +int Credentials::generateCredentials(CephContext* cct, const uint64_t& duration) +{ + uuid_d accessKey, secretKey; + char accessKeyId_str[MAX_ACCESS_KEY_LEN], secretAccessKey_str[MAX_ACCESS_KEY_LEN]; + + //AccessKeyId + accessKey.generate_random(); + accessKey.print(accessKeyId_str); + accessKeyId = accessKeyId_str; + + //SecretAccessKey + secretKey.generate_random(); + secretKey.print(secretAccessKey_str); + secretAccessKey = secretAccessKey_str; + + //Expiration + real_clock::time_point t = real_clock::now(); + + struct timeval tv; + real_clock::to_timeval(t, tv); + tv.tv_sec += duration; + + struct tm result; + gmtime_r(&tv.tv_sec, &result); + int usec = (int)tv.tv_usec/1000; + expiration = boost::str(boost::format("%s-%s-%sT%s:%s:%s.%sZ") + % (result.tm_year + 1900) + % (result.tm_mon + 1) + % result.tm_mday + % result.tm_hour + % result.tm_min + % result.tm_sec + % usec); + + //Session Token - Encrypt using AES & base64 encode the result + auto* cryptohandler = cct->get_crypto_handler(CEPH_CRYPTO_AES); + if (! cryptohandler) { + return -EINVAL; + } + char secret_s[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + }; + bufferptr secret(secret_s, sizeof(secret_s)); + int ret = 0; + if (ret = cryptohandler->validate_secret(secret); ret < 0) { + ldout(cct, 0) << "ERROR: Invalid secret key" << dendl; + return ret; + } + string error; + auto* keyhandler = cryptohandler->get_key_handler(secret, error); + if (! keyhandler) { + return -EINVAL; + } + error.clear(); + string encrypted_str, input_str = "acess_key_id=" + accessKeyId + "&" + + "secret_access_key=" + secretAccessKey + "&" + + "expiration=" + expiration; + bufferlist input, enc_output; + input.append(input_str); + if (ret = keyhandler->encrypt(input, enc_output, &error); ret < 0) { + return ret; + } + + enc_output.append('\0'); + encrypted_str = enc_output.c_str(); + + bufferlist enc_bp, encoded_op; + enc_bp.append(encrypted_str); + enc_bp.encode_base64(encoded_op); + encoded_op.append('\0'); + sessionToken = encoded_op.c_str(); + + return ret; +} + +void AssumedRoleUser::dump(Formatter *f) const +{ + encode_json("Arn", arn , f); + encode_json("AssumeRoleId", assumeRoleId , f); +} + +int AssumedRoleUser::generateAssumedRoleUser(CephContext* cct, + RGWRados *store, + const string& roleId, + const rgw::IAM::ARN& roleArn, + const string& roleSessionName) +{ + string resource = std::move(roleArn.resource); + boost::replace_first(resource, "role", "assumed-role"); + resource.append("/"); + resource.append(roleSessionName); + + rgw::IAM::ARN assumed_role_arn(rgw::IAM::Partition::aws, + rgw::IAM::Service::sts, + "", roleArn.account, resource); + arn = assumed_role_arn.to_string(); + + //Assumeroleid = roleid:rolesessionname + assumeRoleId = roleId + ":" + roleSessionName; + + return 0; +} + +AssumeRoleRequest::AssumeRoleRequest(string& _duration, string& _externalId, string& _iamPolicy, + string& _roleArn, string& _roleSessionName, string& _serialNumber, + string& _tokenCode) + : externalId(_externalId), iamPolicy(_iamPolicy), + roleArn(_roleArn), roleSessionName(_roleSessionName), + serialNumber(_serialNumber), tokenCode(_tokenCode) +{ + if (_duration.empty()) { + duration = DEFAULT_DURATION_IN_SECS; + } else { + duration = std::stoull(_duration); + } +} + +int AssumeRoleRequest::validate_input() const +{ + if (duration < MIN_DURATION_IN_SECS || + duration > MAX_DURATION_IN_SECS) { + return -EINVAL; + } + + if (! externalId.empty()) { + if (externalId.length() < MIN_EXTERNAL_ID_LEN || + externalId.length() > MAX_EXTERNAL_ID_LEN) { + return -EINVAL; + } + + std::regex regex_externalId("[A-Za-z0-9_=,.@:/-]+"); + if (! std::regex_match(externalId, regex_externalId)) { + return -EINVAL; + } + } + if (! iamPolicy.empty() && + (iamPolicy.size() < MIN_POLICY_SIZE || iamPolicy.size() > MAX_POLICY_SIZE)) { + return -ERR_PACKED_POLICY_TOO_LARGE; + } + + if (! roleArn.empty() && + (roleArn.size() < MIN_ROLE_ARN_SIZE || roleArn.size() > MAX_ROLE_ARN_SIZE)) { + return -EINVAL; + } + + if (! roleSessionName.empty()) { + if (roleSessionName.size() < MIN_ROLE_SESSION_SIZE || roleSessionName.size() > MAX_ROLE_SESSION_SIZE) { + return -EINVAL; + } + + std::regex regex_roleSession("[A-Za-z0-9_=,.@-]+"); + if (! std::regex_match(roleSessionName, regex_roleSession)) { + return -EINVAL; + } + } + if (! serialNumber.empty()){ + if (serialNumber.size() < MIN_SERIAL_NUMBER_SIZE || serialNumber.size() > MAX_SERIAL_NUMBER_SIZE) { + return -EINVAL; + } + + std::regex regex_serialNumber("[A-Za-z0-9_=/:,.@-]+"); + if (! std::regex_match(serialNumber, regex_serialNumber)) { + return -EINVAL; + } + } + if (! tokenCode.empty() && tokenCode.size() == TOKEN_CODE_SIZE) { + return -EINVAL; + } + + return 0; +} + +std::tuple STSService::getRoleInfo(const string& arn) +{ + if (auto r_arn = rgw::IAM::ARN::parse(arn); r_arn) { + auto pos = r_arn->resource.find_last_of('/'); + string roleName = r_arn->resource.substr(pos + 1); + RGWRole role(cct, store, roleName, r_arn->account); + if (int ret = role.get(); ret < 0) { + if (ret == -ENOENT) { + ret = -ERR_NO_ROLE_FOUND; + } + return make_tuple(ret, this->role); + } else { + this->role = std::move(role); + return make_tuple(0, this->role); + } + } else { + return make_tuple(-EINVAL, this->role); + } +} + +int STSService::_storeARNandPolicy(string& policy, string& arn) +{ + int ret = 0; + RGWUserInfo info; + if (ret = rgw_get_user_info_by_uid(store, user_id, info); ret < 0) { + return -ERR_NO_SUCH_ENTITY; + } + + info.assumed_role_arn = arn; + + map uattrs; + if (ret = rgw_get_user_attrs_by_uid(store, user_id, uattrs); ret == -ENOENT) { + return -ERR_NO_SUCH_ENTITY; + } + if (! policy.empty()) { + bufferlist bl = bufferlist::static_from_string(policy); + ldout(cct, 20) << "bufferlist policy: " << bl.c_str() << dendl; + try { + const rgw::IAM::Policy p(cct, user_id.tenant, bl); + map policies; + if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) { + bufferlist out_bl = uattrs[RGW_ATTR_USER_POLICY]; + decode(policies, out_bl); + } + bufferlist in_bl; + policies["assumerolepolicy"] = policy; + encode(policies, in_bl); + uattrs[RGW_ATTR_USER_POLICY] = in_bl; + } catch (rgw::IAM::PolicyParseException& e) { + ldout(cct, 20) << "failed to parse policy: " << e.what() << dendl; + return -ERR_MALFORMED_DOC; + } + } + RGWObjVersionTracker objv_tracker; + if (rgw_store_user_info(store, info, &info, &objv_tracker, real_time(), + false, &uattrs); ret < 0) { + return -ERR_INTERNAL_ERROR; + } + return ret; +} + +AssumeRoleResponse STSService::assumeRole(AssumeRoleRequest& req) +{ + uint64_t packedPolicySize = 0, roleMaxSessionDuration = 0; + AssumedRoleUser user; + Credentials cred; + string roleId; + + //Get the role info which is being assumed + boost::optional r_arn; + if (r_arn = rgw::IAM::ARN::parse(req.getRoleARN()); r_arn == boost::none) { + return make_tuple(-EINVAL, user, cred, packedPolicySize); + } + + roleId = role.get_id(); + roleMaxSessionDuration = role.get_max_session_duration(); + req.setMaxDuration(roleMaxSessionDuration); + + //Validate input + int ret = 0; + if (ret = req.validate_input(); ret < 0) { + return make_tuple(ret, user, cred, packedPolicySize); + } + + //Calculate PackedPolicySize + string policy = req.getPolicy(); + packedPolicySize = (policy.size() / req.getMaxPolicySize()) * 100; + + //Generate Assumed Role User + if (ret = user.generateAssumedRoleUser(cct, store, roleId, r_arn.get(), req.getRoleSessionName()); ret < 0) { + return make_tuple(ret, user, cred, packedPolicySize); + } + + //Generate Credentials + if (ret = cred.generateCredentials(cct, req.getDuration()); ret < 0) { + return make_tuple(ret, user, cred, packedPolicySize); + } + + //Save ARN and Policy with the user + string arn = user.getARN(); + if (ret = _storeARNandPolicy(policy, arn); ret < 0) { + return make_tuple(ret, user, cred, packedPolicySize); + } + + return make_tuple(0, user, cred, packedPolicySize); +} + +} \ No newline at end of file diff --git a/src/rgw/rgw_sts.h b/src/rgw/rgw_sts.h new file mode 100644 index 00000000000..dbcf396263e --- /dev/null +++ b/src/rgw/rgw_sts.h @@ -0,0 +1,94 @@ +#ifndef CEPH_RGW_STS_H +#define CEPH_RGW_STS_H + +#include "rgw_role.h" + +namespace STS { + +class AssumeRoleRequest { + static constexpr uint64_t MIN_POLICY_SIZE = 1; + static constexpr uint64_t MAX_POLICY_SIZE = 2048; + static constexpr uint64_t DEFAULT_DURATION_IN_SECS = 3600; + static constexpr uint64_t MIN_DURATION_IN_SECS = 900; + static constexpr uint64_t MIN_EXTERNAL_ID_LEN = 2; + static constexpr uint64_t MAX_EXTERNAL_ID_LEN = 1224; + static constexpr uint64_t MIN_ROLE_ARN_SIZE = 2; + static constexpr uint64_t MAX_ROLE_ARN_SIZE = 2048; + static constexpr uint64_t MIN_ROLE_SESSION_SIZE = 2; + static constexpr uint64_t MAX_ROLE_SESSION_SIZE = 64; + static constexpr uint64_t MIN_SERIAL_NUMBER_SIZE = 9; + static constexpr uint64_t MAX_SERIAL_NUMBER_SIZE = 256; + static constexpr uint64_t TOKEN_CODE_SIZE = 6; + uint64_t MAX_DURATION_IN_SECS; + uint64_t duration; + string externalId; + string iamPolicy; + string roleArn; + string roleSessionName; + string serialNumber; + string tokenCode; +public: + AssumeRoleRequest( string& _duration, + string& _externalId, + string& _iamPolicy, + string& _roleArn, + string& _roleSessionName, + string& _serialNumber, + string& _tokenCode); + const string& getRoleARN() const { return roleArn; } + const string& getRoleSessionName() const { return roleSessionName; } + const string& getPolicy() const {return iamPolicy; } + static const uint64_t& getMaxPolicySize() { return MAX_POLICY_SIZE; } + void setMaxDuration(const uint64_t& maxDuration) { MAX_DURATION_IN_SECS = maxDuration; } + uint64_t& getDuration() { return duration; } + int validate_input() const; +}; + + +class AssumedRoleUser { + string arn; + string assumeRoleId; +public: + int generateAssumedRoleUser( CephContext* cct, + RGWRados *store, + const string& roleId, + const rgw::IAM::ARN& roleArn, + const string& roleSessionName); + const string& getARN() const { return arn; } + const string& getAssumeRoleId() const { return assumeRoleId; } + void dump(Formatter *f) const; +}; + +class Credentials { + static constexpr int MAX_ACCESS_KEY_LEN = 64; + string accessKeyId; + string expiration; + string secretAccessKey; + string sessionToken; +public: + int generateCredentials(CephContext* cct, const uint64_t& duration); + const string& getAccessKeyId() const { return accessKeyId; } + const string& getExpiration() const { return expiration; } + const string& getSecretAccessKey() const { return secretAccessKey; } + const string& getSessionToken() const { return sessionToken; } + void dump(Formatter *f) const; +}; + +//AssumedRoleUser, Credentials, PackedpolicySize +using AssumeRoleResponse = std::tuple ; + +class STSService { + CephContext* cct; + RGWRados *store; + rgw_user user_id; + RGWRole role; + int _storeARNandPolicy(string& policy, string& arn); +public: + STSService() = default; + STSService(CephContext* _cct, RGWRados *_store, rgw_user _user_id) : cct(_cct), store(_store), user_id(_user_id) {} + std::tuple getRoleInfo(const string& arn); + AssumeRoleResponse assumeRole(AssumeRoleRequest& req); +}; +} +#endif /* CEPH_RGW_STS_H */ + diff --git a/src/rgw/sts-assume-role.cc b/src/rgw/sts-assume-role.cc deleted file mode 100644 index 0c4c5b0bda9..00000000000 --- a/src/rgw/sts-assume-role.cc +++ /dev/null @@ -1,317 +0,0 @@ -#include -#include -#include -#include -#include - -#include "common/errno.h" -#include "common/Formatter.h" -#include "common/ceph_json.h" -#include "common/ceph_time.h" -#include "rgw_rados.h" -#include "auth/Crypto.h" -#include "include/ceph_fs.h" - -#include "include/types.h" -#include "rgw_string.h" - -#include "rgw_common.h" -#include "rgw_tools.h" -#include "rgw_role.h" -#include "rgw_user.h" -#include "rgw_iam_policy.h" -#include "sts-assume-role.h" - -#define dout_subsys ceph_subsys_rgw - -namespace STS { - -void Credentials::dump(Formatter *f) const -{ - encode_json("AccessKeyId", accessKeyId , f); - encode_json("Expiration", expiration , f); - encode_json("SecretAccessKey", secretAccessKey , f); - encode_json("SessionToken", sessionToken , f); -} - -int Credentials::generateCredentials(CephContext* cct, const uint64_t& duration) -{ - uuid_d accessKey, secretKey; - char accessKeyId_str[MAX_ACCESS_KEY_LEN], secretAccessKey_str[MAX_ACCESS_KEY_LEN]; - - //AccessKeyId - accessKey.generate_random(); - accessKey.print(accessKeyId_str); - accessKeyId = accessKeyId_str; - - //SecretAccessKey - secretKey.generate_random(); - secretKey.print(secretAccessKey_str); - secretAccessKey = secretAccessKey_str; - - //Expiration - real_clock::time_point t = real_clock::now(); - - struct timeval tv; - real_clock::to_timeval(t, tv); - tv.tv_sec += duration; - - struct tm result; - gmtime_r(&tv.tv_sec, &result); - int usec = (int)tv.tv_usec/1000; - expiration = boost::str(boost::format("%s-%s-%sT%s:%s:%s.%sZ") - % (result.tm_year + 1900) - % (result.tm_mon + 1) - % result.tm_mday - % result.tm_hour - % result.tm_min - % result.tm_sec - % usec); - - //Session Token - Encrypt using AES & base64 encode the result - auto* cryptohandler = cct->get_crypto_handler(CEPH_CRYPTO_AES); - if (! cryptohandler) { - return -EINVAL; - } - char secret_s[] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - }; - bufferptr secret(secret_s, sizeof(secret_s)); - int ret = 0; - if (ret = cryptohandler->validate_secret(secret); ret < 0) { - ldout(cct, 0) << "ERROR: Invalid secret key" << dendl; - return ret; - } - string error; - auto* keyhandler = cryptohandler->get_key_handler(secret, error); - if (! keyhandler) { - return -EINVAL; - } - error.clear(); - string encrypted_str, input_str = "acess_key_id=" + accessKeyId + "&" + - "secret_access_key=" + secretAccessKey + "&" + - "expiration=" + expiration; - bufferlist input, enc_output; - input.append(input_str); - if (ret = keyhandler->encrypt(input, enc_output, &error); ret < 0) { - return ret; - } - - enc_output.append('\0'); - encrypted_str = enc_output.c_str(); - - bufferlist enc_bp, encoded_op; - enc_bp.append(encrypted_str); - enc_bp.encode_base64(encoded_op); - encoded_op.append('\0'); - sessionToken = encoded_op.c_str(); - - return ret; -} - -void AssumedRoleUser::dump(Formatter *f) const -{ - encode_json("Arn", arn , f); - encode_json("AssumeRoleId", assumeRoleId , f); -} - -int AssumedRoleUser::generateAssumedRoleUser(CephContext* cct, - RGWRados *store, - const string& roleId, - const rgw::IAM::ARN& roleArn, - const string& roleSessionName) -{ - string resource = std::move(roleArn.resource); - boost::replace_first(resource, "role", "assumed-role"); - resource.append("/"); - resource.append(roleSessionName); - - rgw::IAM::ARN assumed_role_arn(rgw::IAM::Partition::aws, - rgw::IAM::Service::sts, - "", roleArn.account, resource); - arn = assumed_role_arn.to_string(); - - //Assumeroleid = roleid:rolesessionname - assumeRoleId = roleId + ":" + roleSessionName; - - return 0; -} - -AssumeRoleRequest::AssumeRoleRequest(string& _duration, string& _externalId, string& _iamPolicy, - string& _roleArn, string& _roleSessionName, string& _serialNumber, - string& _tokenCode) - : externalId(_externalId), iamPolicy(_iamPolicy), - roleArn(_roleArn), roleSessionName(_roleSessionName), - serialNumber(_serialNumber), tokenCode(_tokenCode) -{ - if (_duration.empty()) { - duration = DEFAULT_DURATION_IN_SECS; - } else { - duration = std::stoull(_duration); - } -} - -int AssumeRoleRequest::validate_input() const -{ - if (duration < MIN_DURATION_IN_SECS || - duration > MAX_DURATION_IN_SECS) { - return -EINVAL; - } - - if (! externalId.empty()) { - if (externalId.length() < MIN_EXTERNAL_ID_LEN || - externalId.length() > MAX_EXTERNAL_ID_LEN) { - return -EINVAL; - } - - std::regex regex_externalId("[A-Za-z0-9_=,.@:/-]+"); - if (! std::regex_match(externalId, regex_externalId)) { - return -EINVAL; - } - } - if (! iamPolicy.empty() && - (iamPolicy.size() < MIN_POLICY_SIZE || iamPolicy.size() > MAX_POLICY_SIZE)) { - return -ERR_PACKED_POLICY_TOO_LARGE; - } - - if (! roleArn.empty() && - (roleArn.size() < MIN_ROLE_ARN_SIZE || roleArn.size() > MAX_ROLE_ARN_SIZE)) { - return -EINVAL; - } - - if (! roleSessionName.empty()) { - if (roleSessionName.size() < MIN_ROLE_SESSION_SIZE || roleSessionName.size() > MAX_ROLE_SESSION_SIZE) { - return -EINVAL; - } - - std::regex regex_roleSession("[A-Za-z0-9_=,.@-]+"); - if (! std::regex_match(roleSessionName, regex_roleSession)) { - return -EINVAL; - } - } - if (! serialNumber.empty()){ - if (serialNumber.size() < MIN_SERIAL_NUMBER_SIZE || serialNumber.size() > MAX_SERIAL_NUMBER_SIZE) { - return -EINVAL; - } - - std::regex regex_serialNumber("[A-Za-z0-9_=/:,.@-]+"); - if (! std::regex_match(serialNumber, regex_serialNumber)) { - return -EINVAL; - } - } - if (! tokenCode.empty() && tokenCode.size() == TOKEN_CODE_SIZE) { - return -EINVAL; - } - - return 0; -} - -std::tuple STSService::getRoleInfo(const string& arn) -{ - if (auto r_arn = rgw::IAM::ARN::parse(arn); r_arn) { - auto pos = r_arn->resource.find_last_of('/'); - string roleName = r_arn->resource.substr(pos + 1); - RGWRole role(cct, store, roleName, r_arn->account); - if (int ret = role.get(); ret < 0) { - if (ret == -ENOENT) { - ret = -ERR_NO_ROLE_FOUND; - } - return make_tuple(ret, this->role); - } else { - this->role = std::move(role); - return make_tuple(0, this->role); - } - } else { - return make_tuple(-EINVAL, this->role); - } -} - -int STSService::_storeARNandPolicy(string& policy, string& arn) -{ - int ret = 0; - RGWUserInfo info; - if (ret = rgw_get_user_info_by_uid(store, user_id, info); ret < 0) { - return -ERR_NO_SUCH_ENTITY; - } - - info.assumed_role_arn = arn; - - map uattrs; - if (ret = rgw_get_user_attrs_by_uid(store, user_id, uattrs); ret == -ENOENT) { - return -ERR_NO_SUCH_ENTITY; - } - if (! policy.empty()) { - bufferlist bl = bufferlist::static_from_string(policy); - ldout(cct, 20) << "bufferlist policy: " << bl.c_str() << dendl; - try { - const rgw::IAM::Policy p(cct, user_id.tenant, bl); - map policies; - if (auto it = uattrs.find(RGW_ATTR_USER_POLICY); it != uattrs.end()) { - bufferlist out_bl = uattrs[RGW_ATTR_USER_POLICY]; - decode(policies, out_bl); - } - bufferlist in_bl; - policies["assumerolepolicy"] = policy; - encode(policies, in_bl); - uattrs[RGW_ATTR_USER_POLICY] = in_bl; - } catch (rgw::IAM::PolicyParseException& e) { - ldout(cct, 20) << "failed to parse policy: " << e.what() << dendl; - return -ERR_MALFORMED_DOC; - } - } - RGWObjVersionTracker objv_tracker; - if (rgw_store_user_info(store, info, &info, &objv_tracker, real_time(), - false, &uattrs); ret < 0) { - return -ERR_INTERNAL_ERROR; - } - return ret; -} - -AssumeRoleResponse STSService::assumeRole(AssumeRoleRequest& req) -{ - uint64_t packedPolicySize = 0, roleMaxSessionDuration = 0; - AssumedRoleUser user; - Credentials cred; - string roleId; - - //Get the role info which is being assumed - boost::optional r_arn; - if (r_arn = rgw::IAM::ARN::parse(req.getRoleARN()); r_arn == boost::none) { - return make_tuple(-EINVAL, user, cred, packedPolicySize); - } - - roleId = role.get_id(); - roleMaxSessionDuration = role.get_max_session_duration(); - req.setMaxDuration(roleMaxSessionDuration); - - //Validate input - int ret = 0; - if (ret = req.validate_input(); ret < 0) { - return make_tuple(ret, user, cred, packedPolicySize); - } - - //Calculate PackedPolicySize - string policy = req.getPolicy(); - packedPolicySize = (policy.size() / req.getMaxPolicySize()) * 100; - - //Generate Assumed Role User - if (ret = user.generateAssumedRoleUser(cct, store, roleId, r_arn.get(), req.getRoleSessionName()); ret < 0) { - return make_tuple(ret, user, cred, packedPolicySize); - } - - //Generate Credentials - if (ret = cred.generateCredentials(cct, req.getDuration()); ret < 0) { - return make_tuple(ret, user, cred, packedPolicySize); - } - - //Save ARN and Policy with the user - string arn = user.getARN(); - if (ret = _storeARNandPolicy(policy, arn); ret < 0) { - return make_tuple(ret, user, cred, packedPolicySize); - } - - return make_tuple(0, user, cred, packedPolicySize); -} - -} \ No newline at end of file diff --git a/src/rgw/sts-assume-role.h b/src/rgw/sts-assume-role.h deleted file mode 100644 index 4f4237ea178..00000000000 --- a/src/rgw/sts-assume-role.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef CEPH_STS_ASSUME_ROLE_H -#define CEPH_STS_ASSUME_ROLE_H - -#include "rgw_role.h" - -namespace STS { - -class AssumeRoleRequest { - static constexpr uint64_t MIN_POLICY_SIZE = 1; - static constexpr uint64_t MAX_POLICY_SIZE = 2048; - static constexpr uint64_t DEFAULT_DURATION_IN_SECS = 3600; - static constexpr uint64_t MIN_DURATION_IN_SECS = 900; - static constexpr uint64_t MIN_EXTERNAL_ID_LEN = 2; - static constexpr uint64_t MAX_EXTERNAL_ID_LEN = 1224; - static constexpr uint64_t MIN_ROLE_ARN_SIZE = 2; - static constexpr uint64_t MAX_ROLE_ARN_SIZE = 2048; - static constexpr uint64_t MIN_ROLE_SESSION_SIZE = 2; - static constexpr uint64_t MAX_ROLE_SESSION_SIZE = 64; - static constexpr uint64_t MIN_SERIAL_NUMBER_SIZE = 9; - static constexpr uint64_t MAX_SERIAL_NUMBER_SIZE = 256; - static constexpr uint64_t TOKEN_CODE_SIZE = 6; - uint64_t MAX_DURATION_IN_SECS; - uint64_t duration; - string externalId; - string iamPolicy; - string roleArn; - string roleSessionName; - string serialNumber; - string tokenCode; -public: - AssumeRoleRequest( string& _duration, - string& _externalId, - string& _iamPolicy, - string& _roleArn, - string& _roleSessionName, - string& _serialNumber, - string& _tokenCode); - const string& getRoleARN() const { return roleArn; } - const string& getRoleSessionName() const { return roleSessionName; } - const string& getPolicy() const {return iamPolicy; } - static const uint64_t& getMaxPolicySize() { return MAX_POLICY_SIZE; } - void setMaxDuration(const uint64_t& maxDuration) { MAX_DURATION_IN_SECS = maxDuration; } - uint64_t& getDuration() { return duration; } - int validate_input() const; -}; - - -class AssumedRoleUser { - string arn; - string assumeRoleId; -public: - int generateAssumedRoleUser( CephContext* cct, - RGWRados *store, - const string& roleId, - const rgw::IAM::ARN& roleArn, - const string& roleSessionName); - const string& getARN() const { return arn; } - const string& getAssumeRoleId() const { return assumeRoleId; } - void dump(Formatter *f) const; -}; - -class Credentials { - static constexpr int MAX_ACCESS_KEY_LEN = 64; - string accessKeyId; - string expiration; - string secretAccessKey; - string sessionToken; -public: - int generateCredentials(CephContext* cct, const uint64_t& duration); - const string& getAccessKeyId() const { return accessKeyId; } - const string& getExpiration() const { return expiration; } - const string& getSecretAccessKey() const { return secretAccessKey; } - const string& getSessionToken() const { return sessionToken; } - void dump(Formatter *f) const; -}; - -//AssumedRoleUser, Credentials, PackedpolicySize -using AssumeRoleResponse = std::tuple ; - -class STSService { - CephContext* cct; - RGWRados *store; - rgw_user user_id; - RGWRole role; - int _storeARNandPolicy(string& policy, string& arn); -public: - STSService() = default; - STSService(CephContext* _cct, RGWRados *_store, rgw_user _user_id) : cct(_cct), store(_store), user_id(_user_id) {} - std::tuple getRoleInfo(const string& arn); - AssumeRoleResponse assumeRole(AssumeRoleRequest& req); -}; -} -#endif /* CEPH_STS_ASSUME_ROLE_H */ -