~ubuntu-branches/ubuntu/dapper/gnupg2/dapper

« back to all changes in this revision

Viewing changes to scd/scdaemon.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-03-29 10:30:32 UTC
  • Revision ID: james.westby@ubuntu.com-20050329103032-sj42n2ain3ipx310
Tags: upstream-1.9.15
ImportĀ upstreamĀ versionĀ 1.9.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* scdaemon.c  -  The GnuPG Smartcard Daemon
 
2
 *      Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
 
3
 *
 
4
 * This file is part of GnuPG.
 
5
 *
 
6
 * GnuPG is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * GnuPG is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software
 
18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
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
#ifdef USE_GNU_PTH
 
39
# include <pth.h>
 
40
#endif
 
41
 
 
42
#define JNLIB_NEED_LOG_LOGV
 
43
#include "scdaemon.h"
 
44
#include <ksba.h>
 
45
#include <gcrypt.h>
 
46
 
 
47
#include <assuan.h> /* malloc hooks */
 
48
 
 
49
#include "i18n.h"
 
50
#include "sysutils.h"
 
51
#include "app-common.h"
 
52
#ifdef HAVE_W32_SYSTEM
 
53
#include "../jnlib/w32-afunix.h"
 
54
#endif
 
55
 
 
56
 
 
57
enum cmd_and_opt_values 
 
58
{ aNull = 0,
 
59
  oCsh            = 'c',
 
60
  oQuiet          = 'q',
 
61
  oSh             = 's',
 
62
  oVerbose        = 'v',
 
63
  
 
64
  oNoVerbose = 500,
 
65
  aGPGConfList,
 
66
  oOptions,
 
67
  oDebug,
 
68
  oDebugAll,
 
69
  oDebugLevel,
 
70
  oDebugWait,
 
71
  oDebugSC,
 
72
  oNoGreeting,
 
73
  oNoOptions,
 
74
  oHomedir,
 
75
  oNoDetach,
 
76
  oNoGrab,
 
77
  oLogFile,
 
78
  oServer,
 
79
  oDaemon,
 
80
  oBatch,
 
81
  oReaderPort,
 
82
  octapiDriver,
 
83
  opcscDriver,
 
84
  oDisableCCID,
 
85
  oDisableOpenSC,
 
86
  oAllowAdmin,
 
87
  oDenyAdmin,
 
88
  oDisableApplication,
 
89
 
 
90
aTest };
 
