* gpgsm.c (main): Renamed the default key database to "keyring.kbx".
[gnupg.git] / sm / gpgsm.c
1 /* gpgsm.c - GnuPG for S/MIME 
2  *      Copyright (C) 2001 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 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include <gcrypt.h>
31 #include "gpgsm.h"
32 #include "../assuan/assuan.h" /* malloc hooks */
33 #include "../kbx/keybox.h" /* malloc hooks */
34 #include "i18n.h"
35 #include "keydb.h"
36
37 enum cmd_and_opt_values {
38   aNull = 0,
39   oArmor          = 'a',
40   aDetachedSign = 'b',
41   aSym    = 'c',
42   aDecrypt        = 'd',
43   aEncr   = 'e',
44   oInteractive  = 'i',
45   oKOption        = 'k',
46   oDryRun         = 'n',
47   oOutput         = 'o',
48   oQuiet          = 'q',
49   oRecipient      = 'r',
50   aSign   = 's',
51   oTextmodeShort= 't',
52   oUser   = 'u',
53   oVerbose        = 'v',
54   oCompress       = 'z',
55   oNotation       = 'N',
56   oBatch          = 500,
57   aClearsign,
58   aStore,
59   aKeygen,
60   aSignEncr,
61   aSignKey,
62   aLSignKey,
63   aListPackets,
64   aEditKey,
65   aDeleteKey,
66   aImport,
67   aVerify,
68   aVerifyFiles,
69   aListKeys,
70   aListSigs,
71   aListSecretKeys,
72   aSendKeys,
73   aRecvKeys,
74   aExport,
75   aExportAll,
76   aCheckKeys,
77   aServer,                        
78
79   oOptions,
80   oDebug,
81   oDebugAll,
82   oDebugWait,
83
84   oEnableSpecialFilenames,
85   oAgentProgram,
86
87
88
89
90
91   oAssumeArmor,
92   oAssumeBase64,
93   oAssumeBinary,
94
95   oBase64,
96   oNoArmor,
97
98
99
100   oTextmode,
101   oFingerprint,
102   oWithFingerprint,
103   oAnswerYes,
104   oAnswerNo,
105   oKeyring,
106   oSecretKeyring,
107   oDefaultKey,
108   oDefRecipient,
109   oDefRecipientSelf,
110   oNoDefRecipient,
111   oStatusFD,
112   oNoComment,
113   oNoVersion,
114   oEmitVersion,
115   oCompletesNeeded,
116   oMarginalsNeeded,
117   oMaxCertDepth,
118   oLoadExtension,
119   oRFC1991,
120   oOpenPGP,
121   oCipherAlgo,
122   oDigestAlgo,
123   oCompressAlgo,
124   oPasswdFD,
125   oCommandFD,
126   oNoVerbose,
127   oTrustDBName,
128   oNoSecmemWarn,
129   oNoDefKeyring,
130   oNoGreeting,
131   oNoTTY,
132   oNoOptions,
133   oNoBatch,
134   oHomedir,
135   oWithColons,
136   oWithKeyData,
137   oSkipVerify,
138   oCompressKeys,
139   oCompressSigs,
140   oAlwaysTrust,
141   oRunAsShmCP,
142   oSetFilename,
143   oSetPolicyURL,
144   oUseEmbeddedFilename,
145   oComment,
146   oDefaultComment,
147   oThrowKeyid,
148   oForceV3Sigs,
149   oForceMDC,
150   oS2KMode,
151   oS2KDigest,
152   oS2KCipher,
153   oCharset,
154   oNotDashEscaped,
155   oEscapeFrom,
156   oLockOnce,
157   oLockMultiple,
158   oLockNever,
159   oKeyServer,
160   oEncryptTo,
161   oNoEncryptTo,
162   oLoggerFD,
163   oUtf8Strings,
164   oNoUtf8Strings,
165   oDisableCipherAlgo,
166   oDisablePubkeyAlgo,
167   oAllowNonSelfsignedUID,
168   oAllowFreeformUID,
169   oNoLiteral,
170   oSetFilesize,
171   oHonorHttpProxy,
172   oFastListMode,
173   oListOnly,
174   oIgnoreTimeConflict,
175   oNoRandomSeedFile,
176   oNoAutoKeyRetrieve,
177   oUseAgent,
178   oMergeOnly,
179   oTryAllSecrets,
180   oTrustedKey,
181   oEmuMDEncodeBug,
182   aDummy
183  };
184
185
186 static ARGPARSE_OPTS opts[] = {
187
188     { 300, NULL, 0, N_("@Commands:\n ") },
189
190     { aSign, "sign",      256, N_("|[file]|make a signature")},
191     { aClearsign, "clearsign", 256, N_("|[file]|make a clear text signature") },
192     { aDetachedSign, "detach-sign", 256, N_("make a detached signature")},
193     { aEncr, "encrypt",   256, N_("encrypt data")},
194     { aSym, "symmetric", 256, N_("encryption only with symmetric cipher")},
195     { aDecrypt, "decrypt",   256, N_("decrypt data (default)")},
196     { aVerify, "verify"   , 256, N_("verify a signature")},
197     { aVerifyFiles, "verify-files" , 256, "@" },
198     { aListKeys, "list-keys", 256, N_("list keys")},
199     { aListKeys, "list-public-keys", 256, "@" },
200     { aDummy,    "list-sigs", 256, "@"}, 
201     { aDummy,    "check-sigs",256, "@"},
202     { oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
203     { aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
204     { aKeygen,     "gen-key",  256, N_("generate a new key pair")},
205     { aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
206     { aExport, "export"           , 256, N_("export keys") },
207     { aSendKeys, "send-keys"     , 256, N_("export keys to a key server") },
208     { aRecvKeys, "recv-keys"     , 256, N_("import keys from a key server") },
209     { aImport, "import",      256     , N_("import/merge keys")},
210     { aServer, "server",      256, N_("run in server mode")},
211     
212
213     { 301, NULL, 0, N_("@\nOptions:\n ") },
214
215     { oArmor, "armor",     0, N_("create ascii armored output")},
216     { oArmor, "armour",    0, "@" },
217     { oBase64, "base64",    0, N_("create base-64 encoded output")},
218     
219     { oAssumeArmor,  "assume-armor", 0, N_("assume input is in PEM format")},
220     { oAssumeBase64, "assume-base64", 0,
221                                       N_("assume input is in base-64 format")},
222     { oAssumeBase64, "assume-binary", 0,
223                                       N_("assume input is in binary format")},
224
225     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
226
227 #if 0
228     { oDefRecipient, "default-recipient" ,2,
229                                   N_("|NAME|use NAME as default recipient")},
230     { oDefRecipientSelf, "default-recipient-self" ,0,
231                                 N_("use the default key as default recipient")},
232     { oNoDefRecipient, "no-default-recipient", 0, "@" },
233     { oEncryptTo, "encrypt-to", 2, "@" },
234     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
235
236 #endif
237     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
238
239 #if 0
240     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
241     { oTextmodeShort, NULL,   0, "@"},
242     { oTextmode, "textmode",  0, N_("use canonical text mode")},
243 #endif
244
245     { oOutput, "output",    2, N_("use as output file")},
246     { oVerbose, "verbose",   0, N_("verbose") },
247     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
248     { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
249 #if 0
250     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
251     { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
252 #endif
253     { oDryRun, "dry-run",   0, N_("do not make any changes") },
254   /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */
255     /*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/
256     { oBatch, "batch",     0, N_("batch mode: never ask")},
257     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
258     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
259
260     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
261     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
262     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
263     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
264     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
265     { oOptions, "options"   , 2, N_("read options from file")},
266
267     { oDebug, "debug"     ,4|16, "@"},
268     { oDebugAll, "debug-all" ,0, "@"},
269     { oDebugWait, "debug-wait" ,1, "@"},
270     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
271     { aDummy, "no-comment", 0,   "@"},
272     { aDummy, "completes-needed", 1, "@"},
273     { aDummy, "marginals-needed", 1, "@"},
274     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
275     { aDummy, "trusted-key", 2, "@"},
276     { oLoadExtension, "load-extension" ,2,
277       N_("|FILE|load extension module FILE")},
278     { aDummy, "rfc1991",   0, "@"},
279     { aDummy, "openpgp",   0, "@"},
280     { aDummy, "s2k-mode",  1, "@"},
281     { aDummy, "s2k-digest-algo",2, "@"},
282     { aDummy, "s2k-cipher-algo",2, "@"},
283     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
284     { oDigestAlgo, "digest-algo", 2 ,
285       N_("|NAME|use message digest algorithm NAME")},
286 #if 0
287     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
288 #endif
289     { aDummy, "throw-keyid", 0, "@"},
290     { aDummy, "notation-data", 2, "@"},
291
292     { 302, NULL, 0, N_(
293   "@\n(See the man page for a complete listing of all commands and options)\n"
294                       )},
295
296     { 303, NULL, 0, N_("@\nExamples:\n\n"
297     " -se -r Bob [file]          sign and encrypt for user Bob\n"
298     " --clearsign [file]         make a clear text signature\n"
299     " --detach-sign [file]       make a detached signature\n"
300     " --list-keys [names]        show keys\n"
301     " --fingerprint [names]      show fingerprints\n"  ) },
302
303   /* hidden options */
304     { oNoVerbose, "no-verbose", 0, "@"},
305
306     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
307
308
309     { oTrustDBName, "trustdb-name", 2, "@" },
310     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, 
311     { oNoArmor, "no-armor",   0, "@"},
312     { oNoArmor, "no-armour",   0, "@"},
313     { oNoDefKeyring, "no-default-keyring", 0, "@" },
314     { oNoGreeting, "no-greeting", 0, "@" },
315     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
316     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
317     { oAgentProgram, "agent-program", 2 , "@" },
318
319     { oNoBatch, "no-batch", 0, "@" },
320     { oWithColons, "with-colons", 0, "@"},
321     { oWithKeyData,"with-key-data", 0, "@"},
322     { aListKeys, "list-key", 0, "@" }, /* alias */
323     { aListSigs, "list-sig", 0, "@" }, /* alias */
324     { aCheckKeys, "check-sig",0, "@" }, /* alias */
325     { oSkipVerify, "skip-verify",0, "@" },
326     { oCompressKeys, "compress-keys",0, "@"},
327     { oCompressSigs, "compress-sigs",0, "@"},
328     { oAlwaysTrust, "always-trust", 0, "@"},
329     { oNoVersion, "no-version", 0, "@"},
330     { oLockOnce, "lock-once", 0, "@" },
331     { oLockMultiple, "lock-multiple", 0, "@" },
332     { oLockNever, "lock-never", 0, "@" },
333     { oLoggerFD, "logger-fd",1, "@" },
334     { oWithFingerprint, "with-fingerprint", 0, "@" },
335     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
336     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
337     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
338     { oListOnly, "list-only", 0, "@"},
339     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
340     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
341 {0} };
342
343
344
345 int gpgsm_errors_seen = 0;
346
347 /* It is possible that we are currentlu running under setuid permissions */
348 static int maybe_setuid = 1;
349
350 /* Option --enable-special-filenames */
351 static int allow_special_filenames;
352
353
354 static char *build_list (const char *text,
355                          const char *(*mapf)(int), int (*chkf)(int));
356 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
357                      enum cmd_and_opt_values new_cmd );
358
359 static int check_special_filename (const char *fname);
360 static int open_read (const char *filename);
361
362
363 static int
364 our_pk_test_algo (int algo)
365 {
366   return 1;
367 }
368
369 static int
370 our_cipher_test_algo (int algo)
371 {
372   return 1;
373 }
374
375 static int
376 our_md_test_algo (int algo)
377 {
378   return 1;
379 }
380
381 static const char *
382 my_strusage( int level )
383 {
384   static char *digests, *pubkeys, *ciphers;
385   const char *p;
386
387   switch (level)
388     {
389     case 11: p = "gpgsm (GnuPG)";
390       break;
391     case 13: p = VERSION; break;
392     case 17: p = PRINTABLE_OS_NAME; break;
393     case 19: p = _("Please report bugs to <bug-gnupg@gnu.org>.\n");
394       break;
395     case 1:
396     case 40: p = _("Usage: gpgsm [options] [files] (-h for help)");
397       break;
398     case 41:
399       p = _("Syntax: gpgsm [options] [files]\n"
400             "sign, check, encrypt or decrypt using the S/MIME protocol\n"
401             "default operation depends on the input data\n");
402       break;
403
404     case 31: p = "\nHome: "; break;
405     case 32: p = opt.homedir; break;
406     case 33: p = _("\nSupported algorithms:\n"); break;
407     case 34:
408       if (!ciphers)
409         ciphers = build_list ("Cipher: ", gcry_cipher_algo_name,
410                               our_cipher_test_algo );
411       p = ciphers;
412       break;
413     case 35:
414       if (!pubkeys)
415         pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name,
416                               our_pk_test_algo );
417       p = pubkeys;
418       break;
419     case 36:
420       if (!digests)
421         digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo );
422       p = digests;
423       break;
424       
425     default: p = NULL; break;
426     }
427   return p;
428 }
429
430
431 static char *
432 build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int))
433 {
434   int i;
435   size_t n=strlen(text)+2;
436   char *list, *p;
437   
438   if (maybe_setuid) {
439     gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */
440   }
441
442   for (i=1; i < 110; i++ )
443     if (!chkf(i))
444       n += strlen(mapf(i)) + 2;
445   list = xmalloc (21 + n);
446   *list = 0;
447   for (p=NULL, i=1; i < 110; i++)
448     {
449       if (!chkf(i))
450         {
451           if( !p )
452             p = stpcpy (list, text );
453           else
454             p = stpcpy (p, ", ");
455           p = stpcpy (p, mapf(i) );
456         }
457     }
458   if (p)
459     p = stpcpy(p, "\n" );
460   return list;
461 }
462
463
464 static void
465 i18n_init(void)
466 {
467 #ifdef USE_SIMPLE_GETTEXT
468   set_gettext_file (PACKAGE);
469 #else
470 # ifdef ENABLE_NLS
471 #  ifdef HAVE_LC_MESSAGES
472   setlocale (LC_TIME, "");
473   setlocale (LC_MESSAGES, "");
474 #  else
475   setlocale (LC_ALL, "" );
476 #  endif
477   bindtextdomain (PACKAGE, GNUPG_LOCALEDIR);
478   textdomain (PACKAGE);
479 # endif
480 #endif
481 }
482
483
484 static void
485 wrong_args (const char *text)
486 {
487   fputs (_("usage: gpgsm [options] "), stderr);
488   fputs (text, stderr);
489   putc ('\n', stderr);
490   gpgsm_exit (2);
491 }
492
493
494 static void
495 set_debug(void)
496 {
497   if (opt.debug & DBG_MPI_VALUE)
498     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
499   if (opt.debug & DBG_CRYPTO_VALUE )
500     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
501 }
502
503
504 static void
505 set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
506 {
507   enum cmd_and_opt_values cmd = *ret_cmd;
508
509   if (!cmd || cmd == new_cmd)
510     cmd = new_cmd;
511   else if ( cmd == aSign && new_cmd == aEncr )
512     cmd = aSignEncr;
513   else if ( cmd == aEncr && new_cmd == aSign )
514     cmd = aSignEncr;
515   else if ( (cmd == aSign && new_cmd == aClearsign)
516             || (cmd == aClearsign && new_cmd == aSign) )
517     cmd = aClearsign;
518   else 
519     {
520       log_error(_("conflicting commands\n"));
521       gpgsm_exit(2);
522     }
523
524   *ret_cmd = cmd;
525 }
526
527
528 int
529 main ( int argc, char **argv)
530 {
531   ARGPARSE_ARGS pargs;
532   int orig_argc;
533   char **orig_argv;
534   const char *fname;
535   /*  char *username;*/
536   int may_coredump;
537   STRLIST sl, remusr= NULL, locusr=NULL;
538   STRLIST nrings=NULL;
539   int detached_sig = 0;
540   FILE *configfp = NULL;
541   char *configname = NULL;
542   unsigned configlineno;
543   int parse_debug = 0;
544   int default_config =1;
545   int default_keyring = 1;
546   int greeting = 0;
547   int nogreeting = 0;
548   int debug_wait = 0;
549   int use_random_seed = 1;
550   int with_fpr = 0;
551   char *def_digest_string = NULL;
552   enum cmd_and_opt_values cmd = 0;
553   struct server_control_s ctrl;
554   CERTLIST recplist = NULL;
555
556   /* FIXME: trap_unaligned ();*/
557   set_strusage (my_strusage);
558   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
559   /* Please note that we may running SUID(ROOT), so be very CAREFUL
560      when adding any stuff between here and the call to secmem_init()
561      somewhere after the option parsing */
562   log_set_prefix ("gpgsm", 1);
563   /* check that the libraries are suitable.  Do it here because the
564      option parse may need services of the library */
565   if (!gcry_check_version ( "1.1.4" ) )
566     {
567       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
568                  VERSION, gcry_check_version (NULL) );
569     }
570
571   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
572
573   may_coredump = 0/* FIXME: disable_core_dumps()*/;
574   
575   /* FIXME: init_signals();*/
576   
577   create_dotlock (NULL); /* register locking cleanup */
578   i18n_init();
579
580   opt.def_cipher_algoid = "1.2.840.113549.3.7";  /*des-EDE3-CBC*/
581 #ifdef __MINGW32__
582   opt.homedir = read_w32_registry_string ( NULL,
583                                            "Software\\GNU\\GnuPG", "HomeDir" );
584 #else
585   opt.homedir = getenv ("GNUPGHOME");
586 #endif
587   if (!opt.homedir || !*opt.homedir ) 
588     {
589       opt.homedir = "~/.gnupg-test" /*fixme: GNUPG_HOMEDIR*/;
590     }
591
592   /* first check whether we have a config file on the commandline */
593   orig_argc = argc;
594   orig_argv = argv;
595   pargs.argc = &argc;
596   pargs.argv = &argv;
597   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
598   while (arg_parse( &pargs, opts))
599     {
600       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
601         parse_debug++;
602       else if (pargs.r_opt == oOptions)
603         { /* yes there is one, so we do not try the default one but
604              read the config file when it is encountered at the
605              commandline */
606           default_config = 0;
607         }
608       else if (pargs.r_opt == oNoOptions)
609         default_config = 0; /* --no-options */
610       else if (pargs.r_opt == oHomedir)
611         opt.homedir = pargs.r.ret_str;
612     }
613   
614   
615   /* initialize the secure memory. */
616   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
617   maybe_setuid = 0;
618
619   /* 
620      Now we are now working under our real uid 
621   */
622
623   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
624   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
625   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
626
627   /* Setup a default control structure */
628   memset (&ctrl, 0, sizeof ctrl);
629   ctrl.no_server = 1;
630   ctrl.status_fd = -1; /* not status output */
631   ctrl.autodetect_encoding = 1;
632
633   /* set the default option file */
634   if (default_config )
635     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
636   
637   argc        = orig_argc;
638   argv        = orig_argv;
639   pargs.argc  = &argc;
640   pargs.argv  = &argv;
641   pargs.flags =  1;  /* do not remove the args */
642
643  next_pass:
644   if (configname) {
645     configlineno = 0;
646     configfp = fopen (configname, "r");
647     if (!configfp)
648       {
649         if (default_config)
650           {
651             if (parse_debug)
652               log_info (_("NOTE: no default option file `%s'\n"), configname);
653           }
654         else 
655           {
656             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
657             gpgsm_exit(2);
658           }
659         xfree(configname);
660         configname = NULL;
661       }
662     if (parse_debug && configname)
663       log_info (_("reading options from `%s'\n"), configname);
664     default_config = 0;
665   }
666
667   while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
668     {
669       switch (pargs.r_opt)
670         {
671         case aServer: 
672           opt.batch = 1;
673           set_cmd (&cmd, aServer);
674           break;
675
676         case aCheckKeys: set_cmd (&cmd, aCheckKeys); break;
677         case aImport: set_cmd (&cmd, aImport); break;
678         case aSendKeys: set_cmd (&cmd, aSendKeys); break;
679         case aRecvKeys: set_cmd (&cmd, aRecvKeys); break;
680         case aExport: set_cmd (&cmd, aExport); break;
681         case aListKeys: set_cmd (&cmd, aListKeys); break;
682
683         case aDeleteKey:
684           set_cmd (&cmd, aDeleteKey);
685           greeting=1;
686           break;
687
688         case aDetachedSign:
689           detached_sig = 1;
690           set_cmd (&cmd, aSign ); 
691           break;
692           
693         case aSym: set_cmd (&cmd, aSym); break;
694         case aDecrypt: set_cmd (&cmd, aDecrypt); break;
695         case aEncr: set_cmd (&cmd, aEncr); break;
696         case aSign: set_cmd (&cmd, aSign );  break;
697         case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break;
698         case aClearsign: set_cmd (&cmd, aClearsign); break;
699         case aVerify: set_cmd (&cmd, aVerify); break;
700
701           /* output encoding selection */
702         case oArmor:
703           ctrl.create_pem = 1;
704           break;
705         case oBase64: 
706           ctrl.create_pem = 0;
707           ctrl.create_base64 = 1;
708           break;
709         case oNoArmor: 
710           ctrl.create_pem = 0;
711           ctrl.create_base64 = 0;
712           break;
713           
714           /* Input encoding selection */
715         case oAssumeArmor:
716           ctrl.autodetect_encoding = 0;
717           ctrl.is_pem = 1;
718           ctrl.is_base64 = 0;
719           break;
720         case oAssumeBase64:
721           ctrl.autodetect_encoding = 0;
722           ctrl.is_pem = 0;
723           ctrl.is_base64 = 1;
724           break;
725         case oAssumeBinary:
726           ctrl.autodetect_encoding = 0;
727           ctrl.is_pem = 0;
728           ctrl.is_base64 = 0;
729           break;
730           
731
732         case oOutput: opt.outfile = pargs.r.ret_str; break;
733
734         
735         case oQuiet: opt.quiet = 1; break;
736         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
737         case oDryRun: opt.dry_run = 1; break;
738
739         case oVerbose:
740           opt.verbose++;
741           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
742           break;
743         case oNoVerbose:
744           opt.verbose = 0;
745           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
746           break;
747           
748         case oBatch: 
749           opt.batch = 1;
750           greeting = 0;
751           break;
752         case oNoBatch: opt.batch = 0; break;
753           
754         case oAnswerYes: opt.answer_yes = 1; break;
755         case oAnswerNo: opt.answer_no = 1; break;
756
757         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
758
759         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
760         case oDebugAll: opt.debug = ~0; break;
761         case oDebugWait: debug_wait = pargs.r.ret_int; break;
762
763         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
764         case oLoggerFD: /* fixme: log_set_logfile (NULL, pargs.r.ret_int );*/ break;
765         case oWithFingerprint:
766           with_fpr=1; /*fall thru*/
767         case oFingerprint:
768           opt.fingerprint++;
769           break;
770
771         case oOptions:
772           /* config files may not be nested (silently ignore them) */
773           if (!configfp)
774             {
775               xfree(configname);
776               configname = xstrdup (pargs.r.ret_str);
777               goto next_pass;
778             }
779           break;
780         case oNoOptions: break; /* no-options */
781         case oHomedir: opt.homedir = pargs.r.ret_str; break;
782         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
783           
784         case oNoDefKeyring: default_keyring = 0; break;
785         case oNoGreeting: nogreeting = 1; break;
786
787         case oDefaultKey:
788           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
789           break;
790         case oDefRecipient:
791           if (*pargs.r.ret_str)
792             opt.def_recipient = xstrdup (pargs.r.ret_str);
793           break;
794         case oDefRecipientSelf:
795           xfree (opt.def_recipient);
796           opt.def_recipient = NULL;
797           opt.def_recipient_self = 1;
798           break;
799         case oNoDefRecipient:
800           xfree (opt.def_recipient);
801           opt.def_recipient = NULL;
802           opt.def_recipient_self = 0;
803           break;
804
805         case oWithKeyData: opt.with_key_data=1; /* fall thru */
806         case oWithColons: ctrl.with_colons = 1; break;
807
808         case oSkipVerify: opt.skip_verify=1; break;
809
810         case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
811         case oEncryptTo: /* store the recipient in the second list */
812           sl = add_to_strlist (&remusr, pargs.r.ret_str);
813           sl->flags = 1;
814           break;
815
816         case oRecipient: /* store the recipient */
817           add_to_strlist ( &remusr, pargs.r.ret_str);
818           break;
819
820         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
821         case oTextmode: /*fixme:opt.textmode=1;*/  break;
822
823         case oUser: /* store the local users */
824           add_to_strlist ( &locusr, pargs.r.ret_str);
825           break;
826
827         case oNoSecmemWarn:
828           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
829           break;
830
831         case oCipherAlgo:
832           opt.def_cipher_algoid = pargs.r.ret_str;
833           break;
834
835         case oDisableCipherAlgo: 
836           {
837             int algo = gcry_cipher_map_name (pargs.r.ret_str);
838             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
839           }
840           break;
841         case oDisablePubkeyAlgo: 
842           {
843             int algo = gcry_pk_map_name (pargs.r.ret_str);
844             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
845           }
846           break;
847
848         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
849         case oNoRandomSeedFile: use_random_seed = 0; break;
850
851         case oEnableSpecialFilenames: allow_special_filenames =1; break;
852           
853
854         case aDummy:
855           break;
856         default: 
857           pargs.err = configfp? 1:2; 
858           break;
859         }
860     }
861
862   if (configfp)
863     {
864       fclose (configfp);
865       configfp = NULL;
866       xfree (configname);
867       configname = NULL;
868       goto next_pass;
869     }
870   
871   xfree (configname);
872   configname = NULL;
873
874   if (log_get_errorcount(0))
875     gpgsm_exit(2);
876   
877   if (nogreeting)
878     greeting = 0;
879   
880   if (greeting)
881     {
882       fprintf(stderr, "%s %s; %s\n",
883               strusage(11), strusage(13), strusage(14) );
884       fprintf(stderr, "%s\n", strusage(15) );
885     }
886 #  ifdef IS_DEVELOPMENT_VERSION
887   if (!opt.batch)
888     {
889       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
890       log_info ("It is only intended for test purposes and should NOT be\n");
891       log_info ("used in a production environment or with production keys!\n");
892     }
893 #  endif
894
895   if (may_coredump && !opt.quiet)
896     log_info (_("WARNING: program may create a core file!\n"));
897   
898 /*FIXME    if (opt.batch) */
899 /*      tty_batchmode (1); */
900
901   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
902
903   set_debug ();
904
905   /* FIXME: should set filenames of libgcrypt explicitly
906    * gpg_opt_homedir = opt.homedir; */
907
908   /* must do this after dropping setuid, because the mapping functions
909      may try to load an module and we may have disabled an algorithm */
910   if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
911        || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
912     log_error (_("selected cipher algorithm is invalid\n"));
913
914   if (def_digest_string)
915     {
916       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
917       xfree (def_digest_string);
918       def_digest_string = NULL;
919       if (our_md_test_algo(opt.def_digest_algo) )
920         log_error (_("selected digest algorithm is invalid\n"));
921     }
922
923   if (log_get_errorcount(0))
924     gpgsm_exit(2);
925   
926   /* set the random seed file */
927   if (use_random_seed) {
928     char *p = make_filename (opt.homedir, "random_seed", NULL);
929 #if 0
930 #warning set_random_seed_file not yet available in Libgcrypt
931     set_random_seed_file(p);
932 #endif
933     xfree(p);
934   }
935
936
937   if (!cmd && opt.fingerprint && !with_fpr)
938     set_cmd (&cmd, aListKeys);
939   
940   if (!nrings && default_keyring)  /* add default keybox */
941     keydb_add_resource ("pubring.kbx", 0, 0);
942   for (sl = nrings; sl; sl = sl->next)
943     keydb_add_resource (sl->d, 0, 0);
944   FREE_STRLIST(nrings);
945
946   for (sl = remusr; sl; sl = sl->next)
947     {
948       int rc = gpgsm_add_to_certlist (sl->d, &recplist);
949       if (rc)
950         log_error (_("can't encrypt to `%s': %s\n"),
951                    sl->d, gnupg_strerror (rc));
952     }
953   if (log_get_errorcount(0))
954     gpgsm_exit(1); /* must stop for invalid recipients */
955   
956
957   
958   fname = argc? *argv : NULL;
959   
960   switch (cmd)
961     {
962     case aServer:
963       if (debug_wait)
964         {
965           log_debug ("waiting for debugger - my pid is %u .....\n",
966                      (unsigned int)getpid());
967           sleep (debug_wait);
968           log_debug ("... okay\n");
969          }
970       gpgsm_server ();
971       break;
972
973     case aEncr: /* encrypt the given file */
974       if (!argc)
975         gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
976       else if (argc == 1)
977         gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
978       else
979         wrong_args (_("--encrypt [datafile]"));
980       break;
981
982     case aSign: /* sign the given file */
983       /* FIXME: we can only do detached sigs for now and we don't
984          handle --output yet. We should also allow to concatenate
985          multiple files for signins because that is what gpg does.*/
986       if (!argc)
987         gpgsm_sign (&ctrl, 0, 1, stdout); /* create from stdin */
988       else if (argc == 1)
989         gpgsm_sign (&ctrl, open_read (*argv), 1, stdout); /* from file */
990       else
991         wrong_args (_("--sign [datafile]"));
992       break;
993 #if 0
994       sl = NULL;
995       if (detached_sig)
996         { /* sign all files */
997           for (; argc; argc--, argv++ )
998             add_to_strlist ( &sl, *argv );
999         }
1000       else
1001         {
1002           if (argc > 1 )
1003             wrong_args (_("--sign [filename]"));
1004           if (argc)
1005             {
1006               sl = xcalloc (1, sizeof *sl + strlen(fname));
1007               strcpy(sl->d, fname);
1008             }
1009         }
1010       if ( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
1011         log_error ("signing failed: %s\n", gpg_errstr(rc) );
1012       free_strlist(sl);
1013 #endif
1014       break;
1015         
1016     case aSignEncr: /* sign and encrypt the given file */
1017 #if 0
1018       if (argc > 1)
1019         wrong_args(_("--sign --encrypt [filename]"));
1020       if (argc)
1021         {
1022           sl = xcalloc( 1, sizeof *sl + strlen(fname));
1023           strcpy(sl->d, fname);
1024         }
1025       else
1026         sl = NULL;
1027
1028       if ( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
1029         log_error ("%s: sign+encrypt failed: %s\n",
1030                    print_fname_stdin(fname), gpg_errstr(rc) );
1031       free_strlist(sl);
1032 #endif
1033       break;
1034
1035     case aClearsign: /* make a clearsig */
1036 #if 0
1037       if (argc > 1)
1038         wrong_args (_("--clearsign [filename]"));
1039       if ( (rc = clearsign_file(fname, locusr, NULL)) )
1040         log_error ("%s: clearsign failed: %s\n",
1041                    print_fname_stdin(fname), gpg_errstr(rc) );
1042 #endif
1043       break;
1044
1045     case aVerify:
1046       if (!argc)
1047         gpgsm_verify (&ctrl, 0, -1); /* normal signature from stdin */
1048       else if (argc == 1)
1049         gpgsm_verify (&ctrl, open_read (*argv), -1); /* normal signature */
1050       else if (argc == 2) /* detached signature (sig, detached) */
1051         gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1])); 
1052       else
1053         wrong_args (_("--verify [signature [detached_data]]"));
1054       break;
1055
1056     case aVerifyFiles:
1057 /*        if ((rc = verify_files( argc, argv ))) */
1058 /*          log_error ("verify files failed: %s\n", gpg_errstr(rc) ); */
1059       break;
1060
1061     case aDecrypt:
1062       if (!argc)
1063         gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
1064       else if (argc == 1)
1065         gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
1066       else
1067         wrong_args (_("--decrypt [filename]"));
1068       break;
1069
1070     case aDeleteKey:
1071       if (argc != 1)
1072         wrong_args(_("--delete-key user-id"));
1073 /*        username = make_username (fname); */
1074 /*        if( (rc = delete_key(username)) ) */
1075 /*          log_error ("%s: delete key failed: %s\n", username, gpg_errstr(rc) ); */
1076 /*        xfree(username); */
1077       break;
1078
1079     case aListKeys:
1080       for (sl=NULL; argc; argc--, argv++)
1081         add_to_strlist (&sl, *argv);
1082       gpgsm_list_keys (&ctrl, sl, stdout);
1083       free_strlist(sl);
1084       break;
1085
1086     case aListSecretKeys:
1087       sl = NULL;
1088       for( ; argc; argc--, argv++ )
1089         add_to_strlist (&sl, *argv);
1090 /*        secret_key_list ( sl ); */
1091       free_strlist(sl);
1092       break;
1093
1094     case aKeygen: /* generate a key */
1095 /*        if (opt.batch) */
1096 /*          { */
1097 /*            if (argc > 1) */
1098 /*              wrong_args("--gen-key [parameterfile]"); */
1099 /*            generate_keypair (argc? *argv : NULL); */
1100 /*      } */
1101 /*        else */
1102 /*          { */
1103 /*            if (argc) */
1104 /*              wrong_args ("--gen-key"); */
1105 /*            generate_keypair(NULL); */
1106 /*      } */
1107       break;
1108
1109     case aImport:
1110       if (!argc)
1111         gpgsm_import (&ctrl, 0);
1112       else
1113         {
1114           for (; argc; argc--, argv++)
1115             gpgsm_import (&ctrl, open_read (*argv));
1116         }
1117       break;
1118       
1119     case aExport:
1120     case aSendKeys:
1121     case aRecvKeys:
1122 /*        sl = NULL; */
1123 /*        for ( ; argc; argc--, argv++ ) */
1124 /*          add_to_strlist (&sl, *argv); */
1125 /*        if ( cmd == aSendKeys ) */
1126 /*          ldap_export (sl); */
1127 /*        else if (cmd == aRecvKeys ) */
1128 /*          ldap_import (sl); */
1129 /*        else */
1130 /*          export_pubkeys (sl, (cmd == aExport)); */
1131 /*        free_strlist (sl); */
1132       break;
1133
1134       default:
1135         if (argc > 1)
1136           wrong_args(_("[filename]"));
1137         /* Issue some output for the unix newbie */
1138         if ( !fname && !opt.outfile && isatty( fileno(stdin) )
1139             && isatty (fileno(stdout) ) && isatty (fileno(stderr) ) )
1140           log_info (_("Go ahead and type your message ...\n"));
1141         
1142 #if 0
1143         if ( !(a = iobuf_open(fname)) )
1144           log_error (_("can't open `%s'\n"), print_fname_stdin(fname));
1145         else
1146           {
1147             if (!opt.no_armor) 
1148               iobuf_close(a);
1149         }
1150 #endif
1151         break;
1152     }
1153   
1154   /* cleanup */
1155   gpgsm_release_certlist (recplist);
1156   FREE_STRLIST(remusr);
1157   FREE_STRLIST(locusr);
1158   gpgsm_exit(0);
1159   return 8; /*NEVER REACHED*/
1160 }
1161
1162
1163 void
1164 gpgsm_exit (int rc)
1165 {
1166   #if 0
1167 #warning no update_random_seed_file
1168   update_random_seed_file();
1169   #endif
1170 #if 0
1171   /* at this time a bit annoying */
1172   if (opt.debug & DBG_MEMSTAT_VALUE)
1173     {
1174       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1175       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1176     }
1177   if (opt.debug)
1178     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1179 #endif
1180   gcry_control (GCRYCTL_TERM_SECMEM );
1181   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1182   exit (rc);
1183 }
1184
1185
1186 /* Check whether the filename has the form "-&nnnn", where n is a
1187    non-zero number.  Returns this number or -1 if it is not the case.  */
1188 static int
1189 check_special_filename (const char *fname)
1190 {
1191   if (allow_special_filenames
1192       && fname && *fname == '-' && fname[1] == '&' ) {
1193     int i;
1194     
1195     fname += 2;
1196     for (i=0; isdigit (fname[i]); i++ )
1197       ;
1198     if ( !fname[i] ) 
1199       return atoi (fname);
1200   }
1201   return -1;
1202 }
1203
1204
1205
1206 /* Open the FILENAME for read and return the fieldescriptor.  Stop
1207    with an error message in case of problems.  "-" denotes stdin and
1208    if special filenames are allowed the given fd is opend instead. */
1209 static int 
1210 open_read (const char *filename)
1211 {
1212   int fd;
1213
1214   if (filename[0] == '-' && !filename[1])
1215     return 0; /* stdin */
1216   fd = check_special_filename (filename);
1217   if (fd != -1)
1218     return fd;
1219   fd = open (filename, O_RDONLY);
1220   if (fd == -1)
1221     {
1222       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1223       gpgsm_exit (2);
1224     }
1225   return fd;
1226 }