d17f1c66d7a07883919d7db1144f2653ef350b57
[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 void emergency_cleanup (void);
407 static int check_special_filename (const char *fname);
408 static int open_read (const char *filename);
409 static FILE *open_fwrite (const char *filename);
410
411
412 static int
413 our_pk_test_algo (int algo)
414 {
415   return 1;
416 }
417
418 static int
419 our_cipher_test_algo (int algo)
420 {
421   return 1;
422 }
423
424 static int
425 our_md_test_algo (int algo)
426 {
427   return 1;
428 }
429
430 static const char *
431 my_strusage( int level )
432 {
433   static char *digests, *pubkeys, *ciphers;
434   const char *p;
435
436   switch (level)
437     {
438     case 11: p = "gpgsm (GnuPG)";
439       break;
440     case 13: p = VERSION; break;
441     case 17: p = PRINTABLE_OS_NAME; break;
442     case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n");
443       break;
444     case 1:
445     case 40: p = _("Usage: gpgsm [options] [files] (-h for help)");
446       break;
447     case 41:
448       p = _("Syntax: gpgsm [options] [files]\n"
449             "sign, check, encrypt or decrypt using the S/MIME protocol\n"
450             "default operation depends on the input data\n");
451       break;
452
453     case 31: p = "\nHome: "; break;
454     case 32: p = opt.homedir; break;
455     case 33: p = _("\nSupported algorithms:\n"); break;
456     case 34:
457       if (!ciphers)
458         ciphers = build_list ("Cipher: ", gcry_cipher_algo_name,
459                               our_cipher_test_algo );
460       p = ciphers;
461       break;
462     case 35:
463       if (!pubkeys)
464         pubkeys = build_list ("Pubkey: ", gcry_pk_algo_name,
465                               our_pk_test_algo );
466       p = pubkeys;
467       break;
468     case 36:
469       if (!digests)
470         digests = build_list("Hash: ", gcry_md_algo_name, our_md_test_algo );
471       p = digests;
472       break;
473       
474     default: p = NULL; break;
475     }
476   return p;
477 }
478
479
480 static char *
481 build_list (const char *text, const char * (*mapf)(int), int (*chkf)(int))
482 {
483   int i;
484   size_t n=strlen(text)+2;
485   char *list, *p;
486   
487   if (maybe_setuid) {
488     gcry_control (GCRYCTL_DROP_PRIVS); /* drop setuid */
489   }
490
491   for (i=1; i < 110; i++ )
492     if (!chkf(i))
493       n += strlen(mapf(i)) + 2;
494   list = xmalloc (21 + n);
495   *list = 0;
496   for (p=NULL, i=1; i < 110; i++)
497     {
498       if (!chkf(i))
499         {
500           if( !p )
501             p = stpcpy (list, text );
502           else
503             p = stpcpy (p, ", ");
504           p = stpcpy (p, mapf(i) );
505         }
506     }
507   if (p)
508     p = stpcpy(p, "\n" );
509   return list;
510 }
511
512
513 static void
514 i18n_init(void)
515 {
516 #ifdef USE_SIMPLE_GETTEXT
517   set_gettext_file (PACKAGE);
518 #else
519 # ifdef ENABLE_NLS
520 #  ifdef HAVE_LC_MESSAGES
521   setlocale (LC_TIME, "");
522   setlocale (LC_MESSAGES, "");
523 #  else
524   setlocale (LC_ALL, "" );
525 #  endif
526   bindtextdomain (PACKAGE, GNUPG_LOCALEDIR);
527   textdomain (PACKAGE);
528 # endif
529 #endif
530 }
531
532
533 static void
534 wrong_args (const char *text)
535 {
536   fputs (_("usage: gpgsm [options] "), stderr);
537   fputs (text, stderr);
538   putc ('\n', stderr);
539   gpgsm_exit (2);
540 }
541
542
543 static void
544 set_debug(void)
545 {
546   if (opt.debug & DBG_MPI_VALUE)
547     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 2);
548   if (opt.debug & DBG_CRYPTO_VALUE )
549     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1);
550 }
551
552
553 static void
554 set_cmd (enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd)
555 {
556   enum cmd_and_opt_values cmd = *ret_cmd;
557
558   if (!cmd || cmd == new_cmd)
559     cmd = new_cmd;
560   else if ( cmd == aSign && new_cmd == aEncr )
561     cmd = aSignEncr;
562   else if ( cmd == aEncr && new_cmd == aSign )
563     cmd = aSignEncr;
564   else if ( (cmd == aSign && new_cmd == aClearsign)
565             || (cmd == aClearsign && new_cmd == aSign) )
566     cmd = aClearsign;
567   else 
568     {
569       log_error(_("conflicting commands\n"));
570       gpgsm_exit(2);
571     }
572
573   *ret_cmd = cmd;
574 }
575
576
577 int
578 main ( int argc, char **argv)
579 {
580   ARGPARSE_ARGS pargs;
581   int orig_argc;
582   char **orig_argv;
583   const char *fname;
584   /*  char *username;*/
585   int may_coredump;
586   STRLIST sl, remusr= NULL, locusr=NULL;
587   STRLIST nrings=NULL;
588   int detached_sig = 0;
589   FILE *configfp = NULL;
590   char *configname = NULL;
591   unsigned configlineno;
592   int parse_debug = 0;
593   int default_config =1;
594   int default_keyring = 1;
595   char *logfile = NULL;
596   int greeting = 0;
597   int nogreeting = 0;
598   int debug_wait = 0;
599   int use_random_seed = 1;
600   int with_fpr = 0;
601   char *def_digest_string = NULL;
602   enum cmd_and_opt_values cmd = 0;
603   struct server_control_s ctrl;
604   CERTLIST recplist = NULL;
605   CERTLIST signerlist = NULL;
606
607   /* trap_unaligned ();*/
608   set_strusage (my_strusage);
609   gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
610   /* Please note that we may running SUID(ROOT), so be very CAREFUL
611      when adding any stuff between here and the call to secmem_init()
612      somewhere after the option parsing */
613   log_set_prefix ("gpgsm", 1);
614   /* check that the libraries are suitable.  Do it here because the
615      option parse may need services of the library */
616   if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
617     {
618       log_fatal( _("libgcrypt is too old (need %s, have %s)\n"),
619                  NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
620     }
621   if (!ksba_check_version (NEED_LIBKSBA_VERSION) )
622     {
623       log_fatal( _("libksba is too old (need %s, have %s)\n"),
624                  NEED_LIBKSBA_VERSION, ksba_check_version (NULL) );
625     }
626
627   gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
628
629   may_coredump = disable_core_dumps ();
630   
631   gnupg_init_signals (0, emergency_cleanup);
632   
633   create_dotlock (NULL); /* register locking cleanup */
634   i18n_init();
635
636   opt.def_cipher_algoid = "1.2.840.113549.3.7";  /*des-EDE3-CBC*/
637 #ifdef __MINGW32__
638   opt.homedir = read_w32_registry_string ( NULL,
639                                            "Software\\GNU\\GnuPG", "HomeDir" );
640 #else
641   opt.homedir = getenv ("GNUPGHOME");
642 #endif
643   if (!opt.homedir || !*opt.homedir ) 
644     opt.homedir = GNUPG_DEFAULT_HOMEDIR;
645
646   /* first check whether we have a config file on the commandline */
647   orig_argc = argc;
648   orig_argv = argv;
649   pargs.argc = &argc;
650   pargs.argv = &argv;
651   pargs.flags= 1|(1<<6);  /* do not remove the args, ignore version */
652   while (arg_parse( &pargs, opts))
653     {
654       if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
655         parse_debug++;
656       else if (pargs.r_opt == oOptions)
657         { /* yes there is one, so we do not try the default one but
658              read the config file when it is encountered at the
659              commandline */
660           default_config = 0;
661         }
662       else if (pargs.r_opt == oNoOptions)
663         default_config = 0; /* --no-options */
664       else if (pargs.r_opt == oHomedir)
665         opt.homedir = pargs.r.ret_str;
666     }
667   
668   
669   /* initialize the secure memory. */
670   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
671   maybe_setuid = 0;
672
673   /* 
674      Now we are now working under our real uid 
675   */
676
677   ksba_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free );
678   assuan_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
679   keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free);
680
681   /* Setup a default control structure for command line mode */
682   memset (&ctrl, 0, sizeof ctrl);
683   gpgsm_init_default_ctrl (&ctrl);
684   ctrl.no_server = 1;
685   ctrl.status_fd = -1; /* not status output */
686   ctrl.autodetect_encoding = 1;
687
688   /* set the default option file */
689   if (default_config )
690     configname = make_filename (opt.homedir, "gpgsm.conf", NULL);
691   /* cet the default policy file */
692   opt.policy_file = make_filename (opt.homedir, "policies.txt", NULL);
693   
694   argc        = orig_argc;
695   argv        = orig_argv;
696   pargs.argc  = &argc;
697   pargs.argv  = &argv;
698   pargs.flags =  1;  /* do not remove the args */
699
700  next_pass:
701   if (configname) {
702     configlineno = 0;
703     configfp = fopen (configname, "r");
704     if (!configfp)
705       {
706         if (default_config)
707           {
708             if (parse_debug)
709               log_info (_("NOTE: no default option file `%s'\n"), configname);
710           }
711         else 
712           {
713             log_error (_("option file `%s': %s\n"), configname, strerror(errno));
714             gpgsm_exit(2);
715           }
716         xfree(configname);
717         configname = NULL;
718       }
719     if (parse_debug && configname)
720       log_info (_("reading options from `%s'\n"), configname);
721     default_config = 0;
722   }
723
724   while (optfile_parse (configfp, configname, &configlineno, &pargs, opts))
725     {
726       switch (pargs.r_opt)
727         {
728         case aServer: 
729           opt.batch = 1;
730           set_cmd (&cmd, aServer);
731           break;
732
733         case aCheckKeys: set_cmd (&cmd, aCheckKeys); break;
734         case aImport: set_cmd (&cmd, aImport); break;
735         case aSendKeys: set_cmd (&cmd, aSendKeys); break;
736         case aRecvKeys: set_cmd (&cmd, aRecvKeys); break;
737         case aExport: set_cmd (&cmd, aExport); break;
738         case aListKeys: set_cmd (&cmd, aListKeys); break;
739         case aListExternalKeys: set_cmd (&cmd, aListExternalKeys); break;
740         case aListSecretKeys: set_cmd (&cmd, aListSecretKeys); break;
741         case aListSigs: set_cmd (&cmd, aListSigs); break;
742
743         case aLearnCard: set_cmd (&cmd, aLearnCard); break;
744
745         case aDeleteKey:
746           set_cmd (&cmd, aDeleteKey);
747           /*greeting=1;*/
748           break;
749
750         case aDetachedSign:
751           detached_sig = 1;
752           set_cmd (&cmd, aSign ); 
753           break;
754           
755         case aSym: set_cmd (&cmd, aSym); break;
756         case aDecrypt: set_cmd (&cmd, aDecrypt); break;
757         case aEncr: set_cmd (&cmd, aEncr); break;
758         case aSign: set_cmd (&cmd, aSign );  break;
759         case aKeygen: set_cmd (&cmd, aKeygen); greeting=1; break;
760         case aClearsign: set_cmd (&cmd, aClearsign); break;
761         case aVerify: set_cmd (&cmd, aVerify); break;
762
763
764           /* output encoding selection */
765         case oArmor:
766           ctrl.create_pem = 1;
767           break;
768         case oBase64: 
769           ctrl.create_pem = 0;
770           ctrl.create_base64 = 1;
771           break;
772         case oNoArmor: 
773           ctrl.create_pem = 0;
774           ctrl.create_base64 = 0;
775           break;
776           
777           /* Input encoding selection */
778         case oAssumeArmor:
779           ctrl.autodetect_encoding = 0;
780           ctrl.is_pem = 1;
781           ctrl.is_base64 = 0;
782           break;
783         case oAssumeBase64:
784           ctrl.autodetect_encoding = 0;
785           ctrl.is_pem = 0;
786           ctrl.is_base64 = 1;
787           break;
788         case oAssumeBinary:
789           ctrl.autodetect_encoding = 0;
790           ctrl.is_pem = 0;
791           ctrl.is_base64 = 0;
792           break;
793
794         case oDisableCRLChecks:
795           opt.no_crl_check = 1;
796           break;
797         case oEnableCRLChecks:
798           opt.no_crl_check = 0;
799           break;
800
801         case oIncludeCerts: ctrl.include_certs = pargs.r.ret_int; break;
802
803         case oPolicyFile:
804           xfree (opt.policy_file);
805           if (*pargs.r.ret_str)
806             opt.policy_file = xstrdup (pargs.r.ret_str);
807           else
808             opt.policy_file = NULL;
809           break;
810
811         case oDisablePolicyChecks:
812           opt.no_policy_check = 1;
813           break;
814         case oEnablePolicyChecks:
815           opt.no_policy_check = 0;
816           break;
817           
818         case oAutoIssuerKeyRetrieve:
819           opt.auto_issuer_key_retrieve = 1;
820           break;
821
822         case oOutput: opt.outfile = pargs.r.ret_str; break;
823
824         
825         case oQuiet: opt.quiet = 1; break;
826         case oNoTTY: /* fixme:tty_no_terminal(1);*/ break;
827         case oDryRun: opt.dry_run = 1; break;
828
829         case oVerbose:
830           opt.verbose++;
831           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
832           break;
833         case oNoVerbose:
834           opt.verbose = 0;
835           gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
836           break;
837
838         case oLogFile: logfile = pargs.r.ret_str; break;
839           
840         case oBatch: 
841           opt.batch = 1;
842           greeting = 0;
843           break;
844         case oNoBatch: opt.batch = 0; break;
845           
846         case oAnswerYes: opt.answer_yes = 1; break;
847         case oAnswerNo: opt.answer_no = 1; break;
848
849         case oKeyring: append_to_strlist (&nrings, pargs.r.ret_str); break;
850
851         case oDebug: opt.debug |= pargs.r.ret_ulong; break;
852         case oDebugAll: opt.debug = ~0; break;
853         case oDebugWait: debug_wait = pargs.r.ret_int; break;
854         case oDebugNoPathValidation: opt.no_path_validation = 1; break;
855
856
857         case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
858         case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;
859         case oWithFingerprint:
860           with_fpr=1; /*fall thru*/
861         case oFingerprint:
862           opt.fingerprint++;
863           break;
864
865         case oOptions:
866           /* config files may not be nested (silently ignore them) */
867           if (!configfp)
868             {
869               xfree(configname);
870               configname = xstrdup (pargs.r.ret_str);
871               goto next_pass;
872             }
873           break;
874         case oNoOptions: break; /* no-options */
875         case oHomedir: opt.homedir = pargs.r.ret_str; break;
876         case oAgentProgram: opt.agent_program = pargs.r.ret_str;  break;
877         case oDisplay: opt.display = xstrdup (pargs.r.ret_str); break;
878         case oTTYname: opt.ttyname = xstrdup (pargs.r.ret_str); break;
879         case oTTYtype: opt.ttytype = xstrdup (pargs.r.ret_str); break;
880         case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break;
881         case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break;
882         case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str;  break;
883           
884         case oFakedSystemTime:
885           gnupg_set_time ( (time_t)pargs.r.ret_ulong, 0);
886           break;
887
888         case oNoDefKeyring: default_keyring = 0; break;
889         case oNoGreeting: nogreeting = 1; break;
890
891         case oDefaultKey:
892           /* fixme:opt.def_secret_key = pargs.r.ret_str;*/
893           break;
894         case oDefRecipient:
895           if (*pargs.r.ret_str)
896             opt.def_recipient = xstrdup (pargs.r.ret_str);
897           break;
898         case oDefRecipientSelf:
899           xfree (opt.def_recipient);
900           opt.def_recipient = NULL;
901           opt.def_recipient_self = 1;
902           break;
903         case oNoDefRecipient:
904           xfree (opt.def_recipient);
905           opt.def_recipient = NULL;
906           opt.def_recipient_self = 0;
907           break;
908
909         case oWithKeyData: opt.with_key_data=1; /* fall thru */
910         case oWithColons: ctrl.with_colons = 1; break;
911
912         case oSkipVerify: opt.skip_verify=1; break;
913
914         case oNoEncryptTo: /*fixme: opt.no_encrypt_to = 1;*/ break;
915         case oEncryptTo: /* store the recipient in the second list */
916           sl = add_to_strlist (&remusr, pargs.r.ret_str);
917           sl->flags = 1;
918           break;
919
920         case oRecipient: /* store the recipient */
921           add_to_strlist ( &remusr, pargs.r.ret_str);
922           break;
923
924         case oTextmodeShort: /*fixme:opt.textmode = 2;*/ break;
925         case oTextmode: /*fixme:opt.textmode=1;*/  break;
926
927         case oUser: /* store the local users, the first one is the default */
928           if (!opt.local_user)
929             opt.local_user = pargs.r.ret_str;
930           add_to_strlist (&locusr, pargs.r.ret_str);
931           break;
932
933         case oNoSecmemWarn:
934           gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); 
935           break;
936
937         case oCipherAlgo:
938           opt.def_cipher_algoid = pargs.r.ret_str;
939           break;
940
941         case oDisableCipherAlgo: 
942           {
943             int algo = gcry_cipher_map_name (pargs.r.ret_str);
944             gcry_cipher_ctl (NULL, GCRYCTL_DISABLE_ALGO, &algo, sizeof algo);
945           }
946           break;
947         case oDisablePubkeyAlgo: 
948           {
949             int algo = gcry_pk_map_name (pargs.r.ret_str);
950             gcry_pk_ctl (GCRYCTL_DISABLE_ALGO,&algo, sizeof algo );
951           }
952           break;
953
954         case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
955         case oNoRandomSeedFile: use_random_seed = 0; break;
956
957         case oEnableSpecialFilenames: allow_special_filenames =1; break;
958           
959
960         case aDummy:
961           break;
962         default: 
963           pargs.err = configfp? 1:2; 
964           break;
965         }
966     }
967
968   if (configfp)
969     {
970       fclose (configfp);
971       configfp = NULL;
972       xfree (configname);
973       configname = NULL;
974       goto next_pass;
975     }
976   
977   xfree (configname);
978   configname = NULL;
979
980   if (log_get_errorcount(0))
981     gpgsm_exit(2);
982   
983   if (nogreeting)
984     greeting = 0;
985   
986   if (greeting)
987     {
988       fprintf(stderr, "%s %s; %s\n",
989               strusage(11), strusage(13), strusage(14) );
990       fprintf(stderr, "%s\n", strusage(15) );
991     }
992 #  ifdef IS_DEVELOPMENT_VERSION
993   if (!opt.batch)
994     {
995       log_info ("NOTE: THIS IS A DEVELOPMENT VERSION!\n");
996       log_info ("It is only intended for test purposes and should NOT be\n");
997       log_info ("used in a production environment or with production keys!\n");
998     }
999 #  endif
1000
1001   if (may_coredump && !opt.quiet)
1002     log_info (_("WARNING: program may create a core file!\n"));
1003
1004   if (logfile)
1005     {
1006       log_set_file (logfile);
1007       log_set_prefix (NULL, 1|2|4);
1008     }
1009
1010   if (gnupg_faked_time_p ())
1011     {
1012       log_info (_("WARNING: running with faked system time: "));
1013       gpgsm_dump_time (gnupg_get_time ());
1014       log_printf ("\n");
1015     }
1016   
1017 /*FIXME    if (opt.batch) */
1018 /*      tty_batchmode (1); */
1019
1020   gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
1021
1022   set_debug ();
1023
1024   /* FIXME: should set filenames of libgcrypt explicitly
1025    * gpg_opt_homedir = opt.homedir; */
1026
1027   /* must do this after dropping setuid, because the mapping functions
1028      may try to load an module and we may have disabled an algorithm */
1029   if ( !gcry_cipher_map_name (opt.def_cipher_algoid)
1030        || !gcry_cipher_mode_from_oid (opt.def_cipher_algoid))
1031     log_error (_("selected cipher algorithm is invalid\n"));
1032
1033   if (def_digest_string)
1034     {
1035       opt.def_digest_algo = gcry_md_map_name (def_digest_string);
1036       xfree (def_digest_string);
1037       def_digest_string = NULL;
1038       if (our_md_test_algo(opt.def_digest_algo) )
1039         log_error (_("selected digest algorithm is invalid\n"));
1040     }
1041
1042   if (log_get_errorcount(0))
1043     gpgsm_exit(2);
1044   
1045   /* set the random seed file */
1046   if (use_random_seed) {
1047     char *p = make_filename (opt.homedir, "random_seed", NULL);
1048 #if 0
1049 #warning set_random_seed_file not yet available in Libgcrypt
1050     set_random_seed_file(p);
1051 #endif
1052     xfree(p);
1053   }
1054
1055
1056   if (!cmd && opt.fingerprint && !with_fpr)
1057     set_cmd (&cmd, aListKeys);
1058   
1059   if (!nrings && default_keyring)  /* add default keybox */
1060     keydb_add_resource ("pubring.kbx", 0, 0);
1061   for (sl = nrings; sl; sl = sl->next)
1062     keydb_add_resource (sl->d, 0, 0);
1063   FREE_STRLIST(nrings);
1064
1065
1066   for (sl = locusr; sl; sl = sl->next)
1067     {
1068       int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 1, &signerlist);
1069       if (rc)
1070         {
1071           log_error (_("can't sign using `%s': %s\n"),
1072                      sl->d, gnupg_strerror (rc));
1073           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
1074                          rc == -1? "1":
1075                          rc == GNUPG_No_Public_Key?       "1":
1076                          rc == GNUPG_Ambiguous_Name?      "2":
1077                          rc == GNUPG_Wrong_Key_Usage?     "3":
1078                          rc == GNUPG_Certificate_Revoked? "4":
1079                          rc == GNUPG_Certificate_Expired? "5":
1080                          rc == GNUPG_No_CRL_Known?        "6":
1081                          rc == GNUPG_CRL_Too_Old?         "7":
1082                          rc == GNUPG_No_Policy_Match?     "8":
1083                          rc == GNUPG_No_Secret_Key?       "9":
1084                          "0",
1085                          sl->d, NULL);
1086         }
1087     }
1088   for (sl = remusr; sl; sl = sl->next)
1089     {
1090       int rc = gpgsm_add_to_certlist (&ctrl, sl->d, 0, &recplist);
1091       if (rc)
1092         {
1093           log_error (_("can't encrypt to `%s': %s\n"),
1094                      sl->d, gnupg_strerror (rc));
1095           gpgsm_status2 (&ctrl, STATUS_INV_RECP,
1096                          rc == -1? "1":
1097                          rc == GNUPG_No_Public_Key?       "1":
1098                          rc == GNUPG_Ambiguous_Name?      "2":
1099                          rc == GNUPG_Wrong_Key_Usage?     "3":
1100                          rc == GNUPG_Certificate_Revoked? "4":
1101                          rc == GNUPG_Certificate_Expired? "5":
1102                          rc == GNUPG_No_CRL_Known?        "6":
1103                          rc == GNUPG_CRL_Too_Old?         "7":
1104                          rc == GNUPG_No_Policy_Match?     "8":
1105                          "0",
1106                          sl->d, NULL);
1107         }
1108   }
1109   if (log_get_errorcount(0))
1110     gpgsm_exit(1); /* must stop for invalid recipients */
1111   
1112
1113   
1114   fname = argc? *argv : NULL;
1115   
1116   switch (cmd)
1117     {
1118     case aServer:
1119       if (debug_wait)
1120         {
1121           log_debug ("waiting for debugger - my pid is %u .....\n",
1122                      (unsigned int)getpid());
1123           sleep (debug_wait);
1124           log_debug ("... okay\n");
1125          }
1126       gpgsm_server ();
1127       break;
1128
1129     case aEncr: /* encrypt the given file */
1130       if (!argc)
1131         gpgsm_encrypt (&ctrl, recplist, 0, stdout); /* from stdin */
1132       else if (argc == 1)
1133         gpgsm_encrypt (&ctrl, recplist, open_read (*argv), stdout); /* from file */
1134       else
1135         wrong_args (_("--encrypt [datafile]"));
1136       break;
1137
1138     case aSign: /* sign the given file */
1139       /* FIXME: We don't handle --output yet. We should also allow
1140          to concatenate multiple files for signing because that is
1141          what gpg does.*/
1142       if (!argc)
1143         gpgsm_sign (&ctrl, signerlist,
1144                     0, detached_sig, stdout); /* create from stdin */
1145       else if (argc == 1)
1146         gpgsm_sign (&ctrl, signerlist,
1147                     open_read (*argv), detached_sig, stdout); /* from file */
1148       else
1149         wrong_args (_("--sign [datafile]"));
1150       break;
1151         
1152     case aSignEncr: /* sign and encrypt the given file */
1153       log_error ("this command has not yet been implemented\n");
1154       break;
1155
1156     case aClearsign: /* make a clearsig */
1157       log_error ("this command has not yet been implemented\n");
1158       break;
1159
1160     case aVerify:
1161       {
1162         FILE *fp = NULL;
1163
1164         if (argc == 2 && opt.outfile)
1165           log_info ("option --output ignored for a detached signature\n");
1166         else if (opt.outfile)
1167           fp = open_fwrite (opt.outfile);
1168
1169         if (!argc)
1170           gpgsm_verify (&ctrl, 0, -1, fp); /* normal signature from stdin */
1171         else if (argc == 1)
1172           gpgsm_verify (&ctrl, open_read (*argv), -1, fp); /* std signature */
1173         else if (argc == 2) /* detached signature (sig, detached) */
1174           gpgsm_verify (&ctrl, open_read (*argv), open_read (argv[1]), NULL); 
1175         else
1176           wrong_args (_("--verify [signature [detached_data]]"));
1177
1178         if (fp && fp != stdout)
1179           fclose (fp);
1180       }
1181       break;
1182
1183     case aVerifyFiles:
1184       log_error ("this command has not yet been implemented\n");
1185       break;
1186
1187     case aDecrypt:
1188       if (!argc)
1189         gpgsm_decrypt (&ctrl, 0, stdout); /* from stdin */
1190       else if (argc == 1)
1191         gpgsm_decrypt (&ctrl, open_read (*argv), stdout); /* from file */
1192       else
1193         wrong_args (_("--decrypt [filename]"));
1194       break;
1195
1196     case aDeleteKey:
1197       for (sl=NULL; argc; argc--, argv++)
1198         add_to_strlist (&sl, *argv);
1199       gpgsm_delete (&ctrl, sl);
1200       free_strlist(sl);
1201       break;
1202
1203     case aListSigs:
1204       ctrl.with_chain = 1;
1205     case aListKeys:
1206       for (sl=NULL; argc; argc--, argv++)
1207         add_to_strlist (&sl, *argv);
1208       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
1209       free_strlist(sl);
1210       break;
1211
1212     case aListExternalKeys:
1213       for (sl=NULL; argc; argc--, argv++)
1214         add_to_strlist (&sl, *argv);
1215       gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<7)));
1216       free_strlist(sl);
1217       break;
1218
1219     case aListSecretKeys:
1220       for (sl=NULL; argc; argc--, argv++)
1221         add_to_strlist (&sl, *argv);
1222       gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
1223       free_strlist(sl);
1224       break;
1225
1226     case aKeygen: /* generate a key */
1227       log_error ("this function is not yet available from the commandline\n");
1228       break;
1229
1230     case aImport:
1231       if (!argc)
1232         gpgsm_import (&ctrl, 0);
1233       else
1234         {
1235           for (; argc; argc--, argv++)
1236             gpgsm_import (&ctrl, open_read (*argv));
1237         }
1238       break;
1239
1240     case aExport:
1241       for (sl=NULL; argc; argc--, argv++)
1242         add_to_strlist (&sl, *argv);
1243       gpgsm_export (&ctrl, sl, stdout);
1244       free_strlist(sl);
1245       break;
1246
1247       
1248     case aSendKeys:
1249     case aRecvKeys:
1250       log_error ("this command has not yet been implemented\n");
1251       break;
1252
1253
1254     case aLearnCard:
1255       if (argc)
1256         wrong_args ("--learn-card");
1257       else
1258         {
1259           int rc = gpgsm_agent_learn ();
1260           if (rc)
1261             log_error ("error learning card: %s\n", gnupg_strerror (rc));
1262         }
1263       break;
1264
1265
1266     default:
1267         log_error ("invalid command (there is no implicit command)\n");
1268         break;
1269     }
1270   
1271   /* cleanup */
1272   gpgsm_release_certlist (recplist);
1273   gpgsm_release_certlist (signerlist);
1274   FREE_STRLIST(remusr);
1275   FREE_STRLIST(locusr);
1276   gpgsm_exit(0);
1277   return 8; /*NEVER REACHED*/
1278 }
1279
1280 /* Note: This function is used by signal handlers!. */
1281 static void
1282 emergency_cleanup (void)
1283 {
1284   gcry_control (GCRYCTL_TERM_SECMEM );
1285 }
1286
1287
1288 void
1289 gpgsm_exit (int rc)
1290 {
1291   #if 0
1292 #warning no update_random_seed_file
1293   update_random_seed_file();
1294   #endif
1295 #if 0
1296   /* at this time a bit annoying */
1297   if (opt.debug & DBG_MEMSTAT_VALUE)
1298     {
1299       gcry_control( GCRYCTL_DUMP_MEMORY_STATS );
1300       gcry_control( GCRYCTL_DUMP_RANDOM_STATS );
1301     }
1302   if (opt.debug)
1303     gcry_control (GCRYCTL_DUMP_SECMEM_STATS );
1304 #endif
1305   emergency_cleanup ();
1306   rc = rc? rc : log_get_errorcount(0)? 2 : gpgsm_errors_seen? 1 : 0;
1307   exit (rc);
1308 }
1309
1310
1311 void
1312 gpgsm_init_default_ctrl (struct server_control_s *ctrl)
1313 {
1314   ctrl->include_certs = 1;  /* only include the signer's cert */
1315 }
1316
1317
1318
1319 /* Check whether the filename has the form "-&nnnn", where n is a
1320    non-zero number.  Returns this number or -1 if it is not the case.  */
1321 static int
1322 check_special_filename (const char *fname)
1323 {
1324   if (allow_special_filenames
1325       && fname && *fname == '-' && fname[1] == '&' ) {
1326     int i;
1327     
1328     fname += 2;
1329     for (i=0; isdigit (fname[i]); i++ )
1330       ;
1331     if ( !fname[i] ) 
1332       return atoi (fname);
1333   }
1334   return -1;
1335 }
1336
1337
1338
1339 /* Open the FILENAME for read and return the filedescriptor.  Stop
1340    with an error message in case of problems.  "-" denotes stdin and
1341    if special filenames are allowed the given fd is opened instead. */
1342 static int 
1343 open_read (const char *filename)
1344 {
1345   int fd;
1346
1347   if (filename[0] == '-' && !filename[1])
1348     return 0; /* stdin */
1349   fd = check_special_filename (filename);
1350   if (fd != -1)
1351     return fd;
1352   fd = open (filename, O_RDONLY);
1353   if (fd == -1)
1354     {
1355       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1356       gpgsm_exit (2);
1357     }
1358   return fd;
1359 }
1360
1361 /* Open FILENAME for fwrite and return the stream.  Stop with an error
1362    message in case of problems.  "-" denotes stdout and if special
1363    filenames are allowed the given fd is opened instead. Caller must
1364    close the returned stream unless it is stdout. */
1365 static FILE *
1366 open_fwrite (const char *filename)
1367 {
1368   int fd;
1369   FILE *fp;
1370
1371   if (filename[0] == '-' && !filename[1])
1372     return stdout;
1373
1374   fd = check_special_filename (filename);
1375   if (fd != -1)
1376     {
1377       fp = fdopen (dup (fd), "wb");
1378       if (!fp)
1379         {
1380           log_error ("fdopen(%d) failed: %s\n", fd, strerror (errno));
1381           gpgsm_exit (2);
1382         }
1383       return fp;
1384     }
1385   fp = fopen (filename, "wb");
1386   if (!fp)
1387     {
1388       log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
1389       gpgsm_exit (2);
1390     }
1391   return fp;
1392 }