91
 
 
92
 
 
93
 
 
94
static ARGPARSE_OPTS opts[] = {
 
95
 
 
96
  { aGPGConfList, "gpgconf-list", 256, "@" },
 
97
  
 
98
  { 301, NULL, 0, N_("@Options:\n ") },
 
99
 
 
100
  { oServer,   "server",     0, N_("run in server mode (foreground)") },
 
101
  { oDaemon,   "daemon",     0, N_("run in daemon mode (background)") },
 
102
  { oVerbose, "verbose",   0, N_("verbose") },
 
103
  { oQuiet,     "quiet",     0, N_("be somewhat more quiet") },
 
104
  { oSh,        "sh",        0, N_("sh-style command output") },
 
105
  { oCsh,       "csh",       0, N_("csh-style command output") },
 
106
  { oOptions, "options"  , 2, N_("read options from file")},
 
107
  { oDebug,     "debug"     ,4|16, "@"},
 
108
  { oDebugAll, "debug-all"     ,0, "@"},
 
109
  { oDebugLevel, "debug-level" ,2, "@"},
 
110
  { oDebugWait,"debug-wait",1, "@"},
 
111
  { oDebugSC,  "debug-sc",  1, N_("|N|set OpenSC debug level to N")},
 
112
  { oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
 
113
  { oLogFile,  "log-file"   ,2, N_("use a log file for the server")},
 
114
  { oReaderPort, "reader-port", 2, N_("|N|connect to reader at port N")},
 
115
  { octapiDriver, "ctapi-driver", 2, N_("|NAME|use NAME as ct-API driver")},
 
116
  { opcscDriver, "pcsc-driver", 2, N_("|NAME|use NAME as PC/SC driver")},
 
117
  { oDisableCCID, "disable-ccid", 0,
 
118
#ifdef HAVE_LIBUSB
 
119
                                    N_("do not use the internal CCID driver")
 
120
#else
 
121
                                    "@"
 
122
#endif
 
123
                                         /* end --disable-ccid */},
 
124
  { oDisableOpenSC, "disable-opensc", 0,
 
125
#ifdef HAVE_OPENSC
 
126
                                    N_("do not use the OpenSC layer")
 
127
#else
 
128
                                    "@"
 
129
#endif
 
130
                                         /* end --disable-opensc */},
 
131
  { oAllowAdmin, "allow-admin", 0, N_("allow the use of admin card commands")},
 
132
  { oDenyAdmin,  "deny-admin",  0, "@" },  
 
133
  { oDisableApplication, "disable-application", 2, "@"},
 
134
 
 
135
  {0}
 
136
};
 
137
 
 
138
 
 
139
/* The card dirver we use by default for PC/SC.  */
 
140
#ifdef HAVE_W32_SYSTEM
 
141
#define DEFAULT_PCSC_DRIVER "winscard.dll"
 
142
#else
 
143
#define DEFAULT_PCSC_DRIVER "libpcsclite.so"
 
144
#endif
 
145
 
 
146
 
 
147
static volatile int caught_fatal_sig = 0;
 
148
 
 
149
/* Flag to indicate that a shutdown was requested. */
 
150
static int shutdown_pending;
 
151
 
 
152
/* It is possible that we are currently running under setuid permissions */
 
153
static int maybe_setuid = 1;
 
154
 
 
155
/* Name of the communication socket */
 
156
static char socket_name[128];
 
157
 
 
158
 
 
159
#ifndef HAVE_OPENSC
 
160
#ifdef USE_GNU_PTH
 
161
/* Pth wrapper function definitions. */
 
162
GCRY_THREAD_OPTION_PTH_IMPL;
 
163
 
 
164
static void *ticker_thread (void *arg);
 
165
#endif /*USE_GNU_PTH*/
 
166
#endif /*!HAVE_OPENSC*/
 
167
 
 
168
static const char *
 
169
my_strusage (int level)
 
170
{
 
171
  const char *p;
 
172
  switch (level)
 
173
    {
 
174
    case 11: p = "scdaemon (GnuPG)";
 
175
      break;
 
176
    case 13: p = VERSION; break;
 
177
    case 17: p = PRINTABLE_OS_NAME; break;
 
178
    case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
 
179
      break;
 
180
    case 1:
 
181
    case 40: p =  _("Usage: scdaemon [options] (-h for help)");
 
182
      break;
 
183
    case 41: p =  _("Syntax: scdaemon [options] [command [args]]\n"
 
184
                    "Smartcard daemon for GnuPG\n");
 
185
    break;
 
186
    
 
187
    default: p = NULL;
 
188
    }
 
189
  return p;
 
190
}
 
191
 
 
192
 
 
193
 
 
194
static void
 
195
i18n_init (void)
 
196
{
 
197
#ifdef USE_SIMPLE_GETTEXT
 
198
    set_gettext_file( PACKAGE_GT );
 
199
#else
 
200
#ifdef ENABLE_NLS
 
201
    setlocale (LC_ALL, "");
 
202
    bindtextdomain (PACKAGE_GT, LOCALEDIR);
 
203
    textdomain (PACKAGE_GT);
 
204
#endif
 
205
#endif
 
206
}
 
207
 
 
208
 
 
209
 
 
210
/* Used by gcry for logging */
 
211
static void
 
212
my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
 
213
{
 
214
  /* translate the log levels */
 
215
  switch (level)
 
216
    {
 
217
    case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
 
218
    case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
 
219
    case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
 
220
    case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
 
221
    case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
 
222
    case GCRY_LOG_BUG:  level = JNLIB_LOG_BUG; break;
 
223
    case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
 
224
    default:            level = JNLIB_LOG_ERROR; break;  
 
225
    }
 
226
  log_logv (level, fmt, arg_ptr);
 
227
}
 
228
 
 
229
 
 
230
/* Setup the debugging.  With a LEVEL of NULL only the active debug
 
231
   flags are propagated to the subsystems.  With LEVEL set, a specific
 
232
   set of debug flags is set; thus overriding all flags already
 
233
   set. */
 
234
static void
 
235
set_debug (const char *level)
 
236
{
 
237
  if (!level)
 
238
    ;
 
239
  else if (!strcmp (level, "none"))
 
240
    opt.debug = 0;
 
241
  else if (!strcmp (level, "basic"))
 
242
    opt.debug = DBG_ASSUAN_VALUE;
 
243
  else if (!strcmp (level, "advanced"))
 
244
    opt.debug = DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE;
 
245
  else if (!strcmp (level, "expert"))
 
246
    opt.debug = (DBG_ASSUAN_VALUE|DBG_COMMAND_VALUE
 
247
                 |DBG_CACHE_VALUE|DBG_CARD_IO_VALUE);
 
248
  else if (!strcmp (level, "guru"))
 
249
    opt.debug = ~0;
 
250
  else
 
251
    {
 
252
      log_error (_("invalid debug-level `%s' given\n"), level);
 
253
      scd_exit(2);
 
254
    }
 
255
 
 
256
 
 
257
  if (opt.debug && !opt.verbose)
 
258
    opt.verbose = 1;
 
259
  if (opt.debug && opt.quiet)
 
260
    opt.quiet = 0;
 
261
 
 
262
  if (opt.debug & DBG_MPI_VALUE)
 
263
    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
 
264
  if (opt.debug & DBG_CRYPTO_VALUE )
 
265
    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
 
266
  gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
 
267
}
 
268
 
 
269
 
 
270
 
 
271
static void
 
272
cleanup (void)
 
273
{
 
274
  if (*socket_name)
 
275
    {
 
276
      char *p;
 
277
 
 
278
      remove (socket_name);
 
279
      p = strrchr (socket_name, '/');
 
280
      if (p)
 
281
        {
 
282
          *p = 0;
 
283
          rmdir (socket_name);
 
284
          *p = '/';
 
285
        }
 
286
      *socket_name = 0;
 
287
    }
 
288
}
 
289
 
 
290
 
 
291
static RETSIGTYPE
 
292
cleanup_sh (int sig)
 
293
{
 
294
  if (caught_fatal_sig)
 
295
    raise (sig);
 
296
  caught_fatal_sig = 1;
 
297
 
 
298
  /* gcry_control( GCRYCTL_TERM_SECMEM );*/
 
299
  cleanup ();
 
300
 
 
301
#ifndef HAVE_DOSISH_SYSTEM
 
302
  {     /* reset action to default action and raise signal again */
 
303
    struct sigaction nact;
 
304
    nact.sa_handler = SIG_DFL;
 
305
    sigemptyset( &nact.sa_mask );
 
306
    nact.sa_flags = 0;
 
307
    sigaction( sig, &nact, NULL);
 
308
  }
 
309
#endif
 
310
  raise( sig );
 
311
}
 
312
 
 
313
int
 
314
main (int argc, char **argv )
 
315
{
 
316
  ARGPARSE_ARGS pargs;
 
317
  int orig_argc;
 
318
  gpg_error_t err;
 
319
  int may_coredump;
 
320
  char **orig_argv;
 
321
  FILE *configfp = NULL;
 
322
  char *configname = NULL;
 
323
  const char *shell;
 
324
  unsigned configlineno;
 
325
  int parse_debug = 0;
 
326
  const char *debug_level = NULL;
 
327
  int default_config =1;
 
328
  int greeting = 0;
 
329
  int nogreeting = 0;
 
330
  int pipe_server = 0;
 
331
  int is_daemon = 0;
 
332
  int nodetach = 0;
 
333
  int csh_style = 0;
 
334
  char *logfile = NULL;
 
335
  int debug_wait = 0;
 
336
  int gpgconf_list = 0;
 
337
  const char *config_filename = NULL;
 
338
 
 
339
  set_strusage (my_strusage);
 
340
  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
 
341
  /* Please note that we may running SUID(ROOT), so be very CAREFUL
 
342
     when adding any stuff between here and the call to INIT_SECMEM()
 
343
     somewhere after the option parsing */
 
344
  log_set_prefix ("scdaemon", 1|4); 
 
345
  /* Try to auto set the character set.  */
 
346
  set_native_charset (NULL); 
 
347
 
 
348
  i18n_init ();
 
349
 
 
350
  /* Libgcrypt requires us to register the threading model first.
 
351
     Note that this will also do the pth_init. */
 
352
#ifndef HAVE_OPENSC
 
353
#ifdef USE_GNU_PTH
 
354
  err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
 
355
  if (err)
 
356
    {
 
357
      log_fatal ("can't register GNU Pth with Libgcrypt: %s\n",
 
358
                 gpg_strerror (err));
 
359
    }
 
360
#endif /*USE_GNU_PTH*/
 
361
#endif /*!HAVE_OPENSC*/
 
362
 
 
363
  /* Check that the libraries are suitable.  Do it here because
 
364
     the option parsing may need services of the library */
 
365
  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
 
366
    {
 
367
      log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
 
368
                 NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
 
369
    }
 
370
 
 
371
  ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
 
372
 
 
373
  assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
 
374
  assuan_set_assuan_log_stream (log_get_stream ());
 
375
  assuan_set_assuan_log_prefix (log_get_prefix (NULL));
 
376
 
 
377
  gcry_set_log_handler (my_gcry_logger, NULL);
 
378
  gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
 
379
 
 
380
  may_coredump = disable_core_dumps ();
 
381
 
 
382
  /* Set default options. */
 
383
  opt.pcsc_driver = DEFAULT_PCSC_DRIVER; 
 
384
 
 
385
 
 
386
  shell = getenv ("SHELL");
 
387
  if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
 
388
    csh_style = 1;
 
389
  
 
390
  opt.homedir = default_homedir ();
 
391
 
 
392
  /* Check whether we have a config file on the commandline */
 
393
  orig_argc = argc;
 
394
  orig_argv = argv;
 
395
  pargs.argc = &argc;
 
396
  pargs.argv = &argv;
 
397
  pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
 
398
  while (arg_parse( &pargs, opts))
 
399
    {
 
400
      if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
 
401
        parse_debug++;
 
402
      else if (pargs.r_opt == oOptions)
 
403
        { /* yes there is one, so we do not try the default one, but
 
404
             read the option file when it is encountered at the
 
405
             commandline */
 
406
          default_config = 0;
 
407
        }
 
408
        else if (pargs.r_opt == oNoOptions)
 
409
          default_config = 0; /* --no-options */
 
410
        else if (pargs.r_opt == oHomedir)
 
411
          opt.homedir = pargs.r.ret_str;
 
412
    }
 
413
 
 
414
  /* initialize the secure memory. */
 
415
  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
 
416
  maybe_setuid = 0;
 
417
 
 
418
  /* 
 
419
     Now we are working under our real uid 
 
420
  */
 
421
 
 
422
 
 
423
  if (default_config)
 
424
    configname = make_filename (opt.homedir, "scdaemon.conf", NULL );
 
425
 
 
426
  
 
427
  argc = orig_argc;
 
428
  argv = orig_argv;
 
429
  pargs.argc = &argc;
 
430
  pargs.argv = &argv;
 
431
  pargs.flags=  1;  /* do not remove the args */
 
432
 next_pass:
 
433
  if (configname)
 
434
    {
 
435
      configlineno = 0;
 
436
      configfp = fopen (configname, "r");
 
437
      if (!configfp)
 
438
        {
 
439
          if (default_config)
 
440
            {
 
441
              if( parse_debug )
 
442
                log_info (_("NOTE: no default option file `%s'\n"),
 
443
                          configname );
 
444
            }
 
445
          else
 
446
            {
 
447
              log_error (_("option file `%s': %s\n"),
 
448
                         configname, strerror(errno) );
 
449
              exit(2);
 
450
            }
 
451
          xfree (configname); 
 
452
          configname = NULL;
 
453
        }
 
454
      if (parse_debug && configname )
 
455
        log_info (_("reading options from `%s'\n"), configname );
 
456
      default_config = 0;
 
457
    }
 
458
 
 
459
  while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
 
460
    {
 
461
      switch (pargs.r_opt)
 
462
        {
 
463
        case aGPGConfList: gpgconf_list = 1; break;
 
464
        case oQuiet: opt.quiet = 1; break;
 
465
        case oVerbose: opt.verbose++; break;
 
466
        case oBatch: opt.batch=1; break;
 
467
 
 
468
        case oDebug: opt.debug |= pargs.r.ret_ulong; break;
 
469
        case oDebugAll: opt.debug = ~0; break;
 
470
        case oDebugLevel: debug_level = pargs.r.ret_str; break;
 
471
        case oDebugWait: debug_wait = pargs.r.ret_int; break;
 
472
        case oDebugSC: opt.debug_sc = pargs.r.ret_int; break;
 
473
 
 
474
        case oOptions:
 
475
          /* config files may not be nested (silently ignore them) */
 
476
          if (!configfp)
 
477
            {
 
478
                xfree(configname);
 
479
                configname = xstrdup(pargs.r.ret_str);
 
480
                goto next_pass;
 
481
            }
 
482
          break;
 
483
        case oNoGreeting: nogreeting = 1; break;
 
484
        case oNoVerbose: opt.verbose = 0; break;
 
485
        case oNoOptions: break; /* no-options */
 
486
        case oHomedir: opt.homedir = pargs.r.ret_str; break;
 
487
        case oNoDetach: nodetach = 1; break;
 
488
        case oLogFile: logfile = pargs.r.ret_str; break;
 
489
        case oCsh: csh_style = 1; break;
 
490
        case oSh: csh_style = 0; break;
 
491
        case oServer: pipe_server = 1; break;
 
492
        case oDaemon: is_daemon = 1; break;
 
493
 
 
494
        case oReaderPort: opt.reader_port = pargs.r.ret_str; break;
 
495
        case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
 
496
        case opcscDriver: opt.pcsc_driver = pargs.r.ret_str; break;
 
497
        case oDisableCCID: opt.disable_ccid = 1; break;
 
498
        case oDisableOpenSC: opt.disable_opensc = 1; break;
 
499
 
 
500
        case oAllowAdmin: opt.allow_admin = 1; break;
 
501
        case oDenyAdmin: opt.allow_admin = 0; break;
 
502
 
 
503
        case oDisableApplication:
 
504
          add_to_strlist (&opt.disabled_applications, pargs.r.ret_str); 
 
505
          break;
 
506
 
 
507
        default : pargs.err = configfp? 1:2; break;
 
508
        }
 
509
    }
 
510
  if (configfp)
 
511
    {
 
512
      fclose( configfp );
 
513
      configfp = NULL;
 
514
      /* Keep a copy of the config name for use by --gpgconf-list. */
 
515
      config_filename = configname;
 
516
      configname = NULL;
 
517
      goto next_pass;
 
518
    }
 
519
  xfree (configname);
 
520
  configname = NULL;
 
521
  if (log_get_errorcount(0))
 
522
    exit(2);
 
523
  if (nogreeting )
 
524
    greeting = 0;
 
525
 
 
526
  if (greeting)
 
527
    {
 
528
      fprintf (stderr, "%s %s; %s\n",
 
529
                 strusage(11), strusage(13), strusage(14) );
 
530
      fprintf (stderr, "%s\n", strusage(15) );
 
531
    }
 
532
#ifdef IS_DEVELOPMENT_VERSION
 
533
  log_info ("NOTE: this is a development version!\n");
 
534
#endif
 
535
 
 
536
 
 
537
  if (atexit (cleanup))
 
538
    {
 
539
      log_error ("atexit failed\n");
 
540
      cleanup ();
 
541
      exit (1);
 
542
    }
 
543
 
 
544
  set_debug (debug_level);
 
545
 
 
546
  if (debug_wait && pipe_server)
 
547
    {
 
548
      log_debug ("waiting for debugger - my pid is %u .....\n",
 
549
                 (unsigned int)getpid());
 
550
      sleep (debug_wait);
 
551
      log_debug ("... okay\n");
 
552
    }
 
553
  
 
554
  if (gpgconf_list)
 
555
    {
 
556
      /* List options and default values in the GPG Conf format.  */
 
557
 
 
558
      /* The following list is taken from gnupg/tools/gpgconf-comp.c.  */
 
559
      /* Option flags.  YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING
 
560
         FLAGS, AS THEY ARE PART OF THE EXTERNAL INTERFACE.  */
 
561
#define GC_OPT_FLAG_NONE        0UL
 
562
      /* The RUNTIME flag for an option indicates that the option can be
 
563
         changed at runtime.  */
 
564
#define GC_OPT_FLAG_RUNTIME     (1UL << 3)
 
565
      /* The DEFAULT flag for an option indicates that the option has a
 
566
         default value.  */
 
567
#define GC_OPT_FLAG_DEFAULT     (1UL << 4)
 
568
      /* The DEF_DESC flag for an option indicates that the option has a
 
569
         default, which is described by the value of the default field.  */
 
570
#define GC_OPT_FLAG_DEF_DESC    (1UL << 5)
 
571
      /* The NO_ARG_DESC flag for an option indicates that the argument has
 
572
         a default, which is described by the value of the ARGDEF field.  */
 
573
#define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6)
 
574
      if (!config_filename)
 
575
        config_filename = make_filename (opt.homedir, "scdaemon.conf", NULL );
 
576
 
 
577
      printf ("gpgconf-scdaemon.conf:%lu:\"%s\n",
 
578
              GC_OPT_FLAG_DEFAULT, config_filename);
 
579
        
 
580
      printf ("verbose:%lu:\n"
 
581
              "quiet:%lu:\n"
 
582
              "debug-level:%lu:\"none:\n"
 
583
              "log-file:%lu:\n",
 
584
              GC_OPT_FLAG_NONE,
 
585
              GC_OPT_FLAG_NONE,
 
586
              GC_OPT_FLAG_DEFAULT,
 
587
              GC_OPT_FLAG_NONE );
 
588
 
 
589
      printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE );
 
590
      printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE );
 
591
      printf ("pcsc-driver:%lu:\"%s:\n",
 
592
              GC_OPT_FLAG_DEFAULT, DEFAULT_PCSC_DRIVER );
 
593
#ifdef HAVE_LIBUSB
 
594
      printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE );
 
