From: Yehuda Sadeh Date: Mon, 4 Dec 2017 13:42:51 +0000 (-0800) Subject: rgw, cls/otp: support for base32 seed type X-Git-Tag: v13.1.0~343^2~7 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d4691332c1c4ae24ab2822fdb39e5b9bc3f9260d;p=ceph.git rgw, cls/otp: support for base32 seed type Signed-off-by: Yehuda Sadeh --- diff --git a/src/cls/otp/cls_otp.cc b/src/cls/otp/cls_otp.cc index 6da4934e8016..b756f66b3c3e 100644 --- a/src/cls/otp/cls_otp.cc +++ b/src/cls/otp/cls_otp.cc @@ -258,18 +258,35 @@ static int write_header(cls_method_context_t hctx, const otp_header& h) return 0; } -static int parse_seed(const string& seed, bufferlist *seed_bin) +static int parse_seed(const string& seed, SeedType seed_type, bufferlist *seed_bin) { - size_t slen = seed.size() / 2 + 1; - char secret[slen]; - int result = oath_hex2bin(seed.c_str(), secret, &slen); + size_t slen = seed.length(); + char secret[seed.length()]; + char *psecret = secret; + int result; + bool need_free = false; + + seed_bin->clear(); + + switch (seed_type) { + case OTP_SEED_BASE32: + need_free = true; /* oath_base32_decode allocates dest buffer */ + result = oath_base32_decode(seed.c_str(), seed.length(), + &psecret, &slen); + break; + default: /* just assume hex is the default */ + result = oath_hex2bin(seed.c_str(), psecret, &slen); + } if (result != OATH_OK) { CLS_LOG(20, "failed to parse seed"); return -EINVAL; } - seed_bin->clear(); - seed_bin->append(secret, slen); + seed_bin->append(psecret, slen); + + if (need_free) { + free(psecret); + } return 0; } @@ -302,7 +319,7 @@ static int otp_set_op(cls_method_context_t hctx, } instance.otp = entry; - r = parse_seed(instance.otp.seed, &instance.otp.seed_bin); + r = parse_seed(instance.otp.seed, instance.otp.seed_type, &instance.otp.seed_bin); if (r < 0) { return r; } diff --git a/src/cls/otp/cls_otp_types.cc b/src/cls/otp/cls_otp_types.cc index 159b3604966c..b8a6e0125e4b 100644 --- a/src/cls/otp/cls_otp_types.cc +++ b/src/cls/otp/cls_otp_types.cc @@ -28,6 +28,18 @@ void otp_info_t::dump(Formatter *f) const encode_json("type", (int)type, f); encode_json("id", id, f); encode_json("seed", seed, f); + string st; + switch (seed_type) { + case rados::cls::otp::OTP_SEED_HEX: + st = "hex"; + break; + case rados::cls::otp::OTP_SEED_BASE32: + st = "base32"; + break; + default: + st = "unknown"; + } + encode_json("seed_type", st, f); encode_json("time_ofs", time_ofs, f); encode_json("step_size", step_size, f); encode_json("window", window, f); @@ -40,6 +52,15 @@ void otp_info_t::decode_json(JSONObj *obj) type = (OTPType)t; JSONDecoder::decode_json("id", id, obj); JSONDecoder::decode_json("seed", seed, obj); + string st; + JSONDecoder::decode_json("seed_type", st, obj); + if (st == "hex") { + seed_type = OTP_SEED_HEX; + } else if (st == "base32") { + seed_type = OTP_SEED_BASE32; + } else { + seed_type = OTP_SEED_UNKNOWN; + } JSONDecoder::decode_json("time_ofs", time_ofs, obj); JSONDecoder::decode_json("step_size", step_size, obj); JSONDecoder::decode_json("window", window, obj); diff --git a/src/cls/otp/cls_otp_types.h b/src/cls/otp/cls_otp_types.h index b863e24fdbb2..24f1f20948d1 100644 --- a/src/cls/otp/cls_otp_types.h +++ b/src/cls/otp/cls_otp_types.h @@ -19,10 +19,17 @@ namespace rados { OTP_TOTP = 2, }; + enum SeedType { + OTP_SEED_UNKNOWN = 0, + OTP_SEED_HEX = 1, + OTP_SEED_BASE32 = 2, + }; + struct otp_info_t { OTPType type{OTP_TOTP}; string id; string seed; + SeedType seed_type{OTP_SEED_UNKNOWN}; bufferlist seed_bin; /* parsed seed, built automatically by otp_set_op, * not being json encoded/decoded on purpose */ @@ -39,6 +46,7 @@ namespace rados { * then we'll need to branch here */ ::encode(id, bl); ::encode(seed, bl); + ::encode((uint8_t)seed_type, bl); ::encode(seed_bin, bl); ::encode(time_ofs, bl); ::encode(step_size, bl); @@ -52,6 +60,9 @@ namespace rados { type = (OTPType)t; ::decode(id, bl); ::decode(seed, bl); + uint8_t st; + ::decode(st, bl); + seed_type = (SeedType)st; ::decode(seed_bin, bl); ::decode(time_ofs, bl); ::decode(step_size, bl); diff --git a/src/rgw/rgw_admin.cc b/src/rgw/rgw_admin.cc index 05c03058b419..bf0575969ca3 100644 --- a/src/rgw/rgw_admin.cc +++ b/src/rgw/rgw_admin.cc @@ -2617,6 +2617,7 @@ int main(int argc, const char **argv) string totp_serial; string totp_seed; + string totp_seed_type = "hex"; vector totp_pin; int totp_seconds = 0; int totp_window = 0; @@ -2948,6 +2949,8 @@ int main(int argc, const char **argv) totp_pin.push_back(val); } else if (ceph_argparse_witharg(args, i, &val, "--totp-seed", (char*)NULL)) { totp_seed = val; + } else if (ceph_argparse_witharg(args, i, &val, "--totp-seed-type", (char*)NULL)) { + totp_seed_type = val; } else if (ceph_argparse_witharg(args, i, &val, "--totp-seconds", (char*)NULL)) { totp_seconds = atoi(val.c_str()); } else if (ceph_argparse_witharg(args, i, &val, "--totp-window", (char*)NULL)) { @@ -7368,8 +7371,20 @@ next: return EINVAL; } + + rados::cls::otp::SeedType seed_type; + if (totp_seed_type == "hex") { + seed_type = rados::cls::otp::OTP_SEED_HEX; + } else if (totp_seed_type == "base32") { + seed_type = rados::cls::otp::OTP_SEED_BASE32; + } else { + cerr << "ERROR: invalid seed type: " << totp_seed_type << std::endl; + return EINVAL; + } + config.id = totp_serial; config.seed = totp_seed; + config.seed_type = seed_type; if (totp_seconds > 0) { config.step_size = totp_seconds;