* delete.c: New.
[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":
1072                          rc == GNUPG_Wrong_Key_Usage?     "3":
1073                          rc == GNUPG_Certificate_Revoked? "4":
1074                          rc == GNUPG_Certificate_Expired? "5":
1075                          rc == GNUPG_No_CRL_Known?        "6":
1076                          rc == GNUPG_CRL_Too_Old?         "7":
1077                          rc == GNUPG_No_Policy_Match?     "8":
1078                          "0",
1079                          sl->d, NULL);
1080         }
1081   }
1082   if (log_get_errorcount(0))
1083     gpgsm_exit(1); /* must stop for invalid recipients */
1084   
1085
1086   
1087   fname = argc? *argv : NULL;
1088   
1089   switch (cmd)
1090     {
1091     case aServer:
1092       if (debug_wait)
1093         {
1094           log_debug ("waiting for debugger - my pid is %u .....\n",
1095                      (unsigned int)getpid());
1096           sleep (debug_wait);
1097           log_debug ("... okay\n");
1098          }
1099       gpgsm_server ();
1100       break;
1101
1102     case aEncr: /* encrypt the given file */
1103       if (!argc)
1104         gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
1105       else if (argc == 1)
1106         gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
1107       else
1108         wrong_args (_("--encrypt [datafile]"));
1109       break;
1110
1111     case aSign: /* sign the given file */
1112       /* FIXME: W we don't handle --output yet. We should also allow
1113          to concatenate multiple files for signing because that is
1114          what gpg does.*/
1115       if (!argc)
1116         gpgsm_sign (&ctrl, 0, detached_sig, stdout); /* create from stdin */
1117       else if (argc == 1)
1118         gpgsm_sign (&ctrl, open_read (*argv),
1119                     detached_sig, stdout); /* from file */
1120       else
1121         wrong_args (_("--sign [datafile]"));
1122       break;
1123 #if 0
1124       sl = NULL;
1125       if (detached_sig)
1126         { /* sign all files */
1127           for (; argc; argc--, argv++ )
1128             add_to_strlist ( &sl, *argv );
1129         }
1130       else
1131         {
1132           if (argc > 1 )
1133             wrong_args (_("--sign [filename]"));
1134           if (argc)
1135             {
1136               sl = xcalloc (1, sizeof *sl + strlen(fname));
1137               strcpy(sl->d, fname);
1138             }
1139         }
1140       if ( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
1141         log_error ("signing failed: %s\n", gpg_errstr(rc) );
1142       free_strlist(sl);
1143 #endif
1144       break;
1145         
1146     case aSignEncr: /* sign and encrypt the given file */
1147       log_error ("this command has not yet been implemented\n");
1148 #if 0
1149       if (argc > 1)
1150         wrong_args(_("--sign --encrypt [filename]"));
1151       if (argc)
1152         {
1153           sl = xcalloc( 1, sizeof *sl + strlen(fname));
1154           strcpy(sl->d, fname);
1155         }
1156       else
1157         sl = NULL;
1158
1159       if ( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
1160         log_error ("%s: sign+encrypt failed: %s\n",
1161                    print_fname_stdin(fname), gpg_errstr(rc) );
1162       free_strlist(sl);
1163 #endif
1164       break;
1165
1166     case aClearsign: /* make a clearsig */
1167       log_error ("this command has not yet been implemented\n");
1168 #if 0
1169       if (argc > 1)
1170         wrong_args (_("--clearsign [filename]"));
1171       if ( (rc = clearsign_file(fname, locusr, NULL)) )
1172         log_error ("%s: clearsign failed: %s\n",
1173                    print_fname_stdin(fname), gpg_errstr(rc) );
1174 #endif
1175       break;
1176
1177     case aVerify:
1178       {
1179         FILE *fp = NULL;
1180
1181         if (argc == 2 && opt.outfile)
1182           log_info ("option --output ignored for a detached signature\n");
1183         else if (opt.outfile)
1184           fp = open_fwrite (opt.outfile);
1185
1186         if (!argc)
1187           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
1188         else if (argc == 1)
1189           gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */
1190         else if (argc == 2) /* detached signature (sig, detached) */
1191           gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); 
1192         else
1193           wrong_args (_("--verify [signature [detached_data]]"));
1194
1195         if (fp && fp != stdout)
1196           fclose (fp);
1197       }
1198       break;
1199
1200     case aVerifyFiles:
1201       log_error ("this command has not yet been implemented\n");
1202 /*        if ((rc = verify_files( argc, argv ))) */
1203 /*          log_error ("verify files failed: %s\n", gpg_errstr(rc) ); */
1204       break;
1205
1206     case aDecrypt:
1207       if (!argc)
1208         gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
1209       else if (argc == 1)
1210         gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
1211       else
1212         wrong_args (_("--decrypt [filename]"));
1213       break;
1214
1215     case aDeleteKey:
1216       for (sl=NULL; argc; argc--, argv++)
1217         add_to_strlist (&sl, *argv);
1218       gpgsm_delete (&ctrl, sl);
1219       free_strlist(sl);
1220       break;
1221
1222     case aListSigs:
1223       ctrl.with_chain = 1;
1224     case aListKeys:
1225       for (sl=NULL; argc; argc--, argv++)
1226         add_to_strlist (&sl, *argv);
1227       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
1228       free_strlist(sl);
1229       break;
1230
1231     case aListExternalKeys:
1232       for (sl=NULL; argc; argc--, argv++)
1233         add_to_strlist (&sl, *argv);
1234       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<7)));
1235       free_strlist(sl);
1236       break;
1237
1238     case aListSecretKeys:
1239       for (sl=NULL; argc; argc--, argv++)
1240         add_to_strlist (&sl, *argv);
1241       gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
1242       free_strlist(sl);
1243       break;
1244
1245     case aKeygen: /* generate a key */
1246       log_error ("this function is not yet available from the commandline\n");
1247 /*        if (opt.batch) */
1248 /*          { */
1249 /*            if (argc > 1) */
1250 /*              wrong_args("--gen-key [parameterfile]"); */
1251 /*            generate_keypair (argc? *argv : NULL); */
1252 /*      } */
1253 /*        else */
1254 /*          { */
1255 /*            if (argc) */
1256 /*              wrong_args ("--gen-key"); */
1257 /*            generate_keypair(NULL); */
1258 /*      } */
1259       break;
1260
1261     case aImport:
1262       if (!argc)
1263         gpgsm_import (&ctrl, 0);
1264       else
1265         {
1266           for (; argc; argc--, argv++)
1267             gpgsm_import (&ctrl, open_read (*argv));
1268         }
1269       break;
1270
1271     case aExport:
1272       for (sl=NULL; argc; argc--, argv++)
1273         add_to_strlist (&sl, *argv);
1274       gpgsm_export (&ctrl, sl, stdout);
1275       free_strlist(sl);
1276       break;
1277
1278       
1279     case aSendKeys:
1280     case aRecvKeys:
1281       log_error ("this command has not yet been implemented\n");
1282 /*        sl = NULL; */
1283 /*        for ( ; argc; argc--, argv++ ) */
1284 /*          add_to_strlist (&sl, *argv); */
1285 /*        if ( cmd == aSendKeys ) */
1286 /*          ldap_export (sl); */
1287 /*        else if (cmd == aRecvKeys ) */
1288 /*          ldap_import (sl); */
1289 /*        else */
1290 /*          export_pubkeys (sl, (cmd == aExport)); */
1291 /*        free_strlist (sl); */
1292       break;
1293
1294
1295     case aLearnCard:
1296       if (argc)
1297         wrong_args ("--learn-card");
1298       else
1299         {
1300           int rc = gpgsm_agent_learn ();
1301           if (rc)
1302             log_error ("error learning card: %s\n", gnupg_strerror (rc));
1303         }
1304       break;
1305
1306
1307     default:
1308         log_error ("invalid command\n");
1309 #if 0
1310         if (argc > 1)
1311           wrong_args(_("[filename]"));
1312         /* Issue some output for the unix newbie */
1313         if ( !fname && !opt.outfile && isatty( fileno(stdin) )
1314             && isatty (fileno(stdout) ) && isatty (fileno(stderr) ) )
1315           log_info (_("Go ahead and type your message ...\n"));
1316         
1317         if ( !(a = iobuf_open(fname)) )
1318           log_error (_("can't open `%s'\n"), print_fname_stdin(fname));
1319         else
1320           {
1321             if (!opt.no_armor) 
1322               iobuf_close(a);
1323         }
1324 #endif
1325         break;
1326     }
1327   
1328   /* cleanup */
1329   gpgsm_release_certlist (recplist);
1330   FREE_STRLIST(remusr);
1331   FREE_STRLIST(locusr);
1332   gpgsm_exit(0);
1333   return 8; /*NEVER REACHED*/
1334 }
1335
1336
1337 void
1338 gpgsm_exit (int rc)
1339 {
1340   #if 0
1341 #warning no update_random_seed_file
1342   update_random_seed_file();
1343   #endif
1344 #if 0
1345   /* at this time a bit annoying */
1346   if (opt.debug & DBG_MEMSTAT_VALUE)
1347     {
1348       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1349       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1350     }
1351   if (opt.debug)
1352     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1353 #endif
1354   gcry_control (GCRYCTL_TERM_SECMEM );
1355   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1356   exit (rc);
1357 }
1358
1359
1360 void
1361 gpgsm_init_default_ctrl (struct server_control_s *ctrl)
1362 {
1363   ctrl->include_certs = 1;  /* only include the signer's cert */
1364 }
1365
1366
1367
1368 /* Check whether the filename has the form "-&nnnn", where n is a
1369    non-zero number.  Returns this number or -1 if it is not the case.  */
1370 static int
1371 check_special_filename (const char *fname)
1372 {
1373   if (allow_special_filenames
1374       && fname && *fname == '-' && fname[1] == '&' ) {
1375     int i;
1376     
1377     fname += 2;
1378     for (i=0; isdigit (fname[i]); i++ )
1379       ;
1380     if ( !fname[i] ) 
1381       return atoi (fname);
1382   }
1383   return -1;
1384 }
1385
1386
1387
1388 /* Open the FILENAME for read and return the filedescriptor.  Stop
1389    with an error message in case of problems.  "-" denotes stdin and
1390    if special filenames are allowed the given fd is opened instead. */
1391 static int 
1392 open_read (const char *filename)
1393 {
1394   int fd;
1395
1396   if (filename[0] == '-' && !filename[1])
1397     return 0; /* stdin */
1398   fd = check_special_filename (filename);
1399   if (fd != -1)
1400     return fd;
1401   fd = open (filename, O_RDONLY);
1402   if (fd == -1)
1403     {
1404       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1405       gpgsm_exit (2);
1406     }
1407   return fd;
1408 }
1409
1410 /* Open FILENAME for fwrite and return the stream.  Stop with an error
1411    message in case of problems.  "-" denotes stdout and if special
1412    filenames are allowed the given fd is opened instead. Caller must
1413    close the returned stream unless it is stdout. */
1414 static FILE *
1415 open_fwrite (const char *filename)
1416 {
1417   int fd;
1418   FILE *fp;
1419
1420   if (filename[0] == '-' && !filename[1])
1421     return stdout;
1422
1423   fd = check_special_filename (filename);
1424   if (fd != -1)
1425     {
1426       fp = fdopen (dup (fd), "wb");
1427       if (!fp)
1428         {
1429           log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
1430           gpgsm_exit (2);
1431         }
1432       return fp;
1433     }
1434   fp = fopen (filename, "wb");
1435   if (!fp)
1436     {
1437       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1438       gpgsm_exit (2);
1439     }
1440   return fp;
1441 }