595
#endif
 
596
#ifdef HAVE_LIBUSB
 
597
      printf ("disable-opensc:%lu:\n", GC_OPT_FLAG_NONE );
 
598
#endif
 
599
      printf ("allow-admin:%lu:\n", GC_OPT_FLAG_NONE );
 
600
 
 
601
 
 
602
      scd_exit (0);
 
603
    }
 
604
 
 
605
  /* now start with logging to a file if this is desired */
 
606
  if (logfile)
 
607
    {
 
608
      log_set_file (logfile);
 
609
      log_set_prefix (NULL, 1|2|4);
 
610
    }
 
611
 
 
612
 
 
613
  if (pipe_server)
 
614
    { /* This is the simple pipe based server */
 
615
#ifndef HAVE_OPENSC
 
616
#ifdef USE_GNU_PTH
 
617
      pth_attr_t tattr;
 
618
 
 
619
      tattr = pth_attr_new();
 
620
      pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
 
621
      pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 512*1024);
 
622
      pth_attr_set (tattr, PTH_ATTR_NAME, "ticker");
 
623
 
 
624
      if (!pth_spawn (tattr, ticker_thread, NULL))
 
625
        {
 
626
          log_error ("error spawning ticker thread: %s\n", strerror (errno));
 
627
          scd_exit (2);
 
628
        }
 
