1 /* mcookie.c -- Generates random numbers for xauth
2 * Created: Fri Feb 3 10:42:48 1995 by faith@cs.unc.edu
3 * Revised: Fri Mar 19 07:48:01 1999 by faith@acm.org
4 * Public Domain 1995, 1999 Rickard E. Faith (faith@acm.org)
5 * This program comes with ABSOLUTELY NO WARRANTY.
7 * This program gathers some random bits of data and used the MD5
8 * message-digest algorithm to generate a 128-bit hexadecimal number for
11 * NOTE: Unless /dev/random is available, this program does not actually
12 * gather 128 bits of random information, so the magic cookie generated
13 * will be considerably easier to guess than one might expect.
15 * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
16 * - added Native Language Support
17 * 1999-03-21 aeb: Added some fragments of code from Colin Plumb.
29 #define BUFFERSIZE 4096
33 int minlength, maxlength;
35 { "/dev/random", 16, 16 }, /* 16 bytes = 128 bits suffice */
36 { "/proc/interrupts", 0, 0 },
37 { "/proc/slabinfo", 0, 0 },
38 { "/proc/stat", 0, 0 },
39 { "/dev/urandom", 32, 64 },
41 #define RNGS (sizeof(rngs)/sizeof(struct rngs))
45 /* The basic function to hash a file */
47 hash_file(struct MD5Context *ctx, int fd)
51 unsigned char buf[BUFFERSIZE];
53 while ((r = read(fd, buf, sizeof(buf))) > 0) {
54 MD5Update(ctx, buf, r);
57 /* Separate files with a null byte */
59 MD5Update(ctx, buf, 1);
63 int main( int argc, char **argv )
66 struct MD5Context ctx;
67 unsigned char digest[16];
68 unsigned char buf[BUFFERSIZE];
77 setlocale(LC_ALL, "");
78 bindtextdomain(PACKAGE, LOCALEDIR);
81 while ((c = getopt( argc, argv, "vf:" )) != -1)
83 case 'v': ++Verbose; break;
84 case 'f': file = optarg; break;
88 gettimeofday( &tv, &tz );
89 MD5Update( &ctx, (unsigned char *)&tv, sizeof( tv ) );
92 MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid ));
94 MD5Update( &ctx, (unsigned char *)&pid, sizeof( pid ));
99 if (file[0] == '-' && !file[1])
102 fd = open( file, O_RDONLY );
105 fprintf( stderr, _("Could not open %s\n"), file );
107 count = hash_file( &ctx, fd );
109 fprintf( stderr, _("Got %d bytes from %s\n"), count, file );
111 if (file[0] != '-' || file[1]) close( fd );
115 for (i = 0; i < RNGS; i++) {
116 if ((fd = open( rngs[i].path, O_RDONLY|O_NONBLOCK )) >= 0) {
117 int count = sizeof(buf);
119 if (rngs[i].maxlength && count > rngs[i].maxlength)
120 count = rngs[i].maxlength;
121 r = read( fd, buf, count );
123 MD5Update( &ctx, buf, r );
128 fprintf( stderr, _("Got %d bytes from %s\n"), r, rngs[i].path );
129 if (rngs[i].minlength && r >= rngs[i].minlength)
132 fprintf( stderr, _("Could not open %s\n"), rngs[i].path );
135 MD5Final( digest, &ctx );
136 for (i = 0; i < 16; i++) printf( "%02x", digest[i] );
140 * The following is important for cases like disk full, so shell scripts
141 * can bomb out properly rather than think they succeeded.
143 if (fflush(stdout) < 0 || fclose(stdout) < 0)