From: Daniel Gryniewicz Date: Tue, 2 Aug 2022 16:16:23 +0000 (-0400) Subject: RGW - Zipper - Add verify_mfa X-Git-Tag: v18.0.0~186^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f93956927d39366184d4be5e9151ca3459137efa;p=ceph.git RGW - Zipper - Add verify_mfa Signed-off-by: Daniel Gryniewicz --- diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 194de861a9a..9cb54e25cdd 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -61,7 +61,6 @@ #include "rgw_bucket_sync.h" #include "services/svc_zone.h" -#include "services/svc_cls.h" #include "include/ceph_assert.h" #include "rgw_role.h" @@ -4830,37 +4829,6 @@ int RGWHandler_REST_S3::init_from_header(rgw::sal::Store* store, return 0; } -static int verify_mfa(rgw::sal::Store* store, RGWUserInfo *user, - const string& mfa_str, bool *verified, const DoutPrefixProvider *dpp, optional_yield y) -{ - vector params; - get_str_vec(mfa_str, " ", params); - - if (params.size() != 2) { - ldpp_dout(dpp, 5) << "NOTICE: invalid mfa string provided: " << mfa_str << dendl; - return -EINVAL; - } - - string& serial = params[0]; - string& pin = params[1]; - - auto i = user->mfa_ids.find(serial); - if (i == user->mfa_ids.end()) { - ldpp_dout(dpp, 5) << "NOTICE: user does not have mfa device with serial=" << serial << dendl; - return -EACCES; - } - - int ret = static_cast(store)->svc()->cls->mfa.check_mfa(dpp, user->user_id, serial, pin, y); - if (ret < 0) { - ldpp_dout(dpp, 20) << "NOTICE: failed to check MFA, serial=" << serial << dendl; - return -EACCES; - } - - *verified = true; - - return 0; -} - int RGWHandler_REST_S3::postauth_init(optional_yield y) { struct req_init_state *t = &s->init_state; @@ -4901,7 +4869,7 @@ int RGWHandler_REST_S3::postauth_init(optional_yield y) const char *mfa = s->info.env->get("HTTP_X_AMZ_MFA"); if (mfa) { - ret = verify_mfa(store, &s->user->get_info(), string(mfa), &s->mfa_verified, s, y); + ret = s->user->verify_mfa(string(mfa), &s->mfa_verified, s, y); } return 0; diff --git a/src/rgw/rgw_sal.h b/src/rgw/rgw_sal.h index f5634b95386..0dfb6dc8fca 100644 --- a/src/rgw/rgw_sal.h +++ b/src/rgw/rgw_sal.h @@ -556,6 +556,8 @@ class User { virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) = 0; /** Remove this User from the backing store */ virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) = 0; + /** Verify multi-factor authentication for this user */ + virtual int verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider* dpp, optional_yield y) = 0; /* dang temporary; will be removed when User is complete */ virtual RGWUserInfo& get_info() = 0; diff --git a/src/rgw/rgw_sal_dbstore.cc b/src/rgw/rgw_sal_dbstore.cc index 2fc9215f94f..b4b1d08464a 100644 --- a/src/rgw/rgw_sal_dbstore.cc +++ b/src/rgw/rgw_sal_dbstore.cc @@ -226,6 +226,12 @@ namespace rgw::sal { return ret; } + int DBUser::verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider *dpp, optional_yield y) + { + *verified = false; + return 0; + } + int DBBucket::remove_bucket(const DoutPrefixProvider *dpp, bool delete_children, bool forward_to_master, req_info* req_info, optional_yield y) { int ret; diff --git a/src/rgw/rgw_sal_dbstore.h b/src/rgw/rgw_sal_dbstore.h index 734d3f78aad..4c1eca4110a 100644 --- a/src/rgw/rgw_sal_dbstore.h +++ b/src/rgw/rgw_sal_dbstore.h @@ -121,6 +121,7 @@ protected: virtual int load_user(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) override; virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider* dpp, optional_yield y) override; friend class DBBucket; }; diff --git a/src/rgw/rgw_sal_filter.cc b/src/rgw/rgw_sal_filter.cc index ecc7ccdca32..6c415786e3b 100644 --- a/src/rgw/rgw_sal_filter.cc +++ b/src/rgw/rgw_sal_filter.cc @@ -660,6 +660,12 @@ int FilterUser::remove_user(const DoutPrefixProvider* dpp, optional_yield y) return next->remove_user(dpp, y); } +int FilterUser::verify_mfa(const std::string& mfa_str, bool* verified, + const DoutPrefixProvider* dpp, optional_yield y) +{ + return next->verify_mfa(mfa_str, verified, dpp, y); +} + std::unique_ptr FilterBucket::get_object(const rgw_obj_key& k) { std::unique_ptr o = next->get_object(k); diff --git a/src/rgw/rgw_sal_filter.h b/src/rgw/rgw_sal_filter.h index 384ecf67d67..d64952a3d5b 100644 --- a/src/rgw/rgw_sal_filter.h +++ b/src/rgw/rgw_sal_filter.h @@ -371,6 +371,8 @@ public: virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) override; virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int verify_mfa(const std::string& mfa_str, bool* verified, + const DoutPrefixProvider* dpp, optional_yield y) override; RGWUserInfo& get_info() override { return next->get_info(); } virtual void print(std::ostream& out) const override { return next->print(out); } diff --git a/src/rgw/rgw_sal_motr.cc b/src/rgw/rgw_sal_motr.cc index 8c60b10b16d..72cb883a596 100644 --- a/src/rgw/rgw_sal_motr.cc +++ b/src/rgw/rgw_sal_motr.cc @@ -449,6 +449,12 @@ int MotrUser::remove_user(const DoutPrefixProvider* dpp, optional_yield y) return 0; } +int MotrUser::verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider *dpp, optional_yield y) +{ + *verified = false; + return 0; +} + int MotrBucket::remove_bucket(const DoutPrefixProvider *dpp, bool delete_children, bool forward_to_master, req_info* req_info, optional_yield y) { int ret; diff --git a/src/rgw/rgw_sal_motr.h b/src/rgw/rgw_sal_motr.h index 3ba2038583f..816bf2bc606 100644 --- a/src/rgw/rgw_sal_motr.h +++ b/src/rgw/rgw_sal_motr.h @@ -196,6 +196,7 @@ class MotrUser : public StoreUser { virtual int load_user(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) override; virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider* dpp, optional_yield y) override; int create_user_info_idx(); diff --git a/src/rgw/rgw_sal_rados.cc b/src/rgw/rgw_sal_rados.cc index ca78de41257..25d01dc8b37 100644 --- a/src/rgw/rgw_sal_rados.cc +++ b/src/rgw/rgw_sal_rados.cc @@ -42,6 +42,7 @@ #include "services/svc_sys_obj.h" #include "services/svc_meta.h" #include "services/svc_meta_be_sobj.h" +#include "services/svc_cls.h" #include "services/svc_zone.h" #include "services/svc_tier_rados.h" #include "services/svc_quota.h" @@ -356,6 +357,37 @@ int RadosUser::remove_user(const DoutPrefixProvider* dpp, optional_yield y) RGWUserCtl::RemoveParams().set_objv_tracker(&objv_tracker)); } +int RadosUser::verify_mfa(const std::string& mfa_str, bool* verified, + const DoutPrefixProvider* dpp, optional_yield y) +{ + vector params; + get_str_vec(mfa_str, " ", params); + + if (params.size() != 2) { + ldpp_dout(dpp, 5) << "NOTICE: invalid mfa string provided: " << mfa_str << dendl; + return -EINVAL; + } + + string& serial = params[0]; + string& pin = params[1]; + + auto i = info.mfa_ids.find(serial); + if (i == info.mfa_ids.end()) { + ldpp_dout(dpp, 5) << "NOTICE: user does not have mfa device with serial=" << serial << dendl; + return -EACCES; + } + + int ret = store->svc()->cls->mfa.check_mfa(dpp, info.user_id, serial, pin, y); + if (ret < 0) { + ldpp_dout(dpp, 20) << "NOTICE: failed to check MFA, serial=" << serial << dendl; + return -EACCES; + } + + *verified = true; + + return 0; +} + RadosBucket::~RadosBucket() {} int RadosBucket::remove_bucket(const DoutPrefixProvider* dpp, diff --git a/src/rgw/rgw_sal_rados.h b/src/rgw/rgw_sal_rados.h index 6b23f8a153c..91677d838d7 100644 --- a/src/rgw/rgw_sal_rados.h +++ b/src/rgw/rgw_sal_rados.h @@ -314,6 +314,7 @@ class RadosUser : public StoreUser { virtual int load_user(const DoutPrefixProvider* dpp, optional_yield y) override; virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info = nullptr) override; virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) override; + virtual int verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider* dpp, optional_yield y) override; friend class RadosBucket; }; diff --git a/src/test/rgw/test_rgw_lua.cc b/src/test/rgw/test_rgw_lua.cc index aed87026925..e87dfb64d9f 100644 --- a/src/test/rgw/test_rgw_lua.cc +++ b/src/test/rgw/test_rgw_lua.cc @@ -119,6 +119,9 @@ public: virtual int merge_and_store_attrs(const DoutPrefixProvider *dpp, rgw::sal::Attrs& attrs, optional_yield y) override { return 0; } + virtual int verify_mfa(const std::string& mfa_str, bool* verified, const DoutPrefixProvider* dpp, optional_yield y) override { + return 0; + } virtual ~TestUser() = default; };