629
#endif /*USE_GNU_PTH*/
 
630
#endif /*!HAVE_OPENSC*/
 
631
      scd_command_handler (-1);
 
632
    }
 
633
  else if (!is_daemon)
 
634
    {
 
635
      log_info (_("please use the option `--daemon'"
 
636
                  " to run the program in the background\n"));
 
637
    }
 
638
  else
 
639
    { /* regular server mode */
 
640
      int fd;
 
641
      pid_t pid;
 
642
      int i;
 
643
      int len;
 
644
      struct sockaddr_un serv_addr;
 
645
      char *p;
 
646
 
 
647
      /* fixme: if there is already a running gpg-agent we should
 
648
         share the same directory - and vice versa */
 
649
      *socket_name = 0;
 
650
      snprintf (socket_name, DIM(socket_name)-1,
 
651
                "/tmp/gpg-XXXXXX/S.scdaemon");
 
652
      socket_name[DIM(socket_name)-1] = 0;
 
653
      p = strrchr (socket_name, '/');
 
654
      if (!p)
 
655
        BUG ();
 
656
      *p = 0;;
 
657
 
 
658
#ifndef HAVE_W32_SYSTEM
 
659
      if (!mkdtemp(socket_name))
 
660
        {
 
661
          log_error ("can't create directory `%s': %s\n",
 
662
                     socket_name, strerror(errno) );
 
663
          exit (1);
 
664
        }
 
665
#endif
 
666
      *p = '/';
 
667
 
 
668
      if (strchr (socket_name, ':') )
 
669
        {
 
670
          log_error ("colons are not allowed in the socket name\n");
 
671
          exit (1);
 
672
        }
 
673
      if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) 
 
