/*
 * Copyright (c) 2001-2002 Damien Miller.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "includes.h"

#include <openssl/rand.h>
#include <openssl/sha.h>
#include <openssl/crypto.h>

/* SunOS 4.4.4 needs this */
#ifdef HAVE_FLOATINGPOINT_H
# include <floatingpoint.h>
#endif /* HAVE_FLOATINGPOINT_H */

#include "misc.h"
#include "xmalloc.h"
#include "atomicio.h"
#include "pathnames.h"
#include "log.h"

RCSID("$Id: ssh-rand-helper.c,v 1.9 2002/10/21 00:13:37 djm Exp $");

/* Number of bytes we write out */
#define OUTPUT_SEED_SIZE	48

/* Length of on-disk seedfiles */
#define SEED_FILE_SIZE		1024

/* Maximum number of command-line arguments to read from file */
#define NUM_ARGS		10

/* Minimum number of usable commands to be considered sufficient */
#define MIN_ENTROPY_SOURCES	16

/* Path to on-disk seed file (relative to user's home directory */
#ifndef SSH_PRNG_SEED_FILE
# define SSH_PRNG_SEED_FILE      _PATH_SSH_USER_DIR"/prng_seed"
#endif

/* Path to PRNG commands list */
#ifndef SSH_PRNG_COMMAND_FILE
# define SSH_PRNG_COMMAND_FILE   SSHDIR "/ssh_prng_cmds"
#endif

#ifdef HAVE___PROGNAME
extern char *__progname;
#else
char *__progname;
#endif

#ifndef offsetof
# define offsetof(type, member) ((size_t) &((type *)0)->member)
#endif

#define WHITESPACE " \t\n"

#ifndef RUSAGE_SELF
# define RUSAGE_SELF 0
#endif
#ifndef RUSAGE_CHILDREN
# define RUSAGE_CHILDREN 0
#endif

#if !defined(PRNGD_SOCKET) && !defined(PRNGD_PORT)
# define USE_SEED_FILES
#endif

typedef struct {
	/* Proportion of data that is entropy */
	double rate;
	/* Counter goes positive if this command times out */
	unsigned int badness;
	/* Increases by factor of two each timeout */
	unsigned int sticky_badness;
	/* Path to executable */
	char *path;
	/* argv to pass to executable */
	char *args[NUM_ARGS]; /* XXX: arbitrary limit */
	/* full command string (debug) */
	char *cmdstring;
} entropy_cmd_t;

/* slow command timeouts (all in milliseconds) */
/* static int entropy_timeout_default = ENTROPY_TIMEOUT_MSEC; */
static int entropy_timeout_current = ENTROPY_TIMEOUT_MSEC;

/* this is initialised from a file, by prng_read_commands() */
static entropy_cmd_t *entropy_cmds = NULL;

/* Prototypes */
double stir_from_system(void);
double stir_from_programs(void);
double stir_gettimeofday(double entropy_estimate);
double stir_clock(double entropy_estimate);
double stir_rusage(int who, double entropy_estimate);
double hash_command_output(entropy_cmd_t *src, unsigned char *hash);
int get_random_bytes_prngd(unsigned char *buf, int len, 
    unsigned short tcp_port, char *socket_path);

/*
 * Collect 'len' bytes of entropy into 'buf' from PRNGD/EGD daemon
 * listening either on 'tcp_port', or via Unix domain socket at *
 * 'socket_path'.
 * Either a non-zero tcp_port or a non-null socket_path must be 
 * supplied.
 * Returns 0 on success, -1 on error
 */
