Key generation and signing using the OpenPGP card does rudimentary work.
[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
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
73 aTest };
74
75
76
77 static ARGPARSE_OPTS opts[] = {
78   
79   { 301, NULL, 0, N_("@Options:\n ") },
80
81   { oServer,   "server",     0, N_("run in server mode (foreground)") },
82   { oDaemon,   "daemon",     0, N_("run in daemon mode (background)") },
83   { oVerbose, "verbose",   0, N_("verbose") },
84   { oQuiet,     "quiet",     0, N_("be somewhat more quiet") },
85   { oSh,        "sh",        0, N_("sh-style command output") },
86   { oCsh,       "csh",       0, N_("csh-style command output") },
87   { oOptions, "options"  , 2, N_("read options from file")},
88   { oDebug,     "debug"     ,4|16, N_("set debugging flags")},
89   { oDebugAll, "debug-all" ,0, N_("enable full debugging")},
90   { oDebugWait,"debug-wait",1, "@"},
91   { oDebugSC,  "debug-sc",  1, N_("|N|set OpenSC debug level to N")},
92   { oNoDetach, "no-detach" ,0, N_("do not detach from the console")},
93   { oLogFile,  "log-file"   ,2, N_("use a log file for the server")},
94   { oReaderPort, "reader-port", 1, N_("|N|connect to reader at port N")},
95
96   {0}
97 };
98
99
100 static volatile int caught_fatal_sig = 0;
101
102 /* It is possible that we are currently running under setuid permissions */
103 static int maybe_setuid = 1;
104
105 /* Name of the communication socket */
106 static char socket_name[128];
107
108 static const char *
109 my_strusage (int level)
110 {
111   const char *p;
112   switch (level)
113     {
114     case 11: p = "scdaemon (GnuPG)";
115       break;
116     case 13: p = VERSION; break;
117     case 17: p = PRINTABLE_OS_NAME; break;
118     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
119       break;
120     case 1:
121     case 40: p =  _("Usage: scdaemon [options] (-h for help)");
122       break;
123     case 41: p =  _("Syntax: scdaemon [options] [command [args]]\n"
124                     "Smartcard daemon for GnuPG\n");
125     break;
126     
127     default: p = NULL;
128     }
129   return p;
130 }
131
132
133
134 static void
135 i18n_init (void)
136 {
137 #ifdef USE_SIMPLE_GETTEXT
138     set_gettext_file( PACKAGE );
139 #else
140 #ifdef ENABLE_NLS
141     setlocale (LC_ALL, "");
142     bindtextdomain (PACKAGE, LOCALEDIR);
143     textdomain (PACKAGE);
144 #endif
145 #endif
146 }
147
148
149
150 /* Used by gcry for logging */
151 static void
152 my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr)
153 {
154   /* translate the log levels */
155   switch (level)
156     {
157     case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break;
158     case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break;
159     case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break;
160     case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break;
161     case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break;
162     case GCRY_LOG_BUG:  level = JNLIB_LOG_BUG; break;
163     case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break;
164     default:            level = JNLIB_LOG_ERROR; break;  
165     }
166   log_logv (level, fmt, arg_ptr);
167 }
168
169
170 static void
171 cleanup (void)
172 {
173   if (*socket_name)
174     {
175       char *p;
176
177       remove (socket_name);
178       p = strrchr (socket_name, '/');
179       if (p)
180         {
181           *p = 0;
182           rmdir (socket_name);
183           *p = '/';
184         }
185       *socket_name = 0;
186     }
187 }
188
189
190 static RETSIGTYPE
191 cleanup_sh (int sig)
192 {
193   if (caught_fatal_sig)
194     raise (sig);
195   caught_fatal_sig = 1;
196
197   /* gcry_control( GCRYCTL_TERM_SECMEM );*/
198   cleanup ();
199
200 #ifndef HAVE_DOSISH_SYSTEM
201   {     /* reset action to default action and raise signal again */
202     struct sigaction nact;
203     nact.sa_handler = SIG_DFL;
204     sigemptyset( &nact.sa_mask );
205     nact.sa_flags = 0;
206     sigaction( sig, &nact, NULL);
207   }
208 #endif
209   raise( sig );
210 }
211
212 int
213 main (int argc, char **argv )
214 {
215   ARGPARSE_ARGS pargs;
216   int orig_argc;
217   int may_coredump;
218   char **orig_argv;
219   FILE *configfp = NULL;
220   char *configname = NULL;
221   const char *shell;
222   unsigned configlineno;
223   int parse_debug = 0;
224   int default_config =1;
225   int greeting = 0;
226   int nogreeting = 0;
227   int pipe_server = 0;
228   int is_daemon = 0;
229   int nodetach = 0;
230   int csh_style = 0;
231   char *logfile = NULL;
232   int debug_wait = 0;
233   int reader_port = 32768; /* First USB reader. */
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   argc = orig_argc;
304   argv = orig_argv;
305   pargs.argc = &argc;
306   pargs.argv = &argv;
307   pargs.flags=  1;  /* do not remove the args */
308  next_pass:
309   if (configname)
310     {
311       configlineno = 0;
312       configfp = fopen (configname, "r");
313       if (!configfp)
314         {
315           if (default_config)
316             {
317               if( parse_debug )
318                 log_info (_("NOTE: no default option file `%s'\n"),
319                           configname );
320             }
321           else
322             {
323               log_error (_("option file `%s': %s\n"),
324                          configname, strerror(errno) );
325               exit(2);
326             }
327           xfree (configname); 
328           configname = NULL;
329         }
330       if (parse_debug && configname )
331         log_info (_("reading options from `%s'\n"), configname );
332       default_config = 0;
333     }
334
335   while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) )
336     {
337       switch (pargs.r_opt)
338         {
339         case oQuiet: opt.quiet = 1; break;
340         case oVerbose: opt.verbose++; break;
341         case oBatch: opt.batch=1; break;
342
343         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
344         case oDebugAll: opt.debug = ~0; break;
345         case oDebugWait: debug_wait = pargs.r.ret_int; break;
346         case oDebugSC: opt.debug_sc = pargs.r.ret_int; break;
347
348         case oOptions:
349           /* config files may not be nested (silently ignore them) */
350           if (!configfp)
351             {
352                 xfree(configname);
353                 configname = xstrdup(pargs.r.ret_str);
354                 goto next_pass;
355             }
356           break;
357         case oNoGreeting: nogreeting = 1; break;
358         case oNoVerbose: opt.verbose = 0; break;
359         case oNoOptions: break; /* no-options */
360         case oHomedir: opt.homedir = pargs.r.ret_str; break;
361         case oNoDetach: nodetach = 1; break;
362         case oLogFile: logfile = pargs.r.ret_str; break;
363         case oCsh: csh_style = 1; break;
364         case oSh: csh_style = 0; break;
365         case oServer: pipe_server = 1; break;
366         case oDaemon: is_daemon = 1; break;
367
368         case oReaderPort: reader_port = pargs.r.ret_int; break;
369
370         default : pargs.err = configfp? 1:2; break;
371         }
372     }
373   if (configfp)
374     {
375       fclose( configfp );
376       configfp = NULL;
377       xfree(configname);
378       configname = NULL;
379       goto next_pass;
380     }
381   xfree (configname);
382   configname = NULL;
383   if (log_get_errorcount(0))
384     exit(2);
385   if (nogreeting )
386     greeting = 0;
387
388   if (greeting)
389     {
390       fprintf (stderr, "%s %s; %s\n",
391                  strusage(11), strusage(13), strusage(14) );
392       fprintf (stderr, "%s\n", strusage(15) );
393     }
394 #ifdef IS_DEVELOPMENT_VERSION
395   log_info ("NOTE: this is a development version!\n");
396 #endif
397
398   
399   if (atexit (cleanup))
400     {
401       log_error ("atexit failed\n");
402       cleanup ();
403       exit (1);
404     }
405
406   
407   if (debug_wait && pipe_server)
408     {
409       log_debug ("waiting for debugger - my pid is %u .....\n",
410                  (unsigned int)getpid());
411       sleep (debug_wait);
412       log_debug ("... okay\n");
413     }
414   
415   /* now start with logging to a file if this is desired */
416   if (logfile)
417     {
418       log_set_file (logfile);
419       log_set_prefix (NULL, 1|2|4);
420     }
421
422
423   if (pipe_server)
424     { /* this is the simple pipe based server */
425       scd_command_handler (-1);
426     }
427   else if (!is_daemon)
428     {
429       log_info (_("please use the option `--daemon'"
430                   " to run the program in the background\n"));
431     }
432   else
433     { /* regular server mode */
434       int fd;
435       pid_t pid;
436       int i;
437       int len;
438       struct sockaddr_un serv_addr;
439       char *p;
440
441       /* fixme: if there is already a running gpg-agent we should
442          share the same directory - and vice versa */
443       *socket_name = 0;
444       snprintf (socket_name, DIM(socket_name)-1,
445                 "/tmp/gpg-XXXXXX/S.scdaemon");
446       socket_name[DIM(socket_name)-1] = 0;
447       p = strrchr (socket_name, '/');
448       if (!p)
449         BUG ();
450       *p = 0;;
451       if (!mkdtemp(socket_name))
452         {
453           log_error ("can't create directory `%s': %s\n",
454                      socket_name, strerror(errno) );
455           exit (1);
456         }
457       *p = '/';
458
459       if (strchr (socket_name, ':') )
460         {
461           log_error ("colons are not allowed in the socket name\n");
462           exit (1);
463         }
464       if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) 
465         {
466           log_error ("name of socket to long\n");
467           exit (1);
468         }
469    
470
471       fd = socket (AF_UNIX, SOCK_STREAM, 0);
472       if (fd == -1)
473         {
474           log_error ("can't create socket: %s\n", strerror(errno) );
475           exit (1);
476         }
477
478       memset (&serv_addr, 0, sizeof serv_addr);
479       serv_addr.sun_family = AF_UNIX;
480       strcpy (serv_addr.sun_path, socket_name);
481       len = (offsetof (struct sockaddr_un, sun_path)
482              + strlen(serv_addr.sun_path) + 1);
483
484       if (bind (fd, (struct sockaddr*)&serv_addr, len) == -1)
485         {
486           log_error ("error binding socket to `%s': %s\n",
487                      serv_addr.sun_path, strerror (errno) );
488           close (fd);
489           exit (1);
490         }
491   
492       if (listen (fd, 5 ) == -1)
493         {
494           log_error ("listen() failed: %s\n", strerror (errno));
495           close (fd);
496           exit (1);
497         }
498
499       if (opt.verbose)
500         log_info ("listening on socket `%s'\n", socket_name );
501
502
503       fflush (NULL);
504       pid = fork ();
505       if (pid == (pid_t)-1) 
506         {
507           log_fatal ("fork failed: %s\n", strerror (errno) );
508           exit (1);
509         }
510       else if (pid) 
511         { /* we are the parent */
512           char *infostr;
513           
514           close (fd);
515           
516           /* create the info string: <name>:<pid>:<protocol_version> */
517           if (asprintf (&infostr, "SCDAEMON_INFO=%s:%lu:1",
518                         socket_name, (ulong)pid ) < 0)
519             {
520               log_error ("out of core\n");
521               kill (pid, SIGTERM);
522               exit (1);
523             }
524           *socket_name = 0; /* don't let cleanup() remove the socket -
525                                the child should do this from now on */
526           if (argc) 
527             { /* run the program given on the commandline */
528               if (putenv (infostr))
529                 {
530                   log_error ("failed to set environment: %s\n",
531                              strerror (errno) );
532                   kill (pid, SIGTERM );
533                   exit (1);
534                 }
535               execvp (argv[0], argv);
536               log_error ("failed to run the command: %s\n", strerror (errno));
537               kill (pid, SIGTERM);
538               exit (1);
539             }
540           else
541             {
542               /* print the environment string, so that the caller can use
543                  shell's eval to set it */
544               if (csh_style)
545                 {
546                   *strchr (infostr, '=') = ' ';
547                   printf ( "setenv %s\n", infostr);
548                 }
549               else
550                 {
551                   printf ( "%s; export SCDAEMON_INFO;\n", infostr);
552                 }
553               free (infostr);
554               exit (0); 
555             }
556           /* NOTREACHED */
557         } /* end parent */
558       
559       /* this is the child */
560
561       /* detach from tty and put process into a new session */
562       if (!nodetach )
563         {  /* close stdin, stdout and stderr unless it is the log stream */
564           for (i=0; i <= 2; i++) 
565             {
566               if ( log_get_fd () != i)
567                 close (i);
568             }
569           if (setsid() == -1)
570             {
571               log_error ("setsid() failed: %s\n", strerror(errno) );
572               cleanup ();
573               exit (1);
574             }
575         }
576
577       /* setup signals */
578       {
579         struct sigaction oact, nact;
580         
581         nact.sa_handler = cleanup_sh;
582         sigemptyset (&nact.sa_mask);
583         nact.sa_flags = 0;
584         
585         sigaction (SIGHUP, NULL, &oact);
586         if (oact.sa_handler != SIG_IGN)
587           sigaction (SIGHUP, &nact, NULL);
588         sigaction( SIGTERM, NULL, &oact );
589         if (oact.sa_handler != SIG_IGN)
590           sigaction (SIGTERM, &nact, NULL);
591         nact.sa_handler = SIG_IGN;
592         sigaction (SIGPIPE, &nact, NULL);
593         sigaction (SIGINT, &nact, NULL);
594       }
595
596       if (chdir("/"))
597         {
598           log_error ("chdir to / failed: %s\n", strerror (errno));
599           exit (1);
600         }
601
602       scd_command_handler (fd);
603
604       close (fd);
605     }
606   
607   return 0;
608 }
609
610 void
611 scd_exit (int rc)
612 {
613   #if 0
614 #warning no update_random_seed_file
615   update_random_seed_file();
616   #endif
617 #if 0
618   /* at this time a bit annoying */
619   if (opt.debug & DBG_MEMSTAT_VALUE)
620     {
621       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
622       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
623     }
624   if (opt.debug)
625     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
626 #endif
627   gcry_control (GCRYCTL_TERM_SECMEM );
628   rc = rc? rc : log_get_errorcount(0)? 2 : 0;
629   exit (rc);
630 }
631
632
633 void
634 scd_init_default_ctrl (CTRL ctrl)
635 {
636
637 }
638