674
        {
 
675
          log_error ("name of socket to long\n");
 
676
          exit (1);
 
677
        }
 
678
   
 
679
 
 
680
#ifdef HAVE_W32_SYSTEM
 
681
      fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0);
 
682
#else
 
683
      fd = socket (AF_UNIX, SOCK_STREAM, 0);
 
684
#endif
 
685
      if (fd == -1)
 
686
        {
 
687
          log_error ("can't create socket: %s\n", strerror(errno) );
 
688
          exit (1);
 
689
        }
 
690
 
 
691
      memset (&serv_addr, 0, sizeof serv_addr);
 
692
      serv_addr.sun_family = AF_UNIX;
 
693
      strcpy (serv_addr.sun_path, socket_name);
 
694
      len = (offsetof (struct sockaddr_un, sun_path)
 
695
             + strlen(serv_addr.sun_path) + 1);
 
696
 
 
697
      if (
 
698
#ifdef HAVE_W32_SYSTEM
 
699
          _w32_sock_bind
 
700
#else
 
701
          bind 
 
702
#endif
 
703
          (fd, (struct sockaddr*)&serv_addr, len) == -1)
 
704
        {
 
705
          log_error ("error binding socket to `%s': %s\n",
 
706
                     serv_addr.sun_path, strerror (errno) );
 
707
          close (fd);
 
708
          exit (1);
 
709
        }
 
