]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add otp pool, create otp service functionality
authorYehuda Sadeh <yehuda@redhat.com>
Mon, 4 Dec 2017 07:51:38 +0000 (23:51 -0800)
committerYehuda Sadeh <yehuda@redhat.com>
Mon, 9 Apr 2018 14:01:02 +0000 (07:01 -0700)
Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
src/rgw/rgw_json_enc.cc
src/rgw/rgw_rados.cc
src/rgw/rgw_rados.h

index af0bf3ba9367b7b8455feffc1d0a898e7e0fc3f2..e11ab1ae1267871cfb631465c7db877423a9ce8f 100644 (file)
@@ -919,6 +919,7 @@ void RGWZoneParams::dump(Formatter *f) const
   encode_json("user_email_pool", user_email_pool, f);
   encode_json("user_swift_pool", user_swift_pool, f);
   encode_json("user_uid_pool", user_uid_pool, f);
+  encode_json("otp_pool", otp_pool, f);
   encode_json_plain("system_key", system_key, f);
   encode_json("placement_pools", placement_pools, f);
   encode_json("metadata_heap", metadata_heap, f);
@@ -961,6 +962,7 @@ void RGWZoneParams::decode_json(JSONObj *obj)
   JSONDecoder::decode_json("user_email_pool", user_email_pool, obj);
   JSONDecoder::decode_json("user_swift_pool", user_swift_pool, obj);
   JSONDecoder::decode_json("user_uid_pool", user_uid_pool, obj);
+  JSONDecoder::decode_json("otp_pool", otp_pool, obj);
   JSONDecoder::decode_json("system_key", system_key, obj);
   JSONDecoder::decode_json("placement_pools", placement_pools, obj);
   JSONDecoder::decode_json("metadata_heap", metadata_heap, obj);
index b0f9d858c69ec3b158b60296350353d90e0ad556..106167ba4884713d96d4672bd5861c696df71d8e 100644 (file)
@@ -40,6 +40,7 @@
 #include "cls/timeindex/cls_timeindex_client.h"
 #include "cls/lock/cls_lock_client.h"
 #include "cls/user/cls_user_client.h"
+#include "cls/otp/cls_otp_client.h"
 #include "osd/osd_types.h"
 
 #include "rgw_tools.h"
