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