~ubuntu-branches/ubuntu/trusty/libgcrypt11/trusty-proposed

« back to all changes in this revision

Viewing changes to src/gcryptrnd.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Kowalik
  • Date: 2008-07-02 18:32:45 UTC
  • mfrom: (1.1.5 upstream) (2.1.2 lenny)
  • Revision ID: james.westby@ubuntu.com-20080702183245-b1p9zumbhmq9wk4g
Tags: 1.4.1-1ubuntu1
* Merge from Debian unstable.
* Remaining Ubuntu changes:
  - Add libgcrypt11-udeb package.
  - Add clean-la.mk, and add a symlink for the .la
* Ubuntu changes dropped:
  - Build-Depends changes.
  - Drop patch 20_socket_nsl_linkage.diff, basically applied upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
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
  (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. */
 
138
static void
 
139
cleanup (void)
 
140
{
 
141
  gcry_control (GCRYCTL_TERM_SECMEM );
 
142
}
 
143
 
 
144
 
 
145
/* Make us a daemon and open the syslog. */
 
146
static void
 
147
daemonize (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
 
 
196
static void
 
197
disable_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
 
 
214
static void
 
215
print_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
 
 
240
static int
 
241
print_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
 
 
249
int 
 
250
main (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. */
 
384
static int
 
385
writen (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. */
 
404
static int
 
405
send_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.  */
 
416
static int
 
417
send_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. */
 
423
static int
 
424
send_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. */
 
440
static int
 
441
send_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
 */
 
488
static void
 
489
connection_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 occured while sending the response. */
 
540
    }
 
541
}
 
542
 
 
543
 
 
544
 
 
545
/* Entry point for a connection's thread. */
 
546
static void *
 
547
connection_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. */
 
568
static int
 
569
handle_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. */
 
613
static void
 
614
serve (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