return 0;
}
+static int otp_get_current_time_op(cls_method_context_t hctx,
+ bufferlist *in, bufferlist *out)
+{
+ CLS_LOG(20, "%s", __func__);
+ cls_otp_get_current_time_op op;
+ try {
+ auto iter = in->begin();
+ ::decode(op, iter);
+ } catch (const buffer::error &err) {
+ CLS_ERR("ERROR: %s(): failed to decode request", __func__);
+ return -EINVAL;
+ }
+
+ cls_otp_get_current_time_reply reply;
+ reply.time = real_clock::now();
+ ::encode(reply, *out);
+
+ return 0;
+}
+
CLS_INIT(otp)
{
CLS_LOG(20, "Loaded otp class!");
* to authenticate.
*/
cls_method_handle_t h_remove_otp_op;
+ cls_method_handle_t h_get_current_time_op;
cls_register("otp", &h_class);
cls_register_cxx_method(h_class, "otp_set",
cls_register_cxx_method(h_class, "otp_remove",
CLS_METHOD_RD | CLS_METHOD_WR,
otp_remove_op, &h_remove_otp_op);
+ cls_register_cxx_method(h_class, "get_current_time",
+ CLS_METHOD_RD,
+ otp_get_current_time_op, &h_get_current_time_op);
return;
}
return get(op, ioctx, oid, nullptr, true, result);
}
+ int OTP::get_current_time(librados::IoCtx& ioctx, const string& oid,
+ ceph::real_time *result) {
+ cls_otp_get_current_time_op op;
+ bufferlist in;
+ bufferlist out;
+ int op_ret;
+ ::encode(op, in);
+ ObjectReadOperation rop;
+ rop.exec("otp", "get_current_time", in, &out, &op_ret);
+ int r = ioctx.operate(oid, &rop, nullptr);
+ if (r < 0) {
+ return r;
+ }
+ if (op_ret < 0) {
+ return op_ret;
+ }
+
+ cls_otp_get_current_time_reply ret;
+ auto iter = out.begin();
+ try {
+ ::decode(ret, iter);
+ } catch (buffer::error& err) {
+ return -EBADMSG;
+ }
+
+ *result = ret.time;
+
+ return 0;
+ }
} // namespace otp
} // namespace cls
} // namespace rados
list<otp_info_t> *result);
static int check(CephContext *cct, librados::IoCtx& ioctx, const string& oid,
const string& id, const string& val, otp_check_t *result);
+ static int get_current_time(librados::IoCtx& ioctx, const string& oid,
+ ceph::real_time *result);
};
class TOTPConfig {
};
WRITE_CLASS_ENCODER(cls_otp_get_otp_reply)
+struct cls_otp_get_current_time_op
+{
+ void encode(bufferlist &bl) const {
+ ENCODE_START(1, 1, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(bufferlist::iterator &bl) {
+ DECODE_START(1, bl);
+ DECODE_FINISH(bl);
+ }
+};
+WRITE_CLASS_ENCODER(cls_otp_get_current_time_op)
+
+struct cls_otp_get_current_time_reply
+{
+ ceph::real_time time;
+
+ void encode(bufferlist &bl) const {
+ ENCODE_START(1, 1, bl);
+ ::encode(time, bl);
+ ENCODE_FINISH(bl);
+ }
+ void decode(bufferlist::iterator &bl) {
+ DECODE_START(1, bl);
+ ::decode(time, bl);
+ DECODE_FINISH(bl);
+ }
+};
+WRITE_CLASS_ENCODER(cls_otp_get_current_time_reply)
+
#endif
return -ret;
}
- ceph::real_time now = real_clock::now(); // need to get it from the osd
+ ceph::real_time now;
+ ret = store->otp_get_current_time(user_id, &now);
+ if (ret < 0) {
+ cerr << "ERROR: failed to fetch current time from osd: " << cpp_strerror(-ret) << std::endl;
+ return -ret;
+ }
time_t time_ofs;
ret = scan_totp(store->ctx(), now, config, totp_pin, &time_ofs);
return 0;
}
+int RGWRados::otp_get_current_time(const rgw_user& user, ceph::real_time *result)
+{
+ rgw_rados_ref ref;
+
+ int r = get_mfa_ref(user, &ref);
+ if (r < 0) {
+ return r;
+ }
+
+ r = rados::cls::otp::OTP::get_current_time(ref.ioctx, ref.oid, result);
+ if (r < 0) {
+ return r;
+ }
+
+ return 0;
+}
+
int RGWRados::set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>& entries,
bool reset_obj, RGWObjVersionTracker *objv_tracker,
const real_time& mtime)
RGWObjVersionTracker *objv_tracker, const ceph::real_time& mtime);
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);
+ int otp_get_current_time(const rgw_user& user, ceph::real_time *result);
/* mfa interfaces used by metadata engine */
int set_mfa(const string& oid, const list<rados::cls::otp::otp_info_t>& entries, bool reset_obj,