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