710
  
 
711
      if (listen (fd, 5 ) == -1)
 
712
        {
 
713
          log_error ("listen() failed: %s\n", strerror (errno));
 
714
          close (fd);
 
715
          exit (1);
 
716
        }
 
717
 
 
718
      if (opt.verbose)
 
719
        log_info ("listening on socket `%s'\n", socket_name );
 
720
 
 
721
 
 
722
      fflush (NULL);
 
723
#ifndef HAVE_W32_SYSTEM
 
724
      pid = fork ();
 
725
      if (pid == (pid_t)-1) 
 
726
        {
 
727
          log_fatal ("fork failed: %s\n", strerror (errno) );
 
728
          exit (1);
 
729
        }
 
730
      else if (pid) 
 
731
        { /* we are the parent */
 
732
          char *infostr;
 
733
          
 
734
          close (fd);
 
735
          
 
736
          /* create the info string: <name>:<pid>:<protocol_version> */
 
737
          if (asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1",
 
738
                        socket_name, (ulong)pid ) < 0)
 
739
            {
 
740
              log_error ("out of core\n");
 
741
              kill (pid, SIGTERM);
 
742
              exit (1);
 
743
            }
 
744
          *socket_name = 0; /* don't let cleanup() remove the socket -
 
745
                               the child should do this from now on */
 
