diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2022-02-02 11:44:35 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2022-02-02 11:44:35 +0900 |
commit | d918d8aee27987c3bb99f44a7ed3508d81009f51 (patch) | |
tree | 14cecf4b4bd2ac68b41bf58730a0c50672cbf8f8 /src | |
parent | dd99ef53d9ee6e503ce288fca853cf4e237ec09e (diff) | |
download | libgcrypt-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.am | 12 | ||||
-rw-r--r-- | src/gcryptrnd.c | 680 | ||||
-rw-r--r-- | src/getrandom.c | 326 |
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; -} |