int
get_random_bytes_prngd(unsigned char *buf, int len, 
    unsigned short tcp_port, char *socket_path)
{
	int fd, addr_len, rval, errors;
	char msg[2];
	struct sockaddr_storage addr;
	struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
	struct sockaddr_un *addr_un = (struct sockaddr_un *)&addr;
	mysig_t old_sigpipe;

	/* Sanity checks */
	if (socket_path == NULL && tcp_port == 0)
		fatal("You must specify a port or a socket");
	if (socket_path != NULL &&
	    strlen(socket_path) >= sizeof(addr_un->sun_path))
		fatal("Random pool path is too long");
	if (len > 255)
		fatal("Too many bytes to read from PRNGD");

	memset(&addr, '\0', sizeof(addr));

	if (tcp_port != 0) {
		addr_in->sin_family = AF_INET;
		addr_in->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		addr_in->sin_port = htons(tcp_port);
		addr_len = sizeof(*addr_in);
	} else {
		addr_un->sun_family = AF_UNIX;
		strlcpy(addr_un->sun_path, socket_path,
		    sizeof(addr_un->sun_path));
		addr_len = offsetof(struct sockaddr_un, sun_path) +
		    strlen(socket_path) + 1;
	}

	old_sigpipe = mysignal(SIGPIPE, SIG_IGN);

	errors = 0;
	rval = -1;
reopen:
	fd = socket(addr.ss_family, SOCK_STREAM, 0);
	if (fd == -1) {
		error("Couldn't create socket: %s", strerror(errno));
		goto done;
	}

	if (connect(fd, (struct sockaddr*)&addr, addr_len) == -1) {
		if (tcp_port != 0) {
			error("Couldn't connect to PRNGD port %d: %s",
			    tcp_port, strerror(errno));
		} else {
			error("Couldn't connect to PRNGD socket \"%s\": %s",
			    addr_un->sun_path, strerror(errno));
		}
		goto done;
	}

	/* Send blocking read request to PRNGD */
	msg[0] = 0x02;
	msg[1] = len;

	if (atomicio(write, fd, msg, sizeof(msg)) != sizeof(msg)) {
		if (errno == EPIPE && errors < 10) {
			close(fd);
			errors++;
			goto reopen;
		}
		error("Couldn't write to PRNGD socket: %s",
		    strerror(errno));
		goto done;
	}

	if (atomicio(read, fd, buf, len) != len) {
		if (errno == EPIPE && errors < 10) {
			close(fd);
			errors++;
			goto reopen;
		}
		error("Couldn't read from PRNGD socket: %s",
		    strerror(errno));
		goto done;
	}

	rval = 0;
done:
	mysignal(SIGPIPE, old_sigpipe);
	if (fd != -1)
		close(fd);
	return rval;
}

double
stir_gettimeofday(double entropy_estimate)
{
	struct timeval tv;

	if (gettimeofday(&tv, NULL) == -1)
		fatal("Couldn't gettimeofday: %s", strerror(errno));

	RAND_add(&tv, sizeof(tv), entropy_estimate);

	return entropy_estimate;
}

double
stir_clock(double entropy_estimate)
{
#ifdef HAVE_CLOCK
	clock_t c;

	c = clock();
	RAND_add(&c, sizeof(c), entropy_estimate);

	return entropy_estimate;
#else /* _HAVE_CLOCK */
	return 0;
#endif /* _HAVE_CLOCK */
}

double
stir_rusage(int who, double entropy_estimate)
{
#ifdef HAVE_GETRUSAGE
	struct rusage ru;

	if (getrusage(who, &ru) == -1)
		return 0;

	RAND_add(&ru, sizeof(ru), entropy_estimate);

	return entropy_estimate;
#else /* _HAVE_GETRUSAGE */
	return 0;
#endif /* _HAVE_GETRUSAGE */
}

static int
timeval_diff(struct timeval *t1, struct timeval *t2)
{
	int secdiff, usecdiff;

	secdiff = t2->tv_sec - t1->tv_sec;
	usecdiff = (secdiff*1000000) + (t2->tv_usec - t1->tv_usec);
	return (int)(usecdiff / 1000);
}

