]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: adding user related web token claims to ops log 38970/head
authorPritha Srivastava <prsrivas@redhat.com>
Mon, 11 May 2020 17:52:02 +0000 (23:22 +0530)
committerNathan Cutler <ncutler@suse.com>
Tue, 19 Jan 2021 17:14:48 +0000 (18:14 +0100)
for auditing purposes.

Fixes: https://tracker.ceph.com/issues/45989
Signed-off-by: Pritha Srivastava <prsrivas@redhat.com>
(cherry picked from commit bb6a68ec14f07c17fdf68243aaec35c17d5e01bf)

src/rgw/rgw_auth.cc
src/rgw/rgw_auth.h
src/rgw/rgw_auth_s3.h
src/rgw/rgw_common.h
src/rgw/rgw_log.cc
src/rgw/rgw_log.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_sts.cc
src/rgw/rgw_sts.h

index 22d8ccd0d49e40b22dac59b863e4acdc1f71ae24..60b01d8588efb2df119bccba14582915827f76e7 100644 (file)
@@ -742,6 +742,11 @@ void rgw::auth::RoleApplier::modify_request_state(const DoutPrefixProvider *dpp,
   string condition = "aws:userid";
   string value = role.id + ":" + role_session_name;
   s->env.emplace(condition, value);
+
+  s->token_claims.emplace_back("sts");
+  for (auto& it : token_claims) {
+    s->token_claims.emplace_back(it);
+  }
 }
 
 rgw::auth::Engine::result_t
index e9a243dbb716e00682bb6fa580d0a326a8a87b54..3d841213a492eb524d7fb75c8267276101dff34a 100644 (file)
@@ -638,6 +638,7 @@ protected:
   const rgw_user user_id;
   string token_policy;
   string role_session_name;
+  std::vector<string> token_claims;
 
 public:
 
@@ -645,11 +646,13 @@ public:
                const Role& role,
                const rgw_user& user_id,
                const string& token_policy,
-               const string& role_session_name)
+               const string& role_session_name,
+               const std::vector<string>& token_claims)
     : role(role),
       user_id(user_id),
       token_policy(token_policy),
-      role_session_name(role_session_name) {}
+      role_session_name(role_session_name),
+      token_claims(token_claims) {}
 
   uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
     return 0;
@@ -678,7 +681,8 @@ public:
                                       const rgw::auth::RoleApplier::Role& role_name,
                                       const rgw_user& user_id,
                                       const std::string& token_policy,
-                                      const std::string& role_session) const = 0;
+                                      const std::string& role_session,
+                                      const std::vector<string>& token_claims) const = 0;
     };
 };
 
index 0809ee854eb8783c3a2f6fe970a69f06b3997a98..0baad3401dd4ab025d0d506474de29376a6bb112 100644 (file)
@@ -68,9 +68,10 @@ class STSAuthStrategy : public rgw::auth::Strategy,
                             const rgw::auth::RoleApplier::Role& role,
                             const rgw_user& user_id,
                             const std::string& token_policy,
-                            const std::string& role_session_name) const override {
+                            const std::string& role_session_name,
+                            const std::vector<string>& token_claims) const override {
     auto apl = rgw::auth::add_sysreq(cct, ctl, s,
-      rgw::auth::RoleApplier(cct, role, user_id, token_policy, role_session_name));
+      rgw::auth::RoleApplier(cct, role, user_id, token_policy, role_session_name, token_claims));
     return aplptr_t(new decltype(apl)(std::move(apl)));
   }
 
index 7ce379b0dda63bac12f75cfb54831d7a1c5eec7f..48115804fc9a3d0e5f8793b8dda14647734317f6 100644 (file)
@@ -1747,6 +1747,9 @@ struct req_state : DoutPrefixProvider {
   /// optional coroutine context
   optional_yield yield{null_yield};
 
+  //token claims from STS token for ops log (can be used for Keystone token also)
+  std::vector<string> token_claims;
+
   req_state(CephContext* _cct, RGWEnv* e, rgw::sal::RGWUser* u, uint64_t id);
   ~req_state();
 
index a0f677644704b1f42e6a2e2be3d88c4de7ccb129..4955715c163c69b7bb252fe2e9e264189aff374a 100644 (file)
@@ -274,6 +274,19 @@ void rgw_format_ops_log_entry(struct rgw_log_entry& entry, Formatter *formatter)
     formatter->close_section();
   }
   formatter->dump_string("trans_id", entry.trans_id);
+  if (entry.token_claims.size() > 0) {
+    if (entry.token_claims[0] == "sts") {
+      formatter->open_object_section("sts_token_claims");
+      for (const auto& iter: entry.token_claims) {
+        auto pos = iter.find(":");
+        if (pos != string::npos) {
+          formatter->dump_string(iter.substr(0, pos), iter.substr(pos + 1));
+        }
+      }
+      formatter->close_section();
+    }
+  }
+
   formatter->close_section();
 }
 
@@ -394,6 +407,10 @@ int rgw_log_op(RGWRados *store, RGWREST* const rest, struct req_state *s,
 
   entry.op = op_name;
 
+  if (! s->token_claims.empty()) {
+    entry.token_claims = std::move(s->token_claims);
+  }
+
   /* custom header logging */
   if (rest) {
     if (rest->log_x_headers()) {
index e8ac71cc053a150e3245adf6a96a9405b8a8dadd..1de5227939a114bd4de7d7f94b4b0159bce685d0 100644 (file)
@@ -35,9 +35,10 @@ struct rgw_log_entry {
   string bucket_id;
   headers_map x_headers;
   string trans_id;
+  std::vector<string> token_claims;
 
   void encode(bufferlist &bl) const {
-    ENCODE_START(10, 5, bl);
+    ENCODE_START(11, 5, bl);
     encode(object_owner.id, bl);
     encode(bucket_owner.id, bl);
     encode(bucket, bl);
@@ -61,10 +62,11 @@ struct rgw_log_entry {
     encode(bucket_owner, bl);
     encode(x_headers, bl);
     encode(trans_id, bl);
+    encode(token_claims, bl);
     ENCODE_FINISH(bl);
   }
   void decode(bufferlist::const_iterator &p) {
-    DECODE_START_LEGACY_COMPAT_LEN(10, 5, 5, p);
+    DECODE_START_LEGACY_COMPAT_LEN(11, 5, 5, p);
     decode(object_owner.id, p);
     if (struct_v > 3)
       decode(bucket_owner.id, p);
@@ -113,6 +115,9 @@ struct rgw_log_entry {
     if (struct_v >= 10) {
       decode(trans_id, p);
     }
+    if (struct_v >= 11) {
+      decode(token_claims, p);
+    }
     DECODE_FINISH(p);
   }
   void dump(ceph::Formatter *f) const;
index d3ac614fc7f0c954560da7378679ff5fe6b02140..857e515742bd272bf6e48c67930cb4502189e176 100644 (file)
@@ -5942,7 +5942,7 @@ rgw::auth::s3::STSEngine::authenticate(
                                             get_creds_info(token));
     return result_t::grant(std::move(apl), completer_factory(boost::none));
   } else if (token.acct_type == TYPE_ROLE) {
-    auto apl = role_apl_factory->create_apl_role(cct, s, r, user_id, token.policy, token.role_session);
+    auto apl = role_apl_factory->create_apl_role(cct, s, r, user_id, token.policy, token.role_session, token.token_claims);
     return result_t::grant(std::move(apl), completer_factory(token.secret_access_key));
   } else { // This is for all local users of type TYPE_RGW or TYPE_NONE
     string subuser;
index ca813c244b614d422f88386b2c8f2cd80393d92d..9b28eca67802f27aada5e81bc1d487ef45c7ba79 100644 (file)
@@ -45,6 +45,7 @@ int Credentials::generateCredentials(CephContext* cct,
                           const boost::optional<string>& policy,
                           const boost::optional<string>& roleId,
                           const boost::optional<string>& role_session,
+                          const boost::optional<std::vector<string>> token_claims,
                           boost::optional<rgw_user> user,
                           rgw::auth::Identity* identity)
 {
@@ -108,6 +109,10 @@ int Credentials::generateCredentials(CephContext* cct,
     token.user = u;
   }
 
+  if (token_claims) {
+    token.token_claims = std::move(*token_claims);
+  }
+
   if (identity) {
     token.acct_name = identity->get_acct_name();
     token.perm_mask = identity->get_perm_mask();
@@ -295,6 +300,7 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo
 {
   AssumeRoleWithWebIdentityResponse response;
   response.assumeRoleResp.packedPolicySize = 0;
+  std::vector<string> token_claims;
 
   if (req.getProviderId().empty()) {
     response.providerId = req.getIss();
@@ -302,6 +308,10 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo
   response.aud = req.getAud();
   response.sub = req.getSub();
 
+  token_claims.emplace_back(string("iss") + ":" + req.getIss());
+  token_claims.emplace_back(string("aud") + ":" + req.getAud());
+  token_claims.emplace_back(string("sub") + ":" + req.getSub());
+
   //Get the role info which is being assumed
   boost::optional<rgw::ARN> r_arn = rgw::ARN::parse(req.getRoleARN());
   if (r_arn == boost::none) {
@@ -338,6 +348,7 @@ AssumeRoleWithWebIdentityResponse STSService::assumeRoleWithWebIdentity(AssumeRo
   response.assumeRoleResp.retCode = response.assumeRoleResp.creds.generateCredentials(cct, req.getDuration(),
                                                                                       req.getPolicy(), roleId,
                                                                                       req.getRoleSessionName(),
+                                                                                      token_claims,
                                                                                       user_id, nullptr);
   if (response.assumeRoleResp.retCode < 0) {
     return response;
@@ -384,6 +395,7 @@ AssumeRoleResponse STSService::assumeRole(AssumeRoleRequest& req)
   response.retCode = response.creds.generateCredentials(cct, req.getDuration(),
                                               req.getPolicy(), roleId,
                                               req.getRoleSessionName(),
+                                              boost::none,
                                               user_id, nullptr);
   if (response.retCode < 0) {
     return response;
@@ -422,6 +434,7 @@ GetSessionTokenResponse STSService::getSessionToken(GetSessionTokenRequest& req)
                                       boost::none,
                                       boost::none,
                                       boost::none,
+                                      boost::none,
                                       user_id,
                                       identity); ret < 0) {
     return make_tuple(ret, cred);
index fa8cc70295da39fd1dbbd3393c29b7190237db4e..37519210efbaffcabd305a25ea499a995727e58e 100644 (file)
@@ -129,11 +129,12 @@ struct SessionToken {
   bool is_admin;
   uint32_t acct_type;
   string role_session;
+  std::vector<string> token_claims;
 
   SessionToken() {}
 
   void encode(bufferlist& bl) const {
-    ENCODE_START(2, 1, bl);
+    ENCODE_START(3, 1, bl);
     encode(access_key_id, bl);
     encode(secret_access_key, bl);
     encode(expiration, bl);
@@ -145,11 +146,12 @@ struct SessionToken {
     encode(is_admin, bl);
     encode(acct_type, bl);
     encode(role_session, bl);
+    encode(token_claims, bl);
     ENCODE_FINISH(bl);
   }
 
   void decode(bufferlist::const_iterator& bl) {
-    DECODE_START(2, bl);
+    DECODE_START(3, bl);
     decode(access_key_id, bl);
     decode(secret_access_key, bl);
     decode(expiration, bl);
@@ -163,6 +165,9 @@ struct SessionToken {
     if (struct_v >= 2) {
       decode(role_session, bl);
     }
+    if (struct_v >= 3) {
+      decode(token_claims, bl);
+    }
     DECODE_FINISH(bl);
   }
 };
@@ -181,6 +186,7 @@ public:
                           const boost::optional<string>& policy,
                           const boost::optional<string>& roleId,
                           const boost::optional<string>& role_session,
+                          const boost::optional<std::vector<string> > token_claims,
                           boost::optional<rgw_user> user,
                           rgw::auth::Identity* identity);
   const string& getAccessKeyId() const { return accessKeyId; }