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