- debug("Seeding random number generator.");
- debug("OpenSSL random status is now %i\n", RAND_status());
- debug("%i bytes from system calls", (int)stir_from_system());
- debug("%i bytes from programs", (int)stir_from_programs());
- debug("OpenSSL random status is now %i\n", RAND_status());
-
- if (!prng_seed_loaded)
- {
- prng_seed_loaded = 1;
- prng_seed_saved = 0;
- prng_read_seedfile();
- fatal_add_cleanup(prng_seed_cleanup, NULL);
- atexit(prng_write_seedfile);
- }
+ if (!prng_initialised)
+ fatal("RNG not initialised");
+
+ /* Make sure some other sigchld handler doesn't reap our entropy */
+ /* commands */
+ old_sigchld_handler = mysignal(SIGCHLD, SIG_DFL);
+
+ debug("Seeded RNG with %i bytes from programs",
+ (int)stir_from_programs());
+ debug("Seeded RNG with %i bytes from system calls",
+ (int)stir_from_system());
+
+ if (!RAND_status())
+ fatal("Not enough entropy in RNG");
+
+ mysignal(SIGCHLD, old_sigchld_handler);
+
+ if (!RAND_status())
+ fatal("Couldn't initialise builtin random number generator -- exiting.");
+}
+
+void
+init_rng(void)
+{
+ int original_euid;
+
+ check_openssl_version();
+
+ original_uid = getuid();
+ original_euid = geteuid();
+
+ /* Read in collection commands */
+ if (!prng_read_commands(SSH_PRNG_COMMAND_FILE))
+ fatal("PRNG initialisation failed -- exiting.");
+
+ /* Set ourselves up to save a seed upon exit */
+ prng_seed_saved = 0;
+
+ /* Give up privs while reading seed file */
+#ifdef SAVED_IDS_WORK_WITH_SETEUID
+ if ((original_uid != original_euid) && (seteuid(original_uid) == -1))
+ fatal("Couldn't give up privileges");
+#else /* SAVED_IDS_WORK_WITH_SETEUID */
+ /*
+ * Propagate the privileged uid to all of our uids.
+ * Set the effective uid to the given (unprivileged) uid.
+ */
+ if (original_uid != original_euid && (setuid(original_euid) == -1 ||
+ seteuid(original_uid) == -1))
+ fatal("Couldn't give up privileges");
+#endif /* SAVED_IDS_WORK_WITH_SETEUID */
+
+ prng_read_seedfile();
+
+#ifdef SAVED_IDS_WORK_WITH_SETEUID
+ if ((original_uid != original_euid) && (seteuid(original_euid) == -1))
+ fatal("Couldn't restore privileges");
+#else /* SAVED_IDS_WORK_WITH_SETEUID */
+ /*
+ * We are unable to restore the real uid to its unprivileged value.
+ * Propagate the real uid (usually more privileged) to effective uid
+ * as well.
+ */
+ if (original_uid != original_euid && (seteuid(original_euid) == -1 ||
+ setuid(original_uid) == -1))
+ fatal("Couldn't restore privileges");
+#endif /* SAVED_IDS_WORK_WITH_SETEUID */
+
+ fatal_add_cleanup(prng_seed_cleanup, NULL);
+ atexit(prng_write_seedfile);
+
+ prng_initialised = 1;