#include #include #include #include #include #include #include #include #include #include "rnd.h" #include "cmdline.h" #include "alg-util.h" #define POOL_SIZE 512 #define POOL_RESERVE 128 extern const char *__progname; static const char *rnddev = "/dev/urandom"; #if POOL_SIZE % 16 #error "Code needs a rethink if POOL_SIZE isn't a multiple of MD5 hash size" #endif static int rndfd = -1; static int poolfd = -1; static unsigned char pool[POOL_SIZE]; static int poolhand; static int stirs = 0; static void stir_pool(void) { int o; void *h; unsigned char res[16]; if (rndfd >= 0) { read(rndfd,&res[0],1); pool[0] ^= res[0]; } for (o=0;o0;len--) { pool[poolhand++] = *dp++; if (poolhand >= POOL_SIZE) stir_pool(); } } static void mixin_command_output(const char *cmd) { int p[2]; pid_t kid; char obuf[512]; int n; if (pipe(p) < 0) { fprintf(stderr,"%s: pipe: %s\n",__progname,strerror(errno)); exit(1); } kid = fork(); if (kid < 0) { fprintf(stderr,"%s: fork: %s\n",__progname,strerror(errno)); exit(1); } if (kid == 0) { close(p[0]); if (p[1] != 1) { dup2(p[1],1); close(p[1]); } dup2(1,2); dup2(1,0); execl("/bin/sh","sh","-c",cmd,(char *)0); _exit(1); } close(p[1]); while (1) { n = read(p[0],&obuf[0],sizeof(obuf)); if (n < 0) { if (errno == EINTR) continue; fprintf(stderr,"%s: read: %s\n",__progname,strerror(errno)); exit(1); } if (n == 0) break; mixin_data(&obuf[0],n); } close(p[0]); wait4(kid,0,0,0); } static void new_pool(void) { if (rndfd < 0) { struct timeval now; mixin_command_output("/bin/ps awwlx"); mixin_command_output("/bin/ls -l / /tmp"); gettimeofday(&now,0); mixin_data(&now,sizeof(struct timeval)); } else { read(rndfd,&pool[0],128); } stir_pool(); } static void load_pool(void) { int n; n = pread(poolfd,&pool[0],POOL_SIZE,0); if (n != POOL_SIZE) { new_pool(); } else { if (rndfd >= 0) { char rbuf[4]; read(rndfd,&rbuf[0],4); mixin_data(&rbuf[0],4); } stir_pool(); } } static void save_pool(void) { char new[POOL_SIZE]; int o; void *h; for (o=0;o0;len--) { *bp++ = pool[poolhand++]; if (poolhand >= POOL_SIZE) stir_pool(); } }