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