repo: ngircd
action: commit
revision: 
path_from: 
revision_from: 5acb90fafc9dea012967751fb6a5c7847da1820a:
path_to: 
revision_to: 
git.thebackupbox.net
ngircd
git clone git://git.thebackupbox.net/ngircd
commit 5acb90fafc9dea012967751fb6a5c7847da1820a
Author: Florian Westphal 
Date:   Sun Mar 27 22:48:01 2011 +0200

    ngircd: improve rng initialisation

    we do not need this for cryptographic purposes, but we can do better
    than plain srandom(getpid()).

    Also, keep in mind that rng state is inherited across fork(), so re-init
    it in the child.

diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c
index 74a998800f364376a87efb290cd2d0dc030a2ab4..
index ..4cac909d8f02e3f4d60593693ee6855b49e7f338 100644
--- a/src/ngircd/ngircd.c
+++ b/src/ngircd/ngircd.c
@@ -60,6 +60,8 @@ static void Pidfile_Delete PARAMS(( void ));

 static void Fill_Version PARAMS(( void ));

+static void Random_Init PARAMS(( void ));
+
 static void Setup_FDStreams PARAMS(( int fd ));

 static bool NGIRCd_Init PARAMS(( bool ));
@@ -262,6 +264,8 @@ main( int argc, const char *argv[] )
 		NGIRCd_SignalRestart = false;
 		NGIRCd_SignalQuit = false;

+		Random_Init();
+
 		/* Initialize modules, part I */
 		Log_Init( ! NGIRCd_NoDaemon );
 		Conf_Init( );
@@ -289,8 +293,6 @@ main( int argc, const char *argv[] )
 			exit(1);
 		}

-		srandom(getpid());
-
 		/* Create protocol and server identification. The syntax
 		 * used by ngIRCd in PASS commands and the known "extended
 		 * flags" are described in doc/Protocol.txt. */
@@ -564,6 +566,37 @@ NGIRCd_getNobodyID(uid_t *uid, gid_t *gid )
 } /* NGIRCd_getNobodyID */


+static bool
+Random_Init_Kern(const char *file)
+{
+	unsigned int seed;
+	bool ret = false;
+	int fd = open(file, O_RDONLY);
+	if (fd >= 0) {
+		if (read(fd, &seed, sizeof(seed)) == sizeof(seed))
+			ret = true;
+		close(fd);
+		srandom(seed);
+	}
+	return ret;
+}
+
+/**
+ * Initialize libc random(3) number generator
+ */
+static void
+Random_Init(void)
+{
+	if (Random_Init_Kern("/dev/urandom"))
+		return;
+	if (Random_Init_Kern("/dev/random"))
+		return;
+	if (Random_Init_Kern("/dev/arandom"))
+		return;
+	srandom(random() ^ getpid() ^ time(NULL));
+}
+
+
 /**
  * Initialize ngIRCd daemon.
  *
diff --git a/src/ngircd/proc.c b/src/ngircd/proc.c
index aace8053c00c2cca27f2a24ed0490f1271137f0e..
index ..557543c26c2385941b3c0ce8f75031398d66f0e8 100644
--- a/src/ngircd/proc.c
+++ b/src/ngircd/proc.c
@@ -50,6 +50,7 @@ GLOBAL pid_t
 Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout)
 {
 	pid_t pid;
+	unsigned int seed;

 	assert(proc != NULL);
 	assert(pipefds != NULL);
@@ -61,6 +62,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout
 		return -1;
 	}

+	seed = random();
 	pid = fork();
 	switch (pid) {
 	case -1:
@@ -71,6 +73,7 @@ Proc_Fork(PROC_STAT *proc, int *pipefds, void (*cbfunc)(int, short), int timeout
 		return -1;
 	case 0:
 		/* New child process: */
+		srandom(seed ^ time(NULL) ^ getpid());
 		Signals_Exit();
 		signal(SIGTERM, Proc_GenericSignalHandler);
 		signal(SIGALRM, Proc_GenericSignalHandler);

-----END OF PAGE-----