1/* gcryptrnd.c - Libgcrypt Random Number Daemon
2 * Copyright (C) 2006 Free Software Foundation, Inc.
3 *
4 * Gcryptend 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.
8 *
9 * Gcryptrnd 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.
13 *
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
17 * 02110-1301, USA.
18 */
19
20/* We require vsyslog pth
21   We need to test for:  setrlimit
22
23   We should also prioritize requests.  This is best done by putting
24   the requests into queues and have a main thread processing these
25   queues.
26
27 */
28
29#include <config.h>
30#include <stdio.h>
31#include <stddef.h>
32#include <stdlib.h>
33#include <assert.h>
34#include <time.h>
35#include <sys/times.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <stdarg.h>
39#include <syslog.h>
40#include <sys/socket.h>
41#include <sys/un.h>
42#include <unistd.h>
43#include <errno.h>
44#include <pth.h>
45#include <gcrypt.h>
46
47#define PGM "gcryptrnd"
48#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
49#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
50
51/* Pth wrapper function definitions. */
52GCRY_THREAD_OPTION_PTH_IMPL;
53
54
55/* Flag set to true if we have been daemonized. */
56static int running_detached;
57/* Flag indicating that a shutdown has been requested.  */
58static int shutdown_pending;
59/* Counter for active connections.  */
60static int active_connections;
61
62
63
64/* Local prototypes.  */
65static void serve (int listen_fd);
66
67
68
69
70
71/* To avoid that a compiler optimizes certain memset calls away, these
72   macros may be used instead. */
73#define wipememory2(_ptr,_set,_len) do { \
74              volatile char *_vptr=(volatile char *)(_ptr); \
75              size_t _vlen=(_len); \
76              while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
77                  } while(0)
78#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
79
80
81
82
83/* Error printing utility.  PRIORITY should be one of syslog's
84   priority levels.  This functions prints to the stderr or syslog
85   depending on whether we are already daemonized. */
86static void
87logit (int priority, const char *format, ...)
88{
89  va_list arg_ptr;
90
91  va_start (arg_ptr, format) ;
92  if (running_detached)
93    {
94      vsyslog (priority, format, arg_ptr);
95    }
96  else
97    {
98      fputs (PGM ": ", stderr);
99      vfprintf (stderr, format, arg_ptr);
100      putc ('\n', stderr);
101    }
102  va_end (arg_ptr);
103}
104
105/* Callback used by libgcrypt for logging. */
106static void
107my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
108{
109  (void)dummy;
110
111  /* Map the log levels. */
112  switch (level)
113    {
114    case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break;
115    case GCRY_LOG_INFO: level = LOG_INFO; break;
116    case GCRY_LOG_WARN: level = LOG_WARNING; break;
117    case GCRY_LOG_ERROR:level = LOG_ERR; break;
118    case GCRY_LOG_FATAL:level = LOG_CRIT; break;
119    case GCRY_LOG_BUG:  level = LOG_CRIT; break;
120    case GCRY_LOG_DEBUG:level = LOG_DEBUG; break;
121    default:            level = LOG_ERR; break;
122    }
123  if (running_detached)
124    {
125      vsyslog (level, format, arg_ptr);
126    }
127  else
128    {
129      fputs (PGM ": ", stderr);
130      vfprintf (stderr, format, arg_ptr);
131      if (!*format || format[strlen (format)-1] != '\n')
132        putc ('\n', stderr);
133    }
134}
135
136
137/* The cleanup handler - used to wipe out the secure memory. */
138static void
139cleanup (void)
140{
141  gcry_control (GCRYCTL_TERM_SECMEM );
142}
143
144
145/* Make us a daemon and open the syslog. */
146static void
147daemonize (void)
148{
149  int i;
150  pid_t pid;
151
152  fflush (NULL);
153
154  pid = fork ();
155  if (pid == (pid_t)-1)
156    {
157      logit (LOG_CRIT, "fork failed: %s", strerror (errno));
158      exit (1);
159    }
160  if (pid)
161    exit (0);
162
163  if (setsid() == -1)
164    {
165      logit (LOG_CRIT, "setsid() failed: %s", strerror(errno));
166      exit (1);
167    }
168
169  signal (SIGHUP, SIG_IGN);
170
171  pid = fork ();
172  if (pid == (pid_t)-1)
173    {
174      logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno));
175      exit (1);
176    }
177  if (pid)
178    exit (0); /* First child exits. */
179
180  running_detached = 1;
181
182  if (chdir("/"))
183    {
184      logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno));
185      exit (1);
186    }
187  umask (0);
188
189  for (i=0; i <= 2; i++)
190    close (i);
191
192  openlog (PGM, LOG_PID, LOG_DAEMON);
193}
194
195
196static void
197disable_core_dumps (void)
198{
199#ifdef HAVE_SETRLIMIT
200  struct rlimit limit;
201
202  if (getrlimit (RLIMIT_CORE, &limit))
203    limit.rlim_max = 0;
204  limit.rlim_cur = 0;
205  if( !setrlimit (RLIMIT_CORE, &limit) )
206    return 0;
207  if (errno != EINVAL && errno != ENOSYS)
208    logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno));
209#endif /* HAVE_SETRLIMIT */
210}
211
212
213
214static void
215print_version (int with_help)
216{
217  fputs (MYVERSION_LINE "\n"
218         "Copyright (C) 2006 Free Software Foundation, Inc.\n"
219         "License GPLv2+: GNU GPL version 2 or later "
220         "<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
221         "This is free software: you are free to change and redistribute it.\n"
222         "There is NO WARRANTY, to the extent permitted by law.\n",
223         stdout);
224
225  if (with_help)
226    fputs ("\n"
227           "Usage: " PGM " [OPTIONS] [SOCKETNAME]\n"
228           "Start Libgcrypt's random number daemon listening"
229           " on socket SOCKETNAME\n"
230           "SOCKETNAME defaults to XXX\n"
231           "\n"
232           "  --no-detach   do not deatach from the console\n"
233           "  --version     print version of the program and exit\n"
234           "  --help        display this help and exit\n"
235           BUGREPORT_LINE, stdout );
236
237  exit (0);
238}
239
240static int
241print_usage (void)
242{
243  fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr);
244  fputs ("       (use --help to display options)\n", stderr);
245  exit (1);
246}
247
248
249int
250main (int argc, char **argv)
251{
252  int no_detach = 0;
253  gpg_error_t err;
254  struct sockaddr_un *srvr_addr;
255  socklen_t addrlen;
256  int fd;
257  int rc;
258  const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
259
260
261  if (argc)
262    {
263      argc--; argv++;
264    }
265  while (argc && **argv == '-' && (*argv)[1] == '-')
266    {
267      if (!(*argv)[2])
268        {
269          argc--; argv++;
270          break;
271        }
272      else if (!strcmp (*argv, "--version"))
273        print_version (0);
274      else if (!strcmp (*argv, "--help"))
275        print_version (1);
276      else if (!strcmp (*argv, "--no-detach"))
277        {
278          no_detach = 1;
279          argc--; argv++;
280        }
281      else
282        print_usage ();
283    }
284
285  if (argc == 1)
286    socketname = argv[0];
287  else if (argc > 1)
288    print_usage ();
289
290  if (!no_detach)
291    daemonize ();
292
293  signal (SIGPIPE, SIG_IGN);
294
295  logit (LOG_NOTICE, "started version " VERSION );
296
297  /* Libgcrypt requires us to register the threading model before we
298     do anything else with it. Note that this also calls pth_init.  We
299     do the initialization while already running as a daemon to avoid
300     overhead with double initialization of Libgcrypt. */
301  err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
302  if (err)
303    {
304      logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s",
305             gpg_strerror (err));
306      exit (1);
307    }
308
309  /* Check that the libgcrypt version is sufficient.  */
310  if (!gcry_check_version (VERSION) )
311    {
312      logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)",
313             VERSION, gcry_check_version (NULL) );
314      exit (1);
315    }
316
317  /* Register the logging callback and tell Libcgrypt to put the
318     random pool into secure memory. */
319  gcry_set_log_handler (my_gcry_logger, NULL);
320  gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
321
322  /* Obviously we don't want to allow any core dumps. */
323  disable_core_dumps ();
324
325  /* Initialize the secure memory stuff which will also drop any extra
326     privileges we have. */
327  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
328
329  /* Register a cleanup handler. */
330  atexit (cleanup);
331
332  /* Create and listen on the socket. */
333  fd = socket (AF_UNIX, SOCK_STREAM, 0);
334  if (fd == -1)
335    {
336      logit (LOG_CRIT, "can't create socket: %s", strerror (errno));
337      exit (1);
338    }
339  srvr_addr = gcry_xmalloc (sizeof *srvr_addr);
340  memset (srvr_addr, 0, sizeof *srvr_addr);
341  srvr_addr->sun_family = AF_UNIX;
342  if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
343    {
344      logit (LOG_CRIT, "socket name `%s' too long", socketname);
345      exit (1);
346    }
347  strcpy (srvr_addr->sun_path, socketname);
348  addrlen = (offsetof (struct sockaddr_un, sun_path)
349             + strlen (srvr_addr->sun_path) + 1);
350  rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
351  if (rc == -1 && errno == EADDRINUSE)
352    {
353      remove (socketname);
354      rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
355    }
356  if (rc == -1)
357    {
358      logit (LOG_CRIT, "error binding socket to `%s': %s",
359             srvr_addr->sun_path, strerror (errno));
360      close (fd);
361      exit (1);
362    }
363
364  if (listen (fd, 5 ) == -1)
365    {
366      logit (LOG_CRIT, "listen() failed: %s", strerror (errno));
367      close (fd);
368      exit (1);
369    }
370
371  logit (LOG_INFO, "listening on socket `%s', fd=%d",
372         srvr_addr->sun_path, fd);
373
374  serve (fd);
375  close (fd);
376
377  logit (LOG_NOTICE, "stopped version " VERSION );
378  return 0;
379}
380
381
382/* Send LENGTH bytes of BUFFER to file descriptor FD.  Returns 0 on
383   success or another value on write error. */
384static int
385writen (int fd, const void *buffer, size_t length)
386{
387  while (length)
388    {
389      ssize_t n = pth_write (fd, buffer, length);
390      if (n < 0)
391         {
392           logit (LOG_ERR, "connection %d: write error: %s",
393                  fd, strerror (errno));
394           return -1; /* write error */
395         }
396      length -= n;
397      buffer = (const char*)buffer + n;
398    }
399  return 0;  /* Okay */
400}
401
402
403/* Send an error response back.  Returns 0 on success. */
404static int
405send_error (int fd, int errcode)
406{
407  unsigned char buf[2];
408
409  buf[0] = errcode;
410  buf[1] = 0;
411  return writen (fd, buf, 2 );
412}
413
414/* Send a pong response back.  Returns 0 on success or another value
415   on write error.  */
416static int
417send_pong (int fd)
418{
419  return writen (fd, "\x00\x04pong", 6);
420}
421
422/* Send a nonce of size LENGTH back. Return 0 on success. */
423static int
424send_nonce (int fd, int length)
425{
426  unsigned char buf[2+255];
427  int rc;
428
429  assert (length >= 0 && length <= 255);
430  buf[0] = 0;
431  buf[1] = length;
432  gcry_create_nonce (buf+2, length);
433  rc = writen (fd, buf, 2+length );
434  wipememory (buf+2, length);
435  return rc;
436}
437
438/* Send a random of size LENGTH with quality LEVEL back. Return 0 on
439   success. */
440static int
441send_random (int fd, int length, int level)
442{
443  unsigned char buf[2+255];
444  int rc;
445
446  assert (length >= 0 && length <= 255);
447  assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM);
448  buf[0] = 0;
449  buf[1] = length;
450  /* Note that we don't bother putting the random stuff into secure
451     memory because this daemon is anyway intended to be run under
452     root and it is questionable whether the kernel buffers etc. are
453     equally well protected. */
454  gcry_randomize (buf+2, length, level);
455  rc = writen (fd, buf, 2+length );
456  wipememory (buf+2, length);
457  return rc;
458}
459
460/* Main processing loop for a connection.
461
462   A request is made up of:
463
464    1 byte  Total length of request; must be 3
465    1 byte  Command
466            0   = Ping
467            10  = GetNonce
468            11  = GetStrongRandom
469            12  = GetVeryStrongRandom
470            (all other values are reserved)
471    1 byte  Number of requested bytes.
472            This is ignored for command Ping.
473
474   A response is made up of:
475
476    1 byte  Error Code
477            0    = Everything is fine
478            1    = Bad Command
479            0xff = Other error.
480            (For a bad request the connection will simply be closed)
481    1 byte  Length of data
482    n byte  data
483
484   The requests are read as long as the connection is open.
485
486
487 */
488static void
489connection_loop (int fd)
490{
491  unsigned char request[3];
492  unsigned char *p;
493  int nleft, n;
494  int rc;
495
496  for (;;)
497    {
498      for (nleft=3, p=request; nleft > 0; )
499        {
500          n = pth_read (fd, p, nleft);
501          if (!n && p == request)
502            return; /* Client terminated connection. */
503          if (n <= 0)
504            {
505              logit (LOG_ERR, "connection %d: read error: %s",
506                     fd, n? strerror (errno) : "Unexpected EOF");
507              return;
508            }
509          p += n;
510          nleft -= n;
511        }
512      if (request[0] != 3)
513        {
514          logit (LOG_ERR, "connection %d: invalid length (%d) of request",
515                 fd, request[0]);
516          return;
517        }
518
519      switch (request[1])
520        {
521        case 0: /* Ping */
522          rc = send_pong (fd);
523          break;
524        case 10: /* GetNonce */
525          rc = send_nonce (fd, request[2]);
526          break;
527        case 11: /* GetStrongRandom */
528          rc = send_random (fd, request[2], GCRY_STRONG_RANDOM);
529          break;
530        case 12: /* GetVeryStrongRandom */
531          rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM);
532          break;
533
534        default: /* Invalid command */
535          rc = send_error (fd, 1);
536          break;
537        }
538      if (rc)
539        break; /* A write error occurred while sending the response. */
540    }
541}
542
543
544
545/* Entry point for a connection's thread. */
546static void *
547connection_thread (void *arg)
548{
549  int fd = (int)arg;
550
551  active_connections++;
552  logit (LOG_INFO, "connection handler for fd %d started", fd);
553
554  connection_loop (fd);
555
556  close (fd);
557  logit (LOG_INFO, "connection handler for fd %d terminated", fd);
558  active_connections--;
559
560  return NULL;
561}
562
563
564/* This signal handler is called from the main loop between acepting
565   connections.  It is called on the regular stack, thus no special
566   caution needs to be taken.  It returns true to indicate that the
567   process should terminate. */
568static int
569handle_signal (int signo)
570{
571  switch (signo)
572    {
573    case SIGHUP:
574      logit (LOG_NOTICE, "SIGHUP received - re-reading configuration");
575      break;
576
577    case SIGUSR1:
578      logit (LOG_NOTICE, "SIGUSR1 received - no action defined");
579      break;
580
581    case SIGUSR2:
582      logit (LOG_NOTICE, "SIGUSR2 received - no action defined");
583      break;
584
585    case SIGTERM:
586      if (!shutdown_pending)
587        logit (LOG_NOTICE, "SIGTERM received - shutting down ...");
588      else
589        logit (LOG_NOTICE, "SIGTERM received - still %d active connections",
590               active_connections);
591      shutdown_pending++;
592      if (shutdown_pending > 2)
593        {
594          logit (LOG_NOTICE, "shutdown forced");
595          return 1;
596	}
597      break;
598
599    case SIGINT:
600      logit (LOG_NOTICE, "SIGINT received - immediate shutdown");
601      return 1;
602
603    default:
604      logit (LOG_NOTICE, "signal %d received - no action defined\n", signo);
605    }
606  return 0;
607}
608
609
610
611/* Main server loop.  This is called with the FD of the listening
612   socket. */
613static void
614serve (int listen_fd)
615{
616  pth_attr_t tattr;
617  pth_event_t ev;
618  sigset_t sigs;
619  int signo;
620  struct sockaddr_un paddr;
621  socklen_t plen = sizeof (paddr);
622  int fd;
623
624  tattr = pth_attr_new();
625  pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
626  pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
627  pth_attr_set (tattr, PTH_ATTR_NAME, "connection");
628
629  sigemptyset (&sigs);
630  sigaddset (&sigs, SIGHUP);
631  sigaddset (&sigs, SIGUSR1);
632  sigaddset (&sigs, SIGUSR2);
633  sigaddset (&sigs, SIGINT);
634  sigaddset (&sigs, SIGTERM);
635  ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
636
637  for (;;)
638    {
639      if (shutdown_pending)
640        {
641          if (!active_connections)
642            break; /* Ready. */
643
644          /* Do not accept anymore connections but wait for existing
645             connections to terminate.  */
646          signo = 0;
647          pth_wait (ev);
648          if (pth_event_occurred (ev) && signo)
649            if (handle_signal (signo))
650              break; /* Stop the loop. */
651          continue;
652	}
653
654      gcry_fast_random_poll ();
655      fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
656      if (fd == -1)
657        {
658          if (pth_event_occurred (ev))
659            {
660              if (handle_signal (signo))
661                break; /* Stop the loop. */
662              continue;
663	    }
664          logit (LOG_WARNING, "accept failed: %s - waiting 1s\n",
665                 strerror (errno));
666          gcry_fast_random_poll ();
667          pth_sleep (1);
668          continue;
669	}
670
671      if (!pth_spawn (tattr, connection_thread, (void*)fd))
672        {
673          logit (LOG_ERR, "error spawning connection handler: %s\n",
674                 strerror (errno) );
675          close (fd);
676	}
677    }
678
679  pth_event_free (ev, PTH_FREE_ALL);
680}
681