Line data Source code
1 : /* scdaemon.c - The GnuPG Smartcard Daemon
2 : * Copyright (C) 2001-2002, 2004-2005, 2007-2009 Free Software Foundation, Inc.
3 : * Copyright (C) 2001-2002, 2004-2005, 2007-2014 Werner Koch
4 : *
5 : * This file is part of GnuPG.
6 : *
7 : * GnuPG is free software; you can redistribute it and/or modify
8 : * it under the terms of the GNU General Public License as published by
9 : * the Free Software Foundation; either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * GnuPG is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU General Public License
18 : * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <config.h>
22 :
23 : #include <stdio.h>
24 : #include <stdlib.h>
25 : #include <stddef.h>
26 : #include <stdarg.h>
27 : #include <string.h>
28 : #include <errno.h>
29 : #include <assert.h>
30 : #include <time.h>
31 : #include <fcntl.h>
32 : #ifndef HAVE_W32_SYSTEM
33 : #include <sys/socket.h>
34 : #include <sys/un.h>
35 : #endif /*HAVE_W32_SYSTEM*/
36 : #include <unistd.h>
37 : #include <signal.h>
38 : #include <npth.h>
39 :
40 : #define GNUPG_COMMON_NEED_AFLOCAL
41 : #include "scdaemon.h"
42 : #include <ksba.h>
43 : #include <gcrypt.h>
44 :
45 : #include <assuan.h> /* malloc hooks */
46 :
47 : #include "i18n.h"
48 : #include "sysutils.h"
49 : #include "app-common.h"
50 : #include "iso7816.h"
51 : #include "apdu.h"
52 : #include "ccid-driver.h"
53 : #include "gc-opt-flags.h"
54 : #include "asshelp.h"
55 : #include "../common/init.h"
56 :
57 : #ifndef ENAMETOOLONG
58 : # define ENAMETOOLONG EINVAL
59 : #endif
60 :
61 : enum cmd_and_opt_values
62 : { aNull = 0,
63 : oCsh = 'c',
64 : oQuiet = 'q',
65 : oSh = 's',
66 : oVerbose = 'v',
67 :
68 : oNoVerbose = 500,
69 : aGPGConfList,
70 : aGPGConfTest,
71 : oOptions,
72 : oDebug,
73 : oDebugAll,
74 : oDebugLevel,
75 : oDebugWait,
76 : oDebugAllowCoreDump,
77 : oDebugCCIDDriver,
78 : oDebugLogTid,
79 : oDebugAssuanLogCats,
80 : oNoGreeting,
81 : oNoOptions,
82 : oHomedir,
83 : oNoDetach,
84 : oNoGrab,
85 : oLogFile,
86 : oServer,
87 : oMultiServer,
88 : oDaemon,
89 : oBatch,
90 : oReaderPort,
91 : oCardTimeout,
92 : octapiDriver,
93 : opcscDriver,
94 : oDisableCCID,
95 : oDisableOpenSC,
96 : oDisablePinpad,
97 : oAllowAdmin,
98 : oDenyAdmin,
99 : oDisableApplication,
100 : oEnablePinpadVarlen,
101 : oDebugDisableTicker
102 : };
103 :
104 :
105 :
106 : static ARGPARSE_OPTS opts[] = {
107 : ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
108 : ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
109 :
110 : ARGPARSE_group (301, N_("@Options:\n ")),
111 :
112 : ARGPARSE_s_n (oServer,"server", N_("run in server mode (foreground)")),
113 : ARGPARSE_s_n (oMultiServer, "multi-server",
114 : N_("run in multi server mode (foreground)")),
115 : ARGPARSE_s_n (oDaemon, "daemon", N_("run in daemon mode (background)")),
116 : ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
117 : ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")),
118 : ARGPARSE_s_n (oSh, "sh", N_("sh-style command output")),
119 : ARGPARSE_s_n (oCsh, "csh", N_("csh-style command output")),
120 : ARGPARSE_s_s (oOptions, "options", N_("|FILE|read options from FILE")),
121 : ARGPARSE_s_s (oDebug, "debug", "@"),
122 : ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
123 : ARGPARSE_s_s (oDebugLevel, "debug-level" ,
124 : N_("|LEVEL|set the debugging level to LEVEL")),
125 : ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
126 : ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"),
127 : ARGPARSE_s_n (oDebugCCIDDriver, "debug-ccid-driver", "@"),
128 : ARGPARSE_s_n (oDebugDisableTicker, "debug-disable-ticker", "@"),
129 : ARGPARSE_s_n (oDebugLogTid, "debug-log-tid", "@"),
130 : ARGPARSE_p_u (oDebugAssuanLogCats, "debug-assuan-log-cats", "@"),
131 : ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
132 : ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write a log to FILE")),
133 : ARGPARSE_s_s (oReaderPort, "reader-port",
134 : N_("|N|connect to reader at port N")),
135 : ARGPARSE_s_s (octapiDriver, "ctapi-driver",
136 : N_("|NAME|use NAME as ct-API driver")),
137 : ARGPARSE_s_s (opcscDriver, "pcsc-driver",
138 : N_("|NAME|use NAME as PC/SC driver")),
139 : ARGPARSE_s_n (oDisableCCID, "disable-ccid",
140 : #ifdef HAVE_LIBUSB
141 : N_("do not use the internal CCID driver")
142 : #else
143 : "@"
144 : #endif
145 : /* end --disable-ccid */),
146 : ARGPARSE_s_u (oCardTimeout, "card-timeout",
147 : N_("|N|disconnect the card after N seconds of inactivity")),
148 :
149 : ARGPARSE_s_n (oDisablePinpad, "disable-pinpad",
150 : N_("do not use a reader's pinpad")),
151 : ARGPARSE_ignore (300, "disable-keypad"),
152 :
153 : ARGPARSE_s_n (oAllowAdmin, "allow-admin", "@"),
154 : ARGPARSE_s_n (oDenyAdmin, "deny-admin",
155 : N_("deny the use of admin card commands")),
156 : ARGPARSE_s_s (oDisableApplication, "disable-application", "@"),
157 : ARGPARSE_s_n (oEnablePinpadVarlen, "enable-pinpad-varlen",
158 : N_("use variable length input for pinpad")),
159 :
160 : ARGPARSE_end ()
161 : };
162 :
163 :
164 : /* The list of supported debug flags. */
165 : static struct debug_flags_s debug_flags [] =
166 : {
167 : { DBG_COMMAND_VALUE, "command" },
168 : { DBG_MPI_VALUE , "mpi" },
169 : { DBG_CRYPTO_VALUE , "crypto" },
170 : { DBG_MEMORY_VALUE , "memory" },
171 : { DBG_CACHE_VALUE , "cache" },
172 : { DBG_MEMSTAT_VALUE, "memstat" },
173 : { DBG_HASHING_VALUE, "hashing" },
174 : { DBG_IPC_VALUE , "ipc" },
175 : { DBG_CARD_IO_VALUE, "cardio" },
176 : { DBG_READER_VALUE , "reader" },
177 : { 0, NULL }
178 : };
179 :
180 :
181 : /* The card driver we use by default for PC/SC. */
182 : #if defined(HAVE_W32_SYSTEM) || defined(__CYGWIN__)
183 : #define DEFAULT_PCSC_DRIVER "winscard.dll"
184 : #elif defined(__APPLE__)
185 : #define DEFAULT_PCSC_DRIVER "/System/Library/Frameworks/PCSC.framework/PCSC"
186 : #elif defined(__GLIBC__)
187 : #define DEFAULT_PCSC_DRIVER "libpcsclite.so.1"
188 : #else
189 : #define DEFAULT_PCSC_DRIVER "libpcsclite.so"
190 : #endif
191 :
192 : /* The timer tick used for housekeeping stuff. We poll every 500ms to
193 : let the user immediately know a status change.
194 :
195 : This is not too good for power saving but given that there is no
196 : easy way to block on card status changes it is the best we can do.
197 : For PC/SC we could in theory use an extra thread to wait for status
198 : changes but that requires a native thread because there is no way
199 : to make the underlying PC/SC card change function block using a Npth
200 : mechanism. Given that a native thread could only be used under W32
201 : we don't do that at all. */
202 : #define TIMERTICK_INTERVAL_SEC (0)
203 : #define TIMERTICK_INTERVAL_USEC (500000)
204 :
205 : /* Flag to indicate that a shutdown was requested. */
206 : static int shutdown_pending;
207 :
208 : /* It is possible that we are currently running under setuid permissions */
209 : static int maybe_setuid = 1;
210 :
211 : /* Flag telling whether we are running as a pipe server. */
212 : static int pipe_server;
213 :
214 : /* Name of the communication socket */
215 : static char *socket_name;
216 : /* Name of the redirected socket or NULL. */
217 : static char *redir_socket_name;
218 :
219 : /* We need to keep track of the server's nonces (these are dummies for
220 : POSIX systems). */
221 : static assuan_sock_nonce_t socket_nonce;
222 :
223 : /* Debug flag to disable the ticker. The ticker is in fact not
224 : disabled but it won't perform any ticker specific actions. */
225 : static int ticker_disabled;
226 :
227 :
228 :
229 : static char *create_socket_name (char *standard_name);
230 : static gnupg_fd_t create_server_socket (const char *name,
231 : char **r_redir_name,
232 : assuan_sock_nonce_t *nonce);
233 :
234 : static void *start_connection_thread (void *arg);
235 : static void handle_connections (int listen_fd);
236 :
237 : /* Pth wrapper function definitions. */
238 0 : ASSUAN_SYSTEM_NPTH_IMPL;
239 :
240 : static int active_connections;
241 :
242 :
243 : static char *
244 0 : make_libversion (const char *libname, const char *(*getfnc)(const char*))
245 : {
246 : const char *s;
247 : char *result;
248 :
249 0 : if (maybe_setuid)
250 : {
251 0 : gcry_control (GCRYCTL_INIT_SECMEM, 0, 0); /* Drop setuid. */
252 0 : maybe_setuid = 0;
253 : }
254 0 : s = getfnc (NULL);
255 0 : result = xmalloc (strlen (libname) + 1 + strlen (s) + 1);
256 0 : strcpy (stpcpy (stpcpy (result, libname), " "), s);
257 0 : return result;
258 : }
259 :
260 :
261 : static const char *
262 0 : my_strusage (int level)
263 : {
264 : static char *ver_gcry, *ver_ksba;
265 : const char *p;
266 :
267 0 : switch (level)
268 : {
269 0 : case 11: p = "@SCDAEMON@ (@GNUPG@)";
270 0 : break;
271 0 : case 13: p = VERSION; break;
272 0 : case 17: p = PRINTABLE_OS_NAME; break;
273 0 : case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break;
274 :
275 : case 20:
276 0 : if (!ver_gcry)
277 0 : ver_gcry = make_libversion ("libgcrypt", gcry_check_version);
278 0 : p = ver_gcry;
279 0 : break;
280 : case 21:
281 0 : if (!ver_ksba)
282 0 : ver_ksba = make_libversion ("libksba", ksba_check_version);
283 0 : p = ver_ksba;
284 0 : break;
285 : case 1:
286 0 : case 40: p = _("Usage: @SCDAEMON@ [options] (-h for help)");
287 0 : break;
288 0 : case 41: p = _("Syntax: scdaemon [options] [command [args]]\n"
289 : "Smartcard daemon for @GNUPG@\n");
290 0 : break;
291 :
292 0 : default: p = NULL;
293 : }
294 0 : return p;
295 : }
296 :
297 :
298 : static int
299 0 : tid_log_callback (unsigned long *rvalue)
300 : {
301 0 : int len = sizeof (*rvalue);
302 : npth_t thread;
303 :
304 0 : thread = npth_self ();
305 0 : if (sizeof (thread) < len)
306 0 : len = sizeof (thread);
307 0 : memcpy (rvalue, &thread, len);
308 :
309 0 : return 2; /* Use use hex representation. */
310 : }
311 :
312 :
313 : /* Setup the debugging. With a LEVEL of NULL only the active debug
314 : flags are propagated to the subsystems. With LEVEL set, a specific
315 : set of debug flags is set; thus overriding all flags already
316 : set. */
317 : static void
318 0 : set_debug (const char *level)
319 : {
320 0 : int numok = (level && digitp (level));
321 0 : int numlvl = numok? atoi (level) : 0;
322 :
323 0 : if (!level)
324 : ;
325 0 : else if (!strcmp (level, "none") || (numok && numlvl < 1))
326 0 : opt.debug = 0;
327 0 : else if (!strcmp (level, "basic") || (numok && numlvl <= 2))
328 0 : opt.debug = DBG_IPC_VALUE;
329 0 : else if (!strcmp (level, "advanced") || (numok && numlvl <= 5))
330 0 : opt.debug = DBG_IPC_VALUE|DBG_COMMAND_VALUE;
331 0 : else if (!strcmp (level, "expert") || (numok && numlvl <= 8))
332 0 : opt.debug = (DBG_IPC_VALUE|DBG_COMMAND_VALUE
333 : |DBG_CACHE_VALUE|DBG_CARD_IO_VALUE);
334 0 : else if (!strcmp (level, "guru") || numok)
335 : {
336 0 : opt.debug = ~0;
337 : /* Unless the "guru" string has been used we don't want to allow
338 : hashing debugging. The rationale is that people tend to
339 : select the highest debug value and would then clutter their
340 : disk with debug files which may reveal confidential data. */
341 0 : if (numok)
342 0 : opt.debug &= ~(DBG_HASHING_VALUE);
343 : }
344 : else
345 : {
346 0 : log_error (_("invalid debug-level '%s' given\n"), level);
347 0 : scd_exit(2);
348 : }
349 :
350 :
351 0 : if (opt.debug && !opt.verbose)
352 0 : opt.verbose = 1;
353 0 : if (opt.debug && opt.quiet)
354 0 : opt.quiet = 0;
355 :
356 0 : if (opt.debug & DBG_MPI_VALUE)
357 0 : gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
358 0 : if (opt.debug & DBG_CRYPTO_VALUE )
359 0 : gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
360 0 : gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
361 :
362 0 : if (opt.debug)
363 0 : parse_debug_flag (NULL, &opt.debug, debug_flags);
364 0 : }
365 :
366 :
367 :
368 : static void
369 0 : cleanup (void)
370 : {
371 0 : if (socket_name && *socket_name)
372 : {
373 : char *name;
374 : char *p;
375 :
376 0 : name = redir_socket_name? redir_socket_name : socket_name;
377 :
378 0 : gnupg_remove (name);
379 0 : p = strrchr (name, '/');
380 0 : if (p)
381 : {
382 0 : *p = 0;
383 0 : rmdir (name);
384 0 : *p = '/';
385 : }
386 0 : *socket_name = 0;
387 : }
388 0 : }
389 :
390 :
391 :
392 : int
393 0 : main (int argc, char **argv )
394 : {
395 : ARGPARSE_ARGS pargs;
396 : int orig_argc;
397 : char **orig_argv;
398 0 : FILE *configfp = NULL;
399 0 : char *configname = NULL;
400 : const char *shell;
401 : unsigned int configlineno;
402 0 : int parse_debug = 0;
403 0 : const char *debug_level = NULL;
404 0 : int default_config =1;
405 0 : int greeting = 0;
406 0 : int nogreeting = 0;
407 0 : int multi_server = 0;
408 0 : int is_daemon = 0;
409 0 : int nodetach = 0;
410 0 : int csh_style = 0;
411 0 : char *logfile = NULL;
412 0 : int debug_wait = 0;
413 0 : int gpgconf_list = 0;
414 0 : const char *config_filename = NULL;
415 0 : int allow_coredump = 0;
416 : struct assuan_malloc_hooks malloc_hooks;
417 : int res;
418 : npth_t pipecon_handler;
419 :
420 0 : early_system_init ();
421 0 : set_strusage (my_strusage);
422 0 : gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
423 : /* Please note that we may running SUID(ROOT), so be very CAREFUL
424 : when adding any stuff between here and the call to INIT_SECMEM()
425 : somewhere after the option parsing */
426 0 : log_set_prefix ("scdaemon", 1|4);
427 :
428 : /* Make sure that our subsystems are ready. */
429 0 : i18n_init ();
430 0 : init_common_subsystems (&argc, &argv);
431 :
432 0 : npth_init ();
433 :
434 : /* Check that the libraries are suitable. Do it here because
435 : the option parsing may need services of the library */
436 0 : if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
437 : {
438 0 : log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
439 : NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
440 : }
441 :
442 0 : ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
443 :
444 0 : malloc_hooks.malloc = gcry_malloc;
445 0 : malloc_hooks.realloc = gcry_realloc;
446 0 : malloc_hooks.free = gcry_free;
447 0 : assuan_set_malloc_hooks (&malloc_hooks);
448 0 : assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
449 0 : assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
450 0 : assuan_sock_init ();
451 0 : setup_libassuan_logging (&opt.debug);
452 :
453 0 : setup_libgcrypt_logging ();
454 0 : gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
455 :
456 0 : disable_core_dumps ();
457 :
458 : /* Set default options. */
459 0 : opt.allow_admin = 1;
460 0 : opt.pcsc_driver = DEFAULT_PCSC_DRIVER;
461 :
462 0 : shell = getenv ("SHELL");
463 0 : if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
464 0 : csh_style = 1;
465 :
466 0 : opt.homedir = default_homedir ();
467 :
468 : /* Check whether we have a config file on the commandline */
469 0 : orig_argc = argc;
470 0 : orig_argv = argv;
471 0 : pargs.argc = &argc;
472 0 : pargs.argv = &argv;
473 0 : pargs.flags= 1|(1<<6); /* do not remove the args, ignore version */
474 0 : while (arg_parse( &pargs, opts))
475 : {
476 0 : if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
477 0 : parse_debug++;
478 0 : else if (pargs.r_opt == oOptions)
479 : { /* yes there is one, so we do not try the default one, but
480 : read the option file when it is encountered at the
481 : commandline */
482 0 : default_config = 0;
483 : }
484 0 : else if (pargs.r_opt == oNoOptions)
485 0 : default_config = 0; /* --no-options */
486 0 : else if (pargs.r_opt == oHomedir)
487 0 : opt.homedir = pargs.r.ret_str;
488 : }
489 :
490 : /* initialize the secure memory. */
491 0 : gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
492 0 : maybe_setuid = 0;
493 :
494 : /*
495 : Now we are working under our real uid
496 : */
497 :
498 :
499 0 : if (default_config)
500 0 : configname = make_filename (opt.homedir, SCDAEMON_NAME EXTSEP_S "conf",
501 : NULL );
502 :
503 :
504 0 : argc = orig_argc;
505 0 : argv = orig_argv;
506 0 : pargs.argc = &argc;
507 0 : pargs.argv = &argv;
508 0 : pargs.flags= 1; /* do not remove the args */
509 : next_pass:
510 0 : if (configname)
511 : {
512 0 : configlineno = 0;
513 0 : configfp = fopen (configname, "r");
514 0 : if (!configfp)
515 : {
516 0 : if (default_config)
517 : {
518 0 : if( parse_debug )
519 0 : log_info (_("Note: no default option file '%s'\n"),
520 : configname );
521 : }
522 : else
523 : {
524 0 : log_error (_("option file '%s': %s\n"),
525 0 : configname, strerror(errno) );
526 0 : exit(2);
527 : }
528 0 : xfree (configname);
529 0 : configname = NULL;
530 : }
531 0 : if (parse_debug && configname )
532 0 : log_info (_("reading options from '%s'\n"), configname );
533 0 : default_config = 0;
534 : }
535 :
536 0 : while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
537 : {
538 0 : switch (pargs.r_opt)
539 : {
540 0 : case aGPGConfList: gpgconf_list = 1; break;
541 0 : case aGPGConfTest: gpgconf_list = 2; break;
542 0 : case oQuiet: opt.quiet = 1; break;
543 0 : case oVerbose: opt.verbose++; break;
544 0 : case oBatch: opt.batch=1; break;
545 :
546 : case oDebug:
547 0 : if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
548 : {
549 0 : pargs.r_opt = ARGPARSE_INVALID_ARG;
550 0 : pargs.err = ARGPARSE_PRINT_ERROR;
551 : }
552 0 : break;
553 0 : case oDebugAll: opt.debug = ~0; break;
554 0 : case oDebugLevel: debug_level = pargs.r.ret_str; break;
555 0 : case oDebugWait: debug_wait = pargs.r.ret_int; break;
556 : case oDebugAllowCoreDump:
557 0 : enable_core_dumps ();
558 0 : allow_coredump = 1;
559 0 : break;
560 : case oDebugCCIDDriver:
561 : #ifdef HAVE_LIBUSB
562 : ccid_set_debug_level (ccid_set_debug_level (-1)+1);
563 : #endif /*HAVE_LIBUSB*/
564 0 : break;
565 0 : case oDebugDisableTicker: ticker_disabled = 1; break;
566 : case oDebugLogTid:
567 0 : log_set_pid_suffix_cb (tid_log_callback);
568 0 : break;
569 : case oDebugAssuanLogCats:
570 0 : set_libassuan_log_cats (pargs.r.ret_ulong);
571 0 : break;
572 :
573 : case oOptions:
574 : /* config files may not be nested (silently ignore them) */
575 0 : if (!configfp)
576 : {
577 0 : xfree(configname);
578 0 : configname = xstrdup(pargs.r.ret_str);
579 0 : goto next_pass;
580 : }
581 0 : break;
582 0 : case oNoGreeting: nogreeting = 1; break;
583 0 : case oNoVerbose: opt.verbose = 0; break;
584 0 : case oNoOptions: break; /* no-options */
585 0 : case oHomedir: opt.homedir = pargs.r.ret_str; break;
586 0 : case oNoDetach: nodetach = 1; break;
587 0 : case oLogFile: logfile = pargs.r.ret_str; break;
588 0 : case oCsh: csh_style = 1; break;
589 0 : case oSh: csh_style = 0; break;
590 0 : case oServer: pipe_server = 1; break;
591 0 : case oMultiServer: pipe_server = 1; multi_server = 1; break;
592 0 : case oDaemon: is_daemon = 1; break;
593 :
594 0 : case oReaderPort: opt.reader_port = pargs.r.ret_str; break;
595 0 : case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
596 0 : case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
597 0 : case oDisableCCID: opt.disable_ccid = 1; break;
598 0 : case oDisableOpenSC: break;
599 :
600 0 : case oDisablePinpad: opt.disable_pinpad = 1; break;
601 :
602 : case oAllowAdmin: /* Dummy because allow is now the default. */
603 0 : break;
604 0 : case oDenyAdmin: opt.allow_admin = 0; break;
605 :
606 0 : case oCardTimeout: opt.card_timeout = pargs.r.ret_ulong; break;
607 :
608 : case oDisableApplication:
609 0 : add_to_strlist (&opt.disabled_applications, pargs.r.ret_str);
610 0 : break;
611 :
612 0 : case oEnablePinpadVarlen: opt.enable_pinpad_varlen = 1; break;
613 :
614 : default:
615 0 : pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
616 0 : break;
617 : }
618 : }
619 0 : if (configfp)
620 : {
621 0 : fclose( configfp );
622 0 : configfp = NULL;
623 : /* Keep a copy of the config name for use by --gpgconf-list. */
624 0 : config_filename = configname;
625 0 : configname = NULL;
626 0 : goto next_pass;
627 : }
628 0 : xfree (configname);
629 0 : configname = NULL;
630 0 : if (log_get_errorcount(0))
631 0 : exit(2);
632 0 : if (nogreeting )
633 0 : greeting = 0;
634 :
635 0 : if (greeting)
636 : {
637 0 : es_fprintf (es_stderr, "%s %s; %s\n",
638 : strusage(11), strusage(13), strusage(14) );
639 0 : es_fprintf (es_stderr, "%s\n", strusage(15) );
640 : }
641 : #ifdef IS_DEVELOPMENT_VERSION
642 : log_info ("NOTE: this is a development version!\n");
643 : #endif
644 :
645 : /* Print a warning if an argument looks like an option. */
646 0 : if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
647 : {
648 : int i;
649 :
650 0 : for (i=0; i < argc; i++)
651 0 : if (argv[i][0] == '-' && argv[i][1] == '-')
652 0 : log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
653 : }
654 :
655 0 : if (atexit (cleanup))
656 : {
657 0 : log_error ("atexit failed\n");
658 0 : cleanup ();
659 0 : exit (1);
660 : }
661 :
662 0 : set_debug (debug_level);
663 :
664 0 : initialize_module_command ();
665 :
666 0 : if (gpgconf_list == 2)
667 0 : scd_exit (0);
668 0 : if (gpgconf_list)
669 : {
670 : /* List options and default values in the GPG Conf format. */
671 0 : char *filename = NULL;
672 : char *filename_esc;
673 :
674 0 : if (config_filename)
675 0 : filename = xstrdup (config_filename);
676 : else
677 0 : filename = make_filename (opt.homedir, SCDAEMON_NAME EXTSEP_S "conf",
678 : NULL);
679 0 : filename_esc = percent_escape (filename, NULL);
680 :
681 0 : es_printf ("%s-%s.conf:%lu:\"%s\n",
682 : GPGCONF_NAME, SCDAEMON_NAME,
683 : GC_OPT_FLAG_DEFAULT, filename_esc);
684 0 : xfree (filename_esc);
685 0 : xfree (filename);
686 :
687 0 : es_printf ("verbose:%lu:\n"
688 : "quiet:%lu:\n"
689 : "debug-level:%lu:\"none:\n"
690 : "log-file:%lu:\n",
691 : GC_OPT_FLAG_NONE,
692 : GC_OPT_FLAG_NONE,
693 : GC_OPT_FLAG_DEFAULT,
694 : GC_OPT_FLAG_NONE );
695 :
696 0 : es_printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE );
697 0 : es_printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE );
698 0 : es_printf ("pcsc-driver:%lu:\"%s:\n",
699 : GC_OPT_FLAG_DEFAULT, DEFAULT_PCSC_DRIVER );
700 : #ifdef HAVE_LIBUSB
701 : es_printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE );
702 : #endif
703 0 : es_printf ("deny-admin:%lu:\n", GC_OPT_FLAG_NONE );
704 0 : es_printf ("disable-pinpad:%lu:\n", GC_OPT_FLAG_NONE );
705 0 : es_printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0);
706 0 : es_printf ("enable-pinpad-varlen:%lu:\n", GC_OPT_FLAG_NONE );
707 :
708 0 : scd_exit (0);
709 : }
710 :
711 : /* Now start with logging to a file if this is desired. */
712 0 : if (logfile)
713 : {
714 0 : log_set_file (logfile);
715 0 : log_set_prefix (NULL, 1|2|4);
716 : }
717 :
718 0 : if (debug_wait && pipe_server)
719 : {
720 0 : log_debug ("waiting for debugger - my pid is %u .....\n",
721 0 : (unsigned int)getpid());
722 0 : gnupg_sleep (debug_wait);
723 0 : log_debug ("... okay\n");
724 : }
725 :
726 0 : if (pipe_server)
727 : {
728 : /* This is the simple pipe based server */
729 : ctrl_t ctrl;
730 : npth_attr_t tattr;
731 0 : int fd = -1;
732 :
733 : #ifndef HAVE_W32_SYSTEM
734 : {
735 : struct sigaction sa;
736 :
737 0 : sa.sa_handler = SIG_IGN;
738 0 : sigemptyset (&sa.sa_mask);
739 0 : sa.sa_flags = 0;
740 0 : sigaction (SIGPIPE, &sa, NULL);
741 : }
742 : #endif
743 :
744 : /* If --debug-allow-core-dump has been given we also need to
745 : switch the working directory to a place where we can actually
746 : write. */
747 0 : if (allow_coredump)
748 : {
749 0 : if (chdir("/tmp"))
750 0 : log_debug ("chdir to '/tmp' failed: %s\n", strerror (errno));
751 : else
752 0 : log_debug ("changed working directory to '/tmp'\n");
753 : }
754 :
755 : /* In multi server mode we need to listen on an additional
756 : socket. Create that socket now before starting the handler
757 : for the pipe connection. This allows that handler to send
758 : back the name of that socket. */
759 0 : if (multi_server)
760 : {
761 0 : socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
762 0 : fd = FD2INT(create_server_socket (socket_name,
763 : &redir_socket_name, &socket_nonce));
764 : }
765 :
766 0 : res = npth_attr_init (&tattr);
767 0 : if (res)
768 : {
769 0 : log_error ("error allocating thread attributes: %s\n",
770 : strerror (res));
771 0 : scd_exit (2);
772 : }
773 0 : npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
774 :
775 0 : ctrl = xtrycalloc (1, sizeof *ctrl);
776 0 : if ( !ctrl )
777 : {
778 0 : log_error ("error allocating connection control data: %s\n",
779 0 : strerror (errno) );
780 0 : scd_exit (2);
781 : }
782 0 : ctrl->thread_startup.fd = GNUPG_INVALID_FD;
783 0 : res = npth_create (&pipecon_handler, &tattr, start_connection_thread, ctrl);
784 0 : if (res)
785 : {
786 0 : log_error ("error spawning pipe connection handler: %s\n",
787 : strerror (res) );
788 0 : xfree (ctrl);
789 0 : scd_exit (2);
790 : }
791 0 : npth_setname_np (pipecon_handler, "pipe-connection");
792 0 : npth_attr_destroy (&tattr);
793 :
794 : /* We run handle_connection to wait for the shutdown signal and
795 : to run the ticker stuff. */
796 0 : handle_connections (fd);
797 0 : if (fd != -1)
798 0 : close (fd);
799 : }
800 0 : else if (!is_daemon)
801 : {
802 0 : log_info (_("please use the option '--daemon'"
803 : " to run the program in the background\n"));
804 : }
805 : else
806 : { /* Regular server mode */
807 : int fd;
808 : #ifndef HAVE_W32_SYSTEM
809 : pid_t pid;
810 : int i;
811 : #endif
812 :
813 : /* Create the socket. */
814 0 : socket_name = create_socket_name (SCDAEMON_SOCK_NAME);
815 0 : fd = FD2INT (create_server_socket (socket_name,
816 : &redir_socket_name, &socket_nonce));
817 :
818 :
819 0 : fflush (NULL);
820 : #ifdef HAVE_W32_SYSTEM
821 : (void)csh_style;
822 : (void)nodetach;
823 : #else
824 0 : pid = fork ();
825 0 : if (pid == (pid_t)-1)
826 : {
827 0 : log_fatal ("fork failed: %s\n", strerror (errno) );
828 : exit (1);
829 : }
830 0 : else if (pid)
831 : { /* we are the parent */
832 : char *infostr;
833 :
834 0 : close (fd);
835 :
836 : /* create the info string: <name>:<pid>:<protocol_version> */
837 0 : if (gpgrt_asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1",
838 : socket_name, (ulong) pid) < 0)
839 : {
840 0 : log_error ("out of core\n");
841 0 : kill (pid, SIGTERM);
842 0 : exit (1);
843 : }
844 0 : *socket_name = 0; /* don't let cleanup() remove the socket -
845 : the child should do this from now on */
846 0 : if (argc)
847 : { /* run the program given on the commandline */
848 0 : if (putenv (infostr))
849 : {
850 0 : log_error ("failed to set environment: %s\n",
851 0 : strerror (errno) );
852 0 : kill (pid, SIGTERM );
853 0 : exit (1);
854 : }
855 0 : execvp (argv[0], argv);
856 0 : log_error ("failed to run the command: %s\n", strerror (errno));
857 0 : kill (pid, SIGTERM);
858 0 : exit (1);
859 : }
860 : else
861 : {
862 : /* Print the environment string, so that the caller can use
863 : shell's eval to set it */
864 0 : if (csh_style)
865 : {
866 0 : *strchr (infostr, '=') = ' ';
867 0 : es_printf ( "setenv %s;\n", infostr);
868 : }
869 : else
870 : {
871 0 : es_printf ( "%s; export SCDAEMON_INFO;\n", infostr);
872 : }
873 0 : xfree (infostr);
874 0 : exit (0);
875 : }
876 : /* NOTREACHED */
877 : } /* end parent */
878 :
879 : /* This is the child. */
880 :
881 : /* Detach from tty and put process into a new session. */
882 0 : if (!nodetach )
883 : {
884 : /* Close stdin, stdout and stderr unless it is the log stream. */
885 0 : for (i=0; i <= 2; i++)
886 : {
887 0 : if ( log_test_fd (i) && i != fd)
888 0 : close (i);
889 : }
890 0 : if (setsid() == -1)
891 : {
892 0 : log_error ("setsid() failed: %s\n", strerror(errno) );
893 0 : cleanup ();
894 0 : exit (1);
895 : }
896 : }
897 :
898 : {
899 : struct sigaction sa;
900 :
901 0 : sa.sa_handler = SIG_IGN;
902 0 : sigemptyset (&sa.sa_mask);
903 0 : sa.sa_flags = 0;
904 0 : sigaction (SIGPIPE, &sa, NULL);
905 : }
906 :
907 0 : if (chdir("/"))
908 : {
909 0 : log_error ("chdir to / failed: %s\n", strerror (errno));
910 0 : exit (1);
911 : }
912 :
913 : #endif /*!HAVE_W32_SYSTEM*/
914 :
915 0 : handle_connections (fd);
916 :
917 0 : close (fd);
918 : }
919 :
920 0 : return 0;
921 : }
922 :
923 : void
924 0 : scd_exit (int rc)
925 : {
926 0 : apdu_prepare_exit ();
927 : #if 0
928 : #warning no update_random_seed_file
929 : update_random_seed_file();
930 : #endif
931 : #if 0
932 : /* at this time a bit annoying */
933 : if (opt.debug & DBG_MEMSTAT_VALUE)
934 : {
935 : gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
936 : gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
937 : }
938 : if (opt.debug)
939 : gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
940 : #endif
941 0 : gcry_control (GCRYCTL_TERM_SECMEM );
942 0 : rc = rc? rc : log_get_errorcount(0)? 2 : 0;
943 0 : exit (rc);
944 : }
945 :
946 :
947 : static void
948 0 : scd_init_default_ctrl (ctrl_t ctrl)
949 : {
950 : (void)ctrl;
951 0 : }
952 :
953 : static void
954 0 : scd_deinit_default_ctrl (ctrl_t ctrl)
955 : {
956 0 : if (!ctrl)
957 0 : return;
958 0 : xfree (ctrl->in_data.value);
959 0 : ctrl->in_data.value = NULL;
960 0 : ctrl->in_data.valuelen = 0;
961 : }
962 :
963 :
964 : /* Return the name of the socket to be used to connect to this
965 : process. If no socket is available, return NULL. */
966 : const char *
967 0 : scd_get_socket_name ()
968 : {
969 0 : if (socket_name && *socket_name)
970 0 : return socket_name;
971 0 : return NULL;
972 : }
973 :
974 :
975 : #ifndef HAVE_W32_SYSTEM
976 : static void
977 0 : handle_signal (int signo)
978 : {
979 0 : switch (signo)
980 : {
981 : case SIGHUP:
982 0 : log_info ("SIGHUP received - "
983 : "re-reading configuration and resetting cards\n");
984 : /* reread_configuration (); */
985 0 : break;
986 :
987 : case SIGUSR1:
988 0 : log_info ("SIGUSR1 received - printing internal information:\n");
989 : /* Fixme: We need to see how to integrate pth dumping into our
990 : logging system. */
991 : /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
992 0 : app_dump_state ();
993 0 : break;
994 :
995 : case SIGUSR2:
996 0 : log_info ("SIGUSR2 received - no action defined\n");
997 0 : break;
998 :
999 : case SIGTERM:
1000 0 : if (!shutdown_pending)
1001 0 : log_info ("SIGTERM received - shutting down ...\n");
1002 : else
1003 0 : log_info ("SIGTERM received - still %i running threads\n",
1004 : active_connections);
1005 0 : shutdown_pending++;
1006 0 : if (shutdown_pending > 2)
1007 : {
1008 0 : log_info ("shutdown forced\n");
1009 0 : log_info ("%s %s stopped\n", strusage(11), strusage(13) );
1010 0 : cleanup ();
1011 0 : scd_exit (0);
1012 : }
1013 0 : break;
1014 :
1015 : case SIGINT:
1016 0 : log_info ("SIGINT received - immediate shutdown\n");
1017 0 : log_info( "%s %s stopped\n", strusage(11), strusage(13));
1018 0 : cleanup ();
1019 0 : scd_exit (0);
1020 0 : break;
1021 :
1022 : default:
1023 0 : log_info ("signal %d received - no action defined\n", signo);
1024 : }
1025 0 : }
1026 : #endif /*!HAVE_W32_SYSTEM*/
1027 :
1028 :
1029 : static void
1030 0 : handle_tick (void)
1031 : {
1032 0 : if (!ticker_disabled)
1033 0 : scd_update_reader_status_file ();
1034 0 : }
1035 :
1036 :
1037 : /* Create a name for the socket. We check for valid characters as
1038 : well as against a maximum allowed length for a unix domain socket
1039 : is done. The function terminates the process in case of an error.
1040 : Retunrs: Pointer to an allcoated string with the absolute name of
1041 : the socket used. */
1042 : static char *
1043 0 : create_socket_name (char *standard_name)
1044 : {
1045 : char *name;
1046 :
1047 0 : name = make_filename (opt.homedir, standard_name, NULL);
1048 0 : if (strchr (name, PATHSEP_C))
1049 : {
1050 0 : log_error (("'%s' are not allowed in the socket name\n"), PATHSEP_S);
1051 0 : scd_exit (2);
1052 : }
1053 0 : return name;
1054 : }
1055 :
1056 :
1057 :
1058 : /* Create a Unix domain socket with NAME. Returns the file descriptor
1059 : or terminates the process in case of an error. If the socket has
1060 : been redirected the name of the real socket is stored as a malloced
1061 : string at R_REDIR_NAME. */
1062 : static gnupg_fd_t
1063 0 : create_server_socket (const char *name, char **r_redir_name,
1064 : assuan_sock_nonce_t *nonce)
1065 : {
1066 : struct sockaddr *addr;
1067 : struct sockaddr_un *unaddr;
1068 : socklen_t len;
1069 : gnupg_fd_t fd;
1070 : int rc;
1071 :
1072 0 : xfree (*r_redir_name);
1073 0 : *r_redir_name = NULL;
1074 :
1075 0 : fd = assuan_sock_new (AF_UNIX, SOCK_STREAM, 0);
1076 0 : if (fd == GNUPG_INVALID_FD)
1077 : {
1078 0 : log_error (_("can't create socket: %s\n"), strerror (errno));
1079 0 : scd_exit (2);
1080 : }
1081 :
1082 0 : unaddr = xmalloc (sizeof (*unaddr));
1083 0 : addr = (struct sockaddr*)unaddr;
1084 :
1085 : #if ASSUAN_VERSION_NUMBER >= 0x020104 /* >= 2.1.4 */
1086 : {
1087 : int redirected;
1088 :
1089 0 : if (assuan_sock_set_sockaddr_un (name, addr, &redirected))
1090 : {
1091 0 : if (errno == ENAMETOOLONG)
1092 0 : log_error (_("socket name '%s' is too long\n"), name);
1093 : else
1094 0 : log_error ("error preparing socket '%s': %s\n",
1095 : name, gpg_strerror (gpg_error_from_syserror ()));
1096 0 : scd_exit (2);
1097 : }
1098 0 : if (redirected)
1099 : {
1100 0 : *r_redir_name = xstrdup (unaddr->sun_path);
1101 0 : if (opt.verbose)
1102 0 : log_info ("redirecting socket '%s' to '%s'\n", name, *r_redir_name);
1103 : }
1104 : }
1105 : #else /* Assuan < 2.1.4 */
1106 : memset (unaddr, 0, sizeof *unaddr);
1107 : unaddr->sun_family = AF_UNIX;
1108 : if (strlen (name) + 1 >= sizeof (unaddr->sun_path))
1109 : {
1110 : log_error (_("socket name '%s' is too long\n"), name);
1111 : scd_exit (2);
1112 : }
1113 : strcpy (unaddr->sun_path, name);
1114 : #endif /* Assuan < 2.1.4 */
1115 :
1116 0 : len = SUN_LEN (unaddr);
1117 :
1118 0 : rc = assuan_sock_bind (fd, addr, len);
1119 0 : if (rc == -1 && errno == EADDRINUSE)
1120 : {
1121 0 : gnupg_remove (unaddr->sun_path);
1122 0 : rc = assuan_sock_bind (fd, addr, len);
1123 : }
1124 0 : if (rc != -1
1125 0 : && (rc=assuan_sock_get_nonce (addr, len, nonce)))
1126 0 : log_error (_("error getting nonce for the socket\n"));
1127 0 : if (rc == -1)
1128 : {
1129 0 : log_error (_("error binding socket to '%s': %s\n"),
1130 0 : unaddr->sun_path,
1131 : gpg_strerror (gpg_error_from_syserror ()));
1132 0 : assuan_sock_close (fd);
1133 0 : scd_exit (2);
1134 : }
1135 :
1136 0 : if (listen (FD2INT(fd), 5 ) == -1)
1137 : {
1138 0 : log_error (_("listen() failed: %s\n"),
1139 : gpg_strerror (gpg_error_from_syserror ()));
1140 0 : assuan_sock_close (fd);
1141 0 : scd_exit (2);
1142 : }
1143 :
1144 0 : if (opt.verbose)
1145 0 : log_info (_("listening on socket '%s'\n"), unaddr->sun_path);
1146 :
1147 0 : return fd;
1148 : }
1149 :
1150 :
1151 :
1152 : /* This is the standard connection thread's main function. */
1153 : static void *
1154 0 : start_connection_thread (void *arg)
1155 : {
1156 0 : ctrl_t ctrl = arg;
1157 :
1158 0 : if (ctrl->thread_startup.fd != GNUPG_INVALID_FD
1159 0 : && assuan_sock_check_nonce (ctrl->thread_startup.fd, &socket_nonce))
1160 : {
1161 0 : log_info (_("error reading nonce on fd %d: %s\n"),
1162 0 : FD2INT(ctrl->thread_startup.fd), strerror (errno));
1163 0 : assuan_sock_close (ctrl->thread_startup.fd);
1164 0 : xfree (ctrl);
1165 0 : return NULL;
1166 : }
1167 :
1168 0 : scd_init_default_ctrl (ctrl);
1169 0 : if (opt.verbose)
1170 0 : log_info (_("handler for fd %d started\n"),
1171 : FD2INT(ctrl->thread_startup.fd));
1172 :
1173 : /* If this is a pipe server, we request a shutdown if the command
1174 : handler asked for it. With the next ticker event and given that
1175 : no other connections are running the shutdown will then
1176 : happen. */
1177 0 : if (scd_command_handler (ctrl, FD2INT(ctrl->thread_startup.fd))
1178 0 : && pipe_server)
1179 0 : shutdown_pending = 1;
1180 :
1181 0 : if (opt.verbose)
1182 0 : log_info (_("handler for fd %d terminated\n"),
1183 : FD2INT (ctrl->thread_startup.fd));
1184 :
1185 0 : scd_deinit_default_ctrl (ctrl);
1186 0 : xfree (ctrl);
1187 0 : return NULL;
1188 : }
1189 :
1190 :
1191 : /* Connection handler loop. Wait for connection requests and spawn a
1192 : thread after accepting a connection. LISTEN_FD is allowed to be -1
1193 : in which case this code will only do regular timeouts and handle
1194 : signals. */
1195 : static void
1196 0 : handle_connections (int listen_fd)
1197 : {
1198 : npth_attr_t tattr;
1199 : struct sockaddr_un paddr;
1200 : socklen_t plen;
1201 : fd_set fdset, read_fdset;
1202 : int ret;
1203 : int fd;
1204 : int nfd;
1205 : struct timespec abstime;
1206 : struct timespec curtime;
1207 : struct timespec timeout;
1208 : int saved_errno;
1209 : #ifndef HAVE_W32_SYSTEM
1210 : int signo;
1211 : #endif
1212 :
1213 0 : ret = npth_attr_init(&tattr);
1214 : /* FIXME: Check error. */
1215 0 : npth_attr_setdetachstate (&tattr, NPTH_CREATE_DETACHED);
1216 :
1217 : #ifndef HAVE_W32_SYSTEM
1218 0 : npth_sigev_init ();
1219 0 : npth_sigev_add (SIGHUP);
1220 0 : npth_sigev_add (SIGUSR1);
1221 0 : npth_sigev_add (SIGUSR2);
1222 0 : npth_sigev_add (SIGINT);
1223 0 : npth_sigev_add (SIGTERM);
1224 0 : npth_sigev_fini ();
1225 : #endif
1226 :
1227 0 : FD_ZERO (&fdset);
1228 0 : nfd = 0;
1229 0 : if (listen_fd != -1)
1230 : {
1231 0 : FD_SET (listen_fd, &fdset);
1232 0 : nfd = listen_fd;
1233 : }
1234 :
1235 0 : npth_clock_gettime (&curtime);
1236 0 : timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
1237 0 : timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
1238 0 : npth_timeradd (&curtime, &timeout, &abstime);
1239 : /* We only require abstime here. The others will be reused. */
1240 :
1241 : for (;;)
1242 : {
1243 0 : if (shutdown_pending)
1244 : {
1245 0 : if (active_connections == 0)
1246 0 : break; /* ready */
1247 :
1248 : /* Do not accept anymore connections but wait for existing
1249 : connections to terminate. We do this by clearing out all
1250 : file descriptors to wait for, so that the select will be
1251 : used to just wait on a signal or timeout event. */
1252 0 : FD_ZERO (&fdset);
1253 0 : listen_fd = -1;
1254 : }
1255 :
1256 0 : npth_clock_gettime (&curtime);
1257 0 : if (!(npth_timercmp (&curtime, &abstime, <)))
1258 : {
1259 : /* Timeout. */
1260 0 : handle_tick ();
1261 0 : timeout.tv_sec = TIMERTICK_INTERVAL_SEC;
1262 0 : timeout.tv_nsec = TIMERTICK_INTERVAL_USEC * 1000;
1263 0 : npth_timeradd (&curtime, &timeout, &abstime);
1264 : }
1265 0 : npth_timersub (&abstime, &curtime, &timeout);
1266 :
1267 : /* POSIX says that fd_set should be implemented as a structure,
1268 : thus a simple assignment is fine to copy the entire set. */
1269 0 : read_fdset = fdset;
1270 :
1271 : #ifndef HAVE_W32_SYSTEM
1272 0 : ret = npth_pselect (nfd+1, &read_fdset, NULL, NULL, &timeout, npth_sigev_sigmask());
1273 0 : saved_errno = errno;
1274 :
1275 0 : while (npth_sigev_get_pending(&signo))
1276 0 : handle_signal (signo);
1277 : #else
1278 : ret = npth_eselect (nfd+1, &read_fdset, NULL, NULL, &timeout, NULL, NULL);
1279 : saved_errno = errno;
1280 : #endif
1281 :
1282 0 : if (ret == -1 && saved_errno != EINTR)
1283 : {
1284 0 : log_error (_("npth_pselect failed: %s - waiting 1s\n"),
1285 : strerror (saved_errno));
1286 0 : npth_sleep (1);
1287 0 : continue;
1288 : }
1289 :
1290 0 : if (ret <= 0)
1291 : /* Timeout. Will be handled when calculating the next timeout. */
1292 0 : continue;
1293 :
1294 0 : if (listen_fd != -1 && FD_ISSET (listen_fd, &read_fdset))
1295 : {
1296 : ctrl_t ctrl;
1297 :
1298 0 : plen = sizeof paddr;
1299 0 : fd = npth_accept (listen_fd, (struct sockaddr *)&paddr, &plen);
1300 0 : if (fd == -1)
1301 : {
1302 0 : log_error ("accept failed: %s\n", strerror (errno));
1303 : }
1304 0 : else if ( !(ctrl = xtrycalloc (1, sizeof *ctrl)) )
1305 : {
1306 0 : log_error ("error allocating connection control data: %s\n",
1307 0 : strerror (errno) );
1308 0 : close (fd);
1309 : }
1310 : else
1311 : {
1312 : char threadname[50];
1313 : npth_t thread;
1314 :
1315 0 : snprintf (threadname, sizeof threadname-1, "conn fd=%d", fd);
1316 0 : threadname[sizeof threadname -1] = 0;
1317 0 : ctrl->thread_startup.fd = INT2FD (fd);
1318 0 : ret = npth_create (&thread, &tattr, start_connection_thread, ctrl);
1319 0 : if (ret)
1320 : {
1321 0 : log_error ("error spawning connection handler: %s\n",
1322 : strerror (ret));
1323 0 : xfree (ctrl);
1324 0 : close (fd);
1325 : }
1326 : else
1327 0 : npth_setname_np (thread, threadname);
1328 : }
1329 0 : fd = -1;
1330 : }
1331 0 : }
1332 :
1333 0 : cleanup ();
1334 0 : log_info (_("%s %s stopped\n"), strusage(11), strusage(13));
1335 0 : npth_attr_destroy (&tattr);
1336 0 : }
|