double
hash_command_output(entropy_cmd_t *src, unsigned char *hash)
{
	char buf[8192];
	fd_set rdset;
	int bytes_read, cmd_eof, error_abort, msec_elapsed, p[2];
	int status, total_bytes_read;
	static int devnull = -1;
	pid_t pid;
	SHA_CTX sha;
	struct timeval tv_start, tv_current;

	debug3("Reading output from \'%s\'", src->cmdstring);

	if (devnull == -1) {
		devnull = open("/dev/null", O_RDWR);
		if (devnull == -1)
			fatal("Couldn't open /dev/null: %s", 
			    strerror(errno));
	}

	if (pipe(p) == -1)
		fatal("Couldn't open pipe: %s", strerror(errno));

	(void)gettimeofday(&tv_start, NULL); /* record start time */

	switch (pid = fork()) {
		case -1: /* Error */
			close(p[0]);
			close(p[1]);
			fatal("Couldn't fork: %s", strerror(errno));
			/* NOTREACHED */
		case 0: /* Child */
			dup2(devnull, STDIN_FILENO);
			dup2(p[1], STDOUT_FILENO);
			dup2(p[1], STDERR_FILENO);
			close(p[0]);
			close(p[1]);
			close(devnull);

			execv(src->path, (char**)(src->args));

			debug("(child) Couldn't exec '%s': %s", 
			    src->cmdstring, strerror(errno));
			_exit(-1);
		default: /* Parent */
			break;
	}

	RAND_add(&pid, sizeof(&pid), 0.0);

	close(p[1]);

	/* Hash output from child */
	SHA1_Init(&sha);

	cmd_eof = error_abort = msec_elapsed = total_bytes_read = 0;
	while (!error_abort && !cmd_eof) {
		int ret;
		struct timeval tv;
		int msec_remaining;

		(void) gettimeofday(&tv_current, 0);
		msec_elapsed = timeval_diff(&tv_start, &tv_current);
		if (msec_elapsed >= entropy_timeout_current) {
			error_abort=1;
			continue;
		}
		msec_remaining = entropy_timeout_current - msec_elapsed;

		FD_ZERO(&rdset);
		FD_SET(p[0], &rdset);
		tv.tv_sec = msec_remaining / 1000;
		tv.tv_usec = (msec_remaining % 1000) * 1000;

		ret = select(p[0] + 1, &rdset, NULL, NULL, &tv);

		RAND_add(&tv, sizeof(tv), 0.0);

		switch (ret) {
		case 0:
			/* timer expired */
			error_abort = 1;
			kill(pid, SIGINT);
			break;
		case 1:
			/* command input */
			do {
				bytes_read = read(p[0], buf, sizeof(buf));
			} while (bytes_read == -1 && errno == EINTR);
			RAND_add(&bytes_read, sizeof(&bytes_read), 0.0);
			if (bytes_read == -1) {
				error_abort = 1;
				break;
			} else if (bytes_read) {
				SHA1_Update(&sha, buf, bytes_read);
				total_bytes_read += bytes_read;
			} else {
				cmd_eof = 1;
			}
			break;
		case -1:
		default:
			/* error */
			debug("Command '%s': select() failed: %s", 
			    src->cmdstring, strerror(errno));
			error_abort = 1;
			break;
		}
	}

	SHA1_Final(hash, &sha);

	close(p[0]);

	debug3("Time elapsed: %d msec", msec_elapsed);

	if (waitpid(pid, &status, 0) == -1) {
	       error("Couldn't wait for child '%s' completion: %s",
		   src->cmdstring, strerror(errno));
		return 0.0;
	}

	RAND_add(&status, sizeof(&status), 0.0);

	if (error_abort) {
		/*
		 * Closing p[0] on timeout causes the entropy command to
		 * SIGPIPE. Take whatever output we got, and mark this 
		 * command as slow 
		 */
		debug2("Command '%s' timed out", src->cmdstring);
		src->sticky_badness *= 2;
		src->badness = src->sticky_badness;
		return total_bytes_read;
	}

	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status) == 0) {
			return total_bytes_read;
		} else {
			debug2("Command '%s' exit status was %d",
			    src->cmdstring, WEXITSTATUS(status));
			src->badness = src->sticky_badness = 128;
			return 0.0;
		}
	} else if (WIFSIGNALED(status)) {
		debug2("Command '%s' returned on uncaught signal %d !",
		    src->cmdstring, status);
		src->badness = src->sticky_badness = 128;
		return 0.0;
	} else
		return 0.0;
}

double
stir_from_system(void)
{
	double total_entropy_estimate;
	long int i;

	total_entropy_estimate = 0;

	i = getpid();
	RAND_add(&i, sizeof(i), 0.5);
	total_entropy_estimate += 0.1;

	i = getppid();
	RAND_add(&i, sizeof(i), 0.5);
	total_entropy_estimate += 0.1;

	i = getuid();
	RAND_add(&i, sizeof(i), 0.0);
	i = getgid();
	RAND_add(&i, sizeof(i), 0.0);

	total_entropy_estimate += stir_gettimeofday(1.0);
	total_entropy_estimate += stir_clock(0.5);
	total_entropy_estimate += stir_rusage(RUSAGE_SELF, 2.0);

	return total_entropy_estimate;
}

