cls/otp, rgw-admin: use older liboath api, parse seed once

Signed-off-by: Yehuda Sadeh <yehuda@redhat.com>
This commit is contained in:
Yehuda Sadeh 2017-12-04 04:28:37 -08:00
parent 679913512b
commit 6976202360
4 changed files with 33 additions and 21 deletions

View File

@ -395,7 +395,7 @@ if(WITH_RADOSGW)
message(WARNING "disabling WITH_RADOSGW_BEAST_FRONTEND, which depends on WITH_BOOST_CONTEXT")
set(WITH_RADOSGW_BEAST_FRONTEND OFF)
endif()
find_package(liboath 2.4 REQUIRED)
find_package(liboath REQUIRED)
# https://curl.haxx.se/docs/install.html mentions the
# configure flags for various ssl backends

View File

@ -121,19 +121,11 @@ void otp_instance::check(const string& token, const string& val, bool *update)
bool otp_instance::verify(const ceph::real_time& timestamp, const string& val)
{
size_t slen = otp.seed.size() / 2 + 1;
char secret[slen];
uint64_t index;
uint32_t secs = (uint32_t)ceph::real_clock::to_time_t(timestamp);
int result = oath_hex2bin(otp.seed.c_str(), secret, &slen);
if (result != OATH_OK) {
CLS_LOG(20, "failed to parse seed");
return result;
}
result = oath_totp_validate3(secret, slen,
int result = oath_totp_validate2(otp.seed_bin.c_str(), otp.seed_bin.length(),
secs, otp.step_size, otp.time_ofs, otp.window,
nullptr /* otp pos */, &index,
nullptr /* otp pos */,
val.c_str());
if (result == OATH_INVALID_OTP ||
result < 0) {
@ -141,6 +133,8 @@ bool otp_instance::verify(const ceph::real_time& timestamp, const string& val)
return false;
}
index = result + (secs - otp.time_ofs) / otp.step_size;
if (index <= last_success) { /* already used value */
CLS_LOG(20, "otp, use of old token: index=%lld last_success=%lld", (long long)index, (long long)last_success);
return false;
@ -264,6 +258,22 @@ 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)
{
size_t slen = seed.size() / 2 + 1;
char secret[slen];
int result = oath_hex2bin(seed.c_str(), secret, &slen);
if (result != OATH_OK) {
CLS_LOG(20, "failed to parse seed");
return -EINVAL;
}
seed_bin->clear();
seed_bin->append(secret, slen);
return 0;
}
static int otp_set_op(cls_method_context_t hctx,
bufferlist *in, bufferlist *out)
{
@ -292,6 +302,11 @@ static int otp_set_op(cls_method_context_t hctx,
}
instance.otp = entry;
r = parse_seed(instance.otp.seed, &instance.otp.seed_bin);
if (r < 0) {
return r;
}
r = write_otp_instance(hctx, instance);
if (r < 0) {
return r;

View File

@ -23,6 +23,9 @@ namespace rados {
OTPType type{OTP_TOTP};
string id;
string seed;
bufferlist seed_bin; /* parsed seed, built automatically by otp_set_op,
* not being json encoded/decoded on purpose
*/
int32_t time_ofs{0};
uint32_t step_size{30}; /* num of seconds foreach otp to test */
uint32_t window{2}; /* num of otp after/before start otp to test */
@ -36,6 +39,7 @@ namespace rados {
* then we'll need to branch here */
::encode(id, bl);
::encode(seed, bl);
::encode(seed_bin, bl);
::encode(time_ofs, bl);
::encode(step_size, bl);
::encode(window, bl);
@ -48,6 +52,7 @@ namespace rados {
type = (OTPType)t;
::decode(id, bl);
::decode(seed, bl);
::decode(seed_bin, bl);
::decode(time_ofs, bl);
::decode(step_size, bl);
::decode(window, bl);

View File

@ -2406,14 +2406,6 @@ static int scan_totp(CephContext *cct, ceph::real_time& now, rados::cls::otp::ot
#define MAX_TOTP_SKEW_HOURS (24 * 7)
assert(pins.size() == 2);
size_t slen = totp.seed.size() / 2 + 1;
char seed[slen];
int rc = oath_hex2bin(totp.seed.c_str(), seed, &slen);
if (rc != OATH_OK) {
cerr << "ERROR: failed to parse seed" << std::endl;
return -EINVAL;
}
time_t start_time = ceph::real_clock::to_time_t(now);
time_t time_ofs = 0, time_ofs_abs = 0;
time_t step_size = totp.step_size;
@ -2426,7 +2418,7 @@ static int scan_totp(CephContext *cct, ceph::real_time& now, rados::cls::otp::ot
uint32_t max_skew = MAX_TOTP_SKEW_HOURS * 3600;
while (time_ofs_abs < max_skew) {
rc = oath_totp_validate2(seed, slen,
int rc = oath_totp_validate2(totp.seed_bin.c_str(), totp.seed_bin.length(),
start_time,
step_size,
time_ofs,
@ -2434,7 +2426,7 @@ static int scan_totp(CephContext *cct, ceph::real_time& now, rados::cls::otp::ot
nullptr,
pins[0].c_str());
if (rc != OATH_INVALID_OTP) {
rc = oath_totp_validate2(seed, slen,
rc = oath_totp_validate2(totp.seed_bin.c_str(), totp.seed_bin.length(),
start_time,
step_size,
time_ofs - step_size, /* smaller time_ofs moves time forward */