@@ -1696,6 +1697,7 @@ int get_zones_pool_set(CephContext* cct,
       pool_names.insert(zone.user_email_pool);
       pool_names.insert(zone.user_swift_pool);
       pool_names.insert(zone.user_uid_pool);
+      pool_names.insert(zone.otp_pool);
       pool_names.insert(zone.roles_pool);
       pool_names.insert(zone.reshard_pool);
       for(auto& iter : zone.placement_pools) {
@@ -1769,6 +1771,7 @@ int RGWZoneParams::fix_pool_names()
   user_uid_pool = fix_zone_pool_dup(pools, name, ".rgw.meta:users.uid", user_uid_pool);
   roles_pool = fix_zone_pool_dup(pools, name, ".rgw.meta:roles", roles_pool);
   reshard_pool = fix_zone_pool_dup(pools, name, ".rgw.log:reshard", reshard_pool);
+  otp_pool = fix_zone_pool_dup(pools, name, ".rgw.otp", otp_pool);
 
   for(auto& iter : placement_pools) {
     iter.second.index_pool = fix_zone_pool_dup(pools, name, "." + default_bucket_index_pool_suffix,
@@ -14158,21 +14161,64 @@ void RGWRados::call_zap() {
   return;
 }
 
-int RGWRados::check_mfa(const rgw_user& user, const string& otp_id, const string& pin)
+int RGWRados::get_mfa_ref(const rgw_user& user, rgw_rados_ref *ref)
 {
   string oid = string("user:") + user.to_str();
   rgw_raw_obj obj(get_zone_params().otp_pool, oid);
+  return get_system_obj_ref(obj, ref);
+}
 
+int RGWRados::check_mfa(const rgw_user& user, const string& otp_id, const string& pin)
+{
   rgw_rados_ref ref;
-  int r = get_system_obj_ref(obj, &ref);
+
+  int r = get_mfa_ref(user, &ref);
   if (r < 0) {
     return r;
   }
 
-  otp_check_t result;
+  rados::cls::otp::otp_check_t result;
+
+  r = rados::cls::otp::OTP::check(cct, ref.ioctx, ref.oid, otp_id, pin, &result);
+  if (r < 0)
+    return r;
+
+  ldout(cct, 20) << "OTP check, otp_id=" << otp_id << " result=" << (int)result.result << dendl;
+
+  return (result.result == rados::cls::otp::OTP_CHECK_SUCCESS ? 0 : -EACCES);
+}
+
+int RGWRados::create_mfa(const rgw_user& user, const rados::cls::otp::otp_info_t& config)
+{
+  rgw_rados_ref ref;
+
+  int r = get_mfa_ref(user, &ref);
+  if (r < 0) {
+    return r;
+  }
 
   librados::ObjectWriteOperation op;
-  rados::cls::otp::OTP::check(ref.io_ctx, obj.get_oid(), otp_id, pin, &result);
+  rados::cls::otp::OTP::create(&op, config);
+  r = ref.ioctx.operate(ref.oid, &op);
+  if (r < 0) {
+    ldout(cct, 20) << "OTP create, otp_id=" << config.id << " result=" << (int)r << dendl;
+    return r;
+  }
+
+  return 0;
+}
+
+int RGWRados::remove_mfa(const rgw_user& user, const string& id)
+{
+  rgw_rados_ref ref;
+
+  int r = get_mfa_ref(user, &ref);
+  if (r < 0) {
+    return r;
+  }
+
+  librados::ObjectWriteOperation op;
+  rados::cls::otp::OTP::remove(&op, id);
   r = ref.ioctx.operate(ref.oid, &op);
   if (r < 0) {
     ldout(cct, 20) << "OTP remove, otp_id=" << id << " result=" << (int)r << dendl;
@@ -14196,8 +14242,23 @@ int RGWRados::get_mfa(const rgw_user& user, const string& id, rados::cls::otp::o
     return r;
   }
 
-  ldout(cct, 20) << "OTP check, otp_id=" << otp_id << " result=" << (int)result << dendl;
+  return 0;
+}
+
+int RGWRados::list_mfa(const rgw_user& user, list<rados::cls::otp::otp_info_t> *result)
+{
+  rgw_rados_ref ref;
+
+  int r = get_mfa_ref(user, &ref);
+  if (r < 0) {
+    return r;
+  }
+
+  r = rados::cls::otp::OTP::get_all(ref.ioctx, ref.oid, result);
+  if (r < 0) {
+    return r;
+  }
 
-  return (result.result == rados::cls::otp::OTP_CHECK ? 0 : -EACCES);
+  return 0;
 }
 
index ddcd3ef62d216394a8c1276616e4a6aa7cdc1855..482176750897200ed9310da3b160b91e11b4e14c 100644 (file)
@@ -19,6 +19,7 @@
 #include "cls/log/cls_log_types.h"
 #include "cls/statelog/cls_statelog_types.h"
 #include "cls/timeindex/cls_timeindex_types.h"
+#include "cls/otp/cls_otp_types.h"
 #include "rgw_log.h"
 #include "rgw_metadata.h"
 #include "rgw_meta_sync_status.h"
@@ -1188,6 +1189,7 @@ struct RGWZoneParams : RGWSystemMetaObj {
   rgw_pool user_uid_pool;
   rgw_pool roles_pool;
   rgw_pool reshard_pool;
+  rgw_pool otp_pool;
 
   RGWAccessKey system_key;
 
@@ -1241,6 +1243,7 @@ struct RGWZoneParams : RGWSystemMetaObj {
     encode(tier_config, bl);
     encode(roles_pool, bl);
     encode(reshard_pool, bl);
+    encode(otp_pool, bl);
     ENCODE_FINISH(bl);
   }
 
@@ -1289,6 +1292,11 @@ struct RGWZoneParams : RGWSystemMetaObj {
     } else {
       reshard_pool = log_pool.name + ":reshard";
     }
+    if (struct_v >= 11) {
+      ::decode(otp_pool, bl);
+    } else {
+      otp_pool = name + ".rgw.otp";
+    }
     DECODE_FINISH(bl);
   }
   void dump(Formatter *f) const;
@@ -3707,7 +3715,13 @@ public:
   int delete_obj_aio(const rgw_obj& obj, RGWBucketInfo& info, RGWObjState *astate,
                      list<librados::AioCompletion *>& handles, bool keep_index_consistent);
 
+  /* mfa/totp stuff */
+  int get_mfa_ref(const rgw_user& user, rgw_rados_ref *ref);
   int check_mfa(const rgw_user& user, const string& otp_id, const string& pin);
+  int create_mfa(const rgw_user& user, const rados::cls::otp::otp_info_t& config);
+  int remove_mfa(const rgw_user& user, const string& id);
+  int get_mfa(const rgw_user& user, const string& id, rados::cls::otp::otp_info_t *result);
+  int list_mfa(const rgw_user& user, list<rados::cls::otp::otp_info_t> *result);
  private:
   /**
    * This is a helper method, it generates a list of bucket index objects with the given