double
stir_from_programs(void)
{
	int c;
	double entropy, total_entropy;
	unsigned char hash[SHA_DIGEST_LENGTH];

	total_entropy = 0;
	for(c = 0; entropy_cmds[c].path != NULL; c++) {
		if (!entropy_cmds[c].badness) {
			/* Hash output from command */
			entropy = hash_command_output(&entropy_cmds[c],
			    hash);

			/* Scale back estimate by command's rate */
			entropy *= entropy_cmds[c].rate;

			/* Upper bound of entropy is SHA_DIGEST_LENGTH */
			if (entropy > SHA_DIGEST_LENGTH)
				entropy = SHA_DIGEST_LENGTH;

			/* Stir it in */
			RAND_add(hash, sizeof(hash), entropy);

			debug3("Got %0.2f bytes of entropy from '%s'", 
			    entropy, entropy_cmds[c].cmdstring);

			total_entropy += entropy;

			/* Execution time should be a bit unpredictable */
			total_entropy += stir_gettimeofday(0.05);
			total_entropy += stir_clock(0.05);
			total_entropy += stir_rusage(RUSAGE_SELF, 0.1);
			total_entropy += stir_rusage(RUSAGE_CHILDREN, 0.1);
		} else {
			debug2("Command '%s' disabled (badness %d)",
			    entropy_cmds[c].cmdstring, 
			    entropy_cmds[c].badness);

			if (entropy_cmds[c].badness > 0)
				entropy_cmds[c].badness--;
		}
	}

	return total_entropy;
}

/*
 * prng seedfile functions
 */
int
prng_check_seedfile(char *filename)
{
	struct stat st;

	/*
	 * XXX raceable: eg replace seed between this stat and subsequent 
	 * open. Not such a problem because we don't really trust the 
	 * seed file anyway.
	 * XXX: use secure path checking as elsewhere in OpenSSH
	 */
	if (lstat(filename, &st) == -1) {
		/* Give up on hard errors */
		if (errno != ENOENT)
			debug("WARNING: Couldn't stat random seed file "
			    "\"%.100s\": %s", filename, strerror(errno));
		return 0;
	}

	/* regular file? */
	if (!S_ISREG(st.st_mode))
		fatal("PRNG seedfile %.100s is not a regular file",
		    filename);

	/* mode 0600, owned by root or the current user? */
	if (((st.st_mode & 0177) != 0) || !(st.st_uid == getuid())) {
		debug("WARNING: PRNG seedfile %.100s must be mode 0600, "
		    "owned by uid %d", filename, getuid());
		return 0;
	}

	return 1;
}

void
prng_write_seedfile(void)
{
	int fd;
	unsigned char seed[SEED_FILE_SIZE];
	char filename[MAXPATHLEN];
	struct passwd *pw;

	pw = getpwuid(getuid());
	if (pw == NULL)
		fatal("Couldn't get password entry for current user "
		    "(%i): %s", getuid(), strerror(errno));

	/* Try to ensure that the parent directory is there */
	snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
	    _PATH_SSH_USER_DIR);
	mkdir(filename, 0700);

	snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
	    SSH_PRNG_SEED_FILE);

	debug("writing PRNG seed to file %.100s", filename);

	RAND_bytes(seed, sizeof(seed));

	/* Don't care if the seed doesn't exist */
	prng_check_seedfile(filename);

	if ((fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0600)) == -1) {
		debug("WARNING: couldn't access PRNG seedfile %.100s "
		    "(%.100s)", filename, strerror(errno));
	} else {
		if (atomicio(write, fd, &seed, sizeof(seed)) < sizeof(seed))
			fatal("problem writing PRNG seedfile %.100s "
			    "(%.100s)", filename, strerror(errno));
		close(fd);
	}
}

