1 /* g13.c - Disk Key management with GnuPG
2  * Copyright (C) 2009 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 3 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, see <https://www.gnu.org/licenses/>.
18  * SPDX-License-Identifier: GPL-3.0-or-later
19  */
20 
21 #include <config.h>
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <ctype.h>
28 #include <unistd.h>
29 #include <fcntl.h>
30 #include <npth.h>
31 
32 #define INCLUDED_BY_MAIN_MODULE 1
33 #include "g13.h"
34 
35 #include <gcrypt.h>
36 #include <assuan.h>
37 
38 #include "../common/i18n.h"
39 #include "../common/sysutils.h"
40 #include "../common/gc-opt-flags.h"
41 #include "../common/asshelp.h"
42 #include "../common/init.h"
43 #include "keyblob.h"
44 #include "server.h"
45 #include "runner.h"
46 #include "create.h"
47 #include "mount.h"
48 #include "suspend.h"
49 #include "mountinfo.h"
50 #include "backend.h"
51 #include "call-syshelp.h"
52 
53 
54 enum cmd_and_opt_values {
55   aNull = 0,
56   oQuiet	= 'q',
57   oVerbose	= 'v',
58   oRecipient	= 'r',
59 
60   aGPGConfList  = 500,
61   aGPGConfTest,
62   aCreate,
63   aMount,
64   aUmount,
65   aSuspend,
66   aResume,
67   aServer,
68   aFindDevice,
69 
70   oOptions,
71   oDebug,
72   oDebugLevel,
73   oDebugAll,
74   oDebugNone,
75   oDebugWait,
76   oDebugAllowCoreDump,
77   oLogFile,
78   oNoLogFile,
79   oAuditLog,
80 
81   oOutput,
82 
83   oAgentProgram,
84   oGpgProgram,
85   oType,
86 
87   oDisplay,
88   oTTYname,
89   oTTYtype,
90   oLCctype,
91   oLCmessages,
92   oXauthority,
93 
94   oStatusFD,
95   oLoggerFD,
96 
97   oNoVerbose,
98   oNoSecmemWarn,
99   oNoGreeting,
100   oNoTTY,
101   oNoOptions,
102   oHomedir,
103   oWithColons,
104   oDryRun,
105   oNoDetach,
106 
107   oNoRandomSeedFile,
108   oFakedSystemTime
109  };
110 
111 
112 static gpgrt_opt_t opts[] = {
113 
114   ARGPARSE_group (300, N_("@Commands:\n ")),
115 
116   ARGPARSE_c (aCreate, "create", N_("Create a new file system container")),
117   ARGPARSE_c (aMount,  "mount",  N_("Mount a file system container") ),
118   ARGPARSE_c (aUmount, "umount", N_("Unmount a file system container") ),
119   ARGPARSE_c (aSuspend, "suspend", N_("Suspend a file system container") ),
120   ARGPARSE_c (aResume,  "resume",  N_("Resume a file system container") ),
121   ARGPARSE_c (aServer, "server", N_("Run in server mode")),
122   ARGPARSE_c (aFindDevice, "find-device", "@"),
123 
124   ARGPARSE_c (aGPGConfList, "gpgconf-list", "@"),
125   ARGPARSE_c (aGPGConfTest, "gpgconf-test", "@"),
126 
127   ARGPARSE_group (301, N_("@\nOptions:\n ")),
128 
129   ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")),
130   ARGPARSE_s_s (oType, "type", N_("|NAME|use container format NAME")),
131 
132   ARGPARSE_s_s (oOutput, "output", N_("|FILE|write output to FILE")),
133   ARGPARSE_s_n (oVerbose, "verbose", N_("verbose")),
134   ARGPARSE_s_n (oQuiet,	"quiet",  N_("be somewhat more quiet")),
135   ARGPARSE_s_n (oNoTTY, "no-tty", N_("don't use the terminal at all")),
136   ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")),
137   ARGPARSE_s_s (oLogFile, "log-file",  N_("|FILE|write log output to FILE")),
138   ARGPARSE_s_n (oNoLogFile, "no-log-file", "@"),
139   ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"),
140 
141   ARGPARSE_s_n (oDryRun, "dry-run", N_("do not make any changes")),
142 
143   ARGPARSE_conffile (oOptions, "options", N_("|FILE|read options from FILE")),
144 
145   ARGPARSE_s_s (oDebug, "debug", "@"),
146   ARGPARSE_s_s (oDebugLevel, "debug-level",
147                 N_("|LEVEL|set the debugging level to LEVEL")),
148   ARGPARSE_s_n (oDebugAll, "debug-all", "@"),
149   ARGPARSE_s_n (oDebugNone, "debug-none", "@"),
150   ARGPARSE_s_i (oDebugWait, "debug-wait", "@"),
151   ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"),
152 
153   ARGPARSE_s_i (oStatusFD, "status-fd",
154                 N_("|FD|write status info to this FD")),
155 
156   ARGPARSE_group (302, N_(
157   "@\n(See the man page for a complete listing of all commands and options)\n"
158   )),
159 
160   ARGPARSE_group (303, N_("@\nExamples:\n\n"
161     " blurb\n"
162                           " blurb\n")),
163 
164   /* Hidden options. */
165   ARGPARSE_s_n (oNoVerbose, "no-verbose", "@"),
166   ARGPARSE_s_n (oNoSecmemWarn, "no-secmem-warning", "@"),
167   ARGPARSE_s_n (oNoGreeting, "no-greeting", "@"),
168   ARGPARSE_noconffile (oNoOptions, "no-options", "@"),
169   ARGPARSE_s_s (oHomedir, "homedir", "@"),
170   ARGPARSE_s_s (oAgentProgram, "agent-program", "@"),
171   ARGPARSE_s_s (oGpgProgram, "gpg-program", "@"),
172   ARGPARSE_s_s (oDisplay,    "display", "@"),
173   ARGPARSE_s_s (oTTYname,    "ttyname", "@"),
174   ARGPARSE_s_s (oTTYtype,    "ttytype", "@"),
175   ARGPARSE_s_s (oLCctype,    "lc-ctype", "@"),
176   ARGPARSE_s_s (oLCmessages, "lc-messages", "@"),
177   ARGPARSE_s_s (oXauthority, "xauthority", "@"),
178   ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
179   ARGPARSE_s_n (oWithColons, "with-colons", "@"),
180   ARGPARSE_s_n (oNoRandomSeedFile,  "no-random-seed-file", "@"),
181 
182   /* Command aliases.  */
183 
184   ARGPARSE_end ()
185 };
186 
187 
188 /* The list of supported debug flags.  */
189 static struct debug_flags_s debug_flags [] =
190   {
191     { DBG_MOUNT_VALUE  , "mount"  },
192     { DBG_CRYPTO_VALUE , "crypto"  },
193     { DBG_MEMORY_VALUE , "memory"  },
194     { DBG_MEMSTAT_VALUE, "memstat" },
195     { DBG_IPC_VALUE    , "ipc"     },
196     { 0, NULL }
197   };
198 
199 
200 /* The timer tick interval used by the idle task.  */
201 #define TIMERTICK_INTERVAL_SEC     (1)
202 
203 /* It is possible that we are currently running under setuid permissions.  */
204 static int maybe_setuid = 1;
205 
206 /* Helper to implement --debug-level and --debug.  */
207 static const char *debug_level;
208 static unsigned int debug_value;
209 
210 /* Flag to indicate that a shutdown was requested.  */
211 static int shutdown_pending;
212 
213 /* The thread id of the idle task.  */
214 static npth_t idle_task_thread;
215 
216 
217 /* The container type as specified on the command line.  */
218 static int cmdline_conttype;
219 
220 
221 
222 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
223                      enum cmd_and_opt_values new_cmd );
224 
225 static void start_idle_task (void);
226 static void join_idle_task (void);
227 
228 
229 /* Begin NPth wrapper functions. */
230 ASSUAN_SYSTEM_NPTH_IMPL;
231 
232 
233 static const char *
my_strusage(int level)234 my_strusage( int level )
235 {
236   const char *p;
237 
238   switch (level)
239     {
240     case  9: p = "GPL-3.0-or-later"; break;
241     case 11: p = "@G13@ (@GNUPG@)";
242       break;
243     case 13: p = VERSION; break;
244     case 14: p = GNUPG_DEF_COPYRIGHT_LINE; break;
245     case 17: p = PRINTABLE_OS_NAME; break;
246     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
247       break;
248     case 1:
249     case 40: p = _("Usage: @G13@ [options] [files] (-h for help)");
250       break;
251     case 41:
252       p = _("Syntax: @G13@ [options] [files]\n"
253             "Create, mount or unmount an encrypted file system container\n");
254       break;
255 
256     case 31: p = "\nHome: "; break;
257     case 32: p = gnupg_homedir (); break;
258 
259     default: p = NULL; break;
260     }
261   return p;
262 }
263 
264 
265 static void
wrong_args(const char * text)266 wrong_args (const char *text)
267 {
268   fprintf (stderr, _("usage: %s [options] "), G13_NAME);
269   fputs (text, stderr);
270   putc ('\n', stderr);
271   g13_exit (2);
272 }
273 
274 
275 /* Setup the debugging.  With a DEBUG_LEVEL of NULL only the active
276    debug flags are propagated to the subsystems.  With DEBUG_LEVEL
277    set, a specific set of debug flags is set; and individual debugging
278    flags will be added on top.  */
279 static void
set_debug(void)280 set_debug (void)
281 {
282   int numok = (debug_level && digitp (debug_level));
283   int numlvl = numok? atoi (debug_level) : 0;
284 
285   if (!debug_level)
286     ;
287   else if (!strcmp (debug_level, "none") || (numok && numlvl < 1))
288     opt.debug = 0;
289   else if (!strcmp (debug_level, "basic") || (numok && numlvl <= 2))
290     opt.debug = DBG_IPC_VALUE|DBG_MOUNT_VALUE;
291   else if (!strcmp (debug_level, "advanced") || (numok && numlvl <= 5))
292     opt.debug = DBG_IPC_VALUE|DBG_MOUNT_VALUE;
293   else if (!strcmp (debug_level, "expert") || (numok && numlvl <= 8))
294     opt.debug = (DBG_IPC_VALUE|DBG_MOUNT_VALUE|DBG_CRYPTO_VALUE);
295   else if (!strcmp (debug_level, "guru") || numok)
296     {
297       opt.debug = ~0;
298       /* if (numok) */
299       /*   opt.debug &= ~(DBG_HASHING_VALUE); */
300     }
301   else
302     {
303       log_error (_("invalid debug-level '%s' given\n"), debug_level);
304       g13_exit(2);
305     }
306 
307   opt.debug |= debug_value;
308 
309   if (opt.debug && !opt.verbose)
310     opt.verbose = 1;
311   if (opt.debug)
312     opt.quiet = 0;
313 
314   if (opt.debug & DBG_CRYPTO_VALUE )
315     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
316   gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
317 
318   if (opt.debug)
319     parse_debug_flag (NULL, &opt.debug, debug_flags);
320 }
321 
322 
323 
324 static void
set_cmd(enum cmd_and_opt_values * ret_cmd,enum cmd_and_opt_values new_cmd)325 set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
326 {
327   enum cmd_and_opt_values cmd = *ret_cmd;
328 
329   if (!cmd || cmd == new_cmd)
330     cmd = new_cmd;
331   else
332     {
333       log_error (_("conflicting commands\n"));
334       g13_exit (2);
335     }
336 
337   *ret_cmd = cmd;
338 }
339 
340 
341 int
main(int argc,char ** argv)342 main (int argc, char **argv)
343 {
344   gpgrt_argparse_t pargs;
345   int orig_argc;
346   char **orig_argv;
347   gpg_error_t err = 0;
348   /* const char *fname; */
349   int may_coredump;
350   char *last_configname = NULL;
351   const char *configname = NULL;
352   int debug_argparser = 0;
353   int no_more_options = 0;
354   char *logfile = NULL;
355   int greeting = 0;
356   int nogreeting = 0;
357   /* int debug_wait = 0; */
358   int use_random_seed = 1;
359   /* int nodetach = 0; */
360   /* int nokeysetup = 0; */
361   enum cmd_and_opt_values cmd = 0;
362   struct server_control_s ctrl;
363   strlist_t recipients = NULL;
364 
365   /*mtrace();*/
366 
367   early_system_init ();
368   gnupg_reopen_std (G13_NAME);
369   gpgrt_set_strusage (my_strusage);
370   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
371 
372   log_set_prefix (G13_NAME, GPGRT_LOG_WITH_PREFIX);
373 
374   /* Make sure that our subsystems are ready.  */
375   i18n_init ();
376   init_common_subsystems (&argc, &argv);
377 
378   npth_init ();
379 
380   /* Take extra care of the random pool.  */
381   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
382 
383   may_coredump = disable_core_dumps ();
384 
385   g13_init_signals ();
386 
387   dotlock_create (NULL, 0); /* Register locking cleanup.  */
388 
389   opt.session_env = session_env_new ();
390   if (!opt.session_env)
391     log_fatal ("error allocating session environment block: %s\n",
392                strerror (errno));
393 
394   /* First check whether we have a config file on the commandline.  */
395   orig_argc = argc;
396   orig_argv = argv;
397   pargs.argc = &argc;
398   pargs.argv = &argv;
399   pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
400   while (gpgrt_argparse (NULL, &pargs, opts))
401     {
402       switch (pargs.r_opt)
403         {
404         case oDebug:
405         case oDebugAll:
406           debug_argparser++;
407           break;
408 
409         case oHomedir:
410           gnupg_set_homedir (pargs.r.ret_str);
411           break;
412         }
413     }
414   /* Reset the flags.  */
415   pargs.flags &= ~(ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
416 
417   /* Initialize the secure memory. */
418   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
419   maybe_setuid = 0;
420 
421   /*
422    *  Now we are now working under our real uid
423    */
424 
425   /* Setup malloc hooks. */
426   {
427     struct assuan_malloc_hooks malloc_hooks;
428 
429     malloc_hooks.malloc = gcry_malloc;
430     malloc_hooks.realloc = gcry_realloc;
431     malloc_hooks.free = gcry_free;
432     assuan_set_malloc_hooks (&malloc_hooks);
433   }
434 
435   /* Prepare libassuan.  */
436   assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
437   assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);
438   setup_libassuan_logging (&opt.debug, NULL);
439 
440   /* Setup a default control structure for command line mode.  */
441   memset (&ctrl, 0, sizeof ctrl);
442   g13_init_default_ctrl (&ctrl);
443   ctrl.no_server = 1;
444   ctrl.status_fd = -1; /* No status output. */
445 
446   /* The configuraton directories for use by gpgrt_argparser.  */
447   gpgrt_set_confdir (GPGRT_CONFDIR_SYS, gnupg_sysconfdir ());
448   gpgrt_set_confdir (GPGRT_CONFDIR_USER, gnupg_homedir ());
449 
450   /* We are re-using the struct, thus the reset flag.  We OR the
451    * flags so that the internal intialized flag won't be cleared. */
452   argc        = orig_argc;
453   argv        = orig_argv;
454   pargs.argc  = &argc;
455   pargs.argv  = &argv;
456   pargs.flags |=  (ARGPARSE_FLAG_RESET
457                    | ARGPARSE_FLAG_KEEP
458                    | ARGPARSE_FLAG_SYS
459                    | ARGPARSE_FLAG_USER);
460 
461   while (!no_more_options
462          && gpgrt_argparser (&pargs, opts, G13_NAME EXTSEP_S "conf"))
463     {
464       switch (pargs.r_opt)
465         {
466         case ARGPARSE_CONFFILE:
467           {
468             if (debug_argparser)
469               log_info (_("reading options from '%s'\n"),
470                         pargs.r_type? pargs.r.ret_str: "[cmdline]");
471             if (pargs.r_type)
472               {
473                 xfree (last_configname);
474                 last_configname = xstrdup (pargs.r.ret_str);
475                 configname = last_configname;
476               }
477             else
478               configname = NULL;
479           }
480           break;
481 
482 	case aGPGConfList:
483 	case aGPGConfTest:
484           set_cmd (&cmd, pargs.r_opt);
485           nogreeting = 1;
486           /* nokeysetup = 1; */
487           break;
488 
489         case aServer:
490         case aMount:
491         case aUmount:
492         case aSuspend:
493         case aResume:
494         case aCreate:
495         case aFindDevice:
496           set_cmd (&cmd, pargs.r_opt);
497           break;
498 
499         case oOutput: opt.outfile = pargs.r.ret_str; break;
500 
501         case oQuiet: opt.quiet = 1; break;
502         case oNoGreeting: nogreeting = 1; break;
503         case oNoTTY:  break;
504 
505         case oDryRun: opt.dry_run = 1; break;
506 
507         case oVerbose:
508           opt.verbose++;
509           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
510           break;
511         case oNoVerbose:
512           opt.verbose = 0;
513           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
514           break;
515 
516         case oLogFile: logfile = pargs.r.ret_str; break;
517         case oNoLogFile: logfile = NULL; break;
518 
519         case oNoDetach: /*nodetach = 1; */break;
520 
521         case oDebug:
522           if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
523             {
524               pargs.r_opt = ARGPARSE_INVALID_ARG;
525               pargs.err = ARGPARSE_PRINT_ERROR;
526             }
527             break;
528         case oDebugAll: debug_value = ~0; break;
529         case oDebugNone: debug_value = 0; break;
530         case oDebugLevel: debug_level = pargs.r.ret_str; break;
531         case oDebugWait: /*debug_wait = pargs.r.ret_int; */break;
532         case oDebugAllowCoreDump:
533           may_coredump = enable_core_dumps ();
534           break;
535 
536         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
537         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
538 
539         case oHomedir: gnupg_set_homedir (pargs.r.ret_str); break;
540 
541         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
542         case oGpgProgram: opt.gpg_program = pargs.r.ret_str;  break;
543         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
544         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
545         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
546         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
547         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
548         case oXauthority: opt.xauthority = xstrdup (pargs.r.ret_str); break;
549 
550         case oFakedSystemTime:
551           {
552             time_t faked_time = isotime2epoch (pargs.r.ret_str);
553             if (faked_time == (time_t)(-1))
554               faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
555             gnupg_set_time (faked_time, 0);
556           }
557           break;
558 
559         case oNoSecmemWarn: gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); break;
560 
561         case oNoRandomSeedFile: use_random_seed = 0; break;
562 
563         case oRecipient: /* Store the encryption key.  */
564           add_to_strlist (&recipients, pargs.r.ret_str);
565           break;
566 
567         case oType:
568           if (!strcmp (pargs.r.ret_str, "help"))
569             {
570               be_parse_conttype_name (NULL);
571               g13_exit (0);
572             }
573           cmdline_conttype = be_parse_conttype_name (pargs.r.ret_str);
574           if (!cmdline_conttype)
575             {
576               pargs.r_opt = ARGPARSE_INVALID_ARG;
577               pargs.err = ARGPARSE_PRINT_ERROR;
578             }
579           break;
580 
581         default:
582           if (configname)
583             pargs.err = ARGPARSE_PRINT_WARNING;
584           else
585             pargs.err = ARGPARSE_PRINT_ERROR;
586           break;
587 	}
588     }
589 
590   gpgrt_argparse (NULL, &pargs, NULL);
591 
592   /* Construct GPG arguments.  */
593   {
594     strlist_t last;
595     last = append_to_strlist (&opt.gpg_arguments, "-z");
596     last = append_to_strlist (&last, "0");
597     last = append_to_strlist (&last, "--trust-model");
598     last = append_to_strlist (&last, "always");
599     (void) last;
600   }
601 
602   if (!last_configname)
603     opt.config_filename = gpgrt_fnameconcat (gnupg_homedir (),
604                                              G13_NAME EXTSEP_S "conf",
605                                              NULL);
606   else
607     {
608       opt.config_filename = last_configname;
609       last_configname = NULL;
610     }
611 
612   if (log_get_errorcount(0))
613     g13_exit(2);
614 
615   /* Now that we have the options parsed we need to update the default
616      control structure.  */
617   g13_init_default_ctrl (&ctrl);
618   ctrl.recipients = recipients;
619   recipients = NULL;
620 
621   if (nogreeting)
622     greeting = 0;
623 
624   if (greeting)
625     {
626       fprintf (stderr, "%s %s; %s\n",
627                gpgrt_strusage(11), gpgrt_strusage(13), gpgrt_strusage(14) );
628       fprintf (stderr, "%s\n", gpgrt_strusage(15));
629     }
630 
631   if (may_coredump && !opt.quiet)
632     log_info (_("WARNING: program may create a core file!\n"));
633 
634   /* Print a warning if an argument looks like an option.  */
635   if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
636     {
637       int i;
638 
639       for (i=0; i < argc; i++)
640         if (argv[i][0] == '-' && argv[i][1] == '-')
641           log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
642     }
643 
644 
645   if (logfile)
646     {
647       log_set_file (logfile);
648       log_set_prefix (NULL, (GPGRT_LOG_WITH_PREFIX
649                              | GPGRT_LOG_WITH_TIME
650                              | GPGRT_LOG_WITH_PID));
651     }
652 
653   if (gnupg_faked_time_p ())
654     {
655       gnupg_isotime_t tbuf;
656 
657       log_info (_("WARNING: running with faked system time: "));
658       gnupg_get_isotime (tbuf);
659       dump_isotime (tbuf);
660       log_printf ("\n");
661     }
662 
663   /* Print any pending secure memory warnings.  */
664   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
665 
666   /* Setup the debug flags for all subsystems.  */
667   set_debug ();
668 
669   /* Install emergency cleanup handler.  */
670   g13_install_emergency_cleanup ();
671 
672   /* Terminate if we found any error until now.  */
673   if (log_get_errorcount(0))
674     g13_exit (2);
675 
676   /* Set the standard GnuPG random seed file.  */
677   if (use_random_seed)
678     {
679       char *p = make_filename (gnupg_homedir (), "random_seed", NULL);
680       gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
681       xfree(p);
682     }
683 
684   /* Store given filename into FNAME. */
685   /* fname = argc? *argv : NULL; */
686 
687   /* Parse all given encryption keys.  This does a lookup of the keys
688      and stops if any of the given keys was not found. */
689 #if 0 /* Currently not implemented.  */
690   if (!nokeysetup)
691     {
692       strlist_t sl;
693       int failed = 0;
694 
695       for (sl = ctrl->recipients; sl; sl = sl->next)
696         if (check_encryption_key ())
697           failed = 1;
698       if (failed)
699         g13_exit (1);
700     }
701 #endif /*0*/
702 
703   /* Dispatch command.  */
704   err = 0;
705   switch (cmd)
706     {
707     case aGPGConfList:
708       { /* List options and default values in the GPG Conf format.  */
709 	char *config_filename_esc = percent_escape (opt.config_filename, NULL);
710 
711         printf ("gpgconf-g13.conf:%lu:\"%s\n",
712                 GC_OPT_FLAG_DEFAULT, config_filename_esc);
713         xfree (config_filename_esc);
714 
715         printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE);
716 	printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE);
717 	printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT);
718 	printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE);
719       }
720       break;
721     case aGPGConfTest:
722       /* This is merely a dummy command to test whether the
723          configuration file is valid.  */
724       break;
725 
726     case aServer:
727       {
728         start_idle_task ();
729         ctrl.no_server = 0;
730         err = g13_server (&ctrl);
731         if (err)
732           log_error ("server exited with error: %s <%s>\n",
733                      gpg_strerror (err), gpg_strsource (err));
734         else
735           g13_request_shutdown ();
736       }
737       break;
738 
739     case aFindDevice:
740       {
741         char *blockdev;
742 
743         if (argc != 1)
744           wrong_args ("--find-device name");
745 
746         err = call_syshelp_find_device (&ctrl, argv[0], &blockdev);
747         if (err)
748           log_error ("error finding device '%s': %s <%s>\n",
749                      argv[0], gpg_strerror (err), gpg_strsource (err));
750         else
751           puts (blockdev);
752       }
753       break;
754 
755     case aCreate: /* Create a new container. */
756       {
757         if (argc != 1)
758           wrong_args ("--create filename");
759         start_idle_task ();
760         err = g13_create_container (&ctrl, argv[0]);
761         if (err)
762           log_error ("error creating a new container: %s <%s>\n",
763                      gpg_strerror (err), gpg_strsource (err));
764         else
765           g13_request_shutdown ();
766       }
767       break;
768 
769     case aMount: /* Mount a container. */
770       {
771         if (argc != 1 && argc != 2 )
772           wrong_args ("--mount filename [mountpoint]");
773         start_idle_task ();
774         err = g13_mount_container (&ctrl, argv[0], argc == 2?argv[1]:NULL);
775         if (err)
776           log_error ("error mounting container '%s': %s <%s>\n",
777                      *argv, gpg_strerror (err), gpg_strsource (err));
778       }
779       break;
780 
781     case aUmount: /* Unmount a mounted container.  */
782       {
783         if (argc != 1)
784           wrong_args ("--umount filename");
785         err = g13_umount_container (&ctrl, argv[0], NULL);
786         if (err)
787           log_error ("error unmounting container '%s': %s <%s>\n",
788                      *argv, gpg_strerror (err), gpg_strsource (err));
789       }
790       break;
791 
792     case aSuspend: /* Suspend a container. */
793       {
794         /* Fixme: Should we add a suspend all container option?  */
795         if (argc != 1)
796           wrong_args ("--suspend filename");
797         err = g13_suspend_container (&ctrl, argv[0]);
798         if (err)
799           log_error ("error suspending container '%s': %s <%s>\n",
800                      *argv, gpg_strerror (err), gpg_strsource (err));
801       }
802       break;
803 
804     case aResume: /* Resume a suspended container. */
805       {
806         /* Fixme: Should we add a resume all container option?  */
807         if (argc != 1)
808           wrong_args ("--resume filename");
809         err = g13_resume_container (&ctrl, argv[0]);
810         if (err)
811           log_error ("error resuming container '%s': %s <%s>\n",
812                      *argv, gpg_strerror (err), gpg_strsource (err));
813       }
814       break;
815 
816     default:
817       log_error (_("invalid command (there is no implicit command)\n"));
818       break;
819     }
820 
821   g13_deinit_default_ctrl (&ctrl);
822 
823   if (!err)
824     join_idle_task ();
825 
826   /* Cleanup.  */
827   g13_exit (0);
828   return 8; /*NOTREACHED*/
829 }
830 
831 
832 /* Store defaults into the per-connection CTRL object.  */
833 void
g13_init_default_ctrl(ctrl_t ctrl)834 g13_init_default_ctrl (ctrl_t ctrl)
835 {
836   ctrl->conttype = cmdline_conttype? cmdline_conttype : CONTTYPE_ENCFS;
837 }
838 
839 
840 /* Release remaining resources allocated in the CTRL object.  */
841 void
g13_deinit_default_ctrl(ctrl_t ctrl)842 g13_deinit_default_ctrl (ctrl_t ctrl)
843 {
844   call_syshelp_release (ctrl);
845   FREE_STRLIST (ctrl->recipients);
846 }
847 
848 
849 /* Request a shutdown.  This can be used when the process should
850  * finish instead of running the idle task.  */
851 void
g13_request_shutdown(void)852 g13_request_shutdown (void)
853 {
854   shutdown_pending++;
855 }
856 
857 
858 /* This function is called for each signal we catch.  It is run in the
859    main context or the one of a NPth thread and thus it is not
860    restricted in what it may do.  */
861 static void
handle_signal(int signo)862 handle_signal (int signo)
863 {
864   switch (signo)
865     {
866 #ifndef HAVE_W32_SYSTEM
867     case SIGHUP:
868       log_info ("SIGHUP received - re-reading configuration\n");
869       /* Fixme:  Not yet implemented.  */
870       break;
871 
872     case SIGUSR1:
873       log_info ("SIGUSR1 received - printing internal information:\n");
874       /* Fixme: We need to see how to integrate pth dumping into our
875          logging system.  */
876       /* pth_ctrl (PTH_CTRL_DUMPSTATE, log_get_stream ()); */
877       mountinfo_dump_all ();
878       break;
879 
880     case SIGUSR2:
881       log_info ("SIGUSR2 received - no action defined\n");
882       break;
883 
884     case SIGTERM:
885       if (!shutdown_pending)
886         log_info ("SIGTERM received - shutting down ...\n");
887       else
888         log_info ("SIGTERM received - still %u runners active\n",
889                   runner_get_threads ());
890       shutdown_pending++;
891       if (shutdown_pending > 2)
892         {
893           log_info ("shutdown forced\n");
894           log_info ("%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13) );
895           g13_exit (0);
896 	}
897       break;
898 
899     case SIGINT:
900       log_info ("SIGINT received - immediate shutdown\n");
901       log_info( "%s %s stopped\n", gpgrt_strusage(11), gpgrt_strusage(13));
902       g13_exit (0);
903       break;
904 #endif /*!HAVE_W32_SYSTEM*/
905 
906     default:
907       log_info ("signal %d received - no action defined\n", signo);
908     }
909 }
910 
911 
912 /* This ticker function is called about every TIMERTICK_INTERVAL_SEC
913    seconds. */
914 static void
handle_tick(void)915 handle_tick (void)
916 {
917   /* log_debug ("TICK\n"); */
918 }
919 
920 
921 /* The idle task.  We use a separate thread to do idle stuff and to
922    catch signals.  */
923 static void *
idle_task(void * dummy_arg)924 idle_task (void *dummy_arg)
925 {
926   int signo;           /* The number of a raised signal is stored here.  */
927   int saved_errno;
928   struct timespec abstime;
929   struct timespec curtime;
930   struct timespec timeout;
931   int ret;
932 
933   (void)dummy_arg;
934 
935   /* Create the event to catch the signals. */
936 #ifndef HAVE_W32_SYSTEM
937   npth_sigev_init ();
938   npth_sigev_add (SIGHUP);
939   npth_sigev_add (SIGUSR1);
940   npth_sigev_add (SIGUSR2);
941   npth_sigev_add (SIGINT);
942   npth_sigev_add (SIGTERM);
943   npth_sigev_fini ();
944 #endif
945 
946   npth_clock_gettime (&abstime);
947   abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
948 
949   for (;;)
950     {
951       /* The shutdown flag allows us to terminate the idle task.  */
952       if (shutdown_pending)
953         {
954           runner_cancel_all ();
955 
956           if (!runner_get_threads ())
957             break; /* ready */
958 	}
959 
960       npth_clock_gettime (&curtime);
961       if (!(npth_timercmp (&curtime, &abstime, <)))
962 	{
963 	  /* Timeout.  */
964 	  handle_tick ();
965 	  npth_clock_gettime (&abstime);
966 	  abstime.tv_sec += TIMERTICK_INTERVAL_SEC;
967 	}
968       npth_timersub (&abstime, &curtime, &timeout);
969 
970 #ifndef HAVE_W32_SYSTEM
971       ret = npth_pselect (0, NULL, NULL, NULL, &timeout, npth_sigev_sigmask());
972       saved_errno = errno;
973 
974       while (npth_sigev_get_pending(&signo))
975 	handle_signal (signo);
976 #else
977       ret = npth_eselect (0, NULL, NULL, NULL, &timeout, NULL, NULL);
978       saved_errno = errno;
979 #endif
980 
981       if (ret == -1 && saved_errno != EINTR)
982 	{
983           log_error (_("npth_pselect failed: %s - waiting 1s\n"),
984                      strerror (saved_errno));
985           npth_sleep (1);
986           continue;
987 	}
988 
989       if (ret <= 0)
990         {
991           /* Interrupt or timeout.  Will be handled when calculating the
992              next timeout.  */
993           continue;
994         }
995 
996       /* Here one would add processing of file descriptors.  */
997     }
998 
999   log_info (_("%s %s stopped\n"), gpgrt_strusage(11), gpgrt_strusage(13));
1000   return NULL;
1001 }
1002 
1003 
1004 /* Start the idle task.   */
1005 static void
start_idle_task(void)1006 start_idle_task (void)
1007 {
1008   npth_attr_t tattr;
1009   npth_t thread;
1010   sigset_t sigs;       /* The set of signals we want to catch.  */
1011   int err;
1012 
1013 #ifndef HAVE_W32_SYSTEM
1014   /* These signals should always go to the idle task, so they need to
1015      be blocked everywhere else.  We assume start_idle_task is called
1016      from the main thread before any other threads are created.  */
1017   sigemptyset (&sigs);
1018   sigaddset (&sigs, SIGHUP);
1019   sigaddset (&sigs, SIGUSR1);
1020   sigaddset (&sigs, SIGUSR2);
1021   sigaddset (&sigs, SIGINT);
1022   sigaddset (&sigs, SIGTERM);
1023   npth_sigmask (SIG_BLOCK, &sigs, NULL);
1024 #endif
1025 
1026   npth_attr_init (&tattr);
1027   npth_attr_setdetachstate (&tattr, NPTH_CREATE_JOINABLE);
1028 
1029   err = npth_create (&thread, &tattr, idle_task, NULL);
1030   if (err)
1031     {
1032       log_fatal ("error starting idle task: %s\n", strerror (err));
1033       return; /*NOTREACHED*/
1034     }
1035   npth_setname_np (thread, "idle-task");
1036   idle_task_thread = thread;
1037   npth_attr_destroy (&tattr);
1038 }
1039 
1040 
1041 /* Wait for the idle task to finish.  */
1042 static void
join_idle_task(void)1043 join_idle_task (void)
1044 {
1045   int err;
1046 
1047   /* FIXME: This assumes that a valid pthread_t is non-null.  That is
1048      not guaranteed.  */
1049   if (idle_task_thread)
1050     {
1051       err = npth_join (idle_task_thread, NULL);
1052       if (err)
1053         log_error ("waiting for idle task thread failed: %s\n",
1054                    strerror (err));
1055     }
1056 }
1057