/* mcookie.c -- Generates random numbers for xauth
 * Created: Fri Feb  3 10:42:48 1995 by faith@cs.unc.edu
 * Revised: Fri Mar 19 07:48:01 1999 by faith@acm.org
 * Public Domain 1995, 1999 Rickard E. Faith (faith@acm.org)
 * This program comes with ABSOLUTELY NO WARRANTY.
 * 
 * This program gathers some random bits of data and used the MD5
 * message-digest algorithm to generate a 128-bit hexadecimal number for
 * use with xauth(1).
 *
 * NOTE: Unless /dev/random is available, this program does not actually
 * gather 128 bits of random information, so the magic cookie generated
 * will be considerably easier to guess than one might expect.
 *
 * 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL>
 * - added Native Language Support
 * 1999-03-21 aeb: Added some fragments of code from Colin Plumb.
 *
 */

#include "c.h"
#include "md5.h"
#include "nls.h"
#include "closestream.h"
#include "randutils.h"
#include "strutils.h"
#include "xalloc.h"
#include "all-io.h"

#include <fcntl.h>
#include <getopt.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>

enum {
	BUFFERSIZE = 4096,
	RAND_BYTES = 128
};

struct mcookie_control {
	struct	UL_MD5Context ctx;
	char	**files;
	size_t	nfiles;
	uint64_t maxsz;

	unsigned int verbose:1;
};

/* The basic function to hash a file */
static uint64_t hash_file(struct mcookie_control *ctl, int fd)
{
	unsigned char buf[BUFFERSIZE];
	uint64_t wanted, count;

	wanted = ctl->maxsz ? ctl->maxsz : sizeof(buf);

	for (count = 0; count < wanted; ) {
		size_t rdsz = sizeof(buf);
		ssize_t r;

		if (wanted - count < rdsz)
			rdsz = wanted - count;

		r = read_all(fd, (char *) buf, rdsz);
		if (r < 0)
			break;
		ul_MD5Update(&ctl->ctx, buf, r);
		count += r;
	}
	/* Separate files with a null byte */
	buf[0] = '\0';
	ul_MD5Update(&ctl->ctx, buf, 1);
	return count;
}

static void __attribute__((__noreturn__)) usage(void)
{
	FILE *out = stdout;
	fputs(USAGE_HEADER, out);
	fprintf(out, _(" %s [options]\n"), program_invocation_short_name);

	fputs(USAGE_SEPARATOR, out);
	fputs(_("Generate magic cookies for xauth.\n"), out);

	fputs(USAGE_OPTIONS, out);
	fputs(_(" -f, --file <file>     use file as a cookie seed\n"), out);
	fputs(_(" -m, --max-size <num>  limit how much is read from seed files\n"), out);
	fputs(_(" -v, --verbose         explain what is being done\n"), out);

	fputs(USAGE_SEPARATOR, out);
	printf(USAGE_HELP_OPTIONS(23));
	printf(USAGE_MAN_TAIL("mcookie(1)"));

	exit(EXIT_SUCCESS);
}

static void randomness_from_files(struct mcookie_control *ctl)
{
	size_t i;

	for (i = 0; i < ctl->nfiles; i++) {
		const char *fname = ctl->files[i];
		size_t count;
		int fd;

		if (*fname == '-' && !*(fname + 1))
			fd = STDIN_FILENO;
		else
			fd = open(fname, O_RDONLY);

		if (fd < 0) {
			warn(_("cannot open %s"), fname);
		} else {
			count = hash_file(ctl, fd);
			if (ctl->verbose)
				fprintf(stderr,
					P_("Got %zu byte from %s\n",
					   "Got %zu bytes from %s\n", count),
					count, fname);

			if (fd != STDIN_FILENO && close(fd))
				err(EXIT_FAILURE, _("closing %s failed"), fname);
		}
	}
}

int main(int argc, char **argv)
{
	struct mcookie_control ctl = { .verbose = 0 };
	size_t i;
	unsigned char digest[UL_MD5LENGTH];
	unsigned char buf[RAND_BYTES];
	int c;

	static const struct option longopts[] = {
		{"file", required_argument, NULL, 'f'},
		{"max-size", required_argument, NULL, 'm'},
		{"verbose", no_argument, NULL, 'v'},
		{"version", no_argument, NULL, 'V'},
		{"help", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while ((c = getopt_long(argc, argv, "f:m:vVh", longopts, NULL)) != -1) {
		switch (c) {
		case 'v':
			ctl.verbose = 1;
			break;
		case 'f':
			if (!ctl.files)
				ctl.files = xmalloc(sizeof(char *) * argc);
			ctl.files[ctl.nfiles++] = optarg;
			break;
		case 'm':
			ctl.maxsz = strtosize_or_err(optarg,
						     _("failed to parse length"));
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			usage();
		default:
			errtryhelp(EXIT_FAILURE);
		}
	}

	if (ctl.maxsz && ctl.nfiles == 0)
		warnx(_("--max-size ignored when used without --file"));

	ul_MD5Init(&ctl.ctx);
	randomness_from_files(&ctl);
	free(ctl.files);

	random_get_bytes(&buf, RAND_BYTES);
	ul_MD5Update(&ctl.ctx, buf, RAND_BYTES);
	if (ctl.verbose)
		fprintf(stderr, P_("Got %d byte from %s\n",
				   "Got %d bytes from %s\n", RAND_BYTES),
				RAND_BYTES, random_tell_source());

	ul_MD5Final(digest, &ctl.ctx);
	for (i = 0; i < UL_MD5LENGTH; i++)
		printf("%02x", digest[i]);
	putchar('\n');

	return EXIT_SUCCESS;
}
