about summary refs log tree commit diff
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2011-03-27 22:48:01 +0200
committerFlorian Westphal <fw@strlen.de>2011-03-28 00:29:58 +0200
commit5acb90fafc9dea012967751fb6a5c7847da1820a (patch)
tree8fac2422a08c0dd1ce2e4e72d20b2b43279494b7
parentd61fbfc6e3a0a85ced036d8c1fa161fab0d9ba3d (diff)
downloadngircd-5acb90fafc9dea012967751fb6a5c7847da1820a.tar.gz
ngircd-5acb90fafc9dea012967751fb6a5c7847da1820a.zip
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.
-rw-r--r--src/ngircd/ngircd.c37
-rw-r--r--src/ngircd/proc.c3
2 files changed, 38 insertions, 2 deletions
diff --git a/src/ngircd/ngircd.c b/src/ngircd/ngircd.c
index 74a99880..4cac909d 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 aace8053..557543c2 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);