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