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