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