746
          if (argc) 
 
747
            { /* run the program given on the commandline */
 
748
              if (putenv (infostr))
 
749
                {
 
750
                  log_error ("failed to set environment: %s\n",
 
751
                             strerror (errno) );
 
752
                  kill (pid, SIGTERM );
 
753
                  exit (1);
 
754
                }
 
755
              execvp (argv[0], argv);
 
756
              log_error ("failed to run the command: %s\n", strerror (errno));
 
757
              kill (pid, SIGTERM);
 
758
              exit (1);
 
759
            }
 
760
          else
 
761
            {
 
762
              /* print the environment string, so that the caller can use
 
763
                 shell's eval to set it */
 
764
              if (csh_style)
 
765
                {
 
766
                  *strchr (infostr, '=') = ' ';
 
767
                  printf ( "setenv %s\n", infostr);
 
768
                }
 
769
              else
 
770
                {
 
771
                  printf ( "%s; export SCDAEMON_INFO;\n", infostr);
 
772
                }
 
773
              free (infostr);
 
774
              exit (0); 
 
775
            }
 
776
          /* NOTREACHED */
 
777
        } /* end parent */
 
778
      
 
779
      /* this is the child */
 
780
 
 
781
      /* detach from tty and put process into a new session */
 
782
      if (!nodetach )
 
783
        {  /* close stdin, stdout and stderr unless it is the log stream */
 
784
          for (i=0; i <= 2; i++) 
 
785
            {
 
786
              if ( log_get_fd () != i)
 
787
                close (i);
 
788
            }
 
789
          if (setsid() == -1)
 
790
            {
 
791
              log_error ("setsid() failed: %s\n", strerror(errno) );
 
792
              cleanup ();
 
793
              exit (1);
 
794
            }
 
795
        }
 
796
 
 
797
      /* setup signals */
 
798
      {
 
799
        struct sigaction oact, nact;
 
800
        
 
801
        nact.sa_handler = cleanup_sh;
 
802
        sigemptyset (&nact.sa_mask);
 
803
        nact.sa_flags = 0;
 
804
        
 
805
        sigaction (SIGHUP, NULL, &oact);
 
806
        if (oact.sa_handler != SIG_IGN)
 
807
          sigaction (SIGHUP, &nact, NULL);
 
808
        sigaction( SIGTERM, NULL, &oact );
 
809
        if (oact.sa_handler != SIG_IGN)
 
810
          sigaction (SIGTERM, &nact, NULL);
 
811
        nact.sa_handler = SIG_IGN;
 
812
        sigaction (SIGPIPE, &nact, NULL);
 
813
        sigaction (SIGINT, &nact, NULL);
 
814
      }
 
815
 
 
816
      if (chdir("/"))
 
817
        {
 
818
          log_error ("chdir to / failed: %s\n", strerror (errno));
 
819
          exit (1);
 
820
        }
 
821
 
 
822
#endif /*!HAVE_W32_SYSTEM*/
 
823
 
 
824
      scd_command_handler (fd);
 
825
 
 
826
      close (fd);
 
827
    }
 
828
  
 
829
  return 0;
 
830
}
 
831
 
 
832
void
 
833
scd_exit (int rc)
 
834
{
 
835
#if 0
 
836
#warning no update_random_seed_file
 
837
  update_random_seed_file();
 
838
#endif
 
839
#if 0
 
840
  /* at this time a bit annoying */
 
841
  if (opt.debug & DBG_MEMSTAT_VALUE)
 
842
    {
 
843
      gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
 
844
      gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
 
845
    }
 
846
  if (opt.debug)
 
847
    gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
 
848
#endif
 
849
  gcry_control (GCRYCTL_TERM_SECMEM );
 
850
  rc = rc? rc : log_get_errorcount(0)? 2 : 0;
 
851
  exit (rc);
 
852
}
 
