]> arthur.barton.de Git - ngircd-alex.git/commitdiff
ngircd: improve rng initialisation
authorFlorian Westphal <fw@strlen.de>
Sun, 27 Mar 2011 20:48:01 +0000 (22:48 +0200)
committerFlorian Westphal <fw@strlen.de>
Sun, 27 Mar 2011 22:29:58 +0000 (00:29 +0200)
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.

src/ngircd/ngircd.c
src/ngircd/proc.c

index 74a998800f364376a87efb290cd2d0dc030a2ab4..4cac909d8f02e3f4d60593693ee6855b49e7f338 100644 (file)
@@ -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.
  *
index aace8053c00c2cca27f2a24ed0490f1271137f0e..557543c26c2385941b3c0ce8f75031398d66f0e8 100644 (file)
@@ -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);