void
prng_read_seedfile(void)
{
	int fd;
	char seed[SEED_FILE_SIZE], filename[MAXPATHLEN];
	struct passwd *pw;

	pw = getpwuid(getuid());
	if (pw == NULL)
		fatal("Couldn't get password entry for current user "
		    "(%i): %s", getuid(), strerror(errno));

	snprintf(filename, sizeof(filename), "%.512s/%s", pw->pw_dir,
		SSH_PRNG_SEED_FILE);

	debug("loading PRNG seed from file %.100s", filename);

	if (!prng_check_seedfile(filename)) {
		verbose("Random seed file not found or invalid, ignoring.");
		return;
	}

	/* open the file and read in the seed */
	fd = open(filename, O_RDONLY);
	if (fd == -1)
		fatal("could not open PRNG seedfile %.100s (%.100s)",
		    filename, strerror(errno));

	if (atomicio(read, fd, &seed, sizeof(seed)) < sizeof(seed)) {
		verbose("invalid or short read from PRNG seedfile "
		    "%.100s - ignoring", filename);
		memset(seed, '\0', sizeof(seed));
	}
	close(fd);

	/* stir in the seed, with estimated entropy zero */
	RAND_add(&seed, sizeof(seed), 0.0);
}


/*
 * entropy command initialisation functions
 */
int
prng_read_commands(char *cmdfilename)
{
	char cmd[SEED_FILE_SIZE], *cp, line[1024], path[SEED_FILE_SIZE];
	double est;
	entropy_cmd_t *entcmd;
	FILE *f;
	int cur_cmd, linenum, num_cmds, arg;

	if ((f = fopen(cmdfilename, "r")) == NULL) {
		fatal("couldn't read entropy commands file %.100s: %.100s",
		    cmdfilename, strerror(errno));
	}

	num_cmds = 64;
	entcmd = xmalloc(num_cmds * sizeof(entropy_cmd_t));
	memset(entcmd, '\0', num_cmds * sizeof(entropy_cmd_t));

	/* Read in file */
	cur_cmd = linenum = 0;
	while (fgets(line, sizeof(line), f)) {
		linenum++;

		/* Skip leading whitespace, blank lines and comments */
		cp = line + strspn(line, WHITESPACE);
		if ((*cp == 0) || (*cp == '#'))
			continue; /* done with this line */

		/*
		 * The first non-whitespace char should be a double quote 
		 * delimiting the commandline
		 */
		if (*cp != '"') {
			error("bad entropy command, %.100s line %d",
			    cmdfilename, linenum);
			continue;
		}

		/*
		 * First token, command args (incl. argv[0]) in double
		 * quotes
		 */
		cp = strtok(cp, "\"");
		if (cp == NULL) {
			error("missing or bad command string, %.100s "
			    "line %d -- ignored", cmdfilename, linenum);
			continue;
		}
		strlcpy(cmd, cp, sizeof(cmd));

		/* Second token, full command path */
		if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
			error("missing command path, %.100s "
			    "line %d -- ignored", cmdfilename, linenum);
			continue;
		}

		/* Did configure mark this as dead? */
		if (strncmp("undef", cp, 5) == 0)
			continue;

		strlcpy(path, cp, sizeof(path));

		/* Third token, entropy rate estimate for this command */
		if ((cp = strtok(NULL, WHITESPACE)) == NULL) {
			error("missing entropy estimate, %.100s "
			    "line %d -- ignored", cmdfilename, linenum);
			continue;
		}
		est = strtod(cp, NULL);

		/* end of line */
		if ((cp = strtok(NULL, WHITESPACE)) != NULL) {
			error("garbage at end of line %d in %.100s "
			    "-- ignored", linenum, cmdfilename);
			continue;
		}

		/* save the command for debug messages */
		entcmd[cur_cmd].cmdstring = xstrdup(cmd);

		/* split the command args */
		cp = strtok(cmd, WHITESPACE);
		arg = 0;
		do {
			entcmd[cur_cmd].args[arg] = xstrdup(cp);
			arg++;
		} while(arg < NUM_ARGS && (cp = strtok(NULL, WHITESPACE)));

		if (strtok(NULL, WHITESPACE))
			error("ignored extra commands (max %d), %.100s "
			    "line %d", NUM_ARGS, cmdfilename, linenum);

		/* Copy the command path and rate estimate */
		entcmd[cur_cmd].path = xstrdup(path);
		entcmd[cur_cmd].rate = est;

		/* Initialise other values */
		entcmd[cur_cmd].sticky_badness = 1;

		cur_cmd++;

		/*
		 * If we've filled the array, reallocate it twice the size
		 * Do this now because even if this we're on the last 
		 * command we need another slot to mark the last entry
		 */
		if (cur_cmd == num_cmds) {
			num_cmds *= 2;
			entcmd = xrealloc(entcmd, num_cmds *
			    sizeof(entropy_cmd_t));
		}
	}

	/* zero the last entry */
	memset(&entcmd[cur_cmd], '\0', sizeof(entropy_cmd_t));

	/* trim to size */
	entropy_cmds = xrealloc(entcmd, (cur_cmd + 1) *
	    sizeof(entropy_cmd_t));

	debug("Loaded %d entropy commands from %.100s", cur_cmd,
	    cmdfilename);

	return cur_cmd < MIN_ENTROPY_SOURCES ? -1 : 0;
}

