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