summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2010-02-09 02:22:27 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2010-02-09 02:22:27 +0000
commitaab7998583ca16590a32c7bdb80955a18b090700 (patch)
treea2b7f6d82a523e683347b7489ab77f0e940bdede /src
parentdb790d9d1516c9c7cd48738340e5df1c8a2bebe3 (diff)
Add random number generation functions to InspIRCd class.
Default implementation uses libc random(), which can be better than rand(). If gnutls is loaded, gcrypt will be used to provide random numbers. git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12404 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src')
-rw-r--r--src/dns.cpp19
-rw-r--r--src/helperfuncs.cpp28
-rw-r--r--src/inspircd.cpp3
-rw-r--r--src/modules/extra/m_ssl_gnutls.cpp15
-rw-r--r--src/modules/m_conn_waitpong.cpp12
-rw-r--r--src/modules/m_randquote.cpp40
-rw-r--r--src/modules/m_spanningtree/capab.cpp2
-rw-r--r--src/modules/m_spanningtree/hmac.cpp30
-rw-r--r--src/modules/m_spanningtree/treesocket.h4
9 files changed, 62 insertions, 91 deletions
diff --git a/src/dns.cpp b/src/dns.cpp
index dee83d3ac..8526d5be2 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -242,11 +242,9 @@ DNSRequest* DNS::AddQuery(DNSHeader *header, int &id, const char* original)
return NULL;
/* Create an id */
- id = this->PRNG() & DNS::MAX_REQUEST_ID;
-
- /* If this id is already 'in flight', pick another. */
- while (requests[id])
- id = this->PRNG() & DNS::MAX_REQUEST_ID;
+ do {
+ id = ServerInstance->GenRandomInt(DNS::MAX_REQUEST_ID);
+ } while (requests[id]);
DNSRequest* req = new DNSRequest(this, id, original);
@@ -1041,14 +1039,3 @@ void DNS::CleanResolvers(Module* module)
}
}
}
-
-/** Generate pseudo-random number */
-unsigned long DNS::PRNG()
-{
- unsigned long val = 0;
- serverstats* s = ServerInstance->stats;
- val = (rand() ^ this->currid++ ^ s->statsAccept) + ServerInstance->Time_ns();
- val += (s->statsCollisions ^ s->statsDnsGood) * s->statsDnsBad;
- val += (s->statsConnects ^ (unsigned long)s->statsSent ^ (unsigned long)s->statsRecv);
- return val;
-}
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp
index bba8dc8dc..66a84bbce 100644
--- a/src/helperfuncs.cpp
+++ b/src/helperfuncs.cpp
@@ -411,3 +411,31 @@ void InspIRCd::AddExtBanChar(char c)
tok.insert(ebpos, 1, c);
}
}
+
+std::string InspIRCd::GenRandomStr(int length, bool printable)
+{
+ char* buf = new char[length];
+ GenRandom(buf, length);
+ std::string rv;
+ rv.resize(length);
+ for(int i=0; i < length; i++)
+ rv[i] = printable ? 0x3F + (buf[i] & 0x3F) : buf[i];
+ delete[] buf;
+ return rv;
+}
+
+// NOTE: this has a slight bias for lower values if max is not a power of 2.
+// Don't use it if that matters.
+unsigned long InspIRCd::GenRandomInt(unsigned long max)
+{
+ unsigned long rv;
+ GenRandom((char*)&rv, sizeof(rv));
+ return rv % max;
+}
+
+// This is overridden by a higher-quality algorithm when SSL support is loaded
+void GenRandomHandler::Call(char *output, size_t max)
+{
+ for(unsigned int i=0; i < max; i++)
+ output[i] = random();
+}
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index fe0ac0a11..b95a6fecb 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -295,6 +295,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
*/
NICKForced("NICKForced", NULL),
OperQuit("OperQuit", NULL),
+ GenRandom(&HandleGenRandom),
IsChannel(&HandleIsChannel),
IsSID(&HandleIsSID),
Rehash(&HandleRehash),
@@ -375,7 +376,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
this->Config->cmdline.argv = argv;
this->Config->cmdline.argc = argc;
- srand(TIME.tv_nsec ^ TIME.tv_sec);
+ srandom(TIME.tv_nsec ^ TIME.tv_sec);
struct option longopts[] =
{
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp
index a0804ddf9..c2dc4c878 100644
--- a/src/modules/extra/m_ssl_gnutls.cpp
+++ b/src/modules/extra/m_ssl_gnutls.cpp
@@ -14,6 +14,7 @@
#include "inspircd.h"
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
+#include <gcrypt.h>
#include "ssl.h"
#include "m_cap.h"
@@ -69,6 +70,16 @@ static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t user_wrap, const void*
return rv;
}
+class RandGen : public HandlerBase2<void, char*, size_t>
+{
+ public:
+ RandGen() {}
+ void Call(char* buffer, size_t len)
+ {
+ gcry_randomize(buffer, len, GCRY_STRONG_RANDOM);
+ }
+};
+
/** Represents an SSL user's extra data
*/
class issl_session
@@ -136,6 +147,7 @@ class ModuleSSLGnuTLS : public Module
bool cred_alloc;
+ RandGen randhandler;
CommandStartTLS starttls;
GenericCap capHandler;
@@ -159,6 +171,8 @@ class ModuleSSLGnuTLS : public Module
// Needs the flag as it ignores a plain /rehash
OnModuleRehash(NULL,"ssl");
+ ServerInstance->GenRandom = &randhandler;
+
// Void return, guess we assume success
gnutls_certificate_set_dh_params(x509_cred, dh_params);
Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnUserConnect,
@@ -294,6 +308,7 @@ class ModuleSSLGnuTLS : public Module
}
gnutls_global_deinit();
delete[] sessions;
+ ServerInstance->GenRandom = &ServerInstance->HandleGenRandom;
}
void OnCleanup(int target_type, void* item)
diff --git a/src/modules/m_conn_waitpong.cpp b/src/modules/m_conn_waitpong.cpp
index 1b9301de5..00b728b51 100644
--- a/src/modules/m_conn_waitpong.cpp
+++ b/src/modules/m_conn_waitpong.cpp
@@ -45,19 +45,9 @@ class ModuleWaitPong : public Module
killonbadreply = true;
}
- std::string RandString()
- {
- char out[11];
- for(unsigned int i = 0; i < 10; i++)
- out[i] = ((rand() % 26) + 65);
- out[10] = '\0';
-
- return out;
- }
-
ModResult OnUserRegister(LocalUser* user)
{
- std::string pingrpl = RandString();
+ std::string pingrpl = ServerInstance->GenRandomStr(10);
user->Write("PING :%s", pingrpl.c_str());
diff --git a/src/modules/m_randquote.cpp b/src/modules/m_randquote.cpp
index 5214d9ad2..7d4ad042f 100644
--- a/src/modules/m_randquote.cpp
+++ b/src/modules/m_randquote.cpp
@@ -15,7 +15,6 @@
static FileReader *quotes = NULL;
-std::string q_file;
std::string prefix;
std::string suffix;
@@ -35,17 +34,9 @@ class CommandRandquote : public Command
std::string str;
int fsize;
- if (q_file.empty() || quotes->Exists())
- {
- fsize = quotes->FileSize();
- str = quotes->GetLine(rand() % fsize);
- user->WriteServ("NOTICE %s :%s%s%s",user->nick.c_str(),prefix.c_str(),str.c_str(),suffix.c_str());
- }
- else
- {
- user->WriteServ("NOTICE %s :Your administrator specified an invalid quotes file, please bug them about this.", user->nick.c_str());
- return CMD_FAILURE;
- }
+ fsize = quotes->FileSize();
+ str = quotes->GetLine(ServerInstance->GenRandomInt(fsize));
+ user->WriteServ("NOTICE %s :%s%s%s",user->nick.c_str(),prefix.c_str(),str.c_str(),suffix.c_str());
return CMD_SUCCESS;
}
@@ -59,29 +50,22 @@ class ModuleRandQuote : public Module
ModuleRandQuote()
: cmd(this)
{
- ConfigReader conf;
- // Sort the Randomizer thingie..
- srand(ServerInstance->Time());
+ }
- q_file = conf.ReadValue("randquote","file",0);
- prefix = conf.ReadValue("randquote","prefix",0);
- suffix = conf.ReadValue("randquote","suffix",0);
+ void init()
+ {
+ ConfigTag* conf = ServerInstance->Config->ConfValue("randquote");
- if (q_file.empty())
- {
- throw ModuleException("m_randquote: Quotefile not specified - Please check your config.");
- }
+ std::string q_file = conf->getString("file","quotes");
+ prefix = conf->getString("prefix");
+ suffix = conf->getString("suffix");
quotes = new FileReader(q_file);
- if(!quotes->Exists())
+ if (!quotes->Exists())
{
throw ModuleException("m_randquote: QuoteFile not Found!! Please check your config - module will not function.");
}
- else
- {
- /* Hidden Command -- Mode clients assume /quote sends raw data to an IRCd >:D */
- ServerInstance->AddCommand(&cmd);
- }
+ ServerInstance->AddCommand(&cmd);
Implementation eventlist[] = { I_OnUserConnect };
ServerInstance->Modules->Attach(eventlist, this, 1);
}
diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp
index 80236c37e..ba34d67b4 100644
--- a/src/modules/m_spanningtree/capab.cpp
+++ b/src/modules/m_spanningtree/capab.cpp
@@ -129,7 +129,7 @@ void TreeSocket::SendCapabilities(int phase)
/* Do we have sha256 available? If so, we send a challenge */
if (Utils->ChallengeResponse && (ServerInstance->Modules->Find("m_sha256.so")))
{
- this->SetOurChallenge(RandString(20));
+ SetOurChallenge(ServerInstance->GenRandomStr(20));
extra = " CHALLENGE=" + this->GetOurChallenge();
}
diff --git a/src/modules/m_spanningtree/hmac.cpp b/src/modules/m_spanningtree/hmac.cpp
index c08ac1522..52128b17b 100644
--- a/src/modules/m_spanningtree/hmac.cpp
+++ b/src/modules/m_spanningtree/hmac.cpp
@@ -96,36 +96,6 @@ std::string TreeSocket::MakePass(const std::string &password, const std::string
return password;
}
-std::string TreeSocket::RandString(unsigned int ilength)
-{
- char* randombuf = new char[ilength+1];
- std::string out;
-#ifndef WINDOWS
- int f = open("/dev/urandom", O_RDONLY, 0);
-
- if (f >= 0)
- {
- if (read(f, randombuf, ilength) < (int)ilength)
- ServerInstance->Logs->Log("m_spanningtree", DEFAULT, "Entropy source has gone predictable (did not return enough data)");
- close(f);
- }
- else
-#endif
- {
- for (unsigned int i = 0; i < ilength; i++)
- randombuf[i] = rand();
- }
-
- for (unsigned int i = 0; i < ilength; i++)
- {
- char randchar = static_cast<char>(0x3F + (randombuf[i] & 0x3F));
- out += randchar;
- }
-
- delete[] randombuf;
- return out;
-}
-
bool TreeSocket::ComparePass(const Link& link, const std::string &theirs)
{
capab->auth_fingerprint = !link.Fingerprint.empty();
diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h
index 4438b473d..1eefc500e 100644
--- a/src/modules/m_spanningtree/treesocket.h
+++ b/src/modules/m_spanningtree/treesocket.h
@@ -146,10 +146,6 @@ class TreeSocket : public BufferedSocket
*/
~TreeSocket();
- /** Generate random string used for challenge-response auth
- */
- std::string RandString(unsigned int length);
-
/** Construct a password, optionally hashed with the other side's
* challenge string
*/