From b455704e7fe472b13344fee5f18c2d080c97a8ef Mon Sep 17 00:00:00 2001 From: codemastr Date: Sun, 5 Jan 2003 01:26:28 +0000 Subject: [PATCH] Added a patch by Syzop to increase randomness of the random numbers --- Changes | 1 + include/h.h | 2 + makefile.win32 | 5 +- src/Makefile | 5 +- src/ircd.c | 1 + src/modules/m_mkpasswd.c | 3 - src/random.c | 181 +++++++++++++++++++++++++++++++++++++++ src/res.c | 16 ++-- src/s_conf.c | 3 + src/s_user.c | 8 +- 10 files changed, 203 insertions(+), 22 deletions(-) create mode 100644 src/random.c diff --git a/Changes b/Changes index 8e36801cb..ab0babe1a 100644 --- a/Changes +++ b/Changes @@ -1758,3 +1758,4 @@ seen. gmtime warning still there - Fixed a bug where leaving out a value for certain config directives would cause a crash, reported by AngryWolf (#0000596) - Fixed whole bunch of users in empty channel bug (probably) +- Added a patch by Syzop to increase the "randomness" of well... the random numbers diff --git a/include/h.h b/include/h.h index fff7cb435..5283c99ef 100644 --- a/include/h.h +++ b/include/h.h @@ -544,5 +544,7 @@ char *ssl_get_cipher(SSL *ssl); #endif long config_checkval(char *value, unsigned short flags); void config_status(char *format, ...); +void init_random(); +u_int32_t getrandom32(); #define EVENT_DRUGS BASE_VERSION diff --git a/makefile.win32 b/makefile.win32 index fc1aa7faf..c80611783 100644 --- a/makefile.win32 +++ b/makefile.win32 @@ -35,7 +35,7 @@ OBJ_FILES=SRC/CHANNEL.OBJ SRC/SEND.OBJ SRC/SOCKET.OBJ \ SRC/S_KLINE.OBJ SRC/S_EXTRA.OBJ SRC/IRCSPRINTF.OBJ SRC/LUSERS.OBJ \ SRC/SCACHE.OBJ SRC/ALN.OBJ SRC/BADWORDS.OBJ SRC/WEBTV.OBJ SRC/RES.OBJ SRC/MODULES.OBJ \ SRC/S_SVS.OBJ SRC/EVENTS.OBJ SRC/UMODES.OBJ SRC/AUTH.OBJ SRC/CIDR.OBJ SRC/SSL.OBJ \ - SRC/SERVICE.OBJ SRC/DEBUG.OBJ + SRC/SERVICE.OBJ SRC/DEBUG.OBJ SRC/RANDOM.OBJ MOD_FILES=SRC/L_COMMANDS.OBJ SRC/M_CHGHOST.OBJ SRC/M_SDESC.OBJ SRC/M_SETIDENT.OBJ \ SRC/M_SETNAME.OBJ SRC/M_SETHOST.OBJ SRC/M_CHGIDENT.OBJ SRC/M_SVSMOTD.OBJ \ @@ -228,6 +228,9 @@ src/auth.obj: src/auth.c $(INCLUDES) src/cidr.obj: src/cidr.c $(INCLUDES) $(CC) $(CFLAGS) src/cidr.c +src/random.obj: src/random.c $(INCLUDES) + $(CC) $(CFLAGS) src/random.c + src/ssl.obj: src/ssl.c $(INCLUDES) $(CC) $(CFLAGS) src/ssl.c diff --git a/src/Makefile b/src/Makefile index 7b051822c..191b23ba9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -28,7 +28,7 @@ OBJS=auth.o aln.o badwords.o channel.o cloak.o crule.o dbuf.o \ s_bsd.o s_conf.o s_debug.o s_err.o s_extra.o s_kline.o \ s_misc.o s_numeric.o s_serv.o s_svs.o $(STRTOUL) socket.o \ ssl.o s_user.o scache.o send.o support.o umodes.o \ - version.o webtv.o whowas.o zip.o cidr.o + version.o webtv.o whowas.o zip.o cidr.o random.o SRC=$(OBJS:%.o=%.c) @@ -237,5 +237,8 @@ crule.o: crule.c $(INCLUDES) cidr.o: cidr.c $(INCLUDES) $(CC) $(CFLAGS) -c cidr.c +random.o: random.c $(INCLUDES) + $(CC) $(CFLAGS) -c random.c + # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/src/ircd.c b/src/ircd.c index 46f7531c0..9c92c9de9 100644 --- a/src/ircd.c +++ b/src/ircd.c @@ -1209,6 +1209,7 @@ int InitwIRCD(int argc, char *argv[]) } } #endif + init_random(); Debug((DEBUG_NOTICE, "Server ready...")); SetupEvents(); loop.do_bancheck = 0; diff --git a/src/modules/m_mkpasswd.c b/src/modules/m_mkpasswd.c index b7e153c38..c86e57a95 100644 --- a/src/modules/m_mkpasswd.c +++ b/src/modules/m_mkpasswd.c @@ -125,9 +125,6 @@ int m_mkpasswd(aClient *cptr, aClient *sptr, int parc, char *parv[]) me.name, IsWebTV(sptr) ? "PRIVMSG" : "NOTICE", parv[0]); return 0; } -#ifndef _WIN32 - srandom(TStime()); -#endif if ((type = Auth_FindType(parv[1])) == -1) { sendto_one(sptr, diff --git a/src/random.c b/src/random.c new file mode 100644 index 000000000..5338945d0 --- /dev/null +++ b/src/random.c @@ -0,0 +1,181 @@ +/************************************************************************ + * IRC - Internet Relay Chat, random.c + * (C) 2003 Bram Matthys (Syzop) + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "struct.h" +#include "common.h" +#include "sys.h" +#include "numeric.h" +#include "msg.h" +#include "channel.h" +#include "version.h" +#include +#ifdef _WIN32 +#include +#endif +#include +#include +#include +#include +#ifdef _WIN32 +#include +#endif +#include +#include "h.h" + +#ifdef NOSPOOF +/* + * getrandom32, written by Syzop. + * This function returns a random 32bit value + */ +u_int32_t getrandom32() +{ +u_int32_t result; +int n; +#ifndef _WIN32 +static struct timeval prevt; +struct timeval nowt; +#else +static struct _timeb prevt; +struct _timeb nowt; +#endif +#ifdef USE_SSL + #if OPENSSL_VERSION_NUMBER >= 0x000907000 + if (EGD_PATH) { + n = RAND_query_egd_bytes(EGD_PATH, (unsigned char *)&result, sizeof(result)); + if (n == sizeof(result)) + return result; + } + #endif +#endif + +#ifndef _WIN32 + gettimeofday(&nowt, NULL); + + /* [random() may return <31 random bits, I assume it will be at least 16 bits] + * 31bits (low) ^ 16bits (high) ^ 19bits (low) ^ 19bits (high) */ + result = random() ^ (random() << 16) ^ nowt.tv_usec ^ (prevt.tv_usec << 13); +#else + _ftime(&nowt); + + /* 15bits (0..14) ^ 15 bits (10..24) ^ 12 bits (20..31) ^ + * 10bits (10..19) ^ 10 bits (20..29) + */ + result = rand() ^ (rand() << 10) ^ (rand() << 20) ^ + (nowt.millitm << 10) ^ (prevt.millitm << 20); +#endif + + prevt = nowt; + return result; +} +#endif + +static unsigned int entropy_cfgcrc = 0, entropy_cfgsize = 0; +static time_t entropy_cfgmtime = 0; + +void add_entropy_configfile(struct stat st, char *buf) +{ + entropy_cfgsize = (entropy_cfgsize << 4) ^ st.st_size; + entropy_cfgmtime = (entropy_cfgmtime << 4) ^ st.st_mtime; + entropy_cfgcrc = entropy_cfgcrc ^ (unsigned int)crc32(buf, strlen(buf)); + Debug((DEBUG_INFO, "add_entropy_configfile: cfgsize: %u", entropy_cfgsize)); + Debug((DEBUG_INFO, "add_entropy_configfile: cfgmtime: %u", + (unsigned int)entropy_cfgmtime)); + Debug((DEBUG_INFO, "add_entropy_configfile: cfgcrc: %u", entropy_cfgcrc)); +} + +/* + * init_random, written by Syzop + * This function (hopefully) intialises the random generator securely + */ +void init_random() +{ +unsigned int seed; +time_t now = TStime(); +#ifndef _WIN32 +struct timeval nowt; +unsigned int xrnd = 0, egd = 0; +int fd, n; +#else +MEMORYSTATUS mstat; +struct _timeb nowt; +#endif + +#ifdef USE_SSL + #if OPENSSL_VERSION_NUMBER >= 0x000907000 + if (EGD_PATH) { + n = RAND_query_egd_bytes(EGD_PATH, (unsigned char *)&egd, sizeof(egd)); + Debug((DEBUG_INFO, + "init_random: RAND_query_egd_bytes() ret=%d, val=%.8x", n, egd)); + } + #endif +#endif + + /* Grab non-OS specific "random" data */ + + /* Grab OS specific "random" data */ +#ifndef _WIN32 + gettimeofday(&nowt, NULL); + fd = open("/dev/random", O_RDONLY); + if (fd) { + (void)read(fd, &xrnd, sizeof(int)); + Debug((DEBUG_INFO, "init_random: read from /dev/random: 0x%.8x", xrnd)); + close(fd); + } else { + fd = open("/dev/urandom", O_RDONLY); + if (fd) { + (void)read(fd, &xrnd, sizeof(int)); + Debug((DEBUG_INFO, "init_random: read from /dev/urandom: 0x%.8x", xrnd)); + close(fd); + } else { + Debug((DEBUG_INFO, "init_random: [BAD] nothing read from random devices")); + } + } +#else + _ftime(&nowt); + GlobalMemoryStatus (&mstat); + #ifdef DEBUGMODE + Debug((DEBUG_INFO, "init_random: mstat.dwAvailPhys=%u, mstat.dwAvailPageFile=%u\n", + mstat.dwAvailPhys, mstat.dwAvailPageFile)); + #endif +#endif + + /* Build the seed (OS specific again) */ +#ifndef _WIN32 + seed = now ^ nowt.tv_usec ^ getpid() ^ (entropy_cfgsize << 24) ^ + (entropy_cfgmtime << 16) ^ entropy_cfgcrc ^ CLOAK_KEY1 ^ xrnd ^ egd; +#else + seed = now ^ nowt.millitm ^ getpid() ^ mstat.dwAvailPhys ^ + (mstat.dwAvailPageFile << 16) ^ (entropy_cfgsize << 8) ^ + (entropy_cfgmtime << 24) ^ entropy_cfgcrc ^ CLOAK_KEY1 ^ egd; +#endif + + Debug((DEBUG_INFO, "init_random: seeding to 0x%.8x (%u)", seed, seed)); + srand(seed); +#ifdef LRAND48 + srand48(seed); +#endif +#ifndef _WIN32 + srandom(seed); +#endif +} + diff --git a/src/res.c b/src/res.c index dffe91d0d..1b165835e 100644 --- a/src/res.c +++ b/src/res.c @@ -118,9 +118,6 @@ int init_resolver(int op) } #endif -#ifdef LRAND48 - srand48(TStime()); -#endif if (op & RES_INITLIST) { bzero((char *)&reinfo, sizeof(reinfo)); @@ -697,20 +694,19 @@ static int query_name(char *name, int class, int type, ResRQ *rptr) return r; } hptr = (HEADER *) buf; -#ifdef LRAND48 - do - { - hptr->id = htons(ntohs(hptr->id) + k + lrand48() & 0xffff); -#else (void)gettimeofday(&tv, NULL); do { /* htons/ntohs can be assembler macros, which cannot be nested. Thus two lines. -Vesa */ +#ifdef LRAND48 u_short nstmp = ntohs(hptr->id) + k + - (u_short)(tv.tv_usec & 0xffff); - hptr->id = htons(nstmp); + (u_short)(tv.tv_usec & 0xffff) + (u_short)(lrand48() & 0xffff); +#else + u_short nstmp = ntohs(hptr->id) + k + + (u_short)(tv.tv_usec & 0xffff) + (u_short)(rand() & 0xffff); #endif /* LRAND48 */ + hptr->id = htons(nstmp); k++; } while (find_id(ntohs(hptr->id))); diff --git a/src/s_conf.c b/src/s_conf.c index 998775c9b..74ef46455 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -322,6 +322,8 @@ extern void win_log(char *format, ...); extern void win_error(); #endif +extern void add_entropy_configfile(struct stat st, char *buf); + /* * Config parser (IRCd) */ @@ -576,6 +578,7 @@ ConfigFile *config_load(char *filename) /* Just me or could this cause memory corrupted when ret <0 ? */ buf[ret] = '\0'; close(fd); + add_entropy_configfile(sb, buf); cfptr = config_parse(filename, buf); free(buf); return cfptr; diff --git a/src/s_user.c b/src/s_user.c index 6dd694000..f4abcc624 100644 --- a/src/s_user.c +++ b/src/s_user.c @@ -1713,13 +1713,7 @@ CMD_FUNC(m_nick) * * Generate a random string for them to pong with. */ -#ifndef _WIN32 - sptr->nospoof = - 1 + (int)(9000000.0 * random() / (RAND_MAX + 80000000.0)); -#else - sptr->nospoof = - 1 + (int)(9000000.0 * rand() / (RAND_MAX + 80000000.0)); -#endif + sptr->nospoof = getrandom32(); sendto_one(sptr, ":%s NOTICE %s :*** If you are having problems" " connecting due to ping timeouts, please" " type /quote pong %X or /raw pong %X now.",