void
usage(void)
{
	fprintf(stderr, "Usage: %s [options]\n", __progname);
	fprintf(stderr, "  -v          Verbose; display verbose debugging messages.\n");
	fprintf(stderr, "              Multiple -v increases verbosity.\n");
	fprintf(stderr, "  -x          Force output in hexidecimal (for debugging)\n");
	fprintf(stderr, "  -X          Force output in binary\n");
	fprintf(stderr, "  -b bytes    Number of bytes to output (default %d)\n",
	    OUTPUT_SEED_SIZE);
}

int 
main(int argc, char **argv)
{
	unsigned char *buf;
	int ret, ch, debug_level, output_hex, bytes;
	extern char *optarg;
	LogLevel ll;

	__progname = get_progname(argv[0]);
	log_init(argv[0], SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_USER, 1);

	ll = SYSLOG_LEVEL_INFO;
	debug_level = output_hex = 0;
	bytes = OUTPUT_SEED_SIZE;

	/* Don't write binary data to a tty, unless we are forced to */
	if (isatty(STDOUT_FILENO))
		output_hex = 1;
	
	while ((ch = getopt(argc, argv, "vxXhb:")) != -1) {
		switch (ch) {
		case 'v':
			if (debug_level < 3)
				ll = SYSLOG_LEVEL_DEBUG1 + debug_level++;
			break;
		case 'x':
			output_hex = 1;
			break;
		case 'X':
			output_hex = 0;
			break;
		case 'b':
			if ((bytes = atoi(optarg)) <= 0)
				fatal("Invalid number of output bytes");
			break;
		case 'h':
			usage();
			exit(0);
		default:
			error("Invalid commandline option");
			usage();
		}
	}

	log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
	
#ifdef USE_SEED_FILES
	prng_read_seedfile();
#endif

	buf = xmalloc(bytes);

	/*
	 * Seed the RNG from wherever we can
	 */
	 
	/* Take whatever is on the stack, but don't credit it */
	RAND_add(buf, bytes, 0);

	debug("Seeded RNG with %i bytes from system calls", 
	    (int)stir_from_system());

#ifdef PRNGD_PORT
	if (get_random_bytes_prngd(buf, bytes, PRNGD_PORT, NULL) == -1)
		fatal("Entropy collection failed");
	RAND_add(buf, bytes, bytes);
#elif defined(PRNGD_SOCKET)
	if (get_random_bytes_prngd(buf, bytes, 0, PRNGD_SOCKET) == -1)
		fatal("Entropy collection failed");
	RAND_add(buf, bytes, bytes);
#else
	/* Read in collection commands */
	if (prng_read_commands(SSH_PRNG_COMMAND_FILE) == -1)
		fatal("PRNG initialisation failed -- exiting.");
	debug("Seeded RNG with %i bytes from programs", 
	    (int)stir_from_programs());
#endif

#ifdef USE_SEED_FILES
	prng_write_seedfile();
#endif

	/*
	 * Write the seed to stdout
	 */

	if (!RAND_status())
		fatal("Not enough entropy in RNG");

	RAND_bytes(buf, bytes);

	if (output_hex) {
		for(ret = 0; ret < bytes; ret++)
			printf("%02x", (unsigned char)(buf[ret]));
		printf("\n");
	} else
		ret = atomicio(write, STDOUT_FILENO, buf, bytes);
		
	memset(buf, '\0', bytes);
	xfree(buf);
	
	return ret == bytes ? 0 : 1;
}
