summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Tanous <ed@tanous.net>2024-06-05 18:45:25 +0300
committerEd Tanous <ed@tanous.net>2024-06-10 18:19:46 +0300
commitb7f3a82babf87c7279ebc4cb728497ade1b1d00a (patch)
tree568378e082ccbf02c8a91b1cb78c3b8d3ef8e6ef
parentd5fb584a8ad7d493a3236261f727852f262271c6 (diff)
downloadbmcweb-b7f3a82babf87c7279ebc4cb728497ade1b1d00a.tar.xz
Break out random ID methods
The method of creating a random ID from an openssl random generator of a particular length is something that is generally useful, and something we can write unit tests for. Add it. Tested: Redfish service validator login flows work correctly in redfish service validator. Change-Id: Ic3b58d33f1421f3eb39e2d57585958f87f6fb8ea Signed-off-by: Ed Tanous <ed@tanous.net>
-rw-r--r--include/ossl_random.hpp20
-rw-r--r--include/sessions.hpp50
-rw-r--r--src/ossl_random.cpp51
-rw-r--r--test/include/ossl_random.cpp9
4 files changed, 71 insertions, 59 deletions
diff --git a/include/ossl_random.hpp b/include/ossl_random.hpp
index 4d4bc04a06..0a92e37181 100644
--- a/include/ossl_random.hpp
+++ b/include/ossl_random.hpp
@@ -2,11 +2,6 @@
#include "logging.hpp"
-extern "C"
-{
-#include <openssl/rand.h>
-}
-
#include <limits>
#include <string>
@@ -15,18 +10,7 @@ namespace bmcweb
struct OpenSSLGenerator
{
- uint8_t operator()()
- {
- uint8_t index = 0;
- int rc = RAND_bytes(&index, sizeof(index));
- if (rc != opensslSuccess)
- {
- BMCWEB_LOG_ERROR("Cannot get random number");
- err = true;
- }
-
- return index;
- }
+ uint8_t operator()();
static constexpr uint8_t max()
{
@@ -53,4 +37,6 @@ struct OpenSSLGenerator
std::string getRandomUUID();
+std::string getRandomIdOfLength(size_t length);
+
} // namespace bmcweb
diff --git a/include/sessions.hpp b/include/sessions.hpp
index 3343933378..10e29c830f 100644
--- a/include/sessions.hpp
+++ b/include/sessions.hpp
@@ -11,6 +11,7 @@
#include <csignal>
#include <optional>
#include <random>
+#include <string>
namespace persistent_data
{
@@ -183,50 +184,17 @@ class SessionStore
PersistenceType persistence = PersistenceType::TIMEOUT,
bool isConfigureSelfOnly = false)
{
- // TODO(ed) find a secure way to not generate session identifiers if
- // persistence is set to SINGLE_REQUEST
- static constexpr std::array<char, 62> alphanum = {
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
- 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
- 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
- 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
- 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
-
- std::string sessionToken;
- sessionToken.resize(sessionTokenSize, '0');
- std::uniform_int_distribution<size_t> dist(0, alphanum.size() - 1);
-
- bmcweb::OpenSSLGenerator gen;
-
- for (char& sessionChar : sessionToken)
- {
- sessionChar = alphanum[dist(gen)];
- if (gen.error())
- {
- return nullptr;
- }
- }
// Only need csrf tokens for cookie based auth, token doesn't matter
- std::string csrfToken;
- csrfToken.resize(sessionTokenSize, '0');
- for (char& csrfChar : csrfToken)
- {
- csrfChar = alphanum[dist(gen)];
- if (gen.error())
- {
- return nullptr;
- }
- }
+ std::string sessionToken =
+ bmcweb::getRandomIdOfLength(sessionTokenSize);
+ std::string csrfToken = bmcweb::getRandomIdOfLength(sessionTokenSize);
+ std::string uniqueId = bmcweb::getRandomIdOfLength(10);
- std::string uniqueId;
- uniqueId.resize(10, '0');
- for (char& uidChar : uniqueId)
+ //
+ if (sessionToken.empty() || csrfToken.empty() || uniqueId.empty())
{
- uidChar = alphanum[dist(gen)];
- if (gen.error())
- {
- return nullptr;
- }
+ BMCWEB_LOG_ERROR("Failed to generate session tokens");
+ return nullptr;
}
auto session = std::make_shared<UserSession>(
diff --git a/src/ossl_random.cpp b/src/ossl_random.cpp
index 126197792b..419fe31455 100644
--- a/src/ossl_random.cpp
+++ b/src/ossl_random.cpp
@@ -1,14 +1,63 @@
#include "ossl_random.hpp"
+extern "C"
+{
+#include <openssl/rand.h>
+}
+
#include <boost/uuid/random_generator.hpp>
#include <boost/uuid/uuid_io.hpp>
+#include <array>
+#include <random>
#include <string>
-std::string bmcweb::getRandomUUID()
+namespace bmcweb
+{
+uint8_t OpenSSLGenerator::operator()()
+{
+ uint8_t index = 0;
+ int rc = RAND_bytes(&index, sizeof(index));
+ if (rc != opensslSuccess)
+ {
+ BMCWEB_LOG_ERROR("Cannot get random number");
+ err = true;
+ }
+
+ return index;
+}
+
+std::string getRandomUUID()
{
using bmcweb::OpenSSLGenerator;
OpenSSLGenerator ossl;
return boost::uuids::to_string(
boost::uuids::basic_random_generator<OpenSSLGenerator>(ossl)());
}
+
+std::string getRandomIdOfLength(size_t length)
+{
+ static constexpr std::array<char, 62> alphanum = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
+ 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+ 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c',
+ 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
+
+ std::string token;
+ token.resize(length, '0');
+ std::uniform_int_distribution<size_t> dist(0, alphanum.size() - 1);
+
+ bmcweb::OpenSSLGenerator gen;
+
+ for (char& tokenChar : token)
+ {
+ tokenChar = alphanum[dist(gen)];
+ if (gen.error())
+ {
+ return "";
+ }
+ }
+ return token;
+}
+} // namespace bmcweb
diff --git a/test/include/ossl_random.cpp b/test/include/ossl_random.cpp
index 512b5c8f83..1b9a2b88da 100644
--- a/test/include/ossl_random.cpp
+++ b/test/include/ossl_random.cpp
@@ -6,6 +6,7 @@
namespace
{
+using testing::IsEmpty;
using testing::MatchesRegex;
TEST(Bmcweb, GetRandomUUID)
@@ -18,4 +19,12 @@ TEST(Bmcweb, GetRandomUUID)
"^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$"));
}
+TEST(Bmcweb, GetRandomIdOfLength)
+{
+ using bmcweb::getRandomIdOfLength;
+ EXPECT_THAT(getRandomIdOfLength(1), MatchesRegex("^[a-zA-Z0-9]$"));
+ EXPECT_THAT(getRandomIdOfLength(10), MatchesRegex("^[a-zA-Z0-9]{10}$"));
+ EXPECT_THAT(getRandomIdOfLength(0), IsEmpty());
+}
+
} // namespace