853
 
 
854
 
 
855
void
 
856
scd_init_default_ctrl (CTRL ctrl)
 
857
{
 
858
  ctrl->reader_slot = -1;
 
859
}
 
860
 
 
861
 
 
862
#ifndef HAVE_OPENSC
 
863
#ifdef USE_GNU_PTH
 
864
 
 
865
static void
 
866
handle_signal (int signo)
 
867
{
 
868
  switch (signo)
 
869
    {
 
870
#ifndef HAVE_W32_SYSTEM
 
871
    case SIGHUP:
 
872
      log_info ("SIGHUP received - "
 
873
                "re-reading configuration and resetting cards\n");
 
874
/*       reread_configuration (); */
 
875
      break;
 
876
      
 
877
    case SIGUSR1:
 
878
      log_info ("SIGUSR1 received - no action defined\n");
 
879
      break;
 
880
 
 
881
    case SIGUSR2:
 
882
      log_info ("SIGUSR2 received - no action defined\n");
 
883
      break;
 
884
 
 
885
    case SIGTERM:
 
886
      if (!shutdown_pending)
 
887
        log_info ("SIGTERM received - shutting down ...\n");
 
888
      else
 
889
        log_info ("SIGTERM received - still %ld running threads\n",
 
890
                  pth_ctrl( PTH_CTRL_GETTHREADS ));
 
891
      shutdown_pending++;
 
892
      if (shutdown_pending > 2)
 
893
        {
 
894
          log_info ("shutdown forced\n");
 
895
          log_info ("%s %s stopped\n", strusage(11), strusage(13) );
 
896
          cleanup ();
 
897
          scd_exit (0);
 
898
        }
 
899
      break;
 
900
        
 
901
    case SIGINT:
 
902
      log_info ("SIGINT received - immediate shutdown\n");
 
903
      log_info( "%s %s stopped\n", strusage(11), strusage(13));
 
904
      cleanup ();
 
905
      scd_exit (0);
 
906
      break;
 
907
#endif /*!HAVE_W32_SYSTEM*/
 
908
 
 
909
    default:
 
910
      log_info ("signal %d received - no action defined\n", signo);
 
911
    }
 
912
}
 
913
 
 
914
static void
 
915
handle_tick (void)
 
916
{
 
917
  scd_update_reader_status_file ();
 
918
}
 
919
 
 
920
static void *
 
921
ticker_thread (void *dummy_arg)
 
922
{
 
923
  pth_event_t sigs_ev, time_ev = NULL;
 
924
  sigset_t sigs;
 
925
  int signo;
 
926
 
 
927
#ifndef HAVE_W32_SYSTEM /* fixme */
 
928
  sigemptyset (&sigs );
 
929
  sigaddset (&sigs, SIGHUP);
 
930
  sigaddset (&sigs, SIGUSR1);
 
931
  sigaddset (&sigs, SIGUSR2);
 
932
  sigaddset (&sigs, SIGINT);
 
933
  sigaddset (&sigs, SIGTERM);
 
934
  sigs_ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
 
935
#else
 
936
  sigs_ev = NULL;
 
937
#endif
 
938
  
 
939
  for (;;)
 
940
    {
 
941
      if (!time_ev)
 
942
        {
 
943
          time_ev = pth_event (PTH_EVENT_TIME, pth_timeout (2, 0));
 
944
          if (time_ev)
 
945
            pth_event_concat (sigs_ev, time_ev, NULL);
 
946
        }
 
947
 
 
948
      if (pth_wait (sigs_ev) < 1)
 
949
        continue;
 
950
 
 
951
      if (
 
952
#ifdef PTH_STATUS_OCCURRED     /* This is Pth 2 */
 
953
          pth_event_status (sigs_ev) == PTH_STATUS_OCCURRED
 
954
#else
 
955
          pth_event_occurred (sigs_ev)
 
956
#endif
 
957
          )
 
958
        handle_signal (signo);
 
959
 
 
960
      /* Always run the ticker. */
 
961
      if (!shutdown_pending)
 
962
        {
 
963
          pth_event_isolate (sigs_ev);
 
964
          pth_event_free (time_ev, PTH_FREE_ALL);
 
965
          time_ev = NULL;
 
966
          handle_tick ();
 
967
        }
 
968
    }
 
969
 
 
970
  pth_event_free (sigs_ev, PTH_FREE_ALL);
 
971
}
 
972
#endif /*USE_GNU_PTH*/
 
973
#endif /*!HAVE_OPENSC*/