X-Git-Url: https://git.distorted.org.uk/~mdw/become/blobdiff_plain/fe59d3d70fc7337b7a50c4fcff72d20967672157..f60a34341fee6aafd5b878dce23b80af7c60064d:/src/noise.c diff --git a/src/noise.c b/src/noise.c deleted file mode 100644 index 2945be0..0000000 --- a/src/noise.c +++ /dev/null @@ -1,324 +0,0 @@ -/* -*-c-*- - * - * $Id: noise.c,v 1.6 1998/06/18 15:08:14 mdw Exp $ - * - * Collection of environmental noise - * - * (c) 1998 EBI - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of `become' - * - * `Become' is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * `Become' is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with `become'; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/*----- Revision history --------------------------------------------------* - * - * $Log: noise.c,v $ - * Revision 1.6 1998/06/18 15:08:14 mdw - * Improve signal handling when accumulating noise from child processes. - * - * Revision 1.5 1998/04/23 13:25:23 mdw - * Try to reduce the amount of `ps'ing done under OSF/1, because /dev/kmem - * seems very slow. - * - * Revision 1.4 1998/02/20 17:52:32 mdw - * Don't use `df' for noise gathering, because it gets upset when NFS - * servers aren't responding. - * - * Revision 1.3 1998/01/12 16:46:19 mdw - * Fix copyright date. - * - * Revision 1.2 1997/08/20 16:19:57 mdw - * Fix test for `/dev/random' so that it doesn't close `stdin' if it fails! - * - * Revision 1.1 1997/08/07 09:45:26 mdw - * New source file added to acquire environmental noise and add it to the - * randomness pool (see `rand.c'). - * - */ - -/*----- Header files ------------------------------------------------------*/ - -/* --- ANSI headers --- */ - -#include -#include -#include -#include -#include -#include -#include - -/* --- Unix headers --- */ - -#include -#include - -#include "config.h" -#if defined(HAVE_GETRUSAGE) -# include -#elif defined(HAVE_VTIMES) -# include -#endif - -#include - -#include -#include - -/* --- Local headers --- */ - -#include "noise.h" -#include "rand.h" -#include "utils.h" - -/*----- Main code ---------------------------------------------------------*/ - -/* --- @noise__shell@ --- * - * - * Arguments: @const char *cmd@ = pointer to a shell command - * - * Returns: --- - * - * Use: Adds the output of the shell command to the randomness pool. - * Some care is taken to do the Right Thing when running setuid. - */ - -static void noise__shell(const char *cmd) -{ - int pfd[2]; - pid_t pid; - -#ifdef HAVE_SIGPROCMASK - sigset_t ob, nb; -#endif - - /* --- Create a pipe for talking to the child --- */ - - if (pipe(pfd)) - return; - - /* --- Sort out the signal handling for the parent --- * - * - * Block @SIGCHLD@ while this is going on. Unlike the standard @system@ - * function, I won't disable @SIGINT@ and @SIGQUIT@. Then, if the user - * stops the child with a terminal signal, the parent (i.e., me) gets - * killed too, and I don't end up with a tiny dribble of entropy when I'm - * expecting quite a lot. - */ - -#ifdef HAVE_SIGPROCMASK - sigemptyset(&nb); - sigaddset(&nb, SIGCHLD); - if (sigprocmask(SIG_BLOCK, &nb, &ob)) - goto fail_0; -#endif - - /* --- Create the child process --- */ - - pid = fork(); - if (pid < 0) - goto fail_1; - - if (pid == 0) { - int fd; - char *argv[] = { "/bin/sh", "-c", 0, 0 }; - char *env[] = { - "PATH=/bin:/usr/bin:/usr/ucb:/usr/etc:/sbin:/usr/sbin", - 0 - }; - - /* --- Restore signal handling things --- */ - -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_SETMASK, &nb, 0); -#endif - - /* --- Become nobody --- * - * - * This assumes that @-2@ is a safe user to be. It shouldn't be root, - * because it doesn't need to be, and nothing should be done as root - * which could be done as someone else. It shouldn't be the user who - * invoked me, because that would enable her to kill the children before - * I've read enough entropy from them, and that wouldn't be good. - */ - - setuid(-2); - - /* --- Close the old standard streams --- */ - - close(0); - close(1); - close(2); - - /* --- Set up stdin and stderr to be empty, and stdout as our pipe --- */ - - if (((fd = open("/dev/null", O_RDONLY)) != 0 && - (fd = dup2(fd, 0)) != 0) || - ((fd = dup2(pfd[1], 1)) != 1) || - ((fd = open("/dev/null", O_WRONLY)) != 2 && - (fd = dup2(fd, 2)) != 2)) - goto child_fail; - - /* --- Close the original pipe file descriptors --- */ - - close(pfd[0]); - close(pfd[1]); - burn(pfd); - - /* --- Now run the child process --- */ - - argv[2] = (char *)cmd; /* POSIX screwed up the prototype */ - execve("/bin/sh", argv, env); - - /* --- Something went horribly wrong --- */ - - child_fail: - _exit(127); - } - - /* --- Now read from the child until it's all done --- */ - - { - char buf[1024]; - ssize_t sz; - - close(pfd[1]); - for (;;) { - sz = read(pfd[0], buf, sizeof(buf)); - if (sz == 0 || (sz < 0 && sz != EINTR)) - break; - rand_add(buf, sz); - } - close(pfd[0]); - rand_add(pfd, sizeof(pfd)); - burn(buf); burn(pfd); - } - - /* --- The child should be dead now, so wait for it --- */ - - { - int st; - wait(&st); - rand_add(&st, sizeof(st)); - rand_add(&pid, sizeof(pid)); - } - - /* --- Restore signals --- */ - -fail_1: -#ifdef HAVE_SIGPROCMASK - sigprocmask(SIG_SETMASK, &ob, 0); -#endif -fail_0:; -} - -/* --- @noise_acquire@ --- * - * - * Arguments: --- - * - * Returns: --- - * - * Use: Attempts to acquire an amount of random noise from the - * environment. A lot of it's not actually much good, but - * it's better than nothing. There's probably a bit or two's - * worth in each item which gets added. - */ - -void noise_acquire(void) -{ - /* --- Try a real random number source --- * - * - * Some operating systems (notably Linux) provide a `/dev/random' which - * contains distilled random numbers from the outside world. - */ - - { - int fd; - int f; - unsigned char buff[64]; - ssize_t sz; - - if ((fd = open("/dev/random", O_RDONLY)) >= 0 && - (f = fcntl(fd, F_GETFL, 0)) >= 0 && - fcntl(fd, F_SETFL, f | O_NONBLOCK) >= 0 && - (sz = read(fd, buff, sizeof(buff))) > 0) { - rand_add(buff, sz); - burn(buff); - } - if (fd >= 0) - close(fd); - } - - /* --- Squeeze some entropy from the current time --- */ - - { - struct timeval tv; - clock_t c; - - gettimeofday(&tv, 0); - c = clock(); - rand_add(&tv, sizeof(tv)); - rand_add(&c, sizeof(c)); - burn(tv); burn(c); - } - - /* --- Try some commands which ask the outside world some questions --- */ - - noise__shell("ps auxww || ps -ef; netstat -an"); - - /* --- Get our resource usage to see if that's at all interesting --- */ - -#if defined(HAVE_GETRUSAGE) - { - struct rusage ru; - getrusage(RUSAGE_SELF, &ru); - rand_add(&ru, sizeof(ru)); - getrusage(RUSAGE_CHILDREN, &ru); - rand_add(&ru, sizeof(ru)); - burn(ru); - } -#elif defined(HAVE_VTIMES) - { - struct vtimes vt, vtc; - vtimes(&vt, &vtc); - rand_add(&vt, sizeof(vt)); - rand_add(&vtc, sizeof(vtc)); - burn(vt); burn(vtc); - } -#endif - - /* --- Squeeze some more entropy from the current time --- */ - - { - struct timeval tv; - clock_t c; - - gettimeofday(&tv, 0); - c = clock(); - rand_add(&tv, sizeof(tv)); - rand_add(&c, sizeof(c)); - burn(tv); burn(c); - } - - /* --- Done -- churn the random pool --- */ - - rand_churn(); -} - -/*----- That's all, folks -------------------------------------------------*/