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