/*
* Portable OpenSSH PRNG seeding:
- * If OpenSSL has not "internally seeded" itself (e.g. pulled data from
- * /dev/random), then we execute a "ssh-rand-helper" program which
- * collects entropy and writes it to stdout. The child program must
+ * If OpenSSL has not "internally seeded" itself (e.g. pulled data from
+ * /dev/random), then we execute a "ssh-rand-helper" program which
+ * collects entropy and writes it to stdout. The child program must
* write at least RANDOM_SEED_SIZE bytes. The child is run with stderr
* attached, so error/debugging output should be visible.
*
pid_t pid;
int ret;
unsigned char buf[RANDOM_SEED_SIZE];
+ mysig_t old_sigchld;
if (RAND_status() == 1) {
debug3("RNG is ready, skipping seeding");
return;
}
- debug3("Seeing PRNG from %s", SSH_RAND_HELPER);
+ debug3("Seeding PRNG from %s", SSH_RAND_HELPER);
if ((devnull = open("/dev/null", O_RDWR)) == -1)
fatal("Couldn't open /dev/null: %s", strerror(errno));
if (pipe(p) == -1)
fatal("pipe: %s", strerror(errno));
+ old_sigchld = signal(SIGCHLD, SIG_DFL);
if ((pid = fork()) == -1)
fatal("Couldn't fork: %s", strerror(errno));
if (pid == 0) {
close(p[1]);
close(devnull);
- if (original_uid != original_euid &&
- setuid(original_uid) == -1) {
- fprintf(stderr, "(rand child) setuid: %s\n",
- strerror(errno));
+ if (original_uid != original_euid &&
+ ( seteuid(getuid()) == -1 ||
+ setuid(original_uid) == -1) ) {
+ fprintf(stderr, "(rand child) setuid(%li): %s\n",
+ (long int)original_uid, strerror(errno));
_exit(1);
}
execl(SSH_RAND_HELPER, "ssh-rand-helper", NULL);
- fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n",
+ fprintf(stderr, "(rand child) Couldn't exec '%s': %s\n",
SSH_RAND_HELPER, strerror(errno));
_exit(1);
}
close(p[0]);
if (waitpid(pid, &ret, 0) == -1)
- fatal("Couldn't wait for ssh-rand-helper completion: %s",
- strerror(errno));
+ fatal("Couldn't wait for ssh-rand-helper completion: %s",
+ strerror(errno));
+ signal(SIGCHLD, old_sigchld);
/* We don't mind if the child exits upon a SIGPIPE */
- if (!WIFEXITED(ret) &&
+ if (!WIFEXITED(ret) &&
(!WIFSIGNALED(ret) || WTERMSIG(ret) != SIGPIPE))
fatal("ssh-rand-helper terminated abnormally");
if (WEXITSTATUS(ret) != 0)
}
void
-init_rng(void)
+init_rng(void)
{
/*
* OpenSSL version numbers: MNNFFPPS: major minor fix patch status