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