Merge pull request #2054 from kitkatt7/zncstring-randomstring-csprng

zncstring: generate RandomString with a CSPRNG instead of rand()
This commit is contained in:
Alexey Sokolov authored and GitHub committed 2026-10-19 18:55:42 +01:00
commit 3d96465fc0
1 file changed
+28 -3
+28 -3
View File
@@ -19,8 +19,13 @@
#include <znc/Utils.h>
#include <znc/MD5.h>
#include <znc/SHA256.h>
#include <random>
#include <sstream>
#ifdef HAVE_LIBSSL
#include <openssl/rand.h>
#endif
using std::stringstream;
static constexpr unsigned char XX = 0xff;
@@ -998,12 +1003,32 @@ CString CString::RandomString(unsigned int uLength) {
"0123456789!?.,:;/*-+_()";
// -1 because sizeof() includes the trailing '\0' byte
const size_t len = sizeof(chars) / sizeof(chars[0]) - 1;
size_t p;
CString sRet;
sRet.reserve(uLength);
std::uniform_int_distribution<size_t> distr(0, len - 1);
#ifdef HAVE_LIBSSL
// OpenSSL's DRBG is seeded once and doesn't go back to the kernel for
// every call, unlike std::random_device.
struct {
using result_type = unsigned int;
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return ~0u; }
result_type operator()() {
result_type r;
if (RAND_bytes(reinterpret_cast<unsigned char*>(&r), sizeof(r)) !=
1) {
r = std::random_device()();
}
return r;
}
} rd;
#else
std::random_device rd;
#endif
for (unsigned int a = 0; a < uLength; a++) {
p = (size_t)(len * (rand() / (RAND_MAX + 1.0)));
sRet += chars[p];
sRet += chars[distr(rd)];
}
return sRet;