summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2022-02-02 11:44:35 +0900
committerNIIBE Yutaka <gniibe@fsij.org>2022-02-02 11:44:35 +0900
commitd918d8aee27987c3bb99f44a7ed3508d81009f51 (patch)
tree14cecf4b4bd2ac68b41bf58730a0c50672cbf8f8 /src
parentdd99ef53d9ee6e503ce288fca853cf4e237ec09e (diff)
downloadlibgcrypt-d918d8aee27987c3bb99f44a7ed3508d81009f51.tar.gz
Remove random-daemon server and util.
* configure.ac (--enable-random-daemon): Remove. * src/Makefile.am: Remove ENABLE_RANDOM_DAEMON things. * src/gcryptrnd.c, src/getrandom.c: Remove. -- GnuPG-bug-id: 5811 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am12
-rw-r--r--src/gcryptrnd.c680
-rw-r--r--src/getrandom.c326
3 files changed, 0 insertions, 1018 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index d2118f6b..018d5761 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,10 +33,6 @@ nodist_include_HEADERS = gcrypt.h
lib_LTLIBRARIES = libgcrypt.la
bin_PROGRAMS = dumpsexp hmac256 mpicalc
-if ENABLE_RANDOM_DAEMON
-sbin_PROGRAMS = gcryptrnd
-bin_PROGRAMS += getrandom
-endif ENABLE_RANDOM_DAEMON
# Depending on the architecture some targets require libgpg-error.
if HAVE_W32CE_SYSTEM
@@ -142,14 +138,6 @@ hmac256_CFLAGS = -DSTANDALONE @DEF_HMAC_BINARY_CHECK@ \
$(arch_gpg_error_cflags)
hmac256_LDADD = $(arch_gpg_error_libs)
-if ENABLE_RANDOM_DAEMON
-gcryptrnd_SOURCES = gcryptrnd.c
-gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
-gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
-
-getrandom_SOURCES = getrandom.c
-endif ENABLE_RANDOM_DAEMON
-
CLEANFILES = libgcrypt.la.done
if USE_HMAC_BINARY_CHECK
CLEANFILES += libgcrypt.so.hmac
diff --git a/src/gcryptrnd.c b/src/gcryptrnd.c
deleted file mode 100644
index b13931b6..00000000
--- a/src/gcryptrnd.c
+++ /dev/null
@@ -1,680 +0,0 @@
-/* gcryptrnd.c - Libgcrypt Random Number Daemon
- * Copyright (C) 2006 Free Software Foundation, Inc.
- *
- * Gcryptend is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * Gcryptrnd is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-/* We require vsyslog pth
- We need to test for: setrlimit
-
- We should also prioritize requests. This is best done by putting
- the requests into queues and have a main thread processing these
- queues.
-
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <time.h>
-#include <sys/times.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <errno.h>
-#include <pth.h>
-#include <gcrypt.h>
-
-#define PGM "gcryptrnd"
-#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
-#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
-
-/* Pth wrapper function definitions. */
-GCRY_THREAD_OPTION_PTH_IMPL;
-
-
-/* Flag set to true if we have been daemonized. */
-static int running_detached;
-/* Flag indicating that a shutdown has been requested. */
-static int shutdown_pending;
-/* Counter for active connections. */
-static int active_connections;
-
-
-
-/* Local prototypes. */
-static void serve (int listen_fd);
-
-
-
-
-
-/* To avoid that a compiler optimizes certain memset calls away, these
- macros may be used instead. */
-#define wipememory2(_ptr,_set,_len) do { \
- volatile char *_vptr=(volatile char *)(_ptr); \
- size_t _vlen=(_len); \
- while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
- } while(0)
-#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
-
-
-
-
-/* Error printing utility. PRIORITY should be one of syslog's
- priority levels. This functions prints to the stderr or syslog
- depending on whether we are already daemonized. */
-static void
-logit (int priority, const char *format, ...)
-{
- va_list arg_ptr;
-
- va_start (arg_ptr, format) ;
- if (running_detached)
- {
- vsyslog (priority, format, arg_ptr);
- }
- else
- {
- fputs (PGM ": ", stderr);
- vfprintf (stderr, format, arg_ptr);
- putc ('\n', stderr);
- }
- va_end (arg_ptr);
-}
-
-/* Callback used by libgcrypt for logging. */
-static void
-my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
-{
- (void)dummy;
-
- /* Map the log levels. */
- switch (level)
- {
- case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break;
- case GCRY_LOG_INFO: level = LOG_INFO; break;
- case GCRY_LOG_WARN: level = LOG_WARNING; break;
- case GCRY_LOG_ERROR:level = LOG_ERR; break;
- case GCRY_LOG_FATAL:level = LOG_CRIT; break;
- case GCRY_LOG_BUG: level = LOG_CRIT; break;
- case GCRY_LOG_DEBUG:level = LOG_DEBUG; break;
- default: level = LOG_ERR; break;
- }
- if (running_detached)
- {
- vsyslog (level, format, arg_ptr);
- }
- else
- {
- fputs (PGM ": ", stderr);
- vfprintf (stderr, format, arg_ptr);
- if (!*format || format[strlen (format)-1] != '\n')
- putc ('\n', stderr);
- }
-}
-
-
-/* The cleanup handler - used to wipe out the secure memory. */
-static void
-cleanup (void)
-{
- gcry_control (GCRYCTL_TERM_SECMEM );
-}
-
-
-/* Make us a daemon and open the syslog. */
-static void
-daemonize (void)
-{
- int i;
- pid_t pid;
-
- fflush (NULL);
-
- pid = fork ();
- if (pid == (pid_t)-1)
- {
- logit (LOG_CRIT, "fork failed: %s", strerror (errno));
- exit (1);
- }
- if (pid)
- exit (0);
-
- if (setsid() == -1)
- {
- logit (LOG_CRIT, "setsid() failed: %s", strerror(errno));
- exit (1);
- }
-
- signal (SIGHUP, SIG_IGN);
-
- pid = fork ();
- if (pid == (pid_t)-1)
- {
- logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno));
- exit (1);
- }
- if (pid)
- exit (0); /* First child exits. */
-
- running_detached = 1;
-
- if (chdir("/"))
- {
- logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno));
- exit (1);
- }
- umask (0);
-
- for (i=0; i <= 2; i++)
- close (i);
-
- openlog (PGM, LOG_PID, LOG_DAEMON);
-}
-
-
-static void
-disable_core_dumps (void)
-{
-#ifdef HAVE_SETRLIMIT
- struct rlimit limit;
-
- if (getrlimit (RLIMIT_CORE, &limit))
- limit.rlim_max = 0;
- limit.rlim_cur = 0;
- if( !setrlimit (RLIMIT_CORE, &limit) )
- return 0;
- if (errno != EINVAL && errno != ENOSYS)
- logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno));
-#endif /* HAVE_SETRLIMIT */
-}
-
-
-
-static void
-print_version (int with_help)
-{
- fputs (MYVERSION_LINE "\n"
- "Copyright (C) 2006 Free Software Foundation, Inc.\n"
- "License GPLv2+: GNU GPL version 2 or later "
- "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.\n",
- stdout);
-
- if (with_help)
- fputs ("\n"
- "Usage: " PGM " [OPTIONS] [SOCKETNAME]\n"
- "Start Libgcrypt's random number daemon listening"
- " on socket SOCKETNAME\n"
- "SOCKETNAME defaults to XXX\n"
- "\n"
- " --no-detach do not deatach from the console\n"
- " --version print version of the program and exit\n"
- " --help display this help and exit\n"
- BUGREPORT_LINE, stdout );
-
- exit (0);
-}
-
-static int
-print_usage (void)
-{
- fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr);
- fputs (" (use --help to display options)\n", stderr);
- exit (1);
-}
-
-
-int
-main (int argc, char **argv)
-{
- int no_detach = 0;
- gpg_error_t err;
- struct sockaddr_un *srvr_addr;
- socklen_t addrlen;
- int fd;
- int rc;
- const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
-
-
- if (argc)
- {
- argc--; argv++;
- }
- while (argc && **argv == '-' && (*argv)[1] == '-')
- {
- if (!(*argv)[2])
- {
- argc--; argv++;
- break;
- }
- else if (!strcmp (*argv, "--version"))
- print_version (0);
- else if (!strcmp (*argv, "--help"))
- print_version (1);
- else if (!strcmp (*argv, "--no-detach"))
- {
- no_detach = 1;
- argc--; argv++;
- }
- else
- print_usage ();
- }
-
- if (argc == 1)
- socketname = argv[0];
- else if (argc > 1)
- print_usage ();
-
- if (!no_detach)
- daemonize ();
-
- signal (SIGPIPE, SIG_IGN);
-
- logit (LOG_NOTICE, "started version " VERSION );
-
- /* Libgcrypt requires us to register the threading model before we
- do anything else with it. Note that this also calls pth_init. We
- do the initialization while already running as a daemon to avoid
- overhead with double initialization of Libgcrypt. */
- err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
- if (err)
- {
- logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s",
- gpg_strerror (err));
- exit (1);
- }
-
- /* Check that the libgcrypt version is sufficient. */
- if (!gcry_check_version (VERSION) )
- {
- logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)",
- VERSION, gcry_check_version (NULL) );
- exit (1);
- }
-
- /* Register the logging callback and tell Libcgrypt to put the
- random pool into secure memory. */
- gcry_set_log_handler (my_gcry_logger, NULL);
- gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
-
- /* Obviously we don't want to allow any core dumps. */
- disable_core_dumps ();
-
- /* Initialize the secure memory stuff which will also drop any extra
- privileges we have. */
- gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
-
- /* Register a cleanup handler. */
- atexit (cleanup);
-
- /* Create and listen on the socket. */
- fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (fd == -1)
- {
- logit (LOG_CRIT, "can't create socket: %s", strerror (errno));
- exit (1);
- }
- srvr_addr = gcry_xmalloc (sizeof *srvr_addr);
- memset (srvr_addr, 0, sizeof *srvr_addr);
- srvr_addr->sun_family = AF_UNIX;
- if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
- {
- logit (LOG_CRIT, "socket name `%s' too long", socketname);
- exit (1);
- }
- strcpy (srvr_addr->sun_path, socketname);
- addrlen = (offsetof (struct sockaddr_un, sun_path)
- + strlen (srvr_addr->sun_path) + 1);
- rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
- if (rc == -1 && errno == EADDRINUSE)
- {
- remove (socketname);
- rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
- }
- if (rc == -1)
- {
- logit (LOG_CRIT, "error binding socket to `%s': %s",
- srvr_addr->sun_path, strerror (errno));
- close (fd);
- exit (1);
- }
-
- if (listen (fd, 5 ) == -1)
- {
- logit (LOG_CRIT, "listen() failed: %s", strerror (errno));
- close (fd);
- exit (1);
- }
-
- logit (LOG_INFO, "listening on socket `%s', fd=%d",
- srvr_addr->sun_path, fd);
-
- serve (fd);
- close (fd);
-
- logit (LOG_NOTICE, "stopped version " VERSION );
- return 0;
-}
-
-
-/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
- success or another value on write error. */
-static int
-writen (int fd, const void *buffer, size_t length)
-{
- while (length)
- {
- ssize_t n = pth_write (fd, buffer, length);
- if (n < 0)
- {
- logit (LOG_ERR, "connection %d: write error: %s",
- fd, strerror (errno));
- return -1; /* write error */
- }
- length -= n;
- buffer = (const char*)buffer + n;
- }
- return 0; /* Okay */
-}
-
-
-/* Send an error response back. Returns 0 on success. */
-static int
-send_error (int fd, int errcode)
-{
- unsigned char buf[2];
-
- buf[0] = errcode;
- buf[1] = 0;
- return writen (fd, buf, 2 );
-}
-
-/* Send a pong response back. Returns 0 on success or another value
- on write error. */
-static int
-send_pong (int fd)
-{
- return writen (fd, "\x00\x04pong", 6);
-}
-
-/* Send a nonce of size LENGTH back. Return 0 on success. */
-static int
-send_nonce (int fd, int length)
-{
- unsigned char buf[2+255];
- int rc;
-
- assert (length >= 0 && length <= 255);
- buf[0] = 0;
- buf[1] = length;
- gcry_create_nonce (buf+2, length);
- rc = writen (fd, buf, 2+length );
- wipememory (buf+2, length);
- return rc;
-}
-
-/* Send a random of size LENGTH with quality LEVEL back. Return 0 on
- success. */
-static int
-send_random (int fd, int length, int level)
-{
- unsigned char buf[2+255];
- int rc;
-
- assert (length >= 0 && length <= 255);
- assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM);
- buf[0] = 0;
- buf[1] = length;
- /* Note that we don't bother putting the random stuff into secure
- memory because this daemon is anyway intended to be run under
- root and it is questionable whether the kernel buffers etc. are
- equally well protected. */
- gcry_randomize (buf+2, length, level);
- rc = writen (fd, buf, 2+length );
- wipememory (buf+2, length);
- return rc;
-}
-
-/* Main processing loop for a connection.
-
- A request is made up of:
-
- 1 byte Total length of request; must be 3
- 1 byte Command
- 0 = Ping
- 10 = GetNonce
- 11 = GetStrongRandom
- 12 = GetVeryStrongRandom
- (all other values are reserved)
- 1 byte Number of requested bytes.
- This is ignored for command Ping.
-
- A response is made up of:
-
- 1 byte Error Code
- 0 = Everything is fine
- 1 = Bad Command
- 0xff = Other error.
- (For a bad request the connection will simply be closed)
- 1 byte Length of data
- n byte data
-
- The requests are read as long as the connection is open.
-
-
- */
-static void
-connection_loop (int fd)
-{
- unsigned char request[3];
- unsigned char *p;
- int nleft, n;
- int rc;
-
- for (;;)
- {
- for (nleft=3, p=request; nleft > 0; )
- {
- n = pth_read (fd, p, nleft);
- if (!n && p == request)
- return; /* Client terminated connection. */
- if (n <= 0)
- {
- logit (LOG_ERR, "connection %d: read error: %s",
- fd, n? strerror (errno) : "Unexpected EOF");
- return;
- }
- p += n;
- nleft -= n;
- }
- if (request[0] != 3)
- {
- logit (LOG_ERR, "connection %d: invalid length (%d) of request",
- fd, request[0]);
- return;
- }
-
- switch (request[1])
- {
- case 0: /* Ping */
- rc = send_pong (fd);
- break;
- case 10: /* GetNonce */
- rc = send_nonce (fd, request[2]);
- break;
- case 11: /* GetStrongRandom */
- rc = send_random (fd, request[2], GCRY_STRONG_RANDOM);
- break;
- case 12: /* GetVeryStrongRandom */
- rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM);
- break;
-
- default: /* Invalid command */
- rc = send_error (fd, 1);
- break;
- }
- if (rc)
- break; /* A write error occurred while sending the response. */
- }
-}
-
-
-
-/* Entry point for a connection's thread. */
-static void *
-connection_thread (void *arg)
-{
- int fd = (int)arg;
-
- active_connections++;
- logit (LOG_INFO, "connection handler for fd %d started", fd);
-
- connection_loop (fd);
-
- close (fd);
- logit (LOG_INFO, "connection handler for fd %d terminated", fd);
- active_connections--;
-
- return NULL;
-}
-
-
-/* This signal handler is called from the main loop between acepting
- connections. It is called on the regular stack, thus no special
- caution needs to be taken. It returns true to indicate that the
- process should terminate. */
-static int
-handle_signal (int signo)
-{
- switch (signo)
- {
- case SIGHUP:
- logit (LOG_NOTICE, "SIGHUP received - re-reading configuration");
- break;
-
- case SIGUSR1:
- logit (LOG_NOTICE, "SIGUSR1 received - no action defined");
- break;
-
- case SIGUSR2:
- logit (LOG_NOTICE, "SIGUSR2 received - no action defined");
- break;
-
- case SIGTERM:
- if (!shutdown_pending)
- logit (LOG_NOTICE, "SIGTERM received - shutting down ...");
- else
- logit (LOG_NOTICE, "SIGTERM received - still %d active connections",
- active_connections);
- shutdown_pending++;
- if (shutdown_pending > 2)
- {
- logit (LOG_NOTICE, "shutdown forced");
- return 1;
- }
- break;
-
- case SIGINT:
- logit (LOG_NOTICE, "SIGINT received - immediate shutdown");
- return 1;
-
- default:
- logit (LOG_NOTICE, "signal %d received - no action defined\n", signo);
- }
- return 0;
-}
-
-
-
-/* Main server loop. This is called with the FD of the listening
- socket. */
-static void
-serve (int listen_fd)
-{
- pth_attr_t tattr;
- pth_event_t ev;
- sigset_t sigs;
- int signo;
- struct sockaddr_un paddr;
- socklen_t plen = sizeof (paddr);
- int fd;
-
- tattr = pth_attr_new();
- pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
- pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
- pth_attr_set (tattr, PTH_ATTR_NAME, "connection");
-
- sigemptyset (&sigs);
- sigaddset (&sigs, SIGHUP);
- sigaddset (&sigs, SIGUSR1);
- sigaddset (&sigs, SIGUSR2);
- sigaddset (&sigs, SIGINT);
- sigaddset (&sigs, SIGTERM);
- ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
-
- for (;;)
- {
- if (shutdown_pending)
- {
- if (!active_connections)
- break; /* Ready. */
-
- /* Do not accept anymore connections but wait for existing
- connections to terminate. */
- signo = 0;
- pth_wait (ev);
- if (pth_event_occurred (ev) && signo)
- if (handle_signal (signo))
- break; /* Stop the loop. */
- continue;
- }
-
- gcry_fast_random_poll ();
- fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
- if (fd == -1)
- {
- if (pth_event_occurred (ev))
- {
- if (handle_signal (signo))
- break; /* Stop the loop. */
- continue;
- }
- logit (LOG_WARNING, "accept failed: %s - waiting 1s\n",
- strerror (errno));
- gcry_fast_random_poll ();
- pth_sleep (1);
- continue;
- }
-
- if (!pth_spawn (tattr, connection_thread, (void*)fd))
- {
- logit (LOG_ERR, "error spawning connection handler: %s\n",
- strerror (errno) );
- close (fd);
- }
- }
-
- pth_event_free (ev, PTH_FREE_ALL);
-}
diff --git a/src/getrandom.c b/src/getrandom.c
deleted file mode 100644
index f9bb5c0c..00000000
--- a/src/getrandom.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/* getrandom.c - Libgcrypt Random Number client
- * Copyright (C) 2006 Free Software Foundation, Inc.
- *
- * Getrandom is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * Getrandom is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-#include <errno.h>
-
-#define PGM "getrandom"
-#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
-#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
-
-
-static void
-logit (const char *format, ...)
-{
- va_list arg_ptr;
-
- va_start (arg_ptr, format) ;
- fputs (PGM ": ", stderr);
- vfprintf (stderr, format, arg_ptr);
- putc ('\n', stderr);
- va_end (arg_ptr);
-}
-
-
-/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
- success or another value on write error. */
-static int
-writen (int fd, const void *buffer, size_t length)
-{
- while (length)
- {
- ssize_t n;
-
- do
- n = write (fd, buffer, length);
- while (n < 0 && errno == EINTR);
- if (n < 0)
- {
- logit ("write error: %s", strerror (errno));
- return -1; /* write error */
- }
- length -= n;
- buffer = (const char *)buffer + n;
- }
- return 0; /* Okay */
-}
-
-
-
-
-static void
-print_version (int with_help)
-{
- fputs (MYVERSION_LINE "\n"
- "Copyright (C) 2006 Free Software Foundation, Inc.\n"
- "License GPLv2+: GNU GPL version 2 or later "
- "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
- "This is free software: you are free to change and redistribute it.\n"
- "There is NO WARRANTY, to the extent permitted by law.\n",
- stdout);
-
- if (with_help)
- fputs ("\n"
- "Usage: " PGM " [OPTIONS] NBYTES\n"
- "Connect to libgcrypt's random number daemon and "
- "return random numbers"
- "\n"
- " --nonce Return weak random suitable for a nonce\n"
- " --very-strong Return very strong random\n"
- " --ping Send a ping\n"
- " --socket NAME Name of sockket to connect to\n"
- " --hex Return result as a hex dump\n"
- " --verbose Show what we are doing\n"
- " --version Print version of the program and exit\n"
- " --help Display this help and exit\n"
- BUGREPORT_LINE, stdout );
-
- exit (0);
-}
-
-static int
-print_usage (void)
-{
- fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
- fputs (" (use --help to display options)\n", stderr);
- exit (1);
-}
-
-
-int
-main (int argc, char **argv)
-{
- struct sockaddr_un *srvr_addr;
- socklen_t addrlen;
- int fd;
- int rc;
- unsigned char buffer[300];
- int nleft, nread;
- const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
- int do_ping = 0;
- int get_nonce = 0;
- int get_very_strong = 0;
- int req_nbytes, nbytes, n;
- int verbose = 0;
- int fail = 0;
- int do_hex = 0;
-
- if (argc)
- {
- argc--; argv++;
- }
- while (argc && **argv == '-' && (*argv)[1] == '-')
- {
- if (!(*argv)[2])
- {
- argc--; argv++;
- break;
- }
- else if (!strcmp (*argv, "--version"))
- print_version (0);
- else if (!strcmp (*argv, "--help"))
- print_version (1);
- else if (!strcmp (*argv, "--socket") && argc > 1 )
- {
- argc--; argv++;
- socketname = *argv;
- argc--; argv++;
- }
- else if (!strcmp (*argv, "--nonce"))
- {
- argc--; argv++;
- get_nonce = 1;
- }
- else if (!strcmp (*argv, "--very-strong"))
- {
- argc--; argv++;
- get_very_strong = 1;
- }
- else if (!strcmp (*argv, "--ping"))
- {
- argc--; argv++;
- do_ping = 1;
- }
- else if (!strcmp (*argv, "--hex"))
- {
- argc--; argv++;
- do_hex = 1;
- }
- else if (!strcmp (*argv, "--verbose"))
- {
- argc--; argv++;
- verbose = 1;
- }
- else
- print_usage ();
- }
-
-
- if (!argc && do_ping)
- ; /* This is allowed. */
- else if (argc != 1)
- print_usage ();
- req_nbytes = argc? atoi (*argv) : 0;
-
- if (req_nbytes < 0)
- print_usage ();
-
- /* Create a socket. */
- fd = socket (AF_UNIX, SOCK_STREAM, 0);
- if (fd == -1)
- {
- logit ("can't create socket: %s", strerror (errno));
- exit (1);
- }
- srvr_addr = malloc (sizeof *srvr_addr);
- if (!srvr_addr)
- {
- logit ("malloc failed: %s", strerror (errno));
- exit (1);
- }
- memset (srvr_addr, 0, sizeof *srvr_addr);
- srvr_addr->sun_family = AF_UNIX;
- if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
- {
- logit ("socket name `%s' too long", socketname);
- exit (1);
- }
- strcpy (srvr_addr->sun_path, socketname);
- addrlen = (offsetof (struct sockaddr_un, sun_path)
- + strlen (srvr_addr->sun_path) + 1);
- rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen);
- if (rc == -1)
- {
- logit ("error connecting socket `%s': %s",
- srvr_addr->sun_path, strerror (errno));
- close (fd);
- exit (1);
- }
-
- do
- {
- nbytes = req_nbytes > 255? 255 : req_nbytes;
- req_nbytes -= nbytes;
-
- buffer[0] = 3;
- if (do_ping)
- buffer[1] = 0;
- else if (get_nonce)
- buffer[1] = 10;
- else if (get_very_strong)
- buffer[1] = 12;
- else
- buffer[1] = 11;
- buffer[2] = nbytes;
- if (writen (fd, buffer, 3))
- fail = 1;
- else
- {
- for (nleft=2, nread=0; nleft > 0; )
- {
- do
- n = read (fd, buffer+nread, nleft);
- while (n < 0 && errno == EINTR);
- if (n < 0)
- {
- logit ("read error: %s", strerror (errno));
- exit (1);
- }
- nleft -= n;
- nread += n;
- if (nread && buffer[0])
- {
- logit ("server returned error code %d", buffer[0]);
- exit (1);
- }
- }
- if (verbose)
- logit ("received response with %d bytes of data", buffer[1]);
- if (buffer[1] < nbytes)
- {
- logit ("warning: server returned less bytes than requested");
- fail = 1;
- }
- else if (buffer[1] > nbytes && !do_ping)
- {
- logit ("warning: server returned more bytes than requested");
- fail = 1;
- }
- nbytes = buffer[1];
- if (nbytes > sizeof buffer)
- {
- logit ("buffer too short to receive data");
- exit (1);
- }
-
- for (nleft=nbytes, nread=0; nleft > 0; )
- {
- do
- n = read (fd, buffer+nread, nleft);
- while (n < 0 && errno == EINTR);
- if (n < 0)
- {
- logit ("read error: %s", strerror (errno));
- exit (1);
- }
- nleft -= n;
- nread += n;
- }
-
- if (do_hex)
- {
- for (n=0; n < nbytes; n++)
- {
- if (!n)
- ;
- else if (!(n % 16))
- putchar ('\n');
- else
- putchar (' ');
- printf ("%02X", buffer[n]);
- }
- if (nbytes)
- putchar ('\n');
- }
- else
- {
- if (fwrite (buffer, nbytes, 1, stdout) != 1)
- {
- logit ("error writing to stdout: %s", strerror (errno));
- fail = 1;
- }
- }
- }
- }
- while (!fail && req_nbytes);
-
- close (fd);
- free (srvr_addr);
- return fail? 1 : 0;
-}