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);
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);
#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"
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) {
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,
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;
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;
}
#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"
rgw_pool user_uid_pool;
rgw_pool roles_pool;
rgw_pool reshard_pool;
+ rgw_pool otp_pool;
RGWAccessKey system_key;
encode(tier_config, bl);
encode(roles_pool, bl);
encode(reshard_pool, bl);
+ encode(otp_pool, bl);
ENCODE_FINISH(bl);
}
} 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;
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