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