1 /* g13.c - Disk Key management with GnuPG
2 * Copyright (C) 2009 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
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.
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.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
37 #include "gc-opt-flags.h"
42 enum cmd_and_opt_values
{
95 static ARGPARSE_OPTS opts
[] = {
97 ARGPARSE_group (300, N_("@Commands:\n ")),
99 ARGPARSE_c (aCreate
, "create", N_("Create a new file system container")),
100 ARGPARSE_c (aMount
, "mount", N_("Mount a file system container") ),
101 ARGPARSE_c (aUmount
, "umount", N_("Unmount a file system container") ),
103 ARGPARSE_c (aGPGConfList
, "gpgconf-list", "@"),
104 ARGPARSE_c (aGPGConfTest
, "gpgconf-test", "@"),
106 ARGPARSE_group (301, N_("@\nOptions:\n ")),
108 ARGPARSE_s_s (oRecipient
, "recipient", N_("|USER-ID|encrypt for USER-ID")),
110 ARGPARSE_s_s (oOutput
, "output", N_("|FILE|write output to FILE")),
111 ARGPARSE_s_n (oVerbose
, "verbose", N_("verbose")),
112 ARGPARSE_s_n (oQuiet
, "quiet", N_("be somewhat more quiet")),
113 ARGPARSE_s_n (oNoTTY
, "no-tty", N_("don't use the terminal at all")),
114 ARGPARSE_s_s (oLogFile
, "log-file", N_("|FILE|write log output to FILE")),
115 ARGPARSE_s_n (oNoLogFile
, "no-log-file", "@"),
116 ARGPARSE_s_i (oLoggerFD
, "logger-fd", "@"),
118 ARGPARSE_s_s (oAuditLog
, "audit-log",
119 N_("|FILE|write an audit log to FILE")),
120 ARGPARSE_s_n (oDryRun
, "dry-run", N_("do not make any changes")),
122 ARGPARSE_s_s (oOptions
, "options", N_("|FILE|read options from FILE")),
124 ARGPARSE_p_u (oDebug
, "debug", "@"),
125 ARGPARSE_s_s (oDebugLevel
, "debug-level",
126 N_("|LEVEL|set the debugging level to LEVEL")),
127 ARGPARSE_s_n (oDebugAll
, "debug-all", "@"),
128 ARGPARSE_s_n (oDebugNone
, "debug-none", "@"),
129 ARGPARSE_s_i (oDebugWait
, "debug-wait", "@"),
130 ARGPARSE_s_n (oDebugAllowCoreDump
, "debug-allow-core-dump", "@"),
132 ARGPARSE_s_i (oStatusFD
, "status-fd",
133 N_("|FD|write status info to this FD")),
135 ARGPARSE_group (302, N_(
136 "@\n(See the man page for a complete listing of all commands and options)\n"
139 ARGPARSE_group (303, N_("@\nExamples:\n\n"
143 /* Hidden options. */
144 ARGPARSE_s_n (oNoVerbose
, "no-verbose", "@"),
145 ARGPARSE_s_n (oNoSecmemWarn
, "no-secmem-warning", "@"),
146 ARGPARSE_s_n (oNoGreeting
, "no-greeting", "@"),
147 ARGPARSE_s_n (oNoOptions
, "no-options", "@"),
148 ARGPARSE_s_s (oHomedir
, "homedir", "@"),
149 ARGPARSE_s_s (oAgentProgram
, "agent-program", "@"),
150 ARGPARSE_s_s (oGpgProgram
, "gpg-program", "@"),
151 ARGPARSE_s_s (oDisplay
, "display", "@"),
152 ARGPARSE_s_s (oTTYname
, "ttyname", "@"),
153 ARGPARSE_s_s (oTTYtype
, "ttytype", "@"),
154 ARGPARSE_s_s (oLCctype
, "lc-ctype", "@"),
155 ARGPARSE_s_s (oLCmessages
, "lc-messages", "@"),
156 ARGPARSE_s_s (oXauthority
, "xauthority", "@"),
157 ARGPARSE_s_s (oFakedSystemTime
, "faked-system-time", "@"),
158 ARGPARSE_s_n (oWithColons
, "with-colons", "@"),
159 ARGPARSE_s_n (oNoRandomSeedFile
, "no-random-seed-file", "@"),
161 /* Command aliases. */
167 /* Global variable to keep an error count. */
168 int g13_errors_seen
= 0;
170 /* It is possible that we are currently running under setuid permissions. */
171 static int maybe_setuid
= 1;
173 /* Helper to implement --debug-level and --debug. */
174 static const char *debug_level
;
175 static unsigned int debug_value
;
177 static void set_cmd (enum cmd_and_opt_values
*ret_cmd
,
178 enum cmd_and_opt_values new_cmd
);
180 static void emergency_cleanup (void);
182 /* Begin Pth wrapper functions. */
183 GCRY_THREAD_OPTION_PTH_IMPL
;
184 static int fixed_gcry_pth_init (void)
186 return pth_self ()? 0 : (pth_init () == FALSE
) ? errno
: 0;
188 /* End Pth wrapper functions. */
192 my_strusage( int level
)
198 case 11: p
= "g13 (GnuPG)";
200 case 13: p
= VERSION
; break;
201 case 17: p
= PRINTABLE_OS_NAME
; break;
202 case 19: p
= _("Please report bugs to <" PACKAGE_BUGREPORT
">.\n");
205 case 40: p
= _("Usage: g13 [options] [files] (-h for help)");
208 p
= _("Syntax: g13 [options] [files]\n"
209 "Create, mount or unmount an encrypted file system container\n");
212 case 31: p
= "\nHome: "; break;
213 case 32: p
= opt
.homedir
; break;
215 default: p
= NULL
; break;
222 wrong_args (const char *text
)
224 fputs (_("usage: g13 [options] "), stderr
);
225 fputs (text
, stderr
);
231 /* Setup the debugging. With a DEBUG_LEVEL of NULL only the active
232 debug flags are propagated to the subsystems. With DEBUG_LEVEL
233 set, a specific set of debug flags is set; and individual debugging
234 flags will be added on top. */
240 else if (!strcmp (debug_level
, "none"))
242 else if (!strcmp (debug_level
, "basic"))
243 opt
.debug
= DBG_ASSUAN_VALUE
|DBG_MOUNT_VALUE
;
244 else if (!strcmp (debug_level
, "advanced"))
245 opt
.debug
= DBG_ASSUAN_VALUE
|DBG_MOUNT_VALUE
;
246 else if (!strcmp (debug_level
, "expert"))
247 opt
.debug
= (DBG_ASSUAN_VALUE
|DBG_MOUNT_VALUE
|DBG_CRYPTO_VALUE
);
248 else if (!strcmp (debug_level
, "guru"))
252 log_error (_("invalid debug-level `%s' given\n"), debug_level
);
256 opt
.debug
|= debug_value
;
258 if (opt
.debug
&& !opt
.verbose
)
263 if (opt
.debug
& DBG_CRYPTO_VALUE
)
264 gcry_control (GCRYCTL_SET_DEBUG_FLAGS
, 1);
265 gcry_control (GCRYCTL_SET_VERBOSITY
, (int)opt
.verbose
);
271 set_cmd (enum cmd_and_opt_values
*ret_cmd
, enum cmd_and_opt_values new_cmd
)
273 enum cmd_and_opt_values cmd
= *ret_cmd
;
275 if (!cmd
|| cmd
== new_cmd
)
279 log_error (_("conflicting commands\n"));
287 /* Helper to add recipients to a list. */
289 add_encryption_key (ctrl_t ctrl
, const char *name
,
290 void /*FIXME*/ *keylist
, int is_cms
)
292 /* FIXME: Decide whether to add a CMS or OpenPGP key and then add
293 the key to a list. */
294 /* int rc = foo_add_to_certlist (ctrl, name, 0, recplist, is_encrypt_to); */
297 /* if (recp_required) */
299 /* log_error ("can't encrypt to `%s': %s\n", name, gpg_strerror (rc)); */
300 /* gpgsm_status2 (ctrl, STATUS_INV_RECP, */
301 /* get_inv_recpsgnr_code (rc), name, NULL); */
304 /* log_info (_("NOTE: won't be able to encrypt to `%s': %s\n"), */
305 /* name, gpg_strerror (rc)); */
307 return 0; /* Key is good. */
312 main ( int argc
, char **argv
)
320 FILE *configfp
= NULL
;
321 char *configname
= NULL
;
322 unsigned configlineno
;
324 int no_more_options
= 0;
325 int default_config
=1;
326 char *logfile
= NULL
;
327 char *auditlog
= NULL
;
331 int use_random_seed
= 1;
333 enum cmd_and_opt_values cmd
= 0;
334 struct server_control_s ctrl
;
335 estream_t auditfp
= NULL
;
336 strlist_t recipients
= NULL
;
340 gnupg_reopen_std ("g13");
341 set_strusage (my_strusage
);
342 gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN
);
344 log_set_prefix ("g13", 1);
346 /* Make sure that our subsystems are ready. */
348 init_common_subsystems ();
350 /* Libgcrypt requires us to register the threading model first.
351 Note that this will also do the pth_init. */
352 gcry_threads_pth
.init
= fixed_gcry_pth_init
;
353 err
= gcry_control (GCRYCTL_SET_THREAD_CBS
, &gcry_threads_pth
);
356 log_fatal ("can't register GNU Pth with Libgcrypt: %s\n",
360 /* Check that the Libgcrypt is suitable. */
361 if (!gcry_check_version (NEED_LIBGCRYPT_VERSION
) )
362 log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
363 NEED_LIBGCRYPT_VERSION
, gcry_check_version (NULL
) );
365 /* Take extra care of the random pool. */
366 gcry_control (GCRYCTL_USE_SECURE_RNDPOOL
);
368 may_coredump
= disable_core_dumps ();
370 gnupg_init_signals (0, emergency_cleanup
);
372 create_dotlock (NULL
); /* Register locking cleanup. */
374 opt
.homedir
= default_homedir ();
376 /* First check whether we have a config file on the commandline. */
381 pargs
.flags
= 1|(1<<6); /* Do not remove the args, ignore version. */
382 while (arg_parse( &pargs
, opts
))
384 if (pargs
.r_opt
== oDebug
|| pargs
.r_opt
== oDebugAll
)
386 else if (pargs
.r_opt
== oOptions
)
387 { /* Yes, there is one, so we do not try the default one but
388 read the config file when it is encountered at the
392 else if (pargs
.r_opt
== oNoOptions
)
393 default_config
= 0; /* --no-options */
394 else if (pargs
.r_opt
== oHomedir
)
395 opt
.homedir
= pargs
.r
.ret_str
;
398 /* Initialize the secure memory. */
399 gcry_control (GCRYCTL_INIT_SECMEM
, 16384, 0);
403 Now we are now working under our real uid
406 /* Setup malloc hooks. */
408 struct assuan_malloc_hooks malloc_hooks
;
410 malloc_hooks
.malloc
= gcry_malloc
;
411 malloc_hooks
.realloc
= gcry_realloc
;
412 malloc_hooks
.free
= gcry_free
;
413 assuan_set_malloc_hooks (&malloc_hooks
);
416 /* Prepare libassuan. */
417 assuan_set_assuan_log_prefix (log_get_prefix (NULL
));
418 assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT
);
421 /* Setup a default control structure for command line mode. */
422 memset (&ctrl
, 0, sizeof ctrl
);
423 g13_init_default_ctrl (&ctrl
);
425 /* Set the default option file */
427 configname
= make_filename (opt
.homedir
, "g13.conf", NULL
);
433 pargs
.flags
= 1; /* Do not remove the args. */
439 configfp
= fopen (configname
, "r");
445 log_info (_("NOTE: no default option file `%s'\n"), configname
);
449 log_error (_("option file `%s': %s\n"),
450 configname
, strerror(errno
));
456 if (parse_debug
&& configname
)
457 log_info (_("reading options from `%s'\n"), configname
);
461 while (!no_more_options
462 && optfile_parse (configfp
, configname
, &configlineno
, &pargs
, opts
))
468 set_cmd (&cmd
, pargs
.r_opt
);
477 set_cmd (&cmd
, pargs
.r_opt
);
480 case oOutput
: opt
.outfile
= pargs
.r
.ret_str
; break;
482 case oQuiet
: opt
.quiet
= 1; break;
483 case oNoGreeting
: nogreeting
= 1; break;
486 case oDryRun
: opt
.dry_run
= 1; break;
490 gcry_control (GCRYCTL_SET_VERBOSITY
, (int)opt
.verbose
);
494 gcry_control (GCRYCTL_SET_VERBOSITY
, (int)opt
.verbose
);
497 case oLogFile
: logfile
= pargs
.r
.ret_str
; break;
498 case oNoLogFile
: logfile
= NULL
; break;
500 case oAuditLog
: auditlog
= pargs
.r
.ret_str
; break;
502 case oDebug
: debug_value
|= pargs
.r
.ret_ulong
; break;
503 case oDebugAll
: debug_value
= ~0; break;
504 case oDebugNone
: debug_value
= 0; break;
505 case oDebugLevel
: debug_level
= pargs
.r
.ret_str
; break;
506 case oDebugWait
: debug_wait
= pargs
.r
.ret_int
; break;
507 case oDebugAllowCoreDump
:
508 may_coredump
= enable_core_dumps ();
511 case oStatusFD
: ctrl
.status_fd
= pargs
.r
.ret_int
; break;
512 case oLoggerFD
: log_set_fd (pargs
.r
.ret_int
); break;
514 case oNoOptions
: break; /* no-options */
516 /* Config files may not be nested (silently ignore them). */
520 configname
= xstrdup (pargs
.r
.ret_str
);
525 case oHomedir
: opt
.homedir
= pargs
.r
.ret_str
; break;
527 case oAgentProgram
: opt
.agent_program
= pargs
.r
.ret_str
; break;
528 case oGpgProgram
: opt
.gpg_program
= pargs
.r
.ret_str
; break;
529 case oDisplay
: opt
.display
= xstrdup (pargs
.r
.ret_str
); break;
530 case oTTYname
: opt
.ttyname
= xstrdup (pargs
.r
.ret_str
); break;
531 case oTTYtype
: opt
.ttytype
= xstrdup (pargs
.r
.ret_str
); break;
532 case oLCctype
: opt
.lc_ctype
= xstrdup (pargs
.r
.ret_str
); break;
533 case oLCmessages
: opt
.lc_messages
= xstrdup (pargs
.r
.ret_str
); break;
534 case oXauthority
: opt
.xauthority
= xstrdup (pargs
.r
.ret_str
); break;
536 case oFakedSystemTime
:
538 time_t faked_time
= isotime2epoch (pargs
.r
.ret_str
);
539 if (faked_time
== (time_t)(-1))
540 faked_time
= (time_t)strtoul (pargs
.r
.ret_str
, NULL
, 10);
541 gnupg_set_time (faked_time
, 0);
545 case oNoSecmemWarn
: gcry_control (GCRYCTL_DISABLE_SECMEM_WARN
); break;
547 case oNoRandomSeedFile
: use_random_seed
= 0; break;
549 case oRecipient
: /* Store the encryption key. */
550 add_to_strlist (&recipients
, pargs
.r
.ret_str
);
555 pargs
.err
= configfp
? ARGPARSE_PRINT_WARNING
:ARGPARSE_PRINT_ERROR
;
564 /* Keep a copy of the config filename. */
565 opt
.config_filename
= configname
;
572 if (!opt
.config_filename
)
573 opt
.config_filename
= make_filename (opt
.homedir
, "g13.conf", NULL
);
575 if (log_get_errorcount(0))
578 /* Now that we have the options parsed we need to update the default
579 control structure. */
580 g13_init_default_ctrl (&ctrl
);
587 fprintf(stderr
, "%s %s; %s\n",
588 strusage(11), strusage(13), strusage(14) );
589 fprintf(stderr
, "%s\n", strusage(15) );
592 if (may_coredump
&& !opt
.quiet
)
593 log_info (_("WARNING: program may create a core file!\n"));
597 log_set_file (logfile
);
598 log_set_prefix (NULL
, 1|2|4);
601 if (gnupg_faked_time_p ())
603 gnupg_isotime_t tbuf
;
605 log_info (_("WARNING: running with faked system time: "));
606 gnupg_get_isotime (tbuf
);
611 /* Print any pending secure memory warnings. */
612 gcry_control (GCRYCTL_RESUME_SECMEM_WARN
);
614 /* Setup the debug flags for all subsystems. */
617 /* Install a regular exit handler to make real sure that the secure
618 memory gets wiped out. */
619 if (atexit (emergency_cleanup
))
621 log_error ("atexit failed\n");
625 /* Terminate if we found any error until now. */
626 if (log_get_errorcount(0))
629 /* Set the standard GnuPG random seed file. */
632 char *p
= make_filename (opt
.homedir
, "random_seed", NULL
);
633 gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE
, p
);
637 /* Store given filename into FNAME. */
638 fname
= argc
? *argv
: NULL
;
640 /* Parse all given encryption keys. This does a lookup of the keys
641 and stops if any of the given keys was not found. */
647 for (sl
= recipients
; sl
; sl
= sl
->next
)
648 if (add_encryption_key (&ctrl
, sl
->d
, NULL
/* FIXME*/, 0))
654 /* Dispatch command. */
658 { /* List options and default values in the GPG Conf format. */
659 char *config_filename_esc
= percent_escape (opt
.config_filename
, NULL
);
661 printf ("gpgconf-g13.conf:%lu:\"%s\n",
662 GC_OPT_FLAG_DEFAULT
, config_filename_esc
);
663 xfree (config_filename_esc
);
665 printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE
);
666 printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE
);
667 printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT
);
668 printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE
);
672 /* This is merely a dummy command to test whether the
673 configuration file is valid. */
676 case aCreate
: /* Create a new container. */
679 wrong_args ("--create filename");
680 err
= create_new_container (&ctrl
, argv
[0]);
682 log_error ("error creating a new container: %s <%s>\n",
683 gpg_strerror (err
), gpg_strsource (err
));
688 log_error (_("invalid command (there is no implicit command)\n"));
692 /* Print the audit result if needed. */
693 if (auditlog
&& auditfp
)
695 /* audit_print_result (ctrl.audit, auditfp, 0); */
696 /* audit_release (ctrl.audit); */
703 return 8; /*NOTREACHED*/
706 /* Note: This function is used by signal handlers!. */
708 emergency_cleanup (void)
710 gcry_control (GCRYCTL_TERM_SECMEM
);
717 gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE
);
718 if (opt
.debug
& DBG_MEMSTAT_VALUE
)
720 gcry_control( GCRYCTL_DUMP_MEMORY_STATS
);
721 gcry_control( GCRYCTL_DUMP_RANDOM_STATS
);
724 gcry_control (GCRYCTL_DUMP_SECMEM_STATS
);
725 emergency_cleanup ();
726 rc
= rc
? rc
: log_get_errorcount(0)? 2 : g13_errors_seen
? 1 : 0;
732 g13_init_default_ctrl (struct server_control_s
*ctrl
)
734 ctrl
->conttype
= CONTTYPE_ENCFS
;