diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2010-02-09 02:22:27 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2010-02-09 02:22:27 +0000 |
commit | aab7998583ca16590a32c7bdb80955a18b090700 (patch) | |
tree | a2b7f6d82a523e683347b7489ab77f0e940bdede /src | |
parent | db790d9d1516c9c7cd48738340e5df1c8a2bebe3 (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.cpp | 19 | ||||
-rw-r--r-- | src/helperfuncs.cpp | 28 | ||||
-rw-r--r-- | src/inspircd.cpp | 3 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 15 | ||||
-rw-r--r-- | src/modules/m_conn_waitpong.cpp | 12 | ||||
-rw-r--r-- | src/modules/m_randquote.cpp | 40 | ||||
-rw-r--r-- | src/modules/m_spanningtree/capab.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_spanningtree/hmac.cpp | 30 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket.h | 4 |
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 */ |