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.
24 #include "closestream.h"
34 #define BUFFERSIZE 4096
38 int minlength
, maxlength
;
40 {"/dev/random", 16, 16}, /* 16 bytes = 128 bits suffice */
41 {"/proc/interrupts", 0, 0},
42 {"/proc/slabinfo", 0, 0},
44 {"/dev/urandom", 32, 64},
47 #define RNGS (sizeof(rngs)/sizeof(struct rngs))
49 /* The basic function to hash a file */
50 static off_t
hash_file(struct MD5Context
*ctx
, int fd
)
54 unsigned char buf
[BUFFERSIZE
];
56 while ((r
= read(fd
, buf
, sizeof(buf
))) > 0) {
57 MD5Update(ctx
, buf
, r
);
60 /* Separate files with a null byte */
62 MD5Update(ctx
, buf
, 1);
66 static void __attribute__ ((__noreturn__
)) usage(FILE * out
)
68 fputs(_("\nUsage:\n"), out
);
70 _(" %s [options]\n"), program_invocation_short_name
);
72 fputs(_("\nOptions:\n"), out
);
73 fputs(_(" -f, --file <file> use file as a cookie seed\n"
74 " -v, --verbose explain what is being done\n"
75 " -V, --version output version information and exit\n"
76 " -h, --help display this help and exit\n\n"), out
);
78 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
81 int main(int argc
, char **argv
)
84 struct MD5Context ctx
;
85 unsigned char digest
[MD5LENGTH
];
86 unsigned char buf
[BUFFERSIZE
];
96 static const struct option longopts
[] = {
97 {"file", required_argument
, NULL
, 'f'},
98 {"verbose", no_argument
, NULL
, 'v'},
99 {"version", no_argument
, NULL
, 'V'},
100 {"help", no_argument
, NULL
, 'h'},
104 setlocale(LC_ALL
, "");
105 bindtextdomain(PACKAGE
, LOCALEDIR
);
107 atexit(close_stdout
);
110 getopt_long(argc
, argv
, "f:vVh", longopts
, NULL
)) != -1)
119 printf(_("%s from %s\n"),
120 program_invocation_short_name
,
130 gettimeofday(&tv
, &tz
);
131 MD5Update(&ctx
, (unsigned char *) &tv
, sizeof(tv
));
134 MD5Update(&ctx
, (unsigned char *) &pid
, sizeof(pid
));
136 MD5Update(&ctx
, (unsigned char *) &pid
, sizeof(pid
));
141 if (file
[0] == '-' && !file
[1])
144 fd
= open(file
, O_RDONLY
);
147 warn(_("Could not open %s"), file
);
149 count
= hash_file(&ctx
, fd
);
152 _("Got %d bytes from %s\n"), count
,
155 if (fd
!= STDIN_FILENO
)
158 _("closing %s failed"), file
);
162 for (i
= 0; i
< RNGS
; i
++) {
163 if ((fd
= open(rngs
[i
].path
, O_RDONLY
| O_NONBLOCK
)) >= 0) {
164 int count
= sizeof(buf
);
166 if (rngs
[i
].maxlength
&& count
> rngs
[i
].maxlength
)
167 count
= rngs
[i
].maxlength
;
168 r
= read(fd
, buf
, count
);
170 MD5Update(&ctx
, buf
, r
);
176 _("Got %d bytes from %s\n"), r
,
178 if (rngs
[i
].minlength
&& r
>= rngs
[i
].minlength
)
181 warn(_("Could not open %s"), rngs
[i
].path
);
184 MD5Final(digest
, &ctx
);
185 for (i
= 0; i
< MD5LENGTH
; i
++)
186 printf("%02x", digest
[i
]);