11952615d4ab7bc622f4e4a2177dc1184b7fbd72
[gnupg.git] / scd / scdaemon.c
1 /* scdaemon.c  -  The GnuPG Smartcard Daemon
2  *      Copyright (C) 2001, 2002 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 #include <sys/socket.h>
33 #include <sys/un.h>
34 #include <unistd.h>
35 #include <signal.h>
36
37 #define JNLIB_NEED_LOG_LOGV
38 #include "scdaemon.h"
39 #include <ksba.h>
40 #include <gcrypt.h>
41
42 #include <assuan.h> /* malloc hooks */
43
44 #include "i18n.h"
45 #include "sysutils.h"
46 #include "app-common.h"
47
48
49 enum cmd_and_opt_values 
50 { aNull = 0,
51   oCsh            = 'c',
52   oQuiet          = 'q',
53   oSh             = 's',
54   oVerbose        = 'v',
55   
56   oNoVerbose = 500,
57   oOptions,
58   oDebug,
59   oDebugAll,
60   oDebugWait,
61   oDebugSC,
62   oNoGreeting,
63   oNoOptions,
64   oHomedir,
65   oNoDetach,
66   oNoGrab,
67   oLogFile,
68   oServer,
69   oDaemon,
70   oBatch,
71   oReaderPort,
72   octapiDriver,
73
74 aTest };
75
76
77
78 static ARGPARSE_OPTS opts[] = {
79   
80   { 301, NULL, 0, N_("@Options:\n ") },
81
82   { oServer,   "server",     0, N_("run in server mode (foreground)") },
83   { oDaemon,   "daemon",     0, N_("run in daemon mode (background)") },
84   { oVerbose, "verbose",   0, N_("verbose") },
85   { oQuiet,     "quiet",     0, N_("be somewhat more quiet") },
86   { oSh,        "sh",        0, N_("sh-style command output") },
87   { oCsh,       "csh",       0, N_("csh-style command output") },
88   { oOptions, "options"  , 2, N_("read options from file")},
89   { oDebug,     "debug"     ,4|16, N_("set debugging flags")},
90   { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
91   { oDebugWait,"debug-wait",1, "@"},
92   { oDebugSC,  "debug-sc",  1, N_("|N|set OpenSC debug level to N")},
93   { oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
94   { oLogFile,  "log-file"   ,2, N_("use a log file for the server")},
95   { oReaderPort, "reader-port", 2, N_("|N|connect to reader at port N")},
96   { octapiDriver, "ctapi-driver", 2, N_("NAME|use NAME as ctAPI driver")},
97   {0}
98 };
99
100
101 static volatile int caught_fatal_sig = 0;
102
103 /* It is possible that we are currently running under setuid permissions */
104 static int maybe_setuid = 1;
105
106 /* Name of the communication socket */
107 static char socket_name[128];
108
109 static const char *
110 my_strusage (int level)
111 {
112   const char *p;
113   switch (level)
114     {
115     case 11: p = "scdaemon (GnuPG)";
116       break;
117     case 13: p = VERSION; break;
118     case 17: p = PRINTABLE_OS_NAME; break;
119     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
120       break;
121     case 1:
122     case 40: p =  _("Usage: scdaemon [options] (-h for help)");
123       break;
124     case 41: p =  _("Syntax: scdaemon [options] [command [args]]\n"
125                     "Smartcard daemon for GnuPG\n");
126     break;
127     
128     default: p = NULL;
129     }
130   return p;
131 }
132
133
134
135 static void
136 i18n_init (void)
137 {
138 #ifdef USE_SIMPLE_GETTEXT
139     set_gettext_file( PACKAGE );
140 #else
141 #ifdef ENABLE_NLS
142     setlocale (LC_ALL, "");
143     bindtextdomain (PACKAGE, LOCALEDIR);
144     textdomain (PACKAGE);
145 #endif
146 #endif
147 }
148
149
150
151 /* Used by gcry for logging */
152 static void
153 my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
154 {
155   /* translate the log levels */
156   switch (level)
157     {
158     case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
159     case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
160     case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
161     case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
162     case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
163     case GCRY_LOG_BUG:  level = JNLIB_LOG_BUG; break;
164     case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
165     default:            level = JNLIB_LOG_ERROR; break;  
166     }
167   log_logv (level, fmt, arg_ptr);
168 }
169
170
171 static void
172 cleanup (void)
173 {
174   if (*socket_name)
175     {
176       char *p;
177
178       remove (socket_name);
179       p = strrchr (socket_name, '/');
180       if (p)
181         {
182           *p = 0;
183           rmdir (socket_name);
184           *p = '/';
185         }
186       *socket_name = 0;
187     }
188 }
189
190
191 static RETSIGTYPE
192 cleanup_sh (int sig)
193 {
194   if (caught_fatal_sig)
195     raise (sig);
196   caught_fatal_sig = 1;
197
198   /* gcry_control( GCRYCTL_TERM_SECMEM );*/
199   cleanup ();
200
201 #ifndef HAVE_DOSISH_SYSTEM
202   {     /* reset action to default action and raise signal again */
203     struct sigaction nact;
204     nact.sa_handler = SIG_DFL;
205     sigemptyset( &nact.sa_mask );
206     nact.sa_flags = 0;
207     sigaction( sig, &nact, NULL);
208   }
209 #endif
210   raise( sig );
211 }
212
213 int
214 main (int argc, char **argv )
215 {
216   ARGPARSE_ARGS pargs;
217   int orig_argc;
218   int may_coredump;
219   char **orig_argv;
220   FILE *configfp = NULL;
221   char *configname = NULL;
222   const char *shell;
223   unsigned configlineno;
224   int parse_debug = 0;
225   int default_config =1;
226   int greeting = 0;
227   int nogreeting = 0;
228   int pipe_server = 0;
229   int is_daemon = 0;
230   int nodetach = 0;
231   int csh_style = 0;
232   char *logfile = NULL;
233   int debug_wait = 0;
234
235   set_strusage (my_strusage);
236   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
237   /* Please note that we may running SUID(ROOT), so be very CAREFUL
238      when adding any stuff between here and the call to INIT_SECMEM()
239      somewhere after the option parsing */
240   log_set_prefix ("scdaemon", 1|4); 
241   i18n_init ();
242
243   /* check that the libraries are suitable.  Do it here because
244      the option parsing may need services of the library */
245   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
246     {
247       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
248                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
249     }
250
251   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
252   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
253   gcry_set_log_handler (my_gcry_logger, NULL);
254   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
255
256   may_coredump = disable_core_dumps ();
257
258   shell = getenv ("SHELL");
259   if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") )
260     csh_style = 1;
261   
262   /* FIXME: Using this homedir option does only make sense when not
263      running as a system service.  We might want to check for this by
264      looking at the uid or ebtter use an explict option for this */
265   opt.homedir = getenv("GNUPGHOME");
266   if (!opt.homedir || !*opt.homedir)
267     opt.homedir = GNUPG_DEFAULT_HOMEDIR;
268
269   /* check whether we have a config file on the commandline */
270   orig_argc = argc;
271   orig_argv = argv;
272   pargs.argc = &argc;
273   pargs.argv = &argv;
274   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
275   while (arg_parse( &pargs, opts))
276     {
277       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
278         parse_debug++;
279       else if (pargs.r_opt == oOptions)
280         { /* yes there is one, so we do not try the default one, but
281              read the option file when it is encountered at the
282              commandline */
283           default_config = 0;
284         }
285         else if (pargs.r_opt == oNoOptions)
286           default_config = 0; /* --no-options */
287         else if (pargs.r_opt == oHomedir)
288           opt.homedir = pargs.r.ret_str;
289     }
290
291   /* initialize the secure memory. */
292   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
293   maybe_setuid = 0;
294
295   /* 
296      Now we are working under our real uid 
297   */
298
299
300   if (default_config)
301     configname = make_filename (opt.homedir, "scdaemon.conf", NULL );
302
303   
304   argc = orig_argc;
305   argv = orig_argv;
306   pargs.argc = &argc;
307   pargs.argv = &argv;
308   pargs.flags=  1;  /* do not remove the args */
309  next_pass:
310   if (configname)
311     {
312       configlineno = 0;
313       configfp = fopen (configname, "r");
314       if (!configfp)
315         {
316           if (default_config)
317             {
318               if( parse_debug )
319                 log_info (_("NOTE: no default option file `%s'\n"),
320                           configname );
321             }
322           else
323             {
324               log_error (_("option file `%s': %s\n"),
325                          configname, strerror(errno) );
326               exit(2);
327             }
328           xfree (configname); 
329           configname = NULL;
330         }
331       if (parse_debug && configname )
332         log_info (_("reading options from `%s'\n"), configname );
333       default_config = 0;
334     }
335
336   while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
337     {
338       switch (pargs.r_opt)
339         {
340         case oQuiet: opt.quiet = 1; break;
341         case oVerbose: opt.verbose++; break;
342         case oBatch: opt.batch=1; break;
343
344         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
345         case oDebugAll: opt.debug = ~0; break;
346         case oDebugWait: debug_wait = pargs.r.ret_int; break;
347         case oDebugSC: opt.debug_sc = pargs.r.ret_int; break;
348
349         case oOptions:
350           /* config files may not be nested (silently ignore them) */
351           if (!configfp)
352             {
353                 xfree(configname);
354                 configname = xstrdup(pargs.r.ret_str);
355                 goto next_pass;
356             }
357           break;
358         case oNoGreeting: nogreeting = 1; break;
359         case oNoVerbose: opt.verbose = 0; break;
360         case oNoOptions: break; /* no-options */
361         case oHomedir: opt.homedir = pargs.r.ret_str; break;
362         case oNoDetach: nodetach = 1; break;
363         case oLogFile: logfile = pargs.r.ret_str; break;
364         case oCsh: csh_style = 1; break;
365         case oSh: csh_style = 0; break;
366         case oServer: pipe_server = 1; break;
367         case oDaemon: is_daemon = 1; break;
368
369         case oReaderPort: app_set_default_reader_port (pargs.r.ret_str); break;
370         case octapiDriver: opt.ctapi_driver = pargs.r.ret_str; break;
371
372         default : pargs.err = configfp? 1:2; break;
373         }
374     }
375   if (configfp)
376     {
377       fclose( configfp );
378       configfp = NULL;
379       xfree(configname);
380       configname = NULL;
381       goto next_pass;
382     }
383   xfree (configname);
384   configname = NULL;
385   if (log_get_errorcount(0))
386     exit(2);
387   if (nogreeting )
388     greeting = 0;
389
390   if (greeting)
391     {
392       fprintf (stderr, "%s %s; %s\n",
393                  strusage(11), strusage(13), strusage(14) );
394       fprintf (stderr, "%s\n", strusage(15) );
395     }
396 #ifdef IS_DEVELOPMENT_VERSION
397   log_info ("NOTE: this is a development version!\n");
398 #endif
399
400   
401   if (atexit (cleanup))
402     {
403       log_error ("atexit failed\n");
404       cleanup ();
405       exit (1);
406     }
407
408   
409   if (debug_wait && pipe_server)
410     {
411       log_debug ("waiting for debugger - my pid is %u .....\n",
412                  (unsigned int)getpid());
413       sleep (debug_wait);
414       log_debug ("... okay\n");
415     }
416   
417   /* now start with logging to a file if this is desired */
418   if (logfile)
419     {
420       log_set_file (logfile);
421       log_set_prefix (NULL, 1|2|4);
422     }
423
424
425   if (pipe_server)
426     { /* this is the simple pipe based server */
427       scd_command_handler (-1);
428     }
429   else if (!is_daemon)
430     {
431       log_info (_("please use the option `--daemon'"
432                   " to run the program in the background\n"));
433     }
434   else
435     { /* regular server mode */
436       int fd;
437       pid_t pid;
438       int i;
439       int len;
440       struct sockaddr_un serv_addr;
441       char *p;
442
443       /* fixme: if there is already a running gpg-agent we should
444          share the same directory - and vice versa */
445       *socket_name = 0;
446       snprintf (socket_name, DIM(socket_name)-1,
447                 "/tmp/gpg-XXXXXX/S.scdaemon");
448       socket_name[DIM(socket_name)-1] = 0;
449       p = strrchr (socket_name, '/');
450       if (!p)
451         BUG ();
452       *p = 0;;
453       if (!mkdtemp(socket_name))
454         {
455           log_error ("can't create directory `%s': %s\n",
456                      socket_name, strerror(errno) );
457           exit (1);
458         }
459       *p = '/';
460
461       if (strchr (socket_name, ':') )
462         {
463           log_error ("colons are not allowed in the socket name\n");
464           exit (1);
465         }
466       if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) 
467         {
468           log_error ("name of socket to long\n");
469           exit (1);
470         }
471    
472
473       fd = socket (AF_UNIX, SOCK_STREAM, 0);
474       if (fd == -1)
475         {
476           log_error ("can't create socket: %s\n", strerror(errno) );
477           exit (1);
478         }
479
480       memset (&serv_addr, 0, sizeof serv_addr);
481       serv_addr.sun_family = AF_UNIX;
482       strcpy (serv_addr.sun_path, socket_name);
483       len = (offsetof (struct sockaddr_un, sun_path)
484              + strlen(serv_addr.sun_path) + 1);
485
486       if (bind (fd, (struct sockaddr*)&serv_addr, len) == -1)
487         {
488           log_error ("error binding socket to `%s': %s\n",
489                      serv_addr.sun_path, strerror (errno) );
490           close (fd);
491           exit (1);
492         }
493   
494       if (listen (fd, 5 ) == -1)
495         {
496           log_error ("listen() failed: %s\n", strerror (errno));
497           close (fd);
498           exit (1);
499         }
500
501       if (opt.verbose)
502         log_info ("listening on socket `%s'\n", socket_name );
503
504
505       fflush (NULL);
506       pid = fork ();
507       if (pid == (pid_t)-1) 
508         {
509           log_fatal ("fork failed: %s\n", strerror (errno) );
510           exit (1);
511         }
512       else if (pid) 
513         { /* we are the parent */
514           char *infostr;
515           
516           close (fd);
517           
518           /* create the info string: <name>:<pid>:<protocol_version> */
519           if (asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1",
520                         socket_name, (ulong)pid ) < 0)
521             {
522               log_error ("out of core\n");
523               kill (pid, SIGTERM);
524               exit (1);
525             }
526           *socket_name = 0; /* don't let cleanup() remove the socket -
527                                the child should do this from now on */
528           if (argc) 
529             { /* run the program given on the commandline */
530               if (putenv (infostr))
531                 {
532                   log_error ("failed to set environment: %s\n",
533                              strerror (errno) );
534                   kill (pid, SIGTERM );
535                   exit (1);
536                 }
537               execvp (argv[0], argv);
538               log_error ("failed to run the command: %s\n", strerror (errno));
539               kill (pid, SIGTERM);
540               exit (1);
541             }
542           else
543             {
544               /* print the environment string, so that the caller can use
545                  shell's eval to set it */
546               if (csh_style)
547                 {
548                   *strchr (infostr, '=') = ' ';
549                   printf ( "setenv %s\n", infostr);
550                 }
551               else
552                 {
553                   printf ( "%s; export SCDAEMON_INFO;\n", infostr);
554                 }
555               free (infostr);
556               exit (0); 
557             }
558           /* NOTREACHED */
559         } /* end parent */
560       
561       /* this is the child */
562
563       /* detach from tty and put process into a new session */
564       if (!nodetach )
565         {  /* close stdin, stdout and stderr unless it is the log stream */
566           for (i=0; i <= 2; i++) 
567             {
568               if ( log_get_fd () != i)
569                 close (i);
570             }
571           if (setsid() == -1)
572             {
573               log_error ("setsid() failed: %s\n", strerror(errno) );
574               cleanup ();
575               exit (1);
576             }
577         }
578
579       /* setup signals */
580       {
581         struct sigaction oact, nact;
582         
583         nact.sa_handler = cleanup_sh;
584         sigemptyset (&nact.sa_mask);
585         nact.sa_flags = 0;
586         
587         sigaction (SIGHUP, NULL, &oact);
588         if (oact.sa_handler != SIG_IGN)
589           sigaction (SIGHUP, &nact, NULL);
590         sigaction( SIGTERM, NULL, &oact );
591         if (oact.sa_handler != SIG_IGN)
592           sigaction (SIGTERM, &nact, NULL);
593         nact.sa_handler = SIG_IGN;
594         sigaction (SIGPIPE, &nact, NULL);
595         sigaction (SIGINT, &nact, NULL);
596       }
597
598       if (chdir("/"))
599         {
600           log_error ("chdir to / failed: %s\n", strerror (errno));
601           exit (1);
602         }
603
604       scd_command_handler (fd);
605
606       close (fd);
607     }
608   
609   return 0;
610 }
611
612 void
613 scd_exit (int rc)
614 {
615   #if 0
616 #warning no update_random_seed_file
617   update_random_seed_file();
618   #endif
619 #if 0
620   /* at this time a bit annoying */
621   if (opt.debug & DBG_MEMSTAT_VALUE)
622     {
623       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
624       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
625     }
626   if (opt.debug)
627     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
628 #endif
629   gcry_control (GCRYCTL_TERM_SECMEM );
630   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
631   exit (rc);
632 }
633
634
635 void
636 scd_init_default_ctrl (CTRL ctrl)
637 {
638
639 }
640