* gpgsm.c (main): Disable the internal libgcrypt locking.
[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, /* nyi */
78   aServer,                        
79   aLearnCard,
80
81   oOptions,
82   oDebug,
83   oDebugAll,
84   oDebugWait,
85   oDebugNoChainValidation,
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     { 301, NULL, 0, N_("@\nOptions:\n ") },
234
235     { oArmor, "armor",     0, N_("create ascii armored output")},
236     { oArmor, "armour",    0, "@" },
237     { oBase64, "base64",    0, N_("create base-64 encoded output")},
238     
239     { oAssumeArmor,  "assume-armor", 0, N_("assume input is in PEM format")},
240     { oAssumeBase64, "assume-base64", 0,
241                                       N_("assume input is in base-64 format")},
242     { oAssumeBinary, "assume-binary", 0,
243                                       N_("assume input is in binary format")},
244
245     { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")},
246
247
248     { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")},
249     { oEnableCRLChecks, "enable-crl-checks", 0, "@"},
250
251     { oIncludeCerts, "include-certs", 1,
252                                  N_("|N|number of certificates to include") },
253
254     { oPolicyFile, "policy-file", 2,
255                     N_("|FILE|take policy information from FILE") },
256
257     { oDisablePolicyChecks, "disable-policy-checks", 0,
258                            N_("do not check certificate policies")},
259     { oEnablePolicyChecks, "enable-policy-checks", 0, "@"},
260
261     { oAutoIssuerKeyRetrieve, "auto-issuer-key-retrieve", 0, 
262       N_("fetch missing issuer certificates")},
263
264 #if 0
265     { oDefRecipient, "default-recipient" ,2,
266                                   N_("|NAME|use NAME as default recipient")},
267     { oDefRecipientSelf, "default-recipient-self" ,0,
268                                 N_("use the default key as default recipient")},
269     { oNoDefRecipient, "no-default-recipient", 0, "@" },
270     { oEncryptTo, "encrypt-to", 2, "@" },
271     { oNoEncryptTo, "no-encrypt-to", 0, "@" },
272
273 #endif
274     { oUser, "local-user",2, N_("use this user-id to sign or decrypt")},
275
276 #if 0
277     { oCompress, NULL,        1, N_("|N|set compress level N (0 disables)") },
278     { oTextmodeShort, NULL,   0, "@"},
279     { oTextmode, "textmode",  0, N_("use canonical text mode")},
280 #endif
281
282     { oOutput, "output",    2, N_("use as output file")},
283     { oVerbose, "verbose",   0, N_("verbose") },
284     { oQuiet,   "quiet",   0, N_("be somewhat more quiet") },
285     { oNoTTY, "no-tty", 0, N_("don't use the terminal at all") },
286 #if 0
287     { oForceV3Sigs, "force-v3-sigs", 0, N_("force v3 signatures") },
288     { oForceMDC, "force-mdc", 0, N_("always use a MDC for encryption") },
289 #endif
290     { oDryRun, "dry-run",   0, N_("do not make any changes") },
291   /*{ oInteractive, "interactive", 0, N_("prompt before overwriting") }, */
292     /*{ oUseAgent, "use-agent",0, N_("use the gpg-agent")},*/
293     { oBatch, "batch",     0, N_("batch mode: never ask")},
294     { oAnswerYes, "yes",       0, N_("assume yes on most questions")},
295     { oAnswerNo,  "no",        0, N_("assume no on most questions")},
296
297     { oKeyring, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
298     { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")},
299     { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")},
300     { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")},
301     { oCharset, "charset"   , 2, N_("|NAME|set terminal charset to NAME") },
302     { oOptions, "options"   , 2, N_("read options from file")},
303
304     { oDebug, "debug"     ,4|16, "@"},
305     { oDebugAll, "debug-all" ,0, "@"},
306     { oDebugWait, "debug-wait" ,1, "@"},
307     { oDebugNoChainValidation, "debug-no-chain-validation" ,0, "@"},
308     { oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
309     { aDummy, "no-comment", 0,   "@"},
310     { aDummy, "completes-needed", 1, "@"},
311     { aDummy, "marginals-needed", 1, "@"},
312     { oMaxCertDepth,    "max-cert-depth", 1, "@" },
313     { aDummy, "trusted-key", 2, "@"},
314     { oLoadExtension, "load-extension" ,2,
315       N_("|FILE|load extension module FILE")},
316     { aDummy, "rfc1991",   0, "@"},
317     { aDummy, "openpgp",   0, "@"},
318     { aDummy, "s2k-mode",  1, "@"},
319     { aDummy, "s2k-digest-algo",2, "@"},
320     { aDummy, "s2k-cipher-algo",2, "@"},
321     { oCipherAlgo, "cipher-algo", 2 , N_("|NAME|use cipher algorithm NAME")},
322     { oDigestAlgo, "digest-algo", 2 ,
323       N_("|NAME|use message digest algorithm NAME")},
324 #if 0
325     { oCompressAlgo, "compress-algo", 1 , N_("|N|use compress algorithm N")},
326 #endif
327     { aDummy, "throw-keyid", 0, "@"},
328     { aDummy, "notation-data", 2, "@"},
329
330     { 302, NULL, 0, N_(
331   "@\n(See the man page for a complete listing of all commands and options)\n"
332                       )},
333
334     { 303, NULL, 0, N_("@\nExamples:\n\n"
335     " -se -r Bob [file]          sign and encrypt for user Bob\n"
336     " --clearsign [file]         make a clear text signature\n"
337     " --detach-sign [file]       make a detached signature\n"
338     " --list-keys [names]        show keys\n"
339     " --fingerprint [names]      show fingerprints\n"  ) },
340
341   /* hidden options */
342     { oNoVerbose, "no-verbose", 0, "@"},
343
344     { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" },
345
346
347     { oTrustDBName, "trustdb-name", 2, "@" },
348     { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, 
349     { oNoArmor, "no-armor",   0, "@"},
350     { oNoArmor, "no-armour",   0, "@"},
351     { oNoDefKeyring, "no-default-keyring", 0, "@" },
352     { oNoGreeting, "no-greeting", 0, "@" },
353     { oNoOptions, "no-options", 0, "@" }, /* shortcut for --options /dev/null */
354     { oHomedir, "homedir", 2, "@" },   /* defaults to "~/.gnupg" */
355     { oAgentProgram, "agent-program", 2 , "@" },
356     { oDisplay,    "display",     2, "@" },
357     { oTTYname,    "ttyname",     2, "@" },
358     { oTTYtype,    "ttytype",     2, "@" },
359     { oLCctype,    "lc-ctype",    2, "@" },
360     { oLCmessages, "lc-messages", 2, "@" },
361     { oDirmngrProgram, "dirmngr-program", 2 , "@" },
362     { oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */
363
364
365     { oNoBatch, "no-batch", 0, "@" },
366     { oWithColons, "with-colons", 0, "@"},
367     { oWithKeyData,"with-key-data", 0, "@"},
368     { aListKeys, "list-key", 0, "@" }, /* alias */
369     { aListSigs, "list-sig", 0, "@" }, /* alias */
370     { aListSigs, "check-sig",0, "@" }, /* alias */
371     { oSkipVerify, "skip-verify",0, "@" },
372     { oCompressKeys, "compress-keys",0, "@"},
373     { oCompressSigs, "compress-sigs",0, "@"},
374     { oAlwaysTrust, "always-trust", 0, "@"},
375     { oNoVersion, "no-version", 0, "@"},
376     { oLockOnce, "lock-once", 0, "@" },
377     { oLockMultiple, "lock-multiple", 0, "@" },
378     { oLockNever, "lock-never", 0, "@" },
379     { oLoggerFD, "logger-fd",1, "@" },
380     { oWithFingerprint, "with-fingerprint", 0, "@" },
381     { oDisableCipherAlgo,  "disable-cipher-algo", 2, "@" },
382     { oDisablePubkeyAlgo,  "disable-pubkey-algo", 2, "@" },
383     { oHonorHttpProxy,"honor-http-proxy", 0, "@" },
384     { oListOnly, "list-only", 0, "@"},
385     { oIgnoreTimeConflict, "ignore-time-conflict", 0, "@" },
386     { oNoRandomSeedFile,  "no-random-seed-file", 0, "@" },
387 {0} };
388
389
390
391 int gpgsm_errors_seen = 0;
392
393 /* It is possible that we are currentlu running under setuid permissions */
394 static int maybe_setuid = 1;
395
396 /* Option --enable-special-filenames */
397 static int allow_special_filenames;
398
399
400 static char *build_list (const char *text,
401                          const char *(*mapf)(int), int (*chkf)(int));
402 static void set_cmd (enum cmd_and_opt_values *ret_cmd,
403                      enum cmd_and_opt_values new_cmd );
404
405 static void emergency_cleanup (void);
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, 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   CERTLIST signerlist = NULL;
605
606   /* trap_unaligned ();*/
607   set_strusage (my_strusage);
608   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
609   /* We don't need any locking in libgcrypt unless we use any kind of
610      threading. */
611   gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING);
612
613   /* Please note that we may running SUID(ROOT), so be very CAREFUL
614      when adding any stuff between here and the call to secmem_init()
615      somewhere after the option parsing */
616   log_set_prefix ("gpgsm", 1);
617   /* check that the libraries are suitable.  Do it here because the
618      option parse may need services of the library */
619   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
620     {
621       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
622                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
623     }
624   if (!ksba_check_version (NEED_KSBA_VERSION) )
625     {
626       log_fatal( _("libksba is too old (need %s, have %s)\n"),
627                  NEED_KSBA_VERSION, ksba_check_version (NULL) );
628     }
629
630   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
631
632   may_coredump = disable_core_dumps ();
633   
634   gnupg_init_signals (0, emergency_cleanup);
635   
636   create_dotlock (NULL); /* register locking cleanup */
637   i18n_init();
638
639   opt.def_cipher_algoid = "1.2.840.113549.3.7";  /*des-EDE3-CBC*/
640 #ifdef __MINGW32__
641   opt.homedir = read_w32_registry_string ( NULL,
642                                            "Software\\GNU\\GnuPG", "HomeDir" );
643 #else
644   opt.homedir = getenv ("GNUPGHOME");
645 #endif
646   if (!opt.homedir || !*opt.homedir ) 
647     opt.homedir = GNUPG_DEFAULT_HOMEDIR;
648
649   /* first check whether we have a config file on the commandline */
650   orig_argc = argc;
651   orig_argv = argv;
652   pargs.argc = &argc;
653   pargs.argv = &argv;
654   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
655   while (arg_parse( &pargs, opts))
656     {
657       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
658         parse_debug++;
659       else if (pargs.r_opt == oOptions)
660         { /* yes there is one, so we do not try the default one but
661              read the config file when it is encountered at the
662              commandline */
663           default_config = 0;
664         }
665       else if (pargs.r_opt == oNoOptions)
666         default_config = 0; /* --no-options */
667       else if (pargs.r_opt == oHomedir)
668         opt.homedir = pargs.r.ret_str;
669     }
670   
671   
672   /* initialize the secure memory. */
673   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
674   maybe_setuid = 0;
675
676   /* 
677      Now we are now working under our real uid 
678   */
679
680   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
681   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
682   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
683
684   /* Setup a default control structure for command line mode */
685   memset (&ctrl, 0, sizeof ctrl);
686   gpgsm_init_default_ctrl (&ctrl);
687   ctrl.no_server = 1;
688   ctrl.status_fd = -1; /* not status output */
689   ctrl.autodetect_encoding = 1;
690
691   /* set the default option file */
692   if (default_config )
693     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
694   /* cet the default policy file */
695   opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
696   
697   argc        = orig_argc;
698   argv        = orig_argv;
699   pargs.argc  = &argc;
700   pargs.argv  = &argv;
701   pargs.flags =  1;  /* do not remove the args */
702
703  next_pass:
704   if (configname) {
705     configlineno = 0;
706     configfp = fopen (configname, "r");
707     if (!configfp)
708       {
709         if (default_config)
710           {
711             if (parse_debug)
712               log_info (_("NOTE: no default option file `%s'\n"), configname);
713           }
714         else 
715           {
716             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
717             gpgsm_exit(2);
718           }
719         xfree(configname);
720         configname = NULL;
721       }
722     if (parse_debug && configname)
723       log_info (_("reading options from `%s'\n"), configname);
724     default_config = 0;
725   }
726
727   while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
728     {
729       switch (pargs.r_opt)
730         {
731         case aServer: 
732           opt.batch = 1;
733           set_cmd (&cmd, aServer);
734           break;
735
736         case aCheckKeys: set_cmd (&cmd, aCheckKeys); break;
737         case aImport: set_cmd (&cmd, aImport); break;
738         case aSendKeys: set_cmd (&cmd, aSendKeys); break;
739         case aRecvKeys: set_cmd (&cmd, aRecvKeys); break;
740         case aExport: set_cmd (&cmd, aExport); break;
741         case aListKeys: set_cmd (&cmd, aListKeys); break;
742         case aListExternalKeys: set_cmd (&cmd, aListExternalKeys); break;
743         case aListSecretKeys: set_cmd (&cmd, aListSecretKeys); break;
744         case aListSigs: set_cmd (&cmd, aListSigs); break;
745
746         case aLearnCard: set_cmd (&cmd, aLearnCard); break;
747
748         case aDeleteKey:
749           set_cmd (&cmd, aDeleteKey);
750           /*greeting=1;*/
751           break;
752
753         case aDetachedSign:
754           detached_sig = 1;
755           set_cmd (&cmd, aSign ); 
756           break;
757           
758         case aSym: set_cmd (&cmd, aSym); break;
759         case aDecrypt: set_cmd (&cmd, aDecrypt); break;
760         case aEncr: set_cmd (&cmd, aEncr); break;
761         case aSign: set_cmd (&cmd, aSign );  break;
762         case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break;
763         case aClearsign: set_cmd (&cmd, aClearsign); break;
764         case aVerify: set_cmd (&cmd, aVerify); break;
765
766
767           /* output encoding selection */
768         case oArmor:
769           ctrl.create_pem = 1;
770           break;
771         case oBase64: 
772           ctrl.create_pem = 0;
773           ctrl.create_base64 = 1;
774           break;
775         case oNoArmor: 
776           ctrl.create_pem = 0;
777           ctrl.create_base64 = 0;
778           break;
779           
780           /* Input encoding selection */
781         case oAssumeArmor:
782           ctrl.autodetect_encoding = 0;
783           ctrl.is_pem = 1;
784           ctrl.is_base64 = 0;
785           break;
786         case oAssumeBase64:
787           ctrl.autodetect_encoding = 0;
788           ctrl.is_pem = 0;
789           ctrl.is_base64 = 1;
790           break;
791         case oAssumeBinary:
792           ctrl.autodetect_encoding = 0;
793           ctrl.is_pem = 0;
794           ctrl.is_base64 = 0;
795           break;
796
797         case oDisableCRLChecks:
798           opt.no_crl_check = 1;
799           break;
800         case oEnableCRLChecks:
801           opt.no_crl_check = 0;
802           break;
803
804         case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
805
806         case oPolicyFile:
807           xfree (opt.policy_file);
808           if (*pargs.r.ret_str)
809             opt.policy_file = xstrdup (pargs.r.ret_str);
810           else
811             opt.policy_file = NULL;
812           break;
813
814         case oDisablePolicyChecks:
815           opt.no_policy_check = 1;
816           break;
817         case oEnablePolicyChecks:
818           opt.no_policy_check = 0;
819           break;
820           
821         case oAutoIssuerKeyRetrieve:
822           opt.auto_issuer_key_retrieve = 1;
823           break;
824
825         case oOutput: opt.outfile = pargs.r.ret_str; break;
826
827         
828         case oQuiet: opt.quiet = 1; break;
829         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
830         case oDryRun: opt.dry_run = 1; break;
831
832         case oVerbose:
833           opt.verbose++;
834           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
835           break;
836         case oNoVerbose:
837           opt.verbose = 0;
838           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
839           break;
840
841         case oLogFile: logfile = pargs.r.ret_str; break;
842           
843         case oBatch: 
844           opt.batch = 1;
845           greeting = 0;
846           break;
847         case oNoBatch: opt.batch = 0; break;
848           
849         case oAnswerYes: opt.answer_yes = 1; break;
850         case oAnswerNo: opt.answer_no = 1; break;
851
852         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
853
854         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
855         case oDebugAll: opt.debug = ~0; break;
856         case oDebugWait: debug_wait = pargs.r.ret_int; break;
857         case oDebugNoChainValidation: opt.no_chain_validation = 1; break;
858
859         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
860         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
861         case oWithFingerprint:
862           with_fpr=1; /*fall thru*/
863         case oFingerprint:
864           opt.fingerprint++;
865           break;
866
867         case oOptions:
868           /* config files may not be nested (silently ignore them) */
869           if (!configfp)
870             {
871               xfree(configname);
872               configname = xstrdup (pargs.r.ret_str);
873               goto next_pass;
874             }
875           break;
876         case oNoOptions: break; /* no-options */
877         case oHomedir: opt.homedir = pargs.r.ret_str; break;
878         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
879         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
880         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
881         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
882         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
883         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
884         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
885           
886         case oFakedSystemTime:
887           gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0);
888           break;
889
890         case oNoDefKeyring: default_keyring = 0; break;
891         case oNoGreeting: nogreeting = 1; break;
892
893         case oDefaultKey:
894           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
895           break;
896         case oDefRecipient:
897           if (*pargs.r.ret_str)
898             opt.def_recipient = xstrdup (pargs.r.ret_str);
899           break;
900         case oDefRecipientSelf:
901           xfree (opt.def_recipient);
902           opt.def_recipient = NULL;
903           opt.def_recipient_self = 1;
904           break;
905         case oNoDefRecipient:
906           xfree (opt.def_recipient);
907           opt.def_recipient = NULL;
908           opt.def_recipient_self = 0;
909           break;
910
911         case oWithKeyData: opt.with_key_data=1; /* fall thru */
912         case oWithColons: ctrl.with_colons = 1; break;
913
914         case oSkipVerify: opt.skip_verify=1; break;
915
916         case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
917         case oEncryptTo: /* store the recipient in the second list */
918           sl = add_to_strlist (&remusr, pargs.r.ret_str);
919           sl->flags = 1;
920           break;
921
922         case oRecipient: /* store the recipient */
923           add_to_strlist ( &remusr, pargs.r.ret_str);
924           break;
925
926         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
927         case oTextmode: /*fixme:opt.textmode=1;*/  break;
928
929         case oUser: /* store the local users, the first one is the default */
930           if (!opt.local_user)
931             opt.local_user = pargs.r.ret_str;
932           add_to_strlist (&locusr, pargs.r.ret_str);
933           break;
934
935         case oNoSecmemWarn:
936           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
937           break;
938
939         case oCipherAlgo:
940           opt.def_cipher_algoid = pargs.r.ret_str;
941           break;
942
943         case oDisableCipherAlgo: 
944           {
945             int algo = gcry_cipher_map_name (pargs.r.ret_str);
946             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
947           }
948           break;
949         case oDisablePubkeyAlgo: 
950           {
951             int algo = gcry_pk_map_name (pargs.r.ret_str);
952             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
953           }
954           break;
955
956         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
957         case oNoRandomSeedFile: use_random_seed = 0; break;
958
959         case oEnableSpecialFilenames: allow_special_filenames =1; break;
960           
961
962         case aDummy:
963           break;
964         default: 
965           pargs.err = configfp? 1:2; 
966           break;
967         }
968     }
969
970   if (configfp)
971     {
972       fclose (configfp);
973       configfp = NULL;
974       xfree (configname);
975       configname = NULL;
976       goto next_pass;
977     }
978   
979   xfree (configname);
980   configname = NULL;
981
982   if (log_get_errorcount(0))
983     gpgsm_exit(2);
984   
985   if (nogreeting)
986     greeting = 0;
987   
988   if (greeting)
989     {
990       fprintf(stderr, "%s %s; %s\n",
991               strusage(11), strusage(13), strusage(14) );
992       fprintf(stderr, "%s\n", strusage(15) );
993     }
994 #  ifdef IS_DEVELOPMENT_VERSION
995   if (!opt.batch)
996     {
997       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
998       log_info ("It is only intended for test purposes and should NOT be\n");
999       log_info ("used in a production environment or with production keys!\n");
1000     }
1001 #  endif
1002
1003   if (may_coredump && !opt.quiet)
1004     log_info (_("WARNING: program may create a core file!\n"));
1005
1006   if (logfile && cmd == aServer)
1007     {
1008       log_set_file (logfile);
1009       log_set_prefix (NULL, 1|2|4);
1010     }
1011
1012   if (gnupg_faked_time_p ())
1013     {
1014       log_info (_("WARNING: running with faked system time: "));
1015       gpgsm_dump_time (gnupg_get_time ());
1016       log_printf ("\n");
1017     }
1018   
1019 /*FIXME    if (opt.batch) */
1020 /*      tty_batchmode (1); */
1021
1022   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
1023
1024   set_debug ();
1025
1026   /* FIXME: should set filenames of libgcrypt explicitly
1027    * gpg_opt_homedir = opt.homedir; */
1028
1029   /* must do this after dropping setuid, because the mapping functions
1030      may try to load an module and we may have disabled an algorithm */
1031   if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
1032        || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
1033     log_error (_("selected cipher algorithm is invalid\n"));
1034
1035   if (def_digest_string)
1036     {
1037       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
1038       xfree (def_digest_string);
1039       def_digest_string = NULL;
1040       if (our_md_test_algo(opt.def_digest_algo) )
1041         log_error (_("selected digest algorithm is invalid\n"));
1042     }
1043
1044   if (log_get_errorcount(0))
1045     gpgsm_exit(2);
1046   
1047   /* set the random seed file */
1048   if (use_random_seed) {
1049     char *p = make_filename (opt.homedir, "random_seed", NULL);
1050 #if 0
1051 #warning set_random_seed_file not yet available in Libgcrypt
1052     set_random_seed_file(p);
1053 #endif
1054     xfree(p);
1055   }
1056
1057
1058   if (!cmd && opt.fingerprint && !with_fpr)
1059     set_cmd (&cmd, aListKeys);
1060   
1061   if (!nrings && default_keyring)  /* add default keybox */
1062     keydb_add_resource ("pubring.kbx", 0, 0);
1063   for (sl = nrings; sl; sl = sl->next)
1064     keydb_add_resource (sl->d, 0, 0);
1065   FREE_STRLIST(nrings);
1066
1067
1068   for (sl = locusr; sl; sl = sl->next)
1069     {
1070       int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist);
1071       if (rc)
1072         {
1073           log_error (_("can't sign using `%s': %s\n"),
1074                      sl->d, gnupg_strerror (rc));
1075           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
1076                          rc == -1? "1":
1077                          rc == GNUPG_No_Public_Key?       "1":
1078                          rc == GNUPG_Ambiguous_Name?      "2":
1079                          rc == GNUPG_Wrong_Key_Usage?     "3":
1080                          rc == GNUPG_Certificate_Revoked? "4":
1081                          rc == GNUPG_Certificate_Expired? "5":
1082                          rc == GNUPG_No_CRL_Known?        "6":
1083                          rc == GNUPG_CRL_Too_Old?         "7":
1084                          rc == GNUPG_No_Policy_Match?     "8":
1085                          rc == GNUPG_No_Secret_Key?       "9":
1086                          "0",
1087                          sl->d, NULL);
1088         }
1089     }
1090   for (sl = remusr; sl; sl = sl->next)
1091     {
1092       int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 0, &recplist);
1093       if (rc)
1094         {
1095           log_error (_("can't encrypt to `%s': %s\n"),
1096                      sl->d, gnupg_strerror (rc));
1097           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
1098                          rc == -1? "1":
1099                          rc == GNUPG_No_Public_Key?       "1":
1100                          rc == GNUPG_Ambiguous_Name?      "2":
1101                          rc == GNUPG_Wrong_Key_Usage?     "3":
1102                          rc == GNUPG_Certificate_Revoked? "4":
1103                          rc == GNUPG_Certificate_Expired? "5":
1104                          rc == GNUPG_No_CRL_Known?        "6":
1105                          rc == GNUPG_CRL_Too_Old?         "7":
1106                          rc == GNUPG_No_Policy_Match?     "8":
1107                          "0",
1108                          sl->d, NULL);
1109         }
1110   }
1111   if (log_get_errorcount(0))
1112     gpgsm_exit(1); /* must stop for invalid recipients */
1113   
1114
1115   
1116   fname = argc? *argv : NULL;
1117   
1118   switch (cmd)
1119     {
1120     case aServer:
1121       if (debug_wait)
1122         {
1123           log_debug ("waiting for debugger - my pid is %u .....\n",
1124                      (unsigned int)getpid());
1125           sleep (debug_wait);
1126           log_debug ("... okay\n");
1127          }
1128       gpgsm_server ();
1129       break;
1130
1131     case aEncr: /* encrypt the given file */
1132       if (!argc)
1133         gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
1134       else if (argc == 1)
1135         gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
1136       else
1137         wrong_args (_("--encrypt [datafile]"));
1138       break;
1139
1140     case aSign: /* sign the given file */
1141       /* FIXME: We don't handle --output yet. We should also allow
1142          to concatenate multiple files for signing because that is
1143          what gpg does.*/
1144       if (!argc)
1145         gpgsm_sign (&ctrl, signerlist,
1146                     0, detached_sig, stdout); /* create from stdin */
1147       else if (argc == 1)
1148         gpgsm_sign (&ctrl, signerlist,
1149                     open_read (*argv), detached_sig, stdout); /* from file */
1150       else
1151         wrong_args (_("--sign [datafile]"));
1152       break;
1153         
1154     case aSignEncr: /* sign and encrypt the given file */
1155       log_error ("this command has not yet been implemented\n");
1156       break;
1157
1158     case aClearsign: /* make a clearsig */
1159       log_error ("this command has not yet been implemented\n");
1160       break;
1161
1162     case aVerify:
1163       {
1164         FILE *fp = NULL;
1165
1166         if (argc == 2 && opt.outfile)
1167           log_info ("option --output ignored for a detached signature\n");
1168         else if (opt.outfile)
1169           fp = open_fwrite (opt.outfile);
1170
1171         if (!argc)
1172           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
1173         else if (argc == 1)
1174           gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */
1175         else if (argc == 2) /* detached signature (sig, detached) */
1176           gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); 
1177         else
1178           wrong_args (_("--verify [signature [detached_data]]"));
1179
1180         if (fp && fp != stdout)
1181           fclose (fp);
1182       }
1183       break;
1184
1185     case aVerifyFiles:
1186       log_error ("this command has not yet been implemented\n");
1187       break;
1188
1189     case aDecrypt:
1190       if (!argc)
1191         gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
1192       else if (argc == 1)
1193         gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
1194       else
1195         wrong_args (_("--decrypt [filename]"));
1196       break;
1197
1198     case aDeleteKey:
1199       for (sl=NULL; argc; argc--, argv++)
1200         add_to_strlist (&sl, *argv);
1201       gpgsm_delete (&ctrl, sl);
1202       free_strlist(sl);
1203       break;
1204
1205     case aListSigs:
1206       ctrl.with_chain = 1;
1207     case aListKeys:
1208       for (sl=NULL; argc; argc--, argv++)
1209         add_to_strlist (&sl, *argv);
1210       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
1211       free_strlist(sl);
1212       break;
1213
1214     case aListExternalKeys:
1215       for (sl=NULL; argc; argc--, argv++)
1216         add_to_strlist (&sl, *argv);
1217       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<7)));
1218       free_strlist(sl);
1219       break;
1220
1221     case aListSecretKeys:
1222       for (sl=NULL; argc; argc--, argv++)
1223         add_to_strlist (&sl, *argv);
1224       gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
1225       free_strlist(sl);
1226       break;
1227
1228     case aKeygen: /* generate a key */
1229       log_error ("this function is not yet available from the commandline\n");
1230       break;
1231
1232     case aImport:
1233       gpgsm_import_files (&ctrl, argc, argv, open_read);
1234       break;
1235
1236     case aExport:
1237       for (sl=NULL; argc; argc--, argv++)
1238         add_to_strlist (&sl, *argv);
1239       gpgsm_export (&ctrl, sl, stdout);
1240       free_strlist(sl);
1241       break;
1242
1243       
1244     case aSendKeys:
1245     case aRecvKeys:
1246       log_error ("this command has not yet been implemented\n");
1247       break;
1248
1249
1250     case aLearnCard:
1251       if (argc)
1252         wrong_args ("--learn-card");
1253       else
1254         {
1255           int rc = gpgsm_agent_learn ();
1256           if (rc)
1257             log_error ("error learning card: %s\n", gnupg_strerror (rc));
1258         }
1259       break;
1260
1261
1262     default:
1263         log_error ("invalid command (there is no implicit command)\n");
1264         break;
1265     }
1266   
1267   /* cleanup */
1268   gpgsm_release_certlist (recplist);
1269   gpgsm_release_certlist (signerlist);
1270   FREE_STRLIST(remusr);
1271   FREE_STRLIST(locusr);
1272   gpgsm_exit(0);
1273   return 8; /*NEVER REACHED*/
1274 }
1275
1276 /* Note: This function is used by signal handlers!. */
1277 static void
1278 emergency_cleanup (void)
1279 {
1280   gcry_control (GCRYCTL_TERM_SECMEM );
1281 }
1282
1283
1284 void
1285 gpgsm_exit (int rc)
1286 {
1287   #if 0
1288 #warning no update_random_seed_file
1289   update_random_seed_file();
1290   #endif
1291 #if 0
1292   /* at this time a bit annoying */
1293   if (opt.debug & DBG_MEMSTAT_VALUE)
1294     {
1295       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1296       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1297     }
1298   if (opt.debug)
1299     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1300 #endif
1301   emergency_cleanup ();
1302   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1303   exit (rc);
1304 }
1305
1306
1307 void
1308 gpgsm_init_default_ctrl (struct server_control_s *ctrl)
1309 {
1310   ctrl->include_certs = 1;  /* only include the signer's cert */
1311 }
1312
1313
1314
1315 /* Check whether the filename has the form "-&nnnn", where n is a
1316    non-zero number.  Returns this number or -1 if it is not the case.  */
1317 static int
1318 check_special_filename (const char *fname)
1319 {
1320   if (allow_special_filenames
1321       && fname && *fname == '-' && fname[1] == '&' ) {
1322     int i;
1323     
1324     fname += 2;
1325     for (i=0; isdigit (fname[i]); i++ )
1326       ;
1327     if ( !fname[i] ) 
1328       return atoi (fname);
1329   }
1330   return -1;
1331 }
1332
1333
1334
1335 /* Open the FILENAME for read and return the filedescriptor.  Stop
1336    with an error message in case of problems.  "-" denotes stdin and
1337    if special filenames are allowed the given fd is opened instead. */
1338 static int 
1339 open_read (const char *filename)
1340 {
1341   int fd;
1342
1343   if (filename[0] == '-' && !filename[1])
1344     return 0; /* stdin */
1345   fd = check_special_filename (filename);
1346   if (fd != -1)
1347     return fd;
1348   fd = open (filename, O_RDONLY);
1349   if (fd == -1)
1350     {
1351       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1352       gpgsm_exit (2);
1353     }
1354   return fd;
1355 }
1356
1357 /* Open FILENAME for fwrite and return the stream.  Stop with an error
1358    message in case of problems.  "-" denotes stdout and if special
1359    filenames are allowed the given fd is opened instead. Caller must
1360    close the returned stream unless it is stdout. */
1361 static FILE *
1362 open_fwrite (const char *filename)
1363 {
1364   int fd;
1365   FILE *fp;
1366
1367   if (filename[0] == '-' && !filename[1])
1368     return stdout;
1369
1370   fd = check_special_filename (filename);
1371   if (fd != -1)
1372     {
1373       fp = fdopen (dup (fd), "wb");
1374       if (!fp)
1375         {
1376           log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
1377           gpgsm_exit (2);
1378         }
1379       return fp;
1380     }
1381   fp = fopen (filename, "wb");
1382   if (!fp)
1383     {
1384       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1385       gpgsm_exit (2);
1386     }
1387   return fp;
1388 }