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