]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: Code for GetSessionToken REST API.
authorPritha Srivastava <prsrivas@redhat.com>
Wed, 11 Jul 2018 06:29:23 +0000 (11:59 +0530)
committerPritha Srivastava <prsrivas@redhat.com>
Fri, 21 Sep 2018 05:39:33 +0000 (11:09 +0530)
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
src/common/legacy_config_opts.h
src/common/options.cc
src/rgw/rgw_auth_keystone.cc
src/rgw/rgw_common.h
src/rgw/rgw_rest_sts.cc
src/rgw/rgw_rest_sts.h
src/rgw/rgw_sts.cc
src/rgw/rgw_sts.h

index a9cea4ad46fb424cf6100a46635e291741188553..0516b31c16998c477496471e5de83709c845d69b 100644 (file)
@@ -1548,3 +1548,4 @@ OPTION(rgw_website_routing_rules_max_num, OPT_INT) // According to AWS S3, An we
 OPTION(rgw_sts_entry, OPT_STR)
 OPTION(rgw_sts_key, OPT_STR)
 OPTION(rgw_s3_auth_use_sts, OPT_BOOL)  // should we try to use sts for s3?
+OPTION(rgw_sts_max_session_duration, OPT_U64) // Max duration in seconds for which the session token is valid.
index 66bb371180b6b772c564a359e39500036c0b24ca..39ebc1a932d8d6410be2b699250c4eae248897d3 100644 (file)
@@ -6362,6 +6362,10 @@ std::vector<Option> get_rgw_options() {
     .set_default(false)
     .set_description("Should S3 authentication use STS."),
 
+    Option("rgw_sts_max_session_duration", Option::TYPE_UINT, Option::LEVEL_ADVANCED)
+    .set_default("43200")
+    .set_description("Session token max duration")
+    .set_long_description("Max duration in seconds for which the session token is valid."),
   });
 }
 
index eac31efa33f7f0eb0167e5da36f821c31b21463b..04faae07fa93d3d6a382d8a0397c79f49316cc08 100644 (file)
@@ -208,6 +208,12 @@ TokenEngine::result_t
 TokenEngine::authenticate(const std::string& token,
                           const req_state* const s) const
 {
+  //If Keystone is enabled and the request has a session token, then keystone shouldn't authenticate it.
+  if (s->info.args.exists("X-Amz-Security-Token") ||
+      s->info.env->exists("HTTP_X_AMZ_SECURITY_TOKEN")) {
+    return result_t::deny();
+  }
+
   boost::optional<TokenEngine::token_envelope_t> t;
 
   /* This will be initialized on the first call to this method. In C++11 it's
index d42e4c14e1b6fd618477f89558fc7b57cefce743..40c55a9cd304bdc4d3ab49a3c84b02128828256c 100644 (file)
@@ -523,6 +523,7 @@ enum RGWOpType {
   RGW_OP_DEL_BUCKET_META_SEARCH,
   /* sts specific*/
   RGW_STS_ASSUME_ROLE,
+  RGW_STS_GET_SESSION_TOKEN,
 };
 
 class RGWAccessControlPolicy;
index 9cfebd3efa64fb35a18688faac59e3b192071866..ad918fab6cadd89fb83c584cb7ca9773ceba51b8 100644 (file)
@@ -73,6 +73,46 @@ void RGWREST_STS::send_response()
   end_header(s);
 }
 
+int RGWSTSGetSessionToken::verify_permission()
+{
+  return 0;
+}
+
+int RGWSTSGetSessionToken::get_params()
+{
+  duration = s->info.args.get("DurationSeconds");
+  serialNumber = s->info.args.get("SerialNumber");
+  tokenCode = s->info.args.get("TokenCode");
+
+  if (! duration.empty()) {
+    uint64_t duration_in_secs = stoull(duration);
+    if (duration_in_secs < STS::GetSessionTokenRequest::getMinDuration() ||
+            duration_in_secs > s->cct->_conf->rgw_sts_max_session_duration)
+      return -EINVAL;
+  }
+
+  return 0;
+}
+
+void RGWSTSGetSessionToken::execute()
+{
+  if (op_ret = get_params(); op_ret < 0) {
+    return;
+  }
+
+  STS::STSService sts(s->cct, store, s->user->user_id);
+
+  STS::GetSessionTokenRequest req(duration, serialNumber, tokenCode);
+  const auto& [ret, creds] = sts.getSessionToken(req);
+  op_ret = std::move(ret);
+  //Dump the output
+  if (op_ret == 0) {
+    s->formatter->open_object_section("Credentials");
+    creds.dump(s->formatter);
+    s->formatter->close_section();
+  }
+}
+
 int RGWSTSAssumeRole::get_params()
 {
   duration = s->info.args.get("DurationSeconds");
@@ -125,8 +165,11 @@ void RGWSTSAssumeRole::execute()
 RGWOp *RGWHandler_REST_STS::op_post()
 {
   if (s->info.args.exists("Action"))    {
-    if (string action = s->info.args.get("Action"); action == "AssumeRole") {
+    string action = s->info.args.get("Action");
+    if (action == "AssumeRole") {
       return new RGWSTSAssumeRole;
+    } else if (action == "GetSessionToken") {
+      return new RGWSTSGetSessionToken;
     }
   }
   return nullptr;
index 2da0b408b1be954a01d35ed042b79a06176fdf4d..37d4050fdb763e736af7a5183861672bc26e413b 100644 (file)
@@ -29,6 +29,20 @@ public:
   RGWOpType get_type() override { return RGW_STS_ASSUME_ROLE; }
 };
 
+class RGWSTSGetSessionToken : public RGWREST_STS {
+protected:
+  string duration;
+  string serialNumber;
+  string tokenCode;
+public:
+  RGWSTSGetSessionToken() = default;
+  void execute() override;
+  int verify_permission() override;
+  int get_params();
+  const char* name() const override { return "get_keystone_session_token"; }
+  RGWOpType get_type() override { return RGW_STS_GET_SESSION_TOKEN; }
+};
+
 class RGWHandler_REST_STS : public RGWHandler_REST {
   const rgw::auth::StrategyRegistry& auth_registry;
   RGWOp *op_post() override;
index 813804507c05b5aa3e6b40d3144bb302c0d02b3b..2a84d52a575d629d9aa3beae8ee9d499308a5586 100644 (file)
@@ -115,7 +115,6 @@ int Credentials::generateCredentials(CephContext* cct,
     token.acct_type = TYPE_NONE;
   }
 
-  string encrypted_str;
   buffer::list input, enc_output;
   encode(token, input);
 
@@ -315,4 +314,31 @@ AssumeRoleResponse STSService::assumeRole(AssumeRoleRequest& req)
   return make_tuple(0, user, cred, packedPolicySize);
 }
 
+GetSessionTokenRequest::GetSessionTokenRequest(string& duration, string& serialNumber, string& tokenCode)
+{
+  if (duration.empty()) {
+    this->duration = DEFAULT_DURATION_IN_SECS;
+  } else {
+    this->duration = stoull(duration);
+  }
+  this->serialNumber = serialNumber;
+  this->tokenCode = tokenCode;
+}
+
+GetSessionTokenResponse STSService::getSessionToken(GetSessionTokenRequest& req)
+{
+  int ret;
+  Credentials cred;
+
+  //Generate Credentials
+  if (ret = cred.generateCredentials(cct,
+                                      req.getDuration(),
+                                      boost::none,
+                                      boost::none); ret < 0) {
+    return make_tuple(ret, cred);
+  }
+
+  return make_tuple(0, cred);
+}
+
 }
\ No newline at end of file
index 344e452cc0dbe18882867d9b56b988386ccb795a..5a82faa532d3fe30cfef054ebabe9d6ade1de600 100644 (file)
@@ -45,6 +45,20 @@ public:
   int validate_input() const;
 };
 
+class GetSessionTokenRequest {
+protected:
+  static constexpr uint64_t MIN_DURATION_IN_SECS = 900;
+  static constexpr uint64_t DEFAULT_DURATION_IN_SECS = 3600;
+  uint64_t duration;
+  string serialNumber;
+  string tokenCode;
+
+public:
+  GetSessionTokenRequest(string& duration, string& serialNumber, string& tokenCode);
+
+  const uint64_t& getDuration() const { return duration; }
+  static const uint64_t& getMinDuration() { return MIN_DURATION_IN_SECS; }
+};
 
 class AssumedRoleUser {
   string arn;
@@ -129,6 +143,7 @@ public:
 
 //AssumedRoleUser, Credentials, PackedpolicySize
 using AssumeRoleResponse = std::tuple<int, AssumedRoleUser, Credentials, uint64_t> ;
+using GetSessionTokenResponse = std::tuple<int, Credentials>;
 
 class STSService {
   CephContext* cct;
@@ -142,6 +157,7 @@ public:
   STSService(CephContext* cct, RGWRados *store, rgw_user user_id, rgw::auth::Identity* identity) : cct(cct), store(store), user_id(user_id), identity(identity) {}
   std::tuple<int, RGWRole> getRoleInfo(const string& arn);
   AssumeRoleResponse assumeRole(AssumeRoleRequest& req);
+  GetSessionTokenResponse getSessionToken(GetSessionTokenRequest& req);
 };
 }
 #endif /* CEPH_RGW_STS_H */