]> git.ipfire.org Git - thirdparty/util-linux.git/blame - misc-utils/mcookie.c
textual: fix some typos and inconsistencies in various messages
[thirdparty/util-linux.git] / misc-utils / mcookie.c
CommitLineData
6dbe3af9
KZ
1/* mcookie.c -- Generates random numbers for xauth
2 * Created: Fri Feb 3 10:42:48 1995 by faith@cs.unc.edu
7eda085c
KZ
3 * Revised: Fri Mar 19 07:48:01 1999 by faith@acm.org
4 * Public Domain 1995, 1999 Rickard E. Faith (faith@acm.org)
6dbe3af9
KZ
5 * This program comes with ABSOLUTELY NO WARRANTY.
6 *
726f69e2
KZ
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
9 * use with xauth(1).
10 *
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.
7eda085c 14 *
b50945d4 15 * 1999-02-22 Arkadiusz Miƛkiewicz <misiek@pld.ORG.PL>
7eda085c
KZ
16 * - added Native Language Support
17 * 1999-03-21 aeb: Added some fragments of code from Colin Plumb.
18 *
6dbe3af9
KZ
19 */
20
e6ebab66
SK
21#include "c.h"
22#include "md5.h"
23#include "nls.h"
c05a80ca 24#include "closestream.h"
0720d60c 25#include "randutils.h"
f7bac573 26#include "strutils.h"
cdf0c325 27#include "xalloc.h"
f7bac573 28#include "all-io.h"
c05a80ca 29
e6ebab66
SK
30#include <fcntl.h>
31#include <getopt.h>
32#include <stddef.h>
6dbe3af9
KZ
33#include <stdio.h>
34#include <stdlib.h>
6dbe3af9
KZ
35#include <sys/time.h>
36#include <unistd.h>
6dbe3af9 37
0720d60c
SK
38enum {
39 BUFFERSIZE = 4096,
40 RAND_BYTES = 128
726f69e2 41};
726f69e2 42
46ae163a
SK
43struct mcookie_control {
44 struct MD5Context ctx;
45 char **files;
46 size_t nfiles;
f7bac573 47 uint64_t maxsz;
46ae163a
SK
48
49 unsigned int verbose:1;
50};
51
7eda085c 52/* The basic function to hash a file */
f7bac573 53static uint64_t hash_file(struct mcookie_control *ctl, int fd)
7eda085c 54{
e6ebab66 55 unsigned char buf[BUFFERSIZE];
f7bac573 56 uint64_t wanted, count;
e6ebab66 57
f7bac573
SK
58 wanted = ctl->maxsz ? ctl->maxsz : sizeof(buf);
59
60 for (count = 0; count < wanted; ) {
61 size_t rdsz = sizeof(buf);
62 ssize_t r;
63
64 if (wanted - count < rdsz)
65 rdsz = wanted - count;
66
67 r = read_all(fd, (char *) buf, rdsz);
68 if (r < 0)
69 break;
46ae163a 70 MD5Update(&ctl->ctx, buf, r);
e6ebab66
SK
71 count += r;
72 }
73 /* Separate files with a null byte */
74 buf[0] = '\0';
46ae163a 75 MD5Update(&ctl->ctx, buf, 1);
e6ebab66 76 return count;
7eda085c
KZ
77}
78
e40f84b9
SK
79static void __attribute__ ((__noreturn__)) usage(FILE * out)
80{
46ae163a
SK
81 fputs(USAGE_HEADER, out);
82 fprintf(out, _(" %s [options]\n"), program_invocation_short_name);
e40f84b9 83
46ae163a
SK
84 fputs(USAGE_OPTIONS, out);
85 fputs(_(" -f, --file <file> use file as a cookie seed\n"), out);
f7bac573 86 fputs(_(" -m, --max-size <num> limit how much is read from seed files\n"), out);
46ae163a
SK
87 fputs(_(" -v, --verbose explain what is being done\n"), out);
88
89 fputs(USAGE_SEPARATOR, out);
90 fputs(USAGE_HELP, out);
91 fputs(USAGE_VERSION, out);
92 fprintf(out, USAGE_MAN_TAIL("mcookie(1)"));
e40f84b9 93
e6ebab66 94 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
e40f84b9 95}
e6ebab66 96
46ae163a 97static void randomness_from_files(struct mcookie_control *ctl)
cdf0c325 98{
46ae163a
SK
99 size_t i;
100
101 for (i = 0; i < ctl->nfiles; i++) {
102 const char *fname = ctl->files[i];
103 size_t count;
104 int fd;
cdf0c325 105
46ae163a 106 if (*fname == '-' && !*(fname + 1))
cdf0c325
SK
107 fd = STDIN_FILENO;
108 else
46ae163a 109 fd = open(fname, O_RDONLY);
cdf0c325
SK
110
111 if (fd < 0) {
46ae163a 112 warn(_("cannot open %s"), fname);
cdf0c325 113 } else {
46ae163a
SK
114 count = hash_file(ctl, fd);
115 if (ctl->verbose)
cdf0c325 116 fprintf(stderr,
a3030b8a
SK
117 P_("Got %zu byte from %s\n",
118 "Got %zu bytes from %s\n", count),
46ae163a 119 count, fname);
cdf0c325
SK
120
121 if (fd != STDIN_FILENO)
122 if (close(fd))
123 err(EXIT_FAILURE,
46ae163a 124 _("closing %s failed"), fname);
cdf0c325
SK
125 }
126 }
127}
128
e6ebab66 129int main(int argc, char **argv)
6dbe3af9 130{
46ae163a 131 struct mcookie_control ctl = { .verbose = 0 };
e6ebab66 132 size_t i;
e429d141 133 unsigned char digest[MD5LENGTH];
0720d60c 134 unsigned char buf[RAND_BYTES];
e6ebab66 135 int c;
e6ebab66
SK
136
137 static const struct option longopts[] = {
138 {"file", required_argument, NULL, 'f'},
f7bac573 139 {"max-size", required_argument, NULL, 'm'},
e6ebab66
SK
140 {"verbose", no_argument, NULL, 'v'},
141 {"version", no_argument, NULL, 'V'},
142 {"help", no_argument, NULL, 'h'},
143 {NULL, 0, NULL, 0}
144 };
145
146 setlocale(LC_ALL, "");
147 bindtextdomain(PACKAGE, LOCALEDIR);
148 textdomain(PACKAGE);
c05a80ca 149 atexit(close_stdout);
e6ebab66 150
46ae163a
SK
151 if (2 < argc)
152 ctl.files = xmalloc(sizeof(char *) * argc);
cdf0c325 153
f7bac573 154 while ((c = getopt_long(argc, argv, "f:m:vVh", longopts, NULL)) != -1) {
e6ebab66
SK
155 switch (c) {
156 case 'v':
46ae163a 157 ctl.verbose = 1;
e6ebab66
SK
158 break;
159 case 'f':
46ae163a 160 ctl.files[ctl.nfiles++] = optarg;
e6ebab66 161 break;
f7bac573
SK
162 case 'm':
163 ctl.maxsz = strtosize_or_err(optarg,
164 _("failed to parse length"));
165 break;
e6ebab66 166 case 'V':
e421313d 167 printf(UTIL_LINUX_VERSION);
e6ebab66
SK
168 return EXIT_SUCCESS;
169 case 'h':
170 usage(stdout);
171 default:
172 usage(stderr);
173 }
46ae163a 174 }
e6ebab66 175
f7bac573 176 if (ctl.maxsz && ctl.nfiles == 0)
09af3db4 177 warnx(_("--max-size ignored when used without --file"));
f7bac573 178
46ae163a
SK
179 randomness_from_files(&ctl);
180 free(ctl.files);
e6ebab66 181
0720d60c 182 random_get_bytes(&buf, RAND_BYTES);
46ae163a
SK
183 MD5Update(&ctl.ctx, buf, RAND_BYTES);
184 if (ctl.verbose)
09af3db4
BS
185 fprintf(stderr, P_("Got %zu byte from %s\n",
186 "Got %zu bytes from %s\n", RAND_BYTES),
187 RAND_BYTES, random_tell_source());
e6ebab66 188
46ae163a 189 MD5Final(digest, &ctl.ctx);
e429d141 190 for (i = 0; i < MD5LENGTH; i++)
e6ebab66
SK
191 printf("%02x", digest[i]);
192 putchar('\n');
193
e6ebab66 194 return EXIT_SUCCESS;
6dbe3af9 195}