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