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