1 /* getrandom.c - Libgcrypt Random Number client
2 * Copyright (C) 2006 Free Software Foundation, Inc.
4 * Getrandom is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * Getrandom is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include <sys/types.h>
28 #include <sys/socket.h>
33 #define PGM "getrandom"
34 #define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
35 #define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
39 logit (const char *format, ...)
43 va_start (arg_ptr, format) ;
44 fputs (PGM ": ", stderr);
45 vfprintf (stderr, format, arg_ptr);
51 /* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
52 success or another value on write error. */
54 writen (int fd, const void *buffer, size_t length)
61 n = write (fd, buffer, length);
62 while (n < 0 && errno == EINTR);
65 logit ("write error: %s", strerror (errno));
66 return -1; /* write error */
69 buffer = (const char *)buffer + n;
78 print_version (int with_help)
80 fputs (MYVERSION_LINE "\n"
81 "Copyright (C) 2006 Free Software Foundation, Inc.\n"
82 "License GPLv2+: GNU GPL version 2 or later "
83 "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
84 "This is free software: you are free to change and redistribute it.\n"
85 "There is NO WARRANTY, to the extent permitted by law.\n",
90 "Usage: " PGM " [OPTIONS] NBYTES\n"
91 "Connect to libgcrypt's random number daemon and "
92 "return random numbers"
94 " --nonce Return weak random suitable for a nonce\n"
95 " --very-strong Return very strong random\n"
96 " --ping Send a ping\n"
97 " --socket NAME Name of sockket to connect to\n"
98 " --hex Return result as a hex dump\n"
99 " --verbose Show what we are doing\n"
100 " --version Print version of the program and exit\n"
101 " --help Display this help and exit\n"
102 BUGREPORT_LINE, stdout );
110 fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
111 fputs (" (use --help to display options)\n", stderr);
117 main (int argc, char **argv)
119 struct sockaddr_un *srvr_addr;
123 unsigned char buffer[300];
125 const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
128 int get_very_strong = 0;
129 int req_nbytes, nbytes, n;
138 while (argc && **argv == '-' && (*argv)[1] == '-')
145 else if (!strcmp (*argv, "--version"))
147 else if (!strcmp (*argv, "--help"))
149 else if (!strcmp (*argv, "--socket") && argc > 1 )
155 else if (!strcmp (*argv, "--nonce"))
160 else if (!strcmp (*argv, "--very-strong"))
165 else if (!strcmp (*argv, "--ping"))
170 else if (!strcmp (*argv, "--hex"))
175 else if (!strcmp (*argv, "--verbose"))
185 if (!argc && do_ping)
186 ; /* This is allowed. */
189 req_nbytes = argc? atoi (*argv) : 0;
194 /* Create a socket. */
195 fd = socket (AF_UNIX, SOCK_STREAM, 0);
198 logit ("can't create socket: %s", strerror (errno));
201 srvr_addr = malloc (sizeof *srvr_addr);
204 logit ("malloc failed: %s", strerror (errno));
207 memset (srvr_addr, 0, sizeof *srvr_addr);
208 srvr_addr->sun_family = AF_UNIX;
209 if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
211 logit ("socket name `%s' too long", socketname);
214 strcpy (srvr_addr->sun_path, socketname);
215 addrlen = (offsetof (struct sockaddr_un, sun_path)
216 + strlen (srvr_addr->sun_path) + 1);
217 rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen);
220 logit ("error connecting socket `%s': %s",
221 srvr_addr->sun_path, strerror (errno));
228 nbytes = req_nbytes > 255? 255 : req_nbytes;
229 req_nbytes -= nbytes;
236 else if (get_very_strong)
241 if (writen (fd, buffer, 3))
245 for (nleft=2, nread=0; nleft > 0; )
248 n = read (fd, buffer+nread, nleft);
249 while (n < 0 && errno == EINTR);
252 logit ("read error: %s", strerror (errno));
257 if (nread && buffer[0])
259 logit ("server returned error code %d", buffer[0]);
264 logit ("received response with %d bytes of data", buffer[1]);
265 if (buffer[1] < nbytes)
267 logit ("warning: server returned less bytes than requested");
270 else if (buffer[1] > nbytes && !do_ping)
272 logit ("warning: server returned more bytes than requested");
276 if (nbytes > sizeof buffer)
278 logit ("buffer too short to receive data");
282 for (nleft=nbytes, nread=0; nleft > 0; )
285 n = read (fd, buffer+nread, nleft);
286 while (n < 0 && errno == EINTR);
289 logit ("read error: %s", strerror (errno));
298 for (n=0; n < nbytes; n++)
306 printf ("%02X", buffer[n]);
313 if (fwrite (buffer, nbytes, 1, stdout) != 1)
315 logit ("error writing to stdout: %s", strerror (errno));
321 while (!fail && req_nbytes);