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>
diff --git a/include/ossl_random.hpp b/include/ossl_random.hpp
index 4d4bc04..0a92e37 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 @@
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 @@
std::string getRandomUUID();
+std::string getRandomIdOfLength(size_t length);
+
} // namespace bmcweb
diff --git a/include/sessions.hpp b/include/sessions.hpp
index 3343933..10e29c8 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 @@
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>(