From: Casey Bodley Date: Fri, 8 Nov 2019 20:52:44 +0000 (-0500) Subject: common: move gen_rand_alphanumeric() helpers into common X-Git-Tag: v14.2.17~17^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=56ab7f02229c827a9a79f81bfe2ceb38b414a704;p=ceph.git common: move gen_rand_alphanumeric() helpers into common and adds overloads that return std::string directly the motivation is to remove cls_otp's dependency on rgw_common.h Signed-off-by: Casey Bodley (cherry picked from commit bfa76731aa338ca2c8a9e6dc52a19ae71aeb0bbf) Conflicts: src/common/CMakeLists.txt - no rabin.cc in nautilus --- diff --git a/src/cls/otp/cls_otp_client.cc b/src/cls/otp/cls_otp_client.cc index f080de08347ae..dc1efab4132a7 100644 --- a/src/cls/otp/cls_otp_client.cc +++ b/src/cls/otp/cls_otp_client.cc @@ -22,7 +22,7 @@ using namespace librados; #include "cls/otp/cls_otp_ops.h" #include "cls/otp/cls_otp_client.h" -#include "rgw/rgw_common.h" /* for gen_random_bytes() */ +#include "common/random_string.h" /* for gen_rand_alphanumeric */ namespace rados { namespace cls { @@ -61,9 +61,7 @@ namespace rados { op.id = id; op.val = val; #define TOKEN_LEN 16 - char buf[TOKEN_LEN + 1]; - gen_rand_alphanumeric(cct, buf, sizeof(buf));; - op.token = buf; + op.token = gen_rand_alphanumeric(cct, TOKEN_LEN); bufferlist in; bufferlist out; @@ -74,7 +72,7 @@ namespace rados { } cls_otp_get_result_op op2; - op2.token = buf; + op2.token = op.token; bufferlist in2; bufferlist out2; encode(op2, in2); diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index bd9276520dc3d..b77159f4d2931 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -82,6 +82,7 @@ set(common_srcs perf_counters_collection.cc perf_histogram.cc pick_address.cc + random_string.cc reverse.c run_cmd.cc scrub_types.cc diff --git a/src/common/random_string.cc b/src/common/random_string.cc new file mode 100644 index 0000000000000..c728956182a4d --- /dev/null +++ b/src/common/random_string.cc @@ -0,0 +1,127 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab ft=cpp + +#include +#include "auth/Crypto.h" +#include "common/armor.h" +#include "common/ceph_context.h" +#include "common/dout.h" +#include "random_string.h" + +int gen_rand_base64(CephContext *cct, char *dest, size_t size) /* size should be the required string size + 1 */ +{ + char buf[size]; + char tmp_dest[size + 4]; /* so that there's space for the extra '=' characters, and some */ + int ret; + + cct->random()->get_bytes(buf, sizeof(buf)); + + ret = ceph_armor(tmp_dest, &tmp_dest[sizeof(tmp_dest)], + (const char *)buf, ((const char *)buf) + ((size - 1) * 3 + 4 - 1) / 4); + if (ret < 0) { + lderr(cct) << "ceph_armor failed" << dendl; + return ret; + } + tmp_dest[ret] = '\0'; + memcpy(dest, tmp_dest, size); + dest[size-1] = '\0'; + + return 0; +} + +// choose 'size' random characters from the given string table +static void choose_from(CryptoRandom* random, std::string_view table, + char *dest, size_t size) +{ + random->get_bytes(dest, size); + + for (size_t i = 0; i < size; i++) { + auto pos = static_cast(dest[i]); + dest[i] = table[pos % table.size()]; + } +} + + +void gen_rand_alphanumeric(CephContext *cct, char *dest, size_t size) /* size should be the required string size + 1 */ +{ + // this is basically a modified base64 charset, url friendly + static constexpr char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; + choose_from(cct->random(), table, dest, size-1); + dest[size-1] = 0; +} + +std::string gen_rand_alphanumeric(CephContext *cct, size_t size) +{ + std::string str; + str.resize(size + 1); + gen_rand_alphanumeric(cct, str.data(), str.size()); + str.pop_back(); // pop the extra \0 + return str; +} + +void gen_rand_alphanumeric_lower(CephContext *cct, char *dest, size_t size) /* size should be the required string size + 1 */ +{ + static constexpr char table[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + choose_from(cct->random(), table, dest, size-1); + dest[size-1] = 0; +} + +std::string gen_rand_alphanumeric_lower(CephContext *cct, size_t size) +{ + std::string str; + str.resize(size + 1); + gen_rand_alphanumeric_lower(cct, str.data(), str.size()); + str.pop_back(); // pop the extra \0 + return str; +} + + +void gen_rand_alphanumeric_upper(CephContext *cct, char *dest, size_t size) /* size should be the required string size + 1 */ +{ + static constexpr char table[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + choose_from(cct->random(), table, dest, size-1); + dest[size-1] = 0; +} + +std::string gen_rand_alphanumeric_upper(CephContext *cct, size_t size) +{ + std::string str; + str.resize(size + 1); + gen_rand_alphanumeric_upper(cct, str.data(), str.size()); + str.pop_back(); // pop the extra \0 + return str; +} + + +void gen_rand_alphanumeric_no_underscore(CephContext *cct, char *dest, size_t size) /* size should be the required string size + 1 */ +{ + static constexpr char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."; + choose_from(cct->random(), table, dest, size-1); + dest[size-1] = 0; +} + +std::string gen_rand_alphanumeric_no_underscore(CephContext *cct, size_t size) +{ + std::string str; + str.resize(size + 1); + gen_rand_alphanumeric_no_underscore(cct, str.data(), str.size()); + str.pop_back(); // pop the extra \0 + return str; +} + + +void gen_rand_alphanumeric_plain(CephContext *cct, char *dest, size_t size) /* size should be the required string size + 1 */ +{ + static constexpr char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + choose_from(cct->random(), table, dest, size-1); + dest[size-1] = 0; +} + +std::string gen_rand_alphanumeric_plain(CephContext *cct, size_t size) +{ + std::string str; + str.resize(size + 1); + gen_rand_alphanumeric_plain(cct, str.data(), str.size()); + str.pop_back(); // pop the extra \0 + return str; +} diff --git a/src/common/random_string.h b/src/common/random_string.h new file mode 100644 index 0000000000000..87c1644c0f2a3 --- /dev/null +++ b/src/common/random_string.h @@ -0,0 +1,36 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab ft=cpp + +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2004-2009 Sage Weil + * Copyright (C) 2015 Yehuda Sadeh + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#pragma once + +#include + +class CephContext; + +/* size should be the required string size + 1 */ +int gen_rand_base64(CephContext *cct, char *dest, size_t size); +void gen_rand_alphanumeric(CephContext *cct, char *dest, size_t size); +void gen_rand_alphanumeric_lower(CephContext *cct, char *dest, size_t size); +void gen_rand_alphanumeric_upper(CephContext *cct, char *dest, size_t size); +void gen_rand_alphanumeric_no_underscore(CephContext *cct, char *dest, size_t size); +void gen_rand_alphanumeric_plain(CephContext *cct, char *dest, size_t size); + +// returns a std::string with 'size' random characters +std::string gen_rand_alphanumeric(CephContext *cct, size_t size); +std::string gen_rand_alphanumeric_lower(CephContext *cct, size_t size); +std::string gen_rand_alphanumeric_upper(CephContext *cct, size_t size); +std::string gen_rand_alphanumeric_no_underscore(CephContext *cct, size_t size); +std::string gen_rand_alphanumeric_plain(CephContext *cct, size_t size); diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 8936cb30fd276..567b80ca6c8ec 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -26,7 +26,6 @@ #include "common/convenience.h" #include "common/strtol.h" #include "include/str_list.h" -#include "auth/Crypto.h" #include "rgw_crypt_sanitize.h" #include @@ -746,105 +745,6 @@ std::string calc_hash_sha256_restart_stream(SHA256 **phash) return hash; } -int gen_rand_base64(CephContext *cct, char *dest, int size) /* size should be the required string size + 1 */ -{ - char buf[size]; - char tmp_dest[size + 4]; /* so that there's space for the extra '=' characters, and some */ - int ret; - - cct->random()->get_bytes(buf, sizeof(buf)); - - ret = ceph_armor(tmp_dest, &tmp_dest[sizeof(tmp_dest)], - (const char *)buf, ((const char *)buf) + ((size - 1) * 3 + 4 - 1) / 4); - if (ret < 0) { - lderr(cct) << "ceph_armor failed" << dendl; - return ret; - } - tmp_dest[ret] = '\0'; - memcpy(dest, tmp_dest, size); - dest[size-1] = '\0'; - - return 0; -} - -static const char alphanum_upper_table[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -void gen_rand_alphanumeric_upper(CephContext *cct, char *dest, int size) /* size should be the required string size + 1 */ -{ - cct->random()->get_bytes(dest, size); - - int i; - for (i=0; irandom()->get_bytes(dest, size); - - int i; - for (i=0; irandom()->get_bytes(dest, size); - - int i; - for (i=0; irandom()->get_bytes(dest, size); - - int i; - for (i=0; irandom()->get_bytes(dest, size); - - int i; - for (i=0; i #include "common/ceph_crypto.h" +#include "common/random_string.h" #include "rgw_acl.h" #include "rgw_cors.h" #include "rgw_iam_policy.h" @@ -258,15 +259,6 @@ struct req_state; typedef void *RGWAccessHandle; -/* size should be the required string size + 1 */ -int gen_rand_base64(CephContext *cct, char *dest, int size); -void gen_rand_alphanumeric(CephContext *cct, char *dest, int size); -void gen_rand_alphanumeric_lower(CephContext *cct, char *dest, int size); -void gen_rand_alphanumeric_upper(CephContext *cct, char *dest, int size); -void gen_rand_alphanumeric_no_underscore(CephContext *cct, char *dest, int size); -void gen_rand_alphanumeric_plain(CephContext *cct, char *dest, int size); -void gen_rand_alphanumeric_lower(CephContext *cct, string *str, int length); - enum RGWIntentEvent { DEL_OBJ = 0, DEL_DIR = 1, diff --git a/src/rgw/rgw_lc_s3.cc b/src/rgw/rgw_lc_s3.cc index 144a92f4cbd59..09eb216f834a9 100644 --- a/src/rgw/rgw_lc_s3.cc +++ b/src/rgw/rgw_lc_s3.cc @@ -91,12 +91,9 @@ void RGWLifecycleConfiguration_S3::decode_xml(XMLObj *obj) for (auto& rule : rules) { if (rule.get_id().empty()) { - string id; - // S3 generates a 48 bit random ID, maybe we could generate shorter IDs static constexpr auto LC_ID_LENGTH = 48; - - gen_rand_alphanumeric_lower(cct, &id, LC_ID_LENGTH); + string id = gen_rand_alphanumeric_lower(cct, LC_ID_LENGTH); rule.set_id(id); } diff --git a/src/rgw/rgw_rados.cc b/src/rgw/rgw_rados.cc index cda2b1ed07228..51d1e2cb68aa9 100644 --- a/src/rgw/rgw_rados.cc +++ b/src/rgw/rgw_rados.cc @@ -7072,8 +7072,7 @@ int RGWRados::olh_init_modification_impl(const RGWBucketInfo& bucket_info, RGWOb if (!has_tag) { /* obj tag */ - string obj_tag; - gen_rand_alphanumeric_lower(cct, &obj_tag, 32); + string obj_tag = gen_rand_alphanumeric_lower(cct, 32); bufferlist bl; bl.append(obj_tag.c_str(), obj_tag.size()); @@ -7083,8 +7082,7 @@ int RGWRados::olh_init_modification_impl(const RGWBucketInfo& bucket_info, RGWOb state.obj_tag = bl; /* olh tag */ - string olh_tag; - gen_rand_alphanumeric_lower(cct, &olh_tag, 32); + string olh_tag = gen_rand_alphanumeric_lower(cct, 32); bufferlist olh_bl; olh_bl.append(olh_tag.c_str(), olh_tag.size()); @@ -7110,8 +7108,7 @@ int RGWRados::olh_init_modification_impl(const RGWBucketInfo& bucket_info, RGWOb snprintf(buf, sizeof(buf), "%016llx", (unsigned long long)ut.sec()); *op_tag = buf; - string s; - gen_rand_alphanumeric_lower(cct, &s, OLH_PENDING_TAG_LEN - op_tag->size()); + string s = gen_rand_alphanumeric_lower(cct, OLH_PENDING_TAG_LEN - op_tag->size()); op_tag->append(s); diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index 3605f362b3fd7..2bb6e86124ebf 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -901,7 +901,7 @@ target_link_libraries(unittest_pageset global) add_executable(unittest_random_string test_random_string.cc $) add_ceph_unittest(unittest_random_string) -target_link_libraries(unittest_random_string global ${rgw_libs}) +target_link_libraries(unittest_random_string global) # unittest_any_ add_executable(unittest_any test_any.cc) diff --git a/src/test/test_random_string.cc b/src/test/test_random_string.cc index 95729e79ec7e5..fa198a3466aab 100644 --- a/src/test/test_random_string.cc +++ b/src/test/test_random_string.cc @@ -12,7 +12,7 @@ * */ -#include "rgw/rgw_common.h" +#include "common/random_string.h" #include "common/ceph_context.h" #include "global/global_context.h" #include @@ -52,6 +52,13 @@ TEST(RandomString, alphanumeric) EXPECT_TRUE(std::all_of(arr, arr + 64, is_alphanumeric)); } +TEST(RandomString, alphanumeric_string) +{ + std::string str = gen_rand_alphanumeric(g_ceph_context, 64); + EXPECT_EQ(64, str.size()); + EXPECT_TRUE(std::all_of(str.begin(), str.end(), is_alphanumeric)); +} + TEST(RandomString, alphanumeric_lower) { char arr[65] = {}; @@ -60,6 +67,13 @@ TEST(RandomString, alphanumeric_lower) EXPECT_TRUE(std::all_of(arr, arr + 64, is_alphanumeric_lower)); } +TEST(RandomString, alphanumeric_lower_string) +{ + std::string str = gen_rand_alphanumeric_lower(g_ceph_context, 64); + EXPECT_EQ(64, str.size()); + EXPECT_TRUE(std::all_of(str.begin(), str.end(), is_alphanumeric_lower)); +} + TEST(RandomString, alphanumeric_upper) { char arr[65] = {}; @@ -68,6 +82,13 @@ TEST(RandomString, alphanumeric_upper) EXPECT_TRUE(std::all_of(arr, arr + 64, is_alphanumeric_upper)); } +TEST(RandomString, alphanumeric_upper_string) +{ + std::string str = gen_rand_alphanumeric_upper(g_ceph_context, 64); + EXPECT_EQ(64, str.size()); + EXPECT_TRUE(std::all_of(str.begin(), str.end(), is_alphanumeric_upper)); +} + TEST(RandomString, alphanumeric_no_underscore) { char arr[65] = {}; @@ -76,6 +97,13 @@ TEST(RandomString, alphanumeric_no_underscore) EXPECT_TRUE(std::all_of(arr, arr + 64, is_alphanumeric_no_underscore)); } +TEST(RandomString, alphanumeric_no_underscore_string) +{ + std::string str = gen_rand_alphanumeric_no_underscore(g_ceph_context, 64); + EXPECT_EQ(64, str.size()); + EXPECT_TRUE(std::all_of(str.begin(), str.end(), is_alphanumeric_no_underscore)); +} + TEST(RandomString, alphanumeric_plain) { char arr[65] = {}; @@ -83,3 +111,10 @@ TEST(RandomString, alphanumeric_plain) EXPECT_EQ(0, arr[64]); EXPECT_TRUE(std::all_of(arr, arr + 64, is_alphanumeric_plain)); } + +TEST(RandomString, alphanumeric_plain_string) +{ + std::string str = gen_rand_alphanumeric_plain(g_ceph_context, 64); + EXPECT_EQ(64, str.size()); + EXPECT_TRUE(std::all_of(str.begin(), str.end(), is_